Project

General

Profile

Download (2.23 KB) Statistics
| Branch: | Tag: | Revision:
require 'fog'
require 'timeout'

class Foreman::Provision::SSH
attr_reader :template, :uuid, :results, :address, :username, :options

def initialize address, username = "root", options = { }
@username = username
@address = address
@template = options.delete(:template) || raise("must provide a template")
@uuid = options.delete(:uuid) || "#{address}-#{username}"
@options = defaults.merge(options)

initiate_connection!
end

def deploy!
logger.debug "about to upload #{template} to remote system at #{remote_script}"
scp.upload(template, remote_script)
logger.debug "about to execute #{command}"
@results = ssh.run(command)
log_stdout
log_stderr
success?
end

private

def success?
return true if results.empty?
results.map(&:status).compact == [0]
end

def log_stdout
results.each do |r|
r.stdout.split("\n").each { |l| logger.debug l }
end
end

def log_stderr
results.each do |r|
r.stderr.split("\n").each { |l| logger.warn l }
end
end

def remote_script
File.join("/", "tmp", "bootstrap-#{uuid}")
end

def command_prefix
username == "root" ? "" : "sudo "
end

def command
"#{command_prefix} bash -c 'chmod 0701 #{remote_script} && #{command_prefix} #{remote_script}' | tee #{remote_script}.log"
end

def defaults
{
:keys_only => true,
:config => false,
:auth_methods => %w( publickey ),
:compression => "zlib",
:logger => logger,
}
end

def logger
Rails.logger
end

def initiate_connection!
Timeout::timeout(360) do
begin
Timeout::timeout(8) do
ssh.run('pwd')
end
rescue Errno::ECONNREFUSED
logger.debug "Connection refused for #{address}, retrying"
sleep(2)
retry
rescue Errno::EHOSTUNREACH
logger.debug "Host unreachable for #{address}, retrying"
sleep(2)
retry
rescue Timeout::Error
retry
rescue => e
logger.debug "SSH error: #{e.message}\n " + e.backtrace.join("\n ")
end
end
end

def ssh
Fog::SSH.new(address, username, options.merge(:timeout => 4))
end

def scp
Fog::SCP.new(address, username, options)
end

end
    (1-1/1)