Class: Cheftacular::Action

Inherits:
Object
  • Object
show all
Includes:
SSHKit::DSL
Defined in:
lib/cheftacular/action.rb,
lib/cheftacular/actions/log.rb,
lib/cheftacular/actions/run.rb,
lib/cheftacular/actions/tail.rb,
lib/cheftacular/actions/check.rb,
lib/cheftacular/actions/scale.rb,
lib/cheftacular/actions/deploy.rb,
lib/cheftacular/actions/verify.rb,
lib/cheftacular/actions/backups.rb,
lib/cheftacular/actions/console.rb,
lib/cheftacular/actions/migrate.rb,
lib/cheftacular/actions/db_console.rb

Instance Method Summary collapse

Constructor Details

#initialize(options, config) ⇒ Action

Returns a new instance of Action.



12
13
14
# File 'lib/cheftacular/action.rb', line 12

def initialize options, config
  @options, @config = options, config
end

Instance Method Details

#backups(command = '') ⇒ Object



35
36
37
38
39
40
41
# File 'lib/cheftacular/actions/backups.rb', line 35

def backups command=''
  command = ARGV[1] if command.blank?

  raise "Unsupported command (#{ command }) for cft backups" unless command =~ /activate|deactivate|fetch|load|restore|status/

  self.send("backups_#{ command }")
end

#check(mode = '', commit_hash = {}, have_revisions = false, have_changed_orgs = false, fetch_all_repository_data = false, headers = [], deployment_args = { in: :parallel }) ⇒ Object Also known as: ch



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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
# File 'lib/cheftacular/actions/check.rb', line 24

def check mode='', commit_hash={}, have_revisions=false, have_changed_orgs=false, fetch_all_repository_data=false, headers=[], deployment_args={ in: :parallel }
  @config['filesystem'].cleanup_file_caches('current-nodes')

  fetch_all_repository_data = ARGV[1] == 'all'
  verify_state_is_latest    = ARGV[1] == 'verify' || ARGV[1] == 've'
  verify_state_is_latest    = mode    == 'verify' if ARGV[1] != 'verify'
  
  nodes = @config['getter'].get_true_node_objects(fetch_all_repository_data)

  nodes = @config['parser'].exclude_nodes(nodes, [{ if: { not_env: @options['env'] } }])

  repositories_to_check = @config['getter'].get_repo_names_for_repositories
  repositories_to_check = repositories_to_check.reject { |key,val| key != @options['repository'] } unless fetch_all_repository_data 

  deployment_args = { in: :groups, limit: 2, wait: 5 } if fetch_all_repository_data

  #this must always precede on () calls so they have the instance variables they need
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars

  on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ), deployment_args do |host|
    n = get_node_from_address(nodes, host.hostname)

    puts("Beginning commit check run for #{ n.name } (#{ n.public_ipaddress })...") unless options['quiet']

    repositories_to_check.each_pair do |repo, repo_hash|
      next unless n.run_list.include?("role[#{ repo_hash['role'] }]")

      options['repository'] = repo
      commit_hash[n.name] ||= {}

      commit_hash[n.name][repo] = start_commit_check( n.name, n.public_ipaddress, options, locs, cheftacular, passwords)

      next if commit_hash[n.name][repo].nil?

      if n.normal_attributes.has_key?(options['repository'])
        commit_hash[n.name][repo]['branch']       = n.normal_attributes[options['repository']]['repo_branch'] if n.normal_attributes[options['repository']].has_key?('repo_branch')
        commit_hash[n.name][repo]['organization'] = n.normal_attributes[options['repository']]['repo_group']  if n.normal_attributes[options['repository']].has_key?('repo_group')
      end

      have_revisions    = true if commit_hash[n.name].has_key?(repo) && commit_hash[n.name][repo].has_key?('branch')
      have_changed_orgs = true if commit_hash[n.name].has_key?(repo) && commit_hash[n.name][repo].has_key?('organization')

      sleep 5
    end
  end

  headers << "\n#{ 'name'.ljust(20) }"
  headers << 'repository'.ljust(30)   if repositories_to_check.length > 1
  headers << "#{ 'deployed_on'.ljust(22) } #{ 'commit'.ljust(40) }"
  headers << 'revision'.ljust(21)     if have_revisions
  headers << 'organization'.ljust(30) if have_changed_orgs

  puts headers.join(' ')
  nodes.each do |n|
    next if commit_hash[n.name].nil?
    repositories_to_check.each_pair do |repo, repo_hash|
      if commit_hash[n.name].has_key?(repo) && !commit_hash[n.name][repo].nil?
        out  = []
        out << n.name.ljust(20, '_')
        out << repo.ljust(30,'_') if repositories_to_check.length > 1
        out << commit_hash[n.name][repo]['time'].ljust(22)
        out << commit_hash[n.name][repo]['name'].ljust(40)
        out << commit_hash[n.name][repo]['branch'].ljust(21, '_')  if commit_hash[n.name][repo].has_key?('branch')
        out << commit_hash[n.name][repo]['organization'].ljust(30) if commit_hash[n.name][repo].has_key?('organization')

        puts out.join(' ')
      end
    end
  end

  @config['helper'].check_if_possible_repo_state(@config['parser'].parse_repo_state_hash_from_commit_hash(commit_hash), 'display_for_check') if verify_state_is_latest
