diff options
author | Salim Alam <salam@chef.io> | 2015-09-22 16:33:10 -0700 |
---|---|---|
committer | Salim Alam <salam@chef.io> | 2015-09-22 16:33:10 -0700 |
commit | 0d93133c31704711b2bb6a20db74a83dc1b23493 (patch) | |
tree | 9d77bff914c9841b09c307424f5af6ebe1e046b2 | |
parent | 48cc7a968c861db91c1b1b2a627c5672240c2e80 (diff) | |
parent | 9efa0d89d2c344c1b383626ad6ffc56169bde5c9 (diff) | |
download | chef-0d93133c31704711b2bb6a20db74a83dc1b23493.tar.gz |
Merge pull request #3939 from chef/salam/lazy-msi
Lazy load MSI provider, add check for MSI support
-rw-r--r-- | lib/chef/platform/query_helpers.rb | 16 | ||||
-rw-r--r-- | lib/chef/provider/package/windows/msi.rb | 4 | ||||
-rw-r--r-- | spec/unit/platform/query_helpers_spec.rb | 49 |
3 files changed, 67 insertions, 2 deletions
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) diff --git a/spec/unit/platform/query_helpers_spec.rb b/spec/unit/platform/query_helpers_spec.rb index b5c56e8f9a..d18b6f7902 100644 --- a/spec/unit/platform/query_helpers_spec.rb +++ b/spec/unit/platform/query_helpers_spec.rb @@ -102,6 +102,55 @@ describe "Chef::Platform#windows_nano_server?" do end end +describe "Chef::Platform#supports_msi?" do + include_context "Win32" # clear and restore Win32:: namespace + + let(:key) { "System\\CurrentControlSet\\Services\\msiserver" } + let(:key_query_value) { 0x0001 } + let(:access) { key_query_value } + let(:hive) { double("Win32::Registry::HKEY_LOCAL_MACHINE") } + let(:registry) { double("Win32::Registry") } + + before(:all) do + Win32::Registry = Class.new + Win32::Registry::Error = Class.new(RuntimeError) + end + + before do + Win32::Registry::HKEY_LOCAL_MACHINE = hive + Win32::Registry::KEY_QUERY_VALUE = key_query_value + end + + after do + Win32::Registry.send(:remove_const, 'HKEY_LOCAL_MACHINE') if defined?(Win32::Registry::HKEY_LOCAL_MACHINE) + Win32::Registry.send(:remove_const, 'KEY_QUERY_VALUE') if defined?(Win32::Registry::KEY_QUERY_VALUE) + end + + it "returns false early when not on windows" do + allow(ChefConfig).to receive(:windows?).and_return(false) + expect(Chef::Platform).to_not receive(:require) + expect(Chef::Platform.supports_msi?).to be false + end + + it "returns true when the registry key exists" do + allow(ChefConfig).to receive(:windows?).and_return(true) + allow(Chef::Platform).to receive(:require).with('win32/registry') + expect(Win32::Registry::HKEY_LOCAL_MACHINE).to receive(:open). + with(key, access). + and_yield(registry) + expect(Chef::Platform.supports_msi?).to be true + end + + it "returns false when the registry key does not exist" do + allow(ChefConfig).to receive(:windows?).and_return(true) + allow(Chef::Platform).to receive(:require).with('win32/registry') + expect(Win32::Registry::HKEY_LOCAL_MACHINE).to receive(:open). + with(key, access). + and_raise(Win32::Registry::Error, "The system cannot find the file specified.") + expect(Chef::Platform.supports_msi?).to be false + end +end + describe 'Chef::Platform#supports_dsc?' do it 'returns false if powershell is not present' do node = Chef::Node.new |