On Fri, 27 Feb 2015 11:20:30 +0200 Apollon Oikonomopoulos <apoi...@debian.org> wrote: > The attached patch on top of 3.7.2-2 (hopefully) addresses all of > these issues (and drops support for pre-2.88 sysv-rc if you don't > mind). I have not tested it on a sysvinit Jessie system though, so if > anyone could do this it would be appreciated!
I also tested it on a sysv-rc Jessie system. This is an updated version of the patch, marking the systemctl command as optional. Without this, sysv-rc Jessie systems would have the Debian provider blacklisted because of the missing systemctl command. Interdiff: --- b/lib/puppet/provider/service/debian.rb +++ b/lib/puppet/provider/service/debian.rb @@ -15,7 +15,7 @@ # http://projects.reductivelabs.com/issues/2538 # is resolved. commands :invoke_rc => "/usr/sbin/invoke-rc.d" - commands :systemctl => "/bin/systemctl" + 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. Cheers, Apollon
From a9b76dbfba96f537227c445297d3ccd115de46ca Mon Sep 17 00:00:00 2001 From: Apollon Oikonomopoulos <apoi...@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,11 @@ 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], "enable" + end end # The start, stop, restart and status command use service -- 2.1.4
signature.asc
Description: Digital signature