chef 12.2.1-x86-mingw32 → 12.3.0.rc.0-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/ext/win32-eventlog/Rakefile +10 -6
  3. data/lib/chef.rb +1 -0
  4. data/lib/chef/application/apply.rb +5 -0
  5. data/lib/chef/application/client.rb +10 -0
  6. data/lib/chef/application/knife.rb +5 -1
  7. data/lib/chef/application/solo.rb +5 -0
  8. data/lib/chef/chef_class.rb +130 -0
  9. data/lib/chef/client.rb +15 -7
  10. data/lib/chef/config.rb +13 -0
  11. data/lib/chef/event_loggers/windows_eventlog.rb +11 -5
  12. data/lib/chef/http.rb +13 -3
  13. data/lib/chef/http/basic_client.rb +21 -4
  14. data/lib/chef/http/socketless_chef_zero_client.rb +207 -0
  15. data/lib/chef/knife.rb +3 -0
  16. data/lib/chef/knife/bootstrap.rb +1 -1
  17. data/lib/chef/knife/core/status_presenter.rb +12 -11
  18. data/lib/chef/knife/ssh.rb +3 -1
  19. data/lib/chef/knife/status.rb +32 -7
  20. data/lib/chef/local_mode.rb +13 -3
  21. data/lib/chef/mixin/provides.rb +32 -0
  22. data/lib/chef/platform/provider_priority_map.rb +16 -7
  23. data/lib/chef/platform/resource_priority_map.rb +37 -0
  24. data/lib/chef/policy_builder/expand_node_object.rb +14 -0
  25. data/lib/chef/policy_builder/policyfile.rb +0 -1
  26. data/lib/chef/provider.rb +5 -20
  27. data/lib/chef/provider/package/rubygems.rb +4 -1
  28. data/lib/chef/provider/service/macosx.rb +66 -30
  29. data/lib/chef/provider_resolver.rb +10 -5
  30. data/lib/chef/resource.rb +5 -39
  31. data/lib/chef/resource/gem_package.rb +5 -0
  32. data/lib/chef/resource/link.rb +1 -1
  33. data/lib/chef/resource/macosx_service.rb +59 -0
  34. data/lib/chef/resource/remote_file.rb +0 -4
  35. data/lib/chef/resource_resolver.rb +101 -0
  36. data/lib/chef/rest.rb +4 -5
  37. data/lib/chef/search/query.rb +1 -1
  38. data/lib/chef/server_api.rb +1 -0
  39. data/lib/chef/version.rb +1 -1
  40. data/spec/data/lwrp/providers/buck_passer.rb +2 -1
  41. data/spec/data/lwrp/resources/bar.rb +1 -1
  42. data/spec/data/{big_json.json → nested.json} +2 -2
  43. data/spec/functional/event_loggers/windows_eventlog_spec.rb +14 -0
  44. data/spec/functional/resource/execute_spec.rb +1 -1
  45. data/spec/integration/client/client_spec.rb +12 -1
  46. data/spec/integration/client/ipv6_spec.rb +1 -1
  47. data/spec/integration/knife/common_options_spec.rb +3 -3
  48. data/spec/integration/recipes/lwrp_inline_resources_spec.rb +1 -1
  49. data/spec/integration/solo/solo_spec.rb +7 -5
  50. data/spec/unit/application/client_spec.rb +10 -0
  51. data/spec/unit/chef_class_spec.rb +91 -0
  52. data/spec/unit/client_spec.rb +13 -0
  53. data/spec/unit/http/basic_client_spec.rb +43 -6
  54. data/spec/unit/http/socketless_chef_zero_client_spec.rb +174 -0
  55. data/spec/unit/http_spec.rb +14 -0
  56. data/spec/unit/json_compat_spec.rb +7 -20
  57. data/spec/unit/knife/ssh_spec.rb +18 -0
  58. data/spec/unit/knife/status_spec.rb +69 -3
  59. data/spec/unit/knife_spec.rb +5 -0
  60. data/spec/unit/provider/package/rubygems_spec.rb +19 -0
  61. data/spec/unit/provider/service/macosx_spec.rb +230 -203
  62. data/spec/unit/provider_resolver_spec.rb +1 -0
  63. data/spec/unit/recipe_spec.rb +48 -0
  64. data/spec/unit/resource/link_spec.rb +15 -0
  65. data/spec/unit/resource_spec.rb +6 -6
  66. data/spec/unit/rest_spec.rb +9 -0
  67. data/spec/unit/search/query_spec.rb +24 -0
  68. data/spec/unit/shell_spec.rb +3 -1
  69. metadata +16 -9
  70. data/spec/data/big_json_plus_one.json +0 -2
