cheftacular 2.15.2 → 2.15.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 05f90c2978ae89eb69550b45a8784c274b114fe9
4
- data.tar.gz: 6406c670ac6daf9b05d7852f655678d001f1007d
3
+ metadata.gz: ca73f1c5b5983aa8a6c458af1b3dca0cfce09d1b
4
+ data.tar.gz: 53377d874c956a367e8fb60ee0c78430b535ea62
5
5
  SHA512:
6
- metadata.gz: 7067830d11b95fad95e141022d575d94697bac18a72b96b2d44de035cb02808e3a38532237cccde2ac77dd77f8f6d05ff228db5819d5d73b9528db403a27d4d2
7
- data.tar.gz: 887a72065e1ace867ed8fcb7fd6fca9fde90d282a67907f517bc98b9544ff90ee57bc4c1defd9a811a22ca5cab6a659ba979045f55dced0bc5363882b5deb382
6
+ metadata.gz: 49e6ccedb14b9b42b96c1f269b45220c0249a4fabe9d440dd871b782d29ba9d78b83c8bf968c8da474b7c5df07db89c7a32625d699986008ab16e56cae66b62d
7
+ data.tar.gz: 79d8c50bff33e56277018e7a5b5ca4fc68ab73ecbe5beea639e01a7690291c78effd316ca49e9eda4703a6cd78c41d852a9c7b708a8e056b8f898596c1510c78
@@ -0,0 +1,50 @@
1
+
2
+ class Cheftacular
3
+ class StatelessActionDocumentation
4
+ def application
5
+ @config['documentation']['stateless_action'][__method__] ||= {}
6
+ @config['documentation']['stateless_action'][__method__]['long_description'] = [
7
+ "`cft application boot|boot_without_deploy|destroy|destroy_raw_servers [SERVER_NAMES]` will boot / destroy the servers for current repository you are connected to",
8
+
9
+ [
10
+ " 1. `boot` will spin up servers and bring them to a stable state. " +
11
+ "This includes setting up their subdomains for the target environment.",
12
+
13
+ " 2. `destroy` will destroy all servers needed for the target environment",
14
+
15
+ " 3. `destroy_raw_servers` will destroy the servers without destroying the node data.",
16
+
17
+ " 4. `boot_without_deploy` will spin up servers and bring them to a state where they are ready to be deployed",
18
+
19
+ " 5. This command will prompt when attempting to destroy servers in staging or production. " +
20
+ "Additionally, only devops clients will be able to destroy servers in those environments.",
21
+
22
+ " 6. This command also accepts a *comma delimited list* of server names to boot / destroy instead of all the stored ones for an environment.",
23
+
24
+ " 7. This command works with all the flags that `cft deploy` works with, like -Z -z -O and so on.",
25
+
26
+ " 8. Aliased to `cft a` and `cft app`"
27
+ ]
28
+ ]
29
+
30
+ @config['documentation']['stateless_action'][__method__]['short_description'] = 'Boots (or destroys) an application based on data stored in cheftacular.yml'
31
+
32
+ @config['documentation']['application'][__method__] = @config['documentation']['stateless_action'][__method__]
33
+ end
34
+ end
35
+
36
+ class StatelessAction
37
+ def application type='boot'
38
+ type = ARGV[1] if ARGV[1]
39
+
40
+ unless (type =~ /boot|destroy|destroy_raw_servers|boot_without_deploy/) == 0
41
+ raise "Unknown type: #{ type }, can only be 'boot'/'boot_without_deploy'/'destroy'/'destroy_raw_servers'"
42
+ end
43
+
44
+ @config['stateless_action'].environment(type, true)
45
+ end
46
+
47
+ alias_method :a, :application
48
+ alias_method :app, :application
49
+ end
50
+ end
@@ -26,23 +26,14 @@ class Cheftacular
26
26
  #must have rails stack to run migrations, only want ONE node
27
27
  nodes = @config['parser'].exclude_nodes(nodes, [{ unless: "role[#{ @options['role'] }]" }, { unless: 'role[rails]' }], true)
28
28
 
29
- log_data = ""
29
+ logs_bag_hash = run_ruby_on_rails('rake db:migrate', __method__.to_s, ['return_logs_bag_hash'], nodes)
30
30
 
