class GaddyGaddy_Client
Public Class Methods
alert(type)
click to toggle source
# File lib/gaddygaddy-client.rb, line 437 def self.alert(type) alert_timing = case type when :no_config_file {:on => 0.1, :off => 0.1,:alert_text => 'Could not found any gaddy config file in /conf/gaddy_XXXX.gcf'} when :no_network {:on => 1,:off => 1, :alert_text => 'Could not connect to internet, network configuration seems broken, restart when fixed'} end begin `echo none >/sys/class/leds/led0/trigger` count = 0 send_info_count = 20 / (alert_timing[:on] + alert_timing[:off]) do_alert = true while do_alert do if (count % send_info_count) == 0 puts alert_timing[:alert_text] ESpeak.speak alert_timing[:alert_text] end `echo 1 >/sys/class/leds/led0/brightness` sleep alert_timing[:on] `echo 0 >/sys/class/leds/led0/brightness` sleep alert_timing[:off] count += 1 end ensure `echo mmc0 >/sys/class/leds/led0/trigger` end end
ip_to_verify()
click to toggle source
# File lib/gaddygaddy-client.rb, line 465 def self.ip_to_verify '8.8.8.8' end
network_failed?()
click to toggle source
# File lib/gaddygaddy-client.rb, line 469 def self.network_failed? ping_result = `ping -w 10 #{ip_to_verify} -c 1` ping_result.index("100% packet loss") || ($?.exitstatus !=0) end
new()
click to toggle source
# File lib/gaddygaddy-client.rb, line 55 def initialize logger.outputters = Log4r::Outputter.stdout end
verify_installation()
click to toggle source
Verify that we have a conf file and verify network connection
# File lib/gaddygaddy-client.rb, line 481 def self.verify_installation conf_file = Dir.glob(File.join('/','conf', "gaddy*.gcf")) alert(:no_config_file) if conf_file.empty? if network_failed? # install_network alert(:no_network) end end
Public Instance Methods
conf_dir()
click to toggle source
Get the config directory
# File lib/gaddygaddy-client.rb, line 230 def conf_dir @options[:conf_dir] end
config_valid()
click to toggle source
Check that the config file exist and has valid content, this will also be validated toward the server
# File lib/gaddygaddy-client.rb, line 372 def config_valid config_ok = false config_file_name = Dir.glob(File.join(conf_dir, @options[:conf_file]))[0] logger.debug "Will validate config for #{config_file_name}" if File.exists?(config_file_name) begin conf_file = File.open(config_file_name) config = JSON.parse(conf_file.read) rescue Exception => e raise "Could not read from file #{config_file_name}" end logger.debug "Have read from file #{config_file_name}" config_ok = config["device_id"] end # TODO validate the client against the client service config_ok end
create_gaddy(gaddy_name, user_name, password)
click to toggle source
# File lib/gaddygaddy-client.rb, line 310 def create_gaddy(gaddy_name, user_name, password) url = Request.get_base_url(get_host) + "/installation/device/1" params = {:device_name => gaddy_name, :user_name => user_name, :user_password => password } response = Request.client_service_post url, params logger.debug "The response for the request is #{response} #{response.class}" raise JCouldNotPostClientDataException.new({:message=> "Could not post data to the gaddygaddy service, error code is #{response.body}"}) unless response[:status].to_i == 0 end
create_new?(name, type)
click to toggle source
# File lib/gaddygaddy-client.rb, line 321 def create_new?(name, type) inp = '' unless @options[:create] puts "#{type} #{name} doesn't exist, would you like to create it (Y/N)" answer = nil while answer.nil? inp = gets.chomp.upcase if inp answer = ['Y','N'].index(inp[0]) ? inp : nil else puts puts "#{type} #{name} doesn't exist, would you like to create it (Y/N)" end end end @options[:create] || (inp == 'Y') end
create_user(user_name, password)
click to toggle source
Create a new user
# File lib/gaddygaddy-client.rb, line 296 def create_user(user_name, password) url = Request.get_base_url(get_host) + "/user/1" params = { :model => { :user_email => URI.encode(user_name), :user_password => password } }.to_json response = Request.client_service_post url, params logger.debug "The response for the request is #{response} #{response.class}" raise JCouldNotPostClientDataException.new({:message=> "Could not post data to the gaddygaddy service, error code is #{response.body}"}) unless response[:status].to_i == 0 end
gaddy_config(gaddy_name, user_name, password)
click to toggle source
Get the gaddy configuration and place it in /conf named gaddy_NAME.gcf
# File lib/gaddygaddy-client.rb, line 340 def gaddy_config(gaddy_name, user_name, password) raise "You need to pass name of gaddy, username and password as parameters, see gaddygaddy-client gaddy_file --help" unless gaddy_name && password && user_name begin FileUtils.mkdir_p conf_dir rescue Exception => e raise e.inspect end puts "1" begin status_gaddy = get_conf_file['status'] rescue RestClient::Unauthorized => e if create_new?(user_name, 'User') logger.info "Will create a new user #{user_name}" create_user(user_name, password) end status_gaddy = get_conf_file['status'] end if status_gaddy == 12 || status_gaddy == 4 if create_new?(gaddy_name, 'Gaddy') logger.info "Will create a new gaddy named #{gaddy_name}" create_gaddy(gaddy_name, user_name, password) if get_conf_file['status'] == 12 puts "Can't find gaddy with name #{name}" end else puts "Can't find gaddy with name #{name}" puts 'If you would like to create it add parameter --create to the command' end end end
get_chef_config()
click to toggle source
# File lib/gaddygaddy-client.rb, line 253 def get_chef_config begin FileUtils.mkdir_p conf_dir rescue Exception => e raise e.inspect end conf_content = get_chef_config_file chef_config = conf_content['variables'] chef_config['run_list'] = conf_content['run_list'] conf_file = File.open File.join(conf_dir, CONFIG_FILE_NAME), "w" conf_file.write chef_config.to_json conf_file.close end
get_chef_config_file()
click to toggle source
# File lib/gaddygaddy-client.rb, line 246 def get_chef_config_file response = Request.client_service_get get_host, "/chef/node_json/1/#{gg_config.user_id_salt}/#{gg_config.device_id}/#{gg_config.token}" raise "Could not get config file for device #{gg_config.device_id}" unless response["run_list"].length > 0 logger.debug "Got config file: #{response}" response end
get_conf_file()
click to toggle source
Get the config file and return the response
# File lib/gaddygaddy-client.rb, line 277 def get_conf_file name = @options[:gaddy_name] conf_content = get_gaddy_config(name, @options[:user_name], @options[:password]) gaddy_file_name = "gaddy_#{name}.gcf" conf_file_name = File.join(conf_dir, gaddy_file_name) if conf_content['device_name'] && conf_content['device_name'] == name begin conf_file = File.open conf_file_name, "w" conf_file.write conf_content.to_json conf_file.close logger.info "Have created the configuration file for the gaddy in #{conf_file_name}" rescue logger.error "Could not write configuration #{conf_file_name}" end end conf_content end
get_gaddy_config(name, user, password)
click to toggle source
# File lib/gaddygaddy-client.rb, line 268 def get_gaddy_config(name, user, password) path = URI.encode("/device/config_file/1/#{name}?user_name=#{user}&user_password=#{password}").gsub('+', '%2B') response = Request.client_service_get get_host, path logger.debug "Got config file: #{response}" response end
get_host()
click to toggle source
Should try to get the host from options or config
# File lib/gaddygaddy-client.rb, line 236 def get_host host = @options[:host] # This is a temporary fix to handle the move to Amazon if host == 'ap.gaddygaddy.com:86' host = 'ap-pre.gaddygaddy.com:86' end host end
gg_config()
click to toggle source
# File lib/gaddygaddy-client.rb, line 225 def gg_config @gg_config ||= GGConfig.new(:conf_dir => @options[:conf_dir], :conf_file => @options[:conf_file]) end
hardware_id()
click to toggle source
Get a device id, to start with only implemented for Raspberry
# File lib/gaddygaddy-client.rb, line 391 def hardware_id hardware_id = `cat /proc/cpuinfo|grep Serial`.strip[10..-1].to_s.strip logger.debug "The device id is #{hardware_id}" if hardware_id == "" hardware_id = 'test_device' end raise JNoDeviceIDFound.new({:message => "Could not found a device id for this computer, a device id is needed, see further help"}) unless hardware_id hardware_id end
install_network()
click to toggle source
Will run chef for network config to try to install network
# File lib/gaddygaddy-client.rb, line 475 def install_network # chef_cmd = CHEF_CMD + ' # run_cmd() end
read_options()
click to toggle source
# File lib/gaddygaddy-client.rb, line 67 def read_options # This hash will hold all of the options # parsed from the command-line by # OptionParser. @options = {} global_options do |opts| opts.banner = "Usage: gaddygaddy-client [options] [subcommand [options]]" opts.description = "GaddyGaddy client for the GaddyGaddy service" opts.separator "" opts.separator "Global options are:" @options[:conf_dir] = DEFAULT_CONF_DIR opts.on( '--config_dir CONF-DIR', "Directory containing the client configuration files, default is #{DEFAULT_CONF_DIR}" ) do |conf_dir| @options[:conf_dir] = conf_dir end @options[:conf_file] = DEFAULT_CONF_FILE opts.on( '--config_file CONF-FILE', "File name (without) path for the configuration file, default is #{DEFAULT_CONF_FILE}" ) do |conf_file| @options[:conf_file] = conf_file end @options[:log_file] = nil opts.on( '-L', '--logfile FILE', 'Write log to FILE, defaults to STDOUT' ) do|file| @options[:log_file] = file end @options[:file_host] = "config2.gaddygaddy.com" opts.on( '--file_host FILE_HOST', 'The file host to get files like cookbooks from' ) do|file_host| @options[:file_host] = file_host end @options[:host] = "https://www.gaddygaddy.com:8012" opts.on( '-H', '--host HOST', 'The host to connect to' ) do|host| @options[:host] = host end @options[:log_level] = 'info' opts.on( '-l', '--log_level level', 'Set the log level (debug, info, warn, error, fatal)' ) do|level| @options[:log_level] = level end @options[:test_mode] = false opts.on( '--test_mode', 'Used for testing, will only retry once for example' ) do @options[:test_mode] = true end @options[:token] = nil opts.on( '-t', '--token TOKEN', 'The token to be used to access' ) do|token| @options[:token] = token end end add_help_option command :get_cookbooks do |opts| opts.banner = "Usage: get_cookbooks [options]" opts.description = "Will download the cookbooks from the GaddyGaddy service" @options[:chef_dir] = DEFAULT_CHEF_DIR opts.on( '--chef_dir CHEF-DIR', "The chef dir to place the files into, default is #{DEFAULT_CHEF_DIR}" ) do |chef_dir| @options[:chef_dir] = chef_dir end @options[:cookbooks_version] = nil opts.on( '--cookbooks_version COOKBOOKS_VERSION', "Override the setting of which cookbook version to download" ) do |cookbooks_version| @options[:cookbooks_version] = cookbooks_version end end command :chef_config do |opts| opts.banner = "Usage: chef_config [options]" opts.description = "Will download the chef config and place it in a directory" end command :gaddy_file do |opts| opts.banner = "Usage: gaddy_file [options]" opts.description = "Will download the gaddy config and place it in /conf" opts.on("-g", "--gaddy gaddy_name", "Name of gaddy") do |gaddy_name| @options[:gaddy_name] = gaddy_name end opts.on("-u", "--user user_name", "User name") do |user_name| @options[:user_name] = user_name end opts.on("-p", "--password password", "Password") do |password| @options[:password] = password end opts.on("-c", "--create", "Create new gaddy if it doesn't exist") do @options[:create] = true end end command :send_device_data do |opts| opts.banner = "Usage: send_device_data [options]" opts.description = "Will send information about the gaddy to gaddygaddy.com" end command :upload_diagnose_data do |opts| opts.banner = "Usage: upload_diagnose_data[options]" opts.description = "Will upload diagnose data" end command :upload_log_file do |opts| opts.banner = "Usage: upload_log_file[options]" opts.description = "Will upload log files" @options[:lines] = 100 opts.on("-i", "--lines lines", "Number of lines to upload, count from end of file") do |lines| @options[:lines] = lines end opts.on("-f", "--id function_id", "Function id") do |function_id| @options[:function_id] = function_id end @options[:upload_log_file] = nil opts.on("-u", "--upload_log_file upload_log_file", "Name of log file to upload, mandatory") do |upload_log_file| @options[:upload_log_file] = upload_log_file end end command :verify_installation do |opts| opts.banner = "Usage: verify_installation[options]" opts.description = "Will verify the installation and check for gaddy file and network configuration" end command :notify do |opts| opts.banner = "Usage: verify_installation[options]" opts.description = "Will verify the installation and check for gaddy file and network configuration" @options[:event] = nil opts.on("-e", "--event event", "Event to notify, should be json format") do |event| @options[:event] = event end end cmd = nil begin cmd = opt_parse mandatory = [] missing = mandatory.select{ |param| @options[param].nil? } unless missing.empty? puts "Missing options: #{missing.join(', ')}" # puts opt_parse # exit 1 end unless cmd puts "No command is specified\n\n" usage puts print_actions exit 1 end rescue OptionParser::InvalidOption, OptionParser::MissingArgument # puts $!.to_s # Friendly output when parsing fails puts opt_parse # exit 1 # end cmd end
read_settings()
click to toggle source
# File lib/gaddygaddy-client.rb, line 490 def read_settings environment = ENV['RACK_ENV'] || ENV['ENV'] || 'gaddy' YAML.load(File.read(File.join(File.dirname(__FILE__), '..','conf', "#{environment}.yml"))) end
run()
click to toggle source
# File lib/gaddygaddy-client.rb, line 495 def run cmd = read_options settings = read_settings begin Retriable.set_test_mode if @options[:test_mode] @device_info = DeviceInfo.new(get_host, gg_config) set_log_level @options[:log_level] set_log_file @options[:log_file] if @options[:log_file] logger.info "Will start #{APPLICATION_NAME} with command #{cmd}" case cmd when "get_cookbooks" chef_files = ChefFiles.new(gg_config, get_host, @options[:chef_dir]) chef_files.get_cookbooks @options[:file_host], @options[:cookbooks_version] when "chef_config" get_chef_config when 'gaddy_file' gaddy_config(@options[:gaddy_name], @options[:user_name], @options[:password]) when 'send_device_data' send_device_data when "verify_installation" self.class.verify_installation when 'notify' Notification::FileNotification.file_dir = settings['file_dir'] notification = Notification::Send.new(:speech_enabled => settings['speech_enabled']) notification.event = @options[:event] notification.notify gg_config.device_id when 'upload_diagnose_data' upload_diagnose_data when 'upload_log_file' upload_log_file else usage raise "No valid command entered, the command is #{cmd}" end rescue Exception => e logger.error e.message logger.error "Enable full stack trace with -l DEBUG" unless logger.debug? logger.error "Backtrace:\n\t#{e.backtrace.join("\n\t")}" if logger.debug? exit -1 end end
send_device_data()
click to toggle source
Will send ohai device data to gaddygaddy
# File lib/gaddygaddy-client.rb, line 402 def send_device_data @device_info.post end
upload_diagnose_data()
click to toggle source
# File lib/gaddygaddy-client.rb, line 406 def upload_diagnose_data url = Request.get_base_url(get_host) + "/device/upload_diagnose_data/1/#{gg_config.user_id_salt}/#{gg_config.device_id}/#{gg_config.token}" diagnose_data = DiagnoseData.get_all_diag_info params = {:diagnose_data => diagnose_data, :diagnose_time_stamp => Time.now } response = Request.client_service_post url, params logger.debug "The response for the request is #{response} #{response.class}" raise JCouldNotPostClientDataException.new({:message=> "Could not post data to the gaddygaddy service, error code is #{response.body}"}) unless response[:status].to_i == 0 end
upload_log_file()
click to toggle source
# File lib/gaddygaddy-client.rb, line 417 def upload_log_file raise "Missing option upload_log_file" unless @options[:upload_log_file] log_file_name = @options[:upload_log_file].split('/').last log_file_name = log_file_name[0..-5] if log_file_name[-4..-1] == '.log' logger.debug "Log file name is #{log_file_name}" full_log_file_name = @options[:upload_log_file] url = Request.get_base_url(get_host) + "/device/upload_log_file/1/#{gg_config.user_id_salt}/#{gg_config.device_id}/#{gg_config.token}/#{log_file_name}" log_data = LogData.get_log_data(@options[:upload_log_file], @options[:lines]) log_time_stamp = LogData.get_log_file_time(@options[:upload_log_file]) params = {:log_data => log_data, :log_time_stamp => log_time_stamp, :full_log_file_name => full_log_file_name, } params[:function_id] = @options[:function_id] if @options[:function_id] response = Request.client_service_post url, params logger.debug "The response for the request is #{response} #{response.class}" raise JCouldNotPostClientDataException.new({:message=> "Could not post data to the gaddygaddy service, error code is #{response.body}"}) unless response[:status].to_i == 0 end
usage()
click to toggle source
# File lib/gaddygaddy-client.rb, line 59 def usage puts "gaddygaddy-client [OPTIONS]" puts "The client to run for the GaddyGaddy service" puts "For more information about the commands run gaddygaddy-client --help" puts "Revision :#{REVISION}" puts end