Class: Chef::Provider::Service::Windows

Inherits:
Chef::Provider::Service show all
Includes:
Mixin::ShellOut, Win32ServiceConstants
Defined in:
lib/chef/provider/service/windows.rb

Constant Summary collapse

AUTO_START =

Win32::Service.get_start_type

"auto start".freeze
MANUAL =
"demand start".freeze
DISABLED =
"disabled".freeze
RUNNING =

Win32::Service.get_current_state

"running".freeze
STOPPED =
"stopped".freeze
CONTINUE_PENDING =
"continue pending".freeze
PAUSE_PENDING =
"pause pending".freeze
PAUSED =
"paused".freeze
START_PENDING =
"start pending".freeze
STOP_PENDING =
"stop pending".freeze
TIMEOUT =
60
SERVICE_RIGHT =
"SeServiceLogonRight".freeze

Constants included from Win32ServiceConstants

Win32ServiceConstants::DELETE, Win32ServiceConstants::ERROR_FILE_NOT_FOUND, Win32ServiceConstants::ERROR_INSUFFICIENT_BUFFER, Win32ServiceConstants::ERROR_MORE_DATA, Win32ServiceConstants::ERROR_RESOURCE_NAME_NOT_FOUND, Win32ServiceConstants::ERROR_RESOURCE_TYPE_NOT_FOUND, Win32ServiceConstants::FORMAT_MESSAGE_FROM_SYSTEM, Win32ServiceConstants::FORMAT_MESSAGE_IGNORE_INSERTS, Win32ServiceConstants::IDLE_CONTROL_CODE, Win32ServiceConstants::INFINITE, Win32ServiceConstants::NO_ERROR, Win32ServiceConstants::SC_ACTION_NONE, Win32ServiceConstants::SC_ACTION_REBOOT, Win32ServiceConstants::SC_ACTION_RESTART, Win32ServiceConstants::SC_ACTION_RUN_COMMAND, Win32ServiceConstants::SC_ENUM_PROCESS_INFO, Win32ServiceConstants::SC_MANAGER_ALL_ACCESS, Win32ServiceConstants::SC_MANAGER_CONNECT, Win32ServiceConstants::SC_MANAGER_CREATE_SERVICE, Win32ServiceConstants::SC_MANAGER_ENUMERATE_SERVICE, Win32ServiceConstants::SC_MANAGER_LOCK, Win32ServiceConstants::SC_MANAGER_MODIFY_BOOT_CONFIG, Win32ServiceConstants::SC_MANAGER_QUERY_LOCK_STATUS, Win32ServiceConstants::SC_STATUS_PROCESS_INFO, Win32ServiceConstants::SERVICE_ACCEPT_HARDWAREPROFILECHANGE, Win32ServiceConstants::SERVICE_ACCEPT_NETBINDCHANGE, Win32ServiceConstants::SERVICE_ACCEPT_PARAMCHANGE, Win32ServiceConstants::SERVICE_ACCEPT_PAUSE_CONTINUE, Win32ServiceConstants::SERVICE_ACCEPT_POWEREVENT, Win32ServiceConstants::SERVICE_ACCEPT_PRESHUTDOWN, Win32ServiceConstants::SERVICE_ACCEPT_SESSIONCHANGE, Win32ServiceConstants::SERVICE_ACCEPT_SHUTDOWN, Win32ServiceConstants::SERVICE_ACCEPT_STOP, Win32ServiceConstants::SERVICE_ACCEPT_TIMECHANGE, Win32ServiceConstants::SERVICE_ACCEPT_TRIGGEREVENT, Win32ServiceConstants::SERVICE_ACTIVE, Win32ServiceConstants::SERVICE_ADAPTER, Win32ServiceConstants::SERVICE_ALL_ACCESS, Win32ServiceConstants::SERVICE_AUTO_START, Win32ServiceConstants::SERVICE_BOOT_START, Win32ServiceConstants::SERVICE_CHANGE_CONFIG, Win32ServiceConstants::SERVICE_CONFIG_DELAYED_AUTO_START_INFO, Win32ServiceConstants::SERVICE_CONFIG_DESCRIPTION, Win32ServiceConstants::SERVICE_CONFIG_FAILURE_ACTIONS, Win32ServiceConstants::SERVICE_CONFIG_FAILURE_ACTIONS_FLAG, Win32ServiceConstants::SERVICE_CONFIG_PRESHUTDOWN_INFO, Win32ServiceConstants::SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO, Win32ServiceConstants::SERVICE_CONFIG_SERVICE_SID_INFO, Win32ServiceConstants::SERVICE_CONTINUE_PENDING, Win32ServiceConstants::SERVICE_CONTROL_CONTINUE, Win32ServiceConstants::SERVICE_CONTROL_DEVICEEVENT, Win32ServiceConstants::SERVICE_CONTROL_HARDWAREPROFILECHANGE, Win32ServiceConstants::SERVICE_CONTROL_INTERROGATE, Win32ServiceConstants::SERVICE_CONTROL_NETBINDADD, Win32ServiceConstants::SERVICE_CONTROL_NETBINDDISABLE, Win32ServiceConstants::SERVICE_CONTROL_NETBINDENABLE, Win32ServiceConstants::SERVICE_CONTROL_NETBINDREMOVE, Win32ServiceConstants::SERVICE_CONTROL_PARAMCHANGE, Win32ServiceConstants::SERVICE_CONTROL_PAUSE, Win32ServiceConstants::SERVICE_CONTROL_POWEREVENT, Win32ServiceConstants::SERVICE_CONTROL_PRESHUTDOWN, Win32ServiceConstants::SERVICE_CONTROL_SESSIONCHANGE, Win32ServiceConstants::SERVICE_CONTROL_SHUTDOWN, Win32ServiceConstants::SERVICE_CONTROL_STOP, Win32ServiceConstants::SERVICE_CONTROL_TIMECHANGE, Win32ServiceConstants::SERVICE_CONTROL_TRIGGEREVENT, Win32ServiceConstants::SERVICE_DEMAND_START, Win32ServiceConstants::SERVICE_DISABLED, Win32ServiceConstants::SERVICE_DRIVER, Win32ServiceConstants::SERVICE_ENUMERATE_DEPENDENTS, Win32ServiceConstants::SERVICE_ERROR_CRITICAL, Win32ServiceConstants::SERVICE_ERROR_IGNORE, Win32ServiceConstants::SERVICE_ERROR_NORMAL, Win32ServiceConstants::SERVICE_ERROR_SEVERE, Win32ServiceConstants::SERVICE_FILE_SYSTEM_DRIVER, Win32ServiceConstants::SERVICE_INACTIVE, Win32ServiceConstants::SERVICE_INTERACTIVE_PROCESS, Win32ServiceConstants::SERVICE_INTERROGATE, Win32ServiceConstants::SERVICE_KERNEL_DRIVER, Win32ServiceConstants::SERVICE_NO_CHANGE, Win32ServiceConstants::SERVICE_PAUSED, Win32ServiceConstants::SERVICE_PAUSE_CONTINUE, Win32ServiceConstants::SERVICE_PAUSE_PENDING, Win32ServiceConstants::SERVICE_QUERY_CONFIG, Win32ServiceConstants::SERVICE_QUERY_STATUS, Win32ServiceConstants::SERVICE_RECOGNIZER_DRIVER, Win32ServiceConstants::SERVICE_RUNNING, Win32ServiceConstants::SERVICE_START, Win32ServiceConstants::SERVICE_START_PENDING, Win32ServiceConstants::SERVICE_STATE_ALL, Win32ServiceConstants::SERVICE_STOP, Win32ServiceConstants::SERVICE_STOPPED, Win32ServiceConstants::SERVICE_STOP_PENDING, Win32ServiceConstants::SERVICE_SYSTEM_START, Win32ServiceConstants::SERVICE_TYPE_ALL, Win32ServiceConstants::SERVICE_USER_DEFINED_CONTROL, Win32ServiceConstants::SERVICE_WIN32, Win32ServiceConstants::SERVICE_WIN32_OWN_PROCESS, Win32ServiceConstants::SERVICE_WIN32_SHARE_PROCESS, Win32ServiceConstants::SE_PRIVILEGE_ENABLED, Win32ServiceConstants::TOKEN_ADJUST_PRIVILEGES, Win32ServiceConstants::TOKEN_QUERY, Win32ServiceConstants::WAIT_FAILED, Win32ServiceConstants::WAIT_OBJECT_0, Win32ServiceConstants::WAIT_TIMEOUT

