summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/chef/application.rb22
-rw-r--r--lib/chef/application/client.rb4
-rw-r--r--lib/chef/application/solo.rb2
-rw-r--r--lib/chef/chef_class.rb1
-rw-r--r--lib/chef/chef_fs/file_system/chef_server/versioned_cookbook_dir.rb2
-rw-r--r--lib/chef/dsl/core.rb2
-rw-r--r--lib/chef/dsl/declare_resource.rb4
-rw-r--r--lib/chef/dsl/method_missing.rb2
-rw-r--r--lib/chef/dsl/recipe.rb2
-rw-r--r--lib/chef/dsl/universal.rb2
-rw-r--r--lib/chef/http.rb7
-rw-r--r--lib/chef/knife.rb22
-rw-r--r--lib/chef/mixin/powershell_out.rb2
-rw-r--r--lib/chef/mixin/shell_out.rb2
-rw-r--r--lib/chef/node.rb4
-rw-r--r--lib/chef/node/attribute.rb166
-rw-r--r--lib/chef/node/attribute_collections.rb43
-rw-r--r--lib/chef/node/common_api.rb6
-rw-r--r--lib/chef/node/immutable_collections.rb95
-rw-r--r--lib/chef/node/mixin/deep_merge_cache.rb61
-rw-r--r--lib/chef/node/mixin/immutablize_array.rb67
-rw-r--r--lib/chef/node/mixin/immutablize_hash.rb54
-rw-r--r--lib/chef/node/mixin/state_tracking.rb71
-rw-r--r--lib/chef/provider/cron.rb2
-rw-r--r--lib/chef/provider/group/suse.rb27
-rw-r--r--lib/chef/provider/package.rb12
-rw-r--r--lib/chef/provider/package/windows/exe.rb7
-rw-r--r--lib/chef/provider/package/windows/msi.rb2
-rw-r--r--lib/chef/provider/ruby_block.rb2
-rw-r--r--lib/chef/provider/user.rb10
-rw-r--r--lib/chef/resource.rb24
-rw-r--r--lib/chef/resource/file.rb2
-rw-r--r--lib/chef/resource/scm.rb8
-rw-r--r--lib/chef/resource/yum_repository.rb2
-rw-r--r--lib/chef/run_context.rb12
-rw-r--r--lib/chef/version.rb2
36 files changed, 470 insertions, 285 deletions
diff --git a/lib/chef/application.rb b/lib/chef/application.rb
index f9735a3769..7f15859c8f 100644
--- a/lib/chef/application.rb
+++ b/lib/chef/application.rb
@@ -28,7 +28,6 @@ require "mixlib/cli"
require "tmpdir"
require "rbconfig"
require "chef/application/exit_code"
-require "yaml"
class Chef
class Application
@@ -111,20 +110,13 @@ class Chef
end
extra_config_options = config.delete(:config_option)
Chef::Config.merge!(config)
- if extra_config_options
- extra_parsed_options = extra_config_options.inject({}) do |memo, option|
- # Sanity check value.
- Chef::Application.fatal!("Unparsable config option #{option.inspect}") if option.empty? || !option.include?("=")
- # Split including whitespace if someone does truly odd like
- # --config-option "foo = bar"
- key, value = option.split(/\s*=\s*/, 2)
- # Call to_sym because Chef::Config expects only symbol keys. Also
- # runs a simple parse on the string for some common types.
- memo[key.to_sym] = YAML.safe_load(value)
- memo
- end
- Chef::Config.merge!(extra_parsed_options)
- end
+ apply_extra_config_options(extra_config_options)
+ end
+
+ def apply_extra_config_options(extra_config_options)
+ Chef::Config.apply_extra_config_options(extra_config_options)
+ rescue ChefConfig::UnparsableConfigOption => e
+ Chef::Application.fatal!(e.message)
end
def set_specific_recipes
diff --git a/lib/chef/application/client.rb b/lib/chef/application/client.rb
index cbaa494b71..000aff905b 100644
--- a/lib/chef/application/client.rb
+++ b/lib/chef/application/client.rb
@@ -202,7 +202,7 @@ class Chef::Application::Client < Chef::Application
:short => "-o RunlistItem,RunlistItem...",
:long => "--override-runlist RunlistItem,RunlistItem...",
:description => "Replace current run list with specified items for a single run",
- :proc => lambda {|items|
+ :proc => lambda { |items|
items = items.split(",")
items.compact.map do |item|
Chef::RunList::RunListItem.new(item)
@@ -213,7 +213,7 @@ class Chef::Application::Client < Chef::Application
:short => "-r RunlistItem,RunlistItem...",
:long => "--runlist RunlistItem,RunlistItem...",
:description => "Permanently replace current run list with specified items",
- :proc => lambda {|items|
+ :proc => lambda { |items|
items = items.split(",")
items.compact.map do |item|
Chef::RunList::RunListItem.new(item)
diff --git a/lib/chef/application/solo.rb b/lib/chef/application/solo.rb
index 446a0f007d..1481338a9c 100644
--- a/lib/chef/application/solo.rb
+++ b/lib/chef/application/solo.rb
@@ -166,7 +166,7 @@ class Chef::Application::Solo < Chef::Application
:short => "-o RunlistItem,RunlistItem...",
:long => "--override-runlist RunlistItem,RunlistItem...",
:description => "Replace current run list with specified items",
- :proc => lambda {|items|
+ :proc => lambda { |items|
items = items.split(",")
items.compact.map do |item|
Chef::RunList::RunListItem.new(item)
diff --git a/lib/chef/chef_class.rb b/lib/chef/chef_class.rb
index f019448bd8..0bb15c03ca 100644
--- a/lib/chef/chef_class.rb
+++ b/lib/chef/chef_class.rb
@@ -30,6 +30,7 @@ require "chef/platform/provider_priority_map"
require "chef/platform/resource_priority_map"
require "chef/platform/provider_handler_map"
require "chef/platform/resource_handler_map"
+require "chef/event_dispatch/dsl"
class Chef
class << self
diff --git a/lib/chef/chef_fs/file_system/chef_server/versioned_cookbook_dir.rb b/lib/chef/chef_fs/file_system/chef_server/versioned_cookbook_dir.rb
index 269e160d43..b7c96c42e1 100644
--- a/lib/chef/chef_fs/file_system/chef_server/versioned_cookbook_dir.rb
+++ b/lib/chef/chef_fs/file_system/chef_server/versioned_cookbook_dir.rb
@@ -24,7 +24,7 @@ class Chef
module ChefServer
class VersionedCookbookDir < CookbookDir
# See Erchef code
- # https://github.com/opscode/chef_objects/blob/968a63344d38fd507f6ace05f73d53e9cd7fb043/src/chef_regex.erl#L94
+ # https://github.com/chef/chef_objects/blob/968a63344d38fd507f6ace05f73d53e9cd7fb043/src/chef_regex.erl#L94
VALID_VERSIONED_COOKBOOK_NAME = /^([.a-zA-Z0-9_-]+)-(\d+\.\d+\.\d+)$/
def initialize(name, parent, options = {})
diff --git a/lib/chef/dsl/core.rb b/lib/chef/dsl/core.rb
index 11507857cf..d7c5b6a006 100644
--- a/lib/chef/dsl/core.rb
+++ b/lib/chef/dsl/core.rb
@@ -1,7 +1,7 @@
#--
# Author:: Adam Jacob (<adam@chef.io>)
# Author:: Christopher Walters (<cw@chef.io>)
-# Copyright:: Copyright 2008-2016, 2009-2015 Chef Software, Inc.
+# Copyright:: Copyright 2008-2016 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/lib/chef/dsl/declare_resource.rb b/lib/chef/dsl/declare_resource.rb
index ed3083e1ca..5bd1f7fb8e 100644
--- a/lib/chef/dsl/declare_resource.rb
+++ b/lib/chef/dsl/declare_resource.rb
@@ -1,7 +1,7 @@
#--
# Author:: Adam Jacob (<adam@chef.io>)
# Author:: Christopher Walters
-# Copyright:: Copyright 2008-2016, 2009-2015 Chef Software, Inc.
+# Copyright:: Copyright 2008-2016 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -47,7 +47,7 @@ class Chef
when Chef::RunContext
rc
when :root
- Chef.run_context
+ run_context.root_run_context
when :parent
run_context.parent_run_context
else
diff --git a/lib/chef/dsl/method_missing.rb b/lib/chef/dsl/method_missing.rb
index 0d7ded30f3..51c3eac606 100644
--- a/lib/chef/dsl/method_missing.rb
+++ b/lib/chef/dsl/method_missing.rb
@@ -1,5 +1,5 @@
#--
-# Copyright:: Copyright 2008-2016, 2009-2015 Chef Software, Inc.
+# Copyright:: Copyright 2008-2016 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/lib/chef/dsl/recipe.rb b/lib/chef/dsl/recipe.rb
index 1bb8f130af..e2bd070179 100644
--- a/lib/chef/dsl/recipe.rb
+++ b/lib/chef/dsl/recipe.rb
@@ -1,7 +1,7 @@
#--
# Author:: Adam Jacob (<adam@chef.io>)
# Author:: Christopher Walters (<cw@chef.io>)
-# Copyright:: Copyright 2008-2016, 2009-2015 Chef Software, Inc.
+# Copyright:: Copyright 2008-2016 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/lib/chef/dsl/universal.rb b/lib/chef/dsl/universal.rb
index 810792f542..6e3d162b6f 100644
--- a/lib/chef/dsl/universal.rb
+++ b/lib/chef/dsl/universal.rb
@@ -1,7 +1,7 @@
#--
# Author:: Adam Jacob (<adam@chef.io>)
# Author:: Christopher Walters (<cw@chef.io>)
-# Copyright:: Copyright 2008-2016, 2009-2015 Chef Software, Inc.
+# Copyright:: Copyright 2008-2016 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/lib/chef/http.rb b/lib/chef/http.rb
index 924081bc6b..12acae953c 100644
--- a/lib/chef/http.rb
+++ b/lib/chef/http.rb
@@ -5,7 +5,7 @@
# Author:: Christopher Brown (<cb@chef.io>)
# Author:: Christopher Walters (<cw@chef.io>)
# Author:: Daniel DeLeo (<dan@chef.io>)
-# Copyright:: Copyright 2009-2016, 2013-2015 Chef Software, Inc.
+# Copyright:: Copyright 2009-2016 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -329,10 +329,9 @@ class Chef
# Runs a synchronous HTTP request, with no middleware applied (use #request
# to have the middleware applied). The entire response will be loaded into memory.
# @api private
- def send_http_request(method, url, headers, body, &response_handler)
- headers = build_headers(method, url, headers, body)
-
+ def send_http_request(method, url, base_headers, body, &response_handler)
retrying_http_errors(url) do
+ headers = build_headers(method, url, base_headers, body)
client = http_client(url)
return_value = nil
if block_given?
diff --git a/lib/chef/knife.rb b/lib/chef/knife.rb
index 0dbd02ceb4..8d40e06a43 100644
--- a/lib/chef/knife.rb
+++ b/lib/chef/knife.rb
@@ -408,11 +408,25 @@ class Chef
config_loader = self.class.load_config(config[:config_file])
config[:config_file] = config_loader.config_location
+ # For CLI options like `--config-option key=value`. These have to get
+ # parsed and applied separately.
+ extra_config_options = config.delete(:config_option)
+
merge_configs
apply_computed_config
- Chef::Config.export_proxies
+
# This has to be after apply_computed_config so that Mixlib::Log is configured
Chef::Log.info("Using configuration from #{config[:config_file]}") if config[:config_file]
+
+ begin
+ Chef::Config.apply_extra_config_options(extra_config_options)
+ rescue ChefConfig::UnparsableConfigOption => e
+ ui.error e.message
+ show_usage
+ exit(1)
+ end
+
+ Chef::Config.export_proxies
end
def show_usage
@@ -525,7 +539,11 @@ class Chef
# FIXME: yard with @yield
def create_object(object, pretty_name = nil, object_class: nil)
- output = edit_data(object, object_class: object_class)
+ output = if object_class
+ edit_data(object, object_class: object_class)
+ else
+ edit_hash(object)
+ end
if Kernel.block_given?
output = yield(output)
diff --git a/lib/chef/mixin/powershell_out.rb b/lib/chef/mixin/powershell_out.rb
index 74de85f86f..ab7cf00a72 100644
--- a/lib/chef/mixin/powershell_out.rb
+++ b/lib/chef/mixin/powershell_out.rb
@@ -91,7 +91,7 @@ class Chef
"-InputFormat None",
]
- "powershell.exe #{flags.join(' ')} -Command \"#{script}\""
+ "powershell.exe #{flags.join(' ')} -Command \"#{script.gsub('"', '\"')}\""
end
end
end
diff --git a/lib/chef/mixin/shell_out.rb b/lib/chef/mixin/shell_out.rb
index a258a91075..d8607c8de7 100644
--- a/lib/chef/mixin/shell_out.rb
+++ b/lib/chef/mixin/shell_out.rb
@@ -61,7 +61,7 @@ class Chef
[:command_log_prepend, :log_tag] ]
# CHEF-3090: Deprecate command_log_level and command_log_prepend
- # Patterned after https://github.com/opscode/chef/commit/e1509990b559984b43e428d4d801c394e970f432
+ # Patterned after https://github.com/chef/chef/commit/e1509990b559984b43e428d4d801c394e970f432
def run_command_compatible_options(command_args)
return command_args unless command_args.last.is_a?(Hash)
diff --git a/lib/chef/node.rb b/lib/chef/node.rb
index 212b1ced14..34a92d325b 100644
--- a/lib/chef/node.rb
+++ b/lib/chef/node.rb
@@ -197,7 +197,6 @@ class Chef
# Set a normal attribute of this node, but auto-vivify any Mashes that
# might be missing
def normal
- attributes.top_level_breadcrumb = nil
attributes.normal
end
@@ -209,14 +208,12 @@ class Chef
# Set a default of this node, but auto-vivify any Mashes that might
# be missing
def default
- attributes.top_level_breadcrumb = nil
attributes.default
end
# Set an override attribute of this node, but auto-vivify any Mashes that
# might be missing
def override
- attributes.top_level_breadcrumb = nil
attributes.override
end
@@ -237,7 +234,6 @@ class Chef
end
def automatic_attrs
- attributes.top_level_breadcrumb = nil
attributes.automatic
end
diff --git a/lib/chef/node/attribute.rb b/lib/chef/node/attribute.rb
index a4a07275c0..2d6aff0b21 100644
--- a/lib/chef/node/attribute.rb
+++ b/lib/chef/node/attribute.rb
@@ -17,6 +17,9 @@
# limitations under the License.
#
+require "chef/node/mixin/deep_merge_cache"
+require "chef/node/mixin/immutablize_hash"
+require "chef/node/mixin/state_tracking"
require "chef/node/immutable_collections"
require "chef/node/attribute_collections"
require "chef/decorator/unchain"
@@ -34,9 +37,18 @@ class Chef
class Attribute < Mash
include Immutablize
-
+ # FIXME: what is include Enumerable doing up here, when down below we delegate
+ # most of the Enumerable/Hash things to the underlying merged ImmutableHash. That
+ # is, in fact, the correct, thing to do, while including Enumerable to try to create
+ # a hash-like API gets lots of things wrong because of the difference between the
+ # Hash `each do |key, value|` vs the Array-like `each do |value|` API that Enumerable
+ # expects. This include should probably be deleted?
include Enumerable
+ include Chef::Node::Mixin::DeepMergeCache
+ include Chef::Node::Mixin::StateTracking
+ include Chef::Node::Mixin::ImmutablizeHash
+
# List of the component attribute hashes, in order of precedence, low to
# high.
COMPONENTS = [
@@ -175,39 +187,21 @@ class Chef
# return the automatic level attribute component
attr_reader :automatic
- # This is used to track the top level key as we descend through method chaining into
- # a precedence level (e.g. node.default['foo']['bar']['baz']= results in 'foo' here). We
- # need this so that when we hit the end of a method chain which results in a mutator method
- # that we can invalidate the whole top-level deep merge cache for the top-level key. It is
- # the responsibility of the accessor on the Chef::Node object to reset this to nil, and then
- # the first VividMash#[] call can ||= and set this to the first key we encounter.
- attr_accessor :top_level_breadcrumb
-
- # Cache of deep merged values by top-level key. This is a simple hash which has keys that are the
- # top-level keys of the node object, and we save the computed deep-merge for that key here. There is
- # no cache of subtrees.
- attr_accessor :deep_merge_cache
-
def initialize(normal, default, override, automatic)
- @default = VividMash.new(self, default)
- @env_default = VividMash.new(self, {})
- @role_default = VividMash.new(self, {})
- @force_default = VividMash.new(self, {})
-
- @normal = VividMash.new(self, normal)
+ @default = VividMash.new(default, self)
+ @env_default = VividMash.new({}, self)
+ @role_default = VividMash.new({}, self)
+ @force_default = VividMash.new({}, self)
- @override = VividMash.new(self, override)
- @role_override = VividMash.new(self, {})
- @env_override = VividMash.new(self, {})
- @force_override = VividMash.new(self, {})
+ @normal = VividMash.new(normal, self)
- @automatic = VividMash.new(self, automatic)
+ @override = VividMash.new(override, self)
+ @role_override = VividMash.new({}, self)
+ @env_override = VividMash.new({}, self)
+ @force_override = VividMash.new({}, self)
- @merged_attributes = nil
- @combined_override = nil
- @combined_default = nil
- @top_level_breadcrumb = nil
- @deep_merge_cache = {}
+ @automatic = VividMash.new(automatic, self)
+ super()
end
# Debug what's going on with an attribute. +args+ is a path spec to the
@@ -235,76 +229,62 @@ class Chef
end
end
- # Invalidate a key in the deep_merge_cache. If called with nil, or no arg, this will invalidate
- # the entire deep_merge cache. In the case of the user doing node.default['foo']['bar']['baz']=
- # that eventually results in a call to reset_cache('foo') here. A node.default=hash_thing call
- # must invalidate the entire cache and re-deep-merge the entire node object.
- def reset_cache(path = nil)
- if path.nil?
- @deep_merge_cache = {}
- else
- deep_merge_cache.delete(path.to_s)
- end
- end
-
- alias :reset :reset_cache
-
# Set the cookbook level default attribute component to +new_data+.
def default=(new_data)
reset
- @default = VividMash.new(self, new_data)
+ @default = VividMash.new(new_data, self)
end
# Set the role level default attribute component to +new_data+
def role_default=(new_data)
reset
- @role_default = VividMash.new(self, new_data)
+ @role_default = VividMash.new(new_data, self)
end
# Set the environment level default attribute component to +new_data+
def env_default=(new_data)
reset
- @env_default = VividMash.new(self, new_data)
+ @env_default = VividMash.new(new_data, self)
end
# Set the force_default (+default!+) level attributes to +new_data+
def force_default=(new_data)
reset
- @force_default = VividMash.new(self, new_data)
+ @force_default = VividMash.new(new_data, self)
end
# Set the normal level attribute component to +new_data+
def normal=(new_data)
reset
- @normal = VividMash.new(self, new_data)
+ @normal = VividMash.new(new_data, self)
end
# Set the cookbook level override attribute component to +new_data+
def override=(new_data)
reset
- @override = VividMash.new(self, new_data)
+ @override = VividMash.new(new_data, self)
end
# Set the role level override attribute component to +new_data+
def role_override=(new_data)
reset
- @role_override = VividMash.new(self, new_data)
+ @role_override = VividMash.new(new_data, self)
end
# Set the environment level override attribute component to +new_data+
def env_override=(new_data)
reset
- @env_override = VividMash.new(self, new_data)
+ @env_override = VividMash.new(new_data, self)
end
def force_override=(new_data)
reset
- @force_override = VividMash.new(self, new_data)
+ @force_override = VividMash.new(new_data, self)
end
def automatic=(new_data)
reset
- @automatic = VividMash.new(self, new_data)
+ @automatic = VividMash.new(new_data, self)
end
#
@@ -413,36 +393,6 @@ class Chef
write(:force_override, *args, value)
end
- # method-style access to attributes
-
- def read(*path)
- merged_attributes.read(*path)
- end
-
- def read!(*path)
- merged_attributes.read!(*path)
- end
-
- def exist?(*path)
- merged_attributes.exist?(*path)
- end
-
- def write(level, *args, &block)
- self.send(level).write(*args, &block)
- end
-
- def write!(level, *args, &block)
- self.send(level).write!(*args, &block)
- end
-
- def unlink(level, *path)
- self.send(level).unlink(*path)
- end
-
- def unlink!(level, *path)
- self.send(level).unlink!(*path)
- end
-
#
# Accessing merged attributes.
#
@@ -484,24 +434,39 @@ class Chef
write(:normal, *args) if read(*args[0...-1]).nil?
end
- def [](key)
- if deep_merge_cache.has_key?(key.to_s)
- # return the cache of the deep merged values by top-level key
- deep_merge_cache[key.to_s]
- else
- # save all the work of computing node[key]
- deep_merge_cache[key.to_s] = merged_attributes(key)
+ def has_key?(key)
+ COMPONENTS.any? do |component_ivar|
+ instance_variable_get(component_ivar).has_key?(key)
end
end
+ # method-style access to attributes (has to come after the prepended ImmutablizeHash)
- def []=(key, value)
- raise Exceptions::ImmutableAttributeModification
+ def read(*path)
+ merged_attributes.read(*path)
end
- def has_key?(key)
- COMPONENTS.any? do |component_ivar|
- instance_variable_get(component_ivar).has_key?(key)
- end
+ def read!(*path)
+ merged_attributes.read!(*path)
+ end
+
+ def exist?(*path)
+ merged_attributes.exist?(*path)
+ end
+
+ def write(level, *args, &block)
+ self.send(level).write(*args, &block)
+ end
+
+ def write!(level, *args, &block)
+ self.send(level).write!(*args, &block)
+ end
+
+ def unlink(level, *path)
+ self.send(level).unlink(*path)
+ end
+
+ def unlink!(level, *path)
+ self.send(level).unlink!(*path)
end
alias :attribute? :has_key?
@@ -600,7 +565,7 @@ class Chef
return nil if components.compact.empty?
- components.inject(ImmutableMash.new({})) do |merged, component|
+ components.inject(ImmutableMash.new({}, self)) do |merged, component|
Chef::Mixin::DeepMerge.hash_only_merge!(merged, component)
end
end
@@ -631,6 +596,11 @@ class Chef
end
end
+ # needed for __path__
+ def convert_key(key)
+ key.kind_of?(Symbol) ? key.to_s : key
+ end
+
end
end
diff --git a/lib/chef/node/attribute_collections.rb b/lib/chef/node/attribute_collections.rb
index 1bd31bceb0..b01b447978 100644
--- a/lib/chef/node/attribute_collections.rb
+++ b/lib/chef/node/attribute_collections.rb
@@ -17,6 +17,7 @@
#
require "chef/node/common_api"
+require "chef/node/mixin/state_tracking"
class Chef
class Node
@@ -63,15 +64,12 @@ class Chef
MUTATOR_METHODS.each do |mutator|
define_method(mutator) do |*args, &block|
ret = super(*args, &block)
- root.reset_cache(root.top_level_breadcrumb)
+ send_reset_cache
ret
end
end
- attr_reader :root
-
- def initialize(root, data)
- @root = root
+ def initialize(data = [])
super(data)
map! { |e| convert_value(e) }
end
@@ -96,14 +94,20 @@ class Chef
when AttrArray
value
when Hash
- VividMash.new(root, value)
+ VividMash.new(value, __root__)
when Array
- AttrArray.new(root, value)
+ AttrArray.new(value, __root__)
else
value
end
end
+ # needed for __path__
+ def convert_key(key)
+ key
+ end
+
+ prepend Chef::Node::Mixin::StateTracking
end
# == VividMash
@@ -117,8 +121,6 @@ class Chef
# #fetch, work as normal).
# * attr_accessor style element set and get are supported via method_missing
class VividMash < Mash
- attr_reader :root
-
include CommonAPI
# Methods that mutate a VividMash. Each of them is overridden so that it
@@ -126,7 +128,6 @@ class Chef
# object.
MUTATOR_METHODS = [
:clear,
- :delete,
:delete_if,
:keep_if,
:merge!,
@@ -140,23 +141,27 @@ class Chef
# For all of the mutating methods on Mash, override them so that they
# also invalidate the cached `merged_attributes` on the root Attribute
# object.
+
+ def delete(key, &block)
+ send_reset_cache(__path__ + [ key ])
+ super
+ end
+
MUTATOR_METHODS.each do |mutator|
define_method(mutator) do |*args, &block|
- root.reset_cache(root.top_level_breadcrumb)
+ send_reset_cache
super(*args, &block)
end
end
- def initialize(root, data = {})
- @root = root
+ def initialize(data = {})
super(data)
end
def [](key)
- root.top_level_breadcrumb ||= key
value = super
if !key?(key)
- value = self.class.new(root)
+ value = self.class.new({}, __root__)
self[key] = value
else
value
@@ -164,9 +169,8 @@ class Chef
end
def []=(key, value)
- root.top_level_breadcrumb ||= key
ret = super
- root.reset_cache(root.top_level_breadcrumb)
+ send_reset_cache(__path__ + [ key ])
ret
end
@@ -205,9 +209,9 @@ class Chef
when AttrArray
value
when Hash
- VividMash.new(root, value)
+ VividMash.new(value, __root__)
when Array
- AttrArray.new(root, value)
+ AttrArray.new(value, __root__)
else
value
end
@@ -217,6 +221,7 @@ class Chef
Mash.new(self)
end
+ prepend Chef::Node::Mixin::StateTracking
end
end
end
diff --git a/lib/chef/node/common_api.rb b/lib/chef/node/common_api.rb
index ce2c6b6878..9bb83a5178 100644
--- a/lib/chef/node/common_api.rb
+++ b/lib/chef/node/common_api.rb
@@ -32,7 +32,6 @@ class Chef
# - autovivifying / autoreplacing writer
# - non-container-ey intermediate objects are replaced with hashes
def write(*args, &block)
- root.top_level_breadcrumb = nil if respond_to?(:root)
value = block_given? ? yield : args.pop
last = args.pop
prev_memo = prev_key = nil
@@ -56,7 +55,6 @@ class Chef
# something that is not a container ("schema violation" issues).
#
def write!(*args, &block)
- root.top_level_breadcrumb = nil if respond_to?(:root)
value = block_given? ? yield : args.pop
last = args.pop
obj = args.inject(self) do |memo, key|
@@ -71,7 +69,6 @@ class Chef
# return true or false based on if the attribute exists
def exist?(*path)
- root.top_level_breadcrumb = nil if respond_to?(:root)
path.inject(self) do |memo, key|
return false unless valid_container?(memo, key)
if memo.is_a?(Hash)
@@ -103,7 +100,6 @@ class Chef
# non-autovivifying reader that throws an exception if the attribute does not exist
def read!(*path)
raise Chef::Exceptions::NoSuchAttribute unless exist?(*path)
- root.top_level_breadcrumb = nil if respond_to?(:root)
path.inject(self) do |memo, key|
memo[key]
end
@@ -112,10 +108,8 @@ class Chef
# FIXME:(?) does anyone really like the autovivifying reader that we have and wants the same behavior? readers that write? ugh...
def unlink(*path, last)
- root.top_level_breadcrumb = nil if respond_to?(:root)
hash = path.empty? ? self : read(*path)
return nil unless hash.is_a?(Hash) || hash.is_a?(Array)
- root.top_level_breadcrumb ||= last
hash.delete(last)
end
diff --git a/lib/chef/node/immutable_collections.rb b/lib/chef/node/immutable_collections.rb
index d4623ace2a..938135cbee 100644
--- a/lib/chef/node/immutable_collections.rb
+++ b/lib/chef/node/immutable_collections.rb
@@ -16,6 +16,9 @@
#
require "chef/node/common_api"
+require "chef/node/mixin/state_tracking"
+require "chef/node/mixin/immutablize_array"
+require "chef/node/mixin/immutablize_hash"
class Chef
class Node
@@ -24,9 +27,9 @@ class Chef
def immutablize(value)
case value
when Hash
- ImmutableMash.new(value)
+ ImmutableMash.new(value, __root__)
when Array
- ImmutableArray.new(value)
+ ImmutableArray.new(value, __root__)
else
value
end
@@ -49,55 +52,12 @@ class Chef
alias :internal_push :<<
private :internal_push
- # A list of methods that mutate Array. Each of these is overridden to
- # raise an error, making this instances of this class more or less
- # immutable.
- DISALLOWED_MUTATOR_METHODS = [
- :<<,
- :[]=,
- :clear,
- :collect!,
- :compact!,
- :default=,
- :default_proc=,
- :delete,
- :delete_at,
- :delete_if,
- :fill,
- :flatten!,
- :insert,
- :keep_if,
- :map!,
- :merge!,
- :pop,
- :push,
- :update,
- :reject!,
- :reverse!,
- :replace,
- :select!,
- :shift,
- :slice!,
- :sort!,
- :sort_by!,
- :uniq!,
- :unshift,
- ]
-
- def initialize(array_data)
+ def initialize(array_data = [])
array_data.each do |value|
internal_push(immutablize(value))
end
end
- # Redefine all of the methods that mutate a Hash to raise an error when called.
- # This is the magic that makes this object "Immutable"
- DISALLOWED_MUTATOR_METHODS.each do |mutator_method_name|
- define_method(mutator_method_name) do |*args, &block|
- raise Exceptions::ImmutableAttributeModification
- end
- end
-
# For elements like Fixnums, true, nil...
def safe_dup(e)
e.dup
@@ -125,6 +85,13 @@ class Chef
a
end
+ # for consistency's sake -- integers 'converted' to integers
+ def convert_key(key)
+ key
+ end
+
+ prepend Chef::Node::Mixin::StateTracking
+ prepend Chef::Node::Mixin::ImmutablizeArray
end
# == ImmutableMash
@@ -140,36 +107,13 @@ class Chef
# it is stale.
# * Values can be accessed in attr_reader-like fashion via method_missing.
class ImmutableMash < Mash
-
include Immutablize
include CommonAPI
alias :internal_set :[]=
private :internal_set
- DISALLOWED_MUTATOR_METHODS = [
- :[]=,
- :clear,
- :collect!,
- :default=,
- :default_proc=,
- :delete,
- :delete_if,
- :keep_if,
- :map!,
- :merge!,
- :update,
- :reject!,
- :replace,
- :select!,
- :shift,
- :write,
- :write!,
- :unlink,
- :unlink!,
- ]
-
- def initialize(mash_data)
+ def initialize(mash_data = {})
mash_data.each do |key, value|
internal_set(key, immutablize(value))
end
@@ -181,14 +125,6 @@ class Chef
alias :attribute? :has_key?
- # Redefine all of the methods that mutate a Hash to raise an error when called.
- # This is the magic that makes this object "Immutable"
- DISALLOWED_MUTATOR_METHODS.each do |mutator_method_name|
- define_method(mutator_method_name) do |*args, &block|
- raise Exceptions::ImmutableAttributeModification
- end
- end
-
def method_missing(symbol, *args)
if symbol == :to_ary
super
@@ -238,7 +174,8 @@ class Chef
h
end
+ prepend Chef::Node::Mixin::StateTracking
+ prepend Chef::Node::Mixin::ImmutablizeHash
end
-
end
end
diff --git a/lib/chef/node/mixin/deep_merge_cache.rb b/lib/chef/node/mixin/deep_merge_cache.rb
new file mode 100644
index 0000000000..b18d6b10cb
--- /dev/null
+++ b/lib/chef/node/mixin/deep_merge_cache.rb
@@ -0,0 +1,61 @@
+#--
+# Copyright:: Copyright 2016, Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class Chef
+ class Node
+ module Mixin
+ module DeepMergeCache
+ # Cache of deep merged values by top-level key. This is a simple hash which has keys that are the
+ # top-level keys of the node object, and we save the computed deep-merge for that key here. There is
+ # no cache of subtrees.
+ attr_accessor :deep_merge_cache
+
+ def initialize
+ @merged_attributes = nil
+ @combined_override = nil
+ @combined_default = nil
+ @deep_merge_cache = {}
+ end
+
+ # Invalidate a key in the deep_merge_cache. If called with nil, or no arg, this will invalidate
+ # the entire deep_merge cache. In the case of the user doing node.default['foo']['bar']['baz']=
+ # that eventually results in a call to reset_cache('foo') here. A node.default=hash_thing call
+ # must invalidate the entire cache and re-deep-merge the entire node object.
+ def reset_cache(path = nil)
+ if path.nil?
+ deep_merge_cache.clear
+ else
+ deep_merge_cache.delete(path.to_s)
+ end
+ end
+
+ alias :reset :reset_cache
+
+ def [](key)
+ if deep_merge_cache.has_key?(key.to_s)
+ # return the cache of the deep merged values by top-level key
+ deep_merge_cache[key.to_s]
+ else
+ # save all the work of computing node[key]
+ deep_merge_cache[key.to_s] = merged_attributes(key)
+ end
+ end
+
+ end
+ end
+ end
+end
diff --git a/lib/chef/node/mixin/immutablize_array.rb b/lib/chef/node/mixin/immutablize_array.rb
new file mode 100644
index 0000000000..cfa7266b9a
--- /dev/null
+++ b/lib/chef/node/mixin/immutablize_array.rb
@@ -0,0 +1,67 @@
+#--
+# Copyright:: Copyright 2016, Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class Chef
+ class Node
+ module Mixin
+ module ImmutablizeArray
+ # A list of methods that mutate Array. Each of these is overridden to
+ # raise an error, making this instances of this class more or less
+ # immutable.
+ DISALLOWED_MUTATOR_METHODS = [
+ :<<,
+ :[]=,
+ :clear,
+ :collect!,
+ :compact!,
+ :default=,
+ :default_proc=,
+ :delete,
+ :delete_at,
+ :delete_if,
+ :fill,
+ :flatten!,
+ :insert,
+ :keep_if,
+ :map!,
+ :merge!,
+ :pop,
+ :push,
+ :update,
+ :reject!,
+ :reverse!,
+ :replace,
+ :select!,
+ :shift,
+ :slice!,
+ :sort!,
+ :sort_by!,
+ :uniq!,
+ :unshift,
+ ]
+
+ # Redefine all of the methods that mutate a Hash to raise an error when called.
+ # This is the magic that makes this object "Immutable"
+ DISALLOWED_MUTATOR_METHODS.each do |mutator_method_name|
+ define_method(mutator_method_name) do |*args, &block|
+ raise Exceptions::ImmutableAttributeModification
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/node/mixin/immutablize_hash.rb b/lib/chef/node/mixin/immutablize_hash.rb
new file mode 100644
index 0000000000..f09e6944fc
--- /dev/null
+++ b/lib/chef/node/mixin/immutablize_hash.rb
@@ -0,0 +1,54 @@
+#--
+# Copyright:: Copyright 2016, Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class Chef
+ class Node
+ module Mixin
+ module ImmutablizeHash
+ DISALLOWED_MUTATOR_METHODS = [
+ :[]=,
+ :clear,
+ :collect!,
+ :default=,
+ :default_proc=,
+ :delete,
+ :delete_if,
+ :keep_if,
+ :map!,
+ :merge!,
+ :update,
+ :reject!,
+ :replace,
+ :select!,
+ :shift,
+ :write,
+ :write!,
+ :unlink,
+ :unlink!,
+ ]
+
+ # Redefine all of the methods that mutate a Hash to raise an error when called.
+ # This is the magic that makes this object "Immutable"
+ DISALLOWED_MUTATOR_METHODS.each do |mutator_method_name|
+ define_method(mutator_method_name) do |*args, &block|
+ raise Exceptions::ImmutableAttributeModification
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/node/mixin/state_tracking.rb b/lib/chef/node/mixin/state_tracking.rb
new file mode 100644
index 0000000000..9be102eeeb
--- /dev/null
+++ b/lib/chef/node/mixin/state_tracking.rb
@@ -0,0 +1,71 @@
+#--
+# Copyright:: Copyright 2016, Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class Chef
+ class Node
+ module Mixin
+ module StateTracking
+ attr_reader :__path__
+ attr_reader :__root__
+
+ NULL = Object.new
+
+ def initialize(data = NULL, root = self)
+ # __path__ and __root__ must be nil when we call super so it knows
+ # to avoid resetting the cache on construction
+ data == NULL ? super() : super(data)
+ @__path__ = []
+ @__root__ = root
+ end
+
+ def [](key)
+ ret = super
+ if ret.is_a?(StateTracking)
+ ret.__path__ = __path__ + [ convert_key(key) ]
+ ret.__root__ = __root__
+ end
+ ret
+ end
+
+ def []=(key, value)
+ ret = super
+ if ret.is_a?(StateTracking)
+ ret.__path__ = __path__ + [ convert_key(key) ]
+ ret.__root__ = __root__
+ end
+ ret
+ end
+
+ protected
+
+ def __path__=(path)
+ @__path__ = path
+ end
+
+ def __root__=(root)
+ @__root__ = root
+ end
+
+ private
+
+ def send_reset_cache(path = __path__)
+ __root__.reset_cache(path.first) if !__root__.nil? && __root__.respond_to?(:reset_cache) && !path.nil?
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/cron.rb b/lib/chef/provider/cron.rb
index 7baaeec0c5..35e5bb874c 100644
--- a/lib/chef/provider/cron.rb
+++ b/lib/chef/provider/cron.rb
@@ -199,7 +199,7 @@ class Chef
def set_environment_var(attr_name, attr_value)
if %w{MAILTO PATH SHELL HOME}.include?(attr_name)
- @current_resource.send(attr_name.downcase.to_sym, attr_value)
+ @current_resource.send(attr_name.downcase.to_sym, attr_value.gsub(/^"|"$/, ""))
else
@current_resource.environment(@current_resource.environment.merge(attr_name => attr_value))
end
diff --git a/lib/chef/provider/group/suse.rb b/lib/chef/provider/group/suse.rb
index a79038e25e..71336f9311 100644
--- a/lib/chef/provider/group/suse.rb
+++ b/lib/chef/provider/group/suse.rb
@@ -17,6 +17,7 @@
#
require "chef/provider/group/groupadd"
+require "etc"
class Chef
class Provider
@@ -36,24 +37,42 @@ class Chef
a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/sbin/groupmod for #{@new_resource.name}"
# No whyrun alternative: this component should be available in the base install of any given system that uses it
end
+
+ requirements.assert(:create, :manage, :modify) do |a|
+ a.assertion do
+ begin
+ to_add(@new_resource.members).all? { |member| Etc.getpwnam(member) }
+ rescue
+ false
+ end
+ end
+ a.failure_message Chef::Exceptions::Group, "Could not add users #{to_add(@new_resource.members).join(", ")} to #{@new_resource.group_name}: one of these users does not exist"
+ a.whyrun "Could not find one of these users: #{to_add(@new_resource.members).join(", ")}. Assuming it will be created by a prior step"
+ end
end
def set_members(members)
- to_delete = @current_resource.members - members
- to_delete.each do |member|
+ to_remove(members).each do |member|
remove_member(member)
end
- to_add = members - @current_resource.members
- to_add.each do |member|
+ to_add(members).each do |member|
add_member(member)
end
end
+ def to_add(members)
+ members - @current_resource.members
+ end
+
def add_member(member)
shell_out!("groupmod -A #{member} #{@new_resource.group_name}")
end
+ def to_remove(members)
+ @current_resource.members - members
+ end
+
def remove_member(member)
shell_out!("groupmod -R #{member} #{@new_resource.group_name}")
end
diff --git a/lib/chef/provider/package.rb b/lib/chef/provider/package.rb
index 3f641145e6..3fed63c914 100644
--- a/lib/chef/provider/package.rb
+++ b/lib/chef/provider/package.rb
@@ -31,6 +31,8 @@ class Chef
include Chef::Mixin::ShellOut
extend Chef::Mixin::SubclassDirective
+ use_inline_resources
+
# subclasses declare this if they want all their arguments as arrays of packages and names
subclass_directive :use_multipackage_api
# subclasses declare this if they want sources (filenames) pulled from their package names
@@ -81,7 +83,7 @@ class Chef
end
end
- def action_install
+ action :install do
unless target_version_array.any?
Chef::Log.debug("#{@new_resource} is already installed - nothing to do")
return
@@ -116,7 +118,7 @@ class Chef
private :install_description
- def action_upgrade
+ action :upgrade do
if !target_version_array.any?
Chef::Log.debug("#{@new_resource} no versions to upgrade - nothing to do")
return
@@ -146,7 +148,7 @@ class Chef
private :upgrade_description
- def action_remove
+ action :remove do
if removing_package?
description = @new_resource.version ? "version #{@new_resource.version} of " : ""
converge_by("remove #{description}package #{@current_resource.package_name}") do
@@ -181,7 +183,7 @@ class Chef
end
end
- def action_purge
+ action :purge do
if removing_package?
description = @new_resource.version ? "version #{@new_resource.version} of" : ""
converge_by("purge #{description} package #{@current_resource.package_name}") do
@@ -193,7 +195,7 @@ class Chef
end
end
- def action_reconfig
+ action :reconfig do
if @current_resource.version == nil
Chef::Log.debug("#{@new_resource} is NOT installed - nothing to do")
return
diff --git a/lib/chef/provider/package/windows/exe.rb b/lib/chef/provider/package/windows/exe.rb
index 44a2f19d1e..60065d9019 100644
--- a/lib/chef/provider/package/windows/exe.rb
+++ b/lib/chef/provider/package/windows/exe.rb
@@ -89,9 +89,10 @@ class Chef
end
def current_installed_version
- @current_installed_version ||= uninstall_entries.count == 0 ? nil : begin
- uninstall_entries.map { |entry| entry.display_version }.uniq
- end
+ @current_installed_version ||=
+ if uninstall_entries.count != 0
+ uninstall_entries.map { |entry| entry.display_version }.uniq
+ end
end
# http://unattended.sourceforge.net/installers.php
diff --git a/lib/chef/provider/package/windows/msi.rb b/lib/chef/provider/package/windows/msi.rb
index 301baa4ed5..ee3b2f7e8e 100644
--- a/lib/chef/provider/package/windows/msi.rb
+++ b/lib/chef/provider/package/windows/msi.rb
@@ -50,7 +50,7 @@ class Chef
Chef::Log.debug("#{new_resource} checking package status and version for #{product_code}")
get_installed_version(product_code)
else
- uninstall_entries.count == 0 ? nil : begin
+ if uninstall_entries.count != 0
uninstall_entries.map { |entry| entry.display_version }.uniq
end
end
diff --git a/lib/chef/provider/ruby_block.rb b/lib/chef/provider/ruby_block.rb
index 0817b14044..18ee9cecc5 100644
--- a/lib/chef/provider/ruby_block.rb
+++ b/lib/chef/provider/ruby_block.rb
@@ -1,7 +1,7 @@
#
# Author:: Adam Jacob (<adam@chef.io>)
# Author:: AJ Christensen (<aj@chef.io>)
-# Copyright:: Copyright 2009-2016, Opscode
+# Copyright:: Copyright 2009-2016, Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/lib/chef/provider/user.rb b/lib/chef/provider/user.rb
index f6b088d333..4b05ac8f5e 100644
--- a/lib/chef/provider/user.rb
+++ b/lib/chef/provider/user.rb
@@ -113,15 +113,13 @@ class Chef
# <true>:: If a change is required
# <false>:: If the users are identical
def compare_user
- changed = [ :comment, :home, :shell, :password ].select do |user_attrib|
- !@new_resource.send(user_attrib).nil? && @new_resource.send(user_attrib) != @current_resource.send(user_attrib)
- end
+ return true if !@new_resource.home.nil? && Pathname.new(@new_resource.home).cleanpath != Pathname.new(@current_resource.home).cleanpath
- changed += [ :uid, :gid ].select do |user_attrib|
- !@new_resource.send(user_attrib).nil? && @new_resource.send(user_attrib).to_s != @current_resource.send(user_attrib).to_s
+ [ :comment, :shell, :password, :uid, :gid ].each do |user_attrib|
+ return true if !@new_resource.send(user_attrib).nil? && @new_resource.send(user_attrib).to_s != @current_resource.send(user_attrib).to_s
end
- changed.any?
+ false
end
def action_create
diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb
index 8048330ce1..074ab772a1 100644
--- a/lib/chef/resource.rb
+++ b/lib/chef/resource.rb
@@ -186,22 +186,16 @@ class Chef
# This should most likely be paired with action :nothing
#
# @param arg [Array[Symbol], Symbol] A list of actions (e.g. `:create`)
- # @return [Array[Symbol]] the list of actions.
#
- def delayed_action(arg = nil)
- if arg
- arg = Array(arg).map(&:to_sym)
- arg.each do |action|
- validate(
- { action: action },
- { action: { kind_of: Symbol, equal_to: allowed_actions } }
- )
- # the resource effectively sends a delayed notification to itself
- run_context.add_delayed_action(Notification.new(self, action, self))
- end
- @delayed_action = arg
- else
- @delayed_action
+ def delayed_action(arg)
+ arg = Array(arg).map(&:to_sym)
+ arg.map do |action|
+ validate(
+ { action: action },
+ { action: { kind_of: Symbol, equal_to: allowed_actions } }
+ )
+ # the resource effectively sends a delayed notification to itself
+ run_context.add_delayed_action(Notification.new(self, action, self))
end
end
diff --git a/lib/chef/resource/file.rb b/lib/chef/resource/file.rb
index 207de63778..5c275a574f 100644
--- a/lib/chef/resource/file.rb
+++ b/lib/chef/resource/file.rb
@@ -1,7 +1,7 @@
#
# Author:: Adam Jacob (<adam@chef.io>)
# Author:: Seth Chisamore (<schisamo@chef.io>)
-# Copyright:: Copyright 2008-2016, 2011-2015 Chef Software, Inc.
+# Copyright:: Copyright 2008-2016 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/lib/chef/resource/scm.rb b/lib/chef/resource/scm.rb
index 1e8c71e59d..533723c2c4 100644
--- a/lib/chef/resource/scm.rb
+++ b/lib/chef/resource/scm.rb
@@ -89,13 +89,7 @@ class Chef
)
end
- def svn_password(arg = nil)
- set_or_return(
- :svn_password,
- arg,
- :kind_of => String
- )
- end
+ property :svn_password, String, sensitive: true, desired_state: false
def svn_arguments(arg = nil)
@svn_arguments, arg = nil, nil if arg == false
diff --git a/lib/chef/resource/yum_repository.rb b/lib/chef/resource/yum_repository.rb
index b1859361b1..1c215b51ff 100644
--- a/lib/chef/resource/yum_repository.rb
+++ b/lib/chef/resource/yum_repository.rb
@@ -57,7 +57,7 @@ class Chef
property :password, String, regex: /.*/
property :repo_gpgcheck, [TrueClass, FalseClass]
property :report_instanceid, [TrueClass, FalseClass]
- property :repositoryid, String, regex: /.*/, name_attribute: true
+ property :repositoryid, String, regex: /.*/, name_property: true
property :sensitive, [TrueClass, FalseClass], default: false
property :skip_if_unavailable, [TrueClass, FalseClass]
property :source, String, regex: /.*/
diff --git a/lib/chef/run_context.rb b/lib/chef/run_context.rb
index 5d29f766c9..626977b09f 100644
--- a/lib/chef/run_context.rb
+++ b/lib/chef/run_context.rb
@@ -85,6 +85,17 @@ class Chef
attr_reader :parent_run_context
#
+ # The root run context.
+ #
+ # @return [Chef::RunContext] The root run context.
+ #
+ def root_run_context
+ rc = self
+ rc = rc.parent_run_context until rc.parent_run_context.nil?
+ rc
+ end
+
+ #
# The collection of resources intended to be converged (and able to be
# notified).
#
@@ -653,6 +664,7 @@ ERROR_MESSAGE
notifies_immediately
notifies_delayed
parent_run_context
+ root_run_context
resource_collection
resource_collection=
}.map { |x| x.to_sym }
diff --git a/lib/chef/version.rb b/lib/chef/version.rb
index 078d42c305..3413b702c4 100644
--- a/lib/chef/version.rb
+++ b/lib/chef/version.rb
@@ -21,7 +21,7 @@
class Chef
CHEF_ROOT = File.expand_path("../..", __FILE__)
- VERSION = "12.15.26"
+ VERSION = "12.16.23"
end
#