summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Dodge <mikedodge04@fb.com>2015-03-10 02:22:17 -0700
committerMike Dodge <mikedodge04@fb.com>2015-03-10 02:22:17 -0700
commitbe5d288671bf5460f227c1b5297f300d36388c20 (patch)
tree67c4f3eb5294dcbba0bb3929fd60a174df2ea173
parent4b0f63b90cc72365fccd3f4f2e07721de7af80e6 (diff)
downloadchef-be5d288671bf5460f227c1b5297f300d36388c20.tar.gz
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. )
-rw-r--r--lib/chef/provider/service/macosx.rb78
-rw-r--r--lib/chef/resource/service.rb21
2 files changed, 73 insertions, 26 deletions
diff --git a/lib/chef/provider/service/macosx.rb b/lib/chef/provider/service/macosx.rb
index 10ad1aa29d..f66614e1f9 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 <afonov@gmail.com>
# 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 "
+ cmd << "-l " if not node['platform_version'].include?('10.10')
+ cmd << "#{@console_user} -c "
+ @base_user_cmd = cmd
+ # 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,20 +149,32 @@ 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
+ cmd = 'launchctl load -w '
+ cmd << "-S #{@session_type} " if @session_type
+ cmd << @plist
+ cmd = "#{@base_user_cmd} '#{cmd}'" if @console_user
+ shell_out_with_systems_locale!(cmd)
+ end
+
+ def unload_service
+ cmd = 'launchctl unload -w '
+ cmd << "-S #{@session_type} " if @session_type
+ cmd << @plist
+ cmd = "#{@base_user_cmd} '#{cmd}'" if @console_user
+ shell_out_with_systems_locale!(cmd)
+ 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}"
+ cmd = "#{@base_user_cmd} '#{cmd}'" if @console_user
+ cmd = shell_out_with_systems_locale(cmd)
if cmd.exitstatus == 0
@current_resource.enabled(true)
@@ -155,16 +183,12 @@ class Chef
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}/
+ cmd.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 +210,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[
diff --git a/lib/chef/resource/service.rb b/lib/chef/resource/service.rb
index 36df7c859a..119ae94de6 100644
--- a/lib/chef/resource/service.rb
+++ b/lib/chef/resource/service.rb
@@ -1,3 +1,4 @@
+# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
#
# Author:: AJ Christensen (<aj@hjksolutions.com>)
# Author:: Tyler Cloke (<tyler@opscode.com>)
@@ -46,6 +47,8 @@ class Chef
@action = "nothing"
@supports = { :restart => false, :reload => false, :status => false }
@allowed_actions.push(:enable, :disable, :start, :stop, :restart, :reload)
+ @plist = nil
+ @session_type = nil
end
def service_name(arg=nil)
@@ -175,6 +178,24 @@ class Chef
)
end
+ # This will enable user to pass a plist in the case that the filename
+ # and label for the service dont match
+ def plist(arg=nil)
+ set_or_return(
+ :plist,
+ arg,
+ :kind_of => String
+ )
+ end
+
+ def session_type(arg=nil)
+ set_or_return(
+ :session_type,
+ arg,
+ :kind_of => String
+ )
+ end
+
def supports(args={})
if args.is_a? Array
args.each { |arg| @supports[arg] = true }