]> git.netwichtig.de Git - user/henk/code/puppet/modules/s6.git/blob - lib/puppet/provider/service/s6.rb
fix dirname
[user/henk/code/puppet/modules/s6.git] / lib / puppet / provider / service / s6.rb
1 Puppet::Type.type(:service).provide(:s6) do
2   desc <<~EOT
3     skarnet.org's small and secure supervision software suite
4
5     The scan directory is the first one found of:
6       * /etc/s6-scandir/
7
8     The first matching service definition found in the following directories
9     is used:
10       * /etc/s6-services/
11
12
13     This provider supports:
14
15     * start/stop
16     * enable/disable
17     * restart
18     * status
19   EOT
20
21   commands :s6_svscan    => 's6-svscan'
22   commands :s6_svscanctl => 's6-svscanctl'
23   commands :s6_svc       => 's6-svc'
24   commands :s6_svstat    => 's6-svstat'
25
26   class << self
27     def specificity
28       return 1
29     end
30
31     attr_writer :defpath
32
33     # this is necessary to autodetect a valid resource
34     # default path, since there is no standard for such directory.
35     def defpath
36       @defpath ||= ["/etc/s6-services"].find do |path|
37         Puppet::FileSystem.exist?(path) && FileTest.directory?(path)
38       end
39       @defpath
40     end
41
42     # returns all providers for all existing services in @defpath
43     # ie enabled or not
44     def instances
45       path = self.defpath
46       unless path
47         Puppet.info("#{self.name} is unsuitable because service directory is nil")
48         return
49       end
50       unless FileTest.directory?(path)
51         Puppet.notice "Service path #{path} does not exist"
52         return
53       end
54
55       # reject entries that aren't either a directory
56       # or don't contain an executable run file
57       Dir.entries(path).reject { |e|
58         fullpath = File.join(path, e)
59         e =~ /^\./ or ! FileTest.directory?(fullpath) or ! Puppet::FileSystem.executable?(File.join(fullpath,"run"))
60       }.collect do |name|
61         new(:name => name, :path => path)
62       end
63     end
64
65     # returns the daemon dir on this node
66     def daemondir
67       self.defpath
68     end
69   end
70
71   attr_writer :servicedir
72
73   # find the service dir on this node
74   def servicedir
75     unless @servicedir
76       ["/etc/s6-scandir"].each do |path|
77         if Puppet::FileSystem.exist?(path) && FileTest.directory?(path)
78           @servicedir = path
79           break
80         end
81       end
82       raise "Could not find service scan directory" unless @servicedir
83     end
84     @servicedir
85   end
86
87   # returns the full path of this service when enabled
88   # (ie in the service directory)
89   def service
90     File.join(self.servicedir, resource[:name])
91   end
92
93   # returns the full path to the current daemon directory
94   # note that this path can be overridden in the resource
95   # definition
96   def daemon
97     path = resource[:path]
98     raise Puppet::Error.new("#{self.class.name} must specify a path for daemon directory") unless path
99     File.join(path, resource[:name])
100   end
101
102   def status
103     begin
104       output = s6_svstat "-u", self.service
105       if output.chomp == 'true'
106         return :running
107       end
108     rescue Puppet::ExecutionFailure => detail
109       unless detail.message =~ /(warning: |s6-supervise not running$)/
110         raise Puppet::Error.new( "Could not get status for service #{resource.ref}: #{detail}", detail )
111       end
112     end
113     :stopped
114   end
115
116   def enabled?
117     # the service is enabled if it is linked
118     case Puppet::FileSystem.symlink?(self.service) ? :true : :false
119     when :true
120       return :true
121     when :false
122       return :false
123     else
124       raise Puppet::Error.new( "Received unknown state for #{self.service}", $!)
125     end
126   end
127
128   def enable
129     if ! FileTest.directory?(self.daemon)
130       Puppet.notice "No daemon dir, calling setupservice for #{resource[:name]}"
131     end
132     if self.daemon
133       if ! Puppet::FileSystem.symlink?(self.service)
134         Puppet.notice "Enabling #{self.service}: linking #{self.daemon} -> #{self.service}"
135         Puppet::FileSystem.symlink(self.daemon, self.service)
136       end
137     end
138     s6_svscanctl "-a", self.servicedir
139   rescue Puppet::ExecutionFailure
140     raise Puppet::Error.new( "No daemon directory found for #{self.service}", $!)
141   end
142
143   def disable
144     # unlink the daemon symlink to disable it
145     Puppet::FileSystem.unlink(self.service) if Puppet::FileSystem.symlink?(self.service)
146     s6_svscanctl "-n", self.servicedir
147   end
148
149   def restart
150     s6_svc "-r", self.service
151   end
152
153   def start
154     if enabled? != :true
155         enable
156     end
157     s6_svc "-u", self.service
158   end
159
160   def stop
161     s6_svc "-d", self.service
162   end
163 end