Instance Attribute Summary

Attributes inherited from Chef::Provider

#action, #current_resource, #logger, #new_resource, #recipe_name, #run_context

Instance Method Summary collapse

Methods included from Mixin::ShellOut

apply_default_env, maybe_add_timeout, #shell_out, #shell_out!

Methods inherited from Chef::Provider::Service

#action_mask, #action_reload, #action_restart, #action_start, #action_stop, #action_unmask, #define_resource_requirements, #initialize, #load_new_resource_state, #mask_service, #reload_service, #shared_resource_requirements, #supports, #unmask_service, #user_services_requirements

Methods inherited from Chef::Provider

action, #action_nothing, #check_resource_semantics!, #cleanup_after_converge, #compile_and_converge_action, #converge_by, #converge_if_changed, #cookbook_name, #define_resource_requirements, #description, #events, include_resource_dsl?, include_resource_dsl_module, #initialize, #introduced, #node, #process_resource_requirements, provides, provides?, #requirements, #resource_collection, #resource_updated?, #run_action, #set_updated_status, supports?, use_inline_resources, #whyrun_mode?, #whyrun_supported?

Methods included from Mixin::Provides

#provided_as, #provides, #provides?

Methods included from Mixin::DescendantsTracker

#descendants, descendants, direct_descendants, #direct_descendants, find_descendants_by_name, #find_descendants_by_name, #inherited, store_inherited

