summaryrefslogtreecommitdiff
path: root/lib/chef/provider/launchd.rb
diff options
context:
space:
mode:
authorMike Dodge <mikedodge04@fb.com>2015-10-27 11:21:04 -0700
committerMike Dodge <mikedodge04@fb.com>2016-02-15 12:48:29 -0800
commit66c4f6af84f33ac40ff2912a61ee9a3be2ca878c (patch)
treefd7064f8b88047cf7f16da3a34a992ff49461bfd /lib/chef/provider/launchd.rb
parent9a9e2b484ac3ac4c8497dd5e0cddff9c7c6c6dac (diff)
downloadchef-66c4f6af84f33ac40ff2912a61ee9a3be2ca878c.tar.gz
launchd
Diffstat (limited to 'lib/chef/provider/launchd.rb')
-rw-r--r--lib/chef/provider/launchd.rb205
1 files changed, 205 insertions, 0 deletions
diff --git a/lib/chef/provider/launchd.rb b/lib/chef/provider/launchd.rb
new file mode 100644
index 0000000000..a6f54e7627
--- /dev/null
+++ b/lib/chef/provider/launchd.rb
@@ -0,0 +1,205 @@
+#
+# Author:: Mike Dodge (<mikedodge04@gmail.com>)
+# Copyright:: Copyright (c) 2015 Facebook, 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'
+require 'chef/resource'
+require 'chef/resource/file'
+require 'chef/resource/cookbook_file'
+require 'chef/resource/macosx_service'
+
+class Chef
+ class Provider
+ class Launchd < Chef::Provider
+
+ def load_current_resource
+ @current_resource = Chef::Resource::Launchd.new(@new_resource.name)
+ @name = @new_resource.name
+ @label = @new_resource.label ? @new_resource.label : @name
+ @backup = @new_resource.backup
+ @cookbook = @new_resource.cookbook
+ @group = @new_resource.group
+ @mode = @new_resource.mode
+ @owner = @new_resource.owner
+ @path = @new_resource.path
+ @source = @new_resource.source
+ @content = content?
+ end
+
+ def action_create
+ manage_plist(:create)
+ end
+
+ def action_create_if_missing
+ manage_plist(:create_if_missing)
+ end
+
+ def action_delete
+ # If you delete a service you want to make sure its not loaded or
+ # the service will be in memory and you wont be able to stop it.
+ if ::File.exists?(@path)
+ manage_service(:disable)
+ end
+ manage_plist(:delete)
+ end
+
+ def action_enable
+ if manage_plist(:create)
+ manage_service(:restart)
+ else
+ manage_service(:enable)
+ end
+ end
+
+ def action_disable
+ manage_service(:disable)
+ end
+
+ def manage_plist(action)
+ if @source
+ res = cookbook_file_resource
+ elsif
+ res = file_resource
+ end
+ res.run_action(action)
+ new_resource.updated_by_last_action(true) if res.updated?
+ res.updated
+ end
+
+ def manage_service(action)
+ res = service_resource
+ res.run_action(action)
+ new_resource.updated_by_last_action(true) if res.updated?
+ end
+
+ def service_resource
+ res = Chef::Resource::MacosxService.new(@label, run_context)
+ res.name(@label)
+ res.service_name(@label)
+ res.plist(@path)
+ res.session_type(@session_type) if @session_type
+
+ res
+ end
+
+ def file_resource
+ res = Chef::Resource::File.new(@path, run_context)
+ res.name(@path)
+ res.backup(@backup) if @backup
+ res.content(@content) if @content
+ res.group(@group) if @group
+ res.mode(@mode) if @mode
+ res.owner(@owner) if @owner
+ res.source(@source) if @source
+
+ res
+ end
+
+ def cookbook_file_resource
+ res = Chef::Resource::CookbookFile.new(@path, run_context)
+ res.name(@path)
+ res.backup(@backup) if @backup
+ res.content(@content) if @content
+ res.cookbook_name = @cookbook if @cookbook
+ res.group(@group) if @group
+ res.mode(@mode) if @mode
+ res.owner(@owner) if @owner
+ res.source(@source) if @source
+
+ res
+ end
+
+ def define_resource_requirements
+ super
+ requirements.assert(
+ :create, :create_if_missing, :delete, :enable, :disable
+ ) do |a|
+ type = @new_resource.type.to_s
+ a.assertion { !['daemon', 'agent'].include?(type) }
+ a.failure_message(
+ Chef::Exceptions::UnsupportedAction,
+ "service_type must be 'daemon' or 'agent'"
+ )
+ end
+ end
+
+ private
+
+ def content?
+ if @new_resource.hash
+ @new_resource.hash.to_plist
+ elsif @new_resource.program || @new_resource.program_arguments
+ gen_plist
+ end
+ end
+
+ def gen_plist
+ plist_hash = {}
+ {
+ 'label' => 'Label',
+ 'program' => 'Program',
+ 'program_arguments' => 'ProgramArguments',
+ 'abandon_process_group' => 'AbandonProcessGroup',
+ 'debug' => 'Debug',
+ 'disabled' => 'Disabled',
+ 'enable_globbing' => 'EnableGlobbing',
+ 'enable_transactions' => 'EnableTransactions',
+ 'environment_variables' => 'EnvironmentVariables',
+ 'exit_timeout' => 'ExitTimeout',
+ 'ld_group' => 'GroupName',
+ 'hard_resource_limits' => 'HardreSourceLimits',
+ 'inetd_compatibility' => 'inetdCompatibility',
+ 'init_groups' => 'InitGroups',
+ 'keep_alive' => 'KeepAlive',
+ 'launch_only_once' => 'LaunchOnlyOnce',
+ 'limit_load_from_hosts' => 'LimitLoadFromHosts',
+ 'limit_load_to_hosts' => 'LimitLoadToHosts',
+ 'limit_load_to_session_type' => 'LimitLoadToSessionType',
+ 'low_priority_io' => 'LowPriorityIO',
+ 'mach_services' => 'MachServices',
+ 'nice' => 'Nice',
+ 'on_demand' => 'OnDemand',
+ 'process_type' => 'ProcessType',
+ 'queue_directories' => 'QueueDirectories',
+ 'root_directory' => 'RootDirectory',
+ 'run_at_load' => 'RunAtLoad',
+ 'sockets' => 'Sockets',
+ 'soft_resource_limits' => 'SoftResourceLimits',
+ 'standard_error_path' => 'StandardErrorPath',
+ 'standard_in_path' => 'StandardInPath',
+ 'standard_out_path' => 'StandardOutPath',
+ 'start_calendar_interval' => 'StartCalendarInterval',
+ 'start_interval' => 'StartInterval',
+ 'start_on_mount' => 'StartOnMount',
+ 'throttle_interval' => 'ThrottleInterval',
+ 'time_out' => 'TimeOut',
+ 'umask' => 'Umask',
+ 'username' => 'UserName',
+ 'wait_for_debugger' => 'WaitForDebugger',
+ 'watch_paths' => 'WatchPaths',
+ 'working_directory' => 'WorkingDirectory',
+ }.each do |key, val|
+ if @new_resource.send(key)
+ plist_hash[val] = @new_resource.send(key)
+ end
+ end
+ plist_hash.to_plist
+ end
+
+ end
+ end
+end