summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSalim Alam <salam@chef.io>2015-09-22 16:33:10 -0700
committerSalim Alam <salam@chef.io>2015-09-22 16:33:10 -0700
commit0d93133c31704711b2bb6a20db74a83dc1b23493 (patch)
tree9d77bff914c9841b09c307424f5af6ebe1e046b2
parent48cc7a968c861db91c1b1b2a627c5672240c2e80 (diff)
parent9efa0d89d2c344c1b383626ad6ffc56169bde5c9 (diff)
downloadchef-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.rb16
-rw-r--r--lib/chef/provider/package/windows/msi.rb4
-rw-r--r--spec/unit/platform/query_helpers_spec.rb49
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