end

#consoleObject Also known as: co



21
22
23
24
25
# File 'lib/cheftacular/actions/console.rb', line 21

def console
  nodes = self.send("console_#{ @config['getter'].get_current_stack }")

  @config['auditor'].notify_slack_on_completion("console run completed on #{ nodes.map { |node| node.name }.join(', ') }\n") if @config['cheftacular']['auditing']
end

#console_allObject



54
55
56
# File 'lib/cheftacular/actions/console.rb', line 54

def console_all
  raise "You attempted to create a console for the all role, this is not possible."
end

#console_nodejsObject



46
47
48
# File 'lib/cheftacular/actions/console.rb', line 46

def console_nodejs
  raise "Not yet implemented"
end

#console_ruby_on_rails(node_args = [{unless: 'role[rails]'}]) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/cheftacular/actions/console.rb', line 27

def console_ruby_on_rails node_args=[{unless: 'role[rails]'}]
  nodes = @config['getter'].get_true_node_objects

  #must have rails stack to run migrations and not be a db, only want ONE node
  node_args << { unless: "role[#{ @options['role'] }]" }

  consolable_nodes = @config['parser'].exclude_nodes( nodes, (node_args + [{ unless: "role[preferred_console]" }]).flatten, true )

  consolable_nodes = @config['parser'].exclude_nodes( nodes, node_args, true ) if consolable_nodes.empty?

  consolable_nodes.each do |n|
    puts("Beginning console run for #{ n.name } (#{ n.public_ipaddress }) on role #{ @options['role'] }") unless @options['quiet']

    start_console_ruby_on_rails(n.public_ipaddress, n.run_list)
  end

  consolable_nodes
end

#console_wordpressObject



50
51
52
# File 'lib/cheftacular/actions/console.rb', line 50

def console_wordpress
  raise "Not yet implemented"
end

#db_consoleObject



21
22
23
# File 'lib/cheftacular/actions/db_console.rb', line 21

def db_console
  nodes = self.send("db_console_#{ @config['getter'].get_current_database }")
end

#db_console_Object



73
74
75
76
77
# File 'lib/cheftacular/actions/db_console.rb', line 73

def db_console_
  puts "db_console method tried to create a db_console for the role \"#{ @options['role'] }\" but it doesn't appear to have a repository set! Skipping..."

  return false
end

#db_console_mongodb(private_database_host_address = nil) ⇒ Object Also known as: mongo



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/cheftacular/actions/db_console.rb', line 44

