diff options
26 files changed, 141 insertions, 76 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 949c2b8bfb..33fde26d4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -104,6 +104,7 @@ * Add declare_resource/build_resource comments, fix faulty ||= * Knife bootstrap creates a client and ships it to the node to implement validatorless bootstraps * Knife bootstrap can use the client it creates to setup chef-vault items for the node +* windows service now has a configurable timeout ## 12.0.3 * [**Phil Dibowitz**](https://github.com/jaymzh): diff --git a/DOC_CHANGES.md b/DOC_CHANGES.md index cae29adb80..f824d2da30 100644 --- a/DOC_CHANGES.md +++ b/DOC_CHANGES.md @@ -78,3 +78,8 @@ validation key. The --bootstrap-vault-item, --bootstrap-vault-json, and --bootstrap-vault-file arguments have been added to knife bootstrap providing three alternative ways to set chef vault items when bootstrapping a host. + +## Windows service now has a configurable timeout + +You can now set the amount of time a chef-client run is allowed when running the provided windows service. This can be configured by +setting `windows_service.watchdog_timeout` in your `client.rb` to the number of seconds desired. The default value is 2 hours. diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 5c8d8faea1..883e882a64 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -114,9 +114,10 @@ The specific components of Chef related to a given platform - including (but not ### Lieutenant +* [Joshua Timberman](https://github.com/jtimberman) + ### Maintainers -* [Joshua Timberman](https://github.com/jtimberman) * [Tyler Ball](https://github.com/tyler-ball) ## FreeBSD diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 4d92eee671..4d0a6cc7ef 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -145,3 +145,9 @@ There is no support for validatorless bootstraps when the node object has been p of the process any old node or client will be deleted when doing validatorless bootstraps. The old process with the validation key still works for this use case. The setting of the run_list, environment and json attributes first via knife bootstrap should mitigate some of the need to precreate the node object by hand first. + + +## Windows service now has a configurable timeout + +You can now set the amount of time a chef-client run is allowed when running the provided windows service. This can be configured by +setting `windows_service.watchdog_timeout` in your `client.rb` to the number of seconds desired. The default value is 2 hours. diff --git a/chef-x86-mingw32.gemspec b/chef-x86-mingw32.gemspec index 0364e07827..18c31d8354 100644 --- a/chef-x86-mingw32.gemspec +++ b/chef-x86-mingw32.gemspec @@ -4,13 +4,13 @@ gemspec = eval(IO.read(File.expand_path("../chef.gemspec", __FILE__))) gemspec.platform = "x86-mingw32" gemspec.add_dependency "ffi", "~> 1.9" -gemspec.add_dependency "windows-api", "0.4.2" -gemspec.add_dependency "windows-pr", "1.2.2" -gemspec.add_dependency "win32-api", "1.5.1" +gemspec.add_dependency "windows-api", "~> 0.4.2" +gemspec.add_dependency "windows-pr", "~> 1.2.2" +gemspec.add_dependency "win32-api", "~> 1.5.1" gemspec.add_dependency "win32-dir", "0.4.5" gemspec.add_dependency "win32-event", "0.6.1" gemspec.add_dependency "win32-mutex", "0.4.1" -gemspec.add_dependency "win32-process", "0.7.3" +gemspec.add_dependency "win32-process", "~> 0.7.3" gemspec.add_dependency "win32-service", "0.8.2" gemspec.add_dependency "win32-mmap", "0.4.0" gemspec.add_dependency "wmi-lite", "~> 1.0" diff --git a/lib/chef/application/windows_service.rb b/lib/chef/application/windows_service.rb index ba7c6dab5a..b42a01cfdb 100644 --- a/lib/chef/application/windows_service.rb +++ b/lib/chef/application/windows_service.rb @@ -189,9 +189,15 @@ 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}") + result = shell_out("chef-client #{config_params}", :timeout => Chef::Config[:windows_service][:watchdog_timeout]) Chef::Log.debug "#{result.stdout}" Chef::Log.debug "#{result.stderr}" + rescue Mixlib::ShellOut::CommandTimeout => e + Chef::Log.error "chef-client timed out\n(#{e})" + Chef::Log.error(<<-EOF) + Your chef-client run timed out. You can increase the time chef-client is given + to complete by configuring windows_service.watchdog_timeout in your client.rb. + EOF rescue Mixlib::ShellOut::ShellCommandFailed => e Chef::Log.warn "Not able to start chef-client in new process (#{e})" rescue => e diff --git a/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb b/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb index 20a3f4e2be..a7f1d733b1 100644 --- a/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb +++ b/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb @@ -36,11 +36,11 @@ class Chef # We need the canonical cookbook name if we are using versioned cookbooks, but we don't # want to spend a lot of time adding code to the main Chef libraries if root.versioned_cookbooks - _canonical_name = canonical_cookbook_name(File.basename(file_path)) - fail "When versioned_cookbooks mode is on, cookbook #{file_path} must match format <cookbook_name>-x.y.z" unless _canonical_name + canonical_name = canonical_cookbook_name(File.basename(file_path)) + fail "When versioned_cookbooks mode is on, cookbook #{file_path} must match format <cookbook_name>-x.y.z" unless canonical_name # KLUDGE: We shouldn't have to use instance_variable_set - loader.instance_variable_set(:@cookbook_name, _canonical_name) + loader.instance_variable_set(:@cookbook_name, canonical_name) end loader.load_cookbooks diff --git a/lib/chef/config.rb b/lib/chef/config.rb index c9e0914c0b..2eb9870a64 100644 --- a/lib/chef/config.rb +++ b/lib/chef/config.rb @@ -643,6 +643,12 @@ class Chef default :normal_attribute_whitelist, nil default :override_attribute_whitelist, nil + config_context :windows_service do + # Set `watchdog_timeout` to the number of seconds to wait for a chef-client run + # to finish + default :watchdog_timeout, 2 * (60 * 60) # 2 hours + end + # Chef requires an English-language UTF-8 locale to function properly. We attempt # to use the 'locale -a' command and search through a list of preferences until we # find one that we can use. On Ubuntu systems we should find 'C.UTF-8' and be diff --git a/lib/chef/dsl/recipe.rb b/lib/chef/dsl/recipe.rb index 7b467fd867..c22f053292 100644 --- a/lib/chef/dsl/recipe.rb +++ b/lib/chef/dsl/recipe.rb @@ -20,6 +20,7 @@ require 'chef/mixin/convert_to_class_name' require 'chef/exceptions' require 'chef/resource_builder' +require 'chef/mixin/shell_out' class Chef module DSL diff --git a/lib/chef/knife/bootstrap.rb b/lib/chef/knife/bootstrap.rb index f23c15fa70..e168a6bd9b 100644 --- a/lib/chef/knife/bootstrap.rb +++ b/lib/chef/knife/bootstrap.rb @@ -313,7 +313,8 @@ class Chef # chef-vault integration must use the new client-side hawtness, otherwise to use the # new client-side hawtness, just delete your validation key. - if chef_vault_handler.doing_chef_vault? || !File.exist?(File.expand_path(Chef::Config[:validation_key])) + if chef_vault_handler.doing_chef_vault? || + (Chef::Config[:validation_key] && !File.exist?(File.expand_path(Chef::Config[:validation_key]))) client_builder.run chef_vault_handler.run(node_name: config[:chef_node_name]) diff --git a/lib/chef/knife/cookbook_site_share.rb b/lib/chef/knife/cookbook_site_share.rb index 560e0669c1..efd2e7f129 100644 --- a/lib/chef/knife/cookbook_site_share.rb +++ b/lib/chef/knife/cookbook_site_share.rb @@ -73,14 +73,6 @@ class Chef begin Chef::Log.debug("Temp cookbook directory is #{tmp_cookbook_dir.inspect}") ui.info("Making tarball #{cookbook_name}.tgz") - tar_cmd = "tar" - begin - # Unix and Mac only - prefer gnutar - if shell_out("which gnutar").exitstatus.equal?(0) - tar_cmd = "gnutar" - end - rescue Errno::ENOENT - end shell_out!("#{tar_cmd} -czf #{cookbook_name}.tgz #{cookbook_name}", :cwd => tmp_cookbook_dir) rescue => e ui.error("Error making tarball #{cookbook_name}.tgz: #{e.message}. Increase log verbosity (-VV) for more information.") @@ -90,7 +82,7 @@ class Chef if config[:dry_run] ui.info("Not uploading #{cookbook_name}.tgz due to --dry-run flag.") - result = shell_out!("tar -tzf #{cookbook_name}.tgz", :cwd => tmp_cookbook_dir) + result = shell_out!("#{tar_cmd} -tzf #{cookbook_name}.tgz", :cwd => tmp_cookbook_dir) ui.info(result.stdout) FileUtils.rm_rf tmp_cookbook_dir return @@ -158,6 +150,20 @@ class Chef end res end + + def tar_cmd + if !@tar_cmd + @tar_cmd = "tar" + begin + # Unix and Mac only - prefer gnutar + if shell_out("which gnutar").exitstatus.equal?(0) + @tar_cmd = "gnutar" + end + rescue Errno::ENOENT + end + end + @tar_cmd + end end end diff --git a/lib/chef/knife/search.rb b/lib/chef/knife/search.rb index caca99b4d8..a6cec761ce 100644 --- a/lib/chef/knife/search.rb +++ b/lib/chef/knife/search.rb @@ -123,8 +123,8 @@ class Chef if ui.interchange? output({:results => result_count, :rows => result_items}) else - ui.msg "#{result_count} items found" - ui.msg("\n") + ui.log "#{result_count} items found" + ui.log("\n") result_items.each do |item| output(item) unless config[:id_only] diff --git a/lib/chef/mixin/shell_out.rb b/lib/chef/mixin/shell_out.rb index d3c14fa408..529023056d 100644 --- a/lib/chef/mixin/shell_out.rb +++ b/lib/chef/mixin/shell_out.rb @@ -76,17 +76,17 @@ class Chef def run_command_compatible_options(command_args) return command_args unless command_args.last.is_a?(Hash) - _command_args = command_args.dup - _options = _command_args.last + my_command_args = command_args.dup + my_options = my_command_args.last DEPRECATED_OPTIONS.each do |old_option, new_option| # Edge case: someone specifies :command_log_level and 'command_log_level' in the option hash - next unless value = _options.delete(old_option) || _options.delete(old_option.to_s) + next unless value = my_options.delete(old_option) || my_options.delete(old_option.to_s) deprecate_option old_option, new_option - _options[new_option] = value + my_options[new_option] = value end - return _command_args + return my_command_args end private diff --git a/lib/chef/provider/package/freebsd/base.rb b/lib/chef/provider/package/freebsd/base.rb index b0f05667ff..6a3b97a4fd 100644 --- a/lib/chef/provider/package/freebsd/base.rb +++ b/lib/chef/provider/package/freebsd/base.rb @@ -48,10 +48,10 @@ class Chef # Otherwise look up the path to the ports directory using 'whereis' else whereis = shell_out!("whereis -s #{port}", :env => nil) - unless _path = whereis.stdout[/^#{Regexp.escape(port)}:\s+(.+)$/, 1] + unless path = whereis.stdout[/^#{Regexp.escape(port)}:\s+(.+)$/, 1] raise Chef::Exceptions::Package, "Could not find port with the name #{port}" end - _path + path end end diff --git a/lib/chef/provider/package/yum.rb b/lib/chef/provider/package/yum.rb index 405e4177ab..2dbda60750 100644 --- a/lib/chef/provider/package/yum.rb +++ b/lib/chef/provider/package/yum.rb @@ -18,7 +18,6 @@ require 'chef/config' require 'chef/provider/package' -require 'chef/mixin/command' # handle_command_failures require 'chef/mixin/shell_out' require 'chef/resource/package' require 'singleton' @@ -984,7 +983,7 @@ class Chef end def yum_command(command) - status, stdout, stderr = output_of_command(command, {:timeout => Chef::Config[:yum_timeout]}) + status = shell_out(command, {:timeout => Chef::Config[:yum_timeout]}) # This is fun: rpm can encounter errors in the %post/%postun scripts which aren't # considered fatal - meaning the rpm is still successfully installed. These issue @@ -996,21 +995,20 @@ class Chef # A cleaner solution would have to be done in python and better hook into # yum/rpm to handle exceptions as we see fit. if status.exitstatus == 1 - stdout.each_line do |l| + status.stdout.each_line do |l| # rpm-4.4.2.3 lib/psm.c line 2182 if l =~ %r{^error: %(post|postun)\(.*\) scriptlet failed, exit status \d+$} Chef::Log.warn("#{@new_resource} caught non-fatal scriptlet issue: \"#{l}\". Can't trust yum exit status " + "so running install again to verify.") - status, stdout, stderr = output_of_command(command, {:timeout => Chef::Config[:yum_timeout]}) + status = shell_out(command, {:timeout => Chef::Config[:yum_timeout]}) break end end end if status.exitstatus > 0 - command_output = "STDOUT: #{stdout}" - command_output << "STDERR: #{stderr}" - Chef::Mixin::Command.handle_command_failures(status, command_output, {}) + command_output = "STDOUT: #{status.stdout}\nSTDERR: #{status.stderr}" + raise Chef::Exceptions::Exec, "#{command} returned #{status.exitstatus}:\n#{command_output}" end end diff --git a/lib/chef/resource/powershell_script.rb b/lib/chef/resource/powershell_script.rb index a88fb5701b..1b8aef94a2 100644 --- a/lib/chef/resource/powershell_script.rb +++ b/lib/chef/resource/powershell_script.rb @@ -34,8 +34,6 @@ class Chef ) end - protected - # Allow callers evaluating guards to request default # attribute values. This is needed to allow # convert_boolean_return to be true in guard context by default, diff --git a/lib/chef/user.rb b/lib/chef/user.rb index 6569a97f00..42fa6b5fa1 100644 --- a/lib/chef/user.rb +++ b/lib/chef/user.rb @@ -165,8 +165,6 @@ class Chef Chef::User.from_hash(response) end - private - # Gross. Transforms an API response in the form of: # [ { "user" => { "username" => USERNAME }}, ...] # into the form @@ -179,5 +177,7 @@ class Chef end new_response end + + private_class_method :transform_ohc_list_response end end diff --git a/lib/chef/version.rb b/lib/chef/version.rb index 27ba372f61..486a3b516d 100644 --- a/lib/chef/version.rb +++ b/lib/chef/version.rb @@ -17,7 +17,7 @@ class Chef CHEF_ROOT = File.dirname(File.expand_path(File.dirname(__FILE__))) - VERSION = '12.1.0.rc.0' + VERSION = '12.1.0' end # diff --git a/lib/chef/whitelist.rb b/lib/chef/whitelist.rb index 86c229d22c..3682f7187e 100644 --- a/lib/chef/whitelist.rb +++ b/lib/chef/whitelist.rb @@ -32,17 +32,15 @@ class Chef new_data = {} whitelist.each do |item| - self.add_data(data, new_data, item) + add_data(data, new_data, item) end new_data end - private - # Walk the data has according to the keys provided by the whitelisted item # and add the data to the whitelisting result. def self.add_data(data, new_data, item) - parts = self.to_array(item) + parts = to_array(item) all_data = data filtered_data = new_data @@ -68,6 +66,8 @@ class Chef new_data end + private_class_method :add_data + # Accepts a String or an Array, and returns an Array of String keys that # are used to traverse the data hash. Strings are split on "/", Arrays are # assumed to contain exact keys (that is, Array elements will not be split @@ -80,5 +80,7 @@ class Chef parts end + private_class_method :to_array + end end diff --git a/lib/chef/win32/security/ace.rb b/lib/chef/win32/security/ace.rb index 3aeae35532..1f54b1cafb 100644 --- a/lib/chef/win32/security/ace.rb +++ b/lib/chef/win32/security/ace.rb @@ -106,8 +106,6 @@ class Chef struct[:AceType] end - private - def self.create_ace_with_mask_and_sid(type, flags, mask, sid) size_needed = size_with_sid(sid) pointer = FFI::MemoryPointer.new size_needed diff --git a/lib/chef/win32/security/acl.rb b/lib/chef/win32/security/acl.rb index fd43b75cbf..e129d5c9a0 100644 --- a/lib/chef/win32/security/acl.rb +++ b/lib/chef/win32/security/acl.rb @@ -90,11 +90,13 @@ class Chef def to_s "[#{self.collect { |ace| ace.to_s }.join(", ")}]" end - private def self.align_dword(size) (size + 4 - 1) & 0xfffffffc end + + private_class_method :align_dword + end end end diff --git a/lib/chef/win32/version.rb b/lib/chef/win32/version.rb index 6a5bd35a26..17c27e4780 100644 --- a/lib/chef/win32/version.rb +++ b/lib/chef/win32/version.rb @@ -34,18 +34,18 @@ class Chef # http://msdn.microsoft.com/en-us/library/ms724833(v=vs.85).aspx # http://msdn.microsoft.com/en-us/library/ms724358(v=vs.85).aspx - private - def self.get_system_metrics(n_index) GetSystemMetrics(n_index) end + private_class_method :get_system_metrics + def self.method_name_from_marketing_name(marketing_name) "#{marketing_name.gsub(/\s/, '_').gsub(/\./, '_').downcase}?" # "#{marketing_name.gsub(/\s/, '_').gsub(//, '_').downcase}?" end - public + private_class_method :method_name_from_marketing_name WIN_VERSIONS = { "Windows 10" => {:major => 6, :minor => 4, :callable => lambda{ |product_type, suite_mask| product_type == VER_NT_WORKSTATION }}, diff --git a/spec/unit/knife/bootstrap_spec.rb b/spec/unit/knife/bootstrap_spec.rb index 5a2e1f1c96..848af11db5 100644 --- a/spec/unit/knife/bootstrap_spec.rb +++ b/spec/unit/knife/bootstrap_spec.rb @@ -593,6 +593,20 @@ describe Chef::Knife::Bootstrap do knife.run end end + + context "when the validation_key is nil" do + before do + # this tests runs the old code path where we have a validation key, so we need to pass that check for some plugins + Chef::Config[:validation_key] = nil + end + + it "creates the client and does not run client_builder or the chef_vault_handler" do + expect(knife_ssh).to receive(:run) + expect(knife.client_builder).not_to receive(:run) + expect(knife.chef_vault_handler).not_to receive(:run) + knife.run + end + end end describe "specifying ssl verification" do diff --git a/spec/unit/knife/cookbook_site_share_spec.rb b/spec/unit/knife/cookbook_site_share_spec.rb index f7207dd175..76e4ec730e 100644 --- a/spec/unit/knife/cookbook_site_share_spec.rb +++ b/spec/unit/knife/cookbook_site_share_spec.rb @@ -144,8 +144,9 @@ describe Chef::Knife::CookbookSiteShare do end it "should list files in the tarball" do - expect(@knife).to receive(:shell_out!).with("tar -czf #{@cookbook.name}.tgz #{@cookbook.name}", {:cwd => "/var/tmp/dummy"}) - expect(@knife).to receive(:shell_out!).with("tar -tzf #{@cookbook.name}.tgz", {:cwd => "/var/tmp/dummy"}) + allow(@knife).to receive(:tar_cmd).and_return("footar") + expect(@knife).to receive(:shell_out!).with("footar -czf #{@cookbook.name}.tgz #{@cookbook.name}", {:cwd => "/var/tmp/dummy"}) + expect(@knife).to receive(:shell_out!).with("footar -tzf #{@cookbook.name}.tgz", {:cwd => "/var/tmp/dummy"}) @knife.run end diff --git a/spec/unit/provider/package/yum_spec.rb b/spec/unit/provider/package/yum_spec.rb index aecbd1c34e..cd2b3decf4 100644 --- a/spec/unit/provider/package/yum_spec.rb +++ b/spec/unit/provider/package/yum_spec.rb @@ -696,9 +696,9 @@ describe Chef::Provider::Package::Yum do describe "when running yum" do it "should run yum once if it exits with a return code of 0" do - @status = double("Status", :exitstatus => 0) - allow(@provider).to receive(:output_of_command).and_return([@status, "", ""]) - expect(@provider).to receive(:output_of_command).once.with( + @status = double("Status", :exitstatus => 0, :stdout => "", :stderr => "") + allow(@provider).to receive(:shell_out).and_return(@status) + expect(@provider).to receive(:shell_out).once.with( "yum -d0 -e0 -y install emacs-1.0", {:timeout => Chef::Config[:yum_timeout]} ) @@ -706,9 +706,9 @@ describe Chef::Provider::Package::Yum do end it "should run yum once if it exits with a return code > 0 and no scriptlet failures" do - @status = double("Status", :exitstatus => 2) - allow(@provider).to receive(:output_of_command).and_return([@status, "failure failure", "problem problem"]) - expect(@provider).to receive(:output_of_command).once.with( + @status = double("Status", :exitstatus => 2, :stdout => "failure failure", :stderr => "problem problem") + allow(@provider).to receive(:shell_out).and_return(@status) + expect(@provider).to receive(:shell_out).once.with( "yum -d0 -e0 -y install emacs-1.0", {:timeout => Chef::Config[:yum_timeout]} ) @@ -716,9 +716,10 @@ describe Chef::Provider::Package::Yum do end it "should run yum once if it exits with a return code of 1 and %pre scriptlet failures" do - @status = double("Status", :exitstatus => 1) - allow(@provider).to receive(:output_of_command).and_return([@status, "error: %pre(demo-1-1.el5.centos.x86_64) scriptlet failed, exit status 2", ""]) - expect(@provider).to receive(:output_of_command).once.with( + @status = double("Status", :exitstatus => 1, :stdout => "error: %pre(demo-1-1.el5.centos.x86_64) scriptlet failed, exit status 2", + :stderr => "") + allow(@provider).to receive(:shell_out).and_return(@status) + expect(@provider).to receive(:shell_out).once.with( "yum -d0 -e0 -y install emacs-1.0", {:timeout => Chef::Config[:yum_timeout]} ) @@ -727,9 +728,10 @@ describe Chef::Provider::Package::Yum do end it "should run yum twice if it exits with a return code of 1 and %post scriptlet failures" do - @status = double("Status", :exitstatus => 1) - allow(@provider).to receive(:output_of_command).and_return([@status, "error: %post(demo-1-1.el5.centos.x86_64) scriptlet failed, exit status 2", ""]) - expect(@provider).to receive(:output_of_command).twice.with( + @status = double("Status", :exitstatus => 1, :stdout => "error: %post(demo-1-1.el5.centos.x86_64) scriptlet failed, exit status 2", + :stderr => "") + allow(@provider).to receive(:shell_out).and_return(@status) + expect(@provider).to receive(:shell_out).twice.with( "yum -d0 -e0 -y install emacs-1.0", {:timeout => Chef::Config[:yum_timeout]} ) @@ -2061,4 +2063,4 @@ describe "Chef::Provider::Package::Yum - Multi" do @provider.install_package(["cups", "vim"], ["1.2.4-11.19.el5", '1.0']) end end -end
\ No newline at end of file +end diff --git a/spec/unit/windows_service_spec.rb b/spec/unit/windows_service_spec.rb index cf933a9ab2..bc5e781c03 100644 --- a/spec/unit/windows_service_spec.rb +++ b/spec/unit/windows_service_spec.rb @@ -39,16 +39,33 @@ describe "Chef::Application::WindowsService", :windows_only do allow(instance).to receive(:state).and_return(4) instance.service_main end - it "passes config params to new process" do - Chef::Config.merge!({:log_location => tempfile.path, :config_file => "test_config_file", :log_level => :info}) - expect(instance).to receive(:configure_chef).twice - instance.service_init - allow(instance).to receive(:running?).and_return(true, false) - allow(instance.instance_variable_get(:@service_signal)).to receive(:wait) - allow(instance).to receive(:state).and_return(4) - expect(instance).to receive(:run_chef_client).and_call_original - expect(instance).to receive(:shell_out).with("chef-client --no-fork -c test_config_file -L #{tempfile.path}").and_return(shell_out_result) - instance.service_main - tempfile.unlink + + context 'when running chef-client' do + it "passes config params to new process with a default timeout of 2 hours (7200 seconds)" do + Chef::Config.merge!({:log_location => tempfile.path, :config_file => "test_config_file", :log_level => :info}) + expect(instance).to receive(:configure_chef).twice + instance.service_init + allow(instance).to receive(:running?).and_return(true, false) + allow(instance.instance_variable_get(:@service_signal)).to receive(:wait) + allow(instance).to receive(:state).and_return(4) + expect(instance).to receive(:run_chef_client).and_call_original + expect(instance).to receive(:shell_out).with("chef-client --no-fork -c test_config_file -L #{tempfile.path}", {:timeout => 7200}).and_return(shell_out_result) + instance.service_main + tempfile.unlink + end + + it "passes config params to new process with a the timeout specified in the config" do + Chef::Config.merge!({:log_location => tempfile.path, :config_file => "test_config_file", :log_level => :info}) + Chef::Config[:windows_service][:watchdog_timeout] = 10 + expect(instance).to receive(:configure_chef).twice + instance.service_init + allow(instance).to receive(:running?).and_return(true, false) + allow(instance.instance_variable_get(:@service_signal)).to receive(:wait) + allow(instance).to receive(:state).and_return(4) + expect(instance).to receive(:run_chef_client).and_call_original + expect(instance).to receive(:shell_out).with("chef-client --no-fork -c test_config_file -L #{tempfile.path}", {:timeout => 10}).and_return(shell_out_result) + instance.service_main + tempfile.unlink + end end end |