@@ -373,6 +373,9 @@ class Chef
373
373
  Chef::Config[:environment] = config[:environment] if config[:environment]
374
374
 
375
375
  Chef::Config.local_mode = config[:local_mode] if config.has_key?(:local_mode)
376
+
377
+ Chef::Config.listen = config[:listen] if config.has_key?(:listen)
378
+
376
379
  if Chef::Config.local_mode && !Chef::Config.has_key?(:cookbook_path) && !Chef::Config.has_key?(:chef_repo_path)
377
380
  Chef::Config.chef_repo_path = Chef::Config.find_chef_repo_path(Dir.pwd)
378
381
  end
@@ -378,7 +378,7 @@ class Chef
378
378
  command = render_template
379
379
 
380
380
  if config[:use_sudo]
381
- command = config[:use_sudo_password] ? "echo '#{config[:ssh_password]}' | sudo -S #{command}" : "sudo #{command}"
381
+ command = config[:use_sudo_password] ? "echo '#{config[:ssh_password]}' | sudo -SH #{command}" : "sudo -H #{command}"
382
382
  end
383
383
 
384
384
  command
@@ -66,16 +66,16 @@ class Chef
66
66
  list.each do |node|
67
67
  result = {}
68
68
 
69
- result["name"] = node.name
70
- result["chef_environment"] = node.chef_environment
71
- ip = (node[:ec2] && node[:ec2][:public_ipv4]) || node[:ipaddress]
72
- fqdn = (node[:ec2] && node[:ec2][:public_hostname]) || node[:fqdn]
69
+ result["name"] = node["name"] || node.name
70
+ result["chef_environment"] = node["chef_environment"]
71
+ ip = (node["ec2"] && node["ec2"]["public_ipv4"]) || node["ipaddress"]
72
+ fqdn = (node["ec2"] && node["ec2"]["public_hostname"]) || node["fqdn"]
73
73
  result["ip"] = ip if ip
74
74
  result["fqdn"] = fqdn if fqdn
75
- result["run_list"] = node.run_list if config[:run_list]
76
- result["ohai_time"] = node[:ohai_time]
77
- result["platform"] = node[:platform] if node[:platform]
78
- result["platform_version"] = node[:platform_version] if node[:platform_version]
75
+ result["run_list"] = node.run_list if config["run_list"]
76
+ result["ohai_time"] = node["ohai_time"]
77
+ result["platform"] = node["platform"] if node["platform"]
78
+ result["platform_version"] = node["platform_version"] if node["platform_version"]
79
79
 
80
80
  if config[:long_output]
81
81
  result["default"] = node.default_attrs
@@ -99,11 +99,12 @@ class Chef
99
99
  # special case ec2 with their split horizon whatsis.
100
100
  ip = (node[:ec2] && node[:ec2][:public_ipv4]) || node[:ipaddress]
101
101
  fqdn = (node[:ec2] && node[:ec2][:public_hostname]) || node[:fqdn]
102
+ name = node['name'] || node.name
102
103
 
103
- hours, minutes, seconds = time_difference_in_hms(node["ohai_time"])
104
+ hours, minutes, _ = time_difference_in_hms(node["ohai_time"])
104
105
  hours_text = "#{hours} hour#{hours == 1 ? ' ' : 's'}"
105
106
  minutes_text = "#{minutes} minute#{minutes == 1 ? ' ' : 's'}"
106
- run_list = "#{node.run_list}" if config[:run_list]
107
+ run_list = "#{node['run_list']}" if config[:run_list]
107
108
  if hours > 24
108
109
  color = :red
109
110
  text = hours_text
@@ -116,7 +117,7 @@ class Chef
116
117
  end
117
118
 
118
119
  line_parts = Array.new
