Created
April 17, 2011 07:33
-
-
Save raggi/923827 to your computer and use it in GitHub Desktop.
A first stab at a launchd provider for chef
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Chef::Provider::Service::Launchd < Chef::Provider::Service::Simple | |
LAUNCHCTL_FORMAT = /([\d-]+)\s+([\d-]+)\s+([[:print:]]+)/ | |
def initialize(new_resource, run_context) | |
raise ArgumentError, "run_context cannot be nil" unless run_context | |
super | |
run_context.node | |
end | |
def load_current_resource | |
@current_resource = Chef::Resource::Service.new(@new_resource.name) | |
@current_resource.service_name(@new_resource.service_name) | |
if @new_resource.status_command | |
Chef::Log.debug("#{@new_resource} you have specified a status command, running..") | |
begin | |
if run_command_with_systems_locale(:command => @new_resource.status_command) == 0 | |
@current_resource.running true | |
end | |
rescue Chef::Exceptions::Exec | |
@current_resource.running false | |
nil | |
end | |
else | |
pid = launchctl_pid | |
if pid | |
@current_resource.enabled true | |
if pid > 0 | |
@current_resource.running true | |
else | |
@current_resource.running false | |
end | |
else | |
@current_resource.enabled false | |
end | |
end | |
@current_resource | |
end | |
def start_service | |
if @current_resource.running | |
Chef::Log.debug("#{@new_resource}: Already running, not starting") | |
else | |
if @new_resource.start_command | |
super | |
else | |
file = launchctl_file | |
run_command_with_systems_locale(:command => "launchctl load #{file}") | |
run_command_with_systems_locale(:command => "launchctl start #{launchctl_name}") | |
end | |
end | |
end | |
def stop_service | |
unless @current_resource.running | |
Chef::Log.debug("#{@new_resource}: Not running, not stopping") | |
else | |
if @new_resource.stop_command | |
super | |
else | |
file = launchctl_file | |
run_command_with_systems_locale(:command => "launchctl unload #{file}") | |
end | |
end | |
end | |
def restart_service | |
if @new_resource.restart_command | |
super | |
else | |
run_command_with_systems_locale(:command => "launchctl stop #{launchctl_name}") | |
end | |
end | |
def reload_service | |
if @new_resource.reload_command | |
super | |
else | |
pid = launchctl_pid | |
run_command_with_systems_locale(:command => "kill -HUP #{pid}") if pid | |
end | |
end | |
def enable_service | |
# Macports integration: | |
run_command_with_systems_locale(:command => "port load #{@new_resource.service_name}") rescue nil | |
file = launchctl_file | |
run_command_with_systems_locale(:command => "launchctl load #{file}") | |
end | |
def disable_service | |
file = launchctl_file | |
run_command_with_systems_locale(:command => "launchctl unload #{file}") | |
# Macports integration: | |
run_command_with_systems_locale(:command => "port unload #{@new_resource.service_name}") rescue nil | |
end | |
# A pid or 0 if not running | |
def launchctl_pid | |
command = "launchctl list | grep #{@new_resource.service_name}" | |
status = popen4(command) do |pid, stdin, stdout, stderr| | |
stdout.each_line do |line| | |
line =~ LAUNCHCTL_FORMAT | |
pid, status, name = Regexp.last_match.captures | |
return pid.to_i if name =~ /#{Regexp.escape @new_resource.service_name}$/ | |
end | |
end | |
nil | |
end | |
def launchctl_name | |
command = "launchctl list | grep #{@new_resource.service_name}" | |
status = popen4(command) do |pid, stdin, stdout, stderr| | |
stdout.each_line do |line| | |
line =~ LAUNCHCTL_FORMAT | |
pid, status, name = Regexp.last_match.captures | |
return name if name =~ /#{Regexp.escape @new_resource.service_name}$/ | |
end | |
end | |
end | |
def launchctl_file | |
Dir["{~,/}Library/LaunchDaemons/*#{@new_resource.service_name}.plist"].first | |
end | |
end |
I was thinking about submitting it as a patch, but haven't gotten around to it yet. It seems like it's a pain in the butt to test, I'm not really sure I want to mock out launchd.
License wise, feel free to take it as MIT.
Hmm. I copied some of this out of the Chef repo actually, so check that license too, if it's MIT that's fine, there's no conflict.
I think chef is actually Apache.
Submitting it as a patch would be awesome, but yeah, not sure about testing. Have to look at how the others are tested. I got it working bu adding a "launchd" cookbook with a libraries directory and put it in there.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Was wondering if you intended to release this as a cookbook or had a license in mind for it.
I forked it here: https://gist.github.com/1060712/5ee1aa5b924069c2b0b4da8c912dc973a9dccac8
Mainly had to update launchctl_file to better support the home directory and to support LaunchDaemons as well as LaunchAgents files.
After that, it worked great!