summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Smith <tsmith@chef.io>2019-03-18 09:52:21 -0700
committerGitHub <noreply@github.com>2019-03-18 09:52:21 -0700
commit7cf3cc364475d4c52bd4672d16a34365873b5dcd (patch)
treef7b070083911086a6dfb49528a52884c935a0794
parent92073aeae333aa97b399090cf8ab7ceb5face006 (diff)
parentfb46ed8de333f035d8f915a8a318f660ac68087a (diff)
downloadchef-7cf3cc364475d4c52bd4672d16a34365873b5dcd.tar.gz
Merge pull request #8301 from chef/lcg/early-run-context
Early allocation of the Chef::RunContext
-rw-r--r--lib/chef/client.rb60
-rw-r--r--lib/chef/data_bag.rb2
-rw-r--r--lib/chef/policy_builder/expand_node_object.rb40
-rw-r--r--lib/chef/policy_builder/policyfile.rb9
-rw-r--r--lib/chef/run_context.rb43
-rw-r--r--spec/unit/client_spec.rb1
-rw-r--r--spec/unit/run_context_spec.rb2
7 files changed, 99 insertions, 58 deletions
diff --git a/lib/chef/client.rb b/lib/chef/client.rb
index 459ce77306..40266df64d 100644
--- a/lib/chef/client.rb
+++ b/lib/chef/client.rb
@@ -72,6 +72,13 @@ class Chef
attr_reader :run_status
#
+ # The run context of the Chef run.
+ #
+ # @return [Chef::RunContext]
+ #
+ attr_reader :run_context
+
+ #
# The node represented by this client.
#
# @return [Chef::Node]
@@ -92,13 +99,6 @@ class Chef
attr_reader :ohai
#
- # The rest object used to communicate with the Chef server.
- #
- # @return [Chef::ServerAPI]
- #
- attr_reader :rest
-
- #
# The runner used to converge.
#
# @return [Chef::Runner]
@@ -234,7 +234,10 @@ class Chef
run_status.run_id = request_id = Chef::RequestID.instance.request_id
- run_context = nil
+ @run_context = Chef::RunContext.new
+ run_context.events = events
+ run_status.run_context = run_context
+
events.run_start(Chef::VERSION, run_status)
logger.info("*** Chef #{Chef::VERSION} ***")
@@ -244,7 +247,15 @@ class Chef
enforce_path_sanity
run_ohai
- register unless Chef::Config[:solo_legacy_mode]
+ unless Chef::Config[:solo_legacy_mode]
+ register
+
+ # create and save the rest objects in the run_context
+ run_context.rest = rest
+ run_context.rest_clean = rest_clean
+
+ events.register(Chef::ResourceReporter.new(rest_clean))
+ end
load_node
@@ -259,7 +270,7 @@ class Chef
Chef.resource_handler_map.lock!
Chef.provider_handler_map.lock!
- run_context = setup_run_context
+ setup_run_context
load_required_recipe(@rest, run_context) unless Chef::Config[:solo_legacy_mode]
@@ -349,16 +360,27 @@ class Chef
end
end
+ # Standard rest object for talking to the Chef Server
+ #
+ # FIXME: Can we drop this and only use the rest_clean object? Did I add rest_clean
+ # only out of some cant-break-a-minor-version paranoia?
+ #
+ # @api private
+ def rest
+ @rest ||= Chef::ServerAPI.new(Chef::Config[:chef_server_url], client_name: node_name,
+ signing_key_filename: Chef::Config[:client_key])
+ end
+
# A rest object with validate_utf8 set to false. This will not throw exceptions
# on non-UTF8 strings in JSON but will sanitize them so that e.g. POSTs will
# never fail. Cannot be configured on a request-by-request basis, so we carry
# around another rest object for it.
#
# @api private
- def rest_clean(client_name = node_name, config = Chef::Config)
+ def rest_clean
@rest_clean ||=
- Chef::ServerAPI.new(config[:chef_server_url], client_name: client_name,
- signing_key_filename: config[:client_key], validate_utf8: false)
+ Chef::ServerAPI.new(Chef::Config[:chef_server_url], client_name: node_name,
+ signing_key_filename: Chef::Config[:client_key], validate_utf8: false)
end
#
@@ -451,9 +473,9 @@ class Chef
#
# @api private
def setup_run_context
- run_context = policy_builder.setup_run_context(specific_recipes)
+ @run_context = policy_builder.setup_run_context(specific_recipes, run_context)
assert_cookbook_path_not_empty(run_context)
- run_status.run_context = run_context
+ run_status.run_context = run_context # backcompat for chefspec
run_context
end
@@ -607,14 +629,6 @@ class Chef
Chef::ApiClient::Registration.new(node_name, config[:client_key]).run
events.registration_completed
end
- # We now have the client key, and should use it from now on.
- @rest = Chef::ServerAPI.new(config[:chef_server_url], client_name: client_name,
- signing_key_filename: config[:client_key])
- # force initialization of the rest_clean API object
- rest_clean(client_name, config)
- # FIXME: we could initialize rest_clean much earlier and hang it off of the run_status and then
- # have the ResourceReporter pull it off of the run_status and eliminate this tight coupling.
- events.register(Chef::ResourceReporter.new(rest_clean))
rescue Exception => e
# TODO this should probably only ever fire if we *started* registration.
# Move it to the block above.
diff --git a/lib/chef/data_bag.rb b/lib/chef/data_bag.rb
index 2533eb2f4a..e8545fb1c0 100644
--- a/lib/chef/data_bag.rb
+++ b/lib/chef/data_bag.rb
@@ -2,7 +2,7 @@
# Author:: Adam Jacob (<adam@chef.io>)
# Author:: Nuo Yan (<nuo@chef.io>)
# Author:: Christopher Brown (<cb@chef.io>)
-# Copyright:: Copyright 2009-2018, Chef Software Inc.
+# Copyright:: Copyright 2009-2019, Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/lib/chef/policy_builder/expand_node_object.rb b/lib/chef/policy_builder/expand_node_object.rb
index 839c3bb526..dda4a2b4c3 100644
--- a/lib/chef/policy_builder/expand_node_object.rb
+++ b/lib/chef/policy_builder/expand_node_object.rb
@@ -3,7 +3,7 @@
# Author:: Tim Hinderliter (<tim@chef.io>)
# Author:: Christopher Walters (<cw@chef.io>)
# Author:: Daniel DeLeo (<dan@chef.io>)
-# Copyright:: Copyright 2008-2018, Chef Software Inc.
+# Copyright:: Copyright 2008-2019, Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -73,25 +73,27 @@ class Chef
# attribute files and recipes, and constructing the entire resource collection.
# (FIXME: break up creating the run_context and compiling the cookbooks)
#
- def setup_run_context(specific_recipes = nil)
- if Chef::Config[:solo_legacy_mode]
- Chef::Cookbook::FileVendor.fetch_from_disk(Chef::Config[:cookbook_path])
- cl = Chef::CookbookLoader.new(Chef::Config[:cookbook_path])
- cl.load_cookbooks
- cookbook_collection = Chef::CookbookCollection.new(cl)
- cookbook_collection.validate!
- cookbook_collection.install_gems(events)
-
- run_context = Chef::RunContext.new(node, cookbook_collection, @events)
- else
- Chef::Cookbook::FileVendor.fetch_from_remote(api_service)
- cookbook_hash = sync_cookbooks
- cookbook_collection = Chef::CookbookCollection.new(cookbook_hash)
- cookbook_collection.validate!
- cookbook_collection.install_gems(events)
+ def setup_run_context(specific_recipes = nil, run_context = nil)
+ run_context ||= Chef::RunContext.new
+
+ run_context.events = events
+ run_context.node = node
+
+ cookbook_collection =
+ if Chef::Config[:solo_legacy_mode]
+ Chef::Cookbook::FileVendor.fetch_from_disk(Chef::Config[:cookbook_path])
+ cl = Chef::CookbookLoader.new(Chef::Config[:cookbook_path])
+ cl.load_cookbooks
+ Chef::CookbookCollection.new(cl)
+ else
+ Chef::Cookbook::FileVendor.fetch_from_remote(api_service)
+ cookbook_hash = sync_cookbooks
+ Chef::CookbookCollection.new(cookbook_hash)
+ end
- run_context = Chef::RunContext.new(node, cookbook_collection, @events)
- end
+ cookbook_collection.validate!
+ cookbook_collection.install_gems(events)
+ run_context.cookbook_collection = cookbook_collection
# TODO: move this into the cookbook_compilation_start hook
setup_chef_class(run_context)
diff --git a/lib/chef/policy_builder/policyfile.rb b/lib/chef/policy_builder/policyfile.rb
index 30818266f0..a4134c02bd 100644
--- a/lib/chef/policy_builder/policyfile.rb
+++ b/lib/chef/policy_builder/policyfile.rb
@@ -3,7 +3,7 @@
# Author:: Tim Hinderliter (<tim@chef.io>)
# Author:: Christopher Walters (<cw@chef.io>)
# Author:: Daniel DeLeo (<dan@chef.io>)
-# Copyright:: Copyright 2008-2018, Chef Software Inc.
+# Copyright:: Copyright 2008-2019, Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -175,14 +175,17 @@ class Chef
# run.
#
# @return [Chef::RunContext]
- def setup_run_context(specific_recipes = nil)
+ def setup_run_context(specific_recipes = nil, run_context = nil)
Chef::Cookbook::FileVendor.fetch_from_remote(api_service)
sync_cookbooks
cookbook_collection = Chef::CookbookCollection.new(cookbooks_to_sync)
cookbook_collection.validate!
cookbook_collection.install_gems(events)
- run_context = Chef::RunContext.new(node, cookbook_collection, events)
+ run_context ||= Chef::RunContext.new
+ run_context.node = node
+ run_context.cookbook_collection = cookbook_collection
+ run_context.events = events
setup_chef_class(run_context)
diff --git a/lib/chef/run_context.rb b/lib/chef/run_context.rb
index bba109360d..dc322b254f 100644
--- a/lib/chef/run_context.rb
+++ b/lib/chef/run_context.rb
@@ -2,7 +2,7 @@
# Author:: Adam Jacob (<adam@chef.io>)
# Author:: Christopher Walters (<cw@chef.io>)
# Author:: Tim Hinderliter (<tim@chef.io>)
-# Copyright:: Copyright 2008-2018, Chef Software Inc.
+# Copyright:: Copyright 2008-2019, Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -35,6 +35,20 @@ class Chef
# Global state
#
+ # Common rest object for using to talk to the Chef Server, this strictly 'validates' utf8
+ # and will throw. (will be nil on solo-legacy runs)
+ #
+ # @return [Chef::ServerAPI]
+ #
+ attr_accessor :rest
+
+ # Common rest object for using to talk to the Chef Server, this has utf8 sanitization turned
+ # on and will replace invalid utf8 with valid characters. (will be nil on solo-legacy runs)
+ #
+ # @return [Chef::ServerAPI]
+ #
+ attr_accessor :rest_clean
+
#
# The node for this run
#
@@ -47,7 +61,7 @@ class Chef
#
# @return [Chef::CookbookCollection]
#
- attr_reader :cookbook_collection
+ attr_accessor :cookbook_collection
#
# Resource Definitions for this run. Populated when the files in
@@ -62,7 +76,7 @@ class Chef
#
# @return [Chef::EventDispatch::Dispatcher]
#
- attr_reader :events
+ attr_accessor :events
#
# Hash of factoids for a reboot request.
@@ -165,15 +179,11 @@ class Chef
# @param events [EventDispatch::Dispatcher] The event dispatcher for this
# run.
#
- def initialize(node, cookbook_collection, events, logger = nil)
- @node = node
- @cookbook_collection = cookbook_collection
+ def initialize(node = nil, cookbook_collection = {}, events = nil, logger = nil)
@events = events
@logger = logger || Chef::Log.with_child
-
- node.run_context = self
- node.set_cookbook_attribute
-
+ @cookbook_collection = cookbook_collection
+ self.node = node if node
@definitions = Hash.new
@loaded_recipes_hash = {}
@loaded_attributes_hash = {}
@@ -184,6 +194,12 @@ class Chef
initialize_child_state
end
+ def node=(node)
+ @node = node
+ node.run_context = self
+ node.set_cookbook_attribute
+ end
+
#
# Triggers the compile phase of the chef run.
#
@@ -603,9 +619,11 @@ class Chef
cancel_reboot
config
cookbook_collection
+ cookbook_collection=
cookbook_compiler
definitions
events
+ events=
has_cookbook_file_in_cookbook?
has_template_in_cookbook?
load
@@ -620,12 +638,17 @@ class Chef
loaded_recipes_hash
logger
node
+ node=
open_stream
reboot_info
reboot_info=
reboot_requested?
request_reboot
resolve_attribute
+ rest
+ rest=
+ rest_clean
+ rest_clean=
unreachable_cookbook?
}
diff --git a/spec/unit/client_spec.rb b/spec/unit/client_spec.rb
index 6fb5a7df64..476647a651 100644
--- a/spec/unit/client_spec.rb
+++ b/spec/unit/client_spec.rb
@@ -102,7 +102,6 @@ shared_context "a client run" do
let(:api_client_exists?) { false }
let(:enable_fork) { false }
- let(:http_data_collector) { double("Chef::ServerAPI (data collector)") }
let(:http_cookbook_sync) { double("Chef::ServerAPI (cookbook sync)") }
let(:http_node_load) { double("Chef::ServerAPI (node)") }
let(:http_node_save) { double("Chef::ServerAPI (node save)") }
diff --git a/spec/unit/run_context_spec.rb b/spec/unit/run_context_spec.rb
index bfef3f8836..0d66b1f66d 100644
--- a/spec/unit/run_context_spec.rb
+++ b/spec/unit/run_context_spec.rb
@@ -2,7 +2,7 @@
# Author:: Adam Jacob (<adam@chef.io>)
# Author:: Tim Hinderliter (<tim@chef.io>)
# Author:: Christopher Walters (<cw@chef.io>)
-# Copyright:: Copyright 2008-2016, Chef Software Inc.
+# Copyright:: Copyright 2008-2019, Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");