Class: Homeseed::Connection

Inherits:
Object
  • Object
show all
Includes:
Logging
Defined in:
lib/homeseed/connection.rb

Instance Method Summary collapse

Methods included from Logging

configure_logger_for, global_level=, #logger, logger_for

Constructor Details

#initialize(params = {}) ⇒ Connection

Returns a new instance of Connection.



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/homeseed/connection.rb', line 5

def initialize(params={})
  raise 'servers and/or user not specified' unless params[:servers] and params[:user]
  @servers = params[:servers].split(',')
  @user = params[:user]

  if params[:has_password]
    cli = HighLine.new
    @password = cli.ask("Enter password: ") { |q| q.echo = false }
  else
    @password = params[:password] || ''
  end

  if params[:logger]
    @logger = params[:logger]
  else
    logger.level = params[:logger_level] || Logger::INFO
  end

  if params[:command]
    @flat_commands = params[:command]
  elsif params[:files]
    @files = params[:files].split(',')
    @flat_commands = ''
    @files.each do |file|
      yml_commands = YAML.load_file(file)
      commands = []
      self.process_hash(commands, '', yml_commands)
      @flat_commands += commands.join('; ') + ';'
    end
  elsif params[:upload_files]
    @remote_path = params[:remote_path] || '/tmp/'
    @upload_files = params[:upload_files].split(',')
  else
    raise 'ERROR command, files or upload_files not specified'
  end
end

Instance Method Details

#process_hash(commands, current_key, obj) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/homeseed/connection.rb', line 42

def process_hash(commands, current_key, obj)
  if obj.is_a?(Hash)
    obj.each do |new_key, value|
      combined_key = [current_key, new_key].delete_if { |k| k == '' }.join(" ")
      process_hash(commands, combined_key, value)
    end
  else obj.is_a?(Array)
    obj.each do |value|
      combined_key = [current_key, value].delete_if { |k| k == '' }.join(" ")
      commands << combined_key
    end
  end
end

#scp_uploadObject



103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/homeseed/connection.rb', line 103

def scp_upload
  @servers.each do |server|
    @upload_files.each do |upload_file|
      logger.info "starting scp #{upload_file} #{@user}@#{server}:#{@remote_path}"
      begin
        Net::SCP.start(server, @user) { |scp| scp.upload!(upload_file, @remote_path) }
        logger.info "finished scp #{upload_file} #{@user}@#{server}:#{@remote_path}"
      rescue => err
        logger.error "scp FAILED #{err}"
      end
    end
  end
end

#ssh_execObject



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/homeseed/connection.rb', line 56

def ssh_exec
  Hash[@servers.map do |server|
    logger.info "ssh #{@user}@#{server} exec: #{@flat_commands}"

    exit_status = nil
    exit_signal = nil

    Net::SSH.start(server, @user, password: @password) do |ssh|
      ssh.open_channel do |channel|
        channel.exec("bash -l") do |ch,success|
          ch.send_data "#{@flat_commands}\n"
          ch.on_data do |c,data|
            data_lines = data.split(/[\r,\n]/)
            data_lines.each do |data_line|
              logger.info data_line unless data_line == ''
            end
          end

          ch.on_extended_data do |c,type,data|
            data_lines = data.split(/[\r,\n]/)
            data_lines.each do |data_line|
              unless data_line == ''
                if data_line.match(/error|failed/i)
                  logger.error data_line
                else
                  logger.info data_line
                end
              end
            end
          end

          ch.on_request("exit-status") do |c,data|
            exit_status = data.read_long
          end

          ch.on_request("exit-signal") do |c,data|
            exit_signal = data.read_long
          end

          ch.send_data "exit\n"
        end
      end
    end
    [server, { exit_status: exit_status, exit_signal: exit_signal }]
  end]
end