class Chef::Provider::Service::Macosx
Constants
- PLIST_DIRS
Public Class Methods
gather_plist_dirs()
click to toggle source
# File lib/chef/provider/service/macosx.rb, line 34 def self.gather_plist_dirs locations = %w{/Library/LaunchAgents /Library/LaunchDaemons /System/Library/LaunchAgents /System/Library/LaunchDaemons } Chef::Util::PathHelper.home("Library", "LaunchAgents") { |p| locations << p } locations end
Public Instance Methods
define_resource_requirements()
click to toggle source
# File lib/chef/provider/service/macosx.rb, line 76 def define_resource_requirements requirements.assert(:reload) do |a| a.failure_message Chef::Exceptions::UnsupportedAction, "#{self} does not support :reload" end requirements.assert(:all_actions) do |a| a.assertion { @plist_size < 2 } a.failure_message Chef::Exceptions::Service, "Several plist files match service name. Please use full service name." end requirements.assert(:all_actions) do |a| a.assertion { ::File.exists?(@plist.to_s) } a.failure_message Chef::Exceptions::Service, "Could not find plist for #{@new_resource}" end requirements.assert(:enable, :disable) do |a| a.assertion { !@service_label.to_s.empty? } a.failure_message Chef::Exceptions::Service, "Could not find service's label in plist file '#{@plist}'!" end requirements.assert(:all_actions) do |a| a.assertion { @plist_size > 0 } # No failure here in original code - so we also will not # fail. Instead warn that the service is potentially missing a.whyrun "Assuming that the service would have been previously installed and is currently disabled." do @current_resource.enabled(false) @current_resource.running(false) end end end
disable_service()
click to toggle source
# File lib/chef/provider/service/macosx.rb, line 156 def disable_service unless @current_resource.enabled logger.trace("#{@new_resource} not enabled, not disabling") else unload_service end end
enable_service()
click to toggle source
On OS/X, enabling a service has the side-effect of starting it, and disabling a service has the side-effect of stopping it.
This makes some sense on OS/X since launchctl is an “init”-style supervisor that will restart daemons that are crashing, etc.
# File lib/chef/provider/service/macosx.rb, line 148 def enable_service if @current_resource.enabled logger.trace("#{@new_resource} already enabled, not enabling") else load_service end end
load_current_resource()
click to toggle source
# File lib/chef/provider/service/macosx.rb, line 49 def load_current_resource @current_resource = Chef::Resource::MacosxService.new(@new_resource.name) @current_resource.service_name(@new_resource.service_name) @plist_size = 0 @plist = @new_resource.plist ? @new_resource.plist : find_service_plist @service_label = find_service_label # LaunchAgents should be loaded as the console user. @console_user = @plist ? @plist.include?("LaunchAgents") : false @session_type = @new_resource.session_type if @console_user @console_user = Etc.getpwuid(::File.stat("/dev/console").uid).name logger.trace("#{new_resource} console_user: '#{@console_user}'") cmd = "su " param = this_version_or_newer?("10.10") ? "" : "-l " param = "-l " if this_version_or_newer?("10.12") @base_user_cmd = cmd + param + "#{@console_user} -c" # Default LaunchAgent session should be Aqua @session_type = "Aqua" if @session_type.nil? end logger.trace("#{new_resource} Plist: '#{@plist}' service_label: '#{@service_label}'") set_service_status @current_resource end
load_service()
click to toggle source
# File lib/chef/provider/service/macosx.rb, line 164 def load_service session = @session_type ? "-S #{@session_type} " : "" cmd = "launchctl load -w " + session + @plist shell_out_as_user(cmd) end
restart_service()
click to toggle source
Calls superclass method
Chef::Provider::Service::Simple#restart_service
# File lib/chef/provider/service/macosx.rb, line 133 def restart_service if @new_resource.restart_command super else unload_service sleep 1 load_service end end
set_service_status()
click to toggle source
# File lib/chef/provider/service/macosx.rb, line 184 def set_service_status return if @plist.nil? || @service_label.to_s.empty? cmd = "launchctl list #{@service_label}" res = shell_out_as_user(cmd) if res.exitstatus == 0 @current_resource.enabled(true) else @current_resource.enabled(false) end if @current_resource.enabled res.stdout.each_line do |line| case line.downcase when /\s+\"pid\"\s+=\s+(\d+).*/ pid = $1 @current_resource.running(pid.to_i != 0) logger.trace("Current PID for #{@service_label} is #{pid}") end end else @current_resource.running(false) end end
shell_out_as_user(cmd)
click to toggle source
# File lib/chef/provider/service/macosx.rb, line 175 def shell_out_as_user(cmd) if @console_user shell_out_with_systems_locale("#{@base_user_cmd} '#{cmd}'") else shell_out_with_systems_locale(cmd) end end
start_service()
click to toggle source
Calls superclass method
Chef::Provider::Service::Simple#start_service
# File lib/chef/provider/service/macosx.rb, line 109 def start_service if @current_resource.running logger.trace("#{@new_resource} already running, not starting") else if @new_resource.start_command super else load_service end end end
stop_service()
click to toggle source
Calls superclass method
Chef::Provider::Service::Simple#stop_service
# File lib/chef/provider/service/macosx.rb, line 121 def stop_service unless @current_resource.running logger.trace("#{@new_resource} not running, not stopping") else if @new_resource.stop_command super else unload_service end end end
this_version_or_newer?(this_version)
click to toggle source
# File lib/chef/provider/service/macosx.rb, line 45 def this_version_or_newer?(this_version) Gem::Version.new(node["platform_version"]) >= Gem::Version.new(this_version) end
unload_service()
click to toggle source
# File lib/chef/provider/service/macosx.rb, line 170 def unload_service cmd = "launchctl unload -w " + @plist shell_out_as_user(cmd) end
Private Instance Methods
find_service_label()
click to toggle source
# File lib/chef/provider/service/macosx.rb, line 212 def find_service_label # CHEF-5223 "you can't glob for a file that hasn't been converged # onto the node yet." return nil if @plist.nil? # Plist must exist by this point raise Chef::Exceptions::FileNotFound, "Cannot find #{@plist}!" unless ::File.exists?(@plist) # Most services have the same internal label as the name of the # plist file. However, there is no rule saying that *has* to be # the case, and some core services (notably, ssh) do not follow # this rule. # plist files can come in XML or Binary formats. this command # will make sure we get XML every time. plist_xml = shell_out_with_systems_locale!( "plutil -convert xml1 -o - #{@plist}" ).stdout plist_doc = REXML::Document.new(plist_xml) plist_doc.elements[ "/plist/dict/key[text()='Label']/following::string[1]/text()"] end
find_service_plist()
click to toggle source
# File lib/chef/provider/service/macosx.rb, line 236 def find_service_plist plists = PLIST_DIRS.inject([]) do |results, dir| edir = ::File.expand_path(dir) entries = Dir.glob( "#{edir}/*#{Chef::Util::PathHelper.escape_glob_dir(@current_resource.service_name)}*.plist" ) entries.any? ? results << entries : results end plists.flatten! @plist_size = plists.size plists.first end