class Proxy::DiscoveryImage::PowerApi

Public Instance Methods

download_and_run_after_response(data, seconds, *command) click to toggle source

Variant which also downloads kernel and initramdisk

# File lib/smart_proxy_discovery_image/power_api.rb, line 62
def download_and_run_after_response(data, seconds, *command)
  Thread.start do
    begin
      # download kernel and initramdisk
      downloaded = download_file(data, 'kernel', 'vmlinuz', '/tmp') &&
                     download_file(data, 'initram', 'initrd.img', '/tmp')
      # wait few seconds just in case the download was fast and perform kexec
      # only perform kexec when both locks were available to prevent subsequent request while downloading
      run_after_response(seconds, *command) if downloaded
    rescue Exception => e
      logger.error "Error during command execution: #{e}"
    end
  end
end
download_file(data, kind, name, prefix) click to toggle source
# File lib/smart_proxy_discovery_image/power_api.rb, line 77
def download_file(data, kind, name, prefix)
  return unless data && (url = data[kind])

  logger.debug "Downloading: #{url}"
  download_thread = ::Proxy::HttpDownload.new(url, File.join(prefix, name)).start
  logger.error("#{name} is still downloading, ignored") unless download_thread
  download_success = download_thread.join.zero?
  logger.error("cannot download #{name} for kexec") unless download_success
  download_success
end
run_after_response(seconds, *command) click to toggle source

Execute command in a separate thread after 5 seconds to give the server some time to finish the request. Does not execute via a shell.

# File lib/smart_proxy_discovery_image/power_api.rb, line 42
def run_after_response(seconds, *command)
  Thread.start do
    begin
      logger.debug "Power API scheduling in #{seconds} seconds: #{command.inspect}"
      sleep seconds
      logger.debug "Power API executing: #{command.inspect}"
      if (sudo = which('sudo'))
        status = system(sudo, *command)
      else
        logger.warn "sudo binary was not found"
      end
      # only report errors
      logger.warn "The attempted command failed with code #{$?.exitstatus}" unless status
    rescue Exception => e
      logger.error "Error during command execution: #{e}"
    end
  end
end