Package: puppet / 3.7.2-4+deb8u1

0005-Fix-service-listing-and-enable-disable-in-Debian.patch Patch series | 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
From a9b76dbfba96f537227c445297d3ccd115de46ca Mon Sep 17 00:00:00 2001
From: Apollon Oikonomopoulos <apoikos@debian.org>
Date: Fri, 27 Feb 2015 10:55:34 +0200
Subject: [PATCH] Fix service listing and enable/disable in Debian
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Add two support methods to detect when we're running systemd as PID 1
and if a service has only an initscript.

Use these to implement the following functionality:

 • Under systemd, use systemctl enable/disable for all services. This
   works correctly for all types of services.

 • Under systemd, use systemctl is-enabled only for services that have a
   systemd unit file and fall back to invoke-rc.d for sysv services.

Also, fix self.instances to augment the list of systemd-enabled services
with the sysv services.

Finally drop pre-2.88 sysv-rc support and use `update-rc.d enable' for
all services when running under sysv-rc, preserving order changes.
---
 lib/puppet/provider/service/debian.rb | 94 ++++++++++++++++++++++++++---------
 1 file changed, 71 insertions(+), 23 deletions(-)

diff --git a/lib/puppet/provider/service/debian.rb b/lib/puppet/provider/service/debian.rb
index 9f7a2f5..7a26409 100644
--- a/lib/puppet/provider/service/debian.rb
+++ b/lib/puppet/provider/service/debian.rb
@@ -15,6 +15,7 @@ Puppet::Type.type(:service).provide :debian, :parent => :init do
   # 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.
@@ -23,38 +24,82 @@ Puppet::Type.type(:service).provide :debian, :parent => :init do
 
   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 `dpkg --compare-versions $(dpkg-query -W --showformat '${Version}' sysv-rc) ge 2.88 ; echo $?`.to_i == 0
-      update_rc @resource[:name], "disable"
+    if self.class.runs_on_systemd?
+      systemctl(:disable, @resource[:name])
     else
-      update_rc "-f", @resource[:name], "remove"
-      update_rc @resource[:name], "stop", "00", "1", "2", "3", "4", "5", "6", "."
+      update_rc @resource[:name], "disable"
     end
   end
 
   def enabled?
-    # 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
+    # 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
-      else
+      rescue Puppet::ExecutionFailure
         return :false
       end
     else
-      return :false
+      # 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
 
@@ -63,8 +108,12 @@ Puppet::Type.type(:service).provide :debian, :parent => :init do
   end
 
   def enable
-    update_rc "-f", @resource[:name], "remove"
-    update_rc @resource[:name], "defaults"
+    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