Class: SSHKit::Backend::Netssh

Inherits:
Object
  • Object
show all
Defined in:
lib/sshkit/getters.rb,
lib/sshkit/helpers.rb,
lib/cheftacular/actions/log.rb,
lib/cheftacular/actions/check.rb,
lib/sshkit/actions/start_task.rb,
lib/cheftacular/actions/deploy.rb,
lib/cheftacular/actions/backups.rb,
lib/cheftacular/stateless_actions/rvm.rb,
lib/cheftacular/stateless_actions/file.rb,
lib/cheftacular/stateless_actions/service.rb,
lib/cheftacular/stateless_actions/chef_server.rb,
lib/cheftacular/stateless_actions/disk_report.rb,
lib/cheftacular/stateless_actions/restart_swap.rb,
lib/cheftacular/stateless_actions/server_update.rb,
lib/cheftacular/stateless_actions/get_haproxy_log.rb,
lib/cheftacular/stateless_actions/replication_status.rb,
lib/cheftacular/stateless_actions/get_active_ssh_connections.rb

Instance Method Summary collapse

Instance Method Details

#backup_gem_dir_sort(password, cheftacular, base_dir) ⇒ Object



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/cheftacular/actions/backups.rb', line 260

def backup_gem_dir_sort password, cheftacular, base_dir
  timestamp_dirs, check_dirs, target_dir = [], [], ''

  dirs = sudo_capture( password, :ls, base_dir )

  dirs.split(' ').each do |timestamp_dir|
    next if timestamp_dir == '.' || timestamp_dir == '..'

    timestamp_dirs << timestamp_dir
  end

  timestamp_dirs.each do |dir|
    if check_dirs.empty?
      check_dirs << dir
      target_dir  = dir
    else
      check_dirs.each do |cdir|
        target_dir = dir if Date.parse(dir) >= Date.parse(target_dir)
      end
    end
  end

  target_file = sudo_capture( password, :ls, File.join(base_dir, target_dir) ).split(' ').last

  [ target_dir, target_file ]
end

#get_node_from_address(nodes, address, ret_node = nil) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
# File 'lib/sshkit/getters.rb', line 28

def get_node_from_address nodes, address, ret_node=nil
  nodes.each do |n|
    if n.public_ipaddress == address
      ret_node = n

      break
    end
  end

  ret_node
end

#get_override_environment(repo_hash, default_env) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/sshkit/getters.rb', line 78

def get_override_environment repo_hash, default_env
  repo_hash['db_env_node_bypass'].each_pair do |original_env, original_env_hash|
    next if default_env != original_env

    default_env = original_env_hash['environment_to_bypass_into']

    break
  end

  default_env
end

#get_repository_from_role_name(name, repositories, *args) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/sshkit/getters.rb', line 4

def get_repository_from_role_name name, repositories, *args
  args = args.flatten

  repo_role_name = ""

  repositories.each_pair { |key, repo_hash| repo_role_name = key if repo_hash['repo_name'] == name }

  if repositories.has_key?(name) && ( args.empty? || args.include?('do_not_raise_on_unknown') )
    return repositories[name]['repo_name']
  elsif !repo_role_name.empty? && ( args.empty? || args.include?('do_not_raise_on_unknown') )
    return repo_role_name
  end

  if args.include?('has_key?')
    return repositories.has_key?(name)
  elsif args.include?('has_value?')
    return !repo_role_name.empty?
  end

  raise "Unknown repository or rolename for #{ name }" unless args.include?('do_not_raise_on_unknown')

  nil
end

#get_role_map(cheftacular, target_role, ret = "") ⇒ Object



62
63
64
65
66
67
68
# File 'lib/sshkit/getters.rb', line 62

def get_role_map cheftacular, target_role, ret=""
  cheftacular['role_maps'].each_pair do |main_role, role_hash|
    ret = role_hash if role_hash['role_name'] == target_role
  end

  ret
end

#get_server_hash_from_address(array_of_server_hashes, address, ret_hash = nil) ⇒ Object



