summaryrefslogtreecommitdiff
path: root/lib/chef/provider/service/debian.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chef/provider/service/debian.rb')
-rw-r--r--lib/chef/provider/service/debian.rb152
1 files changed, 152 insertions, 0 deletions
diff --git a/lib/chef/provider/service/debian.rb b/lib/chef/provider/service/debian.rb
new file mode 100644
index 0000000000..e2a0f60d91
--- /dev/null
+++ b/lib/chef/provider/service/debian.rb
@@ -0,0 +1,152 @@
+#
+# Author:: AJ Christensen (<aj@hjksolutions.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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.
+#
+
+require 'chef/provider/service'
+require 'chef/provider/service/init'
+require 'chef/mixin/command'
+
+class Chef
+ class Provider
+ class Service
+ class Debian < Chef::Provider::Service::Init
+ UPDATE_RC_D_ENABLED_MATCHES = /\/rc[\dS].d\/S|not installed/i
+ UPDATE_RC_D_PRIORITIES = /\/rc([\dS]).d\/([SK])(\d\d)/i
+
+ def load_current_resource
+ super
+ @priority_success = true
+ @rcd_status = nil
+ @current_resource.priority(get_priority)
+ @current_resource.enabled(service_currently_enabled?(@current_resource.priority))
+ @current_resource
+ end
+
+ def define_resource_requirements
+ # do not call super here, inherit only shared_requirements
+ shared_resource_requirements
+ requirements.assert(:all_actions) do |a|
+ update_rcd = "/usr/sbin/update-rc.d"
+ a.assertion { ::File.exists? update_rcd }
+ a.failure_message Chef::Exceptions::Service, "#{update_rcd} does not exist!"
+ # no whyrun recovery - this is a base system component of debian
+ # distros and must be present
+ end
+
+ requirements.assert(:all_actions) do |a|
+ a.assertion { @priority_success }
+ a.failure_message Chef::Exceptions::Service, "/usr/sbin/update-rc.d -n -f #{@current_resource.service_name} failed - #{@rcd_status.inspect}"
+ # This can happen if the service is not yet installed,so we'll fake it.
+ a.whyrun ["Unable to determine priority of service, assuming service would have been correctly installed earlier in the run.",
+ "Assigning temporary priorities to continue.",
+ "If this service is not properly installed prior to this point, this will fail."] do
+ temp_priorities = {"6"=>[:stop, "20"],
+ "0"=>[:stop, "20"],
+ "1"=>[:stop, "20"],
+ "2"=>[:start, "20"],
+ "3"=>[:start, "20"],
+ "4"=>[:start, "20"],
+ "5"=>[:start, "20"]}
+ @current_resource.priority(temp_priorities)
+ end
+ end
+ end
+
+ def get_priority
+ priority = {}
+
+ @rcd_status = popen4("/usr/sbin/update-rc.d -n -f #{@current_resource.service_name} remove") do |pid, stdin, stdout, stderr|
+
+ [stdout, stderr].each do |iop|
+ iop.each_line do |line|
+ if UPDATE_RC_D_PRIORITIES =~ line
+ # priority[runlevel] = [ S|K, priority ]
+ # S = Start, K = Kill
+ # debian runlevels: 0 Halt, 1 Singleuser, 2 Multiuser, 3-5 == 2, 6 Reboot
+ priority[$1] = [($2 == "S" ? :start : :stop), $3]
+ end
+ if line =~ UPDATE_RC_D_ENABLED_MATCHES
+ enabled = true
+ end
+ end
+ end
+ end
+
+ unless @rcd_status.exitstatus == 0
+ @priority_success = false
+ end
+ priority
+ end
+
+ def service_currently_enabled?(priority)
+ enabled = false
+ priority.each { |runlevel, arguments|
+ Chef::Log.debug("#{@new_resource} runlevel #{runlevel}, action #{arguments[0]}, priority #{arguments[1]}")
+ # if we are in a update-rc.d default startup runlevel && we start in this runlevel
+ if (2..5).include?(runlevel.to_i) && arguments[0] == :start
+ enabled = true
+ end
+ }
+
+ enabled
+ end
+
+ def enable_service()
+ if @new_resource.priority.is_a? Integer
+ run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
+ run_command(:command => "/usr/sbin/update-rc.d #{@new_resource.service_name} defaults #{@new_resource.priority} #{100 - @new_resource.priority}")
+ elsif @new_resource.priority.is_a? Hash
+ # we call the same command regardless of we're enabling or disabling
+ # users passing a Hash are responsible for setting their own start priorities
+ set_priority()
+ else # No priority, go with update-rc.d defaults
+ run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
+ run_command(:command => "/usr/sbin/update-rc.d #{@new_resource.service_name} defaults")
+ end
+
+ end
+
+ def disable_service()
+ if @new_resource.priority.is_a? Integer
+ # Stop processes in reverse order of start using '100 - start_priority'
+ run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
+ run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} stop #{100 - @new_resource.priority} 2 3 4 5 .")
+ elsif @new_resource.priority.is_a? Hash
+ # we call the same command regardless of we're enabling or disabling
+ # users passing a Hash are responsible for setting their own stop priorities
+ set_priority()
+ else
+ # no priority, using '100 - 20 (update-rc.d default)' to stop in reverse order of start
+ run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
+ run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} stop 80 2 3 4 5 .")
+ end
+ end
+
+ def set_priority()
+ args = ""
+ @new_resource.priority.each do |level, o|
+ action = o[0]
+ priority = o[1]
+ args += "#{action} #{priority} #{level} . "
+ end
+ run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
+ run_command(:command => "/usr/sbin/update-rc.d #{@new_resource.service_name} #{args}")
+ end
+ end
+ end
+ end
+end