1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
# Daemontools service management
#
# author Brice Figureau <brice-puppet@daysofwonder.com>
Puppet::Type.type(:service).provide :daemontools, :parent => :base do
desc <<-'EOT'
Daemontools service management.
This provider manages daemons supervised by D.J. Bernstein daemontools.
When detecting the service directory it will check, in order of preference:
* `/service`
* `/etc/service`
* `/var/lib/svscan`
The daemon directory should be in one of the following locations:
* `/var/lib/service`
* `/etc`
...or this can be overridden in the resource's attributes:
service { 'myservice':
provider => 'daemontools',
path => '/path/to/daemons',
}
This provider supports out of the box:
* start/stop (mapped to enable/disable)
* enable/disable
* restart
* status
If a service has `ensure => "running"`, it will link /path/to/daemon to
/path/to/service, which will automatically enable the service.
If a service has `ensure => "stopped"`, it will only shut down the service, not
remove the `/path/to/service` link.
EOT
commands :svc => "/usr/bin/svc", :svstat => "/usr/bin/svstat"
class << self
attr_writer :defpath
# Determine the daemon path.
def defpath
@defpath ||= ["/var/lib/service", "/etc"].find do |path|
Puppet::FileSystem.exist?(path) && FileTest.directory?(path)
end
@defpath
end
end
attr_writer :servicedir
# returns all providers for all existing services in @defpath
# ie enabled or not
def self.instances
path = self.defpath
unless path
Puppet.info("#{self.name} is unsuitable because service directory is nil")
return
end
unless FileTest.directory?(path)
Puppet.notice "Service path #{path} does not exist"
return
end
# reject entries that aren't either a directory
# or don't contain a run file
Dir.entries(path).reject { |e|
fullpath = File.join(path, e)
e =~ /^\./ or ! FileTest.directory?(fullpath) or ! Puppet::FileSystem.exist?(File.join(fullpath,"run"))
}.collect do |name|
new(:name => name, :path => path)
end
end
# returns the daemon dir on this node
def self.daemondir
self.defpath
end
# find the service dir on this node
def servicedir
unless @servicedir
["/service", "/etc/service","/var/lib/svscan"].each do |path|
if Puppet::FileSystem.exist?(path)
@servicedir = path
break
end
end
raise "Could not find service directory" unless @servicedir
end
@servicedir
end
# returns the full path of this service when enabled
# (ie in the service directory)
def service
File.join(self.servicedir, resource[:name])
end
# returns the full path to the current daemon directory
# note that this path can be overridden in the resource
# definition
def daemon
path = resource[:path]
raise Puppet::Error.new("#{self.class.name} must specify a path for daemon directory") unless path
File.join(path, resource[:name])
end
def status
begin
output = svstat self.service
if output =~ /:\s+up \(/
return :running
end
rescue Puppet::ExecutionFailure => detail
raise Puppet::Error.new( "Could not get status for service #{resource.ref}: #{detail}", detail)
end
:stopped
end
def setupservice
if resource[:manifest]
Puppet.notice "Configuring #{resource[:name]}"
command = [ resource[:manifest], resource[:name] ]
system("#{command}")
end
rescue Puppet::ExecutionFailure => detail
raise Puppet::Error.new( "Cannot config #{self.service} to enable it: #{detail}", detail)
end
def enabled?
case self.status
when :running
# obviously if the daemon is running then it is enabled
return :true
else
# the service is enabled if it is linked
return Puppet::FileSystem.symlink?(self.service) ? :true : :false
end
end
def enable
if ! FileTest.directory?(self.daemon)
Puppet.notice "No daemon dir, calling setupservice for #{resource[:name]}"
self.setupservice
end
if self.daemon
if ! Puppet::FileSystem.symlink?(self.service)
Puppet.notice "Enabling #{self.service}: linking #{self.daemon} -> #{self.service}"
Puppet::FileSystem.symlink(self.daemon, self.service)
end
end
rescue Puppet::ExecutionFailure
raise Puppet::Error.new( "No daemon directory found for #{self.service}", $!)
end
def disable
begin
if ! FileTest.directory?(self.daemon)
Puppet.notice "No daemon dir, calling setupservice for #{resource[:name]}"
self.setupservice
end
if self.daemon
if Puppet::FileSystem.symlink?(self.service)
Puppet.notice "Disabling #{self.service}: removing link #{self.daemon} -> #{self.service}"
Puppet::FileSystem.unlink(self.service)
end
end
rescue Puppet::ExecutionFailure
raise Puppet::Error.new( "No daemon directory found for #{self.service}", $!)
end
self.stop
end
def restart
svc "-t", self.service
end
def start
enable unless enabled? == :true
svc "-u", self.service
end
def stop
svc "-d", self.service
end
end
|