31
- #this must always precede on () calls so they have the instance variables they need
32
- options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
31
+ if logs_bag_hash["#{ nodes.first.name }-#{ __method__ }"]['text'].empty? ||
32
+ ( cheftacular['repositories'][options['role']].has_key?('not_a_migration_message') && logs_bag_hash["#{ nodes.first.name }-#{ __method__ }"]['text'] == cheftacular['repositories'][options['role']]['not_a_migration_message'] )
33
33
 
34
- on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ) do |host|
35
- n = get_node_from_address(nodes, host.hostname)
36
-
37
- puts("Beginning migration run for #{ n.name } (#{ n.public_ipaddress }) on role #{ options['role'] }") unless options['quiet']
38
-
39
- log_data, timestamp, exit_status = start_task( n.name, n.public_ipaddress, n.run_list, "#{ bundle_command } exec rake db:migrate", options, locs, cheftacular, passwords)
40
-
41
- logs_bag_hash["#{ n.name }-#{ __method__ }"] = { "text" => log_data.scrub_pretty_text.force_encoding('UTF-8'), "timestamp" => timestamp, "exit_status" => exit_status }
34
+ puts("Nothing to migrate for #{ options['role'] }...")
42
35
  end
43
36
 
44
- @config['ChefDataBag'].save_logs_bag
45
-
46
37
  @config['helper'].send_log_bag_hash_slack_notification(logs_bag_hash, __method__, 'Failing migration detected, please fix this and deploy again, exiting...')
47
38
 
48
39
  @options['run_migration_already'] = true
@@ -35,16 +35,16 @@ class Cheftacular
35
35
  @config['auditor'].notify_slack_on_completion("run #{ command } completed on #{ nodes.map { |node| node.name }.join(', ') }\n") if @config['cheftacular']['auditing']
36
36
  end
37
37
 
38
- def run_ruby_on_rails command
39
- run_command(command, __method__.to_s, "#{ @config['bundle_command'] } exec")
38
+ def run_ruby_on_rails command, modes=['normal_output'], nodes=[]
39
+ run_command(command, __method__.to_s, "RAILS_ENV=TRUE_ENVIRONMENT #{ @config['bundle_command'] } exec", modes, nodes)
40
40
  end
41
41
 
42
42
  def run_nodejs command
43
43
  self.send("run_#{ @config['getter'].get_current_sub_stack }", command)
44
44
  end
45
45
 
46
- def run_meteor command
47
- run_command(command, __method__.to_s, '/usr/local/bin/meteor', true)
46
+ def run_meteor command, modes=['sudo', 'normal_output']
47
+ run_command(command, __method__.t, '/usr/local/bin/meteor', modes)
48
48
  end
49
49
 
50
50
  def run_wordpress command
@@ -65,27 +65,37 @@ class Cheftacular
65
65
 
66
66
  private
67
67
 
68
- def run_command command, descriptor, executable, sudo=false
69
- nodes = @config['getter'].get_current_role_nodes
68
+ def run_command command, descriptor, executable, modes=['normal'], nodes=[]
69
+ nodes = @config['getter'].get_current_role_nodes if nodes.empty?
70
70
 
71
71
  #this must always precede on () calls so they have the instance variables they need
72
72
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
73
73
 
74
- on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ) do |host|
75
- n = get_node_from_address(nodes, host.hostname)
76
-
74
+ nodes.each do |n|
77
75
  puts("Beginning #{ descriptor } run for #{ n.name } (#{ n.public_ipaddress }) on role #{ options['role'] }") unless options['quiet']
78
76
 
79
- log_data, timestamp, exit_status = start_task( n.name, n.public_ipaddress, n.run_list, "#{ executable } #{ command }", options, locs, cheftacular, passwords, sudo)
77
+ true_env = @config['dummy_sshkit'].get_true_environment n.run_list, @config['cheftacular']['run_list_environments'][@options['env']], @options['env']
78
+ true_env = @config['dummy_sshkit'].get_override_environment @config['cheftacular']['repositories'][@options['role']], @options['env']
79
+
80
+ base_exec = "ssh #{ Cheftacular::SSH_INLINE_VARS } #{ @config['cheftacular']['deploy_user'] }@#{ n.public_ipaddress }"
81
+ final_command = ["cd #{ @config['cheftacular']['base_file_path'] }/#{ @options['repository'] }/current"]
82
+ final_command << @config['helper'].sudo(ip_address) if modes.include?('sudo')
83
+ final_command << ( executable.gsub('TRUE_ENVIRONMENT', true_env) + ' ' + command )
84
+
85
+ puts "#{ base_exec } \"#{ final_command.join(' && ') }\" > /dev/tty"
80
86
 