70
71
72
73
74
75
76
# File 'lib/sshkit/getters.rb', line 70

def get_server_hash_from_address array_of_server_hashes, address, ret_hash=nil
  array_of_server_hashes.each do |server_hash|
    ret_hash = server_hash if server_hash['address'] == address
  end

  ret_hash
end

#get_true_environment(run_list, chef_env_roles, default_env) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/sshkit/getters.rb', line 40

def get_true_environment run_list, chef_env_roles, default_env
  unless chef_env_roles.nil?
    chef_env_roles.each_pair do |role, env|
      if run_list.include?("role[#{ role }]")
        default_env = env

        break
      end
    end
  end

  default_env
end

#get_worker_role(cheftacular, ret = "") ⇒ Object



54
55
56
57
58
59
60
# File 'lib/sshkit/getters.rb', line 54

def get_worker_role cheftacular, ret=""
  cheftacular['role_maps'].each_pair do |main_role, role_hash|
    ret = role_hash['role_name'] if main_role.include?('worker')
  end

  ret
end

#has_run_list_in_role_map?(run_list, role_map_hash) ⇒ Boolean

Returns:

  • (Boolean)


20
21
22
23
24
25
26
# File 'lib/sshkit/helpers.rb', line 20

def has_run_list_in_role_map? run_list, role_map_hash
  role_map_hash.each_value do |map_hash|
    return true if run_list.include?("role[#{ map_hash['role_name'] }]")
  end

  false
end

#set_log_loc_and_timestamp(locs) ⇒ Object



4
5
6
# File 'lib/sshkit/helpers.rb', line 4

def set_log_loc_and_timestamp locs
  [locs['chef-log'], Time.now.strftime("%Y%m%d%H%M%S")]
end

#start_apt_updater(name, ip_address, options, locs, passwords, out = "") ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/cheftacular/stateless_actions/server_update.rb', line 70