def db_console_mongodb private_database_host_address=nil
  nodes = @config['getter'].get_true_node_objects(true)

  #must have mongo db, only want ONE node
  if @config['getter'].get_current_repo_config.has_key?('db_primary_host_role')
    mongo_host  = @config['parser'].exclude_nodes( nodes, [{ unless: "role[#{ @config['getter'].get_current_repo_config['db_primary_host_role'] }]"}, { if: { not_env: @options['env'] } }], true).first

    private_database_host_address = @config['getter'].get_address_hash(mongo_host.name)[mongo_host.name]['priv']
  end

  mongoable_nodes = @config['parser'].exclude_nodes( nodes, [{ unless: "role[#{ @options['role'] }]" }, { if: { not_env: @options['env'] } }], true )

  mongoable_nodes.each do |n|
    puts("Beginning database console run for #{ n.name } (#{ n.public_ipaddress }) on role #{ @options['role'] }") unless @options['quiet']

    start_console_mongodb(n.public_ipaddress, private_database_host_address)
  end

  @config['auditor'].notify_slack_on_completion("mongo run completed on #{ nodes.first.name } (#{ nodes.first.public_ipaddress })\n") if @config['cheftacular']['auditing']
end

#db_console_mysqlObject



65
66
67
# File 'lib/cheftacular/actions/db_console.rb', line 65

def db_console_mysql
  raise "Not yet implemented"
end

#db_console_noneObject



69
70
71
# File 'lib/cheftacular/actions/db_console.rb', line 69

def db_console_none
  raise "You attempted to create a database console for a role that had no database type attached to it, this is not possible."
end

#db_console_postgresqlObject Also known as: psql



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/cheftacular/actions/db_console.rb', line 25

def db_console_postgresql
  nodes = @config['getter'].get_true_node_objects(true)

  #must have rails stack to run migrations and not be a db, only want ONE node
  psqlable_nodes = @config['parser'].exclude_nodes( nodes, [{ unless: "role[#{ @options['role'] }]" }, { unless: 'role[rails]' }, { if: { not_env: @options['env'] } }], true )

  database_host  = @config['parser'].exclude_nodes( nodes, [{ unless: "role[#{ @config['getter'].get_current_repo_config['db_primary_host_role'] }]"}, { if: { not_env: @options['env'] } }], true).first

  private_database_host_address = @config['getter'].get_address_hash(database_host.name)[database_host.name]['priv']

  psqlable_nodes.each do |n|
    puts("Beginning database console run for #{ n.name } (#{ n.public_ipaddress }) on role #{ @options['role'] }") unless @options['quiet']

    start_console_postgresql(n.public_ipaddress, private_database_host_address )
  end

  @config['auditor'].notify_slack_on_completion("psql run completed on #{ nodes.first.name } (#{ nodes.first.public_ipaddress })\n") if @config['cheftacular']['auditing']
end

#deploy(deployment_args = { in: :groups, limit: 6, wait: 5 }) ⇒ Object Also known as: d



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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
# File 'lib/cheftacular/actions/deploy.rb', line 37

def deploy deployment_args={ in: :groups, limit: 6, wait: 5 }
  run_check  = ARGV[1] == 'check' || ARGV[1] == 'ch'
  run_verify = ARGV[1] == 'verify' || ARGV[1] == 've'

  nodes = @config['getter'].get_true_node_objects(false) #when this is run in scaling we'll need to make sure we deploy to new nodes

  nodes = @config['parser'].exclude_nodes( nodes, [{ if: "role[#{ @options['negative_role'] }]" }]) if @options['negative_role']
  
  #this must always precede on () calls so they have the instance variables they need
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars

  deployment_args = { in: :groups, limit: 10, wait: 5 } if @options['env'] == 'production'

  @config['pleasantries'].good_luck_fridays if @config['cheftacular']['pleasantries']

  #on is namespaced to SSHKit::Backend::Netssh.on 
  on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ), deployment_args do |host|
    n = get_node_from_address(nodes, host.hostname)

    puts("Beginning chef client run for #{ n.name } (#{ n.public_ipaddress }) on role #{ options['role'] }") unless options['quiet']

    log_data, timestamp, exit_status = start_deploy( n.name, n.public_ipaddress, options, locs, passwords)

    logs_bag_hash["#{ n.name }-#{ __method__ }"] = { "text" => log_data.scrub_pretty_text, "timestamp" => timestamp, "exit_status" => exit_status }
  end

  @config['helper'].send_log_bag_hash_slack_notification(logs_bag_hash, __method__)
  
  @config['ChefDataBag'].save_logs_bag unless @options['debug'] #We don't really need to store entire chef runs in the logs bag

  @config['action'].check if run_check && !@options['run_migration_already']

  @config['action'].check('verify') if run_verify && !@options['run_migration_already']

  @config['auditor'].notify_slack_on_completion_for_deploy(nodes.map {|n| n.name }, logs_bag_hash) if @config['cheftacular']['auditing'] && !@options['run_migration_already']

  return false if @options['skip_further_deploy_steps']

  @config['action'].migrate(nodes) if @config['getter'].get_current_repo_config['database'] != 'none' && !@options['run_migration_already']

  split_nodes_hash = {}

  if @config['cheftacular']['run_list_environments'].has_key?(@options['env'])
    @config['cheftacular']['run_list_environments'][@options['env']].each_key do |role_name|
      split_nodes_hash[role_name] = @config['parser'].exclude_nodes( nodes, [{ unless: "role[#{ role_name }]" }])
    end

    split_nodes_hash.each_pair do |role, split_nodes|
      next if split_nodes.empty?

      unless @options["run_#{ role }_migrations_already"]
        @options["run_#{ role }_migrations_already"] = true
        
        if @config['getter'].get_current_repo_config['database'] != 'none'
          puts("Running migration on split environment #{ role }...") if !@options['quiet']
          
          migrate(split_nodes)
        end
      end
    end
  end
