diff options
Diffstat (limited to 'lib/puppet/provider/service/windows.rb')
-rw-r--r-- | lib/puppet/provider/service/windows.rb | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/lib/puppet/provider/service/windows.rb b/lib/puppet/provider/service/windows.rb new file mode 100644 index 000000000..289be697a --- /dev/null +++ b/lib/puppet/provider/service/windows.rb @@ -0,0 +1,110 @@ +# Windows Service Control Manager (SCM) provider + +require 'win32/service' if Puppet.features.microsoft_windows? + +Puppet::Type.type(:service).provide :windows do + + desc "Support for Windows Service Control Manager (SCM). + + Services are controlled according to win32-service gem. + + * All SCM operations (start/stop/enable/disable/query) are supported. + + * Control of service groups (dependencies) is not yet supported." + + defaultfor :operatingsystem => :windows + confine :operatingsystem => :windows + + has_feature :refreshable + + def enable + w32ss = Win32::Service.configure( 'service_name' => @resource[:name], 'start_type' => Win32::Service::SERVICE_AUTO_START ) + raise Puppet::Error.new("Win32 service enable of #{@resource[:name]} failed" ) if( w32ss.nil? ) + rescue Win32::Service::Error => detail + raise Puppet::Error.new("Cannot enable #{@resource[:name]}, error was: #{detail}" ) + end + + def disable + w32ss = Win32::Service.configure( 'service_name' => @resource[:name], 'start_type' => Win32::Service::SERVICE_DISABLED ) + raise Puppet::Error.new("Win32 service disable of #{@resource[:name]} failed" ) if( w32ss.nil? ) + rescue Win32::Service::Error => detail + raise Puppet::Error.new("Cannot disable #{@resource[:name]}, error was: #{detail}" ) + end + + def manual_start + w32ss = Win32::Service.configure( 'service_name' => @resource[:name], 'start_type' => Win32::Service::SERVICE_DEMAND_START ) + raise Puppet::Error.new("Win32 service manual enable of #{@resource[:name]} failed" ) if( w32ss.nil? ) + rescue Win32::Service::Error => detail + raise Puppet::Error.new("Cannot enable #{@resource[:name]} for manual start, error was: #{detail}" ) + end + + def enabled? + w32ss = Win32::Service.config_info( @resource[:name] ) + raise Puppet::Error.new("Win32 service query of #{@resource[:name]} failed" ) unless( !w32ss.nil? && w32ss.instance_of?( Struct::ServiceConfigInfo ) ) + debug("Service #{@resource[:name]} start type is #{w32ss.start_type}") + case w32ss.start_type + when Win32::Service.get_start_type(Win32::Service::SERVICE_AUTO_START), + Win32::Service.get_start_type(Win32::Service::SERVICE_BOOT_START), + Win32::Service.get_start_type(Win32::Service::SERVICE_SYSTEM_START) + :true + when Win32::Service.get_start_type(Win32::Service::SERVICE_DEMAND_START) + :manual + when Win32::Service.get_start_type(Win32::Service::SERVICE_DISABLED) + :false + else + raise Puppet::Error.new("Unknown start type: #{w32ss.start_type}") + end + rescue Win32::Service::Error => detail + raise Puppet::Error.new("Cannot get start type for #{@resource[:name]}, error was: #{detail}" ) + end + + def start + if enabled? == :false + # If disabled and not managing enable, respect disabled and fail. + if @resource[:enable].nil? + raise Puppet::Error, "Will not start disabled service #{@resource[:name]} without managing enable. Specify 'enable => false' to override." + # Otherwise start. If enable => false, we will later sync enable and + # disable the service again. + elsif @resource[:enable] == :true + enable + else + manual_start + end + end + + Win32::Service.start( @resource[:name] ) + rescue Win32::Service::Error => detail + raise Puppet::Error.new("Cannot start #{@resource[:name]}, error was: #{detail}" ) + end + + def stop + Win32::Service.stop( @resource[:name] ) + rescue Win32::Service::Error => detail + raise Puppet::Error.new("Cannot stop #{@resource[:name]}, error was: #{detail}" ) + end + + def restart + self.stop + self.start + end + + def status + w32ss = Win32::Service.status( @resource[:name] ) + raise Puppet::Error.new("Win32 service query of #{@resource[:name]} failed" ) unless( !w32ss.nil? && w32ss.instance_of?( Struct::ServiceStatus ) ) + state = case w32ss.current_state + when "stopped", "pause pending", "stop pending", "paused" then :stopped + when "running", "continue pending", "start pending" then :running + else + raise Puppet::Error.new("Unknown service state '#{w32ss.current_state}' for service '#{@resource[:name]}'") + end + debug("Service #{@resource[:name]} is #{w32ss.current_state}") + return state + rescue Win32::Service::Error => detail + raise Puppet::Error.new("Cannot get status of #{@resource[:name]}, error was: #{detail}" ) + end + + # returns all providers for all existing services and startup state + def self.instances + Win32::Service.services.collect { |s| new(:name => s.service_name) } + end +end |