def start_apt_updater name, ip_address, options, locs, passwords, out=""
  log_loc, timestamp = set_log_loc_and_timestamp(locs)

  puts("Generating apt-get log file for #{ name } (#{ ip_address }) at #{ log_loc }/#{ name }-upgrade-#{ timestamp }.txt") unless options['quiet']

  out << sudo_capture( passwords[ip_address], 'apt-get', 'update' )
  out << sudo_capture( passwords[ip_address], 'apt-get', 'upgrade', '-y', '-o' 'Dpkg::Options::="--force-confnew"' )

  puts(out) if options['output'] || options['verbose']

  ::File.open("#{ log_loc }/server-update/#{ name }-apt-update-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) } unless options['no_logs']

  puts "Succeeded upgrade of #{ name } (#{ ip_address })"

  [out, timestamp] #return out to send to logs_bag
end

#start_chef_server_interactor(command, options, out = "") ⇒ Object



74
75
76
77
78
# File 'lib/cheftacular/stateless_actions/chef_server.rb', line 74

def start_chef_server_interactor command, options, out=""
  puts capture( command )

  puts "Succeeded chef-server interaction run" unless options['quiet']
end

#start_command_run(name, ip_address, options, locs, passwords, cheftacular, command, location, file_name, out = "", exit_status = true) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/cheftacular/stateless_actions/file.rb', line 145

def start_command_run name, ip_address, options, locs, passwords, cheftacular, command, location, file_name, out="", exit_status=true
  log_loc, timestamp = set_log_loc_and_timestamp(locs)
  run_list_command   = command == 'list'
  target_loc = "#{ location }/#{ file_name }"

  if !sudo_test( passwords[ip_address], location ) #true if file exists
    puts "#{ name } (#{ ip_address }) cannot run #{ command } as there is no directory at #{ location }!"

    return false
  end

  if !run_list_command && !sudo_test( passwords[ip_address], target_loc ) #true if file exists
    puts "#{ name } (#{ ip_address }) cannot run #{ command } as there is no file at #{ location }/#{ file_name }! Running list instead..."

    exit_status = false

    run_list_command = true
  end

  return exit_status if command == 'check_existence'

  if run_list_command
    out << sudo_capture( passwords[ip_address], :ls, '-al', location )
  else
    puts "Running #{ command } on #{ target_loc }"
    out << sudo_capture( passwords[ip_address], command, target_loc)
  end

  if options['save_to_file']
    out_location = "#{ log_loc }/#{ options['save_to_file'] }"

    puts "Saving output of file at #{ out_location } }..."

    ::File.open(out_location, "w") { |f| f.write(out) }
  end

  puts out.scrub_pretty_text unless options['save_to_file']

  puts("Succeeded run of \"#{ command }\" for #{ name } (#{ ip_address })") unless run_list_command

  exit_status
end

#start_commit_check(name, ip_address, options, locs, cheftacular, passwords, out = {'name'=>'', 'time'=> ''}) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/cheftacular/actions/check.rb', line 104

def start_commit_check name, ip_address, options, locs, cheftacular, passwords, out={'name'=>'', 'time'=> ''}
  app_loc = "#{ cheftacular['base_file_path'] }/#{ options['repository'] }/releases"
  
  if test("[ -d #{ app_loc } ]") #true if file exists
    within app_loc do
      out['name'] = capture( :ls, '-rt', :|, :tail, '-1' )

      out['time'] = Time.parse(capture( :stat, out['name'], '--printf=%y' )).strftime('%Y-%m-%d %I:%M:%S %p')
    end
  else
    return nil
  end

  out
end

#start_connection_report(name, ip_address, options, locs, passwords, out = []) ⇒ Object



44
45
46
47
48
49
50
51
# File 'lib/cheftacular/stateless_actions/get_active_ssh_connections.rb', line 44

def start_connection_report name, ip_address, options, locs, passwords, out=[]

  out << capture( :netstat, '-atn', :|, :grep, ':22' )

  puts(out.join("\n")) if options['output'] || options['verbose']

  out
end

#start_db_backup_fetch(name, ip_address, options, locs, cheftacular, passwords, backup_master_local_ip, backup_hash, out = []) ⇒ Object



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/cheftacular/actions/backups.rb', line 219

def start_db_backup_fetch name, ip_address, options, locs, cheftacular, passwords, backup_master_local_ip, backup_hash, out=[]
  full_backup_dir  = File.join(cheftacular['backup_config']['db_primary_backup_path'], backup_hash['file_dir'])
  full_backup_path = File.join(full_backup_dir, backup_hash['filename'])

  if sudo_test( passwords[ip_address], full_backup_path ) #true if dir exists
    puts "#{ name } (#{ ip_address }) already has the backup at #{ full_backup_path }, skipping #{ __method__ }..."

    return true
  end

  sudo_execute( passwords[ip_address], :mkdir, '-p', full_backup_dir )

  sudo_execute( passwords[ip_address], :chown, "#{ cheftacular['deploy_user'] }:#{ cheftacular['deploy_user'] }", full_backup_dir )

  sudo_execute( passwords[ip_address], :chmod, cheftacular['backup_config']['backup_dir_mode'], full_backup_dir )

  execute( :scp, '-oStrictHostKeyChecking=no', "#{ cheftacular['deploy_user'] }@#{ backup_master_local_ip }:#{ backup_hash['backup_master_path'] }", full_backup_path )

  puts "Finished transferring #{ full_backup_path } to #{ name }(#{ ip_address })..."
end

#start_db_backup_restore(name, ip_address, options, locs, cheftacular, passwords, applications_as_string, env_db_pass, ruby_command, env_db_mode, env_db_user, out = '') ⇒ Object



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/cheftacular/actions/backups.rb', line 240

def start_db_backup_restore name, ip_address, options, locs, cheftacular, passwords, applications_as_string, env_db_pass, ruby_command, env_db_mode, env_db_user, out=''
  log_loc, timestamp = set_log_loc_and_timestamp(locs)

  puts "Beginning backup run on #{ name } (#{ ip_address }), this command may take a while to complete..."

  case cheftacular['backup_filesystem']
  when 'backup_gem'
    command = cheftacular['backup_config']['backup_load_command']
    command = command.gsub('ENVIRONMENT', options['env']).gsub('APPLICATIONS', applications_as_string).gsub('DB_PASS', env_db_pass)
    command = command.gsub('RUBY_COMMAND', ruby_command ).gsub('MODE', env_db_mode).gsub('DATABASE_USER', env_db_user)

    out << sudo_capture( passwords[ip_address], command )
  when 'raw'
  end

  ::File.open("#{ log_loc }/#{ name }-backup-restore-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) } unless options['no_logs']

  puts "Finished executing backup command on #{ name } (#{ ip_address }). Wrote logs to #{ log_loc }/#{ name }-backup-restore-#{ timestamp }.txt"
end

#start_db_check_and_fetch(name, ip_address, options, locs, cheftacular, passwords, out = [], return_hash = { 'file_check' => false }) ⇒ Object



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/cheftacular/actions/backups.rb', line 186

def start_db_check_and_fetch name, ip_address, options, locs, cheftacular, passwords, out=[], return_hash={ 'file_check' => false }
  base_dir = cheftacular['backup_config']['global_backup_path']

  if !sudo_test( passwords[ip_address], base_dir ) #true if dir exists
    puts "#{ name } (#{ ip_address }) cannot run #{ __method__ } as there is no directory at #{ base_dir }!"

    return return_hash
  end

  target_dir = case cheftacular['backup_filesystem']
               when 'backup_gem'
                 backup_gem_dir_sort passwords[ip_address], cheftacular, base_dir
               when 'raw'
                 File.join( base_dir, sudo_capture( passwords[ip_address], :ls, base_dir ).split(' ').last )
               else
                 raise "#{ __method__ } does not currently support the #{ cheftacular['backup_filesystem'] } backup strategy at this time"
               end

  return_hash['file_check'] = true
  return_hash['filename']   = [target_dir].flatten.last
  return_hash['file_dir']   = case cheftacular['backup_filesystem']
                              when 'backup_gem' then target_dir.first
                              when 'raw'        then base_dir
                              end

  return_hash['backup_master_path'] = case cheftacular['backup_filesystem']
                                      when 'backup_gem' then File.join(base_dir, return_hash['file_dir'], return_hash['filename'])
                                      when 'raw'        then File.join(base_dir, return_hash['filename'])
                                      end

  return_hash
end

#start_deploy(name, ip_address, options, locs, passwords, out = "") ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/cheftacular/actions/deploy.rb', line 107

def start_deploy name, ip_address, options, locs, passwords, out=""
  log_loc, timestamp = set_log_loc_and_timestamp(locs)

  puts "Generating log file for #{ name } (#{ ip_address }) at #{ log_loc }/deploy/#{ name }-deploy-#{ timestamp }.txt"

  capture_args = [ "chef-client" ]
  capture_args << [ '-l', 'debug' ] if options['debug']
  #capture_args << [ '>', '/dev/tty']

  out << sudo_capture( passwords[ip_address], *capture_args.flatten )

  ::File.open("#{ log_loc }/deploy/#{ name }-deploy-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) } unless options['no_logs']

  puts(out) if options['output'] || options['verbose']

  puts "Succeeded deploy of #{ name } (#{ ip_address }) on role #{ options['role'] }"

  ['Successful Deploy', timestamp, 0] #return out to send to logs_bag
rescue SSHKit::Command::Failed => e
  puts "@@@@@CRITICAL! Deploy failed for #{ name } (#{ ip_address })! Please check your #{ log_loc }/failed-deploy for the logs!@@@@@"

  puts(e.message) if options['verbose']

  lines = e.message.split("\n").last(100).join("\n")

  ::File.open("#{ log_loc }/failed-deploy/#{ name }-deploy-#{ timestamp }.txt", "w") { |f| f.write(e.message.scrub_pretty_text) }

  [lines, timestamp, 1]
end

#start_disk_report(name, ip_address, options, locs, passwords, out = []) ⇒ Object



46
47
48
49
50
51
52
53
54
55
# File 'lib/cheftacular/stateless_actions/disk_report.rb', line 46

def start_disk_report name, ip_address, options, locs, passwords, out=[]

  out << sudo_capture( passwords[ip_address], :free, '-m' )
  out << "\n"
  out << sudo_capture( passwords[ip_address], :df, '-aTh' )

  puts(out.join("\n")) if options['output'] || options['verbose']

  out
end

#start_haproxy_log_generator(name, ip_address, options, locs, cheftacular, passwords, out = []) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
# File 'lib/cheftacular/stateless_actions/get_haproxy_log.rb', line 45

def start_haproxy_log_generator name, ip_address, options, locs, cheftacular, passwords, out=[]
  log_loc, timestamp = set_log_loc_and_timestamp(locs)

  puts("Generating log file for haproxy for #{ name } (#{ ip_address }) at #{ log_loc }/#{ name }-haproxy-#{ timestamp }.html") unless options['quiet']

  out << sudo_capture( passwords[ip_address], :curl, "localhost:#{ cheftacular['haproxy_config']['default_port'] }" )

  ::File.open("#{ log_loc }/#{ name }-haproxy-#{ timestamp }.html", "w") { |f| f.write(out.join("\n").scrub_pretty_text.gsub('[sudo] password for deploy: ', '')) } unless options['no_logs']
        
  puts(out) if options['output'] || options['verbose']
end

#start_log_fetch_nginx(name, log_loc, log_cmnd, timestamp, options, out = "") ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/cheftacular/actions/log.rb', line 116

def start_log_fetch_nginx name, log_loc, log_cmnd, timestamp, options, out=""
  out = "" unless options['no_logs']
  log_cmnd, log_lines = get_log_command_and_lines(options)

  nginx_log_loc = "/var/log/nginx/#{ options['repository'] }_access.log"

  puts "Fetching nginx log file... Outputting to #{ log_loc }/applog/#{ name }-nginxlog-#{ timestamp }.txt "

  if log_lines.nil?
    out << capture(log_cmnd.to_sym, nginx_log_loc)

  else 
    out << capture(log_cmnd.to_sym, log_lines, nginx_log_loc)
  end

  ::File.open("#{ log_loc }/applog/#{ name }-nginxlog-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) } unless options['no_logs']

  out
end

#start_log_fetch_ruby_on_rails(name, ip_address, run_list, options, locs, cheftacular, passwords, out = "") ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/cheftacular/actions/log.rb', line 82

def start_log_fetch_ruby_on_rails name, ip_address, run_list, options, locs, cheftacular, passwords, out=""
  log_loc, timestamp  = set_log_loc_and_timestamp(locs)
  true_env            = get_true_environment run_list, cheftacular['run_list_environments'][options['env']], options['env']
  true_env            = get_override_environment cheftacular['repositories'][options['role']], options['env']
  app_log_loc         = "#{ cheftacular['base_file_path'] }/#{ options['repository'] }/current/log"
  log_cmnd, log_lines = get_log_command_and_lines(options)

  if !test("[ -e /#{ app_log_loc }/#{ true_env }.log ]") #true if file exists
    puts "#{ name } (#{ ip_address }) does not have a log file for #{ true_env } at the moment..."

  else

    puts "Fetching log file(s) for #{ name } (#{ ip_address }). Outputting to #{ log_loc }/applog/#{ name }-applog-#{ timestamp }.txt"

    within app_log_loc do
      if log_lines.nil?
        out << capture(log_cmnd.to_sym, "#{ true_env }.log")

      else
        out << capture(log_cmnd.to_sym, log_lines, "#{ true_env }.log")
      end
    end

    #To create the file locally you must namespace like this
    ::File.open("#{ log_loc }/applog/#{ name }-applog-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) } unless options['no_logs']
  end

  out << start_log_fetch_nginx(name, log_loc, log_cmnd, timestamp, options, out) if run_list.include?('role[web]') && options['get_nginx_logs']
  
  out << start_log_role_map(name, ip_address, get_role_map(cheftacular, get_worker_role(cheftacular))['log_location'], log_cmnd, app_log_loc, timestamp, options) if run_list.include?("role[#{ get_worker_role(cheftacular) }]")

  puts(out) if options['verbose']
end

#start_log_role_map(name, ip_address, target_log_loc, options, locs, cheftacular, passwords, out = "") ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/cheftacular/actions/log.rb', line 57

def start_log_role_map name, ip_address, target_log_loc, options, locs, cheftacular, passwords, out=""
  log_loc, timestamp  = set_log_loc_and_timestamp(locs)
  log_cmnd, log_lines = get_log_command_and_lines(options)

  
  puts "Fetching log file(s) for #{ name } (#{ ip_address }). Outputting to #{ log_loc }/rolelog with timestamp: #{ timestamp }"

  target_log_loc.split(',').each do |parsed_log_loc|
    parsed_log_loc = parsed_log_loc.gsub('|current_repo_location|', "#{ cheftacular['base_file_path'] }/#{ options['repository'] }/current")

    if parsed_log_loc != '/var/log/syslog' && !test("[ -e #{ parsed_log_loc }]") #true if file exists ()
      puts "#{ name } (#{ ip_address }) does not have a #{ parsed_log_loc } log file for #{ options['env'] } at the moment..."
    else
      if log_lines.nil?
        out << sudo_capture(passwords[ip_address], log_cmnd.to_sym, parsed_log_loc)

      else
        out << sudo_capture(passwords[ip_address], log_cmnd.to_sym, log_lines, parsed_log_loc)
      end

      ::File.open("#{ log_loc }/rolelog/#{ name }-#{ parsed_log_loc.split('/').last.split('.').first }-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) } unless options['no_logs']
    end
  end
end

#start_replication_report(name, ip_address, options, locs, passwords, out = []) ⇒ Object



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
# File 'lib/cheftacular/stateless_actions/replication_status.rb', line 72

def start_replication_report name, ip_address, options, locs, passwords, out=[]

  psql_commands = [
    "select client_addr, state, sent_location, write_location, flush_location, replay_location, sync_priority from pg_stat_replication;",
    %{
      SELECT
          client_addr,
          sent_offset - (
              replay_offset - (sent_xlog - replay_xlog) * 255 * 16 ^ 6 ) AS byte_lag
      FROM (
          SELECT
              client_addr,
              ('x' || lpad(split_part(sent_location,   '/', 1), 8, '0'))::bit(32)::bigint AS sent_xlog,
              ('x' || lpad(split_part(replay_location, '/', 1), 8, '0'))::bit(32)::bigint AS replay_xlog,
              ('x' || lpad(split_part(sent_location,   '/', 2), 8, '0'))::bit(32)::bigint AS sent_offset,
              ('x' || lpad(split_part(replay_location, '/', 2), 8, '0'))::bit(32)::bigint AS replay_offset
          FROM pg_stat_replication
      ) AS s;
    } #http://www.dansketcher.com/2013/01/27/monitoring-postgresql-streaming-replication/
  ]

  psql_commands.each do |cmnd|
    out << sudo_capture( passwords[ip_address], :sudo, "su", "-", "postgres", "-c \"psql -c \\\"#{ cmnd }\\\"\"" )
  end

  out
end

#start_rvm(name, ip_address, options, locs, passwords, command, cheftacular, out = "") ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/cheftacular/stateless_actions/rvm.rb', line 85

def start_rvm name, ip_address, options, locs, passwords, command, cheftacular, out=""
  log_loc, timestamp = set_log_loc_and_timestamp(locs)
  upgrade_rvm        = command.include?('get stable')
  rvm_location       = "/home/#{ cheftacular['deploy_user'] }/.rvm/bin/rvm"

  puts "Generating rvm log file for #{ name } (#{ ip_address }) at #{ log_loc }/rvm/#{ name }-rvm-#{ timestamp }.txt"


  if !test("[ -e /home/#{ cheftacular['deploy_user'] }/.rvm/bin/rvm ]") #true if file exists
    puts "#{ name } (#{ ip_address }) does not have a rvm bin command at the moment! Updating installation to latest..."

    upgrade_rvm = true
  end

  if upgrade_rvm
    out << sudo_capture( passwords[ip_address], :chown, "#{ cheftacular['deploy_user'] }:root", '-R', "/home/#{ cheftacular['deploy_user'] }/.gnupg")

    out << capture( :gpg, '--keyserver hkp://keys.gnupg.net', "--recv-keys #{ cheftacular['rvm_gpg_key'] }")

    rvm_location = "/home/#{ cheftacular['deploy_user'] }/.rvm/.rvm/bin/rvm" if test("[ -e /home/#{ cheftacular['deploy_user'] }/.rvm/.rvm/bin/rvm ]")
  end

  out << capture( rvm_location, command )

  ::File.open("#{ log_loc }/rvm/#{ name }-rvm-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) } unless options['no_logs']

  puts(out.scrub_pretty_text) if options['output'] || options['verbose']

  puts "Succeeded run of \"rvm #{ command }\" for #{ name } (#{ ip_address })"
end

#start_service_run(name, ip_address, options, locs, passwords, command, cheftacular, service_location, out = "") ⇒ Object



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
# File 'lib/cheftacular/stateless_actions/service.rb', line 61

def start_service_run name, ip_address, options, locs, passwords, command, cheftacular, service_location, out=""
  log_loc, timestamp = set_log_loc_and_timestamp(locs)
  run_list_command   = command == 'list'

  #puts "Generating service run log file for #{ name } (#{ ip_address }) at #{ log_loc }/rolelog/#{ name }-service-#{ timestamp }.txt"

  #TODO check other locations for services!
  if !run_list_command && !sudo_test( passwords[ip_address], "/etc/init/#{ service_location }" ) #true if file exists
    puts "#{ name } (#{ ip_address }) cannot run #{ command } as it's .conf file does not exist! Running list instead..."

    run_list_command = true
  end

  if run_list_command
    out << capture( :ls, '-al', '/etc/init' ) 
  else
    out << sudo_capture( passwords[ip_address], 'service', command)
  end

  #::File.open("#{ log_loc }/rolelog/#{ name }-service-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) } unless options['no_logs']

  puts out.scrub_pretty_text

  puts "Succeeded run of \"service #{ command }\" for #{ name } (#{ ip_address })"
end

#start_slave_replication_report(name, ip_address, options, locs, passwords, out = []) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/cheftacular/stateless_actions/replication_status.rb', line 100

def start_slave_replication_report name, ip_address, options, locs, passwords, out=[]

  psql_commands = [
    "select now() - pg_last_xact_replay_timestamp() AS replication_delay;",
  ]

  begin
    psql_commands.each do |cmnd|
      out << sudo_capture( passwords[ip_address], :sudo, "su", "-", "postgres", "-c \"psql -c \\\"#{ cmnd }\\\"\"" )
    end
  rescue StandardError => e
    out << "This slave database is still setting up its replication! The current status of its process is:"
    out << capture( :ps, :aux, :|, :grep, :startup, :|, :grep, '-v', :grep)
    out << "The reason for the failure was: #{ e }"
  end

  out
end

#start_swap_restart(name, ip_address, options, locs, cheftacular, passwords, out = []) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/cheftacular/stateless_actions/restart_swap.rb', line 43

def start_swap_restart name, ip_address, options, locs, cheftacular, passwords, out=[]

  if test("[ -e #{ cheftacular['default_swap_location'] } ]") #true if file exists
    check = capture( :cat, '/proc/swaps' )

    out << sudo_capture( options['pass'][ip_address], :swapon, cheftacular['default_swap_location'] ) unless check.include?(cheftacular['default_swap_location'])

    puts(out.join("\n")) if options['output'] || options['verbose']
  else
    puts "Node #{ name } (#{ ip_address }) has not had swap initialized! Skipping..."
  end
end

#start_sys_restarter(name, ip_address, options, locs, passwords, out = "") ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/cheftacular/stateless_actions/server_update.rb', line 87

def start_sys_restarter name, ip_address, options, locs, passwords, out=""
  log_loc, timestamp = set_log_loc_and_timestamp(locs)

  out << sudo_capture( passwords[ip_address], 'shutdown', '1', '-r' )

  ::File.open("#{ log_loc }/server-update/#{ name }-upgrade-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) }

  puts(out) if options['output'] || options['verbose']

  puts "Succeeded restart of #{ name } (#{ ip_address })"

  [out, timestamp] #return out to send to logs_bag
end

#start_task(name, ip_address, run_list, command, options, locs, cheftacular, passwords, sudo = false, out = "") ⇒ Object



4
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
41
42
43
44
# File 'lib/sshkit/actions/start_task.rb', line 4

def start_task name, ip_address, run_list, command, options, locs, cheftacular, passwords, sudo=false, out=""
  log_loc, timestamp = set_log_loc_and_timestamp(locs)
  true_env = get_true_environment run_list, cheftacular['run_list_environments'][options['env']], options['env']
  true_env = get_override_environment cheftacular['repositories'][options['role']], options['env']

  puts "Running #{ command } for #{ name } (#{ ip_address }) (Run with with --debug to generate a log as well)"

  target_loc = "#{ cheftacular['base_file_path'] }/#{ options['repository'] }/current"

  if !sudo_test( passwords[ip_address], target_loc )
    puts "#{ name } (#{ ip_address }) cannot run #{ command } as there is no directory at #{ target_loc }!"

    return ['', timestamp]
  end

  capture_args =  []
  capture_args << ["RAILS_ENV=#{ true_env }"] if cheftacular['repositories'][options['role']]['stack'] == 'ruby_on_rails'
  capture_args << command.split(' ')

  within target_loc do
    out << (sudo ? sudo_capture(passwords[ip_address], *capture_args.flatten) : capture( *capture_args.flatten ))
  end

  ::File.open("#{ log_loc }/#{ name }-task-#{ timestamp }.txt", "w") {|f| f.write(out.scrub_pretty_text) } if options['debug']
  
  puts out

  if out.empty? || ( cheftacular['repositories'][options['role']].has_key?('not_a_migration_message') && out == cheftacular['repositories'][options['role']]['not_a_migration_message'] )
    puts("Nothing to migrate for #{ options['role'] }...")
  end

  [out, timestamp, 0] #return out to send to logs_bag
rescue SSHKit::Command::Failed => e
  puts "@@@@@CRITICAL! #{ command } failed for #{ name } (#{ ip_address })! Please check your #{ log_loc }/failed-deploy for the logs!@@@@@"

  puts(e.message)

  ::File.open("#{ log_loc }/failed-deploy/#{ name }-task-#{ timestamp }.txt", "w") { |f| f.write(e.message.scrub_pretty_text) }

  [e.message, timestamp, 1]
end

#sudo_capture(pass, *args) ⇒ Object



8
9
10
# File 'lib/sshkit/helpers.rb', line 8

def sudo_capture pass, *args
  capture :echo, pass, :|, :sudo, '-S', *args
end

#sudo_execute(pass, *args) ⇒ Object



12
13
14
# File 'lib/sshkit/helpers.rb', line 12

def sudo_execute pass, *args
  execute :echo, pass, :|, :sudo, '-S', *args
end

#sudo_test(pass, file_location) ⇒ Object



16
17
18
# File 'lib/sshkit/helpers.rb', line 16

def sudo_test pass, file_location
  sudo_capture( pass, :test, '-e', file_location, '&&', :echo, 'true', { raise_on_non_zero_exit: false, verbosity: Logger::DEBUG }) == 'true'
end