119
- line_parts << @ui.color(text, color) + ' ago' << node.name
120
+ line_parts << @ui.color(text, color) + ' ago' << name
120
121
  line_parts << fqdn if fqdn
121
122
  line_parts << ip if ip
122
123
  line_parts << run_list if run_list
@@ -175,7 +175,9 @@ class Chef
175
175
  if config[:attribute_from_cli]
176
176
  Chef::Log.debug("Using node attribute '#{config[:attribute_from_cli]}' from the command line as the ssh target")
177
177
  host = extract_nested_value(item, config[:attribute_from_cli])
178
- elsif item[:cloud] && item[:cloud][:public_hostname]
178
+ elsif item[:cloud] &&
179
+ item[:cloud][:public_hostname] &&
180
+ !item[:cloud][:public_hostname].empty?
179
181
  Chef::Log.debug("Using node attribute 'cloud[:public_hostname]' automatically as the ssh target")
180
182
  host = item[:cloud][:public_hostname]
181
183
  else
@@ -18,10 +18,12 @@
18
18
 
19
19
  require 'chef/knife'
20
20
  require 'chef/knife/core/status_presenter'
21
+ require 'chef/knife/core/node_presenter'
21
22
 
22
23
  class Chef
23
24
  class Knife
24
25
  class Status < Knife
26
+ include Knife::Core::NodeFormattingOptions
25
27
 
26
28
  deps do
27
29
  require 'chef/search/query'
@@ -44,20 +46,43 @@ class Chef
44
46
  :long => "--hide-healthy",
45
47
  :description => "Hide nodes that have run chef in the last hour"
46
48
 
49
+ def append_to_query(term)
50
+ @query << " AND " unless @query.empty?
51
+ @query << term
52
+ end
53
+
47
54
  def run
48
55
  ui.use_presenter Knife::Core::StatusPresenter
49
- all_nodes = []
50
- q = Chef::Search::Query.new
51
- query = @name_args[0] ? @name_args[0].dup : '*:*'
56
+
57
+ if config[:long_output]
58
+ opts = {}
59
+ else
60
+ opts = {filter_result:
61
+ { name: ["name"], ipaddress: ["ipaddress"], ohai_time: ["ohai_time"],
62
+ ec2: ["ec2"], run_list: ["run_list"], platform: ["platform"],
63
+ platform_version: ["platform_version"], chef_environment: ["chef_environment"]}}
64
+ end
65
+
66
+ @query ||= ""
67
+ append_to_query(@name_args[0]) if @name_args[0]
68
+ append_to_query("chef_environment:#{config[:environment]}") if config[:environment]
69
+
52
70
  if config[:hide_healthy]
53
71
  time = Time.now.to_i
54
- query_unhealthy = "NOT ohai_time:[" << (time - 60*60).to_s << " TO " << time.to_s << "]"
55
- query << ' AND ' << query_unhealthy << @name_args[0] if @name_args[0]
56
- query = query_unhealthy unless @name_args[0]
72
+ # AND NOT is not valid lucene syntax, so don't use append_to_query
73
+ @query << " " unless @query.empty?
74
+ @query << "NOT ohai_time:[#{(time - 60*60).to_s} TO #{time.to_s}]"
57
75
  end
58
- q.search(:node, query) do |node|
76
+
77
+ @query = @query.empty? ? "*:*" : @query
78
+
79
+ all_nodes = []
80
+ q = Chef::Search::Query.new
81
+ Chef::Log.info("Sending query: #{@query}")
82
+ q.search(:node, @query, opts) do |node|
59
83
  all_nodes << node
60
84
  end