Methods included from Mixin::LazyModuleInclude

#descendants, #include, #included

Methods included from Mixin::PowershellOut

#powershell_out, #powershell_out!

Methods included from Mixin::WindowsArchitectureHelper

#assert_valid_windows_architecture!, #disable_wow64_file_redirection, #forced_32bit_override_required?, #is_i386_process_on_x86_64_windows?, #node_supports_windows_architecture?, #node_windows_architecture, #restore_wow64_file_redirection, #valid_windows_architecture?, #with_os_architecture, #wow64_architecture_override_required?, #wow64_directory

Methods included from Mixin::PowershellExec

#powershell_exec

Methods included from DSL::Powershell

#ps_credential

Methods included from DSL::RegistryHelper

#registry_data_exists?, #registry_get_subkeys, #registry_get_values, #registry_has_subkeys?, #registry_key_exists?, #registry_value_exists?

Methods included from DSL::DataQuery

#data_bag, #data_bag_item, #search, #tagged?

Methods included from EncryptedDataBagItem::CheckEncrypted

#encrypted?

Methods included from DSL::PlatformIntrospection

#older_than_win_2012_or_8?, #platform?, #platform_family?, #value_for_platform, #value_for_platform_family

Methods included from Mixin::NotifyingBlock

#notifying_block, #subcontext_block

Methods included from DSL::DeclareResource

#build_resource, #declare_resource, #delete_resource, #delete_resource!, #edit_resource, #edit_resource!, #find_resource, #find_resource!, #resources, #with_run_context

Constructor Details

This class inherits a constructor from Chef::Provider::Service

Instance Method Details

#action_configure_startupObject



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# File 'lib/chef/provider/service/windows.rb', line 246

def action_configure_startup
  startup_type = @new_resource.startup_type
  if current_startup_type != startup_type
    converge_by("set service #{@new_resource} startup type to #{startup_type}") do
      set_startup_type(startup_type)
    end
  else
    logger.trace("#{@new_resource} startup_type already #{startup_type} - nothing to do")
  end

  converge_delayed_start

  # Avoid changing enabled from true/false for now
  @new_resource.enabled(nil)
end

#action_disableObject



233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/chef/provider/service/windows.rb', line 233

def action_disable
  if current_startup_type != :disabled
    converge_by("disable service #{@new_resource}") do
      disable_service
      logger.info("#{@new_resource} disabled")
    end
  else
    logger.trace("#{@new_resource} already disabled - nothing to do")
  end
  load_new_resource_state
  @new_resource.enabled(false)
end

#action_enableObject



220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/chef/provider/service/windows.rb', line 220

def action_enable
  if current_startup_type != :automatic
    converge_by("enable service #{@new_resource}") do
      enable_service
      logger.info("#{@new_resource} enabled")
    end
  else
    logger.trace("#{@new_resource} already enabled - nothing to do")
  end
  load_new_resource_state
  @new_resource.enabled(true)
end

#disable_serviceObject



173
174
175
176
177
178
179
# File 'lib/chef/provider/service/windows.rb', line 173

def disable_service
  if Win32::Service.exists?(@new_resource.service_name)
    set_startup_type(:disabled)
  else
    logger.trace "#{@new_resource} does not exist - nothing to do"
  end
end

#enable_serviceObject



165
166
167
168
169
170
171
# File 'lib/chef/provider/service/windows.rb', line 165

def enable_service
  if Win32::Service.exists?(@new_resource.service_name)
    set_startup_type(:automatic)
  else
    logger.trace "#{@new_resource} does not exist - nothing to do"
  end
