summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Murawski <steven.murawski@gmail.com>2015-11-13 17:56:21 -0600
committerSteven Murawski <steven.murawski@gmail.com>2015-11-18 10:18:50 -0600
commit9f6a1bbe020c2664fbe96f18ed8d5861a9e3da84 (patch)
treeaad306daf0b56602f050204747e24b1bfece1cec
parentfbdf03d3c174f1c2309a497efcf92227e191fdc0 (diff)
downloadchef-9f6a1bbe020c2664fbe96f18ed8d5861a9e3da84.tar.gz
WMF 5 RTM and Win 10 Threshold 2 allow the RefreshMode to be enabled.
-rw-r--r--lib/chef/platform/query_helpers.rb17
-rw-r--r--lib/chef/provider/dsc_resource.rb28
-rw-r--r--spec/unit/provider/dsc_resource_spec.rb103
3 files changed, 102 insertions, 46 deletions
diff --git a/lib/chef/platform/query_helpers.rb b/lib/chef/platform/query_helpers.rb
index dfb99ed750..699e98737c 100644
--- a/lib/chef/platform/query_helpers.rb
+++ b/lib/chef/platform/query_helpers.rb
@@ -85,10 +85,12 @@ class Chef
end
def supports_dsc_invoke_resource?(node)
- require 'rubygems'
supports_dsc?(node) &&
- Gem::Version.new(node[:languages][:powershell][:version]) >=
- Gem::Version.new("5.0.10018.0")
+ supported_powershell_version?(node, "5.0.10018.0")
+ end
+
+ def supports_refresh_mode_enabled?(node)
+ supported_powershell_version?(node, "5.0.10586.0")
end
def dsc_refresh_mode_disabled?(node)
@@ -97,6 +99,15 @@ class Chef
metadata = cmdlet.run!.return_value
metadata['RefreshMode'] == 'Disabled'
end
+
+
+ def supported_powershell_version?(node, version_string)
+ return false unless node[:languages] && node[:languages][:powershell]
+ require 'rubygems'
+ Gem::Version.new(node[:languages][:powershell][:version]) >=
+ Gem::Version.new(version_string)
+ end
+
end
end
end
diff --git a/lib/chef/provider/dsc_resource.rb b/lib/chef/provider/dsc_resource.rb
index c06e062e3c..212e3b0e09 100644
--- a/lib/chef/provider/dsc_resource.rb
+++ b/lib/chef/provider/dsc_resource.rb
@@ -19,6 +19,7 @@ require 'chef/util/powershell/cmdlet'
require 'chef/util/dsc/local_configuration_manager'
require 'chef/mixin/powershell_type_coercions'
require 'chef/util/dsc/resource_store'
+
class Chef
class Provider
class DscResource < Chef::Provider
@@ -30,6 +31,7 @@ class Chef
@module_name = new_resource.module_name
@reboot_resource = nil
end
+
def action_run
if ! test_resource
converge_by(generate_description) do
@@ -38,11 +40,14 @@ class Chef
end
end
end
+
def load_current_resource
end
+
def whyrun_supported?
true
end
+
def define_resource_requirements
requirements.assert(:run) do |a|
a.assertion { supports_dsc_invoke_resource? }
@@ -53,35 +58,48 @@ class Chef
a.block_action!
end
requirements.assert(:run) do |a|
- a.assertion { dsc_refresh_mode_disabled? }
- err = ["The LCM must have its RefreshMode set to Disabled. "]
+ a.assertion { supports_refresh_mode_enabled? || dsc_refresh_mode_disabled? }
+ err = ["The LCM must have its RefreshMode set to Disabled for" \
+ " PowerShell versions before 5.0.10586.0."]
a.failure_message Chef::Exceptions::ProviderNotFound, err.join(' ')
a.whyrun err + ["Assuming a previous resource sets the RefreshMode."]
a.block_action!
end
end
+
protected
+
def local_configuration_manager
@local_configuration_manager ||= Chef::Util::DSC::LocalConfigurationManager.new(
node,
nil
)
end
+
def resource_store
Chef::Util::DSC::ResourceStore.instance
end
+
def supports_dsc_invoke_resource?
run_context && Chef::Platform.supports_dsc_invoke_resource?(node)
end
+
def dsc_refresh_mode_disabled?
Chef::Platform.dsc_refresh_mode_disabled?(node)
end
+
+ def supports_refresh_mode_enabled?
+ Chef::Platform.supports_refresh_mode_enabled?(node)
+ end
+
def generate_description
@converge_description
end
+
def dsc_resource_name
new_resource.resource.to_s
end
+
def module_name
@module_name ||= begin
found = resource_store.find(dsc_resource_name)
@@ -101,6 +119,7 @@ class Chef
end
end
end
+
def test_resource
result = invoke_resource(:test)
# We really want this information from the verbose stream,
@@ -109,6 +128,7 @@ class Chef
@converge_description = result.stdout
return_dsc_resource_result(result, "InDesiredState")
end
+
def set_resource
result = invoke_resource(:set)
if return_dsc_resource_result(result, 'RebootRequired')
@@ -116,6 +136,7 @@ class Chef
end
result.return_value
end
+
def invoke_resource(method, output_format=:object)
properties = translate_type(@new_resource.properties)
switches = "-Method #{method.to_s} -Name #{@new_resource.resource}"\
@@ -130,6 +151,7 @@ class Chef
)
cmdlet.run!
end
+
def return_dsc_resource_result(result, property_name)
if result.return_value.is_a?(Array)
# WMF Feb 2015 Preview
@@ -139,6 +161,7 @@ class Chef
result.return_value[property_name]
end
end
+
def create_reboot_resource
@reboot_resource = Chef::Resource::Reboot.new(
"Reboot for #{@new_resource.name}",
@@ -147,6 +170,7 @@ class Chef
r.reason("Reboot for #{@new_resource.resource}.")
end
end
+
def reboot_if_required
reboot_action = @new_resource.reboot_action
unless @reboot_resource.nil?
diff --git a/spec/unit/provider/dsc_resource_spec.rb b/spec/unit/provider/dsc_resource_spec.rb
index b95b1d7bcf..46cdbd93a6 100644
--- a/spec/unit/provider/dsc_resource_spec.rb
+++ b/spec/unit/provider/dsc_resource_spec.rb
@@ -41,55 +41,76 @@ describe Chef::Provider::DscResource do
end
context 'when Powershell supports Invoke-DscResource' do
+
+ context 'when RefreshMode is not set to Disabled' do
+ context 'and the WMF 5 is a preview release' do
+ let (:node) {
+ node = Chef::Node.new
+ node.automatic[:languages][:powershell][:version] = '5.0.10018.0'
+ node
+ }
+ it 'raises an exception' do
+ expect(provider).to receive(:dsc_refresh_mode_disabled?).and_return(false)
+ expect { provider.run_action(:run) }.to raise_error(
+ Chef::Exceptions::ProviderNotFound, /Disabled/)
+ end
+ end
+ context 'and the WMF is 5 RTM or newer' do
+ let (:node) {
+ node = Chef::Node.new
+ node.automatic[:languages][:powershell][:version] = '5.0.10586.0'
+ node
+ }
+ it 'does not raises an exception' do
+ expect(provider).to receive(:test_resource)
+ expect(provider).to receive(:set_resource)
+ expect(provider).to receive(:reboot_if_required)
+ expect { provider.run_action(:run) }.to_not raise_error
+ end
+ end
+ end
+ end
+
+ context 'when the LCM supports Invoke-DscResource' do
let (:node) {
node = Chef::Node.new
node.automatic[:languages][:powershell][:version] = '5.0.10018.0'
node
}
- context 'when RefreshMode is not set to Disabled' do
- it 'raises an exception' do
- expect(provider).to receive(:dsc_refresh_mode_disabled?).and_return(false)
- expect { provider.run_action(:run) }.to raise_error(
- Chef::Exceptions::ProviderNotFound, /Disabled/)
- end
+ it 'does not update the resource if it is up to date' do
+ expect(provider).to receive(:dsc_refresh_mode_disabled?).and_return(true)
+ expect(provider).to receive(:test_resource).and_return(true)
+ provider.run_action(:run)
+ expect(resource).not_to be_updated
end
- context 'when RefreshMode is set to Disabled' do
- it 'does not update the resource if it is up to date' do
- expect(provider).to receive(:dsc_refresh_mode_disabled?).and_return(true)
- expect(provider).to receive(:test_resource).and_return(true)
- provider.run_action(:run)
- expect(resource).not_to be_updated
- end
-
- it 'converges the resource if it is not up to date' do
- expect(provider).to receive(:dsc_refresh_mode_disabled?).and_return(true)
- expect(provider).to receive(:test_resource).and_return(false)
- expect(provider).to receive(:set_resource)
- provider.run_action(:run)
- expect(resource).to be_updated
- end
-
- it 'flags the resource as reboot required when required' do
- expect(provider).to receive(:dsc_refresh_mode_disabled?).and_return(true)
- expect(provider).to receive(:test_resource).and_return(false)
- expect(provider).to receive(:invoke_resource).
- and_return(double(:stdout => '', :return_value =>nil))
- expect(provider).to receive(:return_dsc_resource_result).and_return(true)
- expect(provider).to receive(:create_reboot_resource)
- provider.run_action(:run)
- end
-
- it 'does not flag the resource as reboot required when not required' do
- expect(provider).to receive(:dsc_refresh_mode_disabled?).and_return(true)
- expect(provider).to receive(:test_resource).and_return(false)
- expect(provider).to receive(:invoke_resource).
- and_return(double(:stdout => '', :return_value =>nil))
- expect(provider).to receive(:return_dsc_resource_result).and_return(false)
- expect(provider).to_not receive(:create_reboot_resource)
- provider.run_action(:run)
- end
+ it 'converges the resource if it is not up to date' do
+ expect(provider).to receive(:dsc_refresh_mode_disabled?).and_return(true)
+ expect(provider).to receive(:test_resource).and_return(false)
+ expect(provider).to receive(:set_resource)
+ provider.run_action(:run)
+ expect(resource).to be_updated
+ end
+
+ it 'flags the resource as reboot required when required' do
+ expect(provider).to receive(:dsc_refresh_mode_disabled?).and_return(true)
+ expect(provider).to receive(:test_resource).and_return(false)
+ expect(provider).to receive(:invoke_resource).
+ and_return(double(:stdout => '', :return_value =>nil))
+ expect(provider).to receive(:return_dsc_resource_result).and_return(true)
+ expect(provider).to receive(:create_reboot_resource)
+ provider.run_action(:run)
+ end
+
+ it 'does not flag the resource as reboot required when not required' do
+ expect(provider).to receive(:dsc_refresh_mode_disabled?).and_return(true)
+ expect(provider).to receive(:test_resource).and_return(false)
+ expect(provider).to receive(:invoke_resource).
+ and_return(double(:stdout => '', :return_value =>nil))
+ expect(provider).to receive(:return_dsc_resource_result).and_return(false)
+ expect(provider).to_not receive(:create_reboot_resource)
+ provider.run_action(:run)
end
end
end \ No newline at end of file