summaryrefslogtreecommitdiff
path: root/lib/chef/provider
diff options
context:
space:
mode:
authorrobuye <rulejczyk@gmail.com>2019-09-17 11:54:23 +0200
committerrobuye <rulejczyk@gmail.com>2019-09-17 14:44:26 +0200
commitec177edf55504e56de1ba1319f5eca8351614e46 (patch)
tree0fddc22c69ca0444a1ccf1384fe71f93914871d5 /lib/chef/provider
parent1c642e292f1356454e0e226c7d33c3bb45dec8fb (diff)
downloadchef-ec177edf55504e56de1ba1319f5eca8351614e46.tar.gz
bring back support for legacy update-rc.d syntax
Legacy syntax is required to support start & stop priorities on very old systems running SysVinit. If an old enough version is detected Chef will prefer legacy syntax, otherwise it will use modern syntax and the priorities will be for the most part ignored. See https://lists.debian.org/debian-devel/2013/05/msg01109.html for additional context. To use legacy syntax sysv-rc package must be installed and it's version must be < 2.88. If the package is not installed at all then update-rc.d is coming from 'init-system-helpers' package and it's at least 2.88dsf-59.2 so it supports only modern syntax. Note that start|stop syntax has been dropped in 2.88dsf-42 and older 2.88 versions could work, but the email linked above indicates it didn't do anything. Signed-off-by: Rob Ulejczyk <rulejczyk@gmail.com>
Diffstat (limited to 'lib/chef/provider')
-rw-r--r--lib/chef/provider/service/debian.rb86
1 files changed, 73 insertions, 13 deletions
diff --git a/lib/chef/provider/service/debian.rb b/lib/chef/provider/service/debian.rb
index 6774b214ae..0fea83ab0f 100644
--- a/lib/chef/provider/service/debian.rb
+++ b/lib/chef/provider/service/debian.rb
@@ -149,43 +149,103 @@ class Chef
end
def enable_service
+ # We call the same command regardless if we're enabling or disabling
+ # Users passing a Hash are responsible for setting their own stop priorities
if new_resource.priority.is_a? Hash
- # we call the same command regardless of we're enabling or disabling
- # users passing a Hash are responsible for setting their own start priorities
set_priority
- else # No priority or Integer. Either way go with update-rc.d defaults
- shell_out!("/usr/sbin/update-rc.d -f #{new_resource.service_name} remove")
- shell_out!("/usr/sbin/update-rc.d #{new_resource.service_name} defaults")
+ return
end
+
+ start_priority = new_resource.priority.is_a?(Integer) ? new_resource.priority : 20
+ # Stop processes in reverse order of start using '100 - start_priority'.
+ stop_priority = 100 - start_priority
+
+ shell_out!("/usr/sbin/update-rc.d -f #{new_resource.service_name} remove")
+ shell_out!("/usr/sbin/update-rc.d #{new_resource.service_name} defaults #{start_priority} #{stop_priority}")
end
def disable_service
if new_resource.priority.is_a? Hash
- # we call the same command regardless of we're enabling or disabling
- # users passing a Hash are responsible for setting their own stop priorities
+ # We call the same command regardless if we're enabling or disabling
+ # Users passing a Hash are responsible for setting their own stop priorities
set_priority
- else # No priority or Integer. Either way disable in all levels.
- shell_out!("/usr/sbin/update-rc.d -f #{new_resource.service_name} remove")
+ return
+ end
+
+ shell_out!("/usr/sbin/update-rc.d -f #{new_resource.service_name} remove")
+
+ # Use legacy syntax if update-rc.d supports it for backward compatibility.
+ if use_legacy_update_rc_d?
+ # If no priority was given assume 20 (update-rc.d default).
+ start_priority = new_resource.priority.is_a?(Integer) ? new_resource.priority : 20
+ # Stop processes in reverse order of start using '100 - start_priority'.
+ stop_priority = 100 - start_priority
+
+ shell_out!("/usr/sbin/update-rc.d -f #{new_resource.service_name} stop #{stop_priority} 2 3 4 5 .")
+ else
shell_out!("/usr/sbin/update-rc.d #{new_resource.service_name} defaults")
shell_out!("/usr/sbin/update-rc.d #{new_resource.service_name} disable")
end
end
def set_priority
+ shell_out!("/usr/sbin/update-rc.d -f #{new_resource.service_name} remove")
+
+ # Use legacy syntax if update-rc.d supports it for backward compatibility.
+ if use_legacy_update_rc_d?
+ args = ""
+ new_resource.priority.each do |level, o|
+ action = o[0]
+ priority = o[1]
+ args += "#{action} #{priority} #{level} . "
+ end
+ shell_out!("/usr/sbin/update-rc.d #{new_resource.service_name} #{args}")
+ return
+ end
+
+ # Use modern syntax, ignoring priorities as update-rc.d does not support it.
+ #
# Reset priorities to default values before applying customizations. This way
# the final state will always be consistent, regardless if all runlevels were
# provided.
- shell_out!("/usr/sbin/update-rc.d -f #{new_resource.service_name} remove")
shell_out!("/usr/sbin/update-rc.d #{new_resource.service_name} defaults")
-
- # Note the `_priority` is not used. update-rc.d does not support priorities
- # anymore, this feature has been dropped in sysvinit 2.88dsf-42.
new_resource.priority.each do |level, (action, _priority)|
disable_or_enable = (action == :start ? "enable" : "disable")
shell_out!("/usr/sbin/update-rc.d #{new_resource.service_name} #{disable_or_enable} #{level}")
end
end
+
+ # Ancient Debian releases used run levels and priorities to manage dependencies ordering.
+ # Old syntax no longer works and new syntax does not support priorities. If Chef detects
+ # ancient update-rc.d it will prefer legacy syntax so priorities can be set correctly in
+ # case the host is in fact running SysVinit.
+ #
+ # Additional context: https://lists.debian.org/debian-devel/2013/05/msg01109.html
+ def use_legacy_update_rc_d?
+ @sysv_rc_version ||= shell_out!("dpkg-query -W --showformat '${Version}' sysv-rc").stdout.strip
+
+ # sysv-rc is not installed therefore we're on modern Debian and legacy syntax does not work
+ if @sysv_rc_version.empty?
+ logger.trace("sysv-rc package is not installed. update-rc.d will use modern syntax")
+ return false
+ end
+
+ # sysv-rc is installed and update-rc.d is old enough to support legacy syntax and features
+ if @sysv_rc_version.to_f < 2.88
+ logger.trace("sysv-rc #{@sysv_rc_version} detected. update-rc.d will use legacy syntax")
+ return true
+ end
+
+ # sysv-rc 2.88dsf-42 drops the legacy syntax
+ if @sysv_rc_version.to_f == 2.88 && @sysv_rc_version[8..9].to_i < 42
+ logger.trace("sysv-rc #{@sysv_rc_version} detected. update-rc.d will use legacy syntax")
+ return true
+ end
+
+ # default to modern syntax
+ false
+ end
end
end
end