end

#logObject



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/cheftacular/actions/log.rb', line 27

def log
  nodes = @config['getter'].get_true_node_objects

  nodes = @config['parser'].exclude_nodes( nodes, [{ unless: "role[#{ @options['role'] }]" }] )

  nodes = @config['parser'].exclude_nodes( nodes, [{ if: "role[#{ @options['negative_role'] }]" }]) if @options['negative_role']
  
  #this must always precede on () calls so they have the instance variables they need
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars

  getter = @config['getter']

  on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ), in: :parallel do |host|
    n = get_node_from_address(nodes, host.hostname)

    puts("Beginning log fetch run for #{ n.name } (#{ n.public_ipaddress }) on role #{ options['role'] }") unless options['quiet']

    if has_run_list_in_role_map?(n.run_list, cheftacular['role_maps'])
      start_log_role_map( n.name, n.public_ipaddress, getter.get_current_role_map(n.run_list)['log_location'], options, locs, cheftacular, passwords)
    else
      self.send("start_log_fetch_#{ getter.get_current_stack }", n.name, n.public_ipaddress, n.run_list, options, locs, cheftacular, passwords)
    end
  end
end

#migrate(nodes = []) ⇒ Object



19
20
21
# File 'lib/cheftacular/actions/migrate.rb', line 19

def migrate nodes=[]
  self.send("migrate_#{ @config['getter'].get_current_stack }", nodes)
end

#migrate_(nodes = []) ⇒ Object



74
75
76
77
78
# File 'lib/cheftacular/actions/migrate.rb', line 74

def migrate_ nodes=[]
  puts("Migrate method tried to migrate the role \"#{ @options['role'] }\" but it doesn't appear to have a repository set! Skipping...") if @options['verbose']

  return false
end

#migrate_all(nodes = []) ⇒ Object



70
71
72
# File 'lib/cheftacular/actions/migrate.rb', line 70

def migrate_all nodes=[]
  raise "You attempted to migrate the all role, this is not possible."
end

#migrate_nodejs(nodes = []) ⇒ Object



64
65
66
67
68
# File 'lib/cheftacular/actions/migrate.rb', line 64

def migrate_nodejs nodes=[]
  puts("Method #{ __method__ } is not yet implemented") if @options['verbose']

  return false
end

#migrate_ruby_on_rails(nodes = []) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/cheftacular/actions/migrate.rb', line 23