81
- logs_bag_hash["#{ n.name }-#{ descriptor }"] = { "text" => log_data.scrub_pretty_text.force_encoding('UTF-8'), "timestamp" => timestamp, "exit_status" => exit_status }
87
+ log_output = `#{ base_exec } "#{ final_command.join(' && ') }" > /dev/tty`
88
+
89
+ logs_bag_hash["#{ n.name }-#{ descriptor }"] = { "text" => log_output.scrub_pretty_text.force_encoding('UTF-8'), "timestamp" => Time.now.strftime("%Y%m%d%H%M%S"), "exit_status" => $?.to_i }
82
90
  end
83
91
 
84
92
  @config['ChefDataBag'].save_logs_bag
85
93
 
86
- @config['helper'].send_log_bag_hash_slack_notification(logs_bag_hash, __method__, 'Failing command detected, exiting...')
94
+ @config['helper'].send_log_bag_hash_slack_notification(logs_bag_hash, __method__, 'Failing command detected, exiting...') if modes.include?('normal_output')
95
+
96
+ return nodes if modes.include?('normal_output')
87
97
 
88
- nodes
98
+ return logs_bag_hash if modes.include?('return_logs_bag_hash')
89
99
  end
90
100
  end
91
101
  end
@@ -13,7 +13,9 @@ class Cheftacular
13
13
  "Worker and job servers should tail their log to the master log (/var/log/syslog) where <b>all</b> of the major processes on the server output to. " +
14
14
  "While the vast majority of this syslog will be relevant to application developers, some will not (usually firewall blocks and the like).",
15
15
 
16
- " 3. if the `PATTERN_TO_MATCH` argument exists, the tail will only return entries that have that pattern rather than everything written to the file."
16
+ " 3. if the `PATTERN_TO_MATCH` argument exists, the tail will only return entries that have that pattern rather than everything written to the file.",
17
+
18
+ " 4. If `--nginx` is specified, the tail will instead try and fetch data from the nginx instance on the matching node rather than the default."
17
19
  ]
18
20
  ]
19
21
 
@@ -36,6 +38,8 @@ class Cheftacular
36
38
 
37
39
  if @config['dummy_sshkit'].has_run_list_in_role_map?(n.run_list, @config['cheftacular']['role_maps'])
38
40
  start_tail_role_map( n.public_ipaddress, n.run_list, pattern_to_match )
41
+ elsif @options['get_nginx_logs']
42
+ start_tail_role_map( n.public_ipaddress, n.run_list, pattern_to_match, "/var/log/nginx/#{ @options['repository'] }_access.log")
39
43
  else
40
44
  self.send("start_tail_#{ @config['getter'].get_current_stack }", n.public_ipaddress, n.run_list, pattern_to_match )
41
45
  end
@@ -44,8 +48,8 @@ class Cheftacular
44
48
 
45
49
  private
46
50
 
47
- def start_tail_role_map ip_address, run_list, pattern_to_match
48
- log_loc = @config['getter'].get_current_role_map(run_list)['log_location'].split(',').first.gsub('|current_repo_location|', "#{ @config['cheftacular']['base_file_path'] }/#{ @options['repository'] }/current")
51
+ def start_tail_role_map ip_address, run_list, pattern_to_match, log_loc='default'
52
+ log_loc = @config['getter'].get_current_role_map(run_list)['log_location'].split(',').first.gsub('|current_repo_location|', "#{ @config['cheftacular']['base_file_path'] }/#{ @options['repository'] }/current") if log_loc == 'default'
49
53
 
50
54
  `ssh #{ Cheftacular::SSH_INLINE_VARS } -tt #{ @config['cheftacular']['deploy_user'] }@#{ ip_address } "#{ @config['helper'].sudo(ip_address) } tail -f #{ log_loc } #{ get_tail_grep_string(pattern_to_match) }" > /dev/tty`
51
55
  end
@@ -106,6 +106,7 @@ class Cheftacular
106
106
 
107
107
  def aliased_command_hash
