From f246fe546c965720eadadc01c7318569d2795aba Mon Sep 17 00:00:00 2001 From: James FitzGibbon Date: Wed, 4 Mar 2015 15:47:25 -0800 Subject: Add warnings to 'knife node run list remove ...' when the item to be removed doesn't exist --- lib/chef/knife/node_run_list_remove.rb | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/node_run_list_remove.rb b/lib/chef/knife/node_run_list_remove.rb index 4b8953a264..ef03c176b8 100644 --- a/lib/chef/knife/node_run_list_remove.rb +++ b/lib/chef/knife/node_run_list_remove.rb @@ -42,7 +42,18 @@ class Chef entries = @name_args[1].split(',').map { |e| e.strip } end - entries.each { |e| node.run_list.remove(e) } + # iterate over the list of things to remove, + # warning if one of them was not found + entries.each do |e| + if node.run_list.find { |rli| e == rli.to_s } + node.run_list.remove(e) + else + ui.warn "#{e} is not in the run list" + unless e =~ /^(recipe|role)\[/ + ui.warn '(did you forget recipe[] or role[] around it?)' + end + end + end node.save -- cgit v1.2.1 From 4cdce72a39b6f2e9ad0eb3029d861c99494738f0 Mon Sep 17 00:00:00 2001 From: Sean Walberg Date: Sun, 5 Apr 2015 00:10:57 -0500 Subject: Allow tags to be set on a node during bootstrap I can set attributes, environment, and run_list, but why not tags? Some of our recipes are driven off of tags, such as for sudo access or membership in a load balancing pool. If this patch is accepted then I will add the corresponding feature to knife-vsphere. This patch only works with the new vault method, not the validator key method. If someone has some pointers on where to add it in the validator method I'd be happy to amend. --- lib/chef/knife/bootstrap.rb | 6 ++++++ lib/chef/knife/bootstrap/client_builder.rb | 3 +++ 2 files changed, 9 insertions(+) (limited to 'lib/chef') diff --git a/lib/chef/knife/bootstrap.rb b/lib/chef/knife/bootstrap.rb index a4095e8402..157c815a98 100644 --- a/lib/chef/knife/bootstrap.rb +++ b/lib/chef/knife/bootstrap.rb @@ -143,6 +143,12 @@ class Chef :proc => lambda { |o| o.split(/[\s,]+/) }, :default => [] + option :tags, + :long => "--tags TAGS", + :description => "Comma separated list of tags to apply to the node", + :proc => lambda { |o| o.split(/[\s,]+/) }, + :default => [] + option :first_boot_attributes, :short => "-j JSON_ATTRIBS", :long => "--json-attributes", diff --git a/lib/chef/knife/bootstrap/client_builder.rb b/lib/chef/knife/bootstrap/client_builder.rb index b9c1d98bec..32258f6fa5 100644 --- a/lib/chef/knife/bootstrap/client_builder.rb +++ b/lib/chef/knife/bootstrap/client_builder.rb @@ -140,6 +140,9 @@ class Chef node.run_list(normalized_run_list) node.normal_attrs = first_boot_attributes if first_boot_attributes node.environment(environment) if environment + (knife_config[:tags] || []).each do |tag| + node.tags << tag + end node end end -- cgit v1.2.1 From f6835a4f5af4a380d7e35e32ddd8c3a0fe7f2ac3 Mon Sep 17 00:00:00 2001 From: Sean Walberg Date: Thu, 9 Apr 2015 09:54:49 -0500 Subject: If tags are present, add to the first-boot.json Thanks to @coderanger from IRC for pointing me in the right direction. I also snuck in a whitespace fix --- lib/chef/knife/core/bootstrap_context.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/core/bootstrap_context.rb b/lib/chef/knife/core/bootstrap_context.rb index 7197653489..867b6fe366 100644 --- a/lib/chef/knife/core/bootstrap_context.rb +++ b/lib/chef/knife/core/bootstrap_context.rb @@ -163,11 +163,14 @@ CONFIG end def first_boot - (@config[:first_boot_attributes] || {}).merge(:run_list => @run_list) + (@config[:first_boot_attributes] || {}).tap do |attributes| + attributes.merge!(:run_list => @run_list) + attributes.merge!(:tags => @config[:tags]) if @config[:tags] && !@config[:tags].empty? + end end private - + # Returns a string for copying the trusted certificates on the workstation to the system being bootstrapped # This string should contain both the commands necessary to both create the files, as well as their content def trusted_certs_content -- cgit v1.2.1 From 841b973d59382192058d05f7a5d46c8e1ea1a875 Mon Sep 17 00:00:00 2001 From: cmluciano Date: Fri, 20 Mar 2015 16:19:04 -0400 Subject: Fix condition of removing a group before user error. This should fix [issue 1586](https://github.com/chef/chef/issues/1586). The issue is that if a group is removed before the user, the GID remained and causes an error. This should remove the check for remove actions. --- lib/chef/provider/user.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/user.rb b/lib/chef/provider/user.rb index f6ac72448e..de261105b3 100644 --- a/lib/chef/provider/user.rb +++ b/lib/chef/provider/user.rb @@ -90,7 +90,7 @@ class Chef end def define_resource_requirements - requirements.assert(:all_actions) do |a| + requirements.assert(:create, :modify, :manage, :lock, :unlock) do |a| a.assertion { @group_name_resolved } a.failure_message Chef::Exceptions::User, "Couldn't lookup integer GID for group name #{@new_resource.gid}" a.whyrun "group name #{@new_resource.gid} does not exist. This will cause group assignment to fail. Assuming this group will have been created previously." -- cgit v1.2.1 From 1162606a8d5f7be3a7af9526732fe8cb61f9c96b Mon Sep 17 00:00:00 2001 From: Jay Mundrawala Date: Mon, 1 Jun 2015 16:40:47 -0700 Subject: Allow creation of secure strings over remoting/services The issue here is the user profile does not get loaded when running over winrm / as a service. This user profile is needed to use the DPAPI to encrypt the data for the current user. Should fix #3246 --- lib/chef/win32/crypto.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/win32/crypto.rb b/lib/chef/win32/crypto.rb index 79cf51b002..a047071b79 100644 --- a/lib/chef/win32/crypto.rb +++ b/lib/chef/win32/crypto.rb @@ -29,7 +29,7 @@ class Chef def self.encrypt(str, &block) data_blob = CRYPT_INTEGER_BLOB.new - unless CryptProtectData(CRYPT_INTEGER_BLOB.new(str.to_wstring), nil, nil, nil, nil, 0, data_blob) + unless CryptProtectData(CRYPT_INTEGER_BLOB.new(str.to_wstring), nil, nil, nil, nil, CRYPTPROTECT_LOCAL_MACHINE, data_blob) Chef::ReservedNames::Win32::Error.raise! end bytes = data_blob[:pbData].get_bytes(0, data_blob[:cbData]) -- cgit v1.2.1 From d9820c430b686a1dedd4ab2cadd20b0cadbbb0d7 Mon Sep 17 00:00:00 2001 From: Kaushik C Date: Tue, 9 Jun 2015 16:00:06 -0400 Subject: Fixing Issue #2513 - the broken render of nested partial templates with variables Authors: Kaushik C , Sam Dunne --- lib/chef/mixin/template.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/chef') diff --git a/lib/chef/mixin/template.rb b/lib/chef/mixin/template.rb index d705a9e7be..9b35bbcc33 100644 --- a/lib/chef/mixin/template.rb +++ b/lib/chef/mixin/template.rb @@ -89,6 +89,7 @@ class Chef raise "You cannot render partials in this context" unless @template_finder partial_variables = options.delete(:variables) || _public_instance_variables + partial_variables[:template_finder] = @template_finder partial_context = self.class.new(partial_variables) partial_context._extend_modules(@_extension_modules) -- cgit v1.2.1 From c93f286bb7c187522a1294ea8e52a5aa04273162 Mon Sep 17 00:00:00 2001 From: Nitz Date: Tue, 31 Mar 2015 18:12:35 +0300 Subject: Migrated deploy resource to use shell_out instead of run_command Should help with troubleshooting failed migrations --- lib/chef/provider/deploy.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/deploy.rb b/lib/chef/provider/deploy.rb index 6d9b7f4397..77a0410593 100644 --- a/lib/chef/provider/deploy.rb +++ b/lib/chef/provider/deploy.rb @@ -201,7 +201,7 @@ class Chef converge_by("execute migration command #{@new_resource.migration_command}") do Chef::Log.info "#{@new_resource} migrating #{@new_resource.user} with environment #{env_info}" - run_command(run_options(:command => @new_resource.migration_command, :cwd=>release_path, :log_level => :info)) + shell_out!(@new_resource.migration_command,run_options(:cwd=>release_path, :log_level => :info)) end end end @@ -221,7 +221,7 @@ class Chef else converge_by("restart app using command #{@new_resource.restart_command}") do Chef::Log.info("#{@new_resource} restarting app") - run_command(run_options(:command => @new_resource.restart_command, :cwd => @new_resource.current_path)) + shell_out!(@new_resource.restart_command,run_options(:cwd=>@new_resource.current_path)) end end end -- cgit v1.2.1 From 9022f929ea74930b4b581edd2a08cd67025c6b68 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 21 Aug 2015 11:37:45 -0500 Subject: Further revision for compile errors due to frozen Per the discussion at the bottom of https://github.com/chef/chef/pull/3757, doing some further refinement of compile_error_inspector's message regarding frozen objects. Helps further address the original issue https://github.com/chef/chef/issues/3734. --- .../error_inspectors/compile_error_inspector.rb | 30 ++++++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/formatters/error_inspectors/compile_error_inspector.rb b/lib/chef/formatters/error_inspectors/compile_error_inspector.rb index fe418ed485..3c22d2e763 100644 --- a/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +++ b/lib/chef/formatters/error_inspectors/compile_error_inspector.rb @@ -47,11 +47,31 @@ class Chef if exception_message_modifying_frozen? msg = <<-MESSAGE - Chef calls the freeze method on certain ruby objects to prevent - pollution across multiple instances. Specifically, resource - properties have frozen default values to avoid modifying the - property for all instances of a resource. Try modifying the - particular instance variable or using an instance accessor instead. + Ruby objects are often frozen to prevent further modifications + when they would negatively impact the process (e.g. values inside + Ruby's ENV class) or to prevent polluting other objects when default + values are passed by reference to many instances of an object (e.g. + the empty Array as a Chef resource default, passed by reference + to every instance of the resource). + + Chef uses Object#freeze to ensure the default values of properties + inside Chef resources are not modified, so that when a new instance + of a Chef resource is created, and Object#dup copies values by + reference, the new resource is not receiving a default value that + has been by a previous instance of that resource. + + Instead of modifying an object that contains a default value for all + instances of a Chef resource, create a new object and assign it to + the resource's parameter, e.g.: + + fruit_basket = resource(:fruit_basket, 'default') + + # BAD: modifies 'contents' object for all new fruit_basket instances + fruit_basket.contents << 'apple' + + # GOOD: allocates new array only owned by this fruit_basket instance + fruit_basket.contents %w(apple) + MESSAGE error_description.section("Additional information:", msg.gsub(/^ {6}/, '')) -- cgit v1.2.1 From 01419e6c445b7e92912d6f501f7e22926472e4d8 Mon Sep 17 00:00:00 2001 From: Simon Detheridge Date: Thu, 20 Aug 2015 17:27:15 +0100 Subject: Replace output_of_command with shell_out! in subversion provider output_of_command doesn't work properly on Windows (see chef/chef#1533) --- lib/chef/provider/subversion.rb | 20 +++++++++++++------- lib/chef/resource/subversion.rb | 5 +++++ 2 files changed, 18 insertions(+), 7 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/subversion.rb b/lib/chef/provider/subversion.rb index 5f36483c32..e3e3d5158a 100644 --- a/lib/chef/provider/subversion.rb +++ b/lib/chef/provider/subversion.rb @@ -130,8 +130,8 @@ class Chef @new_resource.revision else command = scm(:info, @new_resource.repository, @new_resource.svn_info_args, authentication, "-r#{@new_resource.revision}") - status, svn_info, error_message = output_of_command(command, run_options) - handle_command_failures(status, "STDOUT: #{svn_info}\nSTDERR: #{error_message}") + svn_info = shell_out!(command, run_options(:cwd => cwd, :returns => [0,1])).stdout + extract_revision_info(svn_info) end end @@ -142,11 +142,8 @@ class Chef def find_current_revision return nil unless ::File.exist?(::File.join(@new_resource.destination, ".svn")) command = scm(:info) - status, svn_info, error_message = output_of_command(command, run_options(:cwd => cwd)) + svn_info = shell_out!(command, run_options(:cwd => cwd, :returns => [0,1])).stdout - unless [0,1].include?(status.exitstatus) - handle_command_failures(status, "STDOUT: #{svn_info}\nSTDERR: #{error_message}") - end extract_revision_info(svn_info) end @@ -180,6 +177,7 @@ class Chef attrs end rev = (repo_attrs['Last Changed Rev'] || repo_attrs['Revision']) + rev.strip! if rev raise "Could not parse `svn info` data: #{svn_info}" if repo_attrs.empty? Chef::Log.debug "#{@new_resource} resolved revision #{@new_resource.revision} to #{rev}" rev @@ -197,12 +195,20 @@ class Chef end def scm(*args) - ['svn', *args].compact.join(" ") + binary = svn_binary + binary = "\"#{binary}\"" if binary =~ /\s/ + [binary, *args].compact.join(" ") end def target_dir_non_existent_or_empty? !::File.exist?(@new_resource.destination) || Dir.entries(@new_resource.destination).sort == ['.','..'] end + + def svn_binary + @new_resource.svn_binary || + (Chef::Platform.windows? ? 'svn.exe' : 'svn') + end + def assert_target_directory_valid! target_parent_directory = ::File.dirname(@new_resource.destination) unless ::File.directory?(target_parent_directory) diff --git a/lib/chef/resource/subversion.rb b/lib/chef/resource/subversion.rb index ae6a37caa2..a6f4cb4897 100644 --- a/lib/chef/resource/subversion.rb +++ b/lib/chef/resource/subversion.rb @@ -28,12 +28,17 @@ class Chef super @svn_arguments = '--no-auth-cache' @svn_info_args = '--no-auth-cache' + @svn_binary = nil end # Override exception to strip password if any, so it won't appear in logs and different Chef notifications def custom_exception_message(e) "#{self} (#{defined_at}) had an error: #{e.class.name}: #{svn_password ? e.message.gsub(svn_password, "[hidden_password]") : e.message}" end + + def svn_binary(arg=nil) + set_or_return(:svn_binary, arg, :kind_of => [String]) + end end end end -- cgit v1.2.1 From 1b85c82cd8a61e41e675685aa61a0b97857ed84f Mon Sep 17 00:00:00 2001 From: Jay Mundrawala Date: Fri, 28 Aug 2015 16:40:44 -0700 Subject: Make win32/api/net.rb look nicer --- lib/chef/win32/api/net.rb | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/win32/api/net.rb b/lib/chef/win32/api/net.rb index 082cf4bb9a..0519e93a96 100644 --- a/lib/chef/win32/api/net.rb +++ b/lib/chef/win32/api/net.rb @@ -152,13 +152,15 @@ class Chef #_In_ LPBYTE buf, #_Out_ LPDWORD parm_err #); - safe_attach_function :NetLocalGroupAdd, [ :LPCWSTR, :DWORD, :LPBYTE, :LPDWORD], :DWORD + safe_attach_function :NetLocalGroupAdd, [ + :LPCWSTR, :DWORD, :LPBYTE, :LPDWORD + ], :DWORD #NET_API_STATUS NetLocalGroupDel( #_In_ LPCWSTR servername, #_In_ LPCWSTR groupname #); - safe_attach_function :NetLocalGroupDel, [ :LPCWSTR, :LPCWSTR], :DWORD + safe_attach_function :NetLocalGroupDel, [:LPCWSTR, :LPCWSTR], :DWORD #NET_API_STATUS NetLocalGroupGetMembers( #_In_ LPCWSTR servername, @@ -170,7 +172,7 @@ class Chef #_Out_ LPDWORD totalentries, #_Inout_ PDWORD_PTR resumehandle #); - safe_attach_function :NetLocalGroupGetMembers, [ + safe_attach_function :NetLocalGroupGetMembers, [ :LPCWSTR, :LPCWSTR, :DWORD, :LPBYTE, :DWORD, :LPDWORD, :LPDWORD, :PDWORD_PTR ], :DWORD @@ -185,12 +187,15 @@ class Chef # _Out_ LPDWORD totalentries, # _Inout_ LPDWORD resume_handle # ); - safe_attach_function :NetUserEnum, [ :LPCWSTR, :DWORD, :DWORD, :LPBYTE, :DWORD, :LPDWORD, :LPDWORD, :LPDWORD ], :DWORD + safe_attach_function :NetUserEnum, [ + :LPCWSTR, :DWORD, :DWORD, :LPBYTE, + :DWORD, :LPDWORD, :LPDWORD, :LPDWORD + ], :DWORD # NET_API_STATUS NetApiBufferFree( # _In_ LPVOID Buffer # ); - safe_attach_function :NetApiBufferFree, [ :LPVOID ], :DWORD + safe_attach_function :NetApiBufferFree, [:LPVOID], :DWORD #NET_API_STATUS NetUserAdd( #_In_ LMSTR servername, @@ -198,7 +203,9 @@ class Chef #_In_ LPBYTE buf, #_Out_ LPDWORD parm_err #); - safe_attach_function :NetUserAdd, [:LMSTR, :DWORD, :LPBYTE, :LPDWORD ], :DWORD + safe_attach_function :NetUserAdd, [ + :LMSTR, :DWORD, :LPBYTE, :LPDWORD + ], :DWORD #NET_API_STATUS NetLocalGroupAddMembers( # _In_ LPCWSTR servername, @@ -207,7 +214,9 @@ class Chef # _In_ LPBYTE buf, # _In_ DWORD totalentries #); - safe_attach_function :NetLocalGroupAddMembers, [:LPCWSTR, :LPCWSTR, :DWORD, :LPBYTE, :DWORD ], :DWORD + safe_attach_function :NetLocalGroupAddMembers, [ + :LPCWSTR, :LPCWSTR, :DWORD, :LPBYTE, :DWORD + ], :DWORD #NET_API_STATUS NetLocalGroupSetMembers( # _In_ LPCWSTR servername, @@ -216,7 +225,9 @@ class Chef # _In_ LPBYTE buf, # _In_ DWORD totalentries #); - safe_attach_function :NetLocalGroupSetMembers, [:LPCWSTR, :LPCWSTR, :DWORD, :LPBYTE, :DWORD ], :DWORD + safe_attach_function :NetLocalGroupSetMembers, [ + :LPCWSTR, :LPCWSTR, :DWORD, :LPBYTE, :DWORD + ], :DWORD #NET_API_STATUS NetLocalGroupDelMembers( # _In_ LPCWSTR servername, @@ -225,7 +236,9 @@ class Chef # _In_ LPBYTE buf, # _In_ DWORD totalentries #); - safe_attach_function :NetLocalGroupDelMembers, [:LPCWSTR, :LPCWSTR, :DWORD, :LPBYTE, :DWORD ], :DWORD + safe_attach_function :NetLocalGroupDelMembers, [ + :LPCWSTR, :LPCWSTR, :DWORD, :LPBYTE, :DWORD + ], :DWORD #NET_API_STATUS NetUserGetInfo( # _In_ LPCWSTR servername, @@ -233,7 +246,9 @@ class Chef # _In_ DWORD level, # _Out_ LPBYTE *bufptr #); - safe_attach_function :NetUserGetInfo, [:LPCWSTR, :LPCWSTR, :DWORD, :LPBYTE], :DWORD + safe_attach_function :NetUserGetInfo, [ + :LPCWSTR, :LPCWSTR, :DWORD, :LPBYTE + ], :DWORD #NET_API_STATUS NetApiBufferFree( # _In_ LPVOID Buffer @@ -247,7 +262,9 @@ class Chef # _In_ LPBYTE buf, # _Out_ LPDWORD parm_err #); - safe_attach_function :NetUserSetInfo, [:LPCWSTR, :LPCWSTR, :DWORD, :LPBYTE, :LPDWORD], :DWORD + safe_attach_function :NetUserSetInfo, [ + :LPCWSTR, :LPCWSTR, :DWORD, :LPBYTE, :LPDWORD + ], :DWORD #NET_API_STATUS NetUserDel( # _In_ LPCWSTR servername, -- cgit v1.2.1 From a9524b0e799c13e90aef846e96c8d32909b5ee39 Mon Sep 17 00:00:00 2001 From: Jay Mundrawala Date: Thu, 27 Aug 2015 13:33:13 -0700 Subject: Rename NetUser -> Net --- lib/chef/win32/net.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/win32/net.rb b/lib/chef/win32/net.rb index 0de310daf1..babe5f829e 100644 --- a/lib/chef/win32/net.rb +++ b/lib/chef/win32/net.rb @@ -22,7 +22,7 @@ require 'chef/mixin/wstring' class Chef module ReservedNames::Win32 - class NetUser + class Net include Chef::ReservedNames::Win32::API::Error extend Chef::ReservedNames::Win32::API::Error @@ -287,5 +287,6 @@ END end end end + NetUser = Net # For backwards compatibility end end -- cgit v1.2.1 From 306423bac260655a9d4b4b152782401f03325519 Mon Sep 17 00:00:00 2001 From: Jay Mundrawala Date: Thu, 27 Aug 2015 14:02:54 -0700 Subject: Use FFI for NetUseDel --- lib/chef/util/windows/net_use.rb | 15 +++++++++++---- lib/chef/win32/api/net.rb | 11 +++++++++++ lib/chef/win32/net.rb | 20 ++++++++++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/util/windows/net_use.rb b/lib/chef/util/windows/net_use.rb index 62d7e169dc..34835b6d3d 100644 --- a/lib/chef/util/windows/net_use.rb +++ b/lib/chef/util/windows/net_use.rb @@ -21,6 +21,7 @@ #see also cmd.exe: net use /? require 'chef/util/windows' +require 'chef/win32/net' class Chef::Util::Windows::NetUse < Chef::Util::Windows @@ -76,6 +77,7 @@ class Chef::Util::Windows::NetUse < Chef::Util::Windows def initialize(localname) @localname = localname @name = multi_to_wide(localname) + @use_name = localname end def add(args) @@ -111,11 +113,16 @@ class Chef::Util::Windows::NetUse < Chef::Util::Windows def device get_info()[:remote] end - #XXX should we use some FORCE here? + def delete - rc = NetUseDel.call(nil, @name, USE_NOFORCE) - if rc != NERR_Success - raise ArgumentError, get_last_error(rc) + begin + Chef::ReservedNames::Win32::Net.net_use_del(nil, use_name, :use_noforce) + rescue Chef::Exceptions::Win32APIError => e + raise ArgumentError, e end end + + def use_name + @use_name + end end diff --git a/lib/chef/win32/api/net.rb b/lib/chef/win32/api/net.rb index 0519e93a96..a7e20d0aeb 100644 --- a/lib/chef/win32/api/net.rb +++ b/lib/chef/win32/api/net.rb @@ -40,6 +40,10 @@ class Chef UF_NORMAL_ACCOUNT = 0x000200 UF_DONT_EXPIRE_PASSWD = 0x010000 + USE_NOFORCE = 0 + USE_FORCE = 1 + USE_LOTS_OF_FORCE = 2 #every windows API should support this flag + NERR_Success = 0 NERR_InvalidComputer = 2351 NERR_NotPrimary = 2226 @@ -272,6 +276,13 @@ class Chef #); safe_attach_function :NetUserDel, [:LPCWSTR, :LPCWSTR], :DWORD +#NET_API_STATUS NetUseDel( + #_In_ LMSTR UncServerName, + #_In_ LMSTR UseName, + #_In_ DWORD ForceCond +#); + safe_attach_function :NetUseDel, [:LMSTR, :LMSTR, :DWORD], :DWORD + end end end diff --git a/lib/chef/win32/net.rb b/lib/chef/win32/net.rb index babe5f829e..e481be7ddb 100644 --- a/lib/chef/win32/net.rb +++ b/lib/chef/win32/net.rb @@ -286,6 +286,26 @@ END net_api_error!(rc) end end + + def self.net_use_del(server_name, use_name, force=:use_noforce) + server_name = wstring(server_name) + use_name = wstring(use_name) + force_const = case force + when :use_noforce + USE_NOFORCE + when :use_force + USE_FORCE + when :use_lots_of_force + USE_LOTS_OF_FORCE + else + raise ArgumentError, "force must be one of [:use_noforce, :use_force, or :use_lots_of_force]" + end + + rc = NetUseDel(server_name, use_name, force_const) + if rc != NERR_Success + net_api_error!(rc) + end + end end NetUser = Net # For backwards compatibility end -- cgit v1.2.1 From 895c8718463029135cc1fe9b3084ff25957ac94d Mon Sep 17 00:00:00 2001 From: Jay Mundrawala Date: Thu, 27 Aug 2015 14:40:32 -0700 Subject: Create StructHelper --- lib/chef/win32/api/net.rb | 80 +++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 38 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/win32/api/net.rb b/lib/chef/win32/api/net.rb index a7e20d0aeb..90154e7661 100644 --- a/lib/chef/win32/api/net.rb +++ b/lib/chef/win32/api/net.rb @@ -59,37 +59,7 @@ class Chef ffi_lib "netapi32" - class USER_INFO_3 < FFI::Struct - layout :usri3_name, :LPWSTR, - :usri3_password, :LPWSTR, - :usri3_password_age, :DWORD, - :usri3_priv, :DWORD, - :usri3_home_dir, :LPWSTR, - :usri3_comment, :LPWSTR, - :usri3_flags, :DWORD, - :usri3_script_path, :LPWSTR, - :usri3_auth_flags, :DWORD, - :usri3_full_name, :LPWSTR, - :usri3_usr_comment, :LPWSTR, - :usri3_parms, :LPWSTR, - :usri3_workstations, :LPWSTR, - :usri3_last_logon, :DWORD, - :usri3_last_logoff, :DWORD, - :usri3_acct_expires, :DWORD, - :usri3_max_storage, :DWORD, - :usri3_units_per_week, :DWORD, - :usri3_logon_hours, :PBYTE, - :usri3_bad_pw_count, :DWORD, - :usri3_num_logons, :DWORD, - :usri3_logon_server, :LPWSTR, - :usri3_country_code, :DWORD, - :usri3_code_page, :DWORD, - :usri3_user_id, :DWORD, - :usri3_primary_group_id, :DWORD, - :usri3_profile, :LPWSTR, - :usri3_home_dir_drive, :LPWSTR, - :usri3_password_expired, :DWORD - + module StructHelpers def set(key, val) val = if val.is_a? String encoded = if val.encoding == Encoding::UTF_16LE @@ -121,6 +91,47 @@ class Chef end end + def as_ruby + members.inject({}) do |memo, key| + memo[key] = get(key) + memo + end + end + end + + + class USER_INFO_3 < FFI::Struct + include StructHelpers + layout :usri3_name, :LPWSTR, + :usri3_password, :LPWSTR, + :usri3_password_age, :DWORD, + :usri3_priv, :DWORD, + :usri3_home_dir, :LPWSTR, + :usri3_comment, :LPWSTR, + :usri3_flags, :DWORD, + :usri3_script_path, :LPWSTR, + :usri3_auth_flags, :DWORD, + :usri3_full_name, :LPWSTR, + :usri3_usr_comment, :LPWSTR, + :usri3_parms, :LPWSTR, + :usri3_workstations, :LPWSTR, + :usri3_last_logon, :DWORD, + :usri3_last_logoff, :DWORD, + :usri3_acct_expires, :DWORD, + :usri3_max_storage, :DWORD, + :usri3_units_per_week, :DWORD, + :usri3_logon_hours, :PBYTE, + :usri3_bad_pw_count, :DWORD, + :usri3_num_logons, :DWORD, + :usri3_logon_server, :LPWSTR, + :usri3_country_code, :DWORD, + :usri3_code_page, :DWORD, + :usri3_user_id, :DWORD, + :usri3_primary_group_id, :DWORD, + :usri3_profile, :LPWSTR, + :usri3_home_dir_drive, :LPWSTR, + :usri3_password_expired, :DWORD + def usri3_logon_hours val = self[:usri3_logon_hours] if !val.nil? && !val.null? @@ -129,13 +140,6 @@ class Chef nil end end - - def as_ruby - members.inject({}) do |memo, key| - memo[key] = get(key) - memo - end - end end class LOCALGROUP_MEMBERS_INFO_0 < FFI::Struct -- cgit v1.2.1 From 093e2cb93d5f8e14fc86d6eb67f174945b7b05af Mon Sep 17 00:00:00 2001 From: Jay Mundrawala Date: Thu, 27 Aug 2015 15:05:20 -0700 Subject: FFI NetUseGetInfo --- lib/chef/util/windows/net_use.rb | 23 ++++++++++++----------- lib/chef/win32/api/net.rb | 22 ++++++++++++++++++++++ lib/chef/win32/net.rb | 16 ++++++++++++++++ 3 files changed, 50 insertions(+), 11 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/util/windows/net_use.rb b/lib/chef/util/windows/net_use.rb index 34835b6d3d..b9c67a53ac 100644 --- a/lib/chef/util/windows/net_use.rb +++ b/lib/chef/util/windows/net_use.rb @@ -95,19 +95,20 @@ class Chef::Util::Windows::NetUse < Chef::Util::Windows end end - def get_info - ptr = 0.chr * PTR_SIZE - rc = NetUseGetInfo.call(nil, @name, 2, ptr) - - if rc != NERR_Success - raise ArgumentError, get_last_error(rc) + def from_use_info_struct(ui2_hash) + ui2_hash.inject({}) do |memo, (k,v)| + memo[k.to_s.sub('ui2_', '').to_sym] = v + memo end + end - ptr = ptr.unpack('L')[0] - buffer = 0.chr * SIZEOF_USE_INFO_2 - memcpy(buffer, ptr, buffer.size) - NetApiBufferFree(ptr) - use_info_2_unpack(buffer) + def get_info + begin + ui2 = Chef::ReservedNames::Win32::Net.net_use_get_info_l2(nil, use_name) + from_use_info_struct(ui2) + rescue Chef::Exceptions::Win32APIError => e + raise ArgumentError, e + end end def device diff --git a/lib/chef/win32/api/net.rb b/lib/chef/win32/api/net.rb index 90154e7661..b4be47e418 100644 --- a/lib/chef/win32/api/net.rb +++ b/lib/chef/win32/api/net.rb @@ -154,6 +154,21 @@ class Chef layout :lgrpi0_name, :LPWSTR end + class USE_INFO_2 < FFI::Struct + include StructHelpers + + layout :ui2_local, :LMSTR, + :ui2_remote, :LMSTR, + :ui2_password, :LMSTR, + :ui2_status, :DWORD, + :ui2_asg_type, :DWORD, + :ui2_refcount, :DWORD, + :ui2_usecount, :DWORD, + :ui2_username, :LPWSTR, + :ui2_domainname, :LMSTR + end + + #NET_API_STATUS NetLocalGroupAdd( #_In_ LPCWSTR servername, #_In_ DWORD level, @@ -287,6 +302,13 @@ class Chef #); safe_attach_function :NetUseDel, [:LMSTR, :LMSTR, :DWORD], :DWORD +#NET_API_STATUS NetUseGetInfo( + #_In_ LMSTR UncServerName, + #_In_ LMSTR UseName, + #_In_ DWORD Level, + #_Out_ LPBYTE *BufPtr +#); + safe_attach_function :NetUseGetInfo, [:LMSTR, :LMSTR, :DWORD, :pointer], :DWORD end end end diff --git a/lib/chef/win32/net.rb b/lib/chef/win32/net.rb index e481be7ddb..2520e7a117 100644 --- a/lib/chef/win32/net.rb +++ b/lib/chef/win32/net.rb @@ -306,6 +306,22 @@ END net_api_error!(rc) end end + + def self.net_use_get_info_l2(server_name, use_name) + server_name = wstring(server_name) + use_name = wstring(use_name) + ui2_p = FFI::MemoryPointer.new(:pointer) + + rc = NetUseGetInfo(server_name, use_name, 2, ui2_p) + if rc != NERR_Success + net_api_error!(rc) + end + + ui2 = USE_INFO_2.new(ui2_p.read_pointer).as_ruby + NetApiBufferFree(ui2_p.read_pointer) + + ui2 + end end NetUser = Net # For backwards compatibility end -- cgit v1.2.1 From 9b4a7da265329ffc4a41f565f3932c2b0d681a62 Mon Sep 17 00:00:00 2001 From: Jay Mundrawala Date: Thu, 27 Aug 2015 15:23:39 -0700 Subject: FFI NetUseAdd --- lib/chef/util/windows/net_use.rb | 18 +++++++++++++----- lib/chef/win32/api/net.rb | 8 ++++++++ lib/chef/win32/net.rb | 16 ++++++++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/util/windows/net_use.rb b/lib/chef/util/windows/net_use.rb index b9c67a53ac..e2a91db1a4 100644 --- a/lib/chef/util/windows/net_use.rb +++ b/lib/chef/util/windows/net_use.rb @@ -80,6 +80,13 @@ class Chef::Util::Windows::NetUse < Chef::Util::Windows @use_name = localname end + def to_ui2_struct(use_info) + use_info.inject({}) do |memo, (k,v)| + memo["ui2_#{k}".to_sym] = v + memo + end + end + def add(args) if args.class == String remote = args @@ -87,11 +94,12 @@ class Chef::Util::Windows::NetUse < Chef::Util::Windows args[:remote] = remote end args[:local] ||= @localname - use = use_info_2(args) - buffer = use_info_2_pack(use) - rc = NetUseAdd.call(nil, 2, buffer, nil) - if rc != NERR_Success - raise ArgumentError, get_last_error(rc) + ui2_hash = to_ui2_struct(args) + + begin + Chef::ReservedNames::Win32::Net.net_use_add_l2(nil, ui2_hash) + rescue Chef::Exceptions::Win32APIError => e + raise ArgumentError, e end end diff --git a/lib/chef/win32/api/net.rb b/lib/chef/win32/api/net.rb index b4be47e418..6828d7ee2f 100644 --- a/lib/chef/win32/api/net.rb +++ b/lib/chef/win32/api/net.rb @@ -309,6 +309,14 @@ class Chef #_Out_ LPBYTE *BufPtr #); safe_attach_function :NetUseGetInfo, [:LMSTR, :LMSTR, :DWORD, :pointer], :DWORD + +#NET_API_STATUS NetUseAdd( + #_In_ LMSTR UncServerName, + #_In_ DWORD Level, + #_In_ LPBYTE Buf, + #_Out_ LPDWORD ParmError +#); + safe_attach_function :NetUseAdd, [:LMSTR, :DWORD, :LPBYTE, :LPDWORD], :DWORD end end end diff --git a/lib/chef/win32/net.rb b/lib/chef/win32/net.rb index 2520e7a117..c1ef3e83ce 100644 --- a/lib/chef/win32/net.rb +++ b/lib/chef/win32/net.rb @@ -322,6 +322,22 @@ END ui2 end + + def self.net_use_add_l2(server_name, ui2_hash) + server_name = wstring(server_name) + group_name = wstring(group_name) + + buf = USE_INFO_2.new + + ui2_hash.each do |(k,v)| + buf.set(k,v) + end + + rc = NetUseAdd(server_name, 2, buf, nil) + if rc != NERR_Success + net_api_error!(rc) + end + end end NetUser = Net # For backwards compatibility end -- cgit v1.2.1 From a84f30da26f47aeeab2d13a775cb4d33e8c34fd6 Mon Sep 17 00:00:00 2001 From: Jay Mundrawala Date: Thu, 27 Aug 2015 15:34:05 -0700 Subject: Remove unused things --- lib/chef/util/windows/net_use.rb | 54 +--------------------------------------- 1 file changed, 1 insertion(+), 53 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/util/windows/net_use.rb b/lib/chef/util/windows/net_use.rb index e2a91db1a4..b94576e702 100644 --- a/lib/chef/util/windows/net_use.rb +++ b/lib/chef/util/windows/net_use.rb @@ -24,59 +24,7 @@ require 'chef/util/windows' require 'chef/win32/net' class Chef::Util::Windows::NetUse < Chef::Util::Windows - - private - - USE_NOFORCE = 0 - USE_FORCE = 1 - USE_LOTS_OF_FORCE = 2 #every windows API should support this flag - - USE_INFO_2 = [ - [:local, nil], - [:remote, nil], - [:password, nil], - [:status, 0], - [:asg_type, 0], - [:refcount, 0], - [:usecount, 0], - [:username, nil], - [:domainname, nil] - ] - - USE_INFO_2_TEMPLATE = - USE_INFO_2.collect { |field| field[1].class == Fixnum ? 'i' : 'L' }.join - - SIZEOF_USE_INFO_2 = #sizeof(USE_INFO_2) - USE_INFO_2.inject(0) do |sum, item| - sum + (item[1].class == Fixnum ? 4 : PTR_SIZE) - end - - def use_info_2(args) - USE_INFO_2.collect { |field| - args.include?(field[0]) ? args[field[0]] : field[1] - } - end - - def use_info_2_pack(use) - use.collect { |v| - v.class == Fixnum ? v : str_to_ptr(multi_to_wide(v)) - }.pack(USE_INFO_2_TEMPLATE) - end - - def use_info_2_unpack(buffer) - use = Hash.new - USE_INFO_2.each_with_index do |field,offset| - use[field[0]] = field[1].class == Fixnum ? - dword_to_i(buffer, offset) : lpwstr_to_s(buffer, offset) - end - use - end - - public - def initialize(localname) - @localname = localname - @name = multi_to_wide(localname) @use_name = localname end @@ -93,7 +41,7 @@ class Chef::Util::Windows::NetUse < Chef::Util::Windows args = Hash.new args[:remote] = remote end - args[:local] ||= @localname + args[:local] ||= use_name ui2_hash = to_ui2_struct(args) begin -- cgit v1.2.1 From 3a853284da6d566bf96c21a8a5af0413c73c0b6a Mon Sep 17 00:00:00 2001 From: Jay Mundrawala Date: Fri, 28 Aug 2015 18:17:13 -0700 Subject: Remove unused instance variable --- lib/chef/util/windows/net_user.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/util/windows/net_user.rb b/lib/chef/util/windows/net_user.rb index 26fbe53db6..4ce051228a 100644 --- a/lib/chef/util/windows/net_user.rb +++ b/lib/chef/util/windows/net_user.rb @@ -88,7 +88,6 @@ class Chef::Util::Windows::NetUser < Chef::Util::Windows def initialize(username) @username = username - @name = multi_to_wide(username) end LOGON32_PROVIDER_DEFAULT = Security::LOGON32_PROVIDER_DEFAULT -- cgit v1.2.1 From 828847d322c3e8239a73c5615b323c28ded4ad03 Mon Sep 17 00:00:00 2001 From: Jay Mundrawala Date: Thu, 27 Aug 2015 10:15:51 -0700 Subject: Remove dependency on windows-pr --- lib/chef/util/windows.rb | 32 -------------------------------- 1 file changed, 32 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/util/windows.rb b/lib/chef/util/windows.rb index 777fe4adbb..7d29a67ac5 100644 --- a/lib/chef/util/windows.rb +++ b/lib/chef/util/windows.rb @@ -15,42 +15,10 @@ # See the License for the specific language governing permissions and # limitations under the License. # -#requires: gem install windows-pr -require 'windows/api' -require 'windows/error' -require 'windows/handle' -require 'windows/unicode' -require 'windows/msvcrt/buffer' -require 'windows/msvcrt/string' -require 'windows/network/management' class Chef class Util class Windows - protected - - include ::Windows::Error - include ::Windows::Unicode - include ::Windows::MSVCRT::Buffer - include ::Windows::MSVCRT::String - include ::Windows::Network::Management - - PTR_SIZE = 4 #XXX 64-bit - - def lpwstr_to_s(buffer, offset) - str = 0.chr * (256 * 2) #XXX unhardcode this length (*2 for WCHAR) - wcscpy str, buffer[offset*PTR_SIZE,PTR_SIZE].unpack('L')[0] - wide_to_multi str - end - - def dword_to_i(buffer, offset) - buffer[offset*PTR_SIZE,PTR_SIZE].unpack('i')[0] || 0 - end - - #return pointer for use with pack('L') - def str_to_ptr(v) - [v].pack('p*').unpack('L')[0] - end end end end -- cgit v1.2.1 From 998a1341989dc6447061c46629e8d2da8a28e53a Mon Sep 17 00:00:00 2001 From: chefsalim Date: Sat, 29 Aug 2015 21:07:21 -0700 Subject: Prep for Registry FFI; Convert RegDeleteKeyEx to FFI --- lib/chef/win32/api/registry.rb | 45 ++++++++++++++++++++++++++++++++++++++++++ lib/chef/win32/registry.rb | 14 +++++++++++-- 2 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 lib/chef/win32/api/registry.rb (limited to 'lib/chef') diff --git a/lib/chef/win32/api/registry.rb b/lib/chef/win32/api/registry.rb new file mode 100644 index 0000000000..45b91d7d32 --- /dev/null +++ b/lib/chef/win32/api/registry.rb @@ -0,0 +1,45 @@ +# +# Author:: Salim Alam () +# Copyright:: Copyright 2015 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. +# + +require 'chef/win32/api' + +class Chef + module ReservedNames::Win32 + module API + module Registry + extend Chef::ReservedNames::Win32::API + + ############################################### + # Win32 API Bindings + ############################################### + + ffi_lib 'advapi32' + + # LONG WINAPI RegDeleteKeyEx( + # _In_ HKEY hKey, + # _In_ LPCTSTR lpSubKey, + # _In_ REGSAM samDesired, + # _Reserved_ DWORD Reserved + # ); + safe_attach_function :RegDeleteKeyExW, [ :HKEY, :LPCTSTR, :LONG, :DWORD ], :LONG + safe_attach_function :RegDeleteKeyExA, [ :HKEY, :LPCTSTR, :LONG, :DWORD ], :LONG + + end + end + end +end \ No newline at end of file diff --git a/lib/chef/win32/registry.rb b/lib/chef/win32/registry.rb index 1a1aa12fad..ba41a4af1d 100644 --- a/lib/chef/win32/registry.rb +++ b/lib/chef/win32/registry.rb @@ -17,8 +17,11 @@ # limitations under the License. # require 'chef/reserved_names' +require 'chef/win32/api' +require 'chef/mixin/wstring' if RUBY_PLATFORM =~ /mswin|mingw32|windows/ + require 'chef/win32/api/registry' require 'win32/registry' require 'win32/api' end @@ -27,6 +30,14 @@ class Chef class Win32 class Registry + if RUBY_PLATFORM =~ /mswin|mingw32|windows/ + include Chef::ReservedNames::Win32::API::Registry + extend Chef::ReservedNames::Win32::API::Registry + end + + include Chef::Mixin::WideString + extend Chef::Mixin::WideString + attr_accessor :run_context attr_accessor :architecture @@ -142,9 +153,8 @@ class Chef #Using the 'RegDeleteKeyEx' Windows API that correctly supports WOW64 systems (Win2003) #instead of the 'RegDeleteKey' def delete_key_ex(hive, key) - regDeleteKeyEx = ::Win32::API.new('RegDeleteKeyEx', 'LPLL', 'L', 'advapi32') hive_num = hive.hkey - (1 << 32) - regDeleteKeyEx.call(hive_num, key, ::Win32::Registry::KEY_WRITE | registry_system_architecture, 0) + RegDeleteKeyExW(hive_num, wstring(key), ::Win32::Registry::KEY_WRITE | registry_system_architecture, 0) == ERROR_SUCCESS end def key_exists?(key_path) -- cgit v1.2.1 From 0047f4cd275a52aacc14ad8f45c323da3cb93b86 Mon Sep 17 00:00:00 2001 From: Salim Alam Date: Mon, 31 Aug 2015 10:35:45 -0700 Subject: Fix constant --- lib/chef/win32/registry.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/win32/registry.rb b/lib/chef/win32/registry.rb index ba41a4af1d..2bb7b78965 100644 --- a/lib/chef/win32/registry.rb +++ b/lib/chef/win32/registry.rb @@ -154,7 +154,7 @@ class Chef #instead of the 'RegDeleteKey' def delete_key_ex(hive, key) hive_num = hive.hkey - (1 << 32) - RegDeleteKeyExW(hive_num, wstring(key), ::Win32::Registry::KEY_WRITE | registry_system_architecture, 0) == ERROR_SUCCESS + RegDeleteKeyExW(hive_num, wstring(key), ::Win32::Registry::KEY_WRITE | registry_system_architecture, 0) == 0 end def key_exists?(key_path) -- cgit v1.2.1 From 5d4d979768029a6e396608ab683014946aa1148d Mon Sep 17 00:00:00 2001 From: Claire McQuin Date: Wed, 26 Aug 2015 11:08:03 -0700 Subject: Patch Win32::Registry#write on Ruby 2.1, resolves encoding errors --- lib/chef/win32/unicode.rb | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'lib/chef') diff --git a/lib/chef/win32/unicode.rb b/lib/chef/win32/unicode.rb index e7399d5255..ea10dc71d0 100644 --- a/lib/chef/win32/unicode.rb +++ b/lib/chef/win32/unicode.rb @@ -53,3 +53,30 @@ class String Chef::ReservedNames::Win32::Unicode.utf8_to_wide(self) end end + +# https://bugs.ruby-lang.org/issues/11439 +if RUBY_VERSION =~ /^2\.1/ + module Win32 + class Registry + def write(name, type, data) + case type + when REG_SZ, REG_EXPAND_SZ + data = data.to_s.encode(WCHAR) + WCHAR_NUL + when REG_MULTI_SZ + data = data.to_a.map {|s| s.encode(WCHAR)}.join(WCHAR_NUL) << WCHAR_NUL << WCHAR_NUL + when REG_BINARY + data = data.to_s + when REG_DWORD + data = API.packdw(data.to_i) + when REG_DWORD_BIG_ENDIAN + data = [data.to_i].pack('N') + when REG_QWORD + data = API.packqw(data.to_i) + else + raise TypeError, "Unsupported type #{type}" + end + API.SetValue(@hkey, name, type, data, data.bytesize) + end + end + end +end \ No newline at end of file -- cgit v1.2.1 From 12425d32e29fd612a2afaa99a1978df1b600b941 Mon Sep 17 00:00:00 2001 From: Claire McQuin Date: Tue, 1 Sep 2015 11:36:25 -0700 Subject: Refactor Chef::Mixin::WideString to remove implicit Windows dependency. --- lib/chef/mixin/wide_string.rb | 72 ++++++++++++++++++++++++++++++++++++ lib/chef/mixin/windows_env_helper.rb | 5 ++- lib/chef/mixin/wstring.rb | 31 ---------------- lib/chef/win32/api/file.rb | 1 + lib/chef/win32/api/net.rb | 1 + lib/chef/win32/api/unicode.rb | 43 --------------------- lib/chef/win32/crypto.rb | 1 + lib/chef/win32/file.rb | 9 +++-- lib/chef/win32/mutex.rb | 3 +- lib/chef/win32/net.rb | 2 +- lib/chef/win32/registry.rb | 2 +- lib/chef/win32/security.rb | 2 +- lib/chef/win32/security/token.rb | 2 +- lib/chef/win32/unicode.rb | 9 ++++- 14 files changed, 96 insertions(+), 87 deletions(-) create mode 100644 lib/chef/mixin/wide_string.rb delete mode 100644 lib/chef/mixin/wstring.rb (limited to 'lib/chef') diff --git a/lib/chef/mixin/wide_string.rb b/lib/chef/mixin/wide_string.rb new file mode 100644 index 0000000000..0c32b76365 --- /dev/null +++ b/lib/chef/mixin/wide_string.rb @@ -0,0 +1,72 @@ +# +# Author:: Jay Mundrawala() +# Copyright:: Copyright 2015 Chef Software +# 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 + module Mixin + module WideString + + def wstring(str) + if str.nil? || str.encoding == Encoding::UTF_16LE + str + else + utf8_to_wide(str) + end + end + + def utf8_to_wide(ustring) + # ensure it is actually UTF-8 + # Ruby likes to mark binary data as ASCII-8BIT + ustring = (ustring + "").force_encoding('UTF-8') if ustring.respond_to?(:force_encoding) && ustring.encoding.name != "UTF-8" + + # ensure we have the double-null termination Windows Wide likes + ustring = ustring + "\000\000" if ustring.length == 0 or ustring[-1].chr != "\000" + + # encode it all as UTF-16LE AKA Windows Wide Character AKA Windows Unicode + ustring = begin + if ustring.respond_to?(:encode) + ustring.encode('UTF-16LE') + else + require 'iconv' + Iconv.conv("UTF-16LE", "UTF-8", ustring) + end + end + ustring + end + + def wide_to_utf8(wstring) + # ensure it is actually UTF-16LE + # Ruby likes to mark binary data as ASCII-8BIT + wstring = wstring.force_encoding('UTF-16LE') if wstring.respond_to?(:force_encoding) + + # encode it all as UTF-8 + wstring = begin + if wstring.respond_to?(:encode) + wstring.encode('UTF-8') + else + require 'iconv' + Iconv.conv("UTF-8", "UTF-16LE", wstring) + end + end + # remove trailing CRLF and NULL characters + wstring.strip! + wstring + end + + end + end +end diff --git a/lib/chef/mixin/windows_env_helper.rb b/lib/chef/mixin/windows_env_helper.rb index a126801a28..cd12b4254a 100644 --- a/lib/chef/mixin/windows_env_helper.rb +++ b/lib/chef/mixin/windows_env_helper.rb @@ -18,6 +18,7 @@ require 'chef/exceptions' +require 'chef/mixin/wide_string' require 'chef/platform/query_helpers' require 'chef/win32/error' if Chef::Platform.windows? require 'chef/win32/api/system' if Chef::Platform.windows? @@ -26,6 +27,8 @@ require 'chef/win32/api/unicode' if Chef::Platform.windows? class Chef module Mixin module WindowsEnvHelper + include Chef::Mixin::WideString + if Chef::Platform.windows? include Chef::ReservedNames::Win32::API::System end @@ -45,7 +48,7 @@ class Chef Chef::ReservedNames::Win32::Error.raise! end if ( SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0, FFI::MemoryPointer.from_string( - Chef::ReservedNames::Win32::Unicode.utf8_to_wide('Environment') + utf8_to_wide('Environment') ).address, flags, 5000, nil) == 0 ) Chef::ReservedNames::Win32::Error.raise! end diff --git a/lib/chef/mixin/wstring.rb b/lib/chef/mixin/wstring.rb deleted file mode 100644 index bb6fdf4884..0000000000 --- a/lib/chef/mixin/wstring.rb +++ /dev/null @@ -1,31 +0,0 @@ -# -# Author:: Jay Mundrawala() -# Copyright:: Copyright 2015 Chef Software -# 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 - module Mixin - module WideString - def wstring(str) - if str.nil? || str.encoding == Encoding::UTF_16LE - str - else - str.to_wstring - end - end - end - end -end diff --git a/lib/chef/win32/api/file.rb b/lib/chef/win32/api/file.rb index 728a6c14df..9ff1ad40d6 100644 --- a/lib/chef/win32/api/file.rb +++ b/lib/chef/win32/api/file.rb @@ -20,6 +20,7 @@ require 'chef/win32/api' require 'chef/win32/api/security' require 'chef/win32/api/system' +require 'chef/win32/unicode' class Chef module ReservedNames::Win32 diff --git a/lib/chef/win32/api/net.rb b/lib/chef/win32/api/net.rb index 6828d7ee2f..b173987a05 100644 --- a/lib/chef/win32/api/net.rb +++ b/lib/chef/win32/api/net.rb @@ -17,6 +17,7 @@ # require 'chef/win32/api' +require 'chef/win32/unicode' class Chef module ReservedNames::Win32 diff --git a/lib/chef/win32/api/unicode.rb b/lib/chef/win32/api/unicode.rb index 2e3a599f0a..2a9166aa99 100644 --- a/lib/chef/win32/api/unicode.rb +++ b/lib/chef/win32/api/unicode.rb @@ -129,49 +129,6 @@ int WideCharToMultiByte( =end safe_attach_function :WideCharToMultiByte, [:UINT, :DWORD, :LPCWSTR, :int, :LPSTR, :int, :LPCSTR, :LPBOOL], :int - ############################################### - # Helpers - ############################################### - - def utf8_to_wide(ustring) - # ensure it is actually UTF-8 - # Ruby likes to mark binary data as ASCII-8BIT - ustring = (ustring + "").force_encoding('UTF-8') if ustring.respond_to?(:force_encoding) && ustring.encoding.name != "UTF-8" - - # ensure we have the double-null termination Windows Wide likes - ustring = ustring + "\000\000" if ustring.length == 0 or ustring[-1].chr != "\000" - - # encode it all as UTF-16LE AKA Windows Wide Character AKA Windows Unicode - ustring = begin - if ustring.respond_to?(:encode) - ustring.encode('UTF-16LE') - else - require 'iconv' - Iconv.conv("UTF-16LE", "UTF-8", ustring) - end - end - ustring - end - - def wide_to_utf8(wstring) - # ensure it is actually UTF-16LE - # Ruby likes to mark binary data as ASCII-8BIT - wstring = wstring.force_encoding('UTF-16LE') if wstring.respond_to?(:force_encoding) - - # encode it all as UTF-8 - wstring = begin - if wstring.respond_to?(:encode) - wstring.encode('UTF-8') - else - require 'iconv' - Iconv.conv("UTF-8", "UTF-16LE", wstring) - end - end - # remove trailing CRLF and NULL characters - wstring.strip! - wstring - end - end end end diff --git a/lib/chef/win32/crypto.rb b/lib/chef/win32/crypto.rb index 79cf51b002..aa20c2dfd4 100644 --- a/lib/chef/win32/crypto.rb +++ b/lib/chef/win32/crypto.rb @@ -19,6 +19,7 @@ require 'chef/win32/error' require 'chef/win32/api/memory' require 'chef/win32/api/crypto' +require 'chef/win32/unicode' require 'digest' class Chef diff --git a/lib/chef/win32/file.rb b/lib/chef/win32/file.rb index 57347643fc..700ddb24d3 100644 --- a/lib/chef/win32/file.rb +++ b/lib/chef/win32/file.rb @@ -17,10 +17,11 @@ # limitations under the License. # +require 'chef/mixin/wide_string' require 'chef/win32/api/file' require 'chef/win32/api/security' require 'chef/win32/error' -require 'chef/mixin/wstring' +require 'chef/win32/unicode' class Chef module ReservedNames::Win32 @@ -161,9 +162,9 @@ class Chef def self.file_access_check(path, desired_access) security_descriptor = Chef::ReservedNames::Win32::Security.get_file_security(path) - token_rights = Chef::ReservedNames::Win32::Security::TOKEN_IMPERSONATE | + token_rights = Chef::ReservedNames::Win32::Security::TOKEN_IMPERSONATE | Chef::ReservedNames::Win32::Security::TOKEN_QUERY | - Chef::ReservedNames::Win32::Security::TOKEN_DUPLICATE | + Chef::ReservedNames::Win32::Security::TOKEN_DUPLICATE | Chef::ReservedNames::Win32::Security::STANDARD_RIGHTS_READ token = Chef::ReservedNames::Win32::Security.open_process_token( Chef::ReservedNames::Win32::Process.get_current_process, @@ -176,7 +177,7 @@ class Chef mapping[:GenericExecute] = Chef::ReservedNames::Win32::Security::FILE_GENERIC_EXECUTE mapping[:GenericAll] = Chef::ReservedNames::Win32::Security::FILE_ALL_ACCESS - Chef::ReservedNames::Win32::Security.access_check(security_descriptor, duplicate_token, + Chef::ReservedNames::Win32::Security.access_check(security_descriptor, duplicate_token, desired_access, mapping) end diff --git a/lib/chef/win32/mutex.rb b/lib/chef/win32/mutex.rb index 0b7d99f111..f4755e9019 100644 --- a/lib/chef/win32/mutex.rb +++ b/lib/chef/win32/mutex.rb @@ -17,6 +17,7 @@ # require 'chef/win32/api/synchronization' +require 'chef/win32/unicode' class Chef module ReservedNames::Win32 @@ -113,5 +114,3 @@ if the mutex is attempted to be acquired by other threads.") end end end - - diff --git a/lib/chef/win32/net.rb b/lib/chef/win32/net.rb index c1ef3e83ce..59f29c4d1b 100644 --- a/lib/chef/win32/net.rb +++ b/lib/chef/win32/net.rb @@ -18,7 +18,7 @@ require 'chef/win32/api/net' require 'chef/win32/error' -require 'chef/mixin/wstring' +require 'chef/mixin/wide_string' class Chef module ReservedNames::Win32 diff --git a/lib/chef/win32/registry.rb b/lib/chef/win32/registry.rb index 2bb7b78965..b25ce7937e 100644 --- a/lib/chef/win32/registry.rb +++ b/lib/chef/win32/registry.rb @@ -18,7 +18,7 @@ # require 'chef/reserved_names' require 'chef/win32/api' -require 'chef/mixin/wstring' +require 'chef/mixin/wide_string' if RUBY_PLATFORM =~ /mswin|mingw32|windows/ require 'chef/win32/api/registry' diff --git a/lib/chef/win32/security.rb b/lib/chef/win32/security.rb index 5c83180bc0..bc80517d80 100644 --- a/lib/chef/win32/security.rb +++ b/lib/chef/win32/security.rb @@ -22,7 +22,7 @@ require 'chef/win32/memory' require 'chef/win32/process' require 'chef/win32/unicode' require 'chef/win32/security/token' -require 'chef/mixin/wstring' +require 'chef/mixin/wide_string' class Chef module ReservedNames::Win32 diff --git a/lib/chef/win32/security/token.rb b/lib/chef/win32/security/token.rb index 9e494a73b9..8d4e54ad8c 100644 --- a/lib/chef/win32/security/token.rb +++ b/lib/chef/win32/security/token.rb @@ -18,7 +18,7 @@ require 'chef/win32/security' require 'chef/win32/api/security' - +require 'chef/win32/unicode' require 'ffi' class Chef diff --git a/lib/chef/win32/unicode.rb b/lib/chef/win32/unicode.rb index ea10dc71d0..562301a040 100644 --- a/lib/chef/win32/unicode.rb +++ b/lib/chef/win32/unicode.rb @@ -17,6 +17,7 @@ # limitations under the License. # +require 'chef/mixin/wide_string' require 'chef/win32/api/unicode' class Chef @@ -30,6 +31,8 @@ end module FFI class Pointer + include Chef::Mixin::WideString + def read_wstring(num_wchars = nil) if num_wchars.nil? # Find the length of the string @@ -43,14 +46,16 @@ module FFI num_wchars = length end - Chef::ReservedNames::Win32::Unicode.wide_to_utf8(self.get_bytes(0, num_wchars*2)) + wide_to_utf8(self.get_bytes(0, num_wchars*2)) end end end class String + include Chef::Mixin::WideString + def to_wstring - Chef::ReservedNames::Win32::Unicode.utf8_to_wide(self) + utf8_to_wide(self) end end -- cgit v1.2.1 From b63f742a826be3b97e9eea34f725fbdbdfc87aa8 Mon Sep 17 00:00:00 2001 From: Noah Kantrowitz Date: Tue, 1 Sep 2015 18:22:40 -0700 Subject: Refactor knife ssh options stuff. This allows most config options to work with the SSH gateway too. The most important of these is the identity file stuffs. --- lib/chef/knife/ssh.rb | 74 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 29 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/ssh.rb b/lib/chef/knife/ssh.rb index 68e01cf94f..a34e790c30 100644 --- a/lib/chef/knife/ssh.rb +++ b/lib/chef/knife/ssh.rb @@ -132,15 +132,18 @@ class Chef if config[:ssh_gateway] gw_host, gw_user = config[:ssh_gateway].split('@').reverse gw_host, gw_port = gw_host.split(':') - gw_opts = gw_port ? { :port => gw_port } : {} + gw_opts = session_options(gw_host, gw_port, gw_user) - session.via(gw_host, gw_user || config[:ssh_user], gw_opts) + begin + # Try to connect with a key. + session.via(gw_host, gw_opts[:user], gw_opts) + rescue Net::SSH::AuthenticationFailed + prompt = "Enter the password for #{user}@#{gw_host}: " + gw_opts[:password] = prompt_for_password(prompt) + # Try again with a password. + session.via(gw_host, user, gw_opts) + end end - rescue Net::SSH::AuthenticationFailed - user = gw_user || config[:ssh_user] - prompt = "Enter the password for #{user}@#{gw_host}: " - gw_opts.merge!(:password => prompt_for_password(prompt)) - session.via(gw_host, user, gw_opts) end def configure_session @@ -204,32 +207,45 @@ class Chef list end - def session_from_list(list) - list.each do |item| - host, ssh_port = item - Chef::Log.debug("Adding #{host}") - session_opts = {} - - ssh_config = Net::SSH.configuration_for(host) - + # Net::SSH session options hash for global options. These should be + # options that will apply to the gateway connection in addition to the + # main one. + # + # @since 12.5.0 + # @param host [String] Hostname for this session. + # @param port [String] SSH port for this session. + # @param user [String] Optional username for this session. + # @return [Hash] + def session_options(host, port, user=nil) + ssh_config = Net::SSH.configuration_for(host) + {}.tap do |opts| # Chef::Config[:knife][:ssh_user] is parsed in #configure_user and written to config[:ssh_user] - user = config[:ssh_user] || ssh_config[:user] - hostspec = user ? "#{user}@#{host}" : host - session_opts[:keys] = File.expand_path(config[:identity_file]) if config[:identity_file] - session_opts[:keys_only] = true if config[:identity_file] - session_opts[:password] = config[:ssh_password] if config[:ssh_password] - session_opts[:forward_agent] = config[:forward_agent] - session_opts[:port] = config[:ssh_port] || - ssh_port || # Use cloud port if available - Chef::Config[:knife][:ssh_port] || - ssh_config[:port] - session_opts[:logger] = Chef::Log.logger if Chef::Log.level == :debug - + opts[:user] = user || config[:ssh_user] || ssh_config[:user] + if config[:identity_file] + opts[:keys] = File.expand_path(config[:identity_file]) + opts[:keys_only] = true + end + opts[:forward_agent] = config[:forward_agent] || ssh_config[:forward_agent] + opts[:port] = port || ssh_config[:port] + opts[:logger] = Chef::Log.logger if Chef::Log.level == :debug if !config[:host_key_verify] - session_opts[:paranoid] = false - session_opts[:user_known_hosts_file] = "/dev/null" + opts[:paranoid] = false + opts[:user_known_hosts_file] = '/dev/null' end + end + end + def session_from_list(list) + list.each do |item| + host, ssh_port = item + Chef::Log.debug("Adding #{host}") + session_opts = session_options(host, ssh_port) + # Handle port overrides for the main connection. + session_opts[:port] = Chef::Config[:knife][:ssh_port] if Chef::Config[:knife][:ssh_port] + session_opts[:port] = config[:ssh_port] if config[:ssh_port] + # Create the hostspec. + hostspec = session_opts[:user] ? "#{session_opts[:user]}@#{host}" : host + # Connect a new session on the multi. session.use(hostspec, session_opts) @longest = host.length if host.length > @longest -- cgit v1.2.1 From ca0726ef3c7c89533d5bd4146fcb3f20e2a50b80 Mon Sep 17 00:00:00 2001 From: Noah Kantrowitz Date: Tue, 1 Sep 2015 18:28:28 -0700 Subject: Missed a variable while moving code around. --- lib/chef/knife/ssh.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/ssh.rb b/lib/chef/knife/ssh.rb index a34e790c30..5ccef3000d 100644 --- a/lib/chef/knife/ssh.rb +++ b/lib/chef/knife/ssh.rb @@ -141,7 +141,7 @@ class Chef prompt = "Enter the password for #{user}@#{gw_host}: " gw_opts[:password] = prompt_for_password(prompt) # Try again with a password. - session.via(gw_host, user, gw_opts) + session.via(gw_host, gw_opts[:user], gw_opts) end end end -- cgit v1.2.1 From 25dac92eeb1ffa83ec549bfed0b19672c5847d80 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Mon, 31 Aug 2015 14:38:50 -0700 Subject: Pass deprecations through formatter instead of logs --- lib/chef/application.rb | 2 +- lib/chef/chef_class.rb | 16 ++++++++++++++ lib/chef/cookbook_version.rb | 6 +++--- lib/chef/deprecation/warnings.rb | 5 ++--- lib/chef/dsl/recipe.rb | 5 ++--- lib/chef/dsl/resources.rb | 4 ++-- lib/chef/event_dispatch/base.rb | 15 ++++++++----- lib/chef/event_dispatch/dispatcher.rb | 4 +++- lib/chef/formatters/base.rb | 3 +++ lib/chef/formatters/doc.rb | 36 ++++++++++++++++++++++++++++++++ lib/chef/knife/core/subcommand_loader.rb | 6 +++--- lib/chef/log.rb | 3 ++- lib/chef/mixin/deprecation.rb | 16 +++++++------- lib/chef/node_map.rb | 4 ++-- lib/chef/property.rb | 2 +- lib/chef/provider.rb | 2 +- lib/chef/provider_resolver.rb | 4 ++-- lib/chef/resource.rb | 6 +++--- lib/chef/resource/chef_gem.rb | 6 +++--- lib/chef/resource/file/verification.rb | 2 +- lib/chef/resource_resolver.rb | 6 +++--- lib/chef/run_context.rb | 8 +++---- 22 files changed, 111 insertions(+), 50 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/application.rb b/lib/chef/application.rb index 0563822ede..f43b6bbd8d 100644 --- a/lib/chef/application.rb +++ b/lib/chef/application.rb @@ -382,7 +382,7 @@ class Chef def emit_warnings if Chef::Config[:chef_gem_compile_time] - Chef::Log.deprecation "setting chef_gem_compile_time to true is deprecated" + Chef.log.deprecation "setting chef_gem_compile_time to true is deprecated" end end diff --git a/lib/chef/chef_class.rb b/lib/chef/chef_class.rb index 458ac82467..e825bedb34 100644 --- a/lib/chef/chef_class.rb +++ b/lib/chef/chef_class.rb @@ -190,6 +190,22 @@ class Chef def resource_handler_map @resource_handler_map ||= Chef::Platform::ResourceHandlerMap.instance end + + # + # @overload log + # Get the current log object. + # + # @return An object that supports `deprecation(message)` + # + # @example + # run_context.log.deprecation("Deprecated!") + # + # @api private + def log + # `run_context.events` is the primary deprecation target if we're in a run. If we + # are not yet in a run, print to `Chef::Log`. + (run_context && run_context.events) || Chef::Log + end end reset! diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb index 8d302eeec2..0a7e1df2f7 100644 --- a/lib/chef/cookbook_version.rb +++ b/lib/chef/cookbook_version.rb @@ -51,12 +51,12 @@ class Chef attr_accessor :metadata_filenames def status=(new_status) - Chef::Log.deprecation("Deprecated method `status' called from #{caller(1).first}. This method will be removed") + Chef.log.deprecation("Deprecated method `status' called. This method will be removed.", caller(1..1)) @status = new_status end def status - Chef::Log.deprecation("Deprecated method `status' called from #{caller(1).first}. This method will be removed") + Chef.log.deprecation("Deprecated method `status' called. This method will be removed.", caller(1..1)) @status end @@ -480,7 +480,7 @@ class Chef # @deprecated This method was used by the Ruby Chef Server and is no longer # needed. There is no replacement. def generate_manifest_with_urls(&url_generator) - Chef::Log.deprecation("Deprecated method #generate_manifest_with_urls called from #{caller(1).first}") + Chef.log.deprecation("Deprecated method #generate_manifest_with_urls.", caller(1..1)) rendered_manifest = manifest.dup COOKBOOK_SEGMENTS.each do |segment| diff --git a/lib/chef/deprecation/warnings.rb b/lib/chef/deprecation/warnings.rb index 34f468ff53..616f179d53 100644 --- a/lib/chef/deprecation/warnings.rb +++ b/lib/chef/deprecation/warnings.rb @@ -26,9 +26,8 @@ class Chef define_method(name) do |*args| message = [] message << "Method '#{name}' of '#{self.class}' is deprecated. It will be removed in Chef 12." - message << "Please update your cookbooks accordingly. Accessed from:" - caller[0..3].each {|l| message << l} - Chef::Log.deprecation message + message << "Please update your cookbooks accordingly." + Chef.log.deprecation(message, caller(0..3)) super(*args) end end diff --git a/lib/chef/dsl/recipe.rb b/lib/chef/dsl/recipe.rb index 29cfcd478c..e3b91a7eab 100644 --- a/lib/chef/dsl/recipe.rb +++ b/lib/chef/dsl/recipe.rb @@ -140,8 +140,7 @@ class Chef # method_missing manually. Not a fan. Not. A. Fan. # if respond_to?(method_symbol) - Chef::Log.deprecation("Calling method_missing(#{method_symbol.inspect}) directly is deprecated in Chef 12 and will be removed in Chef 13.") - Chef::Log.deprecation("Use public_send() or send() instead.") + Chef.log.deprecation("Calling method_missing(#{method_symbol.inspect}) directly is deprecated in Chef 12 and will be removed in Chef 13. Use public_send() or send() instead.") return send(method_symbol, *args, &block) end @@ -150,7 +149,7 @@ class Chef # never called. DEPRECATED. # if run_context.definitions.has_key?(method_symbol.to_sym) - Chef::Log.deprecation("Definition #{method_symbol} (#{run_context.definitions[method_symbol.to_sym]}) was added to the run_context without calling Chef::DSL::Definitions.add_definition(#{method_symbol.to_sym.inspect}). This will become required in Chef 13.") + Chef.log.deprecation("Definition #{method_symbol} (#{run_context.definitions[method_symbol.to_sym]}) was added to the run_context without calling Chef::DSL::Definitions.add_definition(#{method_symbol.to_sym.inspect}). This will become required in Chef 13.") Chef::DSL::Definitions.add_definition(method_symbol) return send(method_symbol, *args, &block) end diff --git a/lib/chef/dsl/resources.rb b/lib/chef/dsl/resources.rb index f15beaeab0..8e75223b0d 100644 --- a/lib/chef/dsl/resources.rb +++ b/lib/chef/dsl/resources.rb @@ -11,14 +11,14 @@ class Chef begin module_eval(<<-EOM, __FILE__, __LINE__+1) def #{dsl_name}(*args, &block) - Chef::Log.deprecation("Cannot create resource #{dsl_name} with more than one argument. All arguments except the name (\#{args[0].inspect}) will be ignored. This will cause an error in Chef 13. Arguments: \#{args}") if args.size > 1 + Chef.log.deprecation("Cannot create resource #{dsl_name} with more than one argument. All arguments except the name (\#{args[0].inspect}) will be ignored. This will cause an error in Chef 13. Arguments: \#{args}") if args.size > 1 declare_resource(#{dsl_name.inspect}, args[0], caller[0], &block) end EOM rescue SyntaxError # Handle the case where dsl_name has spaces, etc. define_method(dsl_name.to_sym) do |*args, &block| - Chef::Log.deprecation("Cannot create resource #{dsl_name} with more than one argument. All arguments except the name (#{args[0].inspect}) will be ignored. This will cause an error in Chef 13. Arguments: #{args}") if args.size > 1 + Chef.log.deprecation("Cannot create resource #{dsl_name} with more than one argument. All arguments except the name (#{args[0].inspect}) will be ignored. This will cause an error in Chef 13. Arguments: #{args}") if args.size > 1 declare_resource(dsl_name, args[0], caller[0], &block) end end diff --git a/lib/chef/event_dispatch/base.rb b/lib/chef/event_dispatch/base.rb index 0ae5101029..1c9a58be23 100644 --- a/lib/chef/event_dispatch/base.rb +++ b/lib/chef/event_dispatch/base.rb @@ -47,14 +47,19 @@ class Chef def ohai_completed(node) end - # Already have a client key, assuming this node has registered. + # Announce that we're not going to register the client. Generally because + # we already have the private key, or because we're deliberately not using + # a key. def skipping_registration(node_name, config) end - # About to attempt to register as +node_name+ + # About to attempt to create a private key registered to the server with + # client +node_name+. def registration_start(node_name, config) end + # Successfully created the private key and registered this client with the + # server. def registration_completed end @@ -340,7 +345,6 @@ class Chef def resource_completed(resource) end - # A stream has opened. def stream_opened(stream, options = {}) end @@ -376,8 +380,9 @@ class Chef def whyrun_assumption(action, resource, message) end - ## TODO: deprecation warning. this way we can queue them up and present - # them all at once. + # Emit a message about something being deprecated. + def deprecation(message, location=caller(2..2)[0]) + end # An uncategorized message. This supports the case that a user needs to # pass output that doesn't fit into one of the callbacks above. Note that diff --git a/lib/chef/event_dispatch/dispatcher.rb b/lib/chef/event_dispatch/dispatcher.rb index 9e17d78507..0c5b27514c 100644 --- a/lib/chef/event_dispatch/dispatcher.rb +++ b/lib/chef/event_dispatch/dispatcher.rb @@ -28,6 +28,9 @@ class Chef # Define a method that will be forwarded to all def self.def_forwarding_method(method_name) define_method(method_name) do |*args| + if method_name == :deprecation && args.size == 1 + args << caller(2..2)[0] + end @subscribers.each do |s| # Skip new/unsupported event names. if s.respond_to?(method_name) @@ -49,4 +52,3 @@ class Chef end end end - diff --git a/lib/chef/formatters/base.rb b/lib/chef/formatters/base.rb index c901068aa0..d3756ef00c 100644 --- a/lib/chef/formatters/base.rb +++ b/lib/chef/formatters/base.rb @@ -212,6 +212,9 @@ class Chef file_load_failed(path, exception) end + def deprecation(message, location=caller(2..2)[0]) + Chef::Log.deprecation("#{message} at #{location}") + end end diff --git a/lib/chef/formatters/doc.rb b/lib/chef/formatters/doc.rb index a5d7e210c5..614cc44e6d 100644 --- a/lib/chef/formatters/doc.rb +++ b/lib/chef/formatters/doc.rb @@ -43,6 +43,26 @@ class Chef def run_completed(node) @end_time = Time.now + # Print out deprecations. + if !deprecations.empty? + puts_line "" + puts_line "Deprecated features used!" + deprecations.each do |message, locations| + if locations.size == 1 + puts_line " #{message} at #{locations.size} location:" + else + puts_line " #{message} at #{locations.size} locations:" + end + locations.each do |location| + prefix = " - " + Array(location).each do |line| + puts_line "#{prefix}#{line}" + prefix = " " + end + end + end + puts_line "" + end if Chef::Config[:why_run] puts_line "Chef Client finished, #{@updated_resources}/#{total_resources} resources would have been updated" else @@ -336,6 +356,16 @@ class Chef end end + def deprecation(message, location=caller(2..2)[0]) + if Chef::Config[:treat_deprecation_warnings_as_errors] + super + end + + # Save deprecations to the screen until the end + deprecations[message] ||= Set.new + deprecations[message] << location + end + def indent indent_by(2) end @@ -343,6 +373,12 @@ class Chef def unindent indent_by(-2) end + + protected + + def deprecations + @deprecations ||= {} + end end end end diff --git a/lib/chef/knife/core/subcommand_loader.rb b/lib/chef/knife/core/subcommand_loader.rb index 1d359ffd53..646a75a21c 100644 --- a/lib/chef/knife/core/subcommand_loader.rb +++ b/lib/chef/knife/core/subcommand_loader.rb @@ -51,7 +51,7 @@ class Chef Chef::Log.debug("Using autogenerated hashed command manifest #{plugin_manifest_path}") Knife::SubcommandLoader::HashedCommandLoader.new(chef_config_dir, plugin_manifest) elsif custom_manifest? - Chef::Log.deprecation("Using custom manifest #{plugin_manifest_path} is deprecated. Please use a `knife rehash` autogenerated manifest instead.") + Chef.log.deprecation("Using custom manifest #{plugin_manifest_path} is deprecated. Please use a `knife rehash` autogenerated manifest instead.") Knife::SubcommandLoader::CustomManifestLoader.new(chef_config_dir, plugin_manifest) else Knife::SubcommandLoader::GemGlobLoader.new(chef_config_dir) @@ -84,7 +84,7 @@ class Chef # Deprecated and un-used instance variable. @env = env unless env.nil? - Chef::Log.deprecation("The env argument to Chef::Knife::SubcommandLoader is deprecated. If you are using env to inject/mock HOME, consider mocking Chef::Util::PathHelper.home instead.") + Chef.log.deprecation("The env argument to Chef::Knife::SubcommandLoader is deprecated. If you are using env to inject/mock HOME, consider mocking Chef::Util::PathHelper.home instead.") end end @@ -149,7 +149,7 @@ class Chef # to get in the past. # def subcommand_files - Chef::Log.deprecation "Using Chef::Knife::SubcommandLoader directly is deprecated. + Chef.log.deprecation "Using Chef::Knife::SubcommandLoader directly is deprecated. Please use Chef::Knife::SubcommandLoader.for_config(chef_config_dir, env)" @subcommand_files ||= if Chef::Knife::SubcommandLoader.plugin_manifest? Chef::Knife::SubcommandLoader::CustomManifestLoader.new(chef_config_dir, env).subcommand_files diff --git a/lib/chef/log.rb b/lib/chef/log.rb index 9b27778a40..2cf08324c8 100644 --- a/lib/chef/log.rb +++ b/lib/chef/log.rb @@ -37,7 +37,8 @@ class Chef end end - def self.deprecation(msg=nil, &block) + def self.deprecation(msg=nil, location=caller(2..2)[0], &block) + msg = Array(msg) + [ location ] if location if Chef::Config[:treat_deprecation_warnings_as_errors] error(msg, &block) raise Chef::Exceptions::DeprecatedFeatureError.new(msg) diff --git a/lib/chef/mixin/deprecation.rb b/lib/chef/mixin/deprecation.rb index a3eacf75cb..c90daee4f5 100644 --- a/lib/chef/mixin/deprecation.rb +++ b/lib/chef/mixin/deprecation.rb @@ -102,20 +102,20 @@ class Chef def deprecated_attr_reader(name, alternative, level=:warn) define_method(name) do - Chef::Log.deprecation("#{self.class}.#{name} is deprecated. Support will be removed in a future release.") - Chef::Log.deprecation(alternative) - Chef::Log.deprecation("Called from:") - caller[0..3].each {|c| Chef::Log.deprecation(c)} + Chef.log.deprecation("#{self.class}.#{name} is deprecated. Support will be removed in a future release.") + Chef.log.deprecation(alternative) + Chef.log.deprecation("Called from:") + caller[0..3].each {|c| Chef.log.deprecation(c)} instance_variable_get("@#{name}") end end def deprecated_attr_writer(name, alternative, level=:warn) define_method("#{name}=") do |value| - Chef::Log.deprecation("Writing to #{self.class}.#{name} with #{name}= is deprecated. Support will be removed in a future release.") - Chef::Log.deprecation(alternative) - Chef::Log.deprecation("Called from:") - caller[0..3].each {|c| Chef::Log.deprecation(c)} + Chef.log.deprecation("Writing to #{self.class}.#{name} with #{name}= is deprecated. Support will be removed in a future release.") + Chef.log.deprecation(alternative) + Chef.log.deprecation("Called from:") + caller[0..3].each {|c| Chef.log.deprecation(c)} instance_variable_set("@#{name}", value) end end diff --git a/lib/chef/node_map.rb b/lib/chef/node_map.rb index d905c8779e..2e62054b80 100644 --- a/lib/chef/node_map.rb +++ b/lib/chef/node_map.rb @@ -32,8 +32,8 @@ class Chef # @return [NodeMap] Returns self for possible chaining # def set(key, value, platform: nil, platform_version: nil, platform_family: nil, os: nil, on_platform: nil, on_platforms: nil, canonical: nil, override: nil, &block) - Chef::Log.deprecation "The on_platform option to node_map has been deprecated" if on_platform - Chef::Log.deprecation "The on_platforms option to node_map has been deprecated" if on_platforms + Chef.log.deprecation("The on_platform option to node_map has been deprecated") if on_platform + Chef.log.deprecation("The on_platforms option to node_map has been deprecated") if on_platforms platform ||= on_platform || on_platforms filters = {} filters[:platform] = platform if platform diff --git a/lib/chef/property.rb b/lib/chef/property.rb index 1a3b8ec72c..ccdc711698 100644 --- a/lib/chef/property.rb +++ b/lib/chef/property.rb @@ -228,7 +228,7 @@ class Chef if value.nil? && !explicitly_accepts_nil?(resource) # If you say "my_property nil" and the property explicitly accepts # nil values, we consider this a get. - Chef::Log.deprecation("#{name} nil currently does not overwrite the value of #{name}. This will change in Chef 13, and the value will be set to nil instead. Please change your code to explicitly accept nil using \"property :#{name}, [MyType, nil]\", or stop setting this value to nil.") + Chef.log.deprecation("#{name} nil currently does not overwrite the value of #{name}. This will change in Chef 13, and the value will be set to nil instead. Please change your code to explicitly accept nil using \"property :#{name}, [MyType, nil]\", or stop setting this value to nil.") return get(resource) end diff --git a/lib/chef/provider.rb b/lib/chef/provider.rb index f2a493c3e6..5f2430e26e 100644 --- a/lib/chef/provider.rb +++ b/lib/chef/provider.rb @@ -421,7 +421,7 @@ class Chef module DeprecatedLWRPClass def const_missing(class_name) if deprecated_constants[class_name.to_sym] - Chef::Log.deprecation("Using an LWRP provider by its name (#{class_name}) directly is no longer supported in Chef 12 and will be removed. Use Chef::ProviderResolver.new(node, resource, action) instead.") + Chef.log.deprecation("Using an LWRP provider by its name (#{class_name}) directly is no longer supported in Chef 12 and will be removed. Use Chef::ProviderResolver.new(node, resource, action) instead.") deprecated_constants[class_name.to_sym] else raise NameError, "uninitialized constant Chef::Provider::#{class_name}" diff --git a/lib/chef/provider_resolver.rb b/lib/chef/provider_resolver.rb index 8459bc1328..113b1081ee 100644 --- a/lib/chef/provider_resolver.rb +++ b/lib/chef/provider_resolver.rb @@ -157,8 +157,8 @@ class Chef # perf concern otherwise.) handlers = providers.select { |handler| overrode_provides?(handler) && handler.provides?(node, resource) } handlers.each do |handler| - Chef::Log.deprecation("#{handler}.provides? returned true when asked if it provides DSL #{resource.resource_name}, but provides #{resource.resource_name.inspect} was never called!") - Chef::Log.deprecation("In Chef 13, this will break: you must call provides to mark the names you provide, even if you also override provides? yourself.") + Chef.log.deprecation("#{handler}.provides? returned true when asked if it provides DSL #{resource.resource_name}, but provides #{resource.resource_name.inspect} was never called!") + Chef.log.deprecation("In Chef 13, this will break: you must call provides to mark the names you provide, even if you also override provides? yourself.") end end handlers diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb index 5bef40625f..6b8c5434f5 100644 --- a/lib/chef/resource.rb +++ b/lib/chef/resource.rb @@ -809,7 +809,7 @@ class Chef end if !options[:default].frozen? && (options[:default].is_a?(Array) || options[:default].is_a?(Hash)) - Chef::Log.warn("Property #{self}.#{name} has an array or hash default (#{options[:default]}). This means that if one resource modifies or appends to it, all other resources of the same type will also see the changes. Either freeze the constant with `.freeze` to prevent appending, or use lazy { #{options[:default].inspect} }.") + Chef.log.deprecation("Property #{self}.#{name} has an array or hash default (#{options[:default]}). This means that if one resource modifies or appends to it, all other resources of the same type will also see the changes. Either freeze the constant with `.freeze` to prevent appending, or use lazy { #{options[:default].inspect} }.") end local_properties = properties(false) @@ -1211,7 +1211,7 @@ class Chef # @deprecated Use resource_name instead. # def self.dsl_name - Chef::Log.deprecation "Resource.dsl_name is deprecated and will be removed in Chef 13. Use resource_name instead." + Chef.log.deprecation "Resource.dsl_name is deprecated and will be removed in Chef 13. Use resource_name instead." if name name = self.name.split('::')[-1] convert_to_snake_case(name) @@ -1288,7 +1288,7 @@ class Chef # def self.provider_base(arg=nil) if arg - Chef::Log.deprecation("Resource.provider_base is deprecated and will be removed in Chef 13. Use provides on the provider, or provider on the resource, instead.") + Chef.log.deprecation("Resource.provider_base is deprecated and will be removed in Chef 13. Use provides on the provider, or provider on the resource, instead.") end @provider_base ||= arg || Chef::Provider end diff --git a/lib/chef/resource/chef_gem.rb b/lib/chef/resource/chef_gem.rb index 0c2fdfa819..4d198421ce 100644 --- a/lib/chef/resource/chef_gem.rb +++ b/lib/chef/resource/chef_gem.rb @@ -50,9 +50,9 @@ class Chef # Chef::Resource.run_action: Caveat: this skips Chef::Runner.run_action, where notifications are handled # Action could be an array of symbols, but probably won't (think install + enable for a package) if compile_time.nil? - Chef::Log.deprecation "#{self} chef_gem compile_time installation is deprecated" - Chef::Log.deprecation "#{self} Please set `compile_time false` on the resource to use the new behavior." - Chef::Log.deprecation "#{self} or set `compile_time true` on the resource if compile_time behavior is required." + Chef.log.deprecation "#{self} chef_gem compile_time installation is deprecated" + Chef.log.deprecation "#{self} Please set `compile_time false` on the resource to use the new behavior." + Chef.log.deprecation "#{self} or set `compile_time true` on the resource if compile_time behavior is required." end if compile_time || compile_time.nil? diff --git a/lib/chef/resource/file/verification.rb b/lib/chef/resource/file/verification.rb index faf4791884..654f2d72ce 100644 --- a/lib/chef/resource/file/verification.rb +++ b/lib/chef/resource/file/verification.rb @@ -108,7 +108,7 @@ class Chef def verify_command(path, opts) # First implementation interpolated `file`; docs & RFC claim `path` # is interpolated. Until `file` can be deprecated, interpolate both. - Chef::Log.deprecation( + Chef.log.deprecation( '%{file} is deprecated in verify command and will not be '\ 'supported in Chef 13. Please use %{path} instead.' ) if @command.include?('%{file}') diff --git a/lib/chef/resource_resolver.rb b/lib/chef/resource_resolver.rb index 47b3df18af..14b0ff849d 100644 --- a/lib/chef/resource_resolver.rb +++ b/lib/chef/resource_resolver.rb @@ -56,7 +56,7 @@ class Chef attr_reader :resource_name # @api private def resource - Chef::Log.deprecation("Chef::ResourceResolver.resource deprecated. Use resource_name instead.") + Chef.log.deprecation("Chef::ResourceResolver.resource deprecated. Use resource_name instead.") resource_name end # @api private @@ -174,8 +174,8 @@ class Chef if handlers.empty? handlers = resources.select { |handler| overrode_provides?(handler) && handler.provides?(node, resource_name) } handlers.each do |handler| - Chef::Log.deprecation("#{handler}.provides? returned true when asked if it provides DSL #{resource_name}, but provides #{resource_name.inspect} was never called!") - Chef::Log.deprecation("In Chef 13, this will break: you must call provides to mark the names you provide, even if you also override provides? yourself.") + Chef.log.deprecation("#{handler}.provides? returned true when asked if it provides DSL #{resource_name}, but provides #{resource_name.inspect} was never called!") + Chef.log.deprecation("In Chef 13, this will break: you must call provides to mark the names you provide, even if you also override provides? yourself.") end end handlers diff --git a/lib/chef/run_context.rb b/lib/chef/run_context.rb index b1113f594e..dd2da0d7ac 100644 --- a/lib/chef/run_context.rb +++ b/lib/chef/run_context.rb @@ -533,22 +533,22 @@ ERROR_MESSAGE # These need to be settable so deploy can run a resource_collection # independent of any cookbooks via +recipe_eval+ def resource_collection=(value) - Chef::Log.deprecation("Setting run_context.resource_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") + Chef.log.deprecation("Setting run_context.resource_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") @resource_collection = value end def audits=(value) - Chef::Log.deprecation("Setting run_context.audits will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") + Chef.log.deprecation("Setting run_context.audits will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") @audits = value end def immediate_notification_collection=(value) - Chef::Log.deprecation("Setting run_context.immediate_notification_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") + Chef.log.deprecation("Setting run_context.immediate_notification_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") @immediate_notification_collection = value end def delayed_notification_collection=(value) - Chef::Log.deprecation("Setting run_context.delayed_notification_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") + Chef.log.deprecation("Setting run_context.delayed_notification_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") @delayed_notification_collection = value end end -- cgit v1.2.1 From 310f0104d0807f46b77e6055bb20bb20276f33ad Mon Sep 17 00:00:00 2001 From: John Keiser Date: Tue, 1 Sep 2015 13:01:42 -0700 Subject: Make Dispatcher metaprogramming more straightforward --- lib/chef/event_dispatch/dispatcher.rb | 36 +++++++++++++++++------------------ lib/chef/log.rb | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/event_dispatch/dispatcher.rb b/lib/chef/event_dispatch/dispatcher.rb index 0c5b27514c..0f05365ab1 100644 --- a/lib/chef/event_dispatch/dispatcher.rb +++ b/lib/chef/event_dispatch/dispatcher.rb @@ -25,30 +25,30 @@ class Chef # define the forwarding in one go: # - # Define a method that will be forwarded to all - def self.def_forwarding_method(method_name) - define_method(method_name) do |*args| - if method_name == :deprecation && args.size == 1 - args << caller(2..2)[0] - end - @subscribers.each do |s| - # Skip new/unsupported event names. - if s.respond_to?(method_name) - mth = s.method(method_name) - # Anything with a *args is arity -1, so use all arguments. - arity = mth.arity < 0 ? args.length : mth.arity - # Trim arguments to match what the subscriber expects to allow - # adding new arguments without breaking compat. - mth.call(*args.take(arity)) - end - end + def call_subscribers(method_name, *args) + @subscribers.each do |s| + # Skip new/unsupported event names. + next if !s.respond_to?(method_name) + mth = s.method(method_name) + # Trim arguments to match what the subscriber expects to allow + # adding new arguments without breaking compat. + args = args.take(arity) if mth.arity < args.size && mth.arity >= 0 + mth.call(*args) end end (Base.instance_methods - Object.instance_methods).each do |method_name| - def_forwarding_method(method_name) + class_eval <<-EOM + def #{method_name}(*args) + call_subscribers(#{method_name.inspect}, *args) + end + EOM end + # Special case deprecation, since it needs to know its caller + def deprecation(message, location=caller(2..2)[0]) + call_subscribers(:deprecation, message, location) + end end end end diff --git a/lib/chef/log.rb b/lib/chef/log.rb index 2cf08324c8..aff6252e12 100644 --- a/lib/chef/log.rb +++ b/lib/chef/log.rb @@ -38,7 +38,7 @@ class Chef end def self.deprecation(msg=nil, location=caller(2..2)[0], &block) - msg = Array(msg) + [ location ] if location + msg << " at #{Array(location).join("\n")}" if Chef::Config[:treat_deprecation_warnings_as_errors] error(msg, &block) raise Chef::Exceptions::DeprecatedFeatureError.new(msg) -- cgit v1.2.1 From 386468df5441f4a75865bccfd9314f883e5f39ff Mon Sep 17 00:00:00 2001 From: John Keiser Date: Tue, 1 Sep 2015 13:05:40 -0700 Subject: Pass the buck on deprecations from Chef 12 -> 13 --- lib/chef/deprecation/mixin/template.rb | 3 +-- lib/chef/deprecation/provider/cookbook_file.rb | 2 +- lib/chef/deprecation/provider/file.rb | 2 +- lib/chef/deprecation/provider/remote_file.rb | 3 +-- lib/chef/deprecation/provider/template.rb | 2 +- lib/chef/deprecation/warnings.rb | 2 +- 6 files changed, 6 insertions(+), 8 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/deprecation/mixin/template.rb b/lib/chef/deprecation/mixin/template.rb index 36d18ad90d..58a661c4bd 100644 --- a/lib/chef/deprecation/mixin/template.rb +++ b/lib/chef/deprecation/mixin/template.rb @@ -25,7 +25,7 @@ class Chef # == Deprecation::Provider::Mixin::Template # This module contains the deprecated functions of # Chef::Mixin::Template. These functions are refactored to different - # components. They are frozen and will be removed in Chef 12. + # components. They are frozen and will be removed in Chef 13. # module Template @@ -46,4 +46,3 @@ class Chef end end end - diff --git a/lib/chef/deprecation/provider/cookbook_file.rb b/lib/chef/deprecation/provider/cookbook_file.rb index dfbf4a39a4..92f5ce3623 100644 --- a/lib/chef/deprecation/provider/cookbook_file.rb +++ b/lib/chef/deprecation/provider/cookbook_file.rb @@ -24,7 +24,7 @@ class Chef # == Deprecation::Provider::CookbookFile # This module contains the deprecated functions of # Chef::Provider::CookbookFile. These functions are refactored to - # different components. They are frozen and will be removed in Chef 12. + # different components. They are frozen and will be removed in Chef 13. # module CookbookFile diff --git a/lib/chef/deprecation/provider/file.rb b/lib/chef/deprecation/provider/file.rb index 125f31fe10..31038ab3d8 100644 --- a/lib/chef/deprecation/provider/file.rb +++ b/lib/chef/deprecation/provider/file.rb @@ -25,7 +25,7 @@ class Chef # == Deprecation::Provider::File # This module contains the deprecated functions of # Chef::Provider::File. These functions are refactored to different - # components. They are frozen and will be removed in Chef 12. + # components. They are frozen and will be removed in Chef 13. # module File diff --git a/lib/chef/deprecation/provider/remote_file.rb b/lib/chef/deprecation/provider/remote_file.rb index 4452de67cd..c06a5cc695 100644 --- a/lib/chef/deprecation/provider/remote_file.rb +++ b/lib/chef/deprecation/provider/remote_file.rb @@ -23,7 +23,7 @@ class Chef # == Deprecation::Provider::RemoteFile # This module contains the deprecated functions of # Chef::Provider::RemoteFile. These functions are refactored to different - # components. They are frozen and will be removed in Chef 12. + # components. They are frozen and will be removed in Chef 13. # module RemoteFile @@ -83,4 +83,3 @@ class Chef end end end - diff --git a/lib/chef/deprecation/provider/template.rb b/lib/chef/deprecation/provider/template.rb index d7a228e97a..34e5f54b7e 100644 --- a/lib/chef/deprecation/provider/template.rb +++ b/lib/chef/deprecation/provider/template.rb @@ -25,7 +25,7 @@ class Chef # == Deprecation::Provider::Template # This module contains the deprecated functions of # Chef::Provider::Template. These functions are refactored to different - # components. They are frozen and will be removed in Chef 12. + # components. They are frozen and will be removed in Chef 13. # module Template diff --git a/lib/chef/deprecation/warnings.rb b/lib/chef/deprecation/warnings.rb index 616f179d53..d6a9cbe374 100644 --- a/lib/chef/deprecation/warnings.rb +++ b/lib/chef/deprecation/warnings.rb @@ -25,7 +25,7 @@ class Chef m = instance_method(name) define_method(name) do |*args| message = [] - message << "Method '#{name}' of '#{self.class}' is deprecated. It will be removed in Chef 12." + message << "Method '#{name}' of '#{self.class}' is deprecated. It will be removed in Chef 13." message << "Please update your cookbooks accordingly." Chef.log.deprecation(message, caller(0..3)) super(*args) -- cgit v1.2.1 From f975355dc9cb9ef73ff86471a32bfac459efeb7a Mon Sep 17 00:00:00 2001 From: John Keiser Date: Tue, 1 Sep 2015 13:21:02 -0700 Subject: Rename log.deprecation to log_deprecation --- lib/chef/application.rb | 2 +- lib/chef/chef_class.rb | 27 +++++++++++++++++---------- lib/chef/cookbook_version.rb | 6 +++--- lib/chef/deprecation/warnings.rb | 2 +- lib/chef/dsl/recipe.rb | 4 ++-- lib/chef/dsl/resources.rb | 4 ++-- lib/chef/knife/core/subcommand_loader.rb | 6 +++--- lib/chef/mixin/deprecation.rb | 16 ++++++++-------- lib/chef/node_map.rb | 4 ++-- lib/chef/property.rb | 2 +- lib/chef/provider.rb | 2 +- lib/chef/provider_resolver.rb | 4 ++-- lib/chef/resource.rb | 6 +++--- lib/chef/resource/chef_gem.rb | 6 +++--- lib/chef/resource/file/verification.rb | 2 +- lib/chef/resource_resolver.rb | 6 +++--- lib/chef/run_context.rb | 8 ++++---- 17 files changed, 57 insertions(+), 50 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/application.rb b/lib/chef/application.rb index f43b6bbd8d..970544c068 100644 --- a/lib/chef/application.rb +++ b/lib/chef/application.rb @@ -382,7 +382,7 @@ class Chef def emit_warnings if Chef::Config[:chef_gem_compile_time] - Chef.log.deprecation "setting chef_gem_compile_time to true is deprecated" + Chef.log_deprecation "setting chef_gem_compile_time to true is deprecated" end end diff --git a/lib/chef/chef_class.rb b/lib/chef/chef_class.rb index e825bedb34..c2cb9e2b24 100644 --- a/lib/chef/chef_class.rb +++ b/lib/chef/chef_class.rb @@ -192,19 +192,26 @@ class Chef end # - # @overload log - # Get the current log object. + # Emit a deprecation message. # - # @return An object that supports `deprecation(message)` + # @param message The message to send. + # @param location The location. Defaults to the caller who called you (since + # generally the person who triggered the check is the one that needs to be + # fixed). # # @example - # run_context.log.deprecation("Deprecated!") - # - # @api private - def log - # `run_context.events` is the primary deprecation target if we're in a run. If we - # are not yet in a run, print to `Chef::Log`. - (run_context && run_context.events) || Chef::Log + # Chef.deprecation("Deprecated!") + # + # @api private this will likely be removed in favor of an as-yet unwritten + # `Chef.log` + def log_deprecation(message, location=caller(2..2)[0]) + # `run_context.events` is the primary deprecation target if we're in a + # run. If we are not yet in a run, print to `Chef::Log`. + if run_context && run_context.events + run_context.events.deprecation(message, location) + else + Chef::Log.deprecation(message, location) + end end end diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb index 0a7e1df2f7..bff3146572 100644 --- a/lib/chef/cookbook_version.rb +++ b/lib/chef/cookbook_version.rb @@ -51,12 +51,12 @@ class Chef attr_accessor :metadata_filenames def status=(new_status) - Chef.log.deprecation("Deprecated method `status' called. This method will be removed.", caller(1..1)) + Chef.log_deprecation("Deprecated method `status' called. This method will be removed.", caller(1..1)) @status = new_status end def status - Chef.log.deprecation("Deprecated method `status' called. This method will be removed.", caller(1..1)) + Chef.log_deprecation("Deprecated method `status' called. This method will be removed.", caller(1..1)) @status end @@ -480,7 +480,7 @@ class Chef # @deprecated This method was used by the Ruby Chef Server and is no longer # needed. There is no replacement. def generate_manifest_with_urls(&url_generator) - Chef.log.deprecation("Deprecated method #generate_manifest_with_urls.", caller(1..1)) + Chef.log_deprecation("Deprecated method #generate_manifest_with_urls.", caller(1..1)) rendered_manifest = manifest.dup COOKBOOK_SEGMENTS.each do |segment| diff --git a/lib/chef/deprecation/warnings.rb b/lib/chef/deprecation/warnings.rb index d6a9cbe374..376629710e 100644 --- a/lib/chef/deprecation/warnings.rb +++ b/lib/chef/deprecation/warnings.rb @@ -27,7 +27,7 @@ class Chef message = [] message << "Method '#{name}' of '#{self.class}' is deprecated. It will be removed in Chef 13." message << "Please update your cookbooks accordingly." - Chef.log.deprecation(message, caller(0..3)) + Chef.log_deprecation(message, caller(0..3)) super(*args) end end diff --git a/lib/chef/dsl/recipe.rb b/lib/chef/dsl/recipe.rb index e3b91a7eab..26c0ec6768 100644 --- a/lib/chef/dsl/recipe.rb +++ b/lib/chef/dsl/recipe.rb @@ -140,7 +140,7 @@ class Chef # method_missing manually. Not a fan. Not. A. Fan. # if respond_to?(method_symbol) - Chef.log.deprecation("Calling method_missing(#{method_symbol.inspect}) directly is deprecated in Chef 12 and will be removed in Chef 13. Use public_send() or send() instead.") + Chef.log_deprecation("Calling method_missing(#{method_symbol.inspect}) directly is deprecated in Chef 12 and will be removed in Chef 13. Use public_send() or send() instead.") return send(method_symbol, *args, &block) end @@ -149,7 +149,7 @@ class Chef # never called. DEPRECATED. # if run_context.definitions.has_key?(method_symbol.to_sym) - Chef.log.deprecation("Definition #{method_symbol} (#{run_context.definitions[method_symbol.to_sym]}) was added to the run_context without calling Chef::DSL::Definitions.add_definition(#{method_symbol.to_sym.inspect}). This will become required in Chef 13.") + Chef.log_deprecation("Definition #{method_symbol} (#{run_context.definitions[method_symbol.to_sym]}) was added to the run_context without calling Chef::DSL::Definitions.add_definition(#{method_symbol.to_sym.inspect}). This will become required in Chef 13.") Chef::DSL::Definitions.add_definition(method_symbol) return send(method_symbol, *args, &block) end diff --git a/lib/chef/dsl/resources.rb b/lib/chef/dsl/resources.rb index 8e75223b0d..49588ed516 100644 --- a/lib/chef/dsl/resources.rb +++ b/lib/chef/dsl/resources.rb @@ -11,14 +11,14 @@ class Chef begin module_eval(<<-EOM, __FILE__, __LINE__+1) def #{dsl_name}(*args, &block) - Chef.log.deprecation("Cannot create resource #{dsl_name} with more than one argument. All arguments except the name (\#{args[0].inspect}) will be ignored. This will cause an error in Chef 13. Arguments: \#{args}") if args.size > 1 + Chef.log_deprecation("Cannot create resource #{dsl_name} with more than one argument. All arguments except the name (\#{args[0].inspect}) will be ignored. This will cause an error in Chef 13. Arguments: \#{args}") if args.size > 1 declare_resource(#{dsl_name.inspect}, args[0], caller[0], &block) end EOM rescue SyntaxError # Handle the case where dsl_name has spaces, etc. define_method(dsl_name.to_sym) do |*args, &block| - Chef.log.deprecation("Cannot create resource #{dsl_name} with more than one argument. All arguments except the name (#{args[0].inspect}) will be ignored. This will cause an error in Chef 13. Arguments: #{args}") if args.size > 1 + Chef.log_deprecation("Cannot create resource #{dsl_name} with more than one argument. All arguments except the name (#{args[0].inspect}) will be ignored. This will cause an error in Chef 13. Arguments: #{args}") if args.size > 1 declare_resource(dsl_name, args[0], caller[0], &block) end end diff --git a/lib/chef/knife/core/subcommand_loader.rb b/lib/chef/knife/core/subcommand_loader.rb index 646a75a21c..808e053c40 100644 --- a/lib/chef/knife/core/subcommand_loader.rb +++ b/lib/chef/knife/core/subcommand_loader.rb @@ -51,7 +51,7 @@ class Chef Chef::Log.debug("Using autogenerated hashed command manifest #{plugin_manifest_path}") Knife::SubcommandLoader::HashedCommandLoader.new(chef_config_dir, plugin_manifest) elsif custom_manifest? - Chef.log.deprecation("Using custom manifest #{plugin_manifest_path} is deprecated. Please use a `knife rehash` autogenerated manifest instead.") + Chef.log_deprecation("Using custom manifest #{plugin_manifest_path} is deprecated. Please use a `knife rehash` autogenerated manifest instead.") Knife::SubcommandLoader::CustomManifestLoader.new(chef_config_dir, plugin_manifest) else Knife::SubcommandLoader::GemGlobLoader.new(chef_config_dir) @@ -84,7 +84,7 @@ class Chef # Deprecated and un-used instance variable. @env = env unless env.nil? - Chef.log.deprecation("The env argument to Chef::Knife::SubcommandLoader is deprecated. If you are using env to inject/mock HOME, consider mocking Chef::Util::PathHelper.home instead.") + Chef.log_deprecation("The env argument to Chef::Knife::SubcommandLoader is deprecated. If you are using env to inject/mock HOME, consider mocking Chef::Util::PathHelper.home instead.") end end @@ -149,7 +149,7 @@ class Chef # to get in the past. # def subcommand_files - Chef.log.deprecation "Using Chef::Knife::SubcommandLoader directly is deprecated. + Chef.log_deprecation "Using Chef::Knife::SubcommandLoader directly is deprecated. Please use Chef::Knife::SubcommandLoader.for_config(chef_config_dir, env)" @subcommand_files ||= if Chef::Knife::SubcommandLoader.plugin_manifest? Chef::Knife::SubcommandLoader::CustomManifestLoader.new(chef_config_dir, env).subcommand_files diff --git a/lib/chef/mixin/deprecation.rb b/lib/chef/mixin/deprecation.rb index c90daee4f5..562af541bd 100644 --- a/lib/chef/mixin/deprecation.rb +++ b/lib/chef/mixin/deprecation.rb @@ -102,20 +102,20 @@ class Chef def deprecated_attr_reader(name, alternative, level=:warn) define_method(name) do - Chef.log.deprecation("#{self.class}.#{name} is deprecated. Support will be removed in a future release.") - Chef.log.deprecation(alternative) - Chef.log.deprecation("Called from:") - caller[0..3].each {|c| Chef.log.deprecation(c)} + Chef.log_deprecation("#{self.class}.#{name} is deprecated. Support will be removed in a future release.") + Chef.log_deprecation(alternative) + Chef.log_deprecation("Called from:") + caller[0..3].each {|c| Chef.log_deprecation(c)} instance_variable_get("@#{name}") end end def deprecated_attr_writer(name, alternative, level=:warn) define_method("#{name}=") do |value| - Chef.log.deprecation("Writing to #{self.class}.#{name} with #{name}= is deprecated. Support will be removed in a future release.") - Chef.log.deprecation(alternative) - Chef.log.deprecation("Called from:") - caller[0..3].each {|c| Chef.log.deprecation(c)} + Chef.log_deprecation("Writing to #{self.class}.#{name} with #{name}= is deprecated. Support will be removed in a future release.") + Chef.log_deprecation(alternative) + Chef.log_deprecation("Called from:") + caller[0..3].each {|c| Chef.log_deprecation(c)} instance_variable_set("@#{name}", value) end end diff --git a/lib/chef/node_map.rb b/lib/chef/node_map.rb index 2e62054b80..751f9576f6 100644 --- a/lib/chef/node_map.rb +++ b/lib/chef/node_map.rb @@ -32,8 +32,8 @@ class Chef # @return [NodeMap] Returns self for possible chaining # def set(key, value, platform: nil, platform_version: nil, platform_family: nil, os: nil, on_platform: nil, on_platforms: nil, canonical: nil, override: nil, &block) - Chef.log.deprecation("The on_platform option to node_map has been deprecated") if on_platform - Chef.log.deprecation("The on_platforms option to node_map has been deprecated") if on_platforms + Chef.log_deprecation("The on_platform option to node_map has been deprecated") if on_platform + Chef.log_deprecation("The on_platforms option to node_map has been deprecated") if on_platforms platform ||= on_platform || on_platforms filters = {} filters[:platform] = platform if platform diff --git a/lib/chef/property.rb b/lib/chef/property.rb index ccdc711698..09198d90f1 100644 --- a/lib/chef/property.rb +++ b/lib/chef/property.rb @@ -228,7 +228,7 @@ class Chef if value.nil? && !explicitly_accepts_nil?(resource) # If you say "my_property nil" and the property explicitly accepts # nil values, we consider this a get. - Chef.log.deprecation("#{name} nil currently does not overwrite the value of #{name}. This will change in Chef 13, and the value will be set to nil instead. Please change your code to explicitly accept nil using \"property :#{name}, [MyType, nil]\", or stop setting this value to nil.") + Chef.log_deprecation("#{name} nil currently does not overwrite the value of #{name}. This will change in Chef 13, and the value will be set to nil instead. Please change your code to explicitly accept nil using \"property :#{name}, [MyType, nil]\", or stop setting this value to nil.") return get(resource) end diff --git a/lib/chef/provider.rb b/lib/chef/provider.rb index 5f2430e26e..3138704a55 100644 --- a/lib/chef/provider.rb +++ b/lib/chef/provider.rb @@ -421,7 +421,7 @@ class Chef module DeprecatedLWRPClass def const_missing(class_name) if deprecated_constants[class_name.to_sym] - Chef.log.deprecation("Using an LWRP provider by its name (#{class_name}) directly is no longer supported in Chef 12 and will be removed. Use Chef::ProviderResolver.new(node, resource, action) instead.") + Chef.log_deprecation("Using an LWRP provider by its name (#{class_name}) directly is no longer supported in Chef 12 and will be removed. Use Chef::ProviderResolver.new(node, resource, action) instead.") deprecated_constants[class_name.to_sym] else raise NameError, "uninitialized constant Chef::Provider::#{class_name}" diff --git a/lib/chef/provider_resolver.rb b/lib/chef/provider_resolver.rb index 113b1081ee..82a24fc078 100644 --- a/lib/chef/provider_resolver.rb +++ b/lib/chef/provider_resolver.rb @@ -157,8 +157,8 @@ class Chef # perf concern otherwise.) handlers = providers.select { |handler| overrode_provides?(handler) && handler.provides?(node, resource) } handlers.each do |handler| - Chef.log.deprecation("#{handler}.provides? returned true when asked if it provides DSL #{resource.resource_name}, but provides #{resource.resource_name.inspect} was never called!") - Chef.log.deprecation("In Chef 13, this will break: you must call provides to mark the names you provide, even if you also override provides? yourself.") + Chef.log_deprecation("#{handler}.provides? returned true when asked if it provides DSL #{resource.resource_name}, but provides #{resource.resource_name.inspect} was never called!") + Chef.log_deprecation("In Chef 13, this will break: you must call provides to mark the names you provide, even if you also override provides? yourself.") end end handlers diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb index 6b8c5434f5..ee75dec3b9 100644 --- a/lib/chef/resource.rb +++ b/lib/chef/resource.rb @@ -809,7 +809,7 @@ class Chef end if !options[:default].frozen? && (options[:default].is_a?(Array) || options[:default].is_a?(Hash)) - Chef.log.deprecation("Property #{self}.#{name} has an array or hash default (#{options[:default]}). This means that if one resource modifies or appends to it, all other resources of the same type will also see the changes. Either freeze the constant with `.freeze` to prevent appending, or use lazy { #{options[:default].inspect} }.") + Chef.log_deprecation("Property #{self}.#{name} has an array or hash default (#{options[:default]}). This means that if one resource modifies or appends to it, all other resources of the same type will also see the changes. Either freeze the constant with `.freeze` to prevent appending, or use lazy { #{options[:default].inspect} }.") end local_properties = properties(false) @@ -1211,7 +1211,7 @@ class Chef # @deprecated Use resource_name instead. # def self.dsl_name - Chef.log.deprecation "Resource.dsl_name is deprecated and will be removed in Chef 13. Use resource_name instead." + Chef.log_deprecation "Resource.dsl_name is deprecated and will be removed in Chef 13. Use resource_name instead." if name name = self.name.split('::')[-1] convert_to_snake_case(name) @@ -1288,7 +1288,7 @@ class Chef # def self.provider_base(arg=nil) if arg - Chef.log.deprecation("Resource.provider_base is deprecated and will be removed in Chef 13. Use provides on the provider, or provider on the resource, instead.") + Chef.log_deprecation("Resource.provider_base is deprecated and will be removed in Chef 13. Use provides on the provider, or provider on the resource, instead.") end @provider_base ||= arg || Chef::Provider end diff --git a/lib/chef/resource/chef_gem.rb b/lib/chef/resource/chef_gem.rb index 4d198421ce..7e9d21ebd2 100644 --- a/lib/chef/resource/chef_gem.rb +++ b/lib/chef/resource/chef_gem.rb @@ -50,9 +50,9 @@ class Chef # Chef::Resource.run_action: Caveat: this skips Chef::Runner.run_action, where notifications are handled # Action could be an array of symbols, but probably won't (think install + enable for a package) if compile_time.nil? - Chef.log.deprecation "#{self} chef_gem compile_time installation is deprecated" - Chef.log.deprecation "#{self} Please set `compile_time false` on the resource to use the new behavior." - Chef.log.deprecation "#{self} or set `compile_time true` on the resource if compile_time behavior is required." + Chef.log_deprecation "#{self} chef_gem compile_time installation is deprecated" + Chef.log_deprecation "#{self} Please set `compile_time false` on the resource to use the new behavior." + Chef.log_deprecation "#{self} or set `compile_time true` on the resource if compile_time behavior is required." end if compile_time || compile_time.nil? diff --git a/lib/chef/resource/file/verification.rb b/lib/chef/resource/file/verification.rb index 654f2d72ce..ba0bb08201 100644 --- a/lib/chef/resource/file/verification.rb +++ b/lib/chef/resource/file/verification.rb @@ -108,7 +108,7 @@ class Chef def verify_command(path, opts) # First implementation interpolated `file`; docs & RFC claim `path` # is interpolated. Until `file` can be deprecated, interpolate both. - Chef.log.deprecation( + Chef.log_deprecation( '%{file} is deprecated in verify command and will not be '\ 'supported in Chef 13. Please use %{path} instead.' ) if @command.include?('%{file}') diff --git a/lib/chef/resource_resolver.rb b/lib/chef/resource_resolver.rb index 14b0ff849d..67cf134c62 100644 --- a/lib/chef/resource_resolver.rb +++ b/lib/chef/resource_resolver.rb @@ -56,7 +56,7 @@ class Chef attr_reader :resource_name # @api private def resource - Chef.log.deprecation("Chef::ResourceResolver.resource deprecated. Use resource_name instead.") + Chef.log_deprecation("Chef::ResourceResolver.resource deprecated. Use resource_name instead.") resource_name end # @api private @@ -174,8 +174,8 @@ class Chef if handlers.empty? handlers = resources.select { |handler| overrode_provides?(handler) && handler.provides?(node, resource_name) } handlers.each do |handler| - Chef.log.deprecation("#{handler}.provides? returned true when asked if it provides DSL #{resource_name}, but provides #{resource_name.inspect} was never called!") - Chef.log.deprecation("In Chef 13, this will break: you must call provides to mark the names you provide, even if you also override provides? yourself.") + Chef.log_deprecation("#{handler}.provides? returned true when asked if it provides DSL #{resource_name}, but provides #{resource_name.inspect} was never called!") + Chef.log_deprecation("In Chef 13, this will break: you must call provides to mark the names you provide, even if you also override provides? yourself.") end end handlers diff --git a/lib/chef/run_context.rb b/lib/chef/run_context.rb index dd2da0d7ac..0c8d3d1a48 100644 --- a/lib/chef/run_context.rb +++ b/lib/chef/run_context.rb @@ -533,22 +533,22 @@ ERROR_MESSAGE # These need to be settable so deploy can run a resource_collection # independent of any cookbooks via +recipe_eval+ def resource_collection=(value) - Chef.log.deprecation("Setting run_context.resource_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") + Chef.log_deprecation("Setting run_context.resource_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") @resource_collection = value end def audits=(value) - Chef.log.deprecation("Setting run_context.audits will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") + Chef.log_deprecation("Setting run_context.audits will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") @audits = value end def immediate_notification_collection=(value) - Chef.log.deprecation("Setting run_context.immediate_notification_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") + Chef.log_deprecation("Setting run_context.immediate_notification_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") @immediate_notification_collection = value end def delayed_notification_collection=(value) - Chef.log.deprecation("Setting run_context.delayed_notification_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") + Chef.log_deprecation("Setting run_context.delayed_notification_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") @delayed_notification_collection = value end end -- cgit v1.2.1 From 86d422017d0d990ac396ac5109320a8a4bbbe878 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Tue, 1 Sep 2015 14:00:44 -0700 Subject: Fix dispatching events to methods with arity < args --- lib/chef/event_dispatch/dispatcher.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/event_dispatch/dispatcher.rb b/lib/chef/event_dispatch/dispatcher.rb index 0f05365ab1..966a3f32ec 100644 --- a/lib/chef/event_dispatch/dispatcher.rb +++ b/lib/chef/event_dispatch/dispatcher.rb @@ -32,7 +32,7 @@ class Chef mth = s.method(method_name) # Trim arguments to match what the subscriber expects to allow # adding new arguments without breaking compat. - args = args.take(arity) if mth.arity < args.size && mth.arity >= 0 + args = args.take(mth.arity) if mth.arity < args.size && mth.arity >= 0 mth.call(*args) end end -- cgit v1.2.1 From 8379bcbdf656f09dbf62a6dfffed5217bf6a146f Mon Sep 17 00:00:00 2001 From: John Keiser Date: Tue, 1 Sep 2015 14:01:17 -0700 Subject: Send a string, not an array --- lib/chef/log.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/log.rb b/lib/chef/log.rb index aff6252e12..bf846c2072 100644 --- a/lib/chef/log.rb +++ b/lib/chef/log.rb @@ -38,7 +38,10 @@ class Chef end def self.deprecation(msg=nil, location=caller(2..2)[0], &block) - msg << " at #{Array(location).join("\n")}" + if msg + msg << " at #{Array(location).join("\n")}" + msg = msg.join("") if msg.respond_to?(:join) + end if Chef::Config[:treat_deprecation_warnings_as_errors] error(msg, &block) raise Chef::Exceptions::DeprecatedFeatureError.new(msg) -- cgit v1.2.1 From a8d5109721deb5d90687f38e10bb37765a5ac65a Mon Sep 17 00:00:00 2001 From: John Keiser Date: Tue, 1 Sep 2015 19:29:53 -0700 Subject: Make file verification deprecation print the proper source loc --- lib/chef/resource/file/verification.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/resource/file/verification.rb b/lib/chef/resource/file/verification.rb index ba0bb08201..9b0788fad3 100644 --- a/lib/chef/resource/file/verification.rb +++ b/lib/chef/resource/file/verification.rb @@ -110,7 +110,8 @@ class Chef # is interpolated. Until `file` can be deprecated, interpolate both. Chef.log_deprecation( '%{file} is deprecated in verify command and will not be '\ - 'supported in Chef 13. Please use %{path} instead.' + 'supported in Chef 13. Please use %{path} instead.', + caller(2..2)[0] ) if @command.include?('%{file}') command = @command % {:file => path, :path => path} interpreter = Chef::GuardInterpreter.for_resource(@parent_resource, command, @command_opts) -- cgit v1.2.1 From 3fa5f5c09f018c08ba64913d82bef6956550fa0b Mon Sep 17 00:00:00 2001 From: Noah Kantrowitz Date: Tue, 1 Sep 2015 20:18:01 -0700 Subject: Don't leak extra keys in the options. --- lib/chef/knife/ssh.rb | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/ssh.rb b/lib/chef/knife/ssh.rb index 5ccef3000d..bb3d9d78bb 100644 --- a/lib/chef/knife/ssh.rb +++ b/lib/chef/knife/ssh.rb @@ -133,15 +133,16 @@ class Chef gw_host, gw_user = config[:ssh_gateway].split('@').reverse gw_host, gw_port = gw_host.split(':') gw_opts = session_options(gw_host, gw_port, gw_user) + user = gw_opts.delete(:user) begin # Try to connect with a key. - session.via(gw_host, gw_opts[:user], gw_opts) + session.via(gw_host, user, gw_opts) rescue Net::SSH::AuthenticationFailed prompt = "Enter the password for #{user}@#{gw_host}: " gw_opts[:password] = prompt_for_password(prompt) # Try again with a password. - session.via(gw_host, gw_opts[:user], gw_opts) + session.via(gw_host, user, gw_opts) end end end @@ -225,8 +226,11 @@ class Chef opts[:keys] = File.expand_path(config[:identity_file]) opts[:keys_only] = true end - opts[:forward_agent] = config[:forward_agent] || ssh_config[:forward_agent] - opts[:port] = port || ssh_config[:port] + # Don't set the keys to nil if we don't have them. + forward_agent = config[:forward_agent] || ssh_config[:forward_agent] + opts[:forward_agent] = forward_agent unless forward_agent.nil? + port ||= ssh_config[:port] + opts[:port] = port unless port.nil? opts[:logger] = Chef::Log.logger if Chef::Log.level == :debug if !config[:host_key_verify] opts[:paranoid] = false @@ -244,7 +248,7 @@ class Chef session_opts[:port] = Chef::Config[:knife][:ssh_port] if Chef::Config[:knife][:ssh_port] session_opts[:port] = config[:ssh_port] if config[:ssh_port] # Create the hostspec. - hostspec = session_opts[:user] ? "#{session_opts[:user]}@#{host}" : host + hostspec = session_opts[:user] ? "#{session_opts.delete(:user)}@#{host}" : host # Connect a new session on the multi. session.use(hostspec, session_opts) -- cgit v1.2.1 From a4ca79d7a3a6e0a992c9710cbf6c7445534cad44 Mon Sep 17 00:00:00 2001 From: Joel Handwell Date: Tue, 25 Aug 2015 16:07:23 -0400 Subject: Human friendly elapsed time in log --- lib/chef/formatters/doc.rb | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/formatters/doc.rb b/lib/chef/formatters/doc.rb index 614cc44e6d..deeb5d3e96 100644 --- a/lib/chef/formatters/doc.rb +++ b/lib/chef/formatters/doc.rb @@ -26,7 +26,15 @@ class Chef end def elapsed_time - end_time - start_time + time = end_time - start_time + if time < 60 then + message = Time.at(time).utc.strftime("%S seconds") + elsif time < 3600 then + message = Time.at(time).utc.strftime("%M minutes %S seconds") + else + message = Time.at(time).utc.strftime("%H hour %M minutes %S seconds") + end + message end def run_start(version) @@ -66,7 +74,7 @@ class Chef if Chef::Config[:why_run] puts_line "Chef Client finished, #{@updated_resources}/#{total_resources} resources would have been updated" else - puts_line "Chef Client finished, #{@updated_resources}/#{total_resources} resources updated in #{elapsed_time} seconds" + puts_line "Chef Client finished, #{@updated_resources}/#{total_resources} resources updated in #{elapsed_time}" if total_audits > 0 puts_line " #{successful_audits}/#{total_audits} controls succeeded" end @@ -78,7 +86,7 @@ class Chef if Chef::Config[:why_run] puts_line "Chef Client failed. #{@updated_resources} resources would have been updated" else - puts_line "Chef Client failed. #{@updated_resources} resources updated in #{elapsed_time} seconds" + puts_line "Chef Client failed. #{@updated_resources} resources updated in #{elapsed_time}" if total_audits > 0 puts_line " #{successful_audits} controls succeeded" end -- cgit v1.2.1 From f2de463a69508cb91e952f3034f7e951c9ab1af7 Mon Sep 17 00:00:00 2001 From: Joel Handwell Date: Tue, 25 Aug 2015 18:08:16 -0400 Subject: Add unit tests for elapsed_time --- lib/chef/formatters/doc.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/formatters/doc.rb b/lib/chef/formatters/doc.rb index deeb5d3e96..93039d6171 100644 --- a/lib/chef/formatters/doc.rb +++ b/lib/chef/formatters/doc.rb @@ -32,7 +32,7 @@ class Chef elsif time < 3600 then message = Time.at(time).utc.strftime("%M minutes %S seconds") else - message = Time.at(time).utc.strftime("%H hour %M minutes %S seconds") + message = Time.at(time).utc.strftime("%H hours %M minutes %S seconds") end message end -- cgit v1.2.1 From 850bded619ac14e62bed15b85cc34d6ef3b99202 Mon Sep 17 00:00:00 2001 From: Joel Handwell Date: Mon, 31 Aug 2015 08:31:55 -0400 Subject: Keep elapsed_time and add pretty_elapsed_time --- lib/chef/formatters/doc.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/formatters/doc.rb b/lib/chef/formatters/doc.rb index 93039d6171..2b0161667b 100644 --- a/lib/chef/formatters/doc.rb +++ b/lib/chef/formatters/doc.rb @@ -26,7 +26,11 @@ class Chef end def elapsed_time - time = end_time - start_time + end_time - start_time + end + + def pretty_elapsed_time + time = elapsed_time if time < 60 then message = Time.at(time).utc.strftime("%S seconds") elsif time < 3600 then @@ -74,7 +78,7 @@ class Chef if Chef::Config[:why_run] puts_line "Chef Client finished, #{@updated_resources}/#{total_resources} resources would have been updated" else - puts_line "Chef Client finished, #{@updated_resources}/#{total_resources} resources updated in #{elapsed_time}" + puts_line "Chef Client finished, #{@updated_resources}/#{total_resources} resources updated in #{pretty_elapsed_time}" if total_audits > 0 puts_line " #{successful_audits}/#{total_audits} controls succeeded" end @@ -86,7 +90,7 @@ class Chef if Chef::Config[:why_run] puts_line "Chef Client failed. #{@updated_resources} resources would have been updated" else - puts_line "Chef Client failed. #{@updated_resources} resources updated in #{elapsed_time}" + puts_line "Chef Client failed. #{@updated_resources} resources updated in #{pretty_elapsed_time}" if total_audits > 0 puts_line " #{successful_audits} controls succeeded" end -- cgit v1.2.1 From 51e98c798e455c9e758d9ace22d1391b7aad596c Mon Sep 17 00:00:00 2001 From: Joel Handwell Date: Tue, 1 Sep 2015 17:32:16 -0400 Subject: Remove Timecop dependency --- lib/chef/formatters/doc.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/formatters/doc.rb b/lib/chef/formatters/doc.rb index 2b0161667b..70108f547b 100644 --- a/lib/chef/formatters/doc.rb +++ b/lib/chef/formatters/doc.rb @@ -33,7 +33,7 @@ class Chef time = elapsed_time if time < 60 then message = Time.at(time).utc.strftime("%S seconds") - elsif time < 3600 then + elsif time < 3600 then message = Time.at(time).utc.strftime("%M minutes %S seconds") else message = Time.at(time).utc.strftime("%H hours %M minutes %S seconds") -- cgit v1.2.1 From a3ac271fdd43a2f6ecf4c6dbe825b0f03f154fa3 Mon Sep 17 00:00:00 2001 From: Dave Eddy Date: Mon, 16 Mar 2015 20:23:42 -0400 Subject: fix locking/unlocking users on SmartOS --- lib/chef/provider/user/solaris.rb | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/user/solaris.rb b/lib/chef/provider/user/solaris.rb index b242095f0c..c16db22ad4 100644 --- a/lib/chef/provider/user/solaris.rb +++ b/lib/chef/provider/user/solaris.rb @@ -1,7 +1,9 @@ # # Author:: Stephen Nelson-Smith () # Author:: Jon Ramsey () +# Author:: Dave Eddy () # Copyright:: Copyright (c) 2012 Opscode, Inc. +# Copyright:: Copyright 2015, Dave Eddy # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,7 +25,6 @@ class Chef class User class Solaris < Chef::Provider::User::Useradd provides :user, platform: %w(omnios solaris2) - UNIVERSAL_OPTIONS = [[:comment, "-c"], [:gid, "-g"], [:shell, "-s"], [:uid, "-u"]] attr_writer :password_file @@ -43,6 +44,32 @@ class Chef super end + def check_lock + shadow_line = shell_out!('getent', 'shadow', new_resource.username).stdout.strip rescue nil + + # if the command fails we return nil, this can happen if the user + # in question doesn't exist + return nil if shadow_line.nil? + + # convert "dave:NP:16507::::::\n" to "NP" + fields = shadow_line.split(':') + + # '*LK*...' and 'LK' are both considered locked, + # so look for LK at the beginning of the shadow entry + # optionally surrounded by '*' + @locked = !!fields[1].match(/^\*?LK\*?/) + + @locked + end + + def lock_user + shell_out!('passwd', '-l', new_resource.username) + end + + def unlock_user + shell_out!('passwd', '-u', new_resource.username) + end + private def manage_password @@ -67,9 +94,10 @@ class Chef buffer.close # FIXME: mostly duplicates code with file provider deploying a file - mode = ::File.stat(@password_file).mode & 07777 - uid = ::File.stat(@password_file).uid - gid = ::File.stat(@password_file).gid + s = ::File.stat(@password_file) + mode = s.mode & 07777 + uid = s.uid + gid = s.gid FileUtils.chown uid, gid, buffer.path FileUtils.chmod mode, buffer.path -- cgit v1.2.1 From 2528c6707beed1b5cdd8029d77d56eee54eff30d Mon Sep 17 00:00:00 2001 From: Lamont Granquist Date: Fri, 28 Aug 2015 10:59:20 -0700 Subject: refactor remote_directory provider - Huge speed and memory perf boost. In the prior code if you were copying 10 dotfiles to a home directory with a million files in it, would slurp all million files into a ruby Set object even if you were not ultimately going to purge the unmanaged files. This code inverts the logic and tracks managed files and then iterates through the filesystem without slurping a list into memory. - Only do file purging logic if purging is set. - Fixes mutation of new_resource.overwrite. - Fixes mutation of new_resource.rights (subtle). - Adds helper delegators to the new_resource properties. - Deprecates (instead of removes) now-unused methods. - Renamed a method (with deprecated alias preserved) for consistency. - Adds YARD for everything. - Changes protected to private because protected is largely useless in ruby. - Removes whyrun_supported? because the superclass sets that. --- lib/chef/deprecation/provider/remote_directory.rb | 52 ++++ lib/chef/provider/remote_directory.rb | 294 ++++++++++++++-------- 2 files changed, 244 insertions(+), 102 deletions(-) create mode 100644 lib/chef/deprecation/provider/remote_directory.rb (limited to 'lib/chef') diff --git a/lib/chef/deprecation/provider/remote_directory.rb b/lib/chef/deprecation/provider/remote_directory.rb new file mode 100644 index 0000000000..b55a304696 --- /dev/null +++ b/lib/chef/deprecation/provider/remote_directory.rb @@ -0,0 +1,52 @@ +# +# Author:: Serdar Sutay () +# Copyright:: Copyright (c) 2013-2015 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 + module Deprecation + module Provider + module RemoteDirectory + + def directory_root_in_cookbook_cache + Chef::Log.deprecation "the Chef::Provider::RemoteDirectory#directory_root_in_cookbook_cache method is deprecated" + + @directory_root_in_cookbook_cache ||= + begin + cookbook = run_context.cookbook_collection[resource_cookbook] + cookbook.preferred_filename_on_disk_location(node, :files, source, path) + end + end + + # List all excluding . and .. + def ls(path) + files = Dir.glob(::File.join(Chef::Util::PathHelper.escape_glob(path), '**', '*'), + ::File::FNM_DOTMATCH) + + # Remove current directory and previous directory + files = files.reject do |name| + basename = Pathname.new(name).basename().to_s + ['.', '..'].include?(basename) + end + + # Clean all the paths... this is required because of the join + files.map {|f| Chef::Util::PathHelper.cleanpath(f)} + end + + end + end + end +end diff --git a/lib/chef/provider/remote_directory.rb b/lib/chef/provider/remote_directory.rb index 85ceb5cdae..56bad5ac42 100644 --- a/lib/chef/provider/remote_directory.rb +++ b/lib/chef/provider/remote_directory.rb @@ -1,6 +1,6 @@ # # Author:: Adam Jacob () -# Copyright:: Copyright (c) 2008 Opscode, Inc. +# Copyright:: Copyright (c) 2008-2015 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,178 +16,268 @@ # limitations under the License. # -require 'chef/provider/file' require 'chef/provider/directory' +require 'chef/resource/file' require 'chef/resource/directory' -require 'chef/resource/remote_file' +require 'chef/resource/cookbook_file' require 'chef/mixin/file_class' -require 'chef/platform' -require 'uri' -require 'tempfile' -require 'net/https' -require 'set' +require 'chef/platform/query_helpers' require 'chef/util/path_helper' +require 'chef/deprecation/warnings' +require 'chef/deprecation/provider/remote_directory' + +require 'forwardable' class Chef class Provider class RemoteDirectory < Chef::Provider::Directory + extend Forwardable + include Chef::Mixin::FileClass provides :remote_directory - include Chef::Mixin::FileClass + def_delegators :@new_resource, :purge, :path, :source, :cookbook, :cookbook_name + def_delegators :@new_resource, :files_rights, :files_mode, :files_group, :files_owner, :files_backup + def_delegators :@new_resource, :rights, :mode, :group, :owner + + attr_accessor :overwrite + + # The overwrite property on the resource. Delegates to new_resource but can be mutated. + # + # @return [Boolean] if we are overwriting + # + def overwrite + @overwrite = new_resource.overwrite if @overwrite.nil? + @overwrite + end + + attr_accessor :managed_files + # Hash containing keys of the paths for all the files that we sync, plus all their + # parent directories. + # + # @return [Hash{String => TrueClass}] Hash of files we've managed. + # + def managed_files + @managed_files ||= {} + end + + # Handle action :create. + # def action_create super - # Mark all files as needing to be purged - files_to_purge = Set.new(ls(@new_resource.path)) # Make sure each path is clean # Transfer files files_to_transfer.each do |cookbook_file_relative_path| create_cookbook_file(cookbook_file_relative_path) - # parent directories and file being transferred are removed from the purge list - Pathname.new(Chef::Util::PathHelper.cleanpath(::File.join(@new_resource.path, cookbook_file_relative_path))).descend do |d| - files_to_purge.delete(d.to_s) - end + # parent directories and file being transferred need to not be removed in the purge + add_managed_file(cookbook_file_relative_path) end - purge_unmanaged_files(files_to_purge) + purge_unmanaged_files end + # Handle action :create_if_missing. + # def action_create_if_missing # if this action is called, ignore the existing overwrite flag - @new_resource.overwrite(false) + @overwrite = false action_create end - protected - - # List all excluding . and .. - def ls(path) - files = Dir.glob(::File.join(Chef::Util::PathHelper.escape_glob(path), '**', '*'), - ::File::FNM_DOTMATCH) + private - # Remove current directory and previous directory - files = files.reject do |name| - basename = Pathname.new(name).basename().to_s - ['.', '..'].include?(basename) + # Add a file and its parent directories to the managed_files Hash. + # + # @param [String] cookbook_file_relative_path relative path to the file + # @api private + # + def add_managed_file(cookbook_file_relative_path) + if purge + Pathname.new(Chef::Util::PathHelper.cleanpath(::File.join(path, cookbook_file_relative_path))).descend do |d| + managed_files[d.to_s] = true + end end - - # Clean all the paths... this is required because of the join - files.map {|f| Chef::Util::PathHelper.cleanpath(f)} end - def purge_unmanaged_files(unmanaged_files) - if @new_resource.purge - unmanaged_files.sort.reverse.each do |f| - # file_class comes from Chef::Mixin::FileClass - if ::File.directory?(f) && !Chef::Platform.windows? && !file_class.symlink?(f.dup) - # Linux treats directory symlinks as files - # Remove a directory as a directory when not on windows if it is not a symlink - purge_directory(f) - elsif ::File.directory?(f) && Chef::Platform.windows? - # Windows treats directory symlinks as directories so we delete them here - purge_directory(f) - else - converge_by("delete unmanaged file #{f}") do - ::File.delete(f) - Chef::Log.debug("#{@new_resource} deleted file #{f}") + # Remove all files not in the managed_files Hash. + # + # @api private + # + def purge_unmanaged_files + if purge + Dir.glob(::File.join(Chef::Util::PathHelper.escape_glob(path), '**', '*'), ::File::FNM_DOTMATCH).sort!.reverse!.each do |file| + # skip '.' and '..' + next if ['.','..'].include?(Pathname.new(file).basename().to_s) + + # Clean the path. This is required because of the ::File.join + file = Chef::Util::PathHelper.cleanpath(file) + + # Skip files that we've sync'd and their parent dirs + next if managed_files.include?(file) + + if ::File.directory?(file) + if !Chef::Platform.windows? && file_class.symlink?(file.dup) + # Unix treats dir symlinks as files + purge_file(file) + else + # Unix dirs are dirs, Windows dirs and dir symlinks are dirs + purge_directory(file) end + else + purge_file(file) end end end end + # Use a Chef directory sub-resource to remove a directory. + # + # @param [String] dir The path of the directory to remove + # @api private + # def purge_directory(dir) - converge_by("delete unmanaged directory #{dir}") do - Dir::rmdir(dir) - Chef::Log.debug("#{@new_resource} removed directory #{dir}") - end + res = Chef::Resource::Directory.new(dir, run_context) + res.run_action(:delete) + new_resource.updated_by_last_action(true) if res.updated? + end + + # Use a Chef file sub-resource to remove a file. + # + # @param [String] file The path of the file to remove + # @api private + # + def purge_file(file) + res = Chef::Resource::File.new(file, run_context) + res.run_action(:delete) + new_resource.updated_by_last_action(true) if res.updated? end + # Get the files to tranfer. This returns files in lexicographical sort order. + # + # FIXME: it should do breadth-first, see CHEF-5080 (please use a performant sort) + # + # @return Array The list of files to transfer + # @api private + # def files_to_transfer cookbook = run_context.cookbook_collection[resource_cookbook] - files = cookbook.relative_filenames_in_preferred_directory(node, :files, @new_resource.source) - files.sort.reverse + files = cookbook.relative_filenames_in_preferred_directory(node, :files, source) + files.sort!.reverse! end - def directory_root_in_cookbook_cache - @directory_root_in_cookbook_cache ||= begin - cookbook = run_context.cookbook_collection[resource_cookbook] - cookbook.preferred_filename_on_disk_location(node, :files, @new_resource.source, @new_resource.path) - end + # Either the explicit cookbook that the user sets on the resource, or the implicit + # cookbook_name that the resource was declared in. + # + # @return [String] Cookbook to get file from. + # @api private + # + def resource_cookbook + cookbook || cookbook_name end - # Determine the cookbook to get the file from. If new resource sets an - # explicit cookbook, use it, otherwise fall back to the implicit cookbook - # i.e., the cookbook the resource was declared in. - def resource_cookbook - @new_resource.cookbook || @new_resource.cookbook_name + # If we are overwriting, then cookbook_file sub-resources should all be action :create, + # otherwise they should be :create_if_missing + # + # @return [Symbol] Action to take on cookbook_file sub-resources + # @api private + # + def action_for_cookbook_file + overwrite ? :create : :create_if_missing end + # This creates and uses a cookbook_file resource to sync a single file from the cookbook. + # + # @param [String] cookbook_file_relative_path The relative path to the cookbook file + # @api private + # def create_cookbook_file(cookbook_file_relative_path) - full_path = ::File.join(@new_resource.path, cookbook_file_relative_path) + full_path = ::File.join(path, cookbook_file_relative_path) ensure_directory_exists(::File.dirname(full_path)) - file_to_fetch = cookbook_file_resource(full_path, cookbook_file_relative_path) - if @new_resource.overwrite - file_to_fetch.run_action(:create) - else - file_to_fetch.run_action(:create_if_missing) - end - @new_resource.updated_by_last_action(true) if file_to_fetch.updated? + res = cookbook_file_resource(full_path, cookbook_file_relative_path) + res.run_action(action_for_cookbook_file) + new_resource.updated_by_last_action(true) if res.updated? end + # This creates the cookbook_file resource for use by create_cookbook_file. + # + # @param [String] target_path Path on the system to create + # @param [String] relative_source_path Relative path in the cookbook to the base source + # @return [Chef::Resource::CookbookFile] The built cookbook_file resource + # @api private + # def cookbook_file_resource(target_path, relative_source_path) - cookbook_file = Chef::Resource::CookbookFile.new(target_path, run_context) - cookbook_file.cookbook_name = @new_resource.cookbook || @new_resource.cookbook_name - cookbook_file.source(::File.join(@new_resource.source, relative_source_path)) - if Chef::Platform.windows? && @new_resource.files_rights - @new_resource.files_rights.each_pair do |permission, *args| - cookbook_file.rights(permission, *args) + res = Chef::Resource::CookbookFile.new(target_path, run_context) + res.cookbook_name = resource_cookbook + res.source(::File.join(source, relative_source_path)) + if Chef::Platform.windows? && files_rights + files_rights.each_pair do |permission, *args| + res.rights(permission, *args) end end - cookbook_file.mode(@new_resource.files_mode) if @new_resource.files_mode - cookbook_file.group(@new_resource.files_group) if @new_resource.files_group - cookbook_file.owner(@new_resource.files_owner) if @new_resource.files_owner - cookbook_file.backup(@new_resource.files_backup) if @new_resource.files_backup + res.mode(files_mode) if files_mode + res.group(files_group) if files_group + res.owner(files_owner) if files_owner + res.backup(files_backup) if files_backup - cookbook_file + res end - def ensure_directory_exists(path) - unless ::File.directory?(path) - directory_to_create = resource_for_directory(path) - directory_to_create.run_action(:create) - @new_resource.updated_by_last_action(true) if directory_to_create.updated? + # This creates and uses a directory resource to create a directory if it is needed. + # + # @param [String] dir The path to the directory to create. + # @api private + # + def ensure_directory_exists(dir) + # doing the check here and skipping the resource should be more performant + unless ::File.directory?(dir) + res = directory_resource(dir) + res.run_action(:create) + new_resource.updated_by_last_action(true) if res.updated? end end - def resource_for_directory(path) - dir = Chef::Resource::Directory.new(path, run_context) - dir.cookbook_name = @new_resource.cookbook || @new_resource.cookbook_name - if Chef::Platform.windows? && @new_resource.rights + # This creates the directory resource for ensure_directory_exists. + # + # @param [String] dir Directory path on the system + # @return [Chef::Resource::Directory] The built directory resource + # @api private + # + def directory_resource(dir) + res = Chef::Resource::Directory.new(dir, run_context) + res.cookbook_name = resource_cookbook + if Chef::Platform.windows? && rights # rights are only meant to be applied to the toppest-level directory; # Windows will handle inheritance. - if path == @new_resource.path - @new_resource.rights.each do |rights| #rights is a hash - permissions = rights.delete(:permissions) #delete will return the value or nil if not found - principals = rights.delete(:principals) - dir.rights(permissions, principals, rights) + if dir == path + rights.each do |r| + r = r.dup # do not update the new_resource + permissions = r.delete(:permissions) + principals = r.delete(:principals) + res.rights(permissions, principals, r) end end end - dir.mode(@new_resource.mode) if @new_resource.mode - dir.group(@new_resource.group) - dir.owner(@new_resource.owner) - dir.recursive(true) - dir - end + res.mode(mode) if mode + res.group(group) if group + res.owner(owner) if owner + res.recursive(true) - def whyrun_supported? - true + res end + # + # Add back deprecated methods and aliases that are internally unused and should be removed in Chef-13 + # + extend Chef::Deprecation::Warnings + include Chef::Deprecation::Provider::RemoteDirectory + add_deprecation_warnings_for(Chef::Deprecation::Provider::RemoteDirectory.instance_methods) + + alias_method :resource_for_directory, :directory_resource + add_deprecation_warnings_for([:resource_for_directory]) + end end end -- cgit v1.2.1 From d9695334d70471dbcb2548960d31a13a0f19fab6 Mon Sep 17 00:00:00 2001 From: Lamont Granquist Date: Mon, 31 Aug 2015 15:36:05 -0700 Subject: review fixes - convert to Set - use #override? --- lib/chef/provider/remote_directory.rb | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/remote_directory.rb b/lib/chef/provider/remote_directory.rb index 56bad5ac42..56c2ff0caf 100644 --- a/lib/chef/provider/remote_directory.rb +++ b/lib/chef/provider/remote_directory.rb @@ -40,15 +40,13 @@ class Chef def_delegators :@new_resource, :files_rights, :files_mode, :files_group, :files_owner, :files_backup def_delegators :@new_resource, :rights, :mode, :group, :owner - attr_accessor :overwrite - # The overwrite property on the resource. Delegates to new_resource but can be mutated. # # @return [Boolean] if we are overwriting # - def overwrite + def overwrite? @overwrite = new_resource.overwrite if @overwrite.nil? - @overwrite + !!@overwrite end attr_accessor :managed_files @@ -56,10 +54,10 @@ class Chef # Hash containing keys of the paths for all the files that we sync, plus all their # parent directories. # - # @return [Hash{String => TrueClass}] Hash of files we've managed. + # @return [Set] Ruby Set of the files that we manage # def managed_files - @managed_files ||= {} + @managed_files ||= Set.new end # Handle action :create. @@ -95,12 +93,12 @@ class Chef def add_managed_file(cookbook_file_relative_path) if purge Pathname.new(Chef::Util::PathHelper.cleanpath(::File.join(path, cookbook_file_relative_path))).descend do |d| - managed_files[d.to_s] = true + managed_files.add(d.to_s) end end end - # Remove all files not in the managed_files Hash. + # Remove all files not in the managed_files Set. # # @api private # @@ -183,7 +181,7 @@ class Chef # @api private # def action_for_cookbook_file - overwrite ? :create : :create_if_missing + overwrite? ? :create : :create_if_missing end # This creates and uses a cookbook_file resource to sync a single file from the cookbook. -- cgit v1.2.1 From 55a6507b98b69652d9b5c74f4209c6472e356834 Mon Sep 17 00:00:00 2001 From: Claire McQuin Date: Tue, 1 Sep 2015 15:27:48 -0700 Subject: Monkey-patch Win32::Registry::API::DeleteValue for Win32::Registry#delete_value. --- lib/chef/monkey_patches/win32/registry.rb | 23 +++++++++++++++++++++++ lib/chef/win32/api/registry.rb | 6 ++++++ lib/chef/win32/registry.rb | 4 ++++ 3 files changed, 33 insertions(+) create mode 100644 lib/chef/monkey_patches/win32/registry.rb (limited to 'lib/chef') diff --git a/lib/chef/monkey_patches/win32/registry.rb b/lib/chef/monkey_patches/win32/registry.rb new file mode 100644 index 0000000000..c7279ced92 --- /dev/null +++ b/lib/chef/monkey_patches/win32/registry.rb @@ -0,0 +1,23 @@ + +require 'chef/win32/api/registry' +require 'chef/win32/unicode' +require 'win32/registry' + +module Win32 + class Registry + module API + + extend Chef::ReservedNames::Win32::API::Registry + + module_function + + # ::Win32::Registry#delete_value is broken in Ruby 2.1 (up to Ruby 2.1.6p336). + # This should be resolved a later release (see note #9 in link below). + # https://bugs.ruby-lang.org/issues/10820 + def DeleteValue(hkey, name) + check RegDeleteValueW(hkey, name.to_wstring) + end + + end + end +end \ No newline at end of file diff --git a/lib/chef/win32/api/registry.rb b/lib/chef/win32/api/registry.rb index 45b91d7d32..cbbf6b66bb 100644 --- a/lib/chef/win32/api/registry.rb +++ b/lib/chef/win32/api/registry.rb @@ -39,6 +39,12 @@ class Chef safe_attach_function :RegDeleteKeyExW, [ :HKEY, :LPCTSTR, :LONG, :DWORD ], :LONG safe_attach_function :RegDeleteKeyExA, [ :HKEY, :LPCTSTR, :LONG, :DWORD ], :LONG + # LONG WINAPI RegDeleteValue( + # _In_ HKEY hKey, + # _In_opt_ LPCTSTR lpValueName + # ); + safe_attach_function :RegDeleteValueW, [ :HKEY, :LPCTSTR ], :LONG + end end end diff --git a/lib/chef/win32/registry.rb b/lib/chef/win32/registry.rb index b25ce7937e..877c2ebff3 100644 --- a/lib/chef/win32/registry.rb +++ b/lib/chef/win32/registry.rb @@ -21,6 +21,10 @@ require 'chef/win32/api' require 'chef/mixin/wide_string' if RUBY_PLATFORM =~ /mswin|mingw32|windows/ + if RUBY_VERSION =~ /^2\.1/ + require 'chef/monkey_patches/win32/registry' + end + require 'chef/win32/api/registry' require 'win32/registry' require 'win32/api' -- cgit v1.2.1 From 30b588f7035c2a219bc96a0b055f1d0eb8e16d3c Mon Sep 17 00:00:00 2001 From: Claire McQuin Date: Wed, 2 Sep 2015 09:11:26 -0700 Subject: Monkey-patch Win32::Registry::API::DeleteKey for Win32::Registry#delete_key --- lib/chef/monkey_patches/win32/registry.rb | 19 ++++++++++++++----- lib/chef/win32/registry.rb | 5 +---- 2 files changed, 15 insertions(+), 9 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/monkey_patches/win32/registry.rb b/lib/chef/monkey_patches/win32/registry.rb index c7279ced92..a754949ca0 100644 --- a/lib/chef/monkey_patches/win32/registry.rb +++ b/lib/chef/monkey_patches/win32/registry.rb @@ -11,11 +11,20 @@ module Win32 module_function - # ::Win32::Registry#delete_value is broken in Ruby 2.1 (up to Ruby 2.1.6p336). - # This should be resolved a later release (see note #9 in link below). - # https://bugs.ruby-lang.org/issues/10820 - def DeleteValue(hkey, name) - check RegDeleteValueW(hkey, name.to_wstring) + if RUBY_VERSION =~ /^2\.1/ + # ::Win32::Registry#delete_value is broken in Ruby 2.1 (up to Ruby 2.1.6). + # This should be resolved in a later release (see note #9 in link below). + # https://bugs.ruby-lang.org/issues/10820 + def DeleteValue(hkey, name) + check RegDeleteValueW(hkey, name.to_wstring) + end + end + + # ::Win32::Registry#delete_key uses RegDeleteKeyW. We need to use + # RegDeleteKeyExW to properly support WOW64 systems. + def DeleteKey(hkey, name) + arch_mask = win64? ? 0x0100 : 0x0200 + check RegDeleteKeyExW(hkey, name.to_wstring, KEY_WRITE | arch_mask, 0) end end diff --git a/lib/chef/win32/registry.rb b/lib/chef/win32/registry.rb index 877c2ebff3..3a01553445 100644 --- a/lib/chef/win32/registry.rb +++ b/lib/chef/win32/registry.rb @@ -21,10 +21,7 @@ require 'chef/win32/api' require 'chef/mixin/wide_string' if RUBY_PLATFORM =~ /mswin|mingw32|windows/ - if RUBY_VERSION =~ /^2\.1/ - require 'chef/monkey_patches/win32/registry' - end - + require 'chef/monkey_patches/win32/registry' require 'chef/win32/api/registry' require 'win32/registry' require 'win32/api' -- cgit v1.2.1 From c00a3bdc8e00e512f4c3cbb2ff7169ff20a66672 Mon Sep 17 00:00:00 2001 From: Claire McQuin Date: Thu, 3 Sep 2015 10:16:49 -0700 Subject: Remove access mask to RegDeleteKeyExW, it's not useful --- lib/chef/monkey_patches/win32/registry.rb | 3 +-- lib/chef/win32/registry.rb | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/monkey_patches/win32/registry.rb b/lib/chef/monkey_patches/win32/registry.rb index a754949ca0..9471777c57 100644 --- a/lib/chef/monkey_patches/win32/registry.rb +++ b/lib/chef/monkey_patches/win32/registry.rb @@ -23,8 +23,7 @@ module Win32 # ::Win32::Registry#delete_key uses RegDeleteKeyW. We need to use # RegDeleteKeyExW to properly support WOW64 systems. def DeleteKey(hkey, name) - arch_mask = win64? ? 0x0100 : 0x0200 - check RegDeleteKeyExW(hkey, name.to_wstring, KEY_WRITE | arch_mask, 0) + check RegDeleteKeyExW(hkey, name.to_wstring, 0, 0) end end diff --git a/lib/chef/win32/registry.rb b/lib/chef/win32/registry.rb index 3a01553445..e699a9bc06 100644 --- a/lib/chef/win32/registry.rb +++ b/lib/chef/win32/registry.rb @@ -154,8 +154,7 @@ class Chef #Using the 'RegDeleteKeyEx' Windows API that correctly supports WOW64 systems (Win2003) #instead of the 'RegDeleteKey' def delete_key_ex(hive, key) - hive_num = hive.hkey - (1 << 32) - RegDeleteKeyExW(hive_num, wstring(key), ::Win32::Registry::KEY_WRITE | registry_system_architecture, 0) == 0 + RegDeleteKeyExW(hive.hkey, wstring(key), 0, 0) == 0 end def key_exists?(key_path) -- cgit v1.2.1 From 25b77f4e175e8a56865d3c908f29147c6d41c93a Mon Sep 17 00:00:00 2001 From: Claire McQuin Date: Thu, 3 Sep 2015 11:15:27 -0700 Subject: Implement delete_key with Win32::Registry#delete_key --- lib/chef/win32/registry.rb | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/win32/registry.rb b/lib/chef/win32/registry.rb index e699a9bc06..12ad08a965 100644 --- a/lib/chef/win32/registry.rb +++ b/lib/chef/win32/registry.rb @@ -127,36 +127,23 @@ class Chef Chef::Log.debug("Registry key #{key_path}, does not exist, not deleting") return true end - #key_path is in the form "HKLM\Software\Opscode" for example, extracting - #hive = HKLM, - #hive_namespace = ::Win32::Registry::HKEY_LOCAL_MACHINE - hive = key_path.split("\\").shift - hive_namespace, key_including_parent = get_hive_and_key(key_path) - if has_subkeys?(key_path) - if recursive == true - subkeys = get_subkeys(key_path) - subkeys.each do |key| - keypath_to_check = hive+"\\"+key_including_parent+"\\"+key - Chef::Log.debug("Deleting registry key #{key_path} recursively") - delete_key(keypath_to_check, true) - end - delete_key_ex(hive_namespace, key_including_parent) - else - raise Chef::Exceptions::Win32RegNoRecursive, "Registry key #{key_path} has subkeys, and recursive not specified" - end - else - delete_key_ex(hive_namespace, key_including_parent) - return true + if has_subkeys?(key_path) && !recursive + raise Chef::Exceptions::Win32RegNoRecursive, "Registry key #{key_path} has subkeys, and recursive not specified" + end + hive, key_including_parent = get_hive_and_key(key_path) + # key_including_parent: Software\\Root\\Branch\\Fruit + # key => Fruit + # key_parent => Software\\Root\\Branch + key_parts = key_including_parent.split("\\") + key = key_parts.pop + key_parent = key_parts.join("\\") + hive.open(key_parent, ::Win32::Registry::KEY_WRITE | registry_system_architecture) do |reg| + reg.delete_key(key, recursive) end + Chef::Log.debug("Registry key #{key_path} deleted") true end - #Using the 'RegDeleteKeyEx' Windows API that correctly supports WOW64 systems (Win2003) - #instead of the 'RegDeleteKey' - def delete_key_ex(hive, key) - RegDeleteKeyExW(hive.hkey, wstring(key), 0, 0) == 0 - end - def key_exists?(key_path) hive, key = get_hive_and_key(key_path) begin -- cgit v1.2.1 From 86869f9aba02d8b40b3ee8c84f0cfaf50295a96e Mon Sep 17 00:00:00 2001 From: Claire McQuin Date: Thu, 3 Sep 2015 13:14:14 -0700 Subject: Add file header. --- lib/chef/monkey_patches/win32/registry.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'lib/chef') diff --git a/lib/chef/monkey_patches/win32/registry.rb b/lib/chef/monkey_patches/win32/registry.rb index 9471777c57..5ebe67c45d 100644 --- a/lib/chef/monkey_patches/win32/registry.rb +++ b/lib/chef/monkey_patches/win32/registry.rb @@ -1,3 +1,19 @@ +# +# Copyright:: Copyright 2015 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. +# require 'chef/win32/api/registry' require 'chef/win32/unicode' -- cgit v1.2.1 From 33fa66713f26456992cfb6f7dff8ebbe2d9e2140 Mon Sep 17 00:00:00 2001 From: Claire McQuin Date: Fri, 4 Sep 2015 10:09:34 -0700 Subject: Move Win32::Registry#write monkeypatch into win32/registry monkeypatch file. --- lib/chef/monkey_patches/win32/registry.rb | 31 ++++++++++++++++++++++++++++--- lib/chef/win32/unicode.rb | 27 --------------------------- 2 files changed, 28 insertions(+), 30 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/monkey_patches/win32/registry.rb b/lib/chef/monkey_patches/win32/registry.rb index 5ebe67c45d..2ce2ac97f1 100644 --- a/lib/chef/monkey_patches/win32/registry.rb +++ b/lib/chef/monkey_patches/win32/registry.rb @@ -21,8 +21,9 @@ require 'win32/registry' module Win32 class Registry + module API - + extend Chef::ReservedNames::Win32::API::Registry module_function @@ -41,7 +42,31 @@ module Win32 def DeleteKey(hkey, name) check RegDeleteKeyExW(hkey, name.to_wstring, 0, 0) end - + + end + + if RUBY_VERSION =~ /^2.1/ + # ::Win32::Registry#write does not correctly handle data in Ruby 2.1 (up to Ruby 2.1.6). + # https://bugs.ruby-lang.org/issues/11439 + def write(name, type, data) + case type + when REG_SZ, REG_EXPAND_SZ + data = data.to_s.encode(WCHAR) + WCHAR_NUL + when REG_MULTI_SZ + data = data.to_a.map {|s| s.encode(WCHAR)}.join(WCHAR_NUL) << WCHAR_NUL << WCHAR_NUL + when REG_BINARY + data = data.to_s + when REG_DWORD + data = API.packdw(data.to_i) + when REG_DWORD_BIG_ENDIAN + data = [data.to_i].pack('N') + when REG_QWORD + data = API.packqw(data.to_i) + else + raise TypeError, "Unsupported type #{type}" + end + API.SetValue(@hkey, name, type, data, data.bytesize) + end end end -end \ No newline at end of file +end diff --git a/lib/chef/win32/unicode.rb b/lib/chef/win32/unicode.rb index 562301a040..d63b9790b9 100644 --- a/lib/chef/win32/unicode.rb +++ b/lib/chef/win32/unicode.rb @@ -58,30 +58,3 @@ class String utf8_to_wide(self) end end - -# https://bugs.ruby-lang.org/issues/11439 -if RUBY_VERSION =~ /^2\.1/ - module Win32 - class Registry - def write(name, type, data) - case type - when REG_SZ, REG_EXPAND_SZ - data = data.to_s.encode(WCHAR) + WCHAR_NUL - when REG_MULTI_SZ - data = data.to_a.map {|s| s.encode(WCHAR)}.join(WCHAR_NUL) << WCHAR_NUL << WCHAR_NUL - when REG_BINARY - data = data.to_s - when REG_DWORD - data = API.packdw(data.to_i) - when REG_DWORD_BIG_ENDIAN - data = [data.to_i].pack('N') - when REG_QWORD - data = API.packqw(data.to_i) - else - raise TypeError, "Unsupported type #{type}" - end - API.SetValue(@hkey, name, type, data, data.bytesize) - end - end - end -end \ No newline at end of file -- cgit v1.2.1 From 998e13adbda5e964d2f8d17ebd8f216f752244a6 Mon Sep 17 00:00:00 2001 From: Claire McQuin Date: Tue, 8 Sep 2015 12:20:45 -0700 Subject: Skip tests unless RefreshMode is Disabled --- lib/chef/platform/query_helpers.rb | 7 +++++++ lib/chef/provider/dsc_resource.rb | 14 +++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/platform/query_helpers.rb b/lib/chef/platform/query_helpers.rb index e64189fbd6..ea86ab227f 100644 --- a/lib/chef/platform/query_helpers.rb +++ b/lib/chef/platform/query_helpers.rb @@ -52,6 +52,13 @@ class Chef Gem::Version.new(node[:languages][:powershell][:version]) >= Gem::Version.new("5.0.10018.0") end + + def refresh_mode_disabled?(node) + require 'chef/util/powershell/cmdlet' + cmdlet = Chef::Util::Powershell::Cmdlet.new(node, "Get-DscLocalConfigurationManager", :object) + metadata = cmdlet.run!.return_value + metadata['RefreshMode'] == 'Disabled' + end end end end diff --git a/lib/chef/provider/dsc_resource.rb b/lib/chef/provider/dsc_resource.rb index 379369ba6e..31c6c078f4 100644 --- a/lib/chef/provider/dsc_resource.rb +++ b/lib/chef/provider/dsc_resource.rb @@ -59,9 +59,7 @@ class Chef a.block_action! end requirements.assert(:run) do |a| - a.assertion { - meta_configuration['RefreshMode'] == 'Disabled' - } + a.assertion { refresh_mode_disabled? } err = ["The LCM must have its RefreshMode set to Disabled. "] a.failure_message Chef::Exceptions::ProviderNotFound, err.join(' ') a.whyrun err + ["Assuming a previous resource sets the RefreshMode."] @@ -85,6 +83,10 @@ class Chef def supports_dsc_invoke_resource? run_context && Chef::Platform.supports_dsc_invoke_resource?(node) end + + def refresh_mode_disabled? + Chef::Platform.refresh_mode_disabled?(node) + end def generate_description @converge_description @@ -153,12 +155,6 @@ class Chef cmdlet.run! end - def meta_configuration - cmdlet = Chef::Util::Powershell::Cmdlet.new(node, "Get-DscLocalConfigurationManager", :object) - result = cmdlet.run! - result.return_value - end - end end end -- cgit v1.2.1 From 2517cae8ac1b52c9a5eca1347a63c072a97e2c4c Mon Sep 17 00:00:00 2001 From: Claire McQuin Date: Tue, 8 Sep 2015 14:57:10 -0700 Subject: Rename refresh_mode_disabled? to dsc_refresh_mode_disabled? --- lib/chef/platform/query_helpers.rb | 2 +- lib/chef/provider/dsc_resource.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/platform/query_helpers.rb b/lib/chef/platform/query_helpers.rb index ea86ab227f..2dd33ea190 100644 --- a/lib/chef/platform/query_helpers.rb +++ b/lib/chef/platform/query_helpers.rb @@ -53,7 +53,7 @@ class Chef Gem::Version.new("5.0.10018.0") end - def refresh_mode_disabled?(node) + def dsc_refresh_mode_disabled?(node) require 'chef/util/powershell/cmdlet' cmdlet = Chef::Util::Powershell::Cmdlet.new(node, "Get-DscLocalConfigurationManager", :object) metadata = cmdlet.run!.return_value diff --git a/lib/chef/provider/dsc_resource.rb b/lib/chef/provider/dsc_resource.rb index 31c6c078f4..65830131ab 100644 --- a/lib/chef/provider/dsc_resource.rb +++ b/lib/chef/provider/dsc_resource.rb @@ -59,7 +59,7 @@ class Chef a.block_action! end requirements.assert(:run) do |a| - a.assertion { refresh_mode_disabled? } + a.assertion { dsc_refresh_mode_disabled? } err = ["The LCM must have its RefreshMode set to Disabled. "] a.failure_message Chef::Exceptions::ProviderNotFound, err.join(' ') a.whyrun err + ["Assuming a previous resource sets the RefreshMode."] @@ -84,8 +84,8 @@ class Chef run_context && Chef::Platform.supports_dsc_invoke_resource?(node) end - def refresh_mode_disabled? - Chef::Platform.refresh_mode_disabled?(node) + def dsc_refresh_mode_disabled? + Chef::Platform.dsc_refresh_mode_disabled?(node) end def generate_description -- cgit v1.2.1 From bc0daaae67b2e6bf032e11edbc3057c7531dfc36 Mon Sep 17 00:00:00 2001 From: Jay Mundrawala Date: Tue, 8 Sep 2015 18:18:09 -0500 Subject: Add monkey patch for webrick Ruby 2.1 introduces a regression on Windows in WEBrick. create_listeners does not throw an exception when we're already listening on a port. This seems to only be an issue on Windows. This patch reverts it back to what it was in Ruby 2.0 It seems the regression was introduced in https://github.com/ruby/ruby/commit/b1f493dcd1092fe17cccec998e175516ed5c6e47#diff-4b178393150b2b3a5ec9d77eced1f09e --- lib/chef/local_mode.rb | 5 ++++ lib/chef/monkey_patches/webrick-utils.rb | 51 ++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 lib/chef/monkey_patches/webrick-utils.rb (limited to 'lib/chef') diff --git a/lib/chef/local_mode.rb b/lib/chef/local_mode.rb index 79fb750dd8..fbb72cd6cb 100644 --- a/lib/chef/local_mode.rb +++ b/lib/chef/local_mode.rb @@ -15,6 +15,11 @@ # See the License for the specific language governing permissions and # limitations under the License. require 'chef/config' +if Chef::Platform.windows? + if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.1') + require 'chef/monkey_patches/webrick-utils' + end +end class Chef module LocalMode diff --git a/lib/chef/monkey_patches/webrick-utils.rb b/lib/chef/monkey_patches/webrick-utils.rb new file mode 100644 index 0000000000..57f6db54ed --- /dev/null +++ b/lib/chef/monkey_patches/webrick-utils.rb @@ -0,0 +1,51 @@ +require 'webrick/utils' + +module WEBrick + module Utils + ## + # Creates TCP server sockets bound to +address+:+port+ and returns them. + # + # It will create IPV4 and IPV6 sockets on all interfaces. + # + # NOTE: We need to monkey patch this method because + # create_listeners on Windows with Ruby > 2.0.0 does not + # raise an error if we're already listening on a port. + # + def create_listeners(address, port, logger=nil) + # + # utils.rb -- Miscellaneous utilities + # + # Author: IPR -- Internet Programming with Ruby -- writers + # Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou + # Copyright (c) 2002 Internet Programming with Ruby writers. All rights + # reserved. + # + # $IPR: utils.rb,v 1.10 2003/02/16 22:22:54 gotoyuzo Exp $ + unless port + raise ArgumentError, "must specify port" + end + res = Socket::getaddrinfo(address, port, + Socket::AF_UNSPEC, # address family + Socket::SOCK_STREAM, # socket type + 0, # protocol + Socket::AI_PASSIVE) # flag + last_error = nil + sockets = [] + res.each{|ai| + begin + logger.debug("TCPServer.new(#{ai[3]}, #{port})") if logger + sock = TCPServer.new(ai[3], port) + port = sock.addr[1] if port == 0 + Utils::set_close_on_exec(sock) + sockets << sock + rescue => ex + logger.warn("TCPServer Error: #{ex}") if logger + last_error = ex + end + } + raise last_error if sockets.empty? + return sockets + end + module_function :create_listeners + end +end -- cgit v1.2.1 From 716eb7679cd30cd0e371ea8699d5dbdb47a05169 Mon Sep 17 00:00:00 2001 From: Matt Wrock Date: Thu, 10 Sep 2015 22:08:51 -0700 Subject: remove pending reboot check for HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile if not on windows 2003 --- lib/chef/dsl/reboot_pending.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/dsl/reboot_pending.rb b/lib/chef/dsl/reboot_pending.rb index c577118dd4..3d84b29ec5 100644 --- a/lib/chef/dsl/reboot_pending.rb +++ b/lib/chef/dsl/reboot_pending.rb @@ -49,7 +49,8 @@ class Chef # The mere existence of the UpdateExeVolatile key should indicate a pending restart for certain updates # http://support.microsoft.com/kb/832475 - (registry_key_exists?('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile') && + Chef::Platform.windows_server_2003? && + (registry_key_exists?('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile') && !registry_get_values('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile').select { |v| v[:name] == "Flags" }[0].nil? && [1,2,3].include?(registry_get_values('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile').select { |v| v[:name] == "Flags" }[0][:data])) elsif platform?("ubuntu") -- cgit v1.2.1 From 72cb4af6451f67791469456899df5bd09db94d7b Mon Sep 17 00:00:00 2001 From: Lamont Granquist Date: Wed, 2 Sep 2015 18:01:09 -0700 Subject: Remove the warning about hashes and arrays as default values - This isn't a bug to declare an LWRP default hash or array, its a bug to use the hash or array in such a way as to mutate it. A lot of LWRP authors will get this triggered on their code when none of their users are actually triggering the bug. - It would be better handled by freezing default values in Chef 13. - We could also just not try to solve this problem in code and treat it fundamentally as a documentation/education problem. --- lib/chef/resource.rb | 4 ---- 1 file changed, 4 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb index ee75dec3b9..aec78b4f6d 100644 --- a/lib/chef/resource.rb +++ b/lib/chef/resource.rb @@ -808,10 +808,6 @@ class Chef property = property_type(**options) end - if !options[:default].frozen? && (options[:default].is_a?(Array) || options[:default].is_a?(Hash)) - Chef.log_deprecation("Property #{self}.#{name} has an array or hash default (#{options[:default]}). This means that if one resource modifies or appends to it, all other resources of the same type will also see the changes. Either freeze the constant with `.freeze` to prevent appending, or use lazy { #{options[:default].inspect} }.") - end - local_properties = properties(false) local_properties[name] = property -- cgit v1.2.1 From fbd4375eb898b6a0e1a3d55dfe1a91e4c1c26d8a Mon Sep 17 00:00:00 2001 From: Claire McQuin Date: Thu, 17 Sep 2015 10:01:02 -0700 Subject: Rename Chef::Resource#current_resource -> Chef::Resource#current_value --- lib/chef/resource.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb index aec78b4f6d..5c230ad2f4 100644 --- a/lib/chef/resource.rb +++ b/lib/chef/resource.rb @@ -1406,7 +1406,7 @@ class Chef # @return A new copy of the resource, with values filled in from the actual # current value. # - def current_resource + def current_value provider = provider_for_action(Array(action).first) if provider.whyrun_mode? && !provider.whyrun_supported? raise "Cannot retrieve #{self.class.current_resource} in why-run mode: #{provider} does not support why-run" -- cgit v1.2.1 From 01be9b1e91e515eb76de43a1e448e5476bd56574 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Wed, 9 Sep 2015 18:17:48 -0700 Subject: Add policy_name and policy_group attrs to Node class --- lib/chef/node.rb | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'lib/chef') diff --git a/lib/chef/node.rb b/lib/chef/node.rb index 22c7d5bd8e..65ed21a442 100644 --- a/lib/chef/node.rb +++ b/lib/chef/node.rb @@ -63,6 +63,8 @@ class Chef include Chef::Mixin::ParamsValidate + NULL_ARG = Object.new + # Create a new Chef::Node object. def initialize(chef_server_rest: nil) @chef_server_rest = chef_server_rest @@ -72,6 +74,9 @@ class Chef @primary_runlist = Chef::RunList.new @override_runlist = Chef::RunList.new + @policy_name = nil + @policy_group = nil + @attributes = Chef::Node::Attribute.new({}, {}, {}, {}) @run_state = {} @@ -132,6 +137,50 @@ class Chef alias :environment :chef_environment + # The `policy_name` for this node. Setting this to a non-nil value will + # enable policyfile mode when `chef-client` is run. If set in the config + # file or in node json, running `chef-client` will update this value. + # + # @see Chef::PolicyBuilder::Dynamic + # @see Chef::PolicyBuilder::Policyfile + # + # @param arg [String] the new policy_name value + # @return [String] the current policy_name, or the one you just set + def policy_name(arg=NULL_ARG) + return @policy_name if arg.equal?(NULL_ARG) + validate({policy_name: arg}, { policy_name: { kind_of: [ String, NilClass ], regex: /^[\-:.[:alnum:]_]+$/ } }) + @policy_name = arg + end + + # A "non-DSL-style" setter for `policy_name` + # + # @see #policy_name + def policy_name=(policy_name) + policy_name(policy_name) + end + + # The `policy_group` for this node. Setting this to a non-nil value will + # enable policyfile mode when `chef-client` is run. If set in the config + # file or in node json, running `chef-client` will update this value. + # + # @see Chef::PolicyBuilder::Dynamic + # @see Chef::PolicyBuilder::Policyfile + # + # @param arg [String] the new policy_group value + # @return [String] the current policy_group, or the one you just set + def policy_group(arg=NULL_ARG) + return @policy_group if arg.equal?(NULL_ARG) + validate({policy_group: arg}, { policy_group: { kind_of: [ String, NilClass ], regex: /^[\-:.[:alnum:]_]+$/ } }) + @policy_group = arg + end + + # A "non-DSL-style" setter for `policy_group` + # + # @see #policy_group + def policy_group=(policy_group) + policy_group(policy_group) + end + def attributes @attributes end -- cgit v1.2.1 From 69c7fa5f63e01c64f8ccc198ddc00c836c24914e Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Wed, 9 Sep 2015 18:33:15 -0700 Subject: Add Dynamic PolicyBuilder to switch on policyfile mode Now we need to switch PolicyBuilder implementations based on several factors instead of just a single config settings, including content of the node fetched from the Chef Server. --- lib/chef/policy_builder.rb | 1 + lib/chef/policy_builder/dynamic.rb | 136 +++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 lib/chef/policy_builder/dynamic.rb (limited to 'lib/chef') diff --git a/lib/chef/policy_builder.rb b/lib/chef/policy_builder.rb index 136b2853b0..036d8bc051 100644 --- a/lib/chef/policy_builder.rb +++ b/lib/chef/policy_builder.rb @@ -18,6 +18,7 @@ require 'chef/policy_builder/expand_node_object' require 'chef/policy_builder/policyfile' +require 'chef/policy_builder/dynamic' class Chef diff --git a/lib/chef/policy_builder/dynamic.rb b/lib/chef/policy_builder/dynamic.rb new file mode 100644 index 0000000000..e976ddd87f --- /dev/null +++ b/lib/chef/policy_builder/dynamic.rb @@ -0,0 +1,136 @@ +# +# Author:: Daniel DeLeo () +# Copyright:: Copyright 2015 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. +# + +require 'chef/log' +require 'chef/rest' +require 'chef/run_context' +require 'chef/config' +require 'chef/node' + +class Chef + module PolicyBuilder + + # PolicyBuilder that selects either a Policyfile or non-Policyfile + # implementation based on the content of the node object. + class Dynamic + + attr_reader :node + attr_reader :node_name + attr_reader :ohai_data + attr_reader :json_attribs + attr_reader :override_runlist + attr_reader :events + + def initialize(node_name, ohai_data, json_attribs, override_runlist, events) + @implementation = nil + + @node_name = node_name + @ohai_data = ohai_data + @json_attribs = json_attribs + @override_runlist = override_runlist + @events = events + + @node = nil + end + + ## PolicyBuilder API ## + + # Loads the node state from the server, then picks the correct + # implementation class based on the node and json_attribs. + def load_node + events.node_load_start(node_name, config) + Chef::Log.debug("Building node object for #{node_name}") + + node = Chef::Node.find_or_create(node_name) + select_implementation(node) + implementation.finish_load_node(node) + node + rescue Exception => e + events.node_load_failed(node_name, e, config) + raise + end + + ## Delegated Methods ## + + def original_runlist + implementation.original_runlist + end + + def run_context + implementation.run_context + end + + def run_list_expansion + implementation.run_list_expansion + end + + def build_node + implementation.build_node + end + + def setup_run_context(specific_recipes=nil) + implementation.setup_run_context(specific_recipes) + end + + def expand_run_list + implementation.expand_run_list + end + + def sync_cookbooks + implementation.sync_cookbooks + end + + def temporary_policy? + implementation.temporary_policy? + end + + ## Internal Public API ## + + def implementation + @implementation + end + + def select_implementation(node) + if policyfile_set_in_config? || policyfile_attribs_in_node_json? || node_has_policyfile_attrs?(node) + @implementation = Policyfile.new(node_name, ohai_data, json_attribs, override_runlist, events) + else + @implementation = ExpandNodeObject.new(node_name, ohai_data, json_attribs, override_runlist, events) + end + end + + def config + Chef::Config + end + + private + + def node_has_policyfile_attrs?(node) + node.policy_name || node.policy_group + end + + def policyfile_attribs_in_node_json? + json_attribs.key?("policy_name") || json_attribs.key?("policy_group") + end + + def policyfile_set_in_config? + config[:use_policyfile] || config[:policy_name] || config[:policy_group] + end + + end + end +end -- cgit v1.2.1 From 6f65a2ea7771a319e4315d68dd5234aeedc7dfd9 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Fri, 11 Sep 2015 17:18:22 -0700 Subject: Use the dynamic policy builder everywhere --- lib/chef/client.rb | 2 +- lib/chef/exceptions.rb | 2 ++ lib/chef/policy_builder.rb | 8 -------- lib/chef/policy_builder/dynamic.rb | 10 ++++++++-- lib/chef/policy_builder/expand_node_object.rb | 20 ++------------------ lib/chef/policy_builder/policyfile.rb | 12 ++---------- 6 files changed, 15 insertions(+), 39 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/client.rb b/lib/chef/client.rb index 621ce3d489..7d5d463242 100644 --- a/lib/chef/client.rb +++ b/lib/chef/client.rb @@ -496,7 +496,7 @@ class Chef # @api private # def policy_builder - @policy_builder ||= Chef::PolicyBuilder.strategy.new(node_name, ohai.data, json_attribs, override_runlist, events) + @policy_builder ||= Chef::PolicyBuilder::Dynamic.new(node_name, ohai.data, json_attribs, override_runlist, events) end # diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb index e3649c068b..7862d9c160 100644 --- a/lib/chef/exceptions.rb +++ b/lib/chef/exceptions.rb @@ -116,6 +116,8 @@ class Chef end end + class InvalidPolicybuilderCall < ArgumentError; end + class InvalidResourceSpecification < ArgumentError; end class SolrConnectionError < RuntimeError; end class IllegalChecksumRevert < RuntimeError; end diff --git a/lib/chef/policy_builder.rb b/lib/chef/policy_builder.rb index 036d8bc051..56415dbbd0 100644 --- a/lib/chef/policy_builder.rb +++ b/lib/chef/policy_builder.rb @@ -38,13 +38,5 @@ class Chef # * cookbook_hash is stored in run_context module PolicyBuilder - def self.strategy - if Chef::Config[:use_policyfile] - Policyfile - else - ExpandNodeObject - end - end - end end diff --git a/lib/chef/policy_builder/dynamic.rb b/lib/chef/policy_builder/dynamic.rb index e976ddd87f..d2849dd4f1 100644 --- a/lib/chef/policy_builder/dynamic.rb +++ b/lib/chef/policy_builder/dynamic.rb @@ -21,6 +21,7 @@ require 'chef/rest' require 'chef/run_context' require 'chef/config' require 'chef/node' +require 'chef/exceptions' class Chef module PolicyBuilder @@ -56,7 +57,12 @@ class Chef events.node_load_start(node_name, config) Chef::Log.debug("Building node object for #{node_name}") - node = Chef::Node.find_or_create(node_name) + @node = + if Chef::Config[:solo] + Chef::Node.build(node_name) + else + Chef::Node.find_or_create(node_name) + end select_implementation(node) implementation.finish_load_node(node) node @@ -102,7 +108,7 @@ class Chef ## Internal Public API ## def implementation - @implementation + @implementation or raise Exceptions::InvalidPolicybuilderCall, "#load_node must be called before other policy builder methods" end def select_implementation(node) diff --git a/lib/chef/policy_builder/expand_node_object.rb b/lib/chef/policy_builder/expand_node_object.rb index 524bdd95b1..543d6a0a7b 100644 --- a/lib/chef/policy_builder/expand_node_object.rb +++ b/lib/chef/policy_builder/expand_node_object.rb @@ -93,26 +93,10 @@ class Chef run_context end - - # In client-server operation, loads the node state from the server. In - # chef-solo operation, builds a new node object. - def load_node - events.node_load_start(node_name, Chef::Config) - Chef::Log.debug("Building node object for #{node_name}") - - if Chef::Config[:solo] - @node = Chef::Node.build(node_name) - else - @node = Chef::Node.find_or_create(node_name) - end - rescue Exception => e - # TODO: wrap this exception so useful error info can be given to the - # user. - events.node_load_failed(node_name, e, Chef::Config) - raise + def finish_load_node(node) + @node = node end - # Applies environment, external JSON attributes, and override run list to # the node, Then expands the run_list. # diff --git a/lib/chef/policy_builder/policyfile.rb b/lib/chef/policy_builder/policyfile.rb index 5991e3ce10..5bcdd5f52f 100644 --- a/lib/chef/policy_builder/policyfile.rb +++ b/lib/chef/policy_builder/policyfile.rb @@ -112,18 +112,10 @@ class Chef ## PolicyBuilder API ## - # Loads the node state from the server. - def load_node - events.node_load_start(node_name, Chef::Config) - Chef::Log.debug("Building node object for #{node_name}") - - @node = Chef::Node.find_or_create(node_name) + def finish_load_node(node) + @node = node validate_policyfile events.policyfile_loaded(policy) - node - rescue Exception => e - events.node_load_failed(node_name, e, Chef::Config) - raise end # Applies environment, external JSON attributes, and override run list to -- cgit v1.2.1 From 3d7ec975024e85f24ef8e4782a00eeb178d379e8 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Mon, 14 Sep 2015 11:29:32 -0700 Subject: Add policyfile attrs to node JSON when present --- lib/chef/node.rb | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib/chef') diff --git a/lib/chef/node.rb b/lib/chef/node.rb index 65ed21a442..34a1edf835 100644 --- a/lib/chef/node.rb +++ b/lib/chef/node.rb @@ -510,6 +510,14 @@ class Chef #Render correctly for run_list items so malformed json does not result "run_list" => @primary_runlist.run_list.map { |item| item.to_s } } + # Chef Server rejects node JSON with extra keys; prior to 12.3, + # "policy_name" and "policy_group" are unknown; after 12.3 they are + # optional, therefore only including them in the JSON if present + # maximizes compatibility for most people. + unless policy_group.nil? && policy_name.nil? + result["policy_name"] = policy_name + result["policy_group"] = policy_group + end result end -- cgit v1.2.1 From 2890a01b06d7b341d8483f946eee788063baecc9 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Mon, 14 Sep 2015 16:13:16 -0700 Subject: Add policyfile attrs to node create/save --- lib/chef/node.rb | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/node.rb b/lib/chef/node.rb index 34a1edf835..3c3286c548 100644 --- a/lib/chef/node.rb +++ b/lib/chef/node.rb @@ -610,8 +610,16 @@ class Chef chef_server_rest.put_rest("nodes/#{name}", data_for_save) end rescue Net::HTTPServerException => e - raise e unless e.response.code == "404" - chef_server_rest.post_rest("nodes", data_for_save) + if e.response.code == "404" + chef_server_rest.post_rest("nodes", data_for_save) + # Chef Server before 12.3 rejects node JSON with 'policy_name' or + # 'policy_group' keys, but 'policy_name' will be detected first. + # Backcompat can be removed in 13.0 + elsif e.response.code == "400" && e.response.body.include?("Invalid key policy_name") + save_without_policyfile_attrs + else + raise + end end self end @@ -620,6 +628,15 @@ class Chef def create chef_server_rest.post_rest("nodes", data_for_save) self + rescue Net::HTTPServerException => e + # Chef Server before 12.3 rejects node JSON with 'policy_name' or + # 'policy_group' keys, but 'policy_name' will be detected first. + # Backcompat can be removed in 13.0 + if e.response.code == "400" && e.response.body.include?("Invalid key policy_name") + chef_server_rest.post_rest("nodes", data_for_save_without_policyfile_attrs) + else + raise + end end def to_s @@ -632,6 +649,22 @@ class Chef private + def save_without_policyfile_attrs + trimmed_data = data_for_save_without_policyfile_attrs + + chef_server_rest.put_rest("nodes/#{name}", trimmed_data) + rescue Net::HTTPServerException => e + raise e unless e.response.code == "404" + chef_server_rest.post_rest("nodes", trimmed_data) + end + + def data_for_save_without_policyfile_attrs + data_for_save.tap do |trimmed_data| + trimmed_data.delete("policy_name") + trimmed_data.delete("policy_group") + end + end + def data_for_save data = for_json ["automatic", "default", "normal", "override"].each do |level| -- cgit v1.2.1 From e441d37d36eedbd73b37166f982536b8702ff4fb Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Mon, 14 Sep 2015 17:25:56 -0700 Subject: Set the precedence of policyfile attrs and propagate them everywhere --- lib/chef/policy_builder/policyfile.rb | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'lib/chef') diff --git a/lib/chef/policy_builder/policyfile.rb b/lib/chef/policy_builder/policyfile.rb index 5bcdd5f52f..ef3b7838cb 100644 --- a/lib/chef/policy_builder/policyfile.rb +++ b/lib/chef/policy_builder/policyfile.rb @@ -114,6 +114,7 @@ class Chef def finish_load_node(node) @node = node + select_policy_name_and_group validate_policyfile events.policyfile_loaded(policy) end @@ -295,6 +296,48 @@ class Chef Chef::Config[:policy_name] end + def select_policy_name_and_group + policy_name_to_set = + policy_name_from_json_attribs || + policy_name_from_config || + policy_name_from_node + + policy_group_to_set = + policy_group_from_json_attribs || + policy_group_from_config || + policy_group_from_node + + node.policy_name = policy_name_to_set + node.policy_group = policy_group_to_set + + Chef::Config[:policy_name] = policy_name_to_set + Chef::Config[:policy_group] = policy_group_to_set + end + + def policy_group_from_json_attribs + json_attribs["policy_group"] + end + + def policy_name_from_json_attribs + json_attribs["policy_name"] + end + + def policy_group_from_config + Chef::Config[:policy_group] + end + + def policy_name_from_config + Chef::Config[:policy_name] + end + + def policy_group_from_node + node.policy_group + end + + def policy_name_from_node + node.policy_name + end + # Builds a 'cookbook_hash' map of the form # "COOKBOOK_NAME" => "IDENTIFIER" # -- cgit v1.2.1 From f21715037c1fc9956738ba069760f3c7615987ce Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Mon, 14 Sep 2015 19:15:41 -0700 Subject: Populate node policyfile attrs from JSON --- lib/chef/node.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/chef') diff --git a/lib/chef/node.rb b/lib/chef/node.rb index 3c3286c548..668ddbdc35 100644 --- a/lib/chef/node.rb +++ b/lib/chef/node.rb @@ -549,6 +549,10 @@ class Chef else o["recipes"].each { |r| node.recipes << r } end + + node.policy_name = o["policy_name"] if o.has_key?("policy_name") + node.policy_group = o["policy_group"] if o.has_key?("policy_group") + node end -- cgit v1.2.1 From 3ca6231a7908e2c54c679c187a46ae10dfe21396 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Tue, 15 Sep 2015 09:57:32 -0700 Subject: Show policyfile attributes in node presenter --- lib/chef/knife/core/node_presenter.rb | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/core/node_presenter.rb b/lib/chef/knife/core/node_presenter.rb index d1aab592ef..d9ea8c7669 100644 --- a/lib/chef/knife/core/node_presenter.rb +++ b/lib/chef/knife/core/node_presenter.rb @@ -67,7 +67,12 @@ class Chef result = {} result["name"] = node.name - result["chef_environment"] = node.chef_environment + if node.policy_name.nil? && node.policy_group.nil? + result["chef_environment"] = node.chef_environment + else + result["policy_name"] = node.policy_name + result["policy_group"] = node.policy_group + end result["run_list"] = node.run_list result["normal"] = node.normal_attrs @@ -95,11 +100,29 @@ class Chef summarized=<<-SUMMARY #{ui.color('Node Name:', :bold)} #{ui.color(node.name, :bold)} +SUMMARY + show_policy = !(node.policy_name.nil? && node.policy_group.nil?) + if show_policy + summarized << <<-POLICY +#{key('Policy Name:')} #{node.policy_name} +#{key('Policy Group:')} #{node.policy_group} +POLICY + else + summarized << <<-ENV #{key('Environment:')} #{node.chef_environment} +ENV + end + summarized << <<-SUMMARY #{key('FQDN:')} #{node[:fqdn]} #{key('IP:')} #{ip} #{key('Run List:')} #{node.run_list} +SUMMARY + unless show_policy + summarized << <<-ROLES #{key('Roles:')} #{Array(node[:roles]).join(', ')} +ROLES + end + summarized << <<-SUMMARY #{key('Recipes:')} #{Array(node[:recipes]).join(', ')} #{key('Platform:')} #{node[:platform]} #{node[:platform_version]} #{key('Tags:')} #{Array(node[:tags]).join(', ')} -- cgit v1.2.1 From 90075c9d83c2df2916fd1a2d441401e1c7cf5362 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Tue, 15 Sep 2015 11:23:06 -0700 Subject: Detect when user wants policyfile compat mode --- lib/chef/policy_builder/dynamic.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/policy_builder/dynamic.rb b/lib/chef/policy_builder/dynamic.rb index d2849dd4f1..0f266a25fb 100644 --- a/lib/chef/policy_builder/dynamic.rb +++ b/lib/chef/policy_builder/dynamic.rb @@ -112,7 +112,10 @@ class Chef end def select_implementation(node) - if policyfile_set_in_config? || policyfile_attribs_in_node_json? || node_has_policyfile_attrs?(node) + if policyfile_set_in_config? || + policyfile_attribs_in_node_json? || + node_has_policyfile_attrs?(node) || + policyfile_compat_mode_config? @implementation = Policyfile.new(node_name, ohai_data, json_attribs, override_runlist, events) else @implementation = ExpandNodeObject.new(node_name, ohai_data, json_attribs, override_runlist, events) @@ -137,6 +140,10 @@ class Chef config[:use_policyfile] || config[:policy_name] || config[:policy_group] end + def policyfile_compat_mode_config? + config[:deployment_group] && !config[:policy_document_native_api] + end + end end end -- cgit v1.2.1 From 41372f5a6b5608625a6d89953d24c60373d4c39b Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Tue, 15 Sep 2015 11:28:35 -0700 Subject: Add policyfile attrs to knife "fuzzy" search --- lib/chef/knife/search.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/search.rb b/lib/chef/knife/search.rb index 9319d30e7d..2b0c79ff6c 100644 --- a/lib/chef/knife/search.rb +++ b/lib/chef/knife/search.rb @@ -160,7 +160,7 @@ class Chef def fuzzify_query if @query !~ /:/ - @query = "tags:*#{@query}* OR roles:*#{@query}* OR fqdn:*#{@query}* OR addresses:*#{@query}*" + @query = "tags:*#{@query}* OR roles:*#{@query}* OR fqdn:*#{@query}* OR addresses:*#{@query}* OR policy_name:*#{@query}* OR policy_group:*#{@query}*" end end -- cgit v1.2.1 From 6c01a178e1c701f2e4c5f85d0c9fa93431bb5b69 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Wed, 16 Sep 2015 16:53:25 -0700 Subject: Use Forwardable to delegate in PolicyBuilder::Dynamic --- lib/chef/policy_builder/dynamic.rb | 45 +++++++++++--------------------------- 1 file changed, 13 insertions(+), 32 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/policy_builder/dynamic.rb b/lib/chef/policy_builder/dynamic.rb index 0f266a25fb..deefd1e855 100644 --- a/lib/chef/policy_builder/dynamic.rb +++ b/lib/chef/policy_builder/dynamic.rb @@ -16,6 +16,8 @@ # limitations under the License. # +require 'forwardable' + require 'chef/log' require 'chef/rest' require 'chef/run_context' @@ -30,6 +32,8 @@ class Chef # implementation based on the content of the node object. class Dynamic + extend Forwardable + attr_reader :node attr_reader :node_name attr_reader :ohai_data @@ -71,39 +75,16 @@ class Chef raise end - ## Delegated Methods ## + ## Delegated Public API Methods ## - def original_runlist - implementation.original_runlist - end - - def run_context - implementation.run_context - end - - def run_list_expansion - implementation.run_list_expansion - end - - def build_node - implementation.build_node - end - - def setup_run_context(specific_recipes=nil) - implementation.setup_run_context(specific_recipes) - end - - def expand_run_list - implementation.expand_run_list - end - - def sync_cookbooks - implementation.sync_cookbooks - end - - def temporary_policy? - implementation.temporary_policy? - end + def_delegator :implementation, :original_runlist + def_delegator :implementation, :run_context + def_delegator :implementation, :run_list_expansion + def_delegator :implementation, :build_node + def_delegator :implementation, :setup_run_context + def_delegator :implementation, :expand_run_list + def_delegator :implementation, :sync_cookbooks + def_delegator :implementation, :temporary_policy? ## Internal Public API ## -- cgit v1.2.1 From d2f5ff985403d32fd452b82a3dab1f09ccf4fae4 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Thu, 17 Sep 2015 09:15:48 -0700 Subject: Document policy builder API on the dynamic builder --- lib/chef/policy_builder/dynamic.rb | 56 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'lib/chef') diff --git a/lib/chef/policy_builder/dynamic.rb b/lib/chef/policy_builder/dynamic.rb index deefd1e855..c9842ba532 100644 --- a/lib/chef/policy_builder/dynamic.rb +++ b/lib/chef/policy_builder/dynamic.rb @@ -57,6 +57,11 @@ class Chef # Loads the node state from the server, then picks the correct # implementation class based on the node and json_attribs. + # + # Calls #finish_load_node on the implementation object to complete the + # loading process. All subsequent lifecycle calls are delegated. + # + # @return [Chef::Node] the loaded node. def load_node events.node_load_start(node_name, config) Chef::Log.debug("Building node object for #{node_name}") @@ -77,21 +82,72 @@ class Chef ## Delegated Public API Methods ## + ### Accessors ### + def_delegator :implementation, :original_runlist def_delegator :implementation, :run_context def_delegator :implementation, :run_list_expansion + + ### Lifecycle Methods ### + + # @!method build_node + # + # Applies external attributes (e.g., from JSON file, environment, + # policyfile, etc.) and determines the correct expanded run list for the + # run. + # + # @return [Chef::Node] def_delegator :implementation, :build_node + + # @!method setup_run_context + # + # Synchronizes cookbooks and initializes the run context object for the + # run. + # + # @return [Chef::RunContext] def_delegator :implementation, :setup_run_context + + # @!method expanded_run_list + # + # Resolves the run list to a form containing only recipes and sets the + # `roles` and `recipes` automatic attributes on the node. + # + # @return [#recipes, #roles] A RunListExpansion or duck-type. def_delegator :implementation, :expand_run_list + + # @!method sync_cookbooks + # + # Synchronizes cookbooks. In a normal chef-client run, this is handled by + # #setup_run_context, but may be called directly in some circumstances. + # + # @return [Hash{String => Chef::CookbookManifest}] A map of + # CookbookManifest objects by cookbook name. def_delegator :implementation, :sync_cookbooks + + # @!method temporary_policy? + # + # Indicates whether the policy is temporary, which means an + # override_runlist was provided. Chef::Client uses this to decide whether + # to do the final node save at the end of the run or not. + # + # @return [true,false] def_delegator :implementation, :temporary_policy? ## Internal Public API ## + # Returns the selected implementation, or raises if not set. The + # implementation is set when #load_node is called. + # + # @return [PolicyBuilder::Policyfile, PolicyBuilder::ExpandNodeObject] def implementation @implementation or raise Exceptions::InvalidPolicybuilderCall, "#load_node must be called before other policy builder methods" end + # @api private + # + # Sets the implementation based on the content of the node, node JSON + # (i.e., the `-j JSON_FILE` data), and config. This is only public for + # testing purposes; production code should call #load_node instead. def select_implementation(node) if policyfile_set_in_config? || policyfile_attribs_in_node_json? || -- cgit v1.2.1 From 6883743831ff798d3d704ee62c78796ff9b4df16 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Thu, 17 Sep 2015 09:26:32 -0700 Subject: Update code comment to reflect reality --- lib/chef/policy_builder/expand_node_object.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/policy_builder/expand_node_object.rb b/lib/chef/policy_builder/expand_node_object.rb index 543d6a0a7b..caedcb4035 100644 --- a/lib/chef/policy_builder/expand_node_object.rb +++ b/lib/chef/policy_builder/expand_node_object.rb @@ -55,9 +55,7 @@ class Chef @run_list_expansion = nil end - # This method injects the run_context and provider and resource priority - # maps into the Chef class. The run_context has to be injected here, the provider and - # resource maps could be moved if a better place can be found to do this work. + # This method injects the run_context and into the Chef class. # # @param run_context [Chef::RunContext] the run_context to inject def setup_chef_class(run_context) -- cgit v1.2.1 From 2cadf9cd40e4c19741121bf2df180941918107bb Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Thu, 17 Sep 2015 09:48:31 -0700 Subject: Add `setup_chef_class` to Policyfile policy builder Also, mark internal public API as @private --- lib/chef/policy_builder/expand_node_object.rb | 3 ++ lib/chef/policy_builder/policyfile.rb | 72 ++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/policy_builder/expand_node_object.rb b/lib/chef/policy_builder/expand_node_object.rb index caedcb4035..26b98afa52 100644 --- a/lib/chef/policy_builder/expand_node_object.rb +++ b/lib/chef/policy_builder/expand_node_object.rb @@ -57,6 +57,9 @@ class Chef # This method injects the run_context and into the Chef class. # + # NOTE: This is duplicated with the Policyfile implementation. If + # it gets any more complicated, it needs to be moved elsewhere. + # # @param run_context [Chef::RunContext] the run_context to inject def setup_chef_class(run_context) Chef.set_run_context(run_context) diff --git a/lib/chef/policy_builder/policyfile.rb b/lib/chef/policy_builder/policyfile.rb index ef3b7838cb..69ef485e14 100644 --- a/lib/chef/policy_builder/policyfile.rb +++ b/lib/chef/policy_builder/policyfile.rb @@ -147,17 +147,28 @@ class Chef raise end + # Synchronizes cookbooks and initializes the run context object for the + # run. + # + # @return [Chef::RunContext] def setup_run_context(specific_recipes=nil) Chef::Cookbook::FileVendor.fetch_from_remote(http_api) sync_cookbooks cookbook_collection = Chef::CookbookCollection.new(cookbooks_to_sync) run_context = Chef::RunContext.new(node, cookbook_collection, events) + setup_chef_class(run_context) + run_context.load(run_list_expansion_ish) + setup_chef_class(run_context) run_context end + # Sets `run_list` on the node from the policy, sets `roles` and `recipes` + # attributes on the node accordingly. + # + # @return [RunListExpansionIsh] A RunListExpansion duck-type. def expand_run_list node.run_list(run_list) node.automatic_attrs[:roles] = [] @@ -165,7 +176,11 @@ class Chef run_list_expansion_ish end - + # Synchronizes cookbooks. In a normal chef-client run, this is handled by + # #setup_run_context, but may be called directly in some circumstances. + # + # @return [Hash{String => Chef::CookbookManifest}] A map of + # CookbookManifest objects by cookbook name. def sync_cookbooks Chef::Log.debug("Synchronizing cookbooks") synchronizer = Chef::CookbookSynchronizer.new(cookbooks_to_sync, events) @@ -179,12 +194,18 @@ class Chef # Whether or not this is a temporary policy. Since PolicyBuilder doesn't # support override_runlist, this is always false. + # + # @return [false] def temporary_policy? false end ## Internal Public API ## + # @api private + # + # Generates an array of strings with recipe names including version and + # identifier info. def run_list_with_versions_for_display run_list.map do |recipe_spec| cookbook, recipe = parse_recipe_spec(recipe_spec) @@ -194,6 +215,11 @@ class Chef end end + # @api private + # + # Sets up a RunListExpansionIsh object so that it can be used in place of + # a RunListExpansion object, to satisfy the API contract of + # #expand_run_list def run_list_expansion_ish recipes = run_list.map do |recipe_spec| cookbook, recipe = parse_recipe_spec(recipe_spec) @@ -202,11 +228,15 @@ class Chef RunListExpansionIsh.new(recipes, []) end + # @api private + # + # Sets attributes from the policyfile on the node, using the role priority. def apply_policyfile_attributes node.attributes.role_default = policy["default_attributes"] node.attributes.role_override = policy["override_attributes"] end + # @api private def parse_recipe_spec(recipe_spec) rmatch = recipe_spec.match(/recipe\[([^:]+)::([^:]+)\]/) if rmatch.nil? @@ -216,20 +246,24 @@ class Chef end end + # @api private def cookbook_lock_for(cookbook_name) cookbook_locks[cookbook_name] end + # @api private def run_list policy["run_list"] end + # @api private def policy @policy ||= http_api.get(policyfile_location) rescue Net::HTTPServerException => e raise ConfigurationError, "Error loading policyfile from `#{policyfile_location}': #{e.class} - #{e.message}" end + # @api private def policyfile_location if Chef::Config[:policy_document_native_api] validate_policy_config! @@ -266,6 +300,7 @@ class Chef end end + # @api private def validate_recipe_spec(recipe_spec) parse_recipe_spec(recipe_spec) nil @@ -275,11 +310,13 @@ class Chef class ConfigurationError < StandardError; end + # @api private def deployment_group Chef::Config[:deployment_group] or raise ConfigurationError, "Setting `deployment_group` is not configured." end + # @api private def validate_policy_config! policy_group or raise ConfigurationError, "Setting `policy_group` is not configured." @@ -288,14 +325,26 @@ class Chef raise ConfigurationError, "Setting `policy_name` is not configured." end + # @api private def policy_group Chef::Config[:policy_group] end + # @api private def policy_name Chef::Config[:policy_name] end + # @api private + # + # Selects the `policy_name` and `policy_group` from the following sources + # in priority order: + # + # 1. JSON attribs (i.e., `-j JSON_FILE`) + # 2. `Chef::Config` + # 3. The node object + # + # The selected values are then copied to `Chef::Config` and the node. def select_policy_name_and_group policy_name_to_set = policy_name_from_json_attribs || @@ -314,30 +363,37 @@ class Chef Chef::Config[:policy_group] = policy_group_to_set end + # @api private def policy_group_from_json_attribs json_attribs["policy_group"] end + # @api private def policy_name_from_json_attribs json_attribs["policy_name"] end + # @api private def policy_group_from_config Chef::Config[:policy_group] end + # @api private def policy_name_from_config Chef::Config[:policy_name] end + # @api private def policy_group_from_node node.policy_group end + # @api private def policy_name_from_node node.policy_name end + # @api private # Builds a 'cookbook_hash' map of the form # "COOKBOOK_NAME" => "IDENTIFIER" # @@ -365,6 +421,7 @@ class Chef raise end + # @api private # Fetches the CookbookVersion object for the given name and identifer # specified in the lock_data. # TODO: This only implements Chef 11 compatibility mode, which means that @@ -378,20 +435,33 @@ class Chef end end + # @api private def cookbook_locks policy["cookbook_locks"] end + # @api private def http_api @api_service ||= Chef::REST.new(config[:chef_server_url]) end + # @api private def config Chef::Config end private + # This method injects the run_context and into the Chef class. + # + # NOTE: This is duplicated with the ExpandNodeObject implementation. If + # it gets any more complicated, it needs to be moved elsewhere. + # + # @param run_context [Chef::RunContext] the run_context to inject + def setup_chef_class(run_context) + Chef.set_run_context(run_context) + end + def compat_mode_manifest_for(cookbook_name, lock_data) xyz_version = lock_data["dotted_decimal_identifier"] rel_url = "cookbooks/#{cookbook_name}/#{xyz_version}" -- cgit v1.2.1 From 9703782bad3ddfad90b21ca5a225d4bd2e393f0d Mon Sep 17 00:00:00 2001 From: Claire McQuin Date: Thu, 17 Sep 2015 09:47:08 -0700 Subject: Don't add win_evt logger when on nano. --- lib/chef/config.rb | 3 ++- lib/chef/platform/query_helpers.rb | 24 +++++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/config.rb b/lib/chef/config.rb index 6382af14c2..a43985f691 100644 --- a/lib/chef/config.rb +++ b/lib/chef/config.rb @@ -55,7 +55,8 @@ class Chef default :event_loggers do evt_loggers = [] - if ChefConfig.windows? and not Chef::Platform.windows_server_2003? + if ChefConfig.windows? && !(Chef::Platform.windows_server_2003? || + Chef::Platform.windows_nano_server?) evt_loggers << :win_evt end evt_loggers diff --git a/lib/chef/platform/query_helpers.rb b/lib/chef/platform/query_helpers.rb index 2dd33ea190..9ba8d2261d 100644 --- a/lib/chef/platform/query_helpers.rb +++ b/lib/chef/platform/query_helpers.rb @@ -36,6 +36,28 @@ class Chef is_server_2003 end + def windows_nano_server? + return false unless windows? + require 'win32/registry' + + # This method may be called before ohai runs (e.g., it may be used to + # determine settings in config.rb). Chef::Win32::Registry.new uses + # node attributes to verify the machine architecture which aren't + # accessible before ohai runs. + nano = nil + key = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Server\\ServerLevels" + access = ::Win32::Registry::KEY_QUERY_VALUE | 0x0100 # nano is 64-bit only + begin + ::Win32::Registry::HKEY_LOCAL_MACHINE.open(key, access) do |reg| + nano = reg["NanoServer"] + end + rescue ::Win32::Registry::Error + # If accessing the registry key failed, then we're probably not on + # nano. Fail through. + end + return nano == 1 + end + def supports_powershell_execution_bypass?(node) node[:languages] && node[:languages][:powershell] && node[:languages][:powershell][:version].to_i >= 3 @@ -52,7 +74,7 @@ class Chef Gem::Version.new(node[:languages][:powershell][:version]) >= Gem::Version.new("5.0.10018.0") end - + def dsc_refresh_mode_disabled?(node) require 'chef/util/powershell/cmdlet' cmdlet = Chef::Util::Powershell::Cmdlet.new(node, "Get-DscLocalConfigurationManager", :object) -- cgit v1.2.1 From 3bffbc968d4dc76cd6992c603f849cf46fd759dc Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Wed, 16 Sep 2015 16:17:00 -0700 Subject: Apply a named_run_list in policy builder via configuration --- lib/chef/policy_builder/policyfile.rb | 36 ++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/policy_builder/policyfile.rb b/lib/chef/policy_builder/policyfile.rb index 69ef485e14..bb9593eb36 100644 --- a/lib/chef/policy_builder/policyfile.rb +++ b/lib/chef/policy_builder/policyfile.rb @@ -170,6 +170,8 @@ class Chef # # @return [RunListExpansionIsh] A RunListExpansion duck-type. def expand_run_list + CookbookCacheCleaner.instance.skip_removal = true if named_run_list_requested? + node.run_list(run_list) node.automatic_attrs[:roles] = [] node.automatic_attrs[:recipes] = run_list_expansion_ish.recipes @@ -253,7 +255,14 @@ class Chef # @api private def run_list - policy["run_list"] + if named_run_list_requested? + named_run_list or + raise ConfigurationError, + "Policy '#{retrieved_policy_name}' revision '#{revision_id}' does not have named_run_list '#{named_run_list_name}'" + + "(available named_run_lists: [#{available_named_run_lists.join(', ')}])" + else + policy["run_list"] + end end # @api private @@ -440,6 +449,11 @@ class Chef policy["cookbook_locks"] end + # @api private + def revision_id + policy["revision_id"] + end + # @api private def http_api @api_service ||= Chef::REST.new(config[:chef_server_url]) @@ -462,6 +476,26 @@ class Chef Chef.set_run_context(run_context) end + def retrieved_policy_name + policy["name"] + end + + def named_run_list + policy["named_run_lists"] && policy["named_run_lists"][named_run_list_name] + end + + def available_named_run_lists + (policy["named_run_lists"] || {}).keys + end + + def named_run_list_requested? + !!Chef::Config[:named_run_list] + end + + def named_run_list_name + Chef::Config[:named_run_list] + end + def compat_mode_manifest_for(cookbook_name, lock_data) xyz_version = lock_data["dotted_decimal_identifier"] rel_url = "cookbooks/#{cookbook_name}/#{xyz_version}" -- cgit v1.2.1 From 6a3ff229c9db3c9811ada59aed2ead80efe699b4 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Thu, 17 Sep 2015 16:14:03 -0700 Subject: Configure named run list via command line or config file --- lib/chef/application/client.rb | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/chef') diff --git a/lib/chef/application/client.rb b/lib/chef/application/client.rb index 73eda81343..148257ab89 100644 --- a/lib/chef/application/client.rb +++ b/lib/chef/application/client.rb @@ -160,6 +160,12 @@ class Chef::Application::Client < Chef::Application :description => "Set the client key file location", :proc => nil + option :named_run_list, + :short => "-n NAMED_RUN_LIST", + :long => "--named-run-list NAMED_RUN_LIST", + :description => "Use a policyfile's named run list instead of the default run list", + :default => nil + option :environment, :short => '-E ENVIRONMENT', :long => '--environment ENVIRONMENT', -- cgit v1.2.1 From 064e0a6b90d1e9a1e00e0c9ef4d18eb1ecc33a3e Mon Sep 17 00:00:00 2001 From: John Keiser Date: Fri, 10 Jul 2015 12:15:07 -0600 Subject: Rename action_provider_class to less-wordy action_class --- lib/chef/exceptions.rb | 2 +- lib/chef/resource.rb | 45 ++++++++++--------- lib/chef/resource/action_class.rb | 83 ++++++++++++++++++++++++++++++++++++ lib/chef/resource/action_provider.rb | 69 ------------------------------ 4 files changed, 106 insertions(+), 93 deletions(-) create mode 100644 lib/chef/resource/action_class.rb delete mode 100644 lib/chef/resource/action_provider.rb (limited to 'lib/chef') diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb index 7862d9c160..6e7ff2e24a 100644 --- a/lib/chef/exceptions.rb +++ b/lib/chef/exceptions.rb @@ -105,7 +105,7 @@ class Chef class VerificationNotFound < RuntimeError; end class InvalidEventType < ArgumentError; end class MultipleIdentityError < RuntimeError; end - # Used in Resource::ActionProvider#load_current_resource to denote that + # Used in Resource::ActionClass#load_current_resource to denote that # the resource doesn't actually exist (for example, the file does not exist) class CurrentValueDoesNotExist < RuntimeError; end diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb index 5c230ad2f4..6c2f91ed8b 100644 --- a/lib/chef/resource.rb +++ b/lib/chef/resource.rb @@ -29,7 +29,7 @@ require 'chef/mixin/convert_to_class_name' require 'chef/guard_interpreter/resource_guard_interpreter' require 'chef/resource/conditional' require 'chef/resource/conditional_action_not_nothing' -require 'chef/resource/action_provider' +require 'chef/resource/action_class' require 'chef/resource_collection' require 'chef/node_map' require 'chef/node' @@ -688,7 +688,7 @@ class Chef # The provider class for this resource. # # If `action :x do ... end` has been declared on this resource or its - # superclasses, this will return the `action_provider_class`. + # superclasses, this will return the `action_class`. # # If this is not set, `provider_for_action` will dynamically determine the # provider. @@ -699,7 +699,7 @@ class Chef # # @return The provider class for this resource. # - # @see Chef::Resource.action_provider_class + # @see Chef::Resource.action_class # def provider(arg=nil) klass = if arg.kind_of?(String) || arg.kind_of?(Symbol) @@ -708,7 +708,7 @@ class Chef arg end set_or_return(:provider, klass, kind_of: [ Class ]) || - self.class.action_provider_class + self.class.action_class end def provider=(arg) provider(arg) @@ -1372,7 +1372,8 @@ class Chef # def self.action(action, &recipe_block) action = action.to_sym - new_action_provider_class.action(action, &recipe_block) + declare_action_class + action_class.action(action, &recipe_block) self.allowed_actions += [ action ] default_action action if Array(default_action) == [:nothing] end @@ -1416,7 +1417,7 @@ class Chef end # - # The action provider class is an automatic `Provider` created to handle + # The action class is an automatic `Provider` created to handle # actions declared by `action :x do ... end`. # # This class will be returned by `resource.provider` if `resource.provider` @@ -1425,40 +1426,38 @@ class Chef # # If the user has not declared actions on this class or its superclasses # using `action :x do ... end`, then there is no need for this class and - # `action_provider_class` will be `nil`. + # `action_class` will be `nil`. # # @api private # - def self.action_provider_class - @action_provider_class || + def self.action_class + @action_class || # If the superclass needed one, then we need one as well. - if superclass.respond_to?(:action_provider_class) && superclass.action_provider_class - new_action_provider_class + if superclass.respond_to?(:action_class) && superclass.action_class + declare_action_class end end # - # Ensure the action provider class actually gets created. This is called + # Ensure the action class actually gets created. This is called # when the user does `action :x do ... end`. # + # If a block is passed, it is run inside the action_class. + # # @api private - def self.new_action_provider_class - return @action_provider_class if @action_provider_class + def self.declare_action_class + return @action_class if @action_class - if superclass.respond_to?(:action_provider_class) - base_provider = superclass.action_provider_class + if superclass.respond_to?(:action_class) + base_provider = superclass.action_class end base_provider ||= Chef::Provider resource_class = self - @action_provider_class = Class.new(base_provider) do - include ActionProvider - define_singleton_method(:to_s) { "#{resource_class} action provider" } - def self.inspect - to_s - end + @action_class = Class.new(base_provider) do + include ActionClass + self.resource_class = resource_class end - @action_provider_class end # diff --git a/lib/chef/resource/action_class.rb b/lib/chef/resource/action_class.rb new file mode 100644 index 0000000000..12211418e9 --- /dev/null +++ b/lib/chef/resource/action_class.rb @@ -0,0 +1,83 @@ +# +# Author:: John Keiser ( 0 + current_resource.load_current_value!(new_resource) + else + current_resource.load_current_value! + end + rescue Chef::Exceptions::CurrentValueDoesNotExist + current_resource = nil + end + end + + @current_resource = current_resource + end + + def self.included(other) + other.extend(ClassMethods) + other.use_inline_resources + other.include_resource_dsl true + end + + module ClassMethods + # + # The Chef::Resource class this ActionClass was declared against. + # + # @return [Class] The Chef::Resource class this ActionClass was declared against. + # + attr_accessor :resource_class + + def to_s + "#{resource_class} action provider" + end + + def inspect + to_s + end + end + end + end +end diff --git a/lib/chef/resource/action_provider.rb b/lib/chef/resource/action_provider.rb deleted file mode 100644 index d71b54ef4d..0000000000 --- a/lib/chef/resource/action_provider.rb +++ /dev/null @@ -1,69 +0,0 @@ -# -# Author:: John Keiser ( 0 - current_resource.load_current_value!(new_resource) - else - current_resource.load_current_value! - end - rescue Chef::Exceptions::CurrentValueDoesNotExist - current_resource = nil - end - end - - @current_resource = current_resource - end - - def self.included(other) - other.extend(ClassMethods) - other.use_inline_resources - other.include_resource_dsl true - end - - module ClassMethods - end - end - end -end -- cgit v1.2.1 From 9efa0d89d2c344c1b383626ad6ffc56169bde5c9 Mon Sep 17 00:00:00 2001 From: Salim Alam Date: Thu, 17 Sep 2015 18:53:09 -0700 Subject: Lazy load MSI provider, add check for MSI support --- lib/chef/platform/query_helpers.rb | 16 ++++++++++++++++ lib/chef/provider/package/windows/msi.rb | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/platform/query_helpers.rb b/lib/chef/platform/query_helpers.rb index 9ba8d2261d..dfb99ed750 100644 --- a/lib/chef/platform/query_helpers.rb +++ b/lib/chef/platform/query_helpers.rb @@ -58,6 +58,22 @@ class Chef return nano == 1 end + def supports_msi? + return false unless windows? + require 'win32/registry' + + key = "System\\CurrentControlSet\\Services\\msiserver" + access = ::Win32::Registry::KEY_QUERY_VALUE + + begin + ::Win32::Registry::HKEY_LOCAL_MACHINE.open(key, access) do |reg| + true + end + rescue ::Win32::Registry::Error + false + end + end + def supports_powershell_execution_bypass?(node) node[:languages] && node[:languages][:powershell] && node[:languages][:powershell][:version].to_i >= 3 diff --git a/lib/chef/provider/package/windows/msi.rb b/lib/chef/provider/package/windows/msi.rb index 31faa78215..7fdbbcff35 100644 --- a/lib/chef/provider/package/windows/msi.rb +++ b/lib/chef/provider/package/windows/msi.rb @@ -18,7 +18,7 @@ # TODO: Allow @new_resource.source to be a Product Code as a GUID for uninstall / network install -require 'chef/win32/api/installer' if RUBY_PLATFORM =~ /mswin|mingw32|windows/ +require 'chef/win32/api/installer' if (RUBY_PLATFORM =~ /mswin|mingw32|windows/) && Chef::Platform.supports_msi? require 'chef/mixin/shell_out' class Chef @@ -26,7 +26,7 @@ class Chef class Package class Windows class MSI - include Chef::ReservedNames::Win32::API::Installer if RUBY_PLATFORM =~ /mswin|mingw32|windows/ + include Chef::ReservedNames::Win32::API::Installer if (RUBY_PLATFORM =~ /mswin|mingw32|windows/) && Chef::Platform.supports_msi? include Chef::Mixin::ShellOut def initialize(resource) -- cgit v1.2.1 From d8f7ca4d08f00db96fbf1e98a7f1ed763c7bab01 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Tue, 22 Sep 2015 22:15:19 -0700 Subject: Honor the ordering of whichever `name_attribute` or `default` comes first --- lib/chef/property.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'lib/chef') diff --git a/lib/chef/property.rb b/lib/chef/property.rb index 09198d90f1..5b6a969d5f 100644 --- a/lib/chef/property.rb +++ b/lib/chef/property.rb @@ -86,6 +86,21 @@ class Chef # def initialize(**options) options.each { |k,v| options[k.to_sym] = v if k.is_a?(String) } + # Only pick the first of :default, :name_property and :name_attribute if + # more than one is specified. + found_default = false + options.reject! do |k,v| + if [ :name_property, :name_attribute, :default ].include?(k) + if found_default + true + else + found_default = true + false + end + else + false + end + end options[:name_property] = options.delete(:name_attribute) if options.has_key?(:name_attribute) && !options.has_key?(:name_property) @options = options -- cgit v1.2.1 From 71fc5c5650f8bd3ec819087d6a5ca7f4eaeb1158 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Tue, 22 Sep 2015 22:39:41 -0700 Subject: Add deprecation warning for properties that specify default and name_property --- lib/chef/property.rb | 16 +++++++++------- lib/chef/resource.rb | 2 ++ 2 files changed, 11 insertions(+), 7 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/property.rb b/lib/chef/property.rb index 5b6a969d5f..7f42616bdd 100644 --- a/lib/chef/property.rb +++ b/lib/chef/property.rb @@ -86,22 +86,24 @@ class Chef # def initialize(**options) options.each { |k,v| options[k.to_sym] = v if k.is_a?(String) } + # Only pick the first of :default, :name_property and :name_attribute if # more than one is specified. - found_default = false + found_defaults = [] options.reject! do |k,v| if [ :name_property, :name_attribute, :default ].include?(k) - if found_default - true - else - found_default = true - false - end + found_defaults << k + # Reject all but the first default key you find + found_defaults.size > 1 else false end end + if found_defaults.size > 1 + Chef::Log.deprecation("Cannot specify keys #{found_defaults.join(", ")} together on property #{options[:name]}--only the first one (#{found_defaults[0]}) will be obeyed. Please pick one.", caller(5..5)[0]) + end options[:name_property] = options.delete(:name_attribute) if options.has_key?(:name_attribute) && !options.has_key?(:name_property) + @options = options options[:name] = options[:name].to_sym if options[:name] diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb index 6c2f91ed8b..9e40fdccfd 100644 --- a/lib/chef/resource.rb +++ b/lib/chef/resource.rb @@ -782,6 +782,8 @@ class Chef def self.property(name, type=NOT_PASSED, **options) name = name.to_sym + options.each { |k,v| options[k.to_sym] = v if k.is_a?(String) } + options[:instance_variable_name] = :"@#{name}" if !options.has_key?(:instance_variable_name) options.merge!(name: name, declared_in: self) -- cgit v1.2.1 From efe6286540a56960e109dcc65db63cc7461c1753 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Wed, 23 Sep 2015 12:48:31 -0700 Subject: Re-upgrade chef-zero to latest --- lib/chef/chef_fs/data_handler/client_data_handler.rb | 4 +++- lib/chef/chef_fs/file_system/chef_server_root_dir.rb | 3 ++- lib/chef/chef_fs/file_system/organization_members_entry.rb | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/chef_fs/data_handler/client_data_handler.rb b/lib/chef/chef_fs/data_handler/client_data_handler.rb index d81f35e861..5bcbd4e373 100644 --- a/lib/chef/chef_fs/data_handler/client_data_handler.rb +++ b/lib/chef/chef_fs/data_handler/client_data_handler.rb @@ -13,11 +13,13 @@ class Chef 'validator' => false, 'chef_type' => 'client' } + # Handle the fact that admin/validator have changed type from string -> boolean + client['admin'] = (client['admin'] == 'true') if client['admin'].is_a?(String) + client['validator'] = (client['validator'] == 'true') if client['validator'].is_a?(String) if entry.respond_to?(:org) && entry.org defaults['orgname'] = entry.org end result = normalize_hash(client, defaults) - # You can NOT send json_class, or it will fail result.delete('json_class') result end diff --git a/lib/chef/chef_fs/file_system/chef_server_root_dir.rb b/lib/chef/chef_fs/file_system/chef_server_root_dir.rb index e3ffd644ad..a243e0ae6b 100644 --- a/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +++ b/lib/chef/chef_fs/file_system/chef_server_root_dir.rb @@ -120,7 +120,8 @@ class Chef if File.dirname(path) == '/organizations' File.basename(path) else - nil + # In Chef 12, everything is in an org. + 'chef' end end end diff --git a/lib/chef/chef_fs/file_system/organization_members_entry.rb b/lib/chef/chef_fs/file_system/organization_members_entry.rb index 94393b341f..40042a9cbc 100644 --- a/lib/chef/chef_fs/file_system/organization_members_entry.rb +++ b/lib/chef/chef_fs/file_system/organization_members_entry.rb @@ -39,9 +39,9 @@ class Chef members = minimize_value(_read_json) (desired_members - members).each do |member| begin - rest.post(File.join(api_path, member), {}) + rest.post(api_path, 'username' => member) rescue Net::HTTPServerException => e - if e.response.code == '404' + if %w(404 405).include?(e.response.code) raise "Chef server at #{api_path} does not allow you to directly add members. Please either upgrade your Chef server or move the users you want into invitations.json instead of members.json." else raise -- cgit v1.2.1 From e92665d448eaaf92fdfb5bb3cdb4be3a2ddad9ac Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Tue, 22 Sep 2015 15:40:34 -0700 Subject: Add policyfile support to bootstrap context --- lib/chef/knife/core/bootstrap_context.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/core/bootstrap_context.rb b/lib/chef/knife/core/bootstrap_context.rb index 867b6fe366..d85ee91490 100644 --- a/lib/chef/knife/core/bootstrap_context.rb +++ b/lib/chef/knife/core/bootstrap_context.rb @@ -164,7 +164,12 @@ CONFIG def first_boot (@config[:first_boot_attributes] || {}).tap do |attributes| - attributes.merge!(:run_list => @run_list) + if @config[:policy_name] && @config[:policy_group] + attributes.merge!(:policy_name => @config[:policy_name], :policy_group => @config[:policy_group]) + else + attributes.merge!(:run_list => @run_list) + end + attributes.merge!(:tags => @config[:tags]) if @config[:tags] && !@config[:tags].empty? end end -- cgit v1.2.1 From 4141c33df8e31b78359fb316315547d36f837df6 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Tue, 22 Sep 2015 17:22:32 -0700 Subject: Add --policy-name and --policy-group opts to knife bootstrap --- lib/chef/knife/bootstrap.rb | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'lib/chef') diff --git a/lib/chef/knife/bootstrap.rb b/lib/chef/knife/bootstrap.rb index f173b6b909..93236225a2 100644 --- a/lib/chef/knife/bootstrap.rb +++ b/lib/chef/knife/bootstrap.rb @@ -143,6 +143,16 @@ class Chef :proc => lambda { |o| o.split(/[\s,]+/) }, :default => [] + option :policy_name, + :long => "--policy-name POLICY_NAME", + :description => "Policyfile name to use (--policy-group must also be given)", + :default => nil + + option :policy_group, + :long => "--policy-group POLICY_GROUP", + :description => "Policy group name to use (--policy-name must also be given)", + :default => nil + option :tags, :long => "--tags TAGS", :description => "Comma separated list of tags to apply to the node", @@ -315,6 +325,7 @@ class Chef def run validate_name_args! + validate_options! $stdout.sync = true @@ -363,6 +374,17 @@ class Chef end end + def validate_options! + if incomplete_policyfile_options? + ui.error("--policy-name and --policy-group must be specified together") + exit 1 + elsif policyfile_and_run_list_given? + ui.error("Policyfile options and --run-list are exclusive") + exit 1 + end + true + end + def knife_ssh ssh = Chef::Knife::Ssh.new ssh.ui = ui @@ -395,6 +417,19 @@ class Chef command end + + private + + # True if policy_name and run_list are both given + def policyfile_and_run_list_given? + !config[:run_list].empty? && !!config[:policy_name] + end + + # True if one of policy_name or policy_group was given, but not both + def incomplete_policyfile_options? + (!!config[:policy_name] ^ config[:policy_group]) + end + end end end -- cgit v1.2.1 From 14d7baab6365e0b4146990a5306f80a7f0d09a82 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Wed, 23 Sep 2015 12:50:54 -0700 Subject: Don't pass -E to chef-client unless given an environment Chef::PolicyBuilder::Policyfile requires `Chef::Config[:environment]` to be nil or empty, in order to prevent confusion that could arise from using two conflicting features. Because `chef-client` merges CLI options to `Chef::Config` automatically, running `chef-cient -E _default` causes `Chef::Config[:environment]` to be non-nil, resulting in chef-client emitting this error when bootstrapping: ``` 192.168.99.143 Unexpected Error: 192.168.99.143 ----------------- 192.168.99.143 Chef::PolicyBuilder::Policyfile::UnsupportedFeature: Policyfile does not work with Chef Environments ``` For non-policyfile users, this should behave the same as before since Chef will just default to the `_default` environment (this gets set via Node#initialize) if none is specified. --- lib/chef/knife/core/bootstrap_context.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/core/bootstrap_context.rb b/lib/chef/knife/core/bootstrap_context.rb index d85ee91490..d210b9418f 100644 --- a/lib/chef/knife/core/bootstrap_context.rb +++ b/lib/chef/knife/core/bootstrap_context.rb @@ -40,7 +40,7 @@ class Chef end def bootstrap_environment - @chef_config[:environment] || '_default' + @chef_config[:environment] end def validation_key @@ -128,7 +128,7 @@ CONFIG client_path = @chef_config[:chef_client_path] || 'chef-client' s = "#{client_path} -j /etc/chef/first-boot.json" s << ' -l debug' if @config[:verbosity] and @config[:verbosity] >= 2 - s << " -E #{bootstrap_environment}" + s << " -E #{bootstrap_environment}" unless bootstrap_environment.nil? s end -- cgit v1.2.1 From 33509c1bbb7366d3e2a50f61d8d53161e51eb6fa Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Thu, 24 Sep 2015 10:08:59 -0700 Subject: Add policyfile attributes to client builder --- lib/chef/knife/bootstrap/client_builder.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'lib/chef') diff --git a/lib/chef/knife/bootstrap/client_builder.rb b/lib/chef/knife/bootstrap/client_builder.rb index 59b0cabd49..7eb1e22628 100644 --- a/lib/chef/knife/bootstrap/client_builder.rb +++ b/lib/chef/knife/bootstrap/client_builder.rb @@ -91,6 +91,16 @@ class Chef knife_config[:run_list] end + # @return [String] policy_name from the knife_config + def policy_name + knife_config[:policy_name] + end + + # @return [String] policy_group from the knife_config + def policy_group + knife_config[:policy_group] + end + # @return [Hash,Array] Object representation of json first-boot attributes from the knife_config def first_boot_attributes knife_config[:first_boot_attributes] @@ -141,6 +151,8 @@ class Chef node.run_list(normalized_run_list) node.normal_attrs = first_boot_attributes if first_boot_attributes node.environment(environment) if environment + node.policy_name = policy_name if policy_name + node.policy_group = policy_group if policy_group (knife_config[:tags] || []).each do |tag| node.tags << tag end -- cgit v1.2.1 From 37df1cf0bcc8405ba9d01245dd8cf6ebcceb426b Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Thu, 24 Sep 2015 13:28:34 -0700 Subject: Remove experimental feature warning for policyfiles Also, improve the language around unsupported features/options. --- lib/chef/policy_builder/policyfile.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/policy_builder/policyfile.rb b/lib/chef/policy_builder/policyfile.rb index bb9593eb36..d6dcdf67b2 100644 --- a/lib/chef/policy_builder/policyfile.rb +++ b/lib/chef/policy_builder/policyfile.rb @@ -68,22 +68,20 @@ class Chef @node = nil - Chef::Log.warn("Using experimental Policyfile feature") - if Chef::Config[:solo] - raise UnsupportedFeature, "Policyfile does not support chef-solo at this time." + raise UnsupportedFeature, "Policyfile does not support chef-solo. Use chef-client local mode instead." end if override_runlist - raise UnsupportedFeature, "Policyfile does not support override run lists at this time" + raise UnsupportedFeature, "Policyfile does not support override run lists. Use named run_lists instead." end if json_attribs && json_attribs.key?("run_list") - raise UnsupportedFeature, "Policyfile does not support setting the run_list in json data at this time" + raise UnsupportedFeature, "Policyfile does not support setting the run_list in json data." end if Chef::Config[:environment] && !Chef::Config[:environment].chomp.empty? - raise UnsupportedFeature, "Policyfile does not work with Chef Environments" + raise UnsupportedFeature, "Policyfile does not work with Chef Environments." end end -- cgit v1.2.1 From c576de210dc42889d796074187a109a8d0dd6a19 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Thu, 24 Sep 2015 18:19:33 -0700 Subject: Prefer name_property: true over default: nil --- lib/chef/property.rb | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/property.rb b/lib/chef/property.rb index 7f42616bdd..6c9d4619b1 100644 --- a/lib/chef/property.rb +++ b/lib/chef/property.rb @@ -89,18 +89,19 @@ class Chef # Only pick the first of :default, :name_property and :name_attribute if # more than one is specified. - found_defaults = [] - options.reject! do |k,v| - if [ :name_property, :name_attribute, :default ].include?(k) - found_defaults << k - # Reject all but the first default key you find - found_defaults.size > 1 - else - false - end - end + found_defaults = options.keys.select { |k| [ :default, :name_attribute, :name_property ].include?(k) } if found_defaults.size > 1 - Chef::Log.deprecation("Cannot specify keys #{found_defaults.join(", ")} together on property #{options[:name]}--only the first one (#{found_defaults[0]}) will be obeyed. Please pick one.", caller(5..5)[0]) + preferred_default = found_defaults[0] + # We do *not* prefer `default: nil` even if it's first, because earlier + # versions of Chef (backcompat) treat specifying something as `nil` the + # same as not specifying it at all. In Chef 13 we can switch this behavior + # back to normal, since only one default will be specifiable. + if preferred_default == :default && options[:default].nil? + preferred_default = found_defaults[1] + end + Chef::Log.deprecation("Cannot specify keys #{found_defaults.join(", ")} together on property #{options[:name]}--only one (#{preferred_default}) will be obeyed. In Chef 13, specifying multiple defaults will become an error.", caller(5..5)[0]) + # Only honor the preferred default + options.reject! { |k,v| found_defaults.include?(k) && k != preferred_default } end options[:name_property] = options.delete(:name_attribute) if options.has_key?(:name_attribute) && !options.has_key?(:name_property) -- cgit v1.2.1 From 424b2dda9b4a2a0ca3e7ca8c9a598643b303ec0f Mon Sep 17 00:00:00 2001 From: John Keiser Date: Fri, 25 Sep 2015 07:19:48 -0700 Subject: Find the spot the user called and use that as the deprecation location --- lib/chef/chef_class.rb | 13 ++++++++++++- lib/chef/cookbook_version.rb | 6 +++--- lib/chef/deprecation/provider/remote_directory.rb | 2 +- lib/chef/deprecation/warnings.rb | 2 +- lib/chef/formatters/base.rb | 2 +- lib/chef/resource/file/verification.rb | 3 +-- 6 files changed, 19 insertions(+), 9 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/chef_class.rb b/lib/chef/chef_class.rb index c2cb9e2b24..b18c3fbdde 100644 --- a/lib/chef/chef_class.rb +++ b/lib/chef/chef_class.rb @@ -204,7 +204,18 @@ class Chef # # @api private this will likely be removed in favor of an as-yet unwritten # `Chef.log` - def log_deprecation(message, location=caller(2..2)[0]) + def log_deprecation(message, location=nil) + if !location + # Pick the first caller that is *not* part of the Chef gem, that's the + # thing the user wrote. + chef_gem_path = File.expand_path("../..", __FILE__) + caller(0..10).each do |c| + if !c.start_with?(chef_gem_path) + location = c + break + end + end + end # `run_context.events` is the primary deprecation target if we're in a # run. If we are not yet in a run, print to `Chef::Log`. if run_context && run_context.events diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb index bff3146572..3cdfd8c10b 100644 --- a/lib/chef/cookbook_version.rb +++ b/lib/chef/cookbook_version.rb @@ -51,12 +51,12 @@ class Chef attr_accessor :metadata_filenames def status=(new_status) - Chef.log_deprecation("Deprecated method `status' called. This method will be removed.", caller(1..1)) + Chef.log_deprecation("Deprecated method `status' called. This method will be removed.") @status = new_status end def status - Chef.log_deprecation("Deprecated method `status' called. This method will be removed.", caller(1..1)) + Chef.log_deprecation("Deprecated method `status' called. This method will be removed.") @status end @@ -480,7 +480,7 @@ class Chef # @deprecated This method was used by the Ruby Chef Server and is no longer # needed. There is no replacement. def generate_manifest_with_urls(&url_generator) - Chef.log_deprecation("Deprecated method #generate_manifest_with_urls.", caller(1..1)) + Chef.log_deprecation("Deprecated method #generate_manifest_with_urls.") rendered_manifest = manifest.dup COOKBOOK_SEGMENTS.each do |segment| diff --git a/lib/chef/deprecation/provider/remote_directory.rb b/lib/chef/deprecation/provider/remote_directory.rb index b55a304696..cc8026ec55 100644 --- a/lib/chef/deprecation/provider/remote_directory.rb +++ b/lib/chef/deprecation/provider/remote_directory.rb @@ -22,7 +22,7 @@ class Chef module RemoteDirectory def directory_root_in_cookbook_cache - Chef::Log.deprecation "the Chef::Provider::RemoteDirectory#directory_root_in_cookbook_cache method is deprecated" + Chef.log_deprecation "the Chef::Provider::RemoteDirectory#directory_root_in_cookbook_cache method is deprecated" @directory_root_in_cookbook_cache ||= begin diff --git a/lib/chef/deprecation/warnings.rb b/lib/chef/deprecation/warnings.rb index 376629710e..0b1ec2d5ed 100644 --- a/lib/chef/deprecation/warnings.rb +++ b/lib/chef/deprecation/warnings.rb @@ -27,7 +27,7 @@ class Chef message = [] message << "Method '#{name}' of '#{self.class}' is deprecated. It will be removed in Chef 13." message << "Please update your cookbooks accordingly." - Chef.log_deprecation(message, caller(0..3)) + Chef.log_deprecation(message) super(*args) end end diff --git a/lib/chef/formatters/base.rb b/lib/chef/formatters/base.rb index d3756ef00c..e4056a00fc 100644 --- a/lib/chef/formatters/base.rb +++ b/lib/chef/formatters/base.rb @@ -213,7 +213,7 @@ class Chef end def deprecation(message, location=caller(2..2)[0]) - Chef::Log.deprecation("#{message} at #{location}") + Chef.log_deprecation("#{message} at #{location}") end end diff --git a/lib/chef/resource/file/verification.rb b/lib/chef/resource/file/verification.rb index 9b0788fad3..ba0bb08201 100644 --- a/lib/chef/resource/file/verification.rb +++ b/lib/chef/resource/file/verification.rb @@ -110,8 +110,7 @@ class Chef # is interpolated. Until `file` can be deprecated, interpolate both. Chef.log_deprecation( '%{file} is deprecated in verify command and will not be '\ - 'supported in Chef 13. Please use %{path} instead.', - caller(2..2)[0] + 'supported in Chef 13. Please use %{path} instead.' ) if @command.include?('%{file}') command = @command % {:file => path, :path => path} interpreter = Chef::GuardInterpreter.for_resource(@parent_resource, command, @command_opts) -- cgit v1.2.1 From af422456552b8a64cb3ea90167a0f80f401790cf Mon Sep 17 00:00:00 2001 From: John Keiser Date: Fri, 25 Sep 2015 07:20:03 -0700 Subject: Fix up property deprecation text --- lib/chef/property.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/property.rb b/lib/chef/property.rb index 6c9d4619b1..011ff93aef 100644 --- a/lib/chef/property.rb +++ b/lib/chef/property.rb @@ -99,7 +99,7 @@ class Chef if preferred_default == :default && options[:default].nil? preferred_default = found_defaults[1] end - Chef::Log.deprecation("Cannot specify keys #{found_defaults.join(", ")} together on property #{options[:name]}--only one (#{preferred_default}) will be obeyed. In Chef 13, specifying multiple defaults will become an error.", caller(5..5)[0]) + Chef.log_deprecation("Cannot specify keys #{found_defaults.join(", ")} together on property #{options[:name]}#{options[:resource_class] ? " of resource #{options[:resource_class].resource_name}" : ""}. Only one (#{preferred_default}) will be obeyed. In Chef 13, specifying multiple defaults will become an error.") # Only honor the preferred default options.reject! { |k,v| found_defaults.include?(k) && k != preferred_default } end -- cgit v1.2.1 From ff54a6dd7ef781f242f1ab5b513f90a76902f5b8 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Fri, 25 Sep 2015 12:21:50 -0700 Subject: Don't treat name_property/attribute as defaults if they are false --- lib/chef/property.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/property.rb b/lib/chef/property.rb index 011ff93aef..d699f16a9d 100644 --- a/lib/chef/property.rb +++ b/lib/chef/property.rb @@ -89,7 +89,11 @@ class Chef # Only pick the first of :default, :name_property and :name_attribute if # more than one is specified. - found_defaults = options.keys.select { |k| [ :default, :name_attribute, :name_property ].include?(k) } + found_defaults = options.keys.select do |k| + # Only treat name_property or name_attribute as a default if they are `true` + k == :default || + ((k == :name_property || k == :name_attribute) && options[k]) + end if found_defaults.size > 1 preferred_default = found_defaults[0] # We do *not* prefer `default: nil` even if it's first, because earlier -- cgit v1.2.1 From 2c083878547343a4ed423e7d20ecbf6059285721 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Fri, 25 Sep 2015 13:10:58 -0700 Subject: If both name_attribute and name_property are specified, raise an error. --- lib/chef/property.rb | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/property.rb b/lib/chef/property.rb index d699f16a9d..f6160d6954 100644 --- a/lib/chef/property.rb +++ b/lib/chef/property.rb @@ -87,27 +87,28 @@ class Chef def initialize(**options) options.each { |k,v| options[k.to_sym] = v if k.is_a?(String) } + # Replace name_attribute with name_property + if options.has_key?(:name_attribute) + # If we have both name_attribute and name_property and they differ, raise an error + if options.has_key?(:name_property) + raise ArgumentError, "Cannot specify both name_property and name_attribute together on property #{options[:name]}#{options[:declared_in] ? " of resource #{options[:declared_in].resource_name}" : ""}." + end + # replace name_property with name_attribute in place + options = options.map { |k,v| k == :name_attribute ? [ :name_property, v ] : [ k,v ] }.to_h + end + # Only pick the first of :default, :name_property and :name_attribute if # more than one is specified. - found_defaults = options.keys.select do |k| - # Only treat name_property or name_attribute as a default if they are `true` - k == :default || - ((k == :name_property || k == :name_attribute) && options[k]) - end - if found_defaults.size > 1 - preferred_default = found_defaults[0] - # We do *not* prefer `default: nil` even if it's first, because earlier - # versions of Chef (backcompat) treat specifying something as `nil` the - # same as not specifying it at all. In Chef 13 we can switch this behavior - # back to normal, since only one default will be specifiable. - if preferred_default == :default && options[:default].nil? - preferred_default = found_defaults[1] + if options.has_key?(:default) && options[:name_property] + if options[:default].nil? || options.keys.index(:name_property) < options.keys.index(:default) + options.delete(:default) + preferred_default = :name_property + else + options.delete(:name_property) + preferred_default = :default end - Chef.log_deprecation("Cannot specify keys #{found_defaults.join(", ")} together on property #{options[:name]}#{options[:resource_class] ? " of resource #{options[:resource_class].resource_name}" : ""}. Only one (#{preferred_default}) will be obeyed. In Chef 13, specifying multiple defaults will become an error.") - # Only honor the preferred default - options.reject! { |k,v| found_defaults.include?(k) && k != preferred_default } + Chef.log_deprecation("Cannot specify both default and name_property together on property #{options[:name]}#{options[:declared_in] ? " of resource #{options[:declared_in].resource_name}" : ""}. Only one (#{preferred_default}) will be obeyed. In Chef 13, this will become an error.") end - options[:name_property] = options.delete(:name_attribute) if options.has_key?(:name_attribute) && !options.has_key?(:name_property) @options = options @@ -446,10 +447,10 @@ class Chef EOM rescue SyntaxError # If the name is not a valid ruby name, we use define_method. - resource_class.define_method(name) do |value=NOT_PASSED| + declared_in.define_method(name) do |value=NOT_PASSED| self.class.properties[name].call(self, value) end - resource_class.define_method("#{name}=") do |value| + declared_in.define_method("#{name}=") do |value| self.class.properties[name].set(self, value) end end -- cgit v1.2.1 From 47fe94f8fafab031065dfe8f46dbbb4b3f90ce47 Mon Sep 17 00:00:00 2001 From: Noah Kantrowitz Date: Fri, 25 Sep 2015 16:05:06 -0700 Subject: I think this was a bad search-and-replace, causes an infinite loop. --- lib/chef/formatters/base.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/formatters/base.rb b/lib/chef/formatters/base.rb index e4056a00fc..d3756ef00c 100644 --- a/lib/chef/formatters/base.rb +++ b/lib/chef/formatters/base.rb @@ -213,7 +213,7 @@ class Chef end def deprecation(message, location=caller(2..2)[0]) - Chef.log_deprecation("#{message} at #{location}") + Chef::Log.deprecation("#{message} at #{location}") end end -- cgit v1.2.1 From cf5e1d000979b9f0004eea4020c8d1d375b4a4c0 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Fri, 25 Sep 2015 16:26:10 -0700 Subject: Use 2.0-compatible Hash rather than to_h --- lib/chef/property.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/property.rb b/lib/chef/property.rb index f6160d6954..2b151b350a 100644 --- a/lib/chef/property.rb +++ b/lib/chef/property.rb @@ -94,7 +94,7 @@ class Chef raise ArgumentError, "Cannot specify both name_property and name_attribute together on property #{options[:name]}#{options[:declared_in] ? " of resource #{options[:declared_in].resource_name}" : ""}." end # replace name_property with name_attribute in place - options = options.map { |k,v| k == :name_attribute ? [ :name_property, v ] : [ k,v ] }.to_h + options = Hash[options.map { |k,v| k == :name_attribute ? [ :name_property, v ] : [ k,v ] }] end # Only pick the first of :default, :name_property and :name_attribute if -- cgit v1.2.1 From 42446f98101eb9ebb80030c63704879539d320df Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Sat, 26 Sep 2015 19:27:20 -0700 Subject: Bootstrap doc doesnt match reality The other scripts are gone. Also update the URLs --- lib/chef/knife/bootstrap/templates/README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/bootstrap/templates/README.md b/lib/chef/knife/bootstrap/templates/README.md index 13a0fe7ada..538d38d0b6 100644 --- a/lib/chef/knife/bootstrap/templates/README.md +++ b/lib/chef/knife/bootstrap/templates/README.md @@ -1,12 +1,11 @@ This directory contains bootstrap templates which can be used with the -d flag to 'knife bootstrap' to install Chef in different ways. To simplify installation, and reduce the matrix of common installation patterns to support, we have -standardized on the [Omnibus](https://github.com/opscode/omnibus-ruby) built installation +standardized on the [Omnibus](https://github.com/chef/omnibus) built installation packages. The 'chef-full' template downloads a script which is used to determine the correct -Omnibus package for this system from the [Omnitruck](https://github.com/opscode/opscode-omnitruck) API. All other templates in this directory are deprecated and will be removed -in the future. +Omnibus package for this system from the [Omnitruck](https://github.com/chef/omnitruck) API. You can still utilize custom bootstrap templates on your system if your installation -needs are unique. Additional information can be found on the [docs site](http://docs.opscode.com/knife_bootstrap.html#custom-templates). \ No newline at end of file +needs are unique. Additional information can be found on the [docs site](https://docs.chef.io/knife_bootstrap.html#custom-templates). -- cgit v1.2.1 From abe044cfdf4ae4a2468bc61aaeeba8c6cfaf39ae Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Sat, 26 Sep 2015 23:29:24 -0700 Subject: Copyright doesn't need to be capitalized --- lib/chef/knife/cookbook_create.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/cookbook_create.rb b/lib/chef/knife/cookbook_create.rb index e17a54079f..97f6e65d3c 100644 --- a/lib/chef/knife/cookbook_create.rb +++ b/lib/chef/knife/cookbook_create.rb @@ -48,7 +48,7 @@ class Chef option :cookbook_copyright, :short => "-C COPYRIGHT", :long => "--copyright COPYRIGHT", - :description => "Name of Copyright holder" + :description => "Name of copyright holder" option :cookbook_email, :short => "-m EMAIL", -- cgit v1.2.1 From 655189ad40cc2ff44795d473c60bb819805ef4d0 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Sat, 26 Sep 2015 23:29:55 -0700 Subject: Fix error message to mention Supermarket not community site Also Supermarket doesn't have a capital M --- lib/chef/knife/cookbook_site_share.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/cookbook_site_share.rb b/lib/chef/knife/cookbook_site_share.rb index efd2e7f129..5784c3d73e 100644 --- a/lib/chef/knife/cookbook_site_share.rb +++ b/lib/chef/knife/cookbook_site_share.rb @@ -48,7 +48,7 @@ class Chef :short => '-n', :boolean => true, :default => false, - :description => "Don't take action, only print what files will be upload to SuperMarket." + :description => "Don't take action, only print what files will be upload to Supermarket." def run config[:cookbook_path] ||= Chef::Config[:cookbook_path] @@ -94,7 +94,7 @@ class Chef Chef::Log.debug("Removing local staging directory at #{tmp_cookbook_dir}") FileUtils.rm_rf tmp_cookbook_dir rescue => e - ui.error("Error uploading cookbook #{cookbook_name} to the Opscode Cookbook Site: #{e.message}. Increase log verbosity (-VV) for more information.") + ui.error("Error uploading cookbook #{cookbook_name} to Supermarket: #{e.message}. Increase log verbosity (-VV) for more information.") Chef::Log.debug("\n#{e.backtrace.join("\n")}") exit(1) end -- cgit v1.2.1 From 28bb3f589e423f37d97294dfe607e45e8d79567d Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Sat, 26 Sep 2015 23:30:51 -0700 Subject: Capitalize first word in sentences --- lib/chef/knife/search.rb | 4 ++-- lib/chef/knife/ssh.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/search.rb b/lib/chef/knife/search.rb index 2b0c79ff6c..014fc8dd87 100644 --- a/lib/chef/knife/search.rb +++ b/lib/chef/knife/search.rb @@ -136,7 +136,7 @@ class Chef def read_cli_args if config[:query] if @name_args[1] - ui.error "please specify query as an argument or an option via -q, not both" + ui.error "Please specify query as an argument or an option via -q, not both" ui.msg opt_parser exit 1 end @@ -145,7 +145,7 @@ class Chef else case name_args.size when 0 - ui.error "no query specified" + ui.error "No query specified" ui.msg opt_parser exit 1 when 1 diff --git a/lib/chef/knife/ssh.rb b/lib/chef/knife/ssh.rb index bb3d9d78bb..62af853e88 100644 --- a/lib/chef/knife/ssh.rb +++ b/lib/chef/knife/ssh.rb @@ -425,7 +425,7 @@ class Chef begin require 'appscript' rescue LoadError - STDERR.puts "you need the rb-appscript gem to use knife ssh macterm. `(sudo) gem install rb-appscript` to install" + STDERR.puts "You need the rb-appscript gem to use knife ssh macterm. `(sudo) gem install rb-appscript` to install" raise end -- cgit v1.2.1 From def9260537b44c4c96c4323ced46d12b300e8b74 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Sat, 26 Sep 2015 23:33:56 -0700 Subject: Fix tense --- lib/chef/knife/cookbook_site_share.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/cookbook_site_share.rb b/lib/chef/knife/cookbook_site_share.rb index 5784c3d73e..8f4cf3a5b3 100644 --- a/lib/chef/knife/cookbook_site_share.rb +++ b/lib/chef/knife/cookbook_site_share.rb @@ -48,7 +48,7 @@ class Chef :short => '-n', :boolean => true, :default => false, - :description => "Don't take action, only print what files will be upload to Supermarket." + :description => "Don't take action, only print what files will be uploaded to Supermarket." def run config[:cookbook_path] ||= Chef::Config[:cookbook_path] -- cgit v1.2.1 From d3b7dd925597dbeedafb2e65b1fd10ffc5b60d22 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Sat, 26 Sep 2015 23:47:05 -0700 Subject: More Community site -> Supermarket --- lib/chef/knife/cookbook_site_share.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/cookbook_site_share.rb b/lib/chef/knife/cookbook_site_share.rb index 8f4cf3a5b3..b0f7f50e4d 100644 --- a/lib/chef/knife/cookbook_site_share.rb +++ b/lib/chef/knife/cookbook_site_share.rb @@ -108,15 +108,15 @@ class Chef def get_category(cookbook_name) begin - data = noauth_rest.get_rest("http://cookbooks.opscode.com/api/v1/cookbooks/#{@name_args[0]}") + data = noauth_rest.get_rest("https://supermarket.chef.io/api/v1/cookbooks/#{@name_args[0]}") if !data["category"] && data["error_code"] - ui.fatal("Received an error from the Opscode Cookbook site: #{data["error_code"]}. On the first time you upload it, you are required to specify the category you want to share this cookbook to.") + ui.fatal("Received an error from the Supermarket site: #{data["error_code"]}. On the first time you upload it, you are required to specify the category you want to share this cookbook to.") exit(1) else data['category'] end rescue => e - ui.fatal("Unable to reach Opscode Cookbook Site: #{e.message}. Increase log verbosity (-VV) for more information.") + ui.fatal("Unable to reach Supermarket site: #{e.message}. Increase log verbosity (-VV) for more information.") Chef::Log.debug("\n#{e.backtrace.join("\n")}") exit(1) end @@ -136,7 +136,7 @@ class Chef if http_resp.code.to_i != 201 if res['error_messages'] if res['error_messages'][0] =~ /Version already exists/ - ui.error "The same version of this cookbook already exists on the Opscode Cookbook Site." + ui.error "The same version of this cookbook already exists on Supermarket." exit(1) else ui.error "#{res['error_messages'][0]}" -- cgit v1.2.1 From 3968f4402d03822051169056138b769508e85c17 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Sun, 27 Sep 2015 11:44:06 -0700 Subject: Supermarket vs. the Supermarket Judging by our docs is seems we're just calling it Supermarket not the Supermarket or the Supermarket site. Lets be consistent here --- lib/chef/knife/cookbook_site_download.rb | 2 +- lib/chef/knife/cookbook_site_share.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/cookbook_site_download.rb b/lib/chef/knife/cookbook_site_download.rb index c2d72ef8da..3e586e6542 100644 --- a/lib/chef/knife/cookbook_site_download.rb +++ b/lib/chef/knife/cookbook_site_download.rb @@ -84,7 +84,7 @@ class Chef end def download_cookbook - ui.info "Downloading #{@name_args[0]} from the cookbooks site at version #{version} to #{download_location}" + ui.info "Downloading #{@name_args[0]} from Supermarket at version #{version} to #{download_location}" noauth_rest.sign_on_redirect = false tf = noauth_rest.get_rest desired_cookbook_data["file"], true diff --git a/lib/chef/knife/cookbook_site_share.rb b/lib/chef/knife/cookbook_site_share.rb index b0f7f50e4d..beb98b71b8 100644 --- a/lib/chef/knife/cookbook_site_share.rb +++ b/lib/chef/knife/cookbook_site_share.rb @@ -110,13 +110,13 @@ class Chef begin data = noauth_rest.get_rest("https://supermarket.chef.io/api/v1/cookbooks/#{@name_args[0]}") if !data["category"] && data["error_code"] - ui.fatal("Received an error from the Supermarket site: #{data["error_code"]}. On the first time you upload it, you are required to specify the category you want to share this cookbook to.") + ui.fatal("Received an error from Supermarket: #{data["error_code"]}. On the first time you upload it, you are required to specify the category you want to share this cookbook to.") exit(1) else data['category'] end rescue => e - ui.fatal("Unable to reach Supermarket site: #{e.message}. Increase log verbosity (-VV) for more information.") + ui.fatal("Unable to reach Supermarket: #{e.message}. Increase log verbosity (-VV) for more information.") Chef::Log.debug("\n#{e.backtrace.join("\n")}") exit(1) end -- cgit v1.2.1 From dabb31a3586a7ec6409b0c054c842e97a4d3380b Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Sun, 27 Sep 2015 11:44:16 -0700 Subject: Capitalize another message --- lib/chef/knife/cookbook_site_install.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/cookbook_site_install.rb b/lib/chef/knife/cookbook_site_install.rb index d0ab6da3ef..aee8b7fa94 100644 --- a/lib/chef/knife/cookbook_site_install.rb +++ b/lib/chef/knife/cookbook_site_install.rb @@ -93,7 +93,7 @@ class Chef # TODO: it'd be better to store these outside the cookbook repo and # keep them around, e.g., in ~/Library/Caches on OS X. - ui.info("removing downloaded tarball") + ui.info("Removing downloaded tarball") File.unlink(upstream_file) if @repo.finalize_updates_to(@cookbook_name, downloader.version) -- cgit v1.2.1 From f0976789c8e810e8e8cf938f950975affda73446 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Sun, 27 Sep 2015 12:18:50 -0700 Subject: Update more references from cookbooks -> supermarket --- lib/chef/cookbook_site_streaming_uploader.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/cookbook_site_streaming_uploader.rb b/lib/chef/cookbook_site_streaming_uploader.rb index 0302a51165..2be189e942 100644 --- a/lib/chef/cookbook_site_streaming_uploader.rb +++ b/lib/chef/cookbook_site_streaming_uploader.rb @@ -26,7 +26,7 @@ require 'openssl' class Chef # == Chef::CookbookSiteStreamingUploader # A streaming multipart HTTP upload implementation. Used to upload cookbooks - # (in tarball form) to http://cookbooks.opscode.com + # (in tarball form) to https://supermarket.chef.io # # inspired by http://stanislavvitvitskiy.blogspot.com/2008/12/multipart-post-in-ruby.html class CookbookSiteStreamingUploader -- cgit v1.2.1 From 876ea381ff7064250c57c563c8724ac1f99fbab5 Mon Sep 17 00:00:00 2001 From: andy-dufour Date: Tue, 22 Sep 2015 13:33:32 -0400 Subject: Fix for #3942 - change remote_directory resource file discovery to traverse breadth first --- lib/chef/provider/remote_directory.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/remote_directory.rb b/lib/chef/provider/remote_directory.rb index 56c2ff0caf..7549920c7a 100644 --- a/lib/chef/provider/remote_directory.rb +++ b/lib/chef/provider/remote_directory.rb @@ -161,7 +161,7 @@ class Chef def files_to_transfer cookbook = run_context.cookbook_collection[resource_cookbook] files = cookbook.relative_filenames_in_preferred_directory(node, :files, source) - files.sort!.reverse! + files.sort_by! { |x| x.split(::File::SEPARATOR).count } end # Either the explicit cookbook that the user sets on the resource, or the implicit -- cgit v1.2.1 From 88a197f61a1f3dde1d617bcc6fe08041388c7ea0 Mon Sep 17 00:00:00 2001 From: andy-dufour Date: Mon, 28 Sep 2015 13:16:21 -0400 Subject: Updating to use count instead of split to sort files in remote_directory --- lib/chef/provider/remote_directory.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/remote_directory.rb b/lib/chef/provider/remote_directory.rb index 7549920c7a..3c1c50b963 100644 --- a/lib/chef/provider/remote_directory.rb +++ b/lib/chef/provider/remote_directory.rb @@ -161,7 +161,7 @@ class Chef def files_to_transfer cookbook = run_context.cookbook_collection[resource_cookbook] files = cookbook.relative_filenames_in_preferred_directory(node, :files, source) - files.sort_by! { |x| x.split(::File::SEPARATOR).count } + files.sort_by! { |x| x.count(::File::SEPARATOR) } end # Either the explicit cookbook that the user sets on the resource, or the implicit -- cgit v1.2.1 From 857b159344ccbc07af06d45854eb8b2f6dc77d11 Mon Sep 17 00:00:00 2001 From: Ranjib Dey Date: Sun, 20 Sep 2015 20:52:56 -0700 Subject: return empty array if no services found --- lib/chef/platform/service_helpers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/platform/service_helpers.rb b/lib/chef/platform/service_helpers.rb index d50812e687..1523747023 100644 --- a/lib/chef/platform/service_helpers.rb +++ b/lib/chef/platform/service_helpers.rb @@ -126,7 +126,7 @@ class Chef # this splits off the suffix after the last dot to return "sshd" services += services.select {|s| s.match(/\.service$/) }.map { |s| s.sub(/(.*)\.service$/, '\1') } rescue Mixlib::ShellOut::ShellCommandFailed - false + [] end def platform_has_systemd_unit?(service_name) -- cgit v1.2.1 From 68656820438b84d433ae9015b953790f67ddf0ec Mon Sep 17 00:00:00 2001 From: John Keiser Date: Fri, 25 Sep 2015 19:04:28 -0700 Subject: Add system providers to the list of world-stubbed stuff --- lib/chef/platform/service_helpers.rb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/chef') diff --git a/lib/chef/platform/service_helpers.rb b/lib/chef/platform/service_helpers.rb index 1523747023..6b44478725 100644 --- a/lib/chef/platform/service_helpers.rb +++ b/lib/chef/platform/service_helpers.rb @@ -102,6 +102,11 @@ class Chef configs end + def reset + @service_resource_providers = nil + @systemctl_path = nil + end + private def systemctl_path -- cgit v1.2.1 From b8cffc2e35c662585acff290b27f072c60105479 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Fri, 25 Sep 2015 22:14:34 -0700 Subject: Add test for nonzero systemctl exit code --- lib/chef/chef_class.rb | 5 +++++ lib/chef/mixin/which.rb | 2 +- lib/chef/platform/service_helpers.rb | 23 ++++++++++++----------- 3 files changed, 18 insertions(+), 12 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/chef_class.rb b/lib/chef/chef_class.rb index b18c3fbdde..6a0d09ec96 100644 --- a/lib/chef/chef_class.rb +++ b/lib/chef/chef_class.rb @@ -226,5 +226,10 @@ class Chef end end + # @api private Only for test dependency injection; not evenly implemented as yet. + def self.path_to(path) + path + end + reset! end diff --git a/lib/chef/mixin/which.rb b/lib/chef/mixin/which.rb index 4179c97b62..4e1c516386 100644 --- a/lib/chef/mixin/which.rb +++ b/lib/chef/mixin/which.rb @@ -28,7 +28,7 @@ class Chef paths = ENV['PATH'].split(File::PATH_SEPARATOR) + extra_path paths.each do |path| filename = File.join(path, cmd) - return filename if File.executable?(filename) + return filename if File.executable?(Chef.path_to(filename)) end false end diff --git a/lib/chef/platform/service_helpers.rb b/lib/chef/platform/service_helpers.rb index 6b44478725..8a840b91c3 100644 --- a/lib/chef/platform/service_helpers.rb +++ b/lib/chef/platform/service_helpers.rb @@ -19,6 +19,7 @@ # XXX: mixing shellout into a mixin into classes has to be code smell require 'chef/mixin/shell_out' require 'chef/mixin/which' +require 'chef/chef_class' class Chef class Platform @@ -44,24 +45,24 @@ class Chef def service_resource_providers @service_resource_providers ||= [].tap do |service_resource_providers| - if ::File.exist?("/usr/sbin/update-rc.d") + if ::File.exist?(Chef.path_to("/usr/sbin/update-rc.d")) service_resource_providers << :debian end - if ::File.exist?("/usr/sbin/invoke-rc.d") + if ::File.exist?(Chef.path_to("/usr/sbin/invoke-rc.d")) service_resource_providers << :invokercd end - if ::File.exist?("/sbin/insserv") + if ::File.exist?(Chef.path_to("/sbin/insserv")) service_resource_providers << :insserv end # debian >= 6.0 has /etc/init but does not have upstart - if ::File.exist?("/etc/init") && ::File.exist?("/sbin/start") + if ::File.exist?(Chef.path_to("/etc/init")) && ::File.exist?(Chef.path_to("/sbin/start")) service_resource_providers << :upstart end - if ::File.exist?("/sbin/chkconfig") + if ::File.exist?(Chef.path_to("/sbin/chkconfig")) service_resource_providers << :redhat end @@ -75,23 +76,23 @@ class Chef def config_for_service(service_name) configs = [] - if ::File.exist?("/etc/init.d/#{service_name}") + if ::File.exist?(Chef.path_to("/etc/init.d/#{service_name}")) configs << :initd end - if ::File.exist?("/etc/init/#{service_name}.conf") + if ::File.exist?(Chef.path_to("/etc/init/#{service_name}.conf")) configs << :upstart end - if ::File.exist?("/etc/xinetd.d/#{service_name}") + if ::File.exist?(Chef.path_to("/etc/xinetd.d/#{service_name}")) configs << :xinetd end - if ::File.exist?("/etc/rc.d/#{service_name}") + if ::File.exist?(Chef.path_to("/etc/rc.d/#{service_name}")) configs << :etc_rcd end - if ::File.exist?("/usr/local/etc/rc.d/#{service_name}") + if ::File.exist?(Chef.path_to("/usr/local/etc/rc.d/#{service_name}")) configs << :usr_local_etc_rcd end @@ -117,7 +118,7 @@ class Chef end def systemd_sanity_check? - systemctl_path && File.exist?("/proc/1/comm") && File.open("/proc/1/comm").gets.chomp == "systemd" + systemctl_path && File.exist?(Chef.path_to("/proc/1/comm")) && File.open(Chef.path_to("/proc/1/comm")).gets.chomp == "systemd" end def extract_systemd_services(command) -- cgit v1.2.1 From 6d08f7dd73b11394c0c899f285dbb7ff21bb1b89 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Mon, 28 Sep 2015 17:34:31 -0700 Subject: Get rid of state-keeping and reset in ServiceHelpers --- lib/chef/platform/service_helpers.rb | 50 ++++++++++++++---------------------- 1 file changed, 19 insertions(+), 31 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/platform/service_helpers.rb b/lib/chef/platform/service_helpers.rb index 8a840b91c3..39457a5d17 100644 --- a/lib/chef/platform/service_helpers.rb +++ b/lib/chef/platform/service_helpers.rb @@ -43,33 +43,29 @@ class Chef # different services is NOT a design concern of this module. # def service_resource_providers - @service_resource_providers ||= [].tap do |service_resource_providers| - - if ::File.exist?(Chef.path_to("/usr/sbin/update-rc.d")) - service_resource_providers << :debian - end - - if ::File.exist?(Chef.path_to("/usr/sbin/invoke-rc.d")) - service_resource_providers << :invokercd - end + if ::File.exist?(Chef.path_to("/usr/sbin/update-rc.d")) + service_resource_providers << :debian + end - if ::File.exist?(Chef.path_to("/sbin/insserv")) - service_resource_providers << :insserv - end + if ::File.exist?(Chef.path_to("/usr/sbin/invoke-rc.d")) + service_resource_providers << :invokercd + end - # debian >= 6.0 has /etc/init but does not have upstart - if ::File.exist?(Chef.path_to("/etc/init")) && ::File.exist?(Chef.path_to("/sbin/start")) - service_resource_providers << :upstart - end + if ::File.exist?(Chef.path_to("/sbin/insserv")) + service_resource_providers << :insserv + end - if ::File.exist?(Chef.path_to("/sbin/chkconfig")) - service_resource_providers << :redhat - end + # debian >= 6.0 has /etc/init but does not have upstart + if ::File.exist?(Chef.path_to("/etc/init")) && ::File.exist?(Chef.path_to("/sbin/start")) + service_resource_providers << :upstart + end - if systemd_sanity_check? - service_resource_providers << :systemd - end + if ::File.exist?(Chef.path_to("/sbin/chkconfig")) + service_resource_providers << :redhat + end + if systemd_sanity_check? + service_resource_providers << :systemd end end @@ -103,18 +99,10 @@ class Chef configs end - def reset - @service_resource_providers = nil - @systemctl_path = nil - end - private def systemctl_path - if @systemctl_path.nil? - @systemctl_path = which("systemctl") - end - @systemctl_path + which("systemctl") end def systemd_sanity_check? -- cgit v1.2.1 From 8f65f75b2ae48ed33cfce1853edcdcc1a949b9c3 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Mon, 28 Sep 2015 18:04:51 -0700 Subject: Make service_providers return the providers --- lib/chef/platform/service_helpers.rb | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/platform/service_helpers.rb b/lib/chef/platform/service_helpers.rb index 39457a5d17..8365141c6e 100644 --- a/lib/chef/platform/service_helpers.rb +++ b/lib/chef/platform/service_helpers.rb @@ -43,30 +43,34 @@ class Chef # different services is NOT a design concern of this module. # def service_resource_providers + providers = [] + if ::File.exist?(Chef.path_to("/usr/sbin/update-rc.d")) - service_resource_providers << :debian + providers << :debian end if ::File.exist?(Chef.path_to("/usr/sbin/invoke-rc.d")) - service_resource_providers << :invokercd + providers << :invokercd end if ::File.exist?(Chef.path_to("/sbin/insserv")) - service_resource_providers << :insserv + providers << :insserv end # debian >= 6.0 has /etc/init but does not have upstart if ::File.exist?(Chef.path_to("/etc/init")) && ::File.exist?(Chef.path_to("/sbin/start")) - service_resource_providers << :upstart + providers << :upstart end if ::File.exist?(Chef.path_to("/sbin/chkconfig")) - service_resource_providers << :redhat + providers << :redhat end if systemd_sanity_check? - service_resource_providers << :systemd + providers << :systemd end + + providers end def config_for_service(service_name) -- cgit v1.2.1 From a2981f12e04b275561e6c42b26f550e43eaa33ac Mon Sep 17 00:00:00 2001 From: John Keiser Date: Mon, 28 Sep 2015 18:07:50 -0700 Subject: Make resource_collection= @api private instead of deprecated --- lib/chef/run_context.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/run_context.rb b/lib/chef/run_context.rb index 0c8d3d1a48..205bb47448 100644 --- a/lib/chef/run_context.rb +++ b/lib/chef/run_context.rb @@ -528,15 +528,13 @@ ERROR_MESSAGE attr_reader :loaded_attributes_hash attr_reader :loaded_recipes_hash + # @api private + attr_writer :resource_collection + module Deprecated ### # These need to be settable so deploy can run a resource_collection # independent of any cookbooks via +recipe_eval+ - def resource_collection=(value) - Chef.log_deprecation("Setting run_context.resource_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") - @resource_collection = value - end - def audits=(value) Chef.log_deprecation("Setting run_context.audits will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") @audits = value -- cgit v1.2.1 From ad6c3e81e504ef8064d591201c09992a8f3f98d0 Mon Sep 17 00:00:00 2001 From: Irving Popovetsky Date: Mon, 28 Sep 2015 13:33:36 -0700 Subject: Use much simpler regex for determining the rpm version --- lib/chef/provider/package/rpm.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/package/rpm.rb b/lib/chef/provider/package/rpm.rb index c5d52a8384..6ce0dd689f 100644 --- a/lib/chef/provider/package/rpm.rb +++ b/lib/chef/provider/package/rpm.rb @@ -61,7 +61,7 @@ class Chef Chef::Log.debug("#{@new_resource} checking rpm status") shell_out_with_timeout!("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' #{@new_resource.source}").stdout.each_line do |line| case line - when /^([\w\d+_.-]+)\s([\w\d~_.-]+)$/ + when /^(\S+)\s(\S+)$/ @current_resource.package_name($1) @new_resource.version($2) @candidate_version = $2 @@ -78,7 +78,7 @@ class Chef @rpm_status = shell_out_with_timeout("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' #{@current_resource.package_name}") @rpm_status.stdout.each_line do |line| case line - when /^([\w\d+_.-]+)\s([\w\d~_.-]+)$/ + when /^(\S+)\s(\S+)$/ Chef::Log.debug("#{@new_resource} current version is #{$2}") @current_resource.version($2) end -- cgit v1.2.1 From f2fec9c1bd644199b62ce22e568c9c90b84c97aa Mon Sep 17 00:00:00 2001 From: Thom May Date: Tue, 29 Sep 2015 10:35:52 -0700 Subject: fix omnitruck url --- lib/chef/knife/bootstrap/templates/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/bootstrap/templates/README.md b/lib/chef/knife/bootstrap/templates/README.md index 538d38d0b6..b5bca25d8e 100644 --- a/lib/chef/knife/bootstrap/templates/README.md +++ b/lib/chef/knife/bootstrap/templates/README.md @@ -5,7 +5,7 @@ standardized on the [Omnibus](https://github.com/chef/omnibus) built installatio packages. The 'chef-full' template downloads a script which is used to determine the correct -Omnibus package for this system from the [Omnitruck](https://github.com/chef/omnitruck) API. +Omnibus package for this system from the [Omnitruck](https://docs.chef.io/api_omnitruck.html) API. You can still utilize custom bootstrap templates on your system if your installation needs are unique. Additional information can be found on the [docs site](https://docs.chef.io/knife_bootstrap.html#custom-templates). -- cgit v1.2.1 From 5d890056a1e8782af98b3d4efe4dded3494404c9 Mon Sep 17 00:00:00 2001 From: andy-dufour Date: Tue, 29 Sep 2015 16:34:56 -0400 Subject: Adding check for custom command in redhat service provider and providing more explicit error message if init.d script or custom command is not found. --- lib/chef/provider/service/redhat.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/service/redhat.rb b/lib/chef/provider/service/redhat.rb index 33a9778715..dd44e441a8 100644 --- a/lib/chef/provider/service/redhat.rb +++ b/lib/chef/provider/service/redhat.rb @@ -61,7 +61,9 @@ class Chef end requirements.assert(:start, :enable, :reload, :restart) do |a| - a.assertion { !@service_missing } + a.assertion do + custom_command_for_action?(action) || !@service_missing + end a.failure_message Chef::Exceptions::Service, "#{new_resource}: unable to locate the init.d script!" a.whyrun "Assuming service would be disabled. The init script is not presently installed." end -- cgit v1.2.1 From 8e8146b8d6a9e2312c0a35f4b1b9c46d02414065 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Tue, 29 Sep 2015 13:36:03 -0700 Subject: Better warning for unsharing --- lib/chef/knife/cookbook_site_unshare.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/knife/cookbook_site_unshare.rb b/lib/chef/knife/cookbook_site_unshare.rb index b34282ec32..77bb18322c 100644 --- a/lib/chef/knife/cookbook_site_unshare.rb +++ b/lib/chef/knife/cookbook_site_unshare.rb @@ -38,7 +38,7 @@ class Chef exit 1 end - confirm "Do you really want to unshare the cookbook #{@cookbook_name}" + confirm "Do you really want to unshare all versions of the cookbook #{@cookbook_name}" begin rest.delete_rest "https://supermarket.chef.io/api/v1/cookbooks/#{@name_args[0]}" @@ -48,7 +48,7 @@ class Chef exit 1 end - ui.info "Unshared cookbook #{@cookbook_name}" + ui.info "Unshared all versions of the cookbook #{@cookbook_name}" end end -- cgit v1.2.1 From 0dc4ae50f145ea81c1faae45326dc3f59a57798d Mon Sep 17 00:00:00 2001 From: andy-dufour Date: Tue, 29 Sep 2015 16:36:32 -0400 Subject: REALLY adding explicit error msg if init.d script or custom command is not found. --- lib/chef/provider/service/redhat.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/service/redhat.rb b/lib/chef/provider/service/redhat.rb index dd44e441a8..3ad11a7672 100644 --- a/lib/chef/provider/service/redhat.rb +++ b/lib/chef/provider/service/redhat.rb @@ -64,7 +64,7 @@ class Chef a.assertion do custom_command_for_action?(action) || !@service_missing end - a.failure_message Chef::Exceptions::Service, "#{new_resource}: unable to locate the init.d script!" + a.failure_message Chef::Exceptions::Service, "#{new_resource}: No custom command for #{action} specified and unable to locate the init.d script!" a.whyrun "Assuming service would be disabled. The init script is not presently installed." end end -- cgit v1.2.1 From 53380ccb30465f003ddc2fb3461007c135110577 Mon Sep 17 00:00:00 2001 From: Thom May Date: Tue, 29 Sep 2015 14:46:28 -0700 Subject: Ensure that our list of recipes is backwards compat Prior to chef 12.2 we included unexpanded 'cookbook' names for default recipes. In 12.2, we moved to expanded ('cookbook::default') names, which broke some searches. However, some of our users have now moved to searching for expanded, so we need to cater for both. Fixes #3767 --- lib/chef/node.rb | 2 +- lib/chef/run_list/versioned_recipe_list.rb | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/node.rb b/lib/chef/node.rb index 668ddbdc35..1e4a850277 100644 --- a/lib/chef/node.rb +++ b/lib/chef/node.rb @@ -440,7 +440,7 @@ class Chef self.tags # make sure they're defined - automatic_attrs[:recipes] = expansion.recipes.with_fully_qualified_names_and_version_constraints + automatic_attrs[:recipes] = expansion.recipes.with_duplicate_names automatic_attrs[:expanded_run_list] = expansion.recipes.with_fully_qualified_names_and_version_constraints automatic_attrs[:roles] = expansion.roles diff --git a/lib/chef/run_list/versioned_recipe_list.rb b/lib/chef/run_list/versioned_recipe_list.rb index 2824f08f31..803156aef9 100644 --- a/lib/chef/run_list/versioned_recipe_list.rb +++ b/lib/chef/run_list/versioned_recipe_list.rb @@ -82,6 +82,21 @@ class Chef qualified_recipe end end + + # Get an array of strings of both fully-qualified and unexpanded recipe names + # in response to chef/chef#3767 + # Chef-13 will revert to the behaviour of just including the fully-qualified name + # + # @return [Array] Array of strings with fully-qualified and unexpanded recipe names + def with_duplicate_names + self.map do |recipe_name| + if recipe_name.include?('::') + recipe_name + else + [recipe_name, "#{recipe_name}::default"] + end + end.flatten + end end end end -- cgit v1.2.1 From a5780a9a67efb8ccd82b5007fdb2c2e7c582d295 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Tue, 29 Sep 2015 14:09:03 -0700 Subject: Make sure name_attribute works on derived properties --- lib/chef/property.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/property.rb b/lib/chef/property.rb index 2b151b350a..b8d8005655 100644 --- a/lib/chef/property.rb +++ b/lib/chef/property.rb @@ -422,7 +422,13 @@ class Chef # @return [Property] The new property type. # def derive(**modified_options) - Property.new(**options.merge(**modified_options)) + # Since name_property and name_attribute are aliases, if you specify either + # one in modified_options it overrides anything in original options. + options = self.options + if modified_options.has_key?(:name_property) || modified_options.has_key?(:name_attribute) + options = options.reject { |k,v| k == :name_attribute || k == :name_property } + end + Property.new(options.merge(modified_options)) end # -- cgit v1.2.1 From d8cb2cf50e6ccb275ee5c686ce14842d58376a16 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Tue, 29 Sep 2015 12:56:06 -0700 Subject: Add tests for things that have created the lockfile but not yet acquired the lock --- lib/chef/run_lock.rb | 51 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 21 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/run_lock.rb b/lib/chef/run_lock.rb index cefe637db6..9e0952bdcb 100644 --- a/lib/chef/run_lock.rb +++ b/lib/chef/run_lock.rb @@ -87,27 +87,8 @@ class Chef # Either acquire() or test() methods should be called in order to # get the ownership of run_lock. def test - # ensure the runlock_file path exists - create_path(File.dirname(runlock_file)) - @runlock = File.open(runlock_file,'a+') - - if Chef::Platform.windows? - acquire_win32_mutex - else - # If we support FD_CLOEXEC, then use it. - # NB: ruby-2.0.0-p195 sets FD_CLOEXEC by default, but not - # ruby-1.8.7/1.9.3 - if Fcntl.const_defined?('F_SETFD') && Fcntl.const_defined?('FD_CLOEXEC') - runlock.fcntl(Fcntl::F_SETFD, runlock.fcntl(Fcntl::F_GETFD, 0) | Fcntl::FD_CLOEXEC) - end - # Flock will return 0 if it can acquire the lock otherwise it - # will return false - if runlock.flock(File::LOCK_NB|File::LOCK_EX) == 0 - true - else - false - end - end + create_lock + acquire_lock end # @@ -147,6 +128,34 @@ class Chef end end + # @api private solely for race condition tests + def create_lock + # ensure the runlock_file path exists + create_path(File.dirname(runlock_file)) + @runlock = File.open(runlock_file,'a+') + end + + # @api private solely for race condition tests + def acquire_lock + if Chef::Platform.windows? + acquire_win32_mutex + else + # If we support FD_CLOEXEC, then use it. + # NB: ruby-2.0.0-p195 sets FD_CLOEXEC by default, but not + # ruby-1.8.7/1.9.3 + if Fcntl.const_defined?('F_SETFD') && Fcntl.const_defined?('FD_CLOEXEC') + runlock.fcntl(Fcntl::F_SETFD, runlock.fcntl(Fcntl::F_GETFD, 0) | Fcntl::FD_CLOEXEC) + end + # Flock will return 0 if it can acquire the lock otherwise it + # will return false + if runlock.flock(File::LOCK_NB|File::LOCK_EX) == 0 + true + else + false + end + end + end + private def reset -- cgit v1.2.1 From 1d4c074c83f9ea2a8a61258323dc9bc45bd802da Mon Sep 17 00:00:00 2001 From: Salim Alam Date: Tue, 29 Sep 2015 16:32:24 -0700 Subject: Use Chef::FileContentManagement::Tempfile to create temp file --- lib/chef/provider/template/content.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/template/content.rb b/lib/chef/provider/template/content.rb index a231bd509e..db7ec99e3b 100644 --- a/lib/chef/provider/template/content.rb +++ b/lib/chef/provider/template/content.rb @@ -52,7 +52,7 @@ class Chef context._extend_modules(@new_resource.helper_modules) output = context.render_template(template_location) - tempfile = Tempfile.open("chef-rendered-template") + tempfile = Chef::FileContentManagement::Tempfile.new(@new_resource).tempfile tempfile.binmode tempfile.write(output) tempfile.close -- cgit v1.2.1 From d0d9e5b7a6973fbb250b9344038c2e79deb28599 Mon Sep 17 00:00:00 2001 From: Noah Kantrowitz Date: Tue, 29 Sep 2015 16:45:01 -0700 Subject: This wasn't intended to be a protected method. /cc @jkeiser --- lib/chef/run_context.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/run_context.rb b/lib/chef/run_context.rb index 205bb47448..b2a4b13ea4 100644 --- a/lib/chef/run_context.rb +++ b/lib/chef/run_context.rb @@ -522,15 +522,15 @@ ERROR_MESSAGE ChildRunContext.new(self) end + # @api private + attr_writer :resource_collection + protected attr_reader :cookbook_compiler attr_reader :loaded_attributes_hash attr_reader :loaded_recipes_hash - # @api private - attr_writer :resource_collection - module Deprecated ### # These need to be settable so deploy can run a resource_collection -- cgit v1.2.1 From d1a0e4b9dc4b5f00ce7fa5d56866fa0cbe8413e9 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Tue, 29 Sep 2015 16:06:41 -0700 Subject: Add ability for default to override name_property --- lib/chef/property.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/property.rb b/lib/chef/property.rb index b8d8005655..c1207d9132 100644 --- a/lib/chef/property.rb +++ b/lib/chef/property.rb @@ -422,11 +422,14 @@ class Chef # @return [Property] The new property type. # def derive(**modified_options) - # Since name_property and name_attribute are aliases, if you specify either - # one in modified_options it overrides anything in original options. + # Since name_property, name_attribute and default override each other, + # if you specify one of them in modified_options it overrides anything in + # the original options. options = self.options - if modified_options.has_key?(:name_property) || modified_options.has_key?(:name_attribute) - options = options.reject { |k,v| k == :name_attribute || k == :name_property } + if modified_options.has_key?(:name_property) || + modified_options.has_key?(:name_attribute) || + modified_options.has_key?(:default) + options = options.reject { |k,v| k == :name_attribute || k == :name_property || k == :default } end Property.new(options.merge(modified_options)) end -- cgit v1.2.1 From bfe6fda62c566f6b55903f1fcc531a277d506555 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Wed, 30 Sep 2015 11:54:10 -0700 Subject: Bump revision to 12.5.0 --- lib/chef/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/version.rb b/lib/chef/version.rb index faa61aee54..c0ff754873 100644 --- a/lib/chef/version.rb +++ b/lib/chef/version.rb @@ -21,7 +21,7 @@ class Chef CHEF_ROOT = File.dirname(File.expand_path(File.dirname(__FILE__))) - VERSION = '12.5.0.current.0' + VERSION = '12.5.0' end # -- cgit v1.2.1 From 55f9fe2812a071c09a6a1ae2a6a0e2d2bc89ff5a Mon Sep 17 00:00:00 2001 From: Salim Alam Date: Wed, 30 Sep 2015 14:46:32 -0700 Subject: Use accessor instead of class variable (cleanup) --- lib/chef/provider/template/content.rb | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/template/content.rb b/lib/chef/provider/template/content.rb index db7ec99e3b..693b19a8c6 100644 --- a/lib/chef/provider/template/content.rb +++ b/lib/chef/provider/template/content.rb @@ -29,30 +29,30 @@ class Chef def template_location @template_file_cache_location ||= begin - template_finder.find(@new_resource.source, :local => @new_resource.local, :cookbook => @new_resource.cookbook) + template_finder.find(new_resource.source, :local => new_resource.local, :cookbook => new_resource.cookbook) end end private def file_for_provider - context = TemplateContext.new(@new_resource.variables) - context[:node] = @run_context.node + context = TemplateContext.new(new_resource.variables) + context[:node] = run_context.node context[:template_finder] = template_finder # helper variables - context[:cookbook_name] = @new_resource.cookbook_name unless context.keys.include?(:coookbook_name) - context[:recipe_name] = @new_resource.recipe_name unless context.keys.include?(:recipe_name) - context[:recipe_line_string] = @new_resource.source_line unless context.keys.include?(:recipe_line_string) - context[:recipe_path] = @new_resource.source_line_file unless context.keys.include?(:recipe_path) - context[:recipe_line] = @new_resource.source_line_number unless context.keys.include?(:recipe_line) - context[:template_name] = @new_resource.source unless context.keys.include?(:template_name) + context[:cookbook_name] = new_resource.cookbook_name unless context.keys.include?(:coookbook_name) + context[:recipe_name] = new_resource.recipe_name unless context.keys.include?(:recipe_name) + context[:recipe_line_string] = new_resource.source_line unless context.keys.include?(:recipe_line_string) + context[:recipe_path] = new_resource.source_line_file unless context.keys.include?(:recipe_path) + context[:recipe_line] = new_resource.source_line_number unless context.keys.include?(:recipe_line) + context[:template_name] = new_resource.source unless context.keys.include?(:template_name) context[:template_path] = template_location unless context.keys.include?(:template_path) - context._extend_modules(@new_resource.helper_modules) + context._extend_modules(new_resource.helper_modules) output = context.render_template(template_location) - tempfile = Chef::FileContentManagement::Tempfile.new(@new_resource).tempfile + tempfile = Chef::FileContentManagement::Tempfile.new(new_resource).tempfile tempfile.binmode tempfile.write(output) tempfile.close @@ -61,7 +61,7 @@ class Chef def template_finder @template_finder ||= begin - TemplateFinder.new(run_context, @new_resource.cookbook_name, @run_context.node) + TemplateFinder.new(run_context, new_resource.cookbook_name, run_context.node) end end end -- cgit v1.2.1 From 5ab3345d22a8941eab8b8e697c31ec7904f14d9d Mon Sep 17 00:00:00 2001 From: Salim Alam Date: Wed, 30 Sep 2015 19:10:26 -0700 Subject: Clean up tests, fix bug in tempfile_open --- lib/chef/file_content_management/tempfile.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/file_content_management/tempfile.rb b/lib/chef/file_content_management/tempfile.rb index 2dde0ce21b..6e1624f9a4 100644 --- a/lib/chef/file_content_management/tempfile.rb +++ b/lib/chef/file_content_management/tempfile.rb @@ -49,7 +49,7 @@ class Chef end end - raise Chef::Exceptions::FileContentStagingError(errors) if tf.nil? + raise Chef::Exceptions::FileContentStagingError, errors if tf.nil? # We always process the tempfile in binmode so that we # preserve the line endings of the content. -- cgit v1.2.1 From 33d6cebdc92e0d5e0c8186480947b9672ae541ed Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Thu, 1 Oct 2015 10:58:00 -0700 Subject: Un-remove ExpandNodeObject#load_node, deprecate it Some third-party tools are using this, we need it to work. --- lib/chef/policy_builder/expand_node_object.rb | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'lib/chef') diff --git a/lib/chef/policy_builder/expand_node_object.rb b/lib/chef/policy_builder/expand_node_object.rb index 26b98afa52..933960a429 100644 --- a/lib/chef/policy_builder/expand_node_object.rb +++ b/lib/chef/policy_builder/expand_node_object.rb @@ -33,6 +33,9 @@ class Chef # expands the run_list on a node object and then queries the chef-server # to find the correct set of cookbooks, given version constraints of the # node's environment. + # + # Note that this class should only be used via PolicyBuilder::Dynamic and + # not instantiated directly. class ExpandNodeObject attr_reader :events @@ -94,6 +97,33 @@ class Chef run_context end + # DEPRECATED: As of Chef 12.5, chef selects either policyfile mode or + # "expand node" mode dynamically, based on the content of the node + # object, first boot JSON, and config. This happens in + # PolicyBuilder::Dynamic, which selects the implementation during + # #load_node and then delegates to either ExpandNodeObject or Policyfile + # implementations as appropriate. Tools authors should update their code + # to create a PolicyBuilder::Dynamc policy builder and allow it to select + # the proper implementation. + def load_node + Chef.log_deprecation("ExpandNodeObject#load_node is deprecated. Please use Chef::PolicyBuilder::Dynamic instead of using ExpandNodeObject directly") + + events.node_load_start(node_name, config) + Chef::Log.debug("Building node object for #{node_name}") + + @node = + if Chef::Config[:solo] + Chef::Node.build(node_name) + else + Chef::Node.find_or_create(node_name) + end + finish_load_node(node) + node + rescue Exception => e + events.node_load_failed(node_name, e, config) + raise + end + def finish_load_node(node) @node = node end -- cgit v1.2.1 From e03535f7e0e239e4f53bc72b057c2fa268970863 Mon Sep 17 00:00:00 2001 From: Claire McQuin Date: Thu, 1 Oct 2015 11:53:17 -0700 Subject: Use -Command flag on Nano --- lib/chef/provider/powershell_script.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/powershell_script.rb b/lib/chef/provider/powershell_script.rb index b876b6d8ee..91ce11c337 100644 --- a/lib/chef/provider/powershell_script.rb +++ b/lib/chef/provider/powershell_script.rb @@ -16,6 +16,7 @@ # limitations under the License. # +require 'chef/platform/query_helpers' require 'chef/provider/windows_script' class Chef @@ -49,7 +50,10 @@ class Chef # code -- otherwise, powershell.exe does not propagate the # error status of a failed Windows process that ran at the # end of the script, it gets changed to '1'. - interpreter_flags = [default_interpreter_flags, '-File'].join(' ') + # + # Nano only supports -Command + file_or_command = Chef::Platform.windows_nano_server? ? '-Command' : '-File' + interpreter_flags = [*default_interpreter_flags, file_or_command].join(' ') if ! (@new_resource.flags.nil?) interpreter_flags = [@new_resource.flags, interpreter_flags].join(' ') @@ -107,6 +111,8 @@ EOH end def default_interpreter_flags + return [] if Chef::Platform.windows_nano_server? + # Execution policy 'Bypass' is preferable since it doesn't require # user input confirmation for files such as PowerShell modules # downloaded from the Internet. However, 'Bypass' is not supported -- cgit v1.2.1 From 091d9e047971cee42193cc3c5fa30bc552175bcf Mon Sep 17 00:00:00 2001 From: sawanoboly Date: Thu, 24 Sep 2015 19:49:02 +0900 Subject: pass ssh_password to session --- lib/chef/knife/ssh.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/chef') diff --git a/lib/chef/knife/ssh.rb b/lib/chef/knife/ssh.rb index 62af853e88..d2df8399db 100644 --- a/lib/chef/knife/ssh.rb +++ b/lib/chef/knife/ssh.rb @@ -225,6 +225,8 @@ class Chef if config[:identity_file] opts[:keys] = File.expand_path(config[:identity_file]) opts[:keys_only] = true + elsif config[:ssh_password] + opts[:password] = config[:ssh_password] end # Don't set the keys to nil if we don't have them. forward_agent = config[:forward_agent] || ssh_config[:forward_agent] -- cgit v1.2.1 From f42e439686db89a1e123ed5293b9e63ebb426bf1 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Mon, 5 Oct 2015 08:11:00 -0700 Subject: Fix forward module.to_s --- lib/chef/provider.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/provider.rb b/lib/chef/provider.rb index 3138704a55..e22f11d9be 100644 --- a/lib/chef/provider.rb +++ b/lib/chef/provider.rb @@ -265,7 +265,7 @@ class Chef provider_class = self @included_resource_dsl_module = Module.new do extend Forwardable - define_singleton_method(:to_s) { "#{resource_class} forwarder module" } + define_singleton_method(:to_s) { "forwarder module for #{provider_class}" } define_singleton_method(:inspect) { to_s } # Add a delegator for each explicit property that will get the *current* value # of the property by default instead of the *actual* value. -- cgit v1.2.1 From e413ea35bba2ad36453b3d428c343ab3f0bce23a Mon Sep 17 00:00:00 2001 From: Claire McQuin Date: Fri, 2 Oct 2015 15:14:29 -0700 Subject: Raise error when running 32-bit scripts on Windows Nano. --- lib/chef/resource/windows_script.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/resource/windows_script.rb b/lib/chef/resource/windows_script.rb index 48e2b535a8..2bbd01d5aa 100644 --- a/lib/chef/resource/windows_script.rb +++ b/lib/chef/resource/windows_script.rb @@ -16,6 +16,7 @@ # limitations under the License. # +require 'chef/platform/query_helpers' require 'chef/resource/script' require 'chef/mixin/windows_architecture_helper' @@ -51,9 +52,12 @@ class Chef protected def assert_architecture_compatible!(desired_architecture) - if ! node_supports_windows_architecture?(node, desired_architecture) + if desired_architecture == :i386 && Chef::Platform.windows_nano_server? raise Chef::Exceptions::Win32ArchitectureIncorrect, - "cannot execute script with requested architecture '#{desired_architecture.to_s}' on a system with architecture '#{node_windows_architecture(node)}'" + "cannot execute script with requested architecture 'i386' on Windows Nano Server" + elsif ! node_supports_windows_architecture?(node, desired_architecture) + raise Chef::Exceptions::Win32ArchitectureIncorrect, + "cannot execute script with requested architecture '#{desired_architecture.to_s}' on a system with architecture '#{node_windows_architecture(node)}'" end end end -- cgit v1.2.1 From 0053c17bba34090083a34395657ff1ba1616e213 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Mon, 5 Oct 2015 13:38:36 -0700 Subject: Fix dispatch when there are different receivers with different numbers of arguments. Fixes https://github.com/chef/chef-dk/issues/546) --- lib/chef/event_dispatch/dispatcher.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/event_dispatch/dispatcher.rb b/lib/chef/event_dispatch/dispatcher.rb index 966a3f32ec..f3e55539a9 100644 --- a/lib/chef/event_dispatch/dispatcher.rb +++ b/lib/chef/event_dispatch/dispatcher.rb @@ -32,8 +32,11 @@ class Chef mth = s.method(method_name) # Trim arguments to match what the subscriber expects to allow # adding new arguments without breaking compat. - args = args.take(mth.arity) if mth.arity < args.size && mth.arity >= 0 - mth.call(*args) + if mth.arity < args.size && mth.arity >= 0 + mth.call(*args.take(mth.arity)) + else + mth.call(*args) + end end end -- cgit v1.2.1 From 130a94291555c03ca4775596ac940bac433b9174 Mon Sep 17 00:00:00 2001 From: Lamont Granquist Date: Mon, 5 Oct 2015 17:22:09 -0700 Subject: add optional ruby-profiling with --profile-ruby dumps a large call graph into /var/chef/cache/graph_profile.out --- lib/chef/application/apply.rb | 6 ++++++ lib/chef/application/client.rb | 8 +++++++- lib/chef/application/solo.rb | 8 +++++++- lib/chef/client.rb | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 2 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/application/apply.rb b/lib/chef/application/apply.rb index 243b441119..69129a4691 100644 --- a/lib/chef/application/apply.rb +++ b/lib/chef/application/apply.rb @@ -97,6 +97,12 @@ class Chef::Application::Apply < Chef::Application :description => 'Enable whyrun mode', :boolean => true + option :profile_ruby, + :long => "--[no-]profile-ruby", + :description => "Output ruby execution profile graph", + :boolean => true, + :default => false + option :color, :long => '--[no-]color', :boolean => true, diff --git a/lib/chef/application/client.rb b/lib/chef/application/client.rb index 148257ab89..690340ca43 100644 --- a/lib/chef/application/client.rb +++ b/lib/chef/application/client.rb @@ -2,7 +2,7 @@ # Author:: AJ Christensen () # Author:: Mark Mzyk (mmzyk@opscode.com) -# Copyright:: Copyright (c) 2008 Opscode, Inc. +# Copyright:: Copyright (c) 2008-2015 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -55,6 +55,12 @@ class Chef::Application::Client < Chef::Application :boolean => true, :default => false + option :profile_ruby, + :long => "--[no-]profile-ruby", + :description => "Output ruby execution profile graph", + :boolean => true, + :default => false + option :color, :long => '--[no-]color', :boolean => true, diff --git a/lib/chef/application/solo.rb b/lib/chef/application/solo.rb index 5bb2a1ceb0..1fcc819068 100644 --- a/lib/chef/application/solo.rb +++ b/lib/chef/application/solo.rb @@ -1,7 +1,7 @@ # # Author:: AJ Christensen () # Author:: Mark Mzyk (mmzyk@opscode.com) -# Copyright:: Copyright (c) 2008 Opscode, Inc. +# Copyright:: Copyright (c) 2008-2015 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -52,6 +52,12 @@ class Chef::Application::Solo < Chef::Application :boolean => true, :default => false + option :profile_ruby, + :long => "--[no-]profile-ruby", + :description => "Output ruby execution profile graph", + :boolean => true, + :default => false + option :color, :long => '--[no-]color', :boolean => true, diff --git a/lib/chef/client.rb b/lib/chef/client.rb index 7d5d463242..3315ae03dd 100644 --- a/lib/chef/client.rb +++ b/lib/chef/client.rb @@ -53,6 +53,11 @@ require 'chef/platform/rebooter' require 'chef/mixin/deprecation' require 'ohai' require 'rbconfig' +begin + require 'ruby-prof' +rescue LoadError + # ruby-prof is optional. +end class Chef # == Chef::Client @@ -232,6 +237,8 @@ class Chef # @return Always returns true. # def run + start_profiling + run_error = nil runlock = RunLock.new(Chef::Config.lockfile) @@ -284,6 +291,9 @@ class Chef run_completed_successfully events.run_completed(node) + # keep this inside the main loop to get exception backtraces + end_profiling + # rebooting has to be the last thing we do, no exceptions. Chef::Platform::Rebooter.reboot_if_needed!(node) rescue Exception => run_error @@ -891,6 +901,28 @@ class Chef attr_reader :override_runlist attr_reader :specific_recipes + def profiling_prereqs! + if !defined? RubyProf + raise "You must have the ruby-prof gem installed in order to use --profile-ruby" + end + end + + def start_profiling + return unless Chef::Config[:profile_ruby] + profiling_prereqs! + RubyProf.start + end + + def end_profiling + return unless Chef::Config[:profile_ruby] + profiling_prereqs! + path = Chef::FileCache.create_cache_path("graph_profile.out", false) + File.open(path, "w+") do |file| + RubyProf::GraphPrinter.new(RubyProf.stop).print(file, {}) + end + Chef::Log.warn("Ruby execution profile dumped to #{path}") + end + def empty_directory?(path) !File.exists?(path) || (Dir.entries(path).size <= 2) end -- cgit v1.2.1 From 9b57fbf80828747699695119a354f51dbb7fa4b2 Mon Sep 17 00:00:00 2001 From: Claire McQuin Date: Tue, 6 Oct 2015 12:44:48 -0700 Subject: Quote paths. --- lib/chef/provider/powershell_script.rb | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/powershell_script.rb b/lib/chef/provider/powershell_script.rb index 91ce11c337..cea9a45dad 100644 --- a/lib/chef/provider/powershell_script.rb +++ b/lib/chef/provider/powershell_script.rb @@ -41,10 +41,6 @@ class Chef # Powershell.exe is always in "v1.0" folder (for backwards compatibility) interpreter_path = Chef::Util::PathHelper.join(basepath, "WindowsPowerShell", "v1.0", interpreter) - "\"#{interpreter_path}\" #{flags} \"#{script_file.path}\"" - end - - def flags # Must use -File rather than -Command to launch the script # file created by the base class that contains the script # code -- otherwise, powershell.exe does not propagate the @@ -52,8 +48,17 @@ class Chef # end of the script, it gets changed to '1'. # # Nano only supports -Command - file_or_command = Chef::Platform.windows_nano_server? ? '-Command' : '-File' - interpreter_flags = [*default_interpreter_flags, file_or_command].join(' ') + cmd = "\"#{interpreter_path}\" #{flags}" + if Chef::Platform.windows_nano_server? + cmd << " -Command \". '#{script_file.path}'\"" + else + cmd << " -File \"#{script_file.path}\"" + end + cmd + end + + def flags + interpreter_flags = [*default_interpreter_flags].join(' ') if ! (@new_resource.flags.nil?) interpreter_flags = [@new_resource.flags, interpreter_flags].join(' ') @@ -91,7 +96,7 @@ EOH # written to the file system at this point, which is required since # the intent is to execute the code just written to it. user_script_file.close - validation_command = "\"#{interpreter}\" #{interpreter_arguments} -Command #{user_script_file.path}" + validation_command = "\"#{interpreter}\" #{interpreter_arguments} -Command \". '#{user_script_file.path}'\"" # Note that other script providers like bash allow syntax errors # to be suppressed by setting 'returns' to a value that the -- cgit v1.2.1 From 533c51401a4b623665146550d816f1910387a6b8 Mon Sep 17 00:00:00 2001 From: Lamont Granquist Date: Tue, 6 Oct 2015 13:59:31 -0700 Subject: make description of option scarier --- lib/chef/application/client.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/application/client.rb b/lib/chef/application/client.rb index 690340ca43..abb2dadd07 100644 --- a/lib/chef/application/client.rb +++ b/lib/chef/application/client.rb @@ -57,7 +57,7 @@ class Chef::Application::Client < Chef::Application option :profile_ruby, :long => "--[no-]profile-ruby", - :description => "Output ruby execution profile graph", + :description => "Dump complete Ruby call graph stack of entire Chef run (expert only)", :boolean => true, :default => false -- cgit v1.2.1 From 343cb04b63cbf3ecb5010b8873c241ed41806a5c Mon Sep 17 00:00:00 2001 From: Lamont Granquist Date: Tue, 6 Oct 2015 14:02:28 -0700 Subject: lazy load ruby-prof --- lib/chef/client.rb | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/client.rb b/lib/chef/client.rb index 3315ae03dd..cc3fe4fd5c 100644 --- a/lib/chef/client.rb +++ b/lib/chef/client.rb @@ -53,11 +53,6 @@ require 'chef/platform/rebooter' require 'chef/mixin/deprecation' require 'ohai' require 'rbconfig' -begin - require 'ruby-prof' -rescue LoadError - # ruby-prof is optional. -end class Chef # == Chef::Client @@ -902,7 +897,9 @@ class Chef attr_reader :specific_recipes def profiling_prereqs! - if !defined? RubyProf + begin + require 'ruby-prof' + rescue LoadError raise "You must have the ruby-prof gem installed in order to use --profile-ruby" end end -- cgit v1.2.1 From 9fa35d05a5eba1b3f5c774cd28ec6169c9b003db Mon Sep 17 00:00:00 2001 From: Adam Edwards Date: Sun, 20 Sep 2015 23:01:50 -0700 Subject: Windows cli tools should have color true by default --- lib/chef/application/apply.rb | 2 +- lib/chef/application/client.rb | 4 ++-- lib/chef/application/knife.rb | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/application/apply.rb b/lib/chef/application/apply.rb index 243b441119..c4f34911f4 100644 --- a/lib/chef/application/apply.rb +++ b/lib/chef/application/apply.rb @@ -100,7 +100,7 @@ class Chef::Application::Apply < Chef::Application option :color, :long => '--[no-]color', :boolean => true, - :default => !Chef::Platform.windows?, + :default => true, :description => "Use colored output, defaults to enabled" option :minimal_ohai, diff --git a/lib/chef/application/client.rb b/lib/chef/application/client.rb index 148257ab89..bf724d7522 100644 --- a/lib/chef/application/client.rb +++ b/lib/chef/application/client.rb @@ -58,8 +58,8 @@ class Chef::Application::Client < Chef::Application option :color, :long => '--[no-]color', :boolean => true, - :default => !Chef::Platform.windows?, - :description => "Use colored output, defaults to false on Windows, true otherwise" + :default => true, + :description => "Use colored output, defaults to enabled" option :log_level, :short => "-l LEVEL", diff --git a/lib/chef/application/knife.rb b/lib/chef/application/knife.rb index af5216ae00..d169a5dab5 100644 --- a/lib/chef/application/knife.rb +++ b/lib/chef/application/knife.rb @@ -44,8 +44,8 @@ class Chef::Application::Knife < Chef::Application option :color, :long => '--[no-]color', :boolean => true, - :default => !Chef::Platform.windows?, - :description => "Use colored output, defaults to false on Windows, true otherwise" + :default => true, + :description => "Use colored output, defaults to enabled" option :environment, :short => "-E ENVIRONMENT", -- cgit v1.2.1 From cdbd244f7d1de53c7228f6758866c083ae71a3c3 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Wed, 7 Oct 2015 17:46:48 -0700 Subject: Bump revision to 12.5.1 --- lib/chef/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/version.rb b/lib/chef/version.rb index c0ff754873..c769533aa6 100644 --- a/lib/chef/version.rb +++ b/lib/chef/version.rb @@ -21,7 +21,7 @@ class Chef CHEF_ROOT = File.dirname(File.expand_path(File.dirname(__FILE__))) - VERSION = '12.5.0' + VERSION = '12.5.1' end # -- cgit v1.2.1 From bc5c350bbf4b339a3a89c685372780ded2d46f12 Mon Sep 17 00:00:00 2001 From: Matt Wrock Date: Thu, 8 Oct 2015 13:08:16 -0700 Subject: ignore gid on windows and warn to use group --- lib/chef/provider/user/windows.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/user/windows.rb b/lib/chef/provider/user/windows.rb index e282a11d45..87310a4acf 100644 --- a/lib/chef/provider/user/windows.rb +++ b/lib/chef/provider/user/windows.rb @@ -35,6 +35,10 @@ class Chef end def load_current_resource + if @new_resource.gid + Chef::Log.warn("The 'gid' attribute is not implemented by the Windows platform. Please use the 'group' resource to assign a user th a group.") + end + @current_resource = Chef::Resource::User.new(@new_resource.name) @current_resource.username(@new_resource.username) user_info = nil @@ -42,7 +46,6 @@ class Chef user_info = @net_user.get_info @current_resource.uid(user_info[:user_id]) - @current_resource.gid(user_info[:primary_group_id]) @current_resource.comment(user_info[:full_name]) @current_resource.home(user_info[:home_dir]) @current_resource.shell(user_info[:script_path]) @@ -60,12 +63,12 @@ class Chef # === Returns # :: If a change is required # :: If the users are identical - def compare_user + def compare_user unless @net_user.validate_credentials(@new_resource.password) Chef::Log.debug("#{@new_resource} password has changed") return true end - [ :uid, :gid, :comment, :home, :shell ].any? do |user_attrib| + [ :uid, :comment, :home, :shell ].any? do |user_attrib| !@new_resource.send(user_attrib).nil? && @new_resource.send(user_attrib) != @current_resource.send(user_attrib) end end @@ -100,7 +103,6 @@ class Chef field_list = { 'comment' => 'full_name', 'home' => 'home_dir', - 'gid' => 'primary_group_id', 'uid' => 'user_id', 'shell' => 'script_path', 'password' => 'password' -- cgit v1.2.1 From f38138ebc52946148e4a9af89ddc259b440b899b Mon Sep 17 00:00:00 2001 From: Matt Wrock Date: Thu, 8 Oct 2015 13:36:20 -0700 Subject: fix spacing --- lib/chef/provider/user/windows.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/user/windows.rb b/lib/chef/provider/user/windows.rb index 87310a4acf..4f3e940ae7 100644 --- a/lib/chef/provider/user/windows.rb +++ b/lib/chef/provider/user/windows.rb @@ -63,7 +63,7 @@ class Chef # === Returns # :: If a change is required # :: If the users are identical - def compare_user + def compare_user unless @net_user.validate_credentials(@new_resource.password) Chef::Log.debug("#{@new_resource} password has changed") return true -- cgit v1.2.1 From 694b46930976f3cb35c166da12f3413dc4dfbdef Mon Sep 17 00:00:00 2001 From: Matt Wrock Date: Thu, 8 Oct 2015 15:50:38 -0700 Subject: fixing typo --- lib/chef/provider/user/windows.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/user/windows.rb b/lib/chef/provider/user/windows.rb index 4f3e940ae7..76519bb498 100644 --- a/lib/chef/provider/user/windows.rb +++ b/lib/chef/provider/user/windows.rb @@ -36,7 +36,7 @@ class Chef def load_current_resource if @new_resource.gid - Chef::Log.warn("The 'gid' attribute is not implemented by the Windows platform. Please use the 'group' resource to assign a user th a group.") + Chef::Log.warn("The 'gid' attribute is not implemented by the Windows platform. Please use the 'group' resource to assign a user to a group.") end @current_resource = Chef::Resource::User.new(@new_resource.name) -- cgit v1.2.1 From c9473b61e7d5f6f48598acaef4af0cfdf821f579 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Thu, 8 Oct 2015 20:24:55 -0700 Subject: Accept coercion as a way to accept nil values --- lib/chef/property.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/property.rb b/lib/chef/property.rb index c1207d9132..e97d8f9607 100644 --- a/lib/chef/property.rb +++ b/lib/chef/property.rb @@ -479,6 +479,8 @@ class Chef # A type accepts nil explicitly if "is" allows nil, it validates as nil, *and* is not simply # an empty type. # + # A type is presumed to accept nil if it does coercion (which must handle nil). + # # These examples accept nil explicitly: # ```ruby # property :a, [ String, nil ] @@ -510,7 +512,8 @@ class Chef # # @api private def explicitly_accepts_nil?(resource) - options.has_key?(:is) && resource.send(:_pv_is, { name => nil }, name, options[:is], raise_error: false) + options.has_key?(:coerce) || + (options.has_key?(:is) && resource.send(:_pv_is, { name => nil }, name, options[:is], raise_error: false)) end def get_value(resource) -- cgit v1.2.1 From ecd535d7fb4036baf949833f7f88cfe0911ddca7 Mon Sep 17 00:00:00 2001 From: Steven Danna Date: Mon, 5 Oct 2015 14:18:52 +0100 Subject: Fix search result pagination The start and rows parameter that are passed as part of the search request are passed directly to Solr on the backend. Results from Solr may contain deleted nodes no longer in the erchef database. Erchef will filter such nodes from the results. Thus, a user may receive fewer rows than they asked for. Incrementing 'start' only by the number of rows received will then result in the next Solr response overlapping the first, which can lead to duplicate results. In the case of a Solr results page that was completely filtered, it would lead to an infinite loop. This commit changes the code to always increment by the requested page size (args[:rows]) when it is non-nil. Incrementing by the length of the response set is still wrong in the case when the args[:rows] is nil, but the server doesn't give us anything else to increment by. Fixes #4027 --- lib/chef/search/query.rb | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/search/query.rb b/lib/chef/search/query.rb index 6469a18c49..658af8779c 100644 --- a/lib/chef/search/query.rb +++ b/lib/chef/search/query.rb @@ -88,8 +88,21 @@ WARNDEP if block response["rows"].each { |row| block.call(row) if row } - unless (response["start"] + response["rows"].length) >= response["total"] - args_h[:start] = response["start"] + response["rows"].length + # + # args_h[:rows] and args_h[:start] are the page size and + # start position requested of the search index backing the + # search API. + # + # The response may contain fewer rows than arg_h[:rows] if + # the page of index results included deleted nodes which + # have been filtered from the returned data. In this case, + # we still want to start the next page at start + + # args_h[:rows] to avoid asking the search backend for + # overlapping pages (which could result in duplicates). + # + next_start = response["start"] + (args_h[:rows] || response["rows"].length) + unless next_start >= response["total"] + args_h[:start] = next_start search(type, query, args_h, &block) end true @@ -99,6 +112,7 @@ WARNDEP end private + def validate_type(t) unless t.kind_of?(String) || t.kind_of?(Symbol) msg = "Invalid search object type #{t.inspect} (#{t.class}), must be a String or Symbol." + -- cgit v1.2.1 From 51c6ba84a3f189398b01de10d031dec5b16d9e8c Mon Sep 17 00:00:00 2001 From: Lamont Granquist Date: Tue, 13 Oct 2015 09:33:44 -0700 Subject: fix PR feedback --- lib/chef/application/apply.rb | 2 +- lib/chef/application/solo.rb | 2 +- lib/chef/client.rb | 8 +++----- 3 files changed, 5 insertions(+), 7 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/application/apply.rb b/lib/chef/application/apply.rb index 69129a4691..565b5e055c 100644 --- a/lib/chef/application/apply.rb +++ b/lib/chef/application/apply.rb @@ -99,7 +99,7 @@ class Chef::Application::Apply < Chef::Application option :profile_ruby, :long => "--[no-]profile-ruby", - :description => "Output ruby execution profile graph", + :description => "Dump complete Ruby call graph stack of entire Chef run (expert only)", :boolean => true, :default => false diff --git a/lib/chef/application/solo.rb b/lib/chef/application/solo.rb index 1fcc819068..4b472e9662 100644 --- a/lib/chef/application/solo.rb +++ b/lib/chef/application/solo.rb @@ -54,7 +54,7 @@ class Chef::Application::Solo < Chef::Application option :profile_ruby, :long => "--[no-]profile-ruby", - :description => "Output ruby execution profile graph", + :description => "Dump complete Ruby call graph stack of entire Chef run (expert only)", :boolean => true, :default => false diff --git a/lib/chef/client.rb b/lib/chef/client.rb index cc3fe4fd5c..e2d76092e2 100644 --- a/lib/chef/client.rb +++ b/lib/chef/client.rb @@ -897,11 +897,9 @@ class Chef attr_reader :specific_recipes def profiling_prereqs! - begin - require 'ruby-prof' - rescue LoadError - raise "You must have the ruby-prof gem installed in order to use --profile-ruby" - end + require 'ruby-prof' + rescue LoadError + raise "You must have the ruby-prof gem installed in order to use --profile-ruby" end def start_profiling -- cgit v1.2.1 From 273e44c04f2d2f1433f25024c1ab788fdd38d9d4 Mon Sep 17 00:00:00 2001 From: pwelch Date: Sat, 17 Oct 2015 21:17:38 -0400 Subject: Fix chef-apply usage banner The chef-apply option flags should trail the recipe or recipe text that is being applied. This updates the chef-apply banner to show the correct usage. Fixes #2372 --- lib/chef/application/apply.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/application/apply.rb b/lib/chef/application/apply.rb index 15697f2955..b21b838d72 100644 --- a/lib/chef/application/apply.rb +++ b/lib/chef/application/apply.rb @@ -29,7 +29,7 @@ require 'chef/resources' class Chef::Application::Apply < Chef::Application - banner "Usage: chef-apply [RECIPE_FILE] [-e RECIPE_TEXT] [-s]" + banner "Usage: chef-apply [RECIPE_FILE | -e RECIPE_TEXT | -s] [OPTIONS]" option :execute, :short => "-e RECIPE_TEXT", -- cgit v1.2.1 From 1dd6fee90b57951a8d1d6b6618131407452ebd37 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Sun, 18 Oct 2015 20:43:12 -0700 Subject: Capitalize sentences --- lib/chef/cookbook/cookbook_version_loader.rb | 2 +- lib/chef/cookbook/remote_file_vendor.rb | 2 +- lib/chef/file_access_control/unix.rb | 24 +++++++++++----------- lib/chef/file_content_management/deploy/cp.rb | 4 ++-- lib/chef/file_content_management/deploy/mv_unix.rb | 8 ++++---- .../file_content_management/deploy/mv_windows.rb | 2 +- .../error_inspectors/compile_error_inspector.rb | 4 ++-- lib/chef/http/decompressor.rb | 4 ++-- lib/chef/knife/ssh.rb | 2 +- lib/chef/provider/package/openbsd.rb | 2 +- lib/chef/provider/remote_file/http.rb | 2 +- lib/chef/resource/execute.rb | 2 +- lib/chef/util/diff.rb | 4 ++-- 13 files changed, 31 insertions(+), 31 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/cookbook/cookbook_version_loader.rb b/lib/chef/cookbook/cookbook_version_loader.rb index bcbfcbeec8..dbccdbc0a8 100644 --- a/lib/chef/cookbook/cookbook_version_loader.rb +++ b/lib/chef/cookbook/cookbook_version_loader.rb @@ -91,7 +91,7 @@ class Chef remove_ignored_files if empty? - Chef::Log.warn "found a directory #{cookbook_name} in the cookbook path, but it contains no cookbook files. skipping." + Chef::Log.warn "Found a directory #{cookbook_name} in the cookbook path, but it contains no cookbook files. skipping." end @cookbook_settings end diff --git a/lib/chef/cookbook/remote_file_vendor.rb b/lib/chef/cookbook/remote_file_vendor.rb index 9d895b168e..7868430227 100644 --- a/lib/chef/cookbook/remote_file_vendor.rb +++ b/lib/chef/cookbook/remote_file_vendor.rb @@ -69,7 +69,7 @@ class Chef Chef::FileCache.move_to(raw_file.path, cache_filename) else Chef::Log.debug("Not fetching #{cache_filename}, as the cache is up to date.") - Chef::Log.debug("current checksum: #{current_checksum}; manifest checksum: #{found_manifest_record['checksum']})") + Chef::Log.debug("Current checksum: #{current_checksum}; manifest checksum: #{found_manifest_record['checksum']})") end full_path_cache_filename = Chef::FileCache.load(cache_filename, false) diff --git a/lib/chef/file_access_control/unix.rb b/lib/chef/file_access_control/unix.rb index c53d832414..8178d5fbf2 100644 --- a/lib/chef/file_access_control/unix.rb +++ b/lib/chef/file_access_control/unix.rb @@ -79,18 +79,18 @@ class Chef def should_update_owner? if target_uid.nil? # the user has not specified a permission on the new resource, so we never manage it with FAC - Chef::Log.debug("found target_uid == nil, so no owner was specified on resource, not managing owner") + Chef::Log.debug("Found target_uid == nil, so no owner was specified on resource, not managing owner") return false elsif current_uid.nil? # the user has specified a permission, and we are creating a file, so always enforce permissions - Chef::Log.debug("found current_uid == nil, so we are creating a new file, updating owner") + Chef::Log.debug("Found current_uid == nil, so we are creating a new file, updating owner") return true elsif target_uid != current_uid # the user has specified a permission, and it does not match the file, so fix the permission - Chef::Log.debug("found target_uid != current_uid, updating owner") + Chef::Log.debug("Found target_uid != current_uid, updating owner") return true else - Chef::Log.debug("found target_uid == current_uid, not updating owner") + Chef::Log.debug("Found target_uid == current_uid, not updating owner") # the user has specified a permission, but it matches the file, so behave idempotently return false end @@ -138,18 +138,18 @@ class Chef def should_update_group? if target_gid.nil? # the user has not specified a permission on the new resource, so we never manage it with FAC - Chef::Log.debug("found target_gid == nil, so no group was specified on resource, not managing group") + Chef::Log.debug("Found target_gid == nil, so no group was specified on resource, not managing group") return false elsif current_gid.nil? # the user has specified a permission, and we are creating a file, so always enforce permissions - Chef::Log.debug("found current_gid == nil, so we are creating a new file, updating group") + Chef::Log.debug("Found current_gid == nil, so we are creating a new file, updating group") return true elsif target_gid != current_gid # the user has specified a permission, and it does not match the file, so fix the permission - Chef::Log.debug("found target_gid != current_gid, updating group") + Chef::Log.debug("Found target_gid != current_gid, updating group") return true else - Chef::Log.debug("found target_gid == current_gid, not updating group") + Chef::Log.debug("Found target_gid == current_gid, not updating group") # the user has specified a permission, but it matches the file, so behave idempotently return false end @@ -187,20 +187,20 @@ class Chef def should_update_mode? if target_mode.nil? # the user has not specified a permission on the new resource, so we never manage it with FAC - Chef::Log.debug("found target_mode == nil, so no mode was specified on resource, not managing mode") + Chef::Log.debug("Found target_mode == nil, so no mode was specified on resource, not managing mode") return false elsif current_mode.nil? # the user has specified a permission, and we are creating a file, so always enforce permissions - Chef::Log.debug("found current_mode == nil, so we are creating a new file, updating mode") + Chef::Log.debug("Found current_mode == nil, so we are creating a new file, updating mode") return true elsif target_mode != current_mode # the user has specified a permission, and it does not match the file, so fix the permission - Chef::Log.debug("found target_mode != current_mode, updating mode") + Chef::Log.debug("Found target_mode != current_mode, updating mode") return true elsif suid_bit_set? and (should_update_group? or should_update_owner?) return true else - Chef::Log.debug("found target_mode == current_mode, not updating mode") + Chef::Log.debug("Found target_mode == current_mode, not updating mode") # the user has specified a permission, but it matches the file, so behave idempotently return false end diff --git a/lib/chef/file_content_management/deploy/cp.rb b/lib/chef/file_content_management/deploy/cp.rb index c6b1d6cd11..ea378c2e5d 100644 --- a/lib/chef/file_content_management/deploy/cp.rb +++ b/lib/chef/file_content_management/deploy/cp.rb @@ -34,12 +34,12 @@ class Chef # class Cp def create(file) - Chef::Log.debug("touching #{file} to create it") + Chef::Log.debug("Touching #{file} to create it") FileUtils.touch(file) end def deploy(src, dst) - Chef::Log.debug("copying temporary file #{src} into place at #{dst}") + Chef::Log.debug("Copying temporary file #{src} into place at #{dst}") FileUtils.cp(src, dst) end end diff --git a/lib/chef/file_content_management/deploy/mv_unix.rb b/lib/chef/file_content_management/deploy/mv_unix.rb index 758c594e50..9712486424 100644 --- a/lib/chef/file_content_management/deploy/mv_unix.rb +++ b/lib/chef/file_content_management/deploy/mv_unix.rb @@ -30,19 +30,19 @@ class Chef def create(file) # this is very simple, but it ensures that ownership and file modes take # good defaults, in particular mode needs to obey umask on create - Chef::Log.debug("touching #{file} to create it") + Chef::Log.debug("Touching #{file} to create it") FileUtils.touch(file) end def deploy(src, dst) # we are only responsible for content so restore the dst files perms - Chef::Log.debug("reading modes from #{dst} file") + Chef::Log.debug("Reading modes from #{dst} file") stat = ::File.stat(dst) mode = stat.mode & 07777 uid = stat.uid gid = stat.gid - Chef::Log.debug("applying mode = #{mode.to_s(8)}, uid = #{uid}, gid = #{gid} to #{src}") + Chef::Log.debug("Applying mode = #{mode.to_s(8)}, uid = #{uid}, gid = #{gid} to #{src}") # i own the inode, so should be able to at least chmod it ::File.chmod(mode, src) @@ -67,7 +67,7 @@ class Chef Chef::Log.warn("Could not set gid = #{gid} on #{src}, file modes not preserved") end - Chef::Log.debug("moving temporary file #{src} into place at #{dst}") + Chef::Log.debug("Moving temporary file #{src} into place at #{dst}") FileUtils.mv(src, dst) end end diff --git a/lib/chef/file_content_management/deploy/mv_windows.rb b/lib/chef/file_content_management/deploy/mv_windows.rb index 0d16da9717..e2951dba4c 100644 --- a/lib/chef/file_content_management/deploy/mv_windows.rb +++ b/lib/chef/file_content_management/deploy/mv_windows.rb @@ -35,7 +35,7 @@ class Chef ACL = Security::ACL def create(file) - Chef::Log.debug("touching #{file} to create it") + Chef::Log.debug("Touching #{file} to create it") FileUtils.touch(file) end diff --git a/lib/chef/formatters/error_inspectors/compile_error_inspector.rb b/lib/chef/formatters/error_inspectors/compile_error_inspector.rb index 3c22d2e763..621fadce40 100644 --- a/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +++ b/lib/chef/formatters/error_inspectors/compile_error_inspector.rb @@ -108,7 +108,7 @@ class Chef def culprit_backtrace_entry @culprit_backtrace_entry ||= begin bt_entry = filtered_bt.first - Chef::Log.debug("backtrace entry for compile error: '#{bt_entry}'") + Chef::Log.debug("Backtrace entry for compile error: '#{bt_entry}'") bt_entry end end @@ -138,7 +138,7 @@ class Chef begin filters = Array(Chef::Config.cookbook_path).map {|p| /^#{Regexp.escape(p)}/i } r = exception.backtrace.select {|line| filters.any? {|filter| line =~ filter }} - Chef::Log.debug("filtered backtrace of compile error: #{r.join(",")}") + Chef::Log.debug("Filtered backtrace of compile error: #{r.join(",")}") r end end diff --git a/lib/chef/http/decompressor.rb b/lib/chef/http/decompressor.rb index e1d776da60..a61f510e7d 100644 --- a/lib/chef/http/decompressor.rb +++ b/lib/chef/http/decompressor.rb @@ -79,10 +79,10 @@ class Chef else case response[CONTENT_ENCODING] when GZIP - Chef::Log.debug "decompressing gzip response" + Chef::Log.debug "Decompressing gzip response" Zlib::Inflate.new(Zlib::MAX_WBITS + 16).inflate(response.body) when DEFLATE - Chef::Log.debug "decompressing deflate response" + Chef::Log.debug "Decompressing deflate response" Zlib::Inflate.inflate(response.body) else response.body diff --git a/lib/chef/knife/ssh.rb b/lib/chef/knife/ssh.rb index d2df8399db..996f40c91d 100644 --- a/lib/chef/knife/ssh.rb +++ b/lib/chef/knife/ssh.rb @@ -467,7 +467,7 @@ class Chef session.servers_for.each do |server| cssh_cmd << " #{server.user ? "#{server.user}@#{server.host}" : server.host}" end - Chef::Log.debug("starting cssh session with command: #{cssh_cmd}") + Chef::Log.debug("Starting cssh session with command: #{cssh_cmd}") exec(cssh_cmd) end diff --git a/lib/chef/provider/package/openbsd.rb b/lib/chef/provider/package/openbsd.rb index 83fc09c8ae..7a6582363e 100644 --- a/lib/chef/provider/package/openbsd.rb +++ b/lib/chef/provider/package/openbsd.rb @@ -111,7 +111,7 @@ class Chef end end results = results.reject(&:nil?) - Chef::Log.debug("candidate versions of '#{new_resource.package_name}' are '#{results}'") + Chef::Log.debug("Candidate versions of '#{new_resource.package_name}' are '#{results}'") case results.length when 0 [] diff --git a/lib/chef/provider/remote_file/http.rb b/lib/chef/provider/remote_file/http.rb index f17ab5a56d..e1f1cb2da7 100644 --- a/lib/chef/provider/remote_file/http.rb +++ b/lib/chef/provider/remote_file/http.rb @@ -105,7 +105,7 @@ class Chef # case you'd end up with a tar archive (no gzip) named, e.g., foo.tgz, # which is not what you wanted. if uri.to_s =~ /gz$/ - Chef::Log.debug("turning gzip compression off due to filename ending in gz") + Chef::Log.debug("Turning gzip compression off due to filename ending in gz") opts[:disable_gzip] = true end opts diff --git a/lib/chef/resource/execute.rb b/lib/chef/resource/execute.rb index ec669a75d3..11c4ae045c 100644 --- a/lib/chef/resource/execute.rb +++ b/lib/chef/resource/execute.rb @@ -102,7 +102,7 @@ class Chef end def path(arg=nil) - Chef::Log.warn "'path' attribute of 'execute' is not used by any provider in Chef 11 and Chef 12. Use 'environment' attribute to configure 'PATH'. This attribute will be removed in Chef 13." + Chef::Log.warn "The 'path' attribute of 'execute' is not used by any provider in Chef 11 or Chef 12. Use 'environment' attribute to configure 'PATH'. This attribute will be removed in Chef 13." set_or_return( :path, diff --git a/lib/chef/util/diff.rb b/lib/chef/util/diff.rb index c2dc6e045c..b8336b5135 100644 --- a/lib/chef/util/diff.rb +++ b/lib/chef/util/diff.rb @@ -64,7 +64,7 @@ class Chef def use_tempfile_if_missing(file) tempfile = nil unless File.exists?(file) - Chef::Log.debug("file #{file} does not exist to diff against, using empty tempfile") + Chef::Log.debug("File #{file} does not exist to diff against, using empty tempfile") tempfile = Tempfile.new("chef-diff") file = tempfile.path end @@ -139,7 +139,7 @@ class Chef return "(new content is binary, diff output suppressed)" if is_binary?(new_file) begin - Chef::Log.debug("running: diff -u #{old_file} #{new_file}") + Chef::Log.debug("Running: diff -u #{old_file} #{new_file}") diff_str = udiff(old_file, new_file) rescue Exception => e -- cgit v1.2.1 From 1b2786a02598ae3f2a98ad74bba415d8ffb62bd0 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Sun, 18 Oct 2015 20:43:39 -0700 Subject: Use why-run vs. why_run or whyrun --- lib/chef/client.rb | 2 +- lib/chef/data_bag.rb | 2 +- lib/chef/data_bag_item.rb | 2 +- lib/chef/node.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/client.rb b/lib/chef/client.rb index e2d76092e2..b2a00a7d01 100644 --- a/lib/chef/client.rb +++ b/lib/chef/client.rb @@ -273,7 +273,7 @@ class Chef if Chef::Config[:why_run] == true # why_run should probably be renamed to why_converge - Chef::Log.debug("Not running controls in 'why_run' mode - this mode is used to see potential converge changes") + Chef::Log.debug("Not running controls in 'why-run' mode - this mode is used to see potential converge changes") elsif Chef::Config[:audit_mode] != :disabled audit_error = run_audits(run_context) end diff --git a/lib/chef/data_bag.rb b/lib/chef/data_bag.rb index 8475774fa1..401ba6f63f 100644 --- a/lib/chef/data_bag.rb +++ b/lib/chef/data_bag.rb @@ -144,7 +144,7 @@ class Chef def save begin if Chef::Config[:why_run] - Chef::Log.warn("In whyrun mode, so NOT performing data bag save.") + Chef::Log.warn("In why-run mode, so NOT performing data bag save.") else create end diff --git a/lib/chef/data_bag_item.rb b/lib/chef/data_bag_item.rb index 9f92e26c50..31c9b69330 100644 --- a/lib/chef/data_bag_item.rb +++ b/lib/chef/data_bag_item.rb @@ -170,7 +170,7 @@ class Chef r = chef_server_rest begin if Chef::Config[:why_run] - Chef::Log.warn("In whyrun mode, so NOT performing data bag item save.") + Chef::Log.warn("In why-run mode, so NOT performing data bag item save.") else r.put_rest("data/#{data_bag}/#{item_id}", self) end diff --git a/lib/chef/node.rb b/lib/chef/node.rb index 1e4a850277..ad065cc02b 100644 --- a/lib/chef/node.rb +++ b/lib/chef/node.rb @@ -609,7 +609,7 @@ class Chef # so then POST to create. begin if Chef::Config[:why_run] - Chef::Log.warn("In whyrun mode, so NOT performing node save.") + Chef::Log.warn("In why-run mode, so NOT performing node save.") else chef_server_rest.put_rest("nodes/#{name}", data_for_save) end -- cgit v1.2.1 From 70c5f6f4bb784c896ac288e2edb5d4997682906b Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Sun, 18 Oct 2015 20:44:09 -0700 Subject: Unnecessary capitalization --- lib/chef/rest.rb | 2 +- lib/chef/run_context.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/rest.rb b/lib/chef/rest.rb index f87cec9b76..4106a01077 100644 --- a/lib/chef/rest.rb +++ b/lib/chef/rest.rb @@ -166,7 +166,7 @@ class Chef def retriable_http_request(method, url, req_body, headers) rest_request = Chef::HTTP::HTTPRequest.new(method, url, req_body, headers) - Chef::Log.debug("Sending HTTP Request via #{method} to #{url.host}:#{url.port}#{rest_request.path}") + Chef::Log.debug("Sending HTTP request via #{method} to #{url.host}:#{url.port}#{rest_request.path}") retrying_http_errors(url) do yield rest_request diff --git a/lib/chef/run_context.rb b/lib/chef/run_context.rb index b2a4b13ea4..f7ab88f7e0 100644 --- a/lib/chef/run_context.rb +++ b/lib/chef/run_context.rb @@ -268,7 +268,7 @@ class Chef # @see DSL::IncludeRecipe#load_recipe # def load_recipe(recipe_name, current_cookbook: nil) - Chef::Log.debug("Loading Recipe #{recipe_name} via include_recipe") + Chef::Log.debug("Loading recipe #{recipe_name} via include_recipe") cookbook_name, recipe_short_name = Chef::Recipe.parse_recipe_name(recipe_name, current_cookbook: current_cookbook) @@ -308,7 +308,7 @@ ERROR_MESSAGE raise Chef::Exceptions::RecipeNotFound, "could not find recipe file #{recipe_file}" end - Chef::Log.debug("Loading Recipe File #{recipe_file}") + Chef::Log.debug("Loading recipe file #{recipe_file}") recipe = Chef::Recipe.new('@recipe_files', recipe_file, self) recipe.from_file(recipe_file) recipe -- cgit v1.2.1 From eaf8806a7b8715c1e4ebb2f5160284fda6e97e66 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Sun, 18 Oct 2015 20:44:50 -0700 Subject: Improve sentences --- lib/chef/provider/execute.rb | 2 +- lib/chef/resource/script.rb | 2 +- lib/chef/win32/mutex.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/execute.rb b/lib/chef/provider/execute.rb index b44112c19e..c3dd3b4ee1 100644 --- a/lib/chef/provider/execute.rb +++ b/lib/chef/provider/execute.rb @@ -41,7 +41,7 @@ class Chef def define_resource_requirements # @todo: this should change to raise in some appropriate major version bump. if creates && creates_relative? && !cwd - Chef::Log.warn "Providing a relative path for the creates attribute without the cwd is deprecated and will be changed to fail (CHEF-3819)" + Chef::Log.warn "Providing a relative path for the creates attribute without the cwd is deprecated and will be changed to fail in the future (CHEF-3819)" end end diff --git a/lib/chef/resource/script.rb b/lib/chef/resource/script.rb index 30bed367cb..5081adf918 100644 --- a/lib/chef/resource/script.rb +++ b/lib/chef/resource/script.rb @@ -40,7 +40,7 @@ class Chef unless arg.nil? # Chef-13: change this to raise if the user is trying to set a value here Chef::Log.warn "Specifying command attribute on a script resource is a coding error, use the 'code' attribute, or the execute resource" - Chef::Log.warn "This attribute is deprecated and must be fixed or this code will fail on Chef-13" + Chef::Log.warn "This attribute is deprecated and must be fixed or this code will fail on Chef 13" end super end diff --git a/lib/chef/win32/mutex.rb b/lib/chef/win32/mutex.rb index f4755e9019..0d8eba1b3c 100644 --- a/lib/chef/win32/mutex.rb +++ b/lib/chef/win32/mutex.rb @@ -79,7 +79,7 @@ class Chef # of the process goes away and this class is only being used # to synchronize chef-clients runs on a node. Chef::Log.error("Can not release mutex '#{name}'. This might cause issues \ -if the mutex is attempted to be acquired by other threads.") +if other threads attempt to acquire the mutex.") Chef::ReservedNames::Win32::Error.raise! end end -- cgit v1.2.1 From dd75aa5d25ea9814164eac2c2cb09a8acadb6bae Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Sun, 18 Oct 2015 20:45:04 -0700 Subject: Fix spelling error --- lib/chef/provider/package/yum.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/package/yum.rb b/lib/chef/provider/package/yum.rb index 81454380a3..aff8dc9326 100644 --- a/lib/chef/provider/package/yum.rb +++ b/lib/chef/provider/package/yum.rb @@ -791,7 +791,7 @@ class Chef "/usr/bin/python" end rescue StandardError => e - Chef::Log.warn("An error occured attempting to determine correct python executable. Using default.") + Chef::Log.warn("An error occurred attempting to determine correct python executable. Using default.") Chef::Log.debug(e) "/usr/bin/python" end -- cgit v1.2.1 From b6ba4d29184cfc14b1256fdb1f442a321047de84 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Tue, 20 Oct 2015 15:32:42 -0700 Subject: Move properties into a mixin module (verbatim move) --- lib/chef/mixin/properties.rb | 303 ++++++++++++++++++++++++++++++++++++++ lib/chef/resource.rb | 339 ++++--------------------------------------- 2 files changed, 332 insertions(+), 310 deletions(-) create mode 100644 lib/chef/mixin/properties.rb (limited to 'lib/chef') diff --git a/lib/chef/mixin/properties.rb b/lib/chef/mixin/properties.rb new file mode 100644 index 0000000000..28ac693472 --- /dev/null +++ b/lib/chef/mixin/properties.rb @@ -0,0 +1,303 @@ +require 'chef/delayed_evaluator' +require 'chef/mixin/params_validate' +require 'chef/property' + +class Chef + module Mixin + module Properties + module ClassMethods + # + # The list of properties defined on this resource. + # + # Everything defined with `property` is in this list. + # + # @param include_superclass [Boolean] `true` to include properties defined + # on superclasses; `false` or `nil` to return the list of properties + # directly on this class. + # + # @return [Hash] The list of property names and types. + # + def properties(include_superclass=true) + @properties ||= {} + if include_superclass + if superclass.respond_to?(:properties) + superclass.properties.merge(@properties) + else + @properties.dup + end + else + @properties + end + end + + # + # Create a property on this resource class. + # + # If a superclass has this property, or if this property has already been + # defined by this resource, this will *override* the previous value. + # + # @param name [Symbol] The name of the property. + # @param type [Object,Array] The type(s) of this property. + # If present, this is prepended to the `is` validation option. + # @param options [Hash] Validation options. + # @option options [Object,Array] :is An object, or list of + # objects, that must match the value using Ruby's `===` operator + # (`options[:is].any? { |v| v === value }`). + # @option options [Object,Array] :equal_to An object, or list + # of objects, that must be equal to the value using Ruby's `==` + # operator (`options[:is].any? { |v| v == value }`) + # @option options [Regexp,Array] :regex An object, or + # list of objects, that must match the value with `regex.match(value)`. + # @option options [Class,Array] :kind_of A class, or + # list of classes, that the value must be an instance of. + # @option options [Hash] :callbacks A hash of + # messages -> procs, all of which match the value. The proc must + # return a truthy or falsey value (true means it matches). + # @option options [Symbol,Array] :respond_to A method + # name, or list of method names, the value must respond to. + # @option options [Symbol,Array] :cannot_be A property, + # or a list of properties, that the value cannot have (such as `:nil` or + # `:empty`). The method with a questionmark at the end is called on the + # value (e.g. `value.empty?`). If the value does not have this method, + # it is considered valid (i.e. if you don't respond to `empty?` we + # assume you are not empty). + # @option options [Proc] :coerce A proc which will be called to + # transform the user input to canonical form. The value is passed in, + # and the transformed value returned as output. Lazy values will *not* + # be passed to this method until after they are evaluated. Called in the + # context of the resource (meaning you can access other properties). + # @option options [Boolean] :required `true` if this property + # must be present; `false` otherwise. This is checked after the resource + # is fully initialized. + # @option options [Boolean] :name_property `true` if this + # property defaults to the same value as `name`. Equivalent to + # `default: lazy { name }`, except that #property_is_set? will + # return `true` if the property is set *or* if `name` is set. + # @option options [Boolean] :name_attribute Same as `name_property`. + # @option options [Object] :default The value this property + # will return if the user does not set one. If this is `lazy`, it will + # be run in the context of the instance (and able to access other + # properties). + # @option options [Boolean] :desired_state `true` if this property is + # part of desired state. Defaults to `true`. + # @option options [Boolean] :identity `true` if this property + # is part of object identity. Defaults to `false`. + # + # @example Bare property + # property :x + # + # @example With just a type + # property :x, String + # + # @example With just options + # property :x, default: 'hi' + # + # @example With type and options + # property :x, String, default: 'hi' + # + def property(name, type=NOT_PASSED, **options) + name = name.to_sym + + options.each { |k,v| options[k.to_sym] = v if k.is_a?(String) } + + options[:instance_variable_name] = :"@#{name}" if !options.has_key?(:instance_variable_name) + options.merge!(name: name, declared_in: self) + + if type == NOT_PASSED + # If a type is not passed, the property derives from the + # superclass property (if any) + if properties.has_key?(name) + property = properties[name].derive(**options) + else + property = property_type(**options) + end + + # If a Property is specified, derive a new one from that. + elsif type.is_a?(Property) || (type.is_a?(Class) && type <= Property) + property = type.derive(**options) + + # If a primitive type was passed, combine it with "is" + else + if options[:is] + options[:is] = ([ type ] + [ options[:is] ]).flatten(1) + else + options[:is] = type + end + property = property_type(**options) + end + + local_properties = properties(false) + local_properties[name] = property + + property.emit_dsl + end + + # + # Create a reusable property type that can be used in multiple properties + # in different resources. + # + # @param options [Hash] Validation options. see #property for + # the list of options. + # + # @example + # property_type(default: 'hi') + # + def property_type(**options) + Property.derive(**options) + end + + # + # Create a lazy value for assignment to a default value. + # + # @param block The block to run when the value is retrieved. + # + # @return [Chef::DelayedEvaluator] The lazy value + # + def lazy(&block) + DelayedEvaluator.new(&block) + end + + # + # Get or set the list of desired state properties for this resource. + # + # State properties are properties that describe the desired state + # of the system, such as file permissions or ownership. + # In general, state properties are properties that could be populated by + # examining the state of the system (e.g., File.stat can tell you the + # permissions on an existing file). Contrarily, properties that are not + # "state properties" usually modify the way Chef itself behaves, for example + # by providing additional options for a package manager to use when + # installing a package. + # + # This list is used by the Chef client auditing system to extract + # information from resources to describe changes made to the system. + # + # This method is unnecessary when declaring properties with `property`; + # properties are added to state_properties by default, and can be turned off + # with `desired_state: false`. + # + # ```ruby + # property :x # part of desired state + # property :y, desired_state: false # not part of desired state + # ``` + # + # @param names [Array] A list of property names to set as desired + # state. + # + # @return [Array] All properties in desired state. + # + def state_properties(*names) + if !names.empty? + names = names.map { |name| name.to_sym }.uniq + + local_properties = properties(false) + # Add new properties to the list. + names.each do |name| + property = properties[name] + if !property + self.property name, instance_variable_name: false, desired_state: true + elsif !property.desired_state? + self.property name, desired_state: true + end + end + + # If state_attrs *excludes* something which is currently desired state, + # mark it as desired_state: false. + local_properties.each do |name,property| + if property.desired_state? && !names.include?(name) + self.property name, desired_state: false + end + end + end + + properties.values.select { |property| property.desired_state? } + end + + # + # Set the identity of this resource to a particular set of properties. + # + # This drives #identity, which returns data that uniquely refers to a given + # resource on the given node (in such a way that it can be correlated + # across Chef runs). + # + # This method is unnecessary when declaring properties with `property`; + # properties can be added to identity during declaration with + # `identity: true`. + # + # ```ruby + # property :x, identity: true # part of identity + # property :y # not part of identity + # ``` + # + # If no properties are marked as identity, "name" is considered the identity. + # + # @param names [Array] A list of property names to set as the identity. + # + # @return [Array] All identity properties. + # + def identity_properties(*names) + if !names.empty? + names = names.map { |name| name.to_sym } + + # Add or change properties that are not part of the identity. + names.each do |name| + property = properties[name] + if !property + self.property name, instance_variable_name: false, identity: true + elsif !property.identity? + self.property name, identity: true + end + end + + # If identity_properties *excludes* something which is currently part of + # the identity, mark it as identity: false. + properties.each do |name,property| + if property.identity? && !names.include?(name) + + self.property name, identity: false + end + end + end + + result = properties.values.select { |property| property.identity? } + result = [ properties[:name] ] if result.empty? + result + end + + def included(other) + other.extend ClassMethods + end + end + + extend ClassMethods + + include Chef::Mixin::ParamsValidate + + # + # Whether this property has been set (or whether it has a default that has + # been retrieved). + # + # @param name [Symbol] The name of the property. + # @return [Boolean] `true` if the property has been set. + # + def property_is_set?(name) + property = self.class.properties[name.to_sym] + raise ArgumentError, "Property #{name} is not defined in class #{self}" if !property + property.is_set?(self) + end + + # + # Clear this property as if it had never been set. It will thereafter return + # the default. + # been retrieved). + # + # @param name [Symbol] The name of the property. + # + def reset_property(name) + property = self.class.properties[name.to_sym] + raise ArgumentError, "Property #{name} is not defined in class #{self}" if !property + property.reset(self) + end + end + end +end diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb index 9e40fdccfd..90453bd00e 100644 --- a/lib/chef/resource.rb +++ b/lib/chef/resource.rb @@ -19,7 +19,6 @@ # require 'chef/exceptions' -require 'chef/mixin/params_validate' require 'chef/dsl/platform_introspection' require 'chef/dsl/data_query' require 'chef/dsl/registry_helper' @@ -40,6 +39,7 @@ require 'chef/resource_resolver' require 'set' require 'chef/mixin/deprecation' +require 'chef/mixin/properties' require 'chef/mixin/provides' require 'chef/mixin/shell_out' require 'chef/mixin/powershell_out' @@ -61,6 +61,34 @@ class Chef include Chef::Mixin::ShellOut include Chef::Mixin::PowershellOut + # Bring in `property` and `property_type` + include Chef::Mixin::Properties + + # + # The name of this particular resource. + # + # This special resource attribute is set automatically from the declaration + # of the resource, e.g. + # + # execute 'Vitruvius' do + # command 'ls' + # end + # + # Will set the name to "Vitruvius". + # + # This is also used in to_s to show the resource name, e.g. `execute[Vitruvius]`. + # + # This is also used for resource notifications and subscribes in the same manner. + # + # This will coerce any object into a string via #to_s. Arrays are a special case + # so that `package ["foo", "bar"]` becomes package[foo, bar] instead of the more + # awkward `package[["foo", "bar"]]` that #to_s would produce. + # + # @param name [Object] The name to set, typically a String or Array + # @return [String] The name of this Resource. + # + property :name, String, coerce: proc { |v| v.is_a?(Array) ? v.join(', ') : v.to_s }, desired_state: false + # # The node the current Chef run is using. # @@ -132,30 +160,6 @@ class Chef @sensitive = false end - # - # The list of properties defined on this resource. - # - # Everything defined with `property` is in this list. - # - # @param include_superclass [Boolean] `true` to include properties defined - # on superclasses; `false` or `nil` to return the list of properties - # directly on this class. - # - # @return [Hash] The list of property names and types. - # - def self.properties(include_superclass=true) - @properties ||= {} - if include_superclass - if superclass.respond_to?(:properties) - superclass.properties.merge(@properties) - else - @properties.dup - end - else - @properties - end - end - # # The action or actions that will be taken when this resource is run. # @@ -681,7 +685,6 @@ class Chef # Resource Definition Interface (for resource developers) # - include Chef::Mixin::ParamsValidate include Chef::Mixin::Deprecation # @@ -714,240 +717,6 @@ class Chef provider(arg) end - # - # Create a property on this resource class. - # - # If a superclass has this property, or if this property has already been - # defined by this resource, this will *override* the previous value. - # - # @param name [Symbol] The name of the property. - # @param type [Object,Array] The type(s) of this property. - # If present, this is prepended to the `is` validation option. - # @param options [Hash] Validation options. - # @option options [Object,Array] :is An object, or list of - # objects, that must match the value using Ruby's `===` operator - # (`options[:is].any? { |v| v === value }`). - # @option options [Object,Array] :equal_to An object, or list - # of objects, that must be equal to the value using Ruby's `==` - # operator (`options[:is].any? { |v| v == value }`) - # @option options [Regexp,Array] :regex An object, or - # list of objects, that must match the value with `regex.match(value)`. - # @option options [Class,Array] :kind_of A class, or - # list of classes, that the value must be an instance of. - # @option options [Hash] :callbacks A hash of - # messages -> procs, all of which match the value. The proc must - # return a truthy or falsey value (true means it matches). - # @option options [Symbol,Array] :respond_to A method - # name, or list of method names, the value must respond to. - # @option options [Symbol,Array] :cannot_be A property, - # or a list of properties, that the value cannot have (such as `:nil` or - # `:empty`). The method with a questionmark at the end is called on the - # value (e.g. `value.empty?`). If the value does not have this method, - # it is considered valid (i.e. if you don't respond to `empty?` we - # assume you are not empty). - # @option options [Proc] :coerce A proc which will be called to - # transform the user input to canonical form. The value is passed in, - # and the transformed value returned as output. Lazy values will *not* - # be passed to this method until after they are evaluated. Called in the - # context of the resource (meaning you can access other properties). - # @option options [Boolean] :required `true` if this property - # must be present; `false` otherwise. This is checked after the resource - # is fully initialized. - # @option options [Boolean] :name_property `true` if this - # property defaults to the same value as `name`. Equivalent to - # `default: lazy { name }`, except that #property_is_set? will - # return `true` if the property is set *or* if `name` is set. - # @option options [Boolean] :name_attribute Same as `name_property`. - # @option options [Object] :default The value this property - # will return if the user does not set one. If this is `lazy`, it will - # be run in the context of the instance (and able to access other - # properties). - # @option options [Boolean] :desired_state `true` if this property is - # part of desired state. Defaults to `true`. - # @option options [Boolean] :identity `true` if this property - # is part of object identity. Defaults to `false`. - # - # @example Bare property - # property :x - # - # @example With just a type - # property :x, String - # - # @example With just options - # property :x, default: 'hi' - # - # @example With type and options - # property :x, String, default: 'hi' - # - def self.property(name, type=NOT_PASSED, **options) - name = name.to_sym - - options.each { |k,v| options[k.to_sym] = v if k.is_a?(String) } - - options[:instance_variable_name] = :"@#{name}" if !options.has_key?(:instance_variable_name) - options.merge!(name: name, declared_in: self) - - if type == NOT_PASSED - # If a type is not passed, the property derives from the - # superclass property (if any) - if properties.has_key?(name) - property = properties[name].derive(**options) - else - property = property_type(**options) - end - - # If a Property is specified, derive a new one from that. - elsif type.is_a?(Property) || (type.is_a?(Class) && type <= Property) - property = type.derive(**options) - - # If a primitive type was passed, combine it with "is" - else - if options[:is] - options[:is] = ([ type ] + [ options[:is] ]).flatten(1) - else - options[:is] = type - end - property = property_type(**options) - end - - local_properties = properties(false) - local_properties[name] = property - - property.emit_dsl - end - - # - # Create a reusable property type that can be used in multiple properties - # in different resources. - # - # @param options [Hash] Validation options. see #property for - # the list of options. - # - # @example - # property_type(default: 'hi') - # - def self.property_type(**options) - Property.derive(**options) - end - - # - # The name of this particular resource. - # - # This special resource attribute is set automatically from the declaration - # of the resource, e.g. - # - # execute 'Vitruvius' do - # command 'ls' - # end - # - # Will set the name to "Vitruvius". - # - # This is also used in to_s to show the resource name, e.g. `execute[Vitruvius]`. - # - # This is also used for resource notifications and subscribes in the same manner. - # - # This will coerce any object into a string via #to_s. Arrays are a special case - # so that `package ["foo", "bar"]` becomes package[foo, bar] instead of the more - # awkward `package[["foo", "bar"]]` that #to_s would produce. - # - # @param name [Object] The name to set, typically a String or Array - # @return [String] The name of this Resource. - # - property :name, String, coerce: proc { |v| v.is_a?(Array) ? v.join(', ') : v.to_s }, desired_state: false - - # - # Whether this property has been set (or whether it has a default that has - # been retrieved). - # - # @param name [Symbol] The name of the property. - # @return [Boolean] `true` if the property has been set. - # - def property_is_set?(name) - property = self.class.properties[name.to_sym] - raise ArgumentError, "Property #{name} is not defined in class #{self}" if !property - property.is_set?(self) - end - - # - # Clear this property as if it had never been set. It will thereafter return - # the default. - # been retrieved). - # - # @param name [Symbol] The name of the property. - # - def reset_property(name) - property = self.class.properties[name.to_sym] - raise ArgumentError, "Property #{name} is not defined in class #{self}" if !property - property.reset(self) - end - - # - # Create a lazy value for assignment to a default value. - # - # @param block The block to run when the value is retrieved. - # - # @return [Chef::DelayedEvaluator] The lazy value - # - def self.lazy(&block) - DelayedEvaluator.new(&block) - end - - # - # Get or set the list of desired state properties for this resource. - # - # State properties are properties that describe the desired state - # of the system, such as file permissions or ownership. - # In general, state properties are properties that could be populated by - # examining the state of the system (e.g., File.stat can tell you the - # permissions on an existing file). Contrarily, properties that are not - # "state properties" usually modify the way Chef itself behaves, for example - # by providing additional options for a package manager to use when - # installing a package. - # - # This list is used by the Chef client auditing system to extract - # information from resources to describe changes made to the system. - # - # This method is unnecessary when declaring properties with `property`; - # properties are added to state_properties by default, and can be turned off - # with `desired_state: false`. - # - # ```ruby - # property :x # part of desired state - # property :y, desired_state: false # not part of desired state - # ``` - # - # @param names [Array] A list of property names to set as desired - # state. - # - # @return [Array] All properties in desired state. - # - def self.state_properties(*names) - if !names.empty? - names = names.map { |name| name.to_sym }.uniq - - local_properties = properties(false) - # Add new properties to the list. - names.each do |name| - property = properties[name] - if !property - self.property name, instance_variable_name: false, desired_state: true - elsif !property.desired_state? - self.property name, desired_state: true - end - end - - # If state_attrs *excludes* something which is currently desired state, - # mark it as desired_state: false. - local_properties.each do |name,property| - if property.desired_state? && !names.include?(name) - self.property name, desired_state: false - end - end - end - - properties.values.select { |property| property.desired_state? } - end - # # Set or return the list of "state properties" implemented by the Resource # subclass. @@ -972,56 +741,6 @@ class Chef state_properties(*names).map { |property| property.name } end - # - # Set the identity of this resource to a particular set of properties. - # - # This drives #identity, which returns data that uniquely refers to a given - # resource on the given node (in such a way that it can be correlated - # across Chef runs). - # - # This method is unnecessary when declaring properties with `property`; - # properties can be added to identity during declaration with - # `identity: true`. - # - # ```ruby - # property :x, identity: true # part of identity - # property :y # not part of identity - # ``` - # - # If no properties are marked as identity, "name" is considered the identity. - # - # @param names [Array] A list of property names to set as the identity. - # - # @return [Array] All identity properties. - # - def self.identity_properties(*names) - if !names.empty? - names = names.map { |name| name.to_sym } - - # Add or change properties that are not part of the identity. - names.each do |name| - property = properties[name] - if !property - self.property name, instance_variable_name: false, identity: true - elsif !property.identity? - self.property name, identity: true - end - end - - # If identity_properties *excludes* something which is currently part of - # the identity, mark it as identity: false. - properties.each do |name,property| - if property.identity? && !names.include?(name) - self.property name, identity: false - end - end - end - - result = properties.values.select { |property| property.identity? } - result = [ properties[:name] ] if result.empty? - result - end - # # Set the identity of this resource to a particular property. # -- cgit v1.2.1 From 4d11c33afc5821d4b19bba4f8431c941c6c73d39 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Tue, 20 Oct 2015 16:02:32 -0700 Subject: Make modules with properties work and inherit as expected --- lib/chef/mixin/properties.rb | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/mixin/properties.rb b/lib/chef/mixin/properties.rb index 28ac693472..85abe4427e 100644 --- a/lib/chef/mixin/properties.rb +++ b/lib/chef/mixin/properties.rb @@ -18,15 +18,12 @@ class Chef # @return [Hash] The list of property names and types. # def properties(include_superclass=true) - @properties ||= {} if include_superclass - if superclass.respond_to?(:properties) - superclass.properties.merge(@properties) - else - @properties.dup - end + result = {} + ancestors.reverse_each { |c| result.merge!(c.properties(false)) if c.respond_to?(:properties) } + result else - @properties + @properties ||= {} end end @@ -269,7 +266,9 @@ class Chef end end - extend ClassMethods + def self.included(other) + other.extend ClassMethods + end include Chef::Mixin::ParamsValidate -- cgit v1.2.1 From 29c01fd3235ba333b68ae1f6a972c049aec00c8c Mon Sep 17 00:00:00 2001 From: Matt Wrock Date: Tue, 20 Oct 2015 16:27:02 -0700 Subject: add logger to windows service shellout --- lib/chef/application/windows_service.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/application/windows_service.rb b/lib/chef/application/windows_service.rb index b42a01cfdb..2551582c3a 100644 --- a/lib/chef/application/windows_service.rb +++ b/lib/chef/application/windows_service.rb @@ -189,7 +189,11 @@ class Chef config_params += " -c #{Chef::Config[:config_file]}" unless Chef::Config[:config_file].nil? config_params += " -L #{Chef::Config[:log_location]}" unless Chef::Config[:log_location] == STDOUT # Starts a new process and waits till the process exits - result = shell_out("chef-client #{config_params}", :timeout => Chef::Config[:windows_service][:watchdog_timeout]) + result = shell_out( + "chef-client #{config_params}", + :timeout => Chef::Config[:windows_service][:watchdog_timeout], + :logger => Chef::Log + ) Chef::Log.debug "#{result.stdout}" Chef::Log.debug "#{result.stderr}" rescue Mixlib::ShellOut::CommandTimeout => e -- cgit v1.2.1 From 9469d3a5ab22655fe13a4dd09823bd371fce3c10 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Sun, 18 Oct 2015 20:39:42 -0700 Subject: Update messaging to match LWRP -> Custom Resource rename If you showed up in a post-LWRP world these would be confusing --- lib/chef/resource/lwrp_base.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/resource/lwrp_base.rb b/lib/chef/resource/lwrp_base.rb index 443e0ed819..a9a669f18c 100644 --- a/lib/chef/resource/lwrp_base.rb +++ b/lib/chef/resource/lwrp_base.rb @@ -1,8 +1,8 @@ # -# Author:: Adam Jacob () -# Author:: Christopher Walters () -# Author:: Daniel DeLeo () -# Copyright:: Copyright (c) 2008-2012 Opscode, Inc. +# Author:: Adam Jacob () +# Author:: Christopher Walters () +# Author:: Daniel DeLeo () +# Copyright:: Copyright (c) 2008-2015 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -45,7 +45,7 @@ class Chef def build_from_file(cookbook_name, filename, run_context) if LWRPBase.loaded_lwrps[filename] - Chef::Log.info("LWRP resource #{filename} from cookbook #{cookbook_name} has already been loaded! Skipping the reload.") + Chef::Log.info("Custom resource #{filename} from cookbook #{cookbook_name} has already been loaded! Skipping the reload.") return loaded_lwrps[filename] end @@ -60,7 +60,7 @@ class Chef # Make a useful string for the class (rather than ) resource_class.instance_eval do define_singleton_method(:to_s) do - "LWRP resource #{resource_name} from cookbook #{cookbook_name}" + "Custom resource #{resource_name} from cookbook #{cookbook_name}" end define_singleton_method(:inspect) { to_s } end -- cgit v1.2.1 From ceeb47d54736673aac2a3c11c89b6580406197f0 Mon Sep 17 00:00:00 2001 From: Nathan Williams Date: Sun, 4 Oct 2015 21:31:19 -0700 Subject: add missing requires for Chef::DSL::Recipe --- lib/chef/provider/lwrp_base.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/chef') diff --git a/lib/chef/provider/lwrp_base.rb b/lib/chef/provider/lwrp_base.rb index a96c382a01..9c7cd15bbf 100644 --- a/lib/chef/provider/lwrp_base.rb +++ b/lib/chef/provider/lwrp_base.rb @@ -19,6 +19,7 @@ # require 'chef/provider' +require 'chef/dsl/recipe' require 'chef/dsl/include_recipe' class Chef -- cgit v1.2.1 From 1a4a6e6b4690ec6c051ce0b98d8d8648a7313f92 Mon Sep 17 00:00:00 2001 From: Alex Pop Date: Thu, 25 Jun 2015 13:21:26 -0700 Subject: print STDOUT from the powershell wrapper. fixes issue #3596 --- lib/chef/provider/powershell_script.rb | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/chef') diff --git a/lib/chef/provider/powershell_script.rb b/lib/chef/provider/powershell_script.rb index cea9a45dad..e04efb6b42 100644 --- a/lib/chef/provider/powershell_script.rb +++ b/lib/chef/provider/powershell_script.rb @@ -199,6 +199,9 @@ elseif ( $LASTEXITCODE -ne $null -and $LASTEXITCODE -ne 0 ) $exitstatus = $LASTEXITCODE } +# Print STDOUT for the script execution +Write-Output $chefscriptresult + # If this script is launched with -File, the process exit # status of PowerShell.exe will be $exitstatus. If it was # launched with -Command, it will be 0 if $exitstatus was 0, -- cgit v1.2.1 From 4fe540a7aac53afa61ada419f76432052a3a28ec Mon Sep 17 00:00:00 2001 From: Kyleen MacGugan Date: Thu, 24 Sep 2015 23:13:42 -0700 Subject: Added run list expansion json conversion. Creates a json tree from the run list expansion trace. Added event to report expanded run list Updated json conversion to use chef compat json. Remove RunListExpansion from JsonCompat --- lib/chef/event_dispatch/base.rb | 3 ++ lib/chef/json_compat.rb | 1 + lib/chef/policy_builder/expand_node_object.rb | 1 + lib/chef/resource_reporter.rb | 6 ++++ lib/chef/run_list/run_list_expansion.rb | 47 +++++++++++++++++++++++++++ 5 files changed, 58 insertions(+) (limited to 'lib/chef') diff --git a/lib/chef/event_dispatch/base.rb b/lib/chef/event_dispatch/base.rb index 1c9a58be23..585a3db174 100644 --- a/lib/chef/event_dispatch/base.rb +++ b/lib/chef/event_dispatch/base.rb @@ -384,6 +384,9 @@ class Chef def deprecation(message, location=caller(2..2)[0]) end + def run_list_expanded(run_list_expansion) + end + # An uncategorized message. This supports the case that a user needs to # pass output that doesn't fit into one of the callbacks above. Note that # there's no semantic information about the content or importance of the diff --git a/lib/chef/json_compat.rb b/lib/chef/json_compat.rb index d0b3b4c7f8..5e9f29a60b 100644 --- a/lib/chef/json_compat.rb +++ b/lib/chef/json_compat.rb @@ -41,6 +41,7 @@ class Chef CHEF_RESOURCECOLLECTION = "Chef::ResourceCollection".freeze CHEF_RESOURCESET = "Chef::ResourceCollection::ResourceSet".freeze CHEF_RESOURCELIST = "Chef::ResourceCollection::ResourceList".freeze + CHEF_RUNLISTEXPANSION = "Chef::RunListExpansion".freeze class < {}, :role => {}} + {:id => @environment, :run_list => convert_run_list_trace('top level', seen_items)} + end + private # these methods modifies internal state based on arguments, so hide it. @@ -140,8 +161,10 @@ class Chef end def expand_run_list_items(items, included_by="top level") + if entry = items.shift @run_list_trace[included_by.to_s] << entry.to_s + @better_run_list_trace[included_by.to_s] << entry case entry.type when :recipe @@ -156,8 +179,26 @@ class Chef end end + # Recursive helper to decode the non-nested hash form back into a tree + def convert_run_list_trace(base, seen_items) + @better_run_list_trace[base].map do |item| + skipped = seen_items[item.type][item.name] + seen_items[item.type][item.name] = true + case item.type + when :recipe + {:type => 'recipe', :name => item.name, :version => item.version, :skipped => !!skipped} + when :role + error = @role_errors[item.name] + missing = @all_missing_roles[item.name] + {:type => :role, :name => item.name, :children => (missing || error || skipped) ? [] : convert_run_list_trace(item.to_s, seen_items), + :missing => missing, :error => error, :skipped => skipped} + end + end + end + end + # Expand a run list from disk. Suitable for chef-solo class RunListExpansionFromDisk < RunListExpansion @@ -184,8 +225,14 @@ class Chef else raise end + rescue Exception => e + @role_errors[name] = e.to_s + raise end + end end end + + -- cgit v1.2.1 From b036d1542c10a6a4c0910b96a27404735134055a Mon Sep 17 00:00:00 2001 From: Steven Danna Date: Thu, 22 Oct 2015 10:53:42 +0100 Subject: Allow downloading of root_files in a chef repository A FileSystemEntry with a nil parent is a "root directory" and thus should exists so long as its filesystem path exists. This was preventing the download of files such as invitation.json whose parent directory is a root directory. --- lib/chef/chef_fs/file_system/file_system_entry.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/chef') diff --git a/lib/chef/chef_fs/file_system/file_system_entry.rb b/lib/chef/chef_fs/file_system/file_system_entry.rb index 8611aa2e0f..478631eac2 100644 --- a/lib/chef/chef_fs/file_system/file_system_entry.rb +++ b/lib/chef/chef_fs/file_system/file_system_entry.rb @@ -83,7 +83,7 @@ class Chef end def exists? - File.exists?(file_path) && parent.can_have_child?(name, dir?) + File.exists?(file_path) && (parent.nil? || parent.can_have_child?(name, dir?)) end def read -- cgit v1.2.1 From fe647990966bb2cd795fe896afb60cca1da7f85d Mon Sep 17 00:00:00 2001 From: Dave Eddy Date: Thu, 2 Apr 2015 18:06:56 -0400 Subject: overhaul solaris SMF service provider --- lib/chef/provider/service/solaris.rb | 60 ++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 17 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/service/solaris.rb b/lib/chef/provider/service/solaris.rb index eaea6bb1ab..7040503c6b 100644 --- a/lib/chef/provider/service/solaris.rb +++ b/lib/chef/provider/service/solaris.rb @@ -30,35 +30,39 @@ class Chef def initialize(new_resource, run_context=nil) super - @init_command = "/usr/sbin/svcadm" - @status_command = "/bin/svcs -l" + @init_command = "/usr/sbin/svcadm" + @status_command = "/bin/svcs" @maintenace = false end def load_current_resource @current_resource = Chef::Resource::Service.new(@new_resource.name) @current_resource.service_name(@new_resource.service_name) - unless ::File.exists? "/bin/svcs" - raise Chef::Exceptions::Service, "/bin/svcs does not exist!" + + [@init_command, @status_command].each do |cmd| + unless ::File.executable? cmd then + raise Chef::Exceptions::Service, "#{cmd} not executable!" + end end @status = service_status.enabled + @current_resource end def enable_service - shell_out!("#{default_init_command} clear #{@new_resource.service_name}") if @maintenance - shell_out!("#{default_init_command} enable -s #{@new_resource.service_name}") + shell_out!(default_init_command, "clear", @new_resource.service_name) if @maintenance + shell_out!(default_init_command, "enable", "-s", @new_resource.service_name) end def disable_service - shell_out!("#{default_init_command} disable -s #{@new_resource.service_name}") + shell_out!(default_init_command, "disable", "-s", @new_resource.service_name) end alias_method :stop_service, :disable_service alias_method :start_service, :enable_service def reload_service - shell_out_with_systems_locale!("#{default_init_command} refresh #{@new_resource.service_name}") + shell_out!(default_init_command, "refresh", @new_resource.service_name) end def restart_service @@ -68,16 +72,38 @@ class Chef end def service_status - status = shell_out!("#{@status_command} #{@current_resource.service_name}", :returns => [0, 1]) - status.stdout.each_line do |line| - case line - when /state\s+online/ - @current_resource.enabled(true) - @current_resource.running(true) - when /state\s+maintenance/ - @maintenance = true - end + cmd = shell_out!(@status_command, "-l", @current_resource.service_name, :returns => [0, 1]) + # Example output + # $ svcs -l rsyslog + # fmri svc:/application/rsyslog:default + # name rsyslog logging utility + # enabled true + # state online + # next_state none + # state_time April 2, 2015 04:25:19 PM EDT + # logfile /var/svc/log/application-rsyslog:default.log + # restarter svc:/system/svc/restarter:default + # contract_id 1115271 + # dependency require_all/error svc:/milestone/multi-user:default (online) + # $ + + # load output into hash + status = {} + cmd.stdout.each_line do |line| + key, value = line.strip.split(/\s+/, 2) + status[key] = value + end + + # check service state + @maintenance = false + case status['state'] + when 'online' + @current_resource.enabled(true) + @current_resource.running(true) + when 'maintenance' + @maintenance = true end + unless @current_resource.enabled @current_resource.enabled(false) @current_resource.running(false) -- cgit v1.2.1 From d246a05fe763e34c0b9fac698d88a45f4daa1a94 Mon Sep 17 00:00:00 2001 From: Mikhail Zholobov Date: Sun, 5 Apr 2015 19:46:06 +0300 Subject: provider/user/dscl: Set default gid to 20 gid should always be defined to create user account properly on OS X. "staff" (gid 20) is a default group for regular user accounts. --- lib/chef/provider/user/dscl.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib/chef') diff --git a/lib/chef/provider/user/dscl.rb b/lib/chef/provider/user/dscl.rb index 0c0c85e18b..d9e235d4b1 100644 --- a/lib/chef/provider/user/dscl.rb +++ b/lib/chef/provider/user/dscl.rb @@ -257,10 +257,13 @@ user password using shadow hash.") # # Sets the group id for the user using dscl. Fails if a group doesn't - # exist on the system with given group id. + # exist on the system with given group id. If `gid` is not specified, it + # sets a default Mac user group "staff", with id 20. # def dscl_set_gid - unless @new_resource.gid && @new_resource.gid.to_s.match(/^\d+$/) + if @new_resource.gid.nil? + @new_resource.gid(20) + elsif !@new_resource.gid.to_s.match(/^\d+$/) begin possible_gid = run_dscl("read /Groups/#{@new_resource.gid} PrimaryGroupID").split(" ").last rescue Chef::Exceptions::DsclCommandFailed => e -- cgit v1.2.1