def migrate_ruby_on_rails nodes=[]
  nodes = @config['getter'].get_true_node_objects if nodes.empty?

  #must have rails stack to run migrations, only want ONE node
  nodes = @config['parser'].exclude_nodes(nodes, [{ unless: "role[#{ @options['role'] }]" }, { unless: 'role[rails]' }], true)

  log_data = ""

  #this must always precede on () calls so they have the instance variables they need
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars

  on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ) do |host|
    n = get_node_from_address(nodes, host.hostname)

    puts("Beginning migration run for #{ n.name } (#{ n.public_ipaddress }) on role #{ options['role'] }") unless options['quiet']

    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)

    logs_bag_hash["#{ n.name }-#{ __method__ }"] = { "text" => log_data.scrub_pretty_text, "timestamp" => timestamp, "exit_status" => exit_status }
  end

  @config['ChefDataBag'].save_logs_bag

  @config['helper'].send_log_bag_hash_slack_notification(logs_bag_hash, __method__, 'Failing migration detected, please fix this and deploy again, exiting...')

  @options['run_migration_already'] = true

  #restart the servers again after a deploy with a migration just in case
  if !log_data.empty? && log_data != @config['cheftacular']['repositories'][@options['role']]['not_a_migration_message']
    @config['auditor'].notify_slack_on_completion("migrate run completed on #{ nodes.map { |node| node.name }.join(', ') }\n") if @config['cheftacular']['auditing']

    @config['action'].deploy
  end
end

#migrate_wordpress(nodes = []) ⇒ Object



58
59
60
61
62
# File 'lib/cheftacular/actions/migrate.rb', line 58

def migrate_wordpress nodes=[]
  puts("Method #{ __method__ } is not yet implemented") if @options['verbose']

  return false
end

#runObject Also known as: meteor



30
31
32
33
34
35
36
# File 'lib/cheftacular/actions/run.rb', line 30

def run
  command = @config['parser'].parse_runtime_arguments 0, 'range'

  nodes = self.send("run_#{ @config['getter'].get_current_stack }", command)

  @config['auditor'].notify_slack_on_completion("run #{ command } completed on #{ nodes.map { |node| node.name }.join(', ') }\n") if @config['cheftacular']['auditing']
end

#run_(command) ⇒ Object



58
59
60
61
62
# File 'lib/cheftacular/actions/run.rb', line 58

def run_ command
  puts "Run method tried to run a command for the role \"#{ @options['role'] }\" but it doesn't appear to have a repository or stack set! Skipping..."

  return false
end

#run_all(command) ⇒ Object



54
55
56
# File 'lib/cheftacular/actions/run.rb', line 54

def run_all command
  raise "You attempted to run a command for the all role, this is not possible."
end

#run_meteor(command) ⇒ Object



46
47
48
# File 'lib/cheftacular/actions/run.rb', line 46

def run_meteor command
  run_command(command, __method__.to_s, '/usr/local/bin/meteor', true)
end

#run_nodejs(command) ⇒ Object



42
43
44
# File 'lib/cheftacular/actions/run.rb', line 42

def run_nodejs command
  self.send("run_#{ @config['getter'].get_current_sub_stack }", command)
end

#run_ruby_on_rails(command) ⇒ Object



38
39
40
# File 'lib/cheftacular/actions/run.rb', line 38

def run_ruby_on_rails command
  run_command(command, __method__.to_s, "#{ @config['bundle_command'] } exec")
end

#run_wordpress(command) ⇒ Object



50
51
52
# File 'lib/cheftacular/actions/run.rb', line 50

def run_wordpress command
  raise "Not yet implemented"
end

#scale(type = "up", num_to_scale = 1) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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
# File 'lib/cheftacular/actions/scale.rb', line 23