108
108
  {
109
+ application: ['a', 'app'],
109
110
  check: ['ch'],
110
111
  console: ['co'],
111
112
  deploy: ['d'],
@@ -212,6 +212,11 @@ class Cheftacular
212
212
  @options['run_on_all'] = true
213
213
  end
214
214
 
215
+ #cft service
216
+ opts.on('--sv', "On cft service calls, utilize the runsv syntax instead of the service syntax (can restart sv programs)") do
217
+ @options['runsv'] = true
218
+ end
219
+
215
220
  #cloud_bootstrap
216
221
 
217
222
  opts.on('--with-dn DOMAIN_NAME', "On hip rax_bootstrap allows you to specify a domain structure other than the default environment one") do |domain|
@@ -63,7 +63,9 @@ class Cheftacular
63
63
  "4. The `-O ORGANIZATION` flag can be used with TheCheftacularCookbook to set an *organization* your app can try " +
64
64
  "deploying from, your git user needs access to these forks / organization(s).",
65
65
 
66
- " 3. The `-z|--unset-github-deploy-args` option will clear your current `-Z` and `-O` flags."
66
+ " 3. The `-z|--unset-github-deploy-args` option will clear your current `-Z` and `-O` flags.",
67
+
68
+ "5. `--nginx` will fetch logs for various logging commands from nginx instead of the default location."
67
69
  ] if @config['documentation']['arguments'].empty?
68
70
  end
69
71
 
@@ -7,7 +7,9 @@ class Cheftacular
7
7
  "`cft env_ssh_exec [command]` will ssh into each server in an environment and run the command as sudo. ",
8
8
 
9
9
  [
10
- " 1. To deactivate logstash: `cft env_ssh_exec sv stop logstash_agent`"
10
+ " 1. To deactivate logstash: `cft env_ssh_exec sv stop logstash_agent`",
11
+
12
+ " 2. To view a tree of all processes running on each server, run pstree -g"
11
13
  ]
12
14
  ]
13
15
 
@@ -34,7 +34,7 @@ class Cheftacular
34
34
  end
35
35
 
36
36
  class StatelessAction
37
- def environment type="boot", ask_on_destroy=false, remove=true, servers_to_interact_with=[], threads=[]
37
+ def environment type="boot", treat_as_stateful=false, servers_to_interact_with=[], ask_on_destroy=false, remove=true, threads=[]
38
38
  ask_on_destroy = case @options['env']
39
39
  when 'staging' then true
40
40
  when 'production' then true
@@ -49,7 +49,7 @@ class Cheftacular
49
49
  raise "Unknown type: #{ type }, can only be 'boot'/'boot_without_deploy'/'destroy'/'destroy_raw_servers'"
50
50
  end
51
51
 
52
- nodes = @config['getter'].get_true_node_objects(true)
52
+ nodes = @config['getter'].get_true_node_objects(!treat_as_stateful)
53
53
 
54
54
  nodes = @config['parser'].exclude_nodes( nodes, [{ unless: { env: @options['env'] }}])
55
55
 
@@ -62,6 +62,12 @@ class Cheftacular
62
62
  initial_servers = initial_servers.delete_if {|name, config_hash| !servers_to_interact_with.include?(name)}
63
63
  end
64
64
 
65
+ if treat_as_stateful
66
+ initial_servers = initial_servers.delete_if { |name, config_hash| config_hash.nil? || !config_hash.has_key?('descriptor') }
67
+
68
+ initial_servers = initial_servers.delete_if { |name, config_hash| !config_hash['descriptor'].include?(@options['repository']) if !config_hash.nil? && config_hash.has_key?('descriptor') }
69
+ end
70
+
65
71
  if initial_servers.empty?
66
72
  puts "There are no servers defined for #{ @options['env'] } in the env_boot_nodes hash in your cheftacular.yml... Exiting"
67
73
 
@@ -131,7 +131,7 @@ class Cheftacular
131
131
 
132
132
  download_location = @options['save_to_file'] ? @options['save_to_file'] : "#{ @config['locs']['chef-log'] }/#{ file_name.split('/').last }"
133
133
 
134
- `scp -oStrictHostKeyChecking=no #{ @config['cheftacular']['deploy_user'] }@#{ n.public_ipaddress }:#{ location }/#{ file_name } #{ download_location } > /dev/tty`
134
+ `scp ssh #{ Cheftacular::SSH_INLINE_VARS } #{ @config['cheftacular']['deploy_user'] }@#{ n.public_ipaddress }:#{ location }/#{ file_name } #{ download_location } > /dev/tty`
135
135
 