85
+
61
86
  output(all_nodes.sort { |n1, n2|
62
87
  if (config[:sort_reverse] || Chef::Config[:knife][:sort_status_reverse])
63
88
  (n2["ohai_time"] or 0) <=> (n1["ohai_time"] or 0)
@@ -18,6 +18,7 @@ require 'chef/config'
18
18
 
19
19
  class Chef
20
20
  module LocalMode
21
+
21
22
  # Create a chef local server (if the configuration requires one) for the
22
23
  # duration of the given block.
23
24
  #
@@ -59,12 +60,21 @@ class Chef
59
60
  server_options = {}
60
61
  server_options[:data_store] = data_store
61
62
  server_options[:log_level] = Chef::Log.level
63
+
62
64
  server_options[:host] = Chef::Config.chef_zero.host
63
65
  server_options[:port] = parse_port(Chef::Config.chef_zero.port)
64
66
  @chef_zero_server = ChefZero::Server.new(server_options)
65
- @chef_zero_server.start_background
66
- Chef::Log.info("Started chef-zero at #{@chef_zero_server.url} with #{@chef_fs.fs_description}")
67
- Chef::Config.chef_server_url = @chef_zero_server.url
67
+
68
+ if Chef::Config[:listen]
69
+ @chef_zero_server.start_background
70
+ else
71
+ @chef_zero_server.start_socketless
72
+ end
73
+
74
+ local_mode_url = @chef_zero_server.local_mode_url
75
+
76
+ Chef::Log.info("Started chef-zero at #{local_mode_url} with #{@chef_fs.fs_description}")
77
+ Chef::Config.chef_server_url = local_mode_url
68
78
  end
69
79
  end
70
80
 
@@ -0,0 +1,32 @@
1
+
2
+ require 'chef/mixin/descendants_tracker'
3
+
4
+ class Chef
5
+ module Mixin
6
+ module Provides
7
+ include Chef::Mixin::DescendantsTracker
8
+
9
+ def node_map
10
+ @node_map ||= Chef::NodeMap.new
11
+ end
12
+
13
+ def provides(short_name, opts={}, &block)
14
+ if !short_name.kind_of?(Symbol)
15
+ # YAGNI: this is probably completely unnecessary and can be removed?
16
+ Chef::Log.deprecation "Passing a non-Symbol to Chef::Resource#provides will be removed"
17
+ if short_name.kind_of?(String)
18
+ short_name.downcase!
19
+ short_name.gsub!(/\s/, "_")
20
+ end
21
+ short_name = short_name.to_sym
22
+ end
23
+ node_map.set(short_name, true, opts, &block)
24
+ end
25
+
26
+ # provides a node on the resource (early binding)
27
+ def provides?(node, resource_name)
28
+ node_map.get(node, resource_name)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,6 +1,4 @@
1
1
 
2
- require 'chef/providers'
3
-
4
2
  class Chef
5
3
  class Platform
6
4
  class ProviderPriorityMap
@@ -10,7 +8,22 @@ class Chef
10
8
  load_default_map
11
9
  end
12
10
 
11
+ def get_priority_array(node, resource_name)
12
+ priority_map.get(node, resource_name.to_sym)
13
+ end
14
+
15
+ def set_priority_array(resource_name, priority_array, *filter)
16
+ priority(resource_name.to_sym, priority_array.to_a, *filter)
17
+ end
18
+
19
+ def priority(*args)
20
+ priority_map.set(*args)
21
+ end
22
+
23
+ private
24
+
13
25
  def load_default_map
26
+ require 'chef/providers'
14
27
 
15
28
  #
16
29
  # Linux
@@ -71,13 +84,9 @@ class Chef
71
84
  end
72
85
 
73
86
  def priority_map
87
+ require 'chef/node_map'
74
88
  @priority_map ||= Chef::NodeMap.new
75
89
  end
76
-
77
- def priority(*args)
78
- priority_map.set(*args)
79
- end
80
-
81
90
  end
82
91
  end
83
92
  end
@@ -0,0 +1,37 @@
1
+ class Chef
2
+ class Platform
3
+ class ResourcePriorityMap
4
+ include Singleton
5
+
6
+ def initialize
7
+ load_default_map
8
+ end
9
+
10
+ def get_priority_array(node, resource_name)
11
+ priority_map.get(node, resource_name.to_sym)
12
+ end
13
+
14
+ def set_priority_array(resource_name, priority_array, *filter)
15
+ priority resource_name.to_sym, priority_array.to_a, *filter
16
+ end
17
+
18
+ def priority(*args)
19
+ priority_map.set(*args)
20
+ end
21
+
22
+ private
23
+
24
+ def load_default_map
25
+ require 'chef/resources'
26
+
27
+ # MacOSX
28
+ priority :package, Chef::Resource::HomebrewPackage, os: "darwin"
29
+ end
30
+
31
+ def priority_map
32
+ require 'chef/node_map'
33
+ @priority_map ||= Chef::NodeMap.new
34
+ end
35
+ end
36
+ end
37
+ end
@@ -24,6 +24,7 @@ require 'chef/rest'
24
24
  require 'chef/run_context'
25
25
  require 'chef/config'
26
26
  require 'chef/node'
27
+ require 'chef/chef_class'
27
28
 
28
29
  class Chef
29
30
  module PolicyBuilder
@@ -54,6 +55,15 @@ class Chef
54
55
  @run_list_expansion = nil
55
56
  end
56
57
 
58
+ # This method injects the run_context and provider and resource priority
59
+ # maps into the Chef class. The run_context has to be injected here, the provider and
60
+ # resource maps could be moved if a better place can be found to do this work.
61
+ #
62
+ # @param run_context [Chef::RunContext] the run_context to inject
63
+ def setup_chef_class(run_context)
64
+ Chef.set_run_context(run_context)
65
+ end
66
+
57
67
  def setup_run_context(specific_recipes=nil)
58
68
  if Chef::Config[:solo]
59
69
  Chef::Cookbook::FileVendor.fetch_from_disk(Chef::Config[:cookbook_path])
@@ -68,6 +78,10 @@ class Chef
68
78
  run_context = Chef::RunContext.new(node, cookbook_collection, @events)
69
79
  end
70
80
 
81
+ # TODO: this is really obviously not the place for this
82
+ # FIXME: need same edits
83
+ setup_chef_class(run_context)
84
+
71
85
  # TODO: this is not the place for this. It should be in Runner or
72
86
  # CookbookCompiler or something.
73
87
  run_context.load(@run_list_expansion)
@@ -385,4 +385,3 @@ class Chef
385
385
  end
386
386
  end
387
387
  end
388
-
@@ -22,7 +22,7 @@ require 'chef/mixin/convert_to_class_name'
22
22
  require 'chef/mixin/enforce_ownership_and_permissions'
23
23
  require 'chef/mixin/why_run'
24
24
  require 'chef/mixin/shell_out'
25
- require 'chef/mixin/descendants_tracker'
25
+ require 'chef/mixin/provides'
26
26
  require 'chef/platform/service_helpers'
27
27
  require 'chef/node_map'
28
28
 
@@ -30,26 +30,11 @@ class Chef
30
30
  class Provider
31
31
  include Chef::Mixin::WhyRun
32
32
  include Chef::Mixin::ShellOut
33
- extend Chef::Mixin::DescendantsTracker
33
+ extend Chef::Mixin::Provides
34
34
 
35
- class << self
36
- def node_map
37
- @node_map ||= Chef::NodeMap.new
38
- end
39
-
40
- def provides(resource_name, opts={}, &block)
41
- node_map.set(resource_name.to_sym, true, opts, &block)
42
- end
43
-
44
- # provides a node on the resource (early binding)
45
- def provides?(node, resource)
46
- node_map.get(node, resource.resource_name)
47
- end
48
-
49
- # supports the given resource and action (late binding)
50
- def supports?(resource, action)
51
- true
52
- end
35
+ # supports the given resource and action (late binding)
36
+ def self.supports?(resource, action)
37
+ true
53
38
  end
54
39
 
55
40
  attr_accessor :new_resource
@@ -538,8 +538,11 @@ class Chef
538
538
  def install_via_gem_command(name, version)
539
539
  if @new_resource.source =~ /\.gem$/i
540
540
  name = @new_resource.source
541
+ elsif @new_resource.clear_sources
542
+ src = ' --clear-sources'
543
+ src << (@new_resource.source && " --source=#{@new_resource.source}" || '')
541
544
  else
542
- src = @new_resource.source && " --source=#{@new_resource.source} --source=https://rubygems.org"
545
+ src = @new_resource.source && " --source=#{@new_resource.source} --source=https://rubygems.org"
543
546
  end
544
547
  if !version.nil? && version.length > 0
545
548
  shell_out!("#{gem_binary_path} install #{name} -q --no-rdoc --no-ri -v \"#{version}\"#{src}#{opts}", :env=>nil)
@@ -16,8 +16,10 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
+ require 'etc'
19
20
  require 'rexml/document'
20
21
  require 'chef/resource/service'
22
+ require 'chef/resource/macosx_service'
21
23
  require 'chef/provider/service/simple'
22
24
  require 'chef/util/path_helper'
23
25
 
@@ -27,6 +29,7 @@ class Chef
27
29
  class Macosx < Chef::Provider::Service::Simple
28
30
 
29
31
  provides :service, os: "darwin"
32
+ provides :macosx_service, os: "darwin"
30
33
 
31
34
  def self.gather_plist_dirs
32
35
  locations = %w{/Library/LaunchAgents
@@ -40,18 +43,32 @@ class Chef
40
43
  PLIST_DIRS = gather_plist_dirs
41
44
 
42
45
  def load_current_resource
43
- @current_resource = Chef::Resource::Service.new(@new_resource.name)
46
+ @current_resource = Chef::Resource::MacosxService.new(@new_resource.name)
44
47
  @current_resource.service_name(@new_resource.service_name)
45
48
  @plist_size = 0
46
- @plist = find_service_plist
49
+ @plist = @new_resource.plist ? @new_resource.plist : find_service_plist
47
50
  @service_label = find_service_label
51
+ # LauchAgents should be loaded as the console user.
52
+ @console_user = @plist ? @plist.include?('LaunchAgents') : false
53
+ @session_type = @new_resource.session_type
54
+
55
+ if @console_user
56
+ @console_user = Etc.getlogin
57
+ Chef::Log.debug("#{new_resource} console_user: '#{@console_user}'")
58
+ cmd = "su "
59
+ param = !node['platform_version'].include?('10.10') ? '-l ' : ''
60
+ @base_user_cmd = cmd + param + "#{@console_user} -c"
61
+ # Default LauchAgent session should be Aqua
62
+ @session_type = 'Aqua' if @session_type.nil?
63
+ end
64
+
65
+ Chef::Log.debug("#{new_resource} Plist: '#{@plist}' service_label: '#{@service_label}'")
48
66
  set_service_status
49
67
 
50
68
  @current_resource
51
69
  end
52
70
 
53
71
  def define_resource_requirements
54
- #super
55
72
  requirements.assert(:reload) do |a|
56
73
  a.failure_message Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :reload"
57
74
  end
@@ -61,6 +78,12 @@ class Chef
61
78
  a.failure_message Chef::Exceptions::Service, "Several plist files match service name. Please use full service name."
62
79
  end
63
80
 
81
+ requirements.assert(:all_actions) do |a|
82
+ a.assertion {::File.exists?(@plist.to_s) }
83
+ a.failure_message Chef::Exceptions::Service,
84
+ "Could not find plist for #{@new_resource}"
85
+ end
86
+
64
87
  requirements.assert(:enable, :disable) do |a|
65
88
  a.assertion { !@service_label.to_s.empty? }
66
89
  a.failure_message Chef::Exceptions::Service,
@@ -69,7 +92,7 @@ class Chef
69
92
 
70
93
  requirements.assert(:all_actions) do |a|
71
94
  a.assertion { @plist_size > 0 }
72
- # No failrue here in original code - so we also will not
95
+ # No failure here in original code - so we also will not
73
96
  # fail. Instead warn that the service is potentially missing
74
97
  a.whyrun "Assuming that the service would have been previously installed and is currently disabled." do
75
98
  @current_resource.enabled(false)
@@ -85,7 +108,7 @@ class Chef
85
108
  if @new_resource.start_command
86
109
  super
87
110
  else
88
- shell_out_with_systems_locale!("launchctl load -w '#{@plist}'", :user => @owner_uid, :group => @owner_gid)
111
+ load_service
89
112
  end
90
113
  end
91
114
  end
@@ -97,7 +120,7 @@ class Chef
97
120
  if @new_resource.stop_command
98
121
  super
99
122
  else
100
- shell_out_with_systems_locale!("launchctl unload '#{@plist}'", :user => @owner_uid, :group => @owner_gid)
123
+ unload_service
101
124
  end
102
125
  end
103
126
  end
@@ -106,9 +129,9 @@ class Chef
106
129
  if @new_resource.restart_command
107
130
  super
108
131
  else
109
- stop_service
132
+ unload_service
110
133
  sleep 1
111
- start_service
134
+ load_service
112
135
  end
113
136
  end
114
137
 
@@ -121,10 +144,7 @@ class Chef
121
144
  if @current_resource.enabled
122
145
  Chef::Log.debug("#{@new_resource} already enabled, not enabling")
123
146
  else
124
- shell_out!(
125
- "launchctl load -w '#{@plist}'",
126
- :user => @owner_uid, :group => @owner_gid
127
- )
147
+ load_service
128
148
  end
129
149
  end
130
150
 
@@ -132,38 +152,49 @@ class Chef
132
152
  unless @current_resource.enabled
133
153
  Chef::Log.debug("#{@new_resource} not enabled, not disabling")
134
154
  else
135
- shell_out!(
136
- "launchctl unload -w '#{@plist}'",
137
- :user => @owner_uid, :group => @owner_gid
138
- )
155
+ unload_service
156
+ end
157
+ end
158
+
159
+ def load_service
160
+ session = @session_type ? "-S #{@session_type} " : ''
161
+ cmd = 'launchctl load -w ' + session + @plist
162
+ shell_out_as_user(cmd)
163
+ end
164
+
165
+ def unload_service
166
+ cmd = 'launchctl unload -w ' + @plist
167
+ shell_out_as_user(cmd)
168
+ end
169
+
170
+ def shell_out_as_user(cmd)
171
+ if @console_user
172
+ shell_out_with_systems_locale("#{@base_user_cmd} '#{cmd}'")
173
+ else
174
+ shell_out_with_systems_locale(cmd)
175
+
139
176
  end
140
177
  end
141
178
 
142
179
  def set_service_status
143
180
  return if @plist == nil or @service_label.to_s.empty?
144
181
 
145
- cmd = shell_out(
146
- "launchctl list #{@service_label}",
147
- :user => @owner_uid, :group => @owner_gid
148
- )
182
+ cmd = "launchctl list #{@service_label}"
183
+ res = shell_out_as_user(cmd)
149
184
 
150
- if cmd.exitstatus == 0
185
+ if res.exitstatus == 0
151
186
  @current_resource.enabled(true)
152
187
  else
153
188
  @current_resource.enabled(false)
154
189
  end
155
190
 
156
191
  if @current_resource.enabled
157
- @owner_uid = ::File.stat(@plist).uid
158
- @owner_gid = ::File.stat(@plist).gid
159
-
160
- shell_out!(
161
- "launchctl list", :user => @owner_uid, :group => @owner_gid
162
- ).stdout.each_line do |line|
163
- case line
164
- when /(\d+|-)\s+(?:\d+|-)\s+(.*\.?)#{@service_label}/
192
+ res.stdout.each_line do |line|
193
+ case line.downcase
194
+ when /\s+\"pid\"\s+=\s+(\d+).*/
165
195
  pid = $1
166
196
  @current_resource.running(!pid.to_i.zero?)
197
+ Chef::Log.debug("Current PID for #{@service_label} is #{pid}")
167
198
  end
168
199
  end
169
200
  else
@@ -178,6 +209,9 @@ class Chef
178
209
  # onto the node yet."
179
210
  return nil if @plist.nil?
180
211
 
212
+ # Plist must exist by this point
213
+ raise Chef::Exceptions::FileNotFound, "Cannot find #{@plist}!" unless ::File.exists?(@plist)
214
+
181
215
  # Most services have the same internal label as the name of the
182
216
  # plist file. However, there is no rule saying that *has* to be
183
217
  # the case, and some core services (notably, ssh) do not follow
@@ -185,7 +219,9 @@ class Chef
185
219
 
186
220
  # plist files can come in XML or Binary formats. this command
187
221
  # will make sure we get XML every time.
188
- plist_xml = shell_out!("plutil -convert xml1 -o - #{@plist}").stdout
222
+ plist_xml = shell_out_with_systems_locale!(
223
+ "plutil -convert xml1 -o - #{@plist}"
224
+ ).stdout
189
225
 
190
226
  plist_doc = REXML::Document.new(plist_xml)
191
227
  plist_doc.elements[