Class: Chef::Client
Overview
Chef::Client
The main object in a Chef run. Preps a Chef::Node and Chef::RunContext, syncs cookbooks if necessary, and triggers convergence.
Constant Summary collapse
- SANE_PATHS =
%w[/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin]
Instance Attribute Summary collapse
-
#node ⇒ Object
Returns the value of attribute node.
-
#rest ⇒ Object
Returns the value of attribute rest.
-
#run_status ⇒ Object
readonly
Returns the value of attribute run_status.
-
#runner ⇒ Object
Returns the value of attribute runner.
Class Method Summary collapse
-
.clear_notifications ⇒ Object
Clears all notifications for client run status events.
-
.run_completed_successfully_notifications ⇒ Object
The list of notifications to be run when the client run completes successfully.
-
.run_failed_notifications ⇒ Object
The list of notifications to be run when the client run fails.
-
.run_start_notifications ⇒ Object
The list of notifications to be run when the client run starts.
-
.when_run_completes_successfully(¬ification_block) ⇒ Object
Add a notification for the ‘client run success’ event.
-
.when_run_fails(¬ification_block) ⇒ Object
Add a notification for the ‘client run failed’ event.
-
.when_run_starts(¬ification_block) ⇒ Object
Add a notification for the ‘client run started’ event.
Instance Method Summary collapse
-
#build_node ⇒ Object
Builds a new node object for this client.
-
#converge(run_context) ⇒ Object
Converges the node.
- #enforce_path_sanity(env = ENV) ⇒ Object
-
#initialize ⇒ Client
constructor
Creates a new Chef::Client.
- #node_name ⇒ Object
-
#run ⇒ Object
Do a full run for this Chef::Client.
-
#run_completed_successfully ⇒ Object
Callback to fire notifications that the run completed successfully.
-
#run_failed ⇒ Object
Callback to fire notifications that the Chef run failed.
-
#run_started ⇒ Object
Callback to fire notifications that the Chef run is starting.
- #save_updated_node ⇒ Object
-
#setup_run_context ⇒ Object
Configures the Chef::Cookbook::FileVendor class to fetch file from the server or disk as appropriate, creates the run context for this run, and sanity checks the cookbook collection.
Constructor Details
#initialize ⇒ Client
Creates a new Chef::Client.
117 118 119 120 121 |
# File 'lib/chef/client.rb', line 117 def initialize @node = nil @run_status = nil @runner = nil end |
Instance Attribute Details
#node ⇒ Object
Returns the value of attribute node.
110 111 112 |
# File 'lib/chef/client.rb', line 110 def node @node end |
#rest ⇒ Object
Returns the value of attribute rest.
111 112 113 |
# File 'lib/chef/client.rb', line 111 def rest @rest end |
#run_status ⇒ Object (readonly)
Returns the value of attribute run_status.
114 115 116 |
# File 'lib/chef/client.rb', line 114 def run_status @run_status end |
#runner ⇒ Object
Returns the value of attribute runner.
112 113 114 |
# File 'lib/chef/client.rb', line 112 def runner @runner end |
Class Method Details
.clear_notifications ⇒ Object
Clears all notifications for client run status events. Primarily for testing purposes.
46 47 48 49 50 |
# File 'lib/chef/client.rb', line 46 def self.clear_notifications @run_start_notifications = nil @run_completed_successfully_notifications = nil @run_failed_notifications = nil end |
.run_completed_successfully_notifications ⇒ Object
The list of notifications to be run when the client run completes successfully.
59 60 61 |
# File 'lib/chef/client.rb', line 59 def self.run_completed_successfully_notifications @run_completed_successfully_notifications ||= [] end |
.run_failed_notifications ⇒ Object
The list of notifications to be run when the client run fails.
64 65 66 |
# File 'lib/chef/client.rb', line 64 def self.run_failed_notifications @run_failed_notifications ||= [] end |
.run_start_notifications ⇒ Object
The list of notifications to be run when the client run starts.
53 54 55 |
# File 'lib/chef/client.rb', line 53 def self.run_start_notifications @run_start_notifications ||= [] end |
.when_run_completes_successfully(¬ification_block) ⇒ Object
Add a notification for the ‘client run success’ event. The notification is provided as a block. The current Chef::RunStatus object will be passed to the notification_block when the event is triggered.
78 79 80 |
# File 'lib/chef/client.rb', line 78 def self.when_run_completes_successfully(¬ification_block) run_completed_successfully_notifications << notification_block end |
.when_run_fails(¬ification_block) ⇒ Object
Add a notification for the ‘client run failed’ event. The notification is provided as a block. The current Chef::RunStatus is passed to the notification_block when the event is triggered.
85 86 87 |
# File 'lib/chef/client.rb', line 85 def self.when_run_fails(¬ification_block) run_failed_notifications << notification_block end |
.when_run_starts(¬ification_block) ⇒ Object
Add a notification for the ‘client run started’ event. The notification is provided as a block. The current Chef::RunStatus object will be passed to the notification_block when the event is triggered.
71 72 73 |
# File 'lib/chef/client.rb', line 71 def self.when_run_starts(¬ification_block) run_start_notifications << notification_block end |
Instance Method Details
#build_node ⇒ Object
Builds a new node object for this client. Starts with querying for the FQDN of the current host (unless it is supplied).
Returns
- node<Chef::Node>
-
Returns the created node object, also stored in @node
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/chef/client.rb', line 200 def build_node Chef::Log.debug("Building node object for #{node_name}") @node = Chef::Node.build(node_name) # Allow user to override the environment of a node by specifying # a config parameter. if Chef::Config[:environment] && !Chef::Config[:environment].chop.empty? @node.chef_environment(Chef::Config[:environment]) end # tom: no longer using json_attribs with consume_external_attrs, # preferring to load from a node.rb # # consume_external_attrs may add items to the run_list. Save the # expanded run_list, which we will pass to the server later to # determine which versions of cookbooks to use. @node.reset_defaults_and_overrides @node.find_file(node_name) @run_list_expansion = @node.('disk') # @run_list_expansion is a RunListExpansion. # # Convert @expanded_run_list, which is an # Array of Hashes of the form # {:name => NAME, :version_constraint => Chef::VersionConstraint }, # into @expanded_run_list_with_versions, an # Array of Strings of the form # "#{NAME}@#{VERSION}" = @run_list_expansion.recipes.with_version_constraints_strings Chef::Log.info("Run List is [#{@node.run_list}]") Chef::Log.info("Run List expands to [#{@expanded_run_list_with_versions.join(', ')}]") @run_status = Chef::RunStatus.new(@node) @node end |
#converge(run_context) ⇒ Object
Converges the node.
Returns
- true
-
Always returns true
243 244 245 246 247 248 |
# File 'lib/chef/client.rb', line 243 def converge(run_context) Chef::Log.debug("Converging node #{node_name}") @runner = Chef::Runner.new(run_context) runner.converge true end |
#enforce_path_sanity(env = ENV) ⇒ Object
250 251 252 253 254 255 256 257 258 259 260 261 262 |
# File 'lib/chef/client.rb', line 250 def enforce_path_sanity(env=ENV) if Chef::Config[:enforce_path_sanity] && RUBY_PLATFORM !~ /mswin|mingw32|windows/ existing_paths = env["PATH"].split(':') SANE_PATHS.each do |sane_path| unless existing_paths.include?(sane_path) env_path = env["PATH"].dup env_path << ':' unless env["PATH"].empty? env_path << sane_path env["PATH"] = env_path end end end end |
#node_name ⇒ Object
183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/chef/client.rb', line 183 def node_name name = Chef::Config[:node_name] Chef::Config[:node_name] = name unless name msg = "Unable to determine node name: configure node_name or configure the system's hostname and fqdn" raise Chef::Exceptions::CannotDetermineNodeName, msg end name end |
#run ⇒ Object
Do a full run for this Chef::Client. Calls:
* build_node - Get the last known state, merge with local changes
* register - If not in solo mode, make sure the server knows about this client
* sync_cookbooks - If not in solo mode, populate the local cache with the node's cookbooks
* converge - Bring this system up to date
Returns
- true
-
Always returns true.
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/chef/client.rb', line 132 def run run_context = nil Chef::Log.info("*** Chef #{Chef::VERSION} ***") enforce_path_sanity build_node begin run_status.start_clock Chef::Log.info("Starting Chef Run for #{node.name}") run_started run_context = setup_run_context converge(run_context) save_updated_node run_status.stop_clock Chef::Log.info("Chef Run complete in #{run_status.elapsed_time} seconds") run_completed_successfully true rescue Exception => e run_status.stop_clock run_status.exception = e run_failed Chef::Log.debug("Re-raising exception: #{e.class} - #{e.message}\n#{e.backtrace.join("\n ")}") raise ensure run_status = nil end true end |
#run_completed_successfully ⇒ Object
Callback to fire notifications that the run completed successfully
97 98 99 100 101 |
# File 'lib/chef/client.rb', line 97 def run_completed_successfully self.class.run_completed_successfully_notifications.each do |notification| notification.call(run_status) end end |
#run_failed ⇒ Object
Callback to fire notifications that the Chef run failed
104 105 106 107 108 |
# File 'lib/chef/client.rb', line 104 def run_failed self.class.run_failed_notifications.each do |notification| notification.call(run_status) end end |
#run_started ⇒ Object
Callback to fire notifications that the Chef run is starting
90 91 92 93 94 |
# File 'lib/chef/client.rb', line 90 def run_started self.class.run_start_notifications.each do |notification| notification.call(run_status) end end |
#save_updated_node ⇒ Object
180 181 |
# File 'lib/chef/client.rb', line 180 def save_updated_node end |
#setup_run_context ⇒ Object
Configures the Chef::Cookbook::FileVendor class to fetch file from the server or disk as appropriate, creates the run context for this run, and sanity checks the cookbook collection.
Returns
- Chef::RunContext
-
the run context for this run.
171 172 173 174 175 176 177 178 |
# File 'lib/chef/client.rb', line 171 def setup_run_context Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::FileSystemFileVendor.new(manifest, Chef::Config[:cookbook_path]) } run_context = Chef::RunContext.new(node, Chef::CookbookCollection.new(Chef::CookbookLoader.new(Chef::Config[:cookbook_path]))) run_status.run_context = run_context run_context.load(@run_list_expansion) assert_cookbook_path_not_empty(run_context) run_context end |