136
136
  puts "Finished downloading #{ file_name } to #{ download_location }!"
137
137
  end
@@ -13,7 +13,9 @@ class Cheftacular
13
13
  " 2. When `list` is passed, the above behavior is performed ",
14
14
 
15
15
  " 3. When `restart|stop|start SERVICE` is passed, the command will attempt to restart|stop|start the " +
16
- "service if it has a .conf file on the remote server in the /etc/init directory."
16
+ "service if it has a .conf file on the remote server in the /etc/init directory.",
17
+
18
+ " 4. `--sv` will use sv syntax for processes that use runsv instead of the older service paradigm."
17
19
  ]
18
20
  ]
19
21
 
@@ -23,21 +25,29 @@ class Cheftacular
23
25
 
24
26
  class StatelessAction
25
27
  def service
26
- raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops')
28
+ #raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops')
27
29
 
28
30
  command = case ARGV[1]
29
- when nil then 'list'
30
- when /list/ then 'list'
31
- when 'restart' then "#{ ARGV[2] } restart"
32
- when 'stop' then "#{ ARGV[2] } stop"
33
- when 'start' then "#{ ARGV[2] } start"
34
- else 'list'
31
+ when nil then 'ls /etc/init'
32
+ when /list/ then 'ls /etc/init'
33
+ when 'restart' then "service #{ ARGV[2] } restart"
34
+ when 'stop' then "service #{ ARGV[2] } stop"
35
+ when 'start' then "service #{ ARGV[2] } start"
36
+ else 'ls /etc/init'
35
37
  end
36
38
 
37
- raise "You did not pass a service to #{ ARGV[1] }" if ARGV[1] =~ /restart|stop|start/ && ARGV[2].nil?
39
+ command = case ARGV[1]
40
+ when nil then 'ls /etc/init.d'
41
+ when /list/ then 'ls /etc/init.d'
42
+ when 'restart' then "sv restart #{ ARGV[2] }"
43
+ when 'stop' then "sv stop #{ ARGV[2] }"
44
+ when 'start' then "sv start #{ ARGV[2] }"
45
+ else 'ls /etc/init.d'
46
+ end if @options['runsv']
38
47
 
39
- service_location = "#{ ARGV[2] }.conf"
48
+ raise "You did not pass a service to #{ ARGV[1] }" if ARGV[1] =~ /restart|stop|start/ && ARGV[2].nil?
40
49
 
50
+ #initctl list | awk '{ print $1 }' | xargs -n1 initctl show-config
41
51
  nodes = @config['getter'].get_true_node_objects
42
52
 
43
53
  nodes = @config['parser'].exclude_nodes( nodes, [{ unless: { env: @options['env'] }}], true )
@@ -47,9 +57,9 @@ class Cheftacular
47
57
  on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ) do |host|
48
58
  n = get_node_from_address(nodes, host.hostname)
49
59
 
50
- puts "Beginning run of \"service #{ command }\" for #{ n.name } (#{ n.public_ipaddress })"
60
+ puts "Beginning run of \"#{ command }\" for #{ n.name } (#{ n.public_ipaddress })"
51
61
 
52
- start_service_run( n.name, n.public_ipaddress, options, locs, passwords, command, cheftacular, service_location )
62
+ start_service_run( n.name, n.public_ipaddress, options, locs, passwords, command, cheftacular)
53
63
  end
54
64
  end
55
65
  end
@@ -58,26 +68,10 @@ end
58
68
  module SSHKit
59
69
  module Backend
60
70
  class Netssh
61
- def start_service_run name, ip_address, options, locs, passwords, command, cheftacular, service_location, out=""
71
+ def start_service_run name, ip_address, options, locs, passwords, command, cheftacular, out=""
62
72
  log_loc, timestamp = set_log_loc_and_timestamp(locs)
63
- run_list_command = command == 'list'
64
-
65
- #puts "Generating service run log file for #{ name } (#{ ip_address }) at #{ log_loc }/rolelog/#{ name }-service-#{ timestamp }.txt"
66
-
67
- #TODO check other locations for services!
68
- if !run_list_command && !sudo_test( passwords[ip_address], "/etc/init/#{ service_location }" ) #true if file exists
69
- puts "#{ name } (#{ ip_address }) cannot run #{ command } as it's .conf file does not exist! Running list instead..."
70
-
71
- run_list_command = true
72
- end
73
-
74
- if run_list_command
75
- out << capture( :ls, '-al', '/etc/init' )
76
- else
77
- out << sudo_capture( passwords[ip_address], 'service', command)
78
- end
79
73
 
