summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt <code@deployable.org>2013-12-05 13:01:10 +0000
committerMatt <code@deployable.org>2013-12-05 13:01:10 +0000
commitc9ba5a629e88cf51af240c711befbc1d093367ad (patch)
tree3f7c171e4e412ccc4cd8fbb22eb8246505fec616
parentecbc917ac5496f3138b798332ea66f477c33f8ba (diff)
downloadchef-c9ba5a629e88cf51af240c711befbc1d093367ad.tar.gz
CHEF-4791 Add more windows service states to the start/stop control flow
http://msdn.microsoft.com/en-us/library/windows/desktop/ee126211(v=vs.85).aspx
-rw-r--r--lib/chef/provider/service/windows.rb36
-rw-r--r--spec/unit/provider/service/windows_spec.rb20
2 files changed, 50 insertions, 6 deletions
diff --git a/lib/chef/provider/service/windows.rb b/lib/chef/provider/service/windows.rb
index ba51e53bed..f4aa28999e 100644
--- a/lib/chef/provider/service/windows.rb
+++ b/lib/chef/provider/service/windows.rb
@@ -28,11 +28,19 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
include Chef::Mixin::ShellOut
- RUNNING = 'running'
- STOPPED = 'stopped'
+ #Win32::Service.get_start_type
AUTO_START = 'auto start'
DISABLED = 'disabled'
+ #Win32::Service.get_current_state
+ RUNNING = 'running'
+ STOPPED = 'stopped'
+ CONTINUE_PENDING = 'continue pending'
+ PAUSE_PENDING = 'pause pending'
+ PAUSED = 'paused'
+ START_PENDING = 'start pending'
+ STOP_PENDING = 'stop pending'
+
def whyrun_supported?
false
end
@@ -49,9 +57,15 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
def start_service
if Win32::Service.exists?(@new_resource.service_name)
- if current_state == RUNNING
+ state = current_state
+ if state == RUNNING
Chef::Log.debug "#{@new_resource} already started - nothing to do"
- else
+ elsif state == START_PENDING
+ Chef::Log.debug "#{@new_resource} already sent start signal - waiting for start"
+ spawn_command_thread do
+ wait_for_state(RUNNING)
+ end
+ elsif state == STOPPED
if @new_resource.start_command
Chef::Log.debug "#{@new_resource} starting service using the given start_command"
shell_out!(@new_resource.start_command)
@@ -62,6 +76,8 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
end
end
@new_resource.updated_by_last_action(true)
+ else
+ raise Chef::Exceptions::Service, "Service #{@new_resource} can't be started from state [#{current_state}]"
end
else
Chef::Log.debug "#{@new_resource} does not exist - nothing to do"
@@ -70,7 +86,8 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
def stop_service
if Win32::Service.exists?(@new_resource.service_name)
- if current_state == RUNNING
+ state = current_state
+ if state == RUNNING
if @new_resource.stop_command
Chef::Log.debug "#{@new_resource} stopping service using the given stop_command"
shell_out!(@new_resource.stop_command)
@@ -81,8 +98,15 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
end
end
@new_resource.updated_by_last_action(true)
+ elsif state == STOPPED
+ Chef::Log.debug "#{@new_resource} already stopped - nothing to do"
+ elsif state == STOP_PENDING
+ Chef::Log.debug "#{@new_resource} already sent stop signal - waiting for stop"
+ spawn_command_thread do
+ wait_for_state(STOPPED)
+ end
else
- Chef::Log.debug "#{@new_resource} already stopped - nothing to do"
+ raise Chef::Exceptions::Service, "Service #{@new_resource} can't be stopped from state [#{current_state}]"
end
else
Chef::Log.debug "#{@new_resource} does not exist - nothing to do"
diff --git a/spec/unit/provider/service/windows_spec.rb b/spec/unit/provider/service/windows_spec.rb
index 7ec4ccf96a..69e942cf16 100644
--- a/spec/unit/provider/service/windows_spec.rb
+++ b/spec/unit/provider/service/windows_spec.rb
@@ -92,6 +92,16 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
@provider.start_service
@new_resource.updated_by_last_action?.should be_false
end
+
+ it "should raise an error if the service is paused" do
+ Win32::Service.stub!(:status).with(@new_resource.service_name).and_return(
+ mock("StatusStruct", :current_state => "paused"))
+ @provider.load_current_resource
+ Win32::Service.should_not_receive(:start).with(@new_resource.service_name)
+ expect { @provider.start_service }.to raise_error( Chef::Exceptions::Service )
+ @new_resource.updated_by_last_action?.should be_false
+ end
+
end
describe Chef::Provider::Service::Windows, "stop_service" do
@@ -130,6 +140,16 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
@provider.stop_service
@new_resource.updated_by_last_action?.should be_false
end
+
+ it "should raise an error if the service is paused" do
+ Win32::Service.stub!(:status).with(@new_resource.service_name).and_return(
+ mock("StatusStruct", :current_state => "paused"))
+ @provider.load_current_resource
+ Win32::Service.should_not_receive(:start).with(@new_resource.service_name)
+ expect { @provider.start_service }.to raise_error( Chef::Exceptions::Service )
+ @new_resource.updated_by_last_action?.should be_false
+ end
+
end
describe Chef::Provider::Service::Windows, "restart_service" do