diff options
Diffstat (limited to 'lib/chef/application/windows_service_manager.rb')
-rw-r--r-- | lib/chef/application/windows_service_manager.rb | 205 |
1 files changed, 0 insertions, 205 deletions
diff --git a/lib/chef/application/windows_service_manager.rb b/lib/chef/application/windows_service_manager.rb deleted file mode 100644 index 4f0de26411..0000000000 --- a/lib/chef/application/windows_service_manager.rb +++ /dev/null @@ -1,205 +0,0 @@ -# -# Author:: Seth Chisamore (<schisamo@chef.io>) -# Copyright:: Copyright (c) Chef Software Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -if RUBY_PLATFORM.match?(/mswin|mingw32|windows/) - require "win32/service" -end -require_relative "../config" -require "mixlib/cli" unless defined?(Mixlib::CLI) -require "chef-utils/dist" unless defined?(ChefUtils::Dist) - -class Chef - class Application - # - # This class is used to create and manage a windows service. - # Service should be created using Daemon class from - # win32/service gem. - # For an example see: Chef::Application::WindowsService - # - # Outside programs are expected to use this class to manage - # windows services. - # - class WindowsServiceManager - include Mixlib::CLI - - option :action, - short: "-a ACTION", - long: "--action ACTION", - default: "status", - description: "Action to carry out on #{ChefUtils::Dist::Infra::SHORT}-service (install, uninstall, status, start, stop, pause, or resume)." - - option :config_file, - short: "-c CONFIG", - long: "--config CONFIG", - default: "#{ChefConfig::Config.c_chef_dir}/client.rb", - description: "The configuration file to use for #{ChefUtils::Dist::Infra::PRODUCT} runs." - - option :log_location, - short: "-L LOGLOCATION", - long: "--logfile LOGLOCATION", - description: "Set the log file location for #{ChefUtils::Dist::Infra::SHORT}-service." - - option :help, - short: "-h", - long: "--help", - description: "Show this help message.", - on: :tail, - boolean: true, - show_options: true, - exit: 0 - - option :version, - short: "-v", - long: "--version", - description: "Show #{ChefUtils::Dist::Infra::PRODUCT} version.", - boolean: true, - proc: lambda { |v| puts "#{ChefUtils::Dist::Infra::PRODUCT}: #{::Chef::VERSION}" }, - exit: 0 - - def initialize(service_options) - # having to call super in initialize is the most annoying - # anti-pattern :( - super() - - raise ArgumentError, "Service definition is not provided" if service_options.nil? - - required_options = %i{service_name service_display_name service_description service_file_path} - - required_options.each do |req_option| - unless service_options.key?(req_option) - raise ArgumentError, "Service definition doesn't contain required option #{req_option}" - end - end - - @service_name = service_options[:service_name] - @service_display_name = service_options[:service_display_name] - @service_description = service_options[:service_description] - @service_file_path = service_options[:service_file_path] - @service_start_name = service_options[:run_as_user] - @password = service_options[:run_as_password] - @delayed_start = service_options[:delayed_start] - @dependencies = service_options[:dependencies] - end - - def run(params = ARGV) - parse_options(params) - - case config[:action] - when "install" - if service_exists? - puts "Service #{@service_name} already exists on the system." - else - ruby = File.join(RbConfig::CONFIG["bindir"], "ruby") - - opts = "" - opts << " -c #{config[:config_file]}" if config[:config_file] - opts << " -L #{config[:log_location]}" if config[:log_location] - - # Quote the full paths to deal with possible spaces in the path name. - # Also ensure all forward slashes are backslashes - cmd = "\"#{ruby}\" \"#{@service_file_path}\" #{opts}".gsub(File::SEPARATOR, File::ALT_SEPARATOR) - - ::Win32::Service.new( - service_name: @service_name, - display_name: @service_display_name, - description: @service_description, - # Prior to 0.8.5, win32-service creates interactive services by default, - # and we don't want that, so we need to override the service type. - service_type: ::Win32::Service::SERVICE_WIN32_OWN_PROCESS, - start_type: ::Win32::Service::SERVICE_AUTO_START, - binary_path_name: cmd, - service_start_name: @service_start_name, - password: @password, - dependencies: @dependencies - ) - unless @delayed_start.nil? - ::Win32::Service.configure( - service_name: @service_name, - delayed_start: @delayed_start - ) - end - puts "Service '#{@service_name}' has successfully been installed." - end - when "status" - if !service_exists? - puts "Service #{@service_name} doesn't exist on the system." - else - puts "State of #{@service_name} service is: #{current_state}" - end - when "start" - # TODO: allow override of startup parameters here? - take_action("start", RUNNING) - when "stop" - take_action("stop", STOPPED) - when "uninstall", "delete" - take_action("stop", STOPPED) - unless service_exists? - puts "Service #{@service_name} doesn't exist on the system." - else - ::Win32::Service.delete(@service_name) - puts "Service #{@service_name} deleted" - end - when "pause" - take_action("pause", PAUSED) - when "resume" - take_action("resume", RUNNING) - end - end - - private - - # Just some state constants - STOPPED = "stopped".freeze - RUNNING = "running".freeze - PAUSED = "paused".freeze - - def service_exists? - ::Win32::Service.exists?(@service_name) - end - - def take_action(action = nil, desired_state = nil) - if service_exists? - if current_state != desired_state - ::Win32::Service.send(action, @service_name) - wait_for_state(desired_state) - puts "Service '#{@service_name}' is now '#{current_state}'." - else - puts "Service '#{@service_name}' is already '#{desired_state}'." - end - else - puts "Cannot '#{action}' service '#{@service_name}'" - puts "Service #{@service_name} doesn't exist on the system." - end - end - - def current_state - ::Win32::Service.status(@service_name).current_state - end - - # Helper method that waits for a status to change its state since state - # changes aren't usually instantaneous. - def wait_for_state(desired_state) - while current_state != desired_state - puts "One moment... #{current_state}" - sleep 1 - end - end - - end - end -end |