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
|