end

#load_current_resourceObject



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/chef/provider/service/windows.rb', line 54

def load_current_resource
  @current_resource = Chef::Resource::WindowsService.new(new_resource.name)
  current_resource.service_name(new_resource.service_name)

  if Win32::Service.exists?(current_resource.service_name)
    current_resource.running(current_state == RUNNING)
    logger.trace "#{new_resource} running: #{current_resource.running}"
    case current_startup_type
    when :automatic
      current_resource.enabled(true)
    when :disabled
      current_resource.enabled(false)
    end
    logger.trace "#{new_resource} enabled: #{current_resource.enabled}"

    config_info = Win32::Service.config_info(current_resource.service_name)
    current_resource.service_type(get_service_type(config_info.service_type))    if config_info.service_type
    current_resource.startup_type(start_type_to_sym(config_info.start_type))     if config_info.start_type
    current_resource.error_control(get_error_control(config_info.error_control)) if config_info.error_control
    current_resource.binary_path_name(config_info.binary_path_name) if config_info.binary_path_name
    current_resource.load_order_group(config_info.load_order_group) if config_info.load_order_group
    current_resource.dependencies(config_info.dependencies)         if config_info.dependencies
    current_resource.run_as_user(config_info.service_start_name)    if config_info.service_start_name
    current_resource.display_name(config_info.display_name)         if config_info.display_name
    current_resource.delayed_start(current_delayed_start)           if current_delayed_start
  end

  current_resource
end

#restart_serviceObject



150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/chef/provider/service/windows.rb', line 150

def restart_service
  if Win32::Service.exists?(@new_resource.service_name)
    if @new_resource.restart_command
      logger.trace "#{@new_resource} restarting service using the given restart_command"
      shell_out!(@new_resource.restart_command)
    else
      stop_service
      start_service
    end
    @new_resource.updated_by_last_action(true)
  else
    logger.trace "#{@new_resource} does not exist - nothing to do"
  end
end

#start_serviceObject



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/chef/provider/service/windows.rb', line 84

def start_service
  if Win32::Service.exists?(@new_resource.service_name)
    configure_service_run_as_properties

    state = current_state
    if state == RUNNING
      logger.trace "#{@new_resource} already started - nothing to do"
    elsif state == START_PENDING
      logger.trace "#{@new_resource} already sent start signal - waiting for start"
      wait_for_state(RUNNING)
    elsif state == STOPPED
      if @new_resource.start_command
        logger.trace "#{@new_resource} starting service using the given start_command"
        shell_out!(@new_resource.start_command)
      else
        spawn_command_thread do
          begin
            Win32::Service.start(@new_resource.service_name)
          rescue SystemCallError => ex
            if ex.errno == ERROR_SERVICE_LOGON_FAILED
              logger.error ex.message
              raise Chef::Exceptions::Service,
                "Service #{@new_resource} did not start due to a logon failure (error #{ERROR_SERVICE_LOGON_FAILED}): possibly the specified user '#{@new_resource.run_as_user}' does not have the 'log on as a service' privilege, or the password is incorrect."
            else
              raise ex
            end
          end
        end
        wait_for_state(RUNNING)
      end
      @new_resource.updated_by_last_action(true)
    else
      raise Chef::Exceptions::Service, "Service #{@new_resource} can't be started from state [#{state}]"
    end
  else
    logger.trace "#{@new_resource} does not exist - nothing to do"
  end
end

#stop_serviceObject



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/chef/provider/service/windows.rb', line 123

def stop_service
  if Win32::Service.exists?(@new_resource.service_name)
    state = current_state
    if state == RUNNING
      if @new_resource.stop_command
        logger.trace "#{@new_resource} stopping service using the given stop_command"
        shell_out!(@new_resource.stop_command)
      else
        spawn_command_thread do
          Win32::Service.stop(@new_resource.service_name)
        end
        wait_for_state(STOPPED)
      end
      @new_resource.updated_by_last_action(true)
    elsif state == STOPPED
      logger.trace "#{@new_resource} already stopped - nothing to do"
    elsif state == STOP_PENDING
      logger.trace "#{@new_resource} already sent stop signal - waiting for stop"
      wait_for_state(STOPPED)
    else
      raise Chef::Exceptions::Service, "Service #{@new_resource} can't be stopped from state [#{state}]"
    end
  else
    logger.trace "#{@new_resource} does not exist - nothing to do"
  end
end