File: debian.rb

package info (click to toggle)
puppet 3.7.2-4+deb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 18,912 kB
  • ctags: 13,168
  • sloc: ruby: 210,410; sh: 2,050; xml: 1,554; lisp: 300; makefile: 142; python: 108; sql: 103; yacc: 72
file content (142 lines) | stat: -rw-r--r-- 4,590 bytes parent folder | download | duplicates (2)
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
# Manage debian services.  Start/stop is the same as InitSvc, but enable/disable
# is special.
Puppet::Type.type(:service).provide :debian, :parent => :init do
  desc <<-EOT
    Debian's form of `init`-style management.

    The only differences from `init` are support for enabling and disabling
    services via `update-rc.d` and the ability to determine enabled status via
    `invoke-rc.d`.

  EOT

  commands :update_rc => "/usr/sbin/update-rc.d"
  # note this isn't being used as a command until
  # http://projects.reductivelabs.com/issues/2538
  # is resolved.
  commands :invoke_rc => "/usr/sbin/invoke-rc.d"
  optional_commands :systemctl => "/bin/systemctl"

  # This isn't being used directly, it's just here to ensure
  # that the /usr/sbin/service binary is available.
  SERVICE = "/usr/sbin/service"
  commands :service_cmd => SERVICE

  defaultfor :operatingsystem => :debian

  def self.runs_on_systemd?
    Dir.exists? "/run/systemd/system"
  end

  def is_sysv_unit?
    # The sysv generator sets the SourcePath attribute to the name of the
    # initscript. Use this to detect whether a unit is backed by an initscript
    # or not.
    source = systemctl(:show, "-pSourcePath", @resource[:name])
    source.start_with? "SourcePath=/etc/init.d/"
  end

  def self.instances
    # We need to merge services with systemd unit files with those only having
    # an initscript. Note that we could use `systemctl --all` to get sysv
    # services as well, however it would only output *enabled* services.
    i = {}
    if self.runs_on_systemd?
      begin
        output = systemctl('list-unit-files', '--type', 'service', '--full', '--all',  '--no-pager')
        output.scan(/^(\S+)\.service\s+(disabled|enabled)\s*$/i).each do |m|
          i[m[0]] = new(:name => m[0])
        end
      rescue Puppet::ExecutionFailure
      end
    end
    get_services(defpath).each do |sysv|
      unless i.has_key?(sysv.name)
        i[sysv.name] = sysv
      end
    end
    return i.values
  end

  # Remove the symlinks
  def disable
    if self.class.runs_on_systemd?
      systemctl(:disable, @resource[:name])
    else
      update_rc @resource[:name], "disable"
    end
  end

  def enabled?
    # Initscript-backed services have no enabled status in systemd, so we
    # need to query them using invoke-rc.d.
    if self.class.runs_on_systemd? and not is_sysv_unit?
      begin
        systemctl("is-enabled", @resource[:name])
        return :true
      rescue Puppet::ExecutionFailure
        return :false
      end
    else
      # TODO: Replace system call when Puppet::Util::Execution.execute gives us a way
      # to determine exit status.  http://projects.reductivelabs.com/issues/2538
      system("/usr/sbin/invoke-rc.d", "--quiet", "--query", @resource[:name], "start")

      # 104 is the exit status when you query start an enabled service.
      # 106 is the exit status when the policy layer supplies a fallback action
      # See x-man-page://invoke-rc.d
      if [104, 106].include?($CHILD_STATUS.exitstatus)
        return :true
      elsif [105].include?($CHILD_STATUS.exitstatus)
        # 105 is unknown, which generally means the iniscript does not support query
        # The debian policy states that the initscript should support methods of query
        # For those that do not, peform the checks manually
        # http://www.debian.org/doc/debian-policy/ch-opersys.html
        if get_start_link_count >= 4
          return :true
        else
          return :false
        end
      else
        return :false
      end
    end
  end

  def get_start_link_count
    Dir.glob("/etc/rc*.d/S??#{@resource[:name]}").length
  end

  def enable
    if self.class.runs_on_systemd?
      systemctl(:enable, @resource[:name])
    else
      update_rc @resource[:name], "defaults"
      update_rc @resource[:name], "enable"
    end
  end

  # The start, stop, restart and status command use service
  # this makes sure that these commands work with whatever init
  # system is installed
  def startcmd
    [SERVICE, @resource[:name], :start]
  end

  # The stop command is just the init script with 'stop'.
  def stopcmd
    [SERVICE, @resource[:name], :stop]
  end

  def restartcmd
    (@resource[:hasrestart] == :true) && [SERVICE, @resource[:name], :restart]
  end

  # If it was specified that the init script has a 'status' command, then
  # we just return that; otherwise, we return false, which causes it to
  # fallback to other mechanisms.
  def statuscmd
    (@resource[:hasstatus] == :true) && [SERVICE, @resource[:name], :status]
  end

end