diff options
author | robuye <rulejczyk@gmail.com> | 2019-09-12 21:52:16 +0200 |
---|---|---|
committer | robuye <rulejczyk@gmail.com> | 2019-09-13 09:55:24 +0200 |
commit | 1c642e292f1356454e0e226c7d33c3bb45dec8fb (patch) | |
tree | 330717f44600d94ed2a1510213b1d9c0c8948061 | |
parent | 5048626424be5940caaff34b9aeee85918a2ec80 (diff) | |
download | chef-1c642e292f1356454e0e226c7d33c3bb45dec8fb.tar.gz |
update syntax of `update-rc.d` commands in enable & disable actions
Previous implementation was built for an outdated version of
`update-rc.d` and it used commands that no longer work.
The `stop` and `start` commands were removed in 2.88.dsf-42 [1]:
```
* sysv-rc:
- update-rc.d no longer supports non-dependency-based boot.
+ Remove non-insserv codepaths.
+ Warn if the start or stop actions are used.
+ Skip runlevel mismatch warnings if default action is used
(no arguments to validate).
+ Update manual page to remove start and stop actions, plus
manual setting of boot sequence ordering; note that start
and stop are no longer supported. Closes: #606505.
```
and has been since ported to all currently supported Debian
distributions (including Jessie, released in 2015).
Both `start` and `stop` commands now effectively call `defaults`.
As a result of this `action_disable` did not disable a service, it would
enable it instead. Chef would execute the following commands on disable:
```
/usr/sbin/update-rc.d -f <service_name> remove
/usr/sbin/update-rc.d -f <service_name> stop 80 2 3 4 5 .
```
But `update-rc.d` would effectively run:
```
/usr/sbin/update-rc.d -f <service_name> remove
/usr/sbin/update-rc.d <service_name> defaults
```
And the service gets enabled instead.
With changes in this commit Chef will effectively run the following
commands:
```
/usr/sbin/update-rc.d -f <service_name> remove
/usr/sbin/update-rc.d <service_name> defaults
/usr/sbin/update-rc.d <service_name> disable
```
The service is now disabled, as expected.
Additionally `priority` support has been dropped entirely from code as
it's not supported by `update-rc.d` either.
It's potentially a breaking change on a very outdated distributions and
it could be worked around with additional `if/else` branches, but given
all non-EOLed distros have up-to-date version of `update-rc.d` available
it didn't feel worth the complexity.
[1] https://launchpad.net/debian/+source/sysvinit/2.88dsf-42
Signed-off-by: Rob Ulejczyk <rulejczyk@gmail.com>
-rw-r--r-- | lib/chef/provider/service/debian.rb | 38 | ||||
-rw-r--r-- | spec/unit/provider/service/debian_service_spec.rb | 38 |
2 files changed, 47 insertions, 29 deletions
diff --git a/lib/chef/provider/service/debian.rb b/lib/chef/provider/service/debian.rb index 9f48504d5e..6774b214ae 100644 --- a/lib/chef/provider/service/debian.rb +++ b/lib/chef/provider/service/debian.rb @@ -149,44 +149,42 @@ class Chef end def enable_service - if new_resource.priority.is_a? Integer - 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 #{new_resource.priority} #{100 - new_resource.priority}") - elsif new_resource.priority.is_a? Hash + 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, go with update-rc.d defaults + 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") end end def disable_service - if new_resource.priority.is_a? Integer - # Stop processes in reverse order of start using '100 - start_priority' - shell_out!("/usr/sbin/update-rc.d -f #{new_resource.service_name} remove") - shell_out!("/usr/sbin/update-rc.d -f #{new_resource.service_name} stop #{100 - new_resource.priority} 2 3 4 5 .") - elsif new_resource.priority.is_a? Hash + 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 set_priority - else - # no priority, using '100 - 20 (update-rc.d default)' to stop in reverse order of start + else # No priority or Integer. Either way disable in all levels. shell_out!("/usr/sbin/update-rc.d -f #{new_resource.service_name} remove") - shell_out!("/usr/sbin/update-rc.d -f #{new_resource.service_name} stop 80 2 3 4 5 .") + 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 - args = "" - new_resource.priority.each do |level, o| - action = o[0] - priority = o[1] - args += "#{action} #{priority} #{level} . " - end + # 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} #{args}") + 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 end end diff --git a/spec/unit/provider/service/debian_service_spec.rb b/spec/unit/provider/service/debian_service_spec.rb index 5f89605b2e..0aef4bc760 100644 --- a/spec/unit/provider/service/debian_service_spec.rb +++ b/spec/unit/provider/service/debian_service_spec.rb @@ -183,7 +183,7 @@ describe Chef::Provider::Service::Debian do describe "enable_service" do let(:service_name) { @new_resource.service_name } context "when the service doesn't set a priority" do - it "calls update-rc.d 'service_name' defaults" do + it "calls update-rc.d remove => defaults" do expect_commands(@provider, [ "/usr/sbin/update-rc.d -f #{service_name} remove", "/usr/sbin/update-rc.d #{service_name} defaults", @@ -197,10 +197,10 @@ describe Chef::Provider::Service::Debian do @new_resource.priority(75) end - it "calls update-rc.d 'service_name' defaults" do + it "calls update-rc.d remove => defaults" do expect_commands(@provider, [ "/usr/sbin/update-rc.d -f #{service_name} remove", - "/usr/sbin/update-rc.d #{service_name} defaults 75 25", + "/usr/sbin/update-rc.d #{service_name} defaults", ]) @provider.enable_service end @@ -211,10 +211,12 @@ describe Chef::Provider::Service::Debian do @new_resource.priority(2 => [:start, 20], 3 => [:stop, 55]) end - it "calls update-rc.d 'service_name' with those priorities" do + it "calls update-rc.d remove => defaults => enable|disable <runlevel>" do expect_commands(@provider, [ "/usr/sbin/update-rc.d -f #{service_name} remove", - "/usr/sbin/update-rc.d #{service_name} start 20 2 . stop 55 3 . ", + "/usr/sbin/update-rc.d #{service_name} defaults", + "/usr/sbin/update-rc.d #{service_name} enable 2", + "/usr/sbin/update-rc.d #{service_name} disable 3", ]) @provider.enable_service end @@ -224,10 +226,11 @@ describe Chef::Provider::Service::Debian do describe "disable_service" do let(:service_name) { @new_resource.service_name } context "when the service doesn't set a priority" do - it "calls update-rc.d -f 'service_name' remove + stop with default priority" do + it "calls update-rc.d remove => defaults => disable" do expect_commands(@provider, [ "/usr/sbin/update-rc.d -f #{service_name} remove", - "/usr/sbin/update-rc.d -f #{service_name} stop 80 2 3 4 5 .", + "/usr/sbin/update-rc.d #{service_name} defaults", + "/usr/sbin/update-rc.d #{service_name} disable", ]) @provider.disable_service end @@ -238,10 +241,27 @@ describe Chef::Provider::Service::Debian do @new_resource.priority(75) end - it "calls update-rc.d -f 'service_name' remove + stop with the specified priority" do + it "calls update-rc.d remove => defaults => disable" do expect_commands(@provider, [ "/usr/sbin/update-rc.d -f #{service_name} remove", - "/usr/sbin/update-rc.d -f #{service_name} stop #{100 - @new_resource.priority} 2 3 4 5 .", + "/usr/sbin/update-rc.d #{service_name} defaults", + "/usr/sbin/update-rc.d #{service_name} disable", + ]) + @provider.disable_service + end + end + + context "when the service sets complex priorities" do + before do + @new_resource.priority(2 => [:start, 20], 3 => [:stop, 55]) + end + + it "calls update-rc.d remove => defaults => enable|disable <runlevel>" do + expect_commands(@provider, [ + "/usr/sbin/update-rc.d -f #{service_name} remove", + "/usr/sbin/update-rc.d #{service_name} defaults", + "/usr/sbin/update-rc.d #{service_name} enable 2", + "/usr/sbin/update-rc.d #{service_name} disable 3", ]) @provider.disable_service end |