From 07da5a4c2498ca68d485ef927dd23e5308d6e62b Mon Sep 17 00:00:00 2001 From: Mike Dodge Date: Tue, 10 Mar 2015 02:22:17 -0700 Subject: Load LaunchAgents as console user, adding plist and session_type options Proposed changes to chef mac osx service provider. This adds two resource parameters, @plist and @session_type and changes logic to Load LaunchAgents as Console user @plist: Adds the logic to handle (https://github.com/chef/chef/issues/2200) by Giving the user the option to pass a plist, in the case that the plist name and label name don't match. @session_type to help account launching the service as the console user with a different session type. ( Im a Facebook employee and PhilD will do the final merge. ) --- lib/chef/provider/service/macosx.rb | 84 +++++++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 27 deletions(-) (limited to 'lib/chef/provider/service') diff --git a/lib/chef/provider/service/macosx.rb b/lib/chef/provider/service/macosx.rb index 10ad1aa29d..b92deeaf42 100644 --- a/lib/chef/provider/service/macosx.rb +++ b/lib/chef/provider/service/macosx.rb @@ -1,3 +1,4 @@ +# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2 # # Author:: Igor Afonov # Copyright:: Copyright (c) 2011 Igor Afonov @@ -16,6 +17,7 @@ # limitations under the License. # +require 'etc' require 'rexml/document' require 'chef/resource/service' require 'chef/provider/service/simple' @@ -44,8 +46,25 @@ class Chef @current_resource = Chef::Resource::Service.new(@new_resource.name) @current_resource.service_name(@new_resource.service_name) @plist_size = 0 - @plist = find_service_plist + @plist = @new_resource.plist ? @new_resource.plist : find_service_plist + Chef::Log.debug("Plist: '#{@plist}'") @service_label = find_service_label + Chef::Log.debug("Service_Label: '#{@service_label}'") + # LauchAgents should be loaded as the console user. + @console_user = @plist.include?('LaunchAgents') + @session_type = @new_resource.session_type + + if @console_user + @console_user = Etc.getlogin + Chef::Log.debug("Console User: '#{@console_user}'") + cmd = "su " + param = '' + param = "-l " if not node['platform_version'].include?('10.10') + @base_user_cmd = cmd + param + "#{@console_user} -c " + # Default LauchAgent session should be Aqua + @session_type = 'Aqua' if @session_type.nil? + end + set_service_status @current_resource @@ -86,7 +105,7 @@ class Chef if @new_resource.start_command super else - shell_out_with_systems_locale!("launchctl load -w '#{@plist}'", :user => @owner_uid, :group => @owner_gid) + load_service end end end @@ -98,7 +117,7 @@ class Chef if @new_resource.stop_command super else - shell_out_with_systems_locale!("launchctl unload '#{@plist}'", :user => @owner_uid, :group => @owner_gid) + unload_service end end end @@ -107,9 +126,9 @@ class Chef if @new_resource.restart_command super else - stop_service + unload_service sleep 1 - start_service + load_service end end @@ -122,10 +141,7 @@ class Chef if @current_resource.enabled Chef::Log.debug("#{@new_resource} already enabled, not enabling") else - shell_out!( - "launchctl load -w '#{@plist}'", - :user => @owner_uid, :group => @owner_gid - ) + load_service end end @@ -133,38 +149,50 @@ class Chef unless @current_resource.enabled Chef::Log.debug("#{@new_resource} not enabled, not disabling") else - shell_out!( - "launchctl unload -w '#{@plist}'", - :user => @owner_uid, :group => @owner_gid - ) + unload_service + end + end + + def load_service + session = @session_type ? "-S #{@session_type}" : '' + cmd = 'launchctl load -w ' + session + @plist + shell_out_with_su?(cmd) + end + + def unload_service + session = @session_type ? "-S #{@session_type}" : '' + cmd = 'launchctl unload -w ' + session + @plist + shell_out_with_su?(cmd) + end + + def shell_out_with_su?(cmd) + if @console_user + shell_out_with_systems_locale("#{@base_user_cmd} '#{cmd}'") + else + shell_out_with_systems_locale(cmd) + end end def set_service_status return if @plist == nil or @service_label.to_s.empty? - cmd = shell_out( - "launchctl list #{@service_label}", - :user => @owner_uid, :group => @owner_gid - ) + cmd = "launchctl list #{@service_label}" + res = shell_out_with_su?(cmd) - if cmd.exitstatus == 0 + if res.exitstatus == 0 @current_resource.enabled(true) else @current_resource.enabled(false) end if @current_resource.enabled - @owner_uid = ::File.stat(@plist).uid - @owner_gid = ::File.stat(@plist).gid - - shell_out!( - "launchctl list", :user => @owner_uid, :group => @owner_gid - ).stdout.each_line do |line| - case line - when /(\d+|-)\s+(?:\d+|-)\s+(.*\.?)#{@service_label}/ + res.stdout.each_line do |line| + case line.downcase + when /\s+\"pid\"\s+=\s+(\d+).*/ pid = $1 @current_resource.running(!pid.to_i.zero?) + Chef::Log.debug("Current PID for #{@service_label} is #{pid}") end end else @@ -186,7 +214,9 @@ class Chef # plist files can come in XML or Binary formats. this command # will make sure we get XML every time. - plist_xml = shell_out!("plutil -convert xml1 -o - #{@plist}").stdout + plist_xml = shell_out_with_systems_locale!( + "plutil -convert xml1 -o - #{@plist}" + ).stdout plist_doc = REXML::Document.new(plist_xml) plist_doc.elements[ -- cgit v1.2.1 From d931e5eab8fae4204e7415d82f6b492f490df18d Mon Sep 17 00:00:00 2001 From: Mike Dodge Date: Tue, 10 Mar 2015 23:46:21 -0700 Subject: small change to the base user cmd --- lib/chef/provider/service/macosx.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/chef/provider/service') diff --git a/lib/chef/provider/service/macosx.rb b/lib/chef/provider/service/macosx.rb index b92deeaf42..4a782146c0 100644 --- a/lib/chef/provider/service/macosx.rb +++ b/lib/chef/provider/service/macosx.rb @@ -58,8 +58,7 @@ class Chef @console_user = Etc.getlogin Chef::Log.debug("Console User: '#{@console_user}'") cmd = "su " - param = '' - param = "-l " if not node['platform_version'].include?('10.10') + param = !node['platform_version'].include?('10.10') ? '-l ' : '' @base_user_cmd = cmd + param + "#{@console_user} -c " # Default LauchAgent session should be Aqua @session_type = 'Aqua' if @session_type.nil? -- cgit v1.2.1 From a3fd8c19d9634588444c11928337ad6b52520572 Mon Sep 17 00:00:00 2001 From: Mike Dodge Date: Thu, 12 Mar 2015 00:01:08 -0700 Subject: First pass at fixing the unit tests --- lib/chef/provider/service/macosx.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'lib/chef/provider/service') diff --git a/lib/chef/provider/service/macosx.rb b/lib/chef/provider/service/macosx.rb index 4a782146c0..fa178466a9 100644 --- a/lib/chef/provider/service/macosx.rb +++ b/lib/chef/provider/service/macosx.rb @@ -20,6 +20,7 @@ require 'etc' require 'rexml/document' require 'chef/resource/service' +require 'chef/resource/macosx_service' require 'chef/provider/service/simple' require 'chef/util/path_helper' @@ -29,6 +30,7 @@ class Chef class Macosx < Chef::Provider::Service::Simple provides :service, os: "darwin" + provides :macosx_service, os: "darwin" def self.gather_plist_dirs locations = %w{/Library/LaunchAgents @@ -43,7 +45,7 @@ class Chef PLIST_DIRS = gather_plist_dirs def load_current_resource - @current_resource = Chef::Resource::Service.new(@new_resource.name) + @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 @@ -51,7 +53,7 @@ class Chef @service_label = find_service_label Chef::Log.debug("Service_Label: '#{@service_label}'") # LauchAgents should be loaded as the console user. - @console_user = @plist.include?('LaunchAgents') + @console_user = @plist ? @plist.include?('LaunchAgents') : false @session_type = @new_resource.session_type if @console_user @@ -59,7 +61,7 @@ class Chef Chef::Log.debug("Console User: '#{@console_user}'") cmd = "su " param = !node['platform_version'].include?('10.10') ? '-l ' : '' - @base_user_cmd = cmd + param + "#{@console_user} -c " + @base_user_cmd = cmd + param + "#{@console_user} -c" # Default LauchAgent session should be Aqua @session_type = 'Aqua' if @session_type.nil? end @@ -153,14 +155,13 @@ class Chef end def load_service - session = @session_type ? "-S #{@session_type}" : '' + session = @session_type ? "-S #{@session_type} " : '' cmd = 'launchctl load -w ' + session + @plist shell_out_with_su?(cmd) end def unload_service - session = @session_type ? "-S #{@session_type}" : '' - cmd = 'launchctl unload -w ' + session + @plist + cmd = 'launchctl unload -w ' + @plist shell_out_with_su?(cmd) end -- cgit v1.2.1 From 6ef7ea3b49ff5f3166be5dcbd718076993a781ea Mon Sep 17 00:00:00 2001 From: Mike Dodge Date: Tue, 24 Mar 2015 11:18:20 -0700 Subject: removing vim comment (sorry its a habit to add) --- lib/chef/provider/service/macosx.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/chef/provider/service') diff --git a/lib/chef/provider/service/macosx.rb b/lib/chef/provider/service/macosx.rb index fa178466a9..1c6952bb81 100644 --- a/lib/chef/provider/service/macosx.rb +++ b/lib/chef/provider/service/macosx.rb @@ -1,4 +1,3 @@ -# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2 # # Author:: Igor Afonov # Copyright:: Copyright (c) 2011 Igor Afonov -- cgit v1.2.1 From 5b8fcf1e8285643e797090de505f33d5aab2a89f Mon Sep 17 00:00:00 2001 From: Mike Dodge Date: Wed, 25 Mar 2015 00:10:04 -0700 Subject: addressed each of the comments --- lib/chef/provider/service/macosx.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/chef/provider/service') diff --git a/lib/chef/provider/service/macosx.rb b/lib/chef/provider/service/macosx.rb index 1c6952bb81..82c66c3199 100644 --- a/lib/chef/provider/service/macosx.rb +++ b/lib/chef/provider/service/macosx.rb @@ -48,16 +48,16 @@ class Chef @current_resource.service_name(@new_resource.service_name) @plist_size = 0 @plist = @new_resource.plist ? @new_resource.plist : find_service_plist - Chef::Log.debug("Plist: '#{@plist}'") + Chef::Log.debug("#{new_resource} Plist: '#{@plist}'") @service_label = find_service_label - Chef::Log.debug("Service_Label: '#{@service_label}'") + Chef::Log.debug("#{new_resource} service_label: '#{@service_label}'") # LauchAgents 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.getlogin - Chef::Log.debug("Console User: '#{@console_user}'") + Chef::Log.debug("#{new_resource} console_user: '#{@console_user}'") cmd = "su " param = !node['platform_version'].include?('10.10') ? '-l ' : '' @base_user_cmd = cmd + param + "#{@console_user} -c" -- cgit v1.2.1 From 0d1bc71edebcf4b7e11b5640c9331bc13030bf91 Mon Sep 17 00:00:00 2001 From: Mike Dodge Date: Thu, 26 Mar 2015 15:09:19 -0700 Subject: added requsted chagnes --- lib/chef/provider/service/macosx.rb | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'lib/chef/provider/service') diff --git a/lib/chef/provider/service/macosx.rb b/lib/chef/provider/service/macosx.rb index 82c66c3199..38ea6124bf 100644 --- a/lib/chef/provider/service/macosx.rb +++ b/lib/chef/provider/service/macosx.rb @@ -96,6 +96,11 @@ class Chef @current_resource.running(false) end end + + requirements.assert(:all_actions) do |a| + a.assertion { @plist.nil? ? true : ::File.exists?(@plist) } + a.failure_message Chef::Exceptions::Service, "#{@plist} does not exist" + end end def start_service @@ -156,15 +161,15 @@ class Chef def load_service session = @session_type ? "-S #{@session_type} " : '' cmd = 'launchctl load -w ' + session + @plist - shell_out_with_su?(cmd) + shell_out_as_user(cmd) end def unload_service cmd = 'launchctl unload -w ' + @plist - shell_out_with_su?(cmd) + shell_out_as_user(cmd) end - def shell_out_with_su?(cmd) + def shell_out_as_user(cmd) if @console_user shell_out_with_systems_locale("#{@base_user_cmd} '#{cmd}'") else @@ -177,7 +182,7 @@ class Chef return if @plist == nil or @service_label.to_s.empty? cmd = "launchctl list #{@service_label}" - res = shell_out_with_su?(cmd) + res = shell_out_as_user(cmd) if res.exitstatus == 0 @current_resource.enabled(true) -- cgit v1.2.1 From 73fd4949b2ab478e377bb352f90172c8a060e36e Mon Sep 17 00:00:00 2001 From: Mike Dodge Date: Thu, 26 Mar 2015 15:29:42 -0700 Subject: moved around debugs --- lib/chef/provider/service/macosx.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/chef/provider/service') diff --git a/lib/chef/provider/service/macosx.rb b/lib/chef/provider/service/macosx.rb index 38ea6124bf..fbc16d6d53 100644 --- a/lib/chef/provider/service/macosx.rb +++ b/lib/chef/provider/service/macosx.rb @@ -48,9 +48,7 @@ class Chef @current_resource.service_name(@new_resource.service_name) @plist_size = 0 @plist = @new_resource.plist ? @new_resource.plist : find_service_plist - Chef::Log.debug("#{new_resource} Plist: '#{@plist}'") @service_label = find_service_label - Chef::Log.debug("#{new_resource} service_label: '#{@service_label}'") # LauchAgents should be loaded as the console user. @console_user = @plist ? @plist.include?('LaunchAgents') : false @session_type = @new_resource.session_type @@ -65,6 +63,7 @@ class Chef @session_type = 'Aqua' if @session_type.nil? end + Chef::Log.debug("#{new_resource} Plist: '#{@plist}' service_label: '#{@service_label}'") set_service_status @current_resource -- cgit v1.2.1 From 04bd76a051270d529333c943e27fc2154378954f Mon Sep 17 00:00:00 2001 From: Mike Dodge Date: Thu, 26 Mar 2015 18:22:28 -0700 Subject: fix some typos in comments --- lib/chef/provider/service/macosx.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/chef/provider/service') diff --git a/lib/chef/provider/service/macosx.rb b/lib/chef/provider/service/macosx.rb index fbc16d6d53..4c40c5c865 100644 --- a/lib/chef/provider/service/macosx.rb +++ b/lib/chef/provider/service/macosx.rb @@ -70,7 +70,6 @@ class Chef end def define_resource_requirements - #super requirements.assert(:reload) do |a| a.failure_message Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :reload" end @@ -88,7 +87,7 @@ class Chef requirements.assert(:all_actions) do |a| a.assertion { @plist_size > 0 } - # No failrue here in original code - so we also will not + # 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) -- cgit v1.2.1 From 455aaf2b879f341eea406b2004ff9524544da96e Mon Sep 17 00:00:00 2001 From: Mike Dodge Date: Wed, 1 Apr 2015 13:35:03 -0700 Subject: adding assert for plist --- lib/chef/provider/service/macosx.rb | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'lib/chef/provider/service') diff --git a/lib/chef/provider/service/macosx.rb b/lib/chef/provider/service/macosx.rb index 4c40c5c865..f6a4c1a9c3 100644 --- a/lib/chef/provider/service/macosx.rb +++ b/lib/chef/provider/service/macosx.rb @@ -79,6 +79,12 @@ class Chef 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, @@ -94,11 +100,6 @@ class Chef @current_resource.running(false) end end - - requirements.assert(:all_actions) do |a| - a.assertion { @plist.nil? ? true : ::File.exists?(@plist) } - a.failure_message Chef::Exceptions::Service, "#{@plist} does not exist" - end end def start_service @@ -209,6 +210,9 @@ class Chef # 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 -- cgit v1.2.1