80
- #::File.open("#{ log_loc }/rolelog/#{ name }-service-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) } unless options['no_logs']
74
+ out << sudo_capture( passwords[ip_address], command)
81
75
 
82
76
  puts out.scrub_pretty_text
83
77
 
@@ -1,5 +1,5 @@
1
1
  class Cheftacular
2
2
  #major_version.minor_version.bugfixes
3
- VERSION = "2.15.2"
3
+ VERSION = "2.15.3"
4
4
  RUBY_VERSION = "2.2.2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cheftacular
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.15.2
4
+ version: 2.15.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Louis Alridge
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-19 00:00:00.000000000 Z
11
+ date: 2016-04-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashie
@@ -252,6 +252,7 @@ files:
252
252
  - lib/cheftacular.rb
253
253
  - lib/cheftacular/README.md
254
254
  - lib/cheftacular/action.rb
255
+ - lib/cheftacular/actions/application.rb
255
256
  - lib/cheftacular/actions/backups.rb
256
257
  - lib/cheftacular/actions/check.rb
257
258
  - lib/cheftacular/actions/console.rb
@@ -383,7 +384,6 @@ files:
383
384
  - lib/cloud_interactor/volume/read.rb
384
385
  - lib/cloudflare/monkeypatches.rb
385
386
  - lib/ridley/monkeypatches.rb
386
- - lib/sshkit/actions/start_task.rb
387
387
  - lib/sshkit/getters.rb
388
388
  - lib/sshkit/helpers.rb
389
389
  - lib/sshkit/monkeypatches.rb
@@ -1,47 +0,0 @@
1
- module SSHKit
2
- module Backend
3
- class Netssh
4
- def start_task name, ip_address, run_list, command, options, locs, cheftacular, passwords, sudo=false, out=""
5
- log_loc, timestamp = set_log_loc_and_timestamp(locs)
6
- true_env = get_true_environment run_list, cheftacular['run_list_environments'][options['env']], options['env']
7
- true_env = get_override_environment cheftacular['repositories'][options['role']], options['env']
8
-
9
- puts "Running #{ command } for #{ name } (#{ ip_address }) (Run with with --debug to generate a log as well)"
10
-
11
- target_loc = "#{ cheftacular['base_file_path'] }/#{ options['repository'] }/current"
12
-
13
- if !sudo_test( passwords[ip_address], target_loc )
14
- puts "#{ name } (#{ ip_address }) cannot run #{ command } as there is no directory at #{ target_loc }!"
15
-
16
- return ['', timestamp]
17
- end
18
-
19
- capture_args = []
20
- capture_args << ["RAILS_ENV=#{ true_env }"] if cheftacular['repositories'][options['role']]['stack'] == 'ruby_on_rails'
21
- capture_args << command.split(' ')
22
-
23
- within target_loc do
24
- out << (sudo ? sudo_capture(passwords[ip_address], *capture_args.flatten) : capture( *capture_args.flatten ))
25
- end
26
-
27
- ::File.open("#{ log_loc }/#{ name }-task-#{ timestamp }.txt", "w") {|f| f.write(out.scrub_pretty_text) } if options['debug']
28
-
29
- puts out
30
-
31
- if out.empty? || ( cheftacular['repositories'][options['role']].has_key?('not_a_migration_message') && out == cheftacular['repositories'][options['role']]['not_a_migration_message'] )
32
- puts("Nothing to migrate for #{ options['role'] }...")
33
- end
34
-
35
- [out, timestamp, 0] #return out to send to logs_bag
36
- rescue SSHKit::Command::Failed => e
37
- puts "@@@@@CRITICAL! #{ command } failed for #{ name } (#{ ip_address })! Please check your #{ log_loc }/failed-deploy for the logs!@@@@@"
38
-
39
- puts(e.message)
40
-
41
- ::File.open("#{ log_loc }/failed-deploy/#{ name }-task-#{ timestamp }.txt", "w") { |f| f.write(e.message.scrub_pretty_text) }
42
-
43
- [e.message, timestamp, 1]
44
- end
45
- end
46
- end
47
- end