File: daemontools.rb

package info (click to toggle)
puppet-agent 7.23.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 19,092 kB
  • sloc: ruby: 245,074; sh: 456; makefile: 38; xml: 33
file content (193 lines) | stat: -rw-r--r-- 5,343 bytes parent folder | download
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