Module: ClusterChef::KnifeCommon

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



192
193
194
195
196
# File 'lib/chef/knife/knife_common.rb', line 192

def self.included(base)
  base.class_eval do
    extend ClassMethods
  end
end

.load_depsObject



6
7
8
9
10
11
# File 'lib/chef/knife/knife_common.rb', line 6

def self.load_deps
  require 'formatador'
  require 'chef/node'
  require 'chef/api_client'
  require 'fog'
end

Instance Method Details

#bootstrapper(server, hostname) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/chef/knife/knife_common.rb', line 111

def bootstrapper(server, hostname)
  bootstrap = Chef::Knife::Bootstrap.new
  bootstrap.config.merge!(config)

  bootstrap.name_args               = [ hostname ]
  bootstrap.config[:node]           = server
  bootstrap.config[:run_list]       = server.combined_run_list
  bootstrap.config[:ssh_user]       = config[:ssh_user]       || server.cloud.ssh_user
  bootstrap.config[:attribute]      = config[:attribute]
  bootstrap.config[:identity_file]  = config[:identity_file]  || server.cloud.ssh_identity_file
  bootstrap.config[:distro]         = config[:distro]         || server.cloud.bootstrap_distro
  bootstrap.config[:use_sudo]       = true unless config[:use_sudo] == false
  bootstrap.config[:chef_node_name] = server.fullname
  bootstrap.config[:client_key]     = server.client_key.body            if server.client_key.body

  bootstrap
end

#configure_dry_runObject

Put Fog into mock mode if –dry_run



83
84
85
86
87
88
# File 'lib/chef/knife/knife_common.rb', line 83

def configure_dry_run
  if config[:dry_run]
    Fog.mock!
    Fog::Mock.delay = 0
  end
end

#confirm_execution(*args) ⇒ Object

override in subclass to confirm risky actions



54
55
56
# File 'lib/chef/knife/knife_common.rb', line 54

def confirm_execution(*args)
  # pass
end

#confirm_or_exit(question, correct_answer) ⇒ Object



154
155
156
157
158
159
160
# File 'lib/chef/knife/knife_common.rb', line 154

def confirm_or_exit question, correct_answer
  response = ui.ask_question(question)
  unless response.chomp == correct_answer
    die "I didn't think so.", "Aborting!", 1
  end
  ui.info("")
end

#die(*args) ⇒ Object



170
171
172
# File 'lib/chef/knife/knife_common.rb', line 170

def die *args
  ClusterChef.die(*args)
end

#display(target, display_style = nil, &block) ⇒ Object

passes target to ClusterSlice#display, will show headings in server slice tables based on the –verbose flag



75
76
77
78
# File 'lib/chef/knife/knife_common.rb', line 75

def display(target, display_style=nil, &block)
  display_style ||= (config[:verbosity] == 0 ? :default : :expanded)
  target.display(display_style, &block)
end

#get_relevant_slice(*predicate) ⇒ Object

Get a slice of nodes matching the given filter

Examples:

target = get_relevant_slice(* @name_args)


64
65
66
67
68
69
70
71
# File 'lib/chef/knife/knife_common.rb', line 64

def get_relevant_slice( *predicate )
  full_target = get_slice( *predicate )
  display(full_target) do |svr|
    rel = relevant?(svr)
    { :relevant? => (rel ? "[blue]#{rel}[reset]" : '-' ) }
  end
  full_target.select{|svr| relevant?(svr) }
end

#get_slice(cluster_name, facet_name = nil, slice_indexes = nil) ⇒ ClusterChef::ServerSlice

A slice of a cluster:

Parameters:

  • cluster_name (String)

    – cluster to slice

  • facet_name (String) (defaults to: nil)

    – facet to slice (or nil for all in cluster)

  • slice_indexes (Array, String) (defaults to: nil)

    – servers in that facet (or nil for all in facet). You must specify a facet if you use slice_indexes.

Returns:

  • (ClusterChef::ServerSlice)

    the requested slice



30
31
32
33
34
35
36
37
38
39
# File 'lib/chef/knife/knife_common.rb', line 30

def get_slice(cluster_name, facet_name=nil, slice_indexes=nil)
  if facet_name.nil? && slice_indexes.nil?
    cluster_name, facet_name, slice_indexes = cluster_name.split(/[\s\-]/, 3)
  end
  ui.info("Inventorying servers in #{predicate_str(cluster_name, facet_name, slice_indexes)}")
  cluster = ClusterChef.load_cluster(cluster_name)
  cluster.resolve!
  cluster.discover!
  cluster.slice(facet_name, slice_indexes)
end

#load_cluster_chefObject



13
14
15
16
17
18
19
# File 'lib/chef/knife/knife_common.rb', line 13

def load_cluster_chef
  $LOAD_PATH << File.join(Chef::Config[:cluster_chef_path], '/lib') if Chef::Config[:cluster_chef_path]
  require 'cluster_chef'
  $stdout.sync = true
  ClusterChef.ui          = self.ui
  ClusterChef.chef_config = self.config
end

#predicate_str(cluster_name, facet_name, slice_indexes) ⇒ Object



41
42
43
44
45
46
# File 'lib/chef/knife/knife_common.rb', line 41

def predicate_str(cluster_name, facet_name, slice_indexes)
  [ "#{ui.color(cluster_name, :bold)} cluster",
    (facet_name    ? "#{ui.color(facet_name, :bold)} facet"      : "#{ui.color("all", :bold)} facets"),
    (slice_indexes ? "servers #{ui.color(slice_indexes, :bold)}" : "#{ui.color("all", :bold)} servers")
  ].join(', ')
end

#progressbar_for_threads(threads) ⇒ Object

Show a pretty progress bar while we wait for a set of threads to finish.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/chef/knife/knife_common.rb', line 91

def progressbar_for_threads(threads)
  section "Waiting for servers:"
  total      = threads.length
  remaining  = threads.select(&:alive?)
  start_time = Time.now
  until remaining.empty?
    remaining = remaining.select(&:alive?)
    if config[:verbose]
      ui.info "waiting: #{total - remaining.length} / #{total}, #{(Time.now - start_time).to_i}s"
      sleep 5
    else
      Formatador.redisplay_progressbar(total - remaining.length, total, {:started_at => start_time })
      sleep 1
    end
  end
  # Collapse the threads
  threads.each(&:join)
  ui.info ''
end

#relevant?(server) ⇒ Boolean

method to nodes should be filtered on

Returns:

  • (Boolean)


49
50
51
# File 'lib/chef/knife/knife_common.rb', line 49

def relevant?(server)
  server.exists?
end

#run_bootstrap(node, hostname) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/chef/knife/knife_common.rb', line 129

def run_bootstrap(node, hostname)
  bs = bootstrapper(node, hostname)
  if config[:skip].to_s == 'true'
    ui.info "Skipping: bootstrapp #{hostname} with #{JSON.pretty_generate(bs.config)}"
    return
  end
  begin
    bs.run
  rescue StandardError => e
    ui.warn e
    ui.warn e.backtrace
    ui.warn ""
    ui.warn node.inspect
    ui.warn ""
  end
end

#section(desc, *style) ⇒ Object

Announce a new section of tasks



165
166
167
168
# File 'lib/chef/knife/knife_common.rb', line 165

def section(desc, *style)
  style = [:blue] if style.empty?
  ui.info(ui.color(desc, *style))
end

#sub_commandObject

Utilities



150
151
152
# File 'lib/chef/knife/knife_common.rb', line 150

def sub_command
  self.class.sub_command
end