def scale type="up", num_to_scale=1
  type         = ARGV[1] if ARGV[1]
  num_to_scale = ARGV[2] if ARGV[2]

  raise "Unknown type for scaling: #{ type }" unless (type =~ /up|down/) == 0
  raise "Unknown scaling: #{ num_to_scale }"  unless num_to_scale.is_a?(Fixnum) && num_to_scale >= 1

  nodes = @config['getter'].get_true_node_objects

  base_node_names = {}

  nodes = @config['parser'].exclude_nodes( nodes, [{ unless: 'role[scalable]' }] )

  nodes.each do |n|
    #names are stored alphabetically so this will always put the result hash in the form of {base_name => highest N}
    base_node_names[n.name.gsub(/\d/,'')] ||= {}
    base_node_names[n.name.gsub(/\d/,'')][n.name]        = n.name.gsub(/[^\d]/,'')

    if base_node_names[n.name.gsub(/\d/,'')][n.name] > base_node_names[n.name.gsub(/\d/,'')]['highest_val'] || base_node_names[n.name.gsub(/\d/,'')]['highest_val'].nil?
      base_node_names[n.name.gsub(/\d/,'')]['highest_val'] = n.name.gsub(/[^\d]/,'').to_i 
    end
  end

  base_node_names.each_pair do |base_name, nodes_under_name_hash|
    raise "Cannot scale lower than 1" if (nodes_under_name_hash.keys-1).count <= num_to_scale && type == 'down'
  end

  if base_node_names.empty?
    puts("There are no nodes for #{ @options['role'] } in env #{ @options['env'] } that have scaling enabled.") unless options['quiet']
  end

  @options['force_yes']  = true
  @options['in_scaling'] = true

  scaling_node_defaults = @config['cheftacular']['scaling_nodes']

  (1..num_to_scale).each do |i|
    case type
    when 'up'
      base_node_names.each_pair do |base_name, nodes_under_name_hash|
        @options['node_name']   = base_name + ( node_under_name_hash['highest_val'] + i ).to_s.rjust(2, '0')

        if scaling_node_defaults.has_key?(base_name)
          @options['flavor_name'] = scaling_node_defaults[base_name].has_key?('flavor') ? scaling_node_defaults[base_name]['flavor'] : @config['cheftacular']['default_flavor_name']
          @options['descriptor']  = scaling_node_defaults[base_name].has_key?('descriptor') ? scaling_node_defaults[base_name]['descriptor'] : @options['node_name']
        else
          @options['flavor_name'] = @config['cheftacular']['default_flavor_name']
          @options['descriptor']  = @options['node_name']
        end

        puts("Preparing to scale #{ type } server #{ @options['node_name'] } on role #{ @options['role'] }!") unless @options['quiet']

        @config['stateless_action'].cloud_bootstrap
      end
    when 'down'
      base_node_names.each_pair do |base_name, nodes_under_name_hash|
        @options['node_name']   = base_name + ( node_under_name_hash['highest_val'] + i ).to_s.rjust(2, '0')

        puts("Preparing to scale #{ type } server #{ @options['node_name'] } on role #{ @options['role'] }!") unless @options['quiet']

        remove_client true
      end
    end

    sleep 15 if num_to_scale > 1
  end

  @config['ChefDataBag'].save_server_passwords_bag #we must save the auth bag here and not in the individual rax_bootstrap runs so they don't corrupt the bags

  @options['node_name'] = nil #if this is not nil deploy_role will try to deploy to a single server instead of the group

  @config['action'].deploy
end

#tail(pattern_to_match = '') ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/cheftacular/actions/tail.rb', line 25

def tail pattern_to_match=''
  pattern_to_match = ARGV[1] if pattern_to_match.blank?

  nodes = @config['getter'].get_true_node_objects

  nodes = @config['parser'].exclude_nodes( nodes, [{ unless: "role[#{ @options['role'] }]" }], true )

  nodes = @config['parser'].exclude_nodes( nodes, [{ if: "role[#{ @options['negative_role'] }]" }], true) if @options['negative_role']

  nodes.each do |n|
    puts("Beginning tail run for #{ n.name } (#{ n.public_ipaddress }) on role #{ @options['role'] }") unless @options['quiet']

    if @config['dummy_sshkit'].has_run_list_in_role_map?(n.run_list, @config['cheftacular']['role_maps'])
      start_tail_role_map( n.public_ipaddress, n.run_list, pattern_to_match )
    else
      self.send("start_tail_#{ @config['getter'].get_current_stack }", n.public_ipaddress, n.run_list, pattern_to_match )
    end
  end
end

#verifyObject Also known as: ve



18
19
20
# File 'lib/cheftacular/actions/verify.rb', line 18

def verify
  @config['action'].check('verify')
end