From b2f65af035d501d4da3b3c2e2c955b18044fc073 Mon Sep 17 00:00:00 2001 From: Thom May Date: Fri, 20 Apr 2018 14:24:46 +0100 Subject: [Debian/Ubuntu] Detect init script service levels Debian removed the no-op flag from update-rc.d, and so we're now unlinking services rather than just querying them. Just parsing the scripts ourselves is much safer. Fixes: #7119 Signed-off-by: Thom May --- spec/unit/provider/service/debian_service_spec.rb | 202 +++++----------------- 1 file changed, 41 insertions(+), 161 deletions(-) (limited to 'spec/unit') diff --git a/spec/unit/provider/service/debian_service_spec.rb b/spec/unit/provider/service/debian_service_spec.rb index d944192755..25e7c9acc2 100644 --- a/spec/unit/provider/service/debian_service_spec.rb +++ b/spec/unit/provider/service/debian_service_spec.rb @@ -32,6 +32,17 @@ describe Chef::Provider::Service::Debian do @provider.current_resource = @current_resource @pid, @stdin, @stdout, @stderr = nil, nil, nil, nil + allow(File).to receive(:exist?).with("/etc/init.d/chef").and_return true + end + + let(:init_lines) do + [ + "### BEGIN INIT INFO", + "# Required-Start: hostname $local_fs", + "# Default-Start: 2 3 4 5", + "# Default-Stop: 0 1 6", + "### END INIT INFO", + ] end describe "load_current_resource" do @@ -47,22 +58,14 @@ describe Chef::Provider::Service::Debian do context "when update-rc.d shows init linked to rc*.d/" do before do allow(@provider).to receive(:assert_update_rcd_available) + allow(File).to receive(:readlines).with("/etc/init.d/chef").and_return(init_lines) - result = <<-UPDATE_RC_D_SUCCESS - Removing any system startup links for /etc/init.d/chef ... - /etc/rc0.d/K20chef - /etc/rc1.d/K20chef - /etc/rc2.d/S20chef - /etc/rc3.d/S20chef - /etc/rc4.d/S20chef - /etc/rc5.d/S20chef - /etc/rc6.d/K20chef - UPDATE_RC_D_SUCCESS - - @stdout = result - @stderr = "" - @status = double("Status", :exitstatus => 0, :stdout => @stdout, :stderr => @stderr) - allow(@provider).to receive(:shell_out!).and_return(@status) + [0, 1, 6].each do |stop| + allow(Dir).to receive(:glob).with("/etc/rc#{stop}.d/[SK][0-9][0-9]chef").and_return(["/etc/rc#{stop}.d/K20chef"]) + end + [2, 3, 4, 5].each do |start| + allow(Dir).to receive(:glob).with("/etc/rc#{start}.d/[SK][0-9][0-9]chef").and_return(["/etc/rc#{start}.d/S20chef"]) + end end it "says the service is enabled" do @@ -74,14 +77,34 @@ describe Chef::Provider::Service::Debian do expect(@provider.load_current_resource).to equal(@current_resource) expect(@current_resource.enabled).to be_truthy end + + it "stores the start/stop priorities of the service" do + @provider.load_current_resource + expect(@provider.current_resource.priority).to eq( + { + "2" => [:start, "20"], + "3" => [:start, "20"], + "4" => [:start, "20"], + "5" => [:start, "20"], + "0" => [:stop, "20"], + "1" => [:stop, "20"], + "6" => [:stop, "20"] + }) + end end context "when update-rc.d shows init isn't linked to rc*.d/" do before do allow(@provider).to receive(:assert_update_rcd_available) - @stdout = " Removing any system startup links for /etc/init.d/chef ..." - @status = double("Status", :exitstatus => 0, :stdout => @stdout, stderr: "") - allow(@provider).to receive(:shell_out!).and_return(@status) + + allow(File).to receive(:readlines).with("/etc/init.d/chef").and_return(init_lines) + + [0, 1, 6].each do |stop| + allow(Dir).to receive(:glob).with("/etc/rc#{stop}.d/[SK][0-9][0-9]chef").and_return([]) + end + [2, 3, 4, 5].each do |start| + allow(Dir).to receive(:glob).with("/etc/rc#{start}.d/[SK][0-9][0-9]chef").and_return([]) + end end it "says the service is disabled" do @@ -95,149 +118,6 @@ describe Chef::Provider::Service::Debian do end end - context "when update-rc.d fails" do - before do - @status = double("Status", exitstatus: -1, stdout: "", stderr: "") - allow(@provider).to receive(:shell_out!).and_return(@status) - end - - it "raises an error" do - @provider.load_current_resource - @provider.define_resource_requirements - expect do - @provider.process_resource_requirements - end.to raise_error(Chef::Exceptions::Service) - end - end - - { "Debian/Lenny and older" => { - "linked" => { - "stdout" => <<-STDOUT, - Removing any system startup links for /etc/init.d/chef ... - /etc/rc0.d/K20chef - /etc/rc1.d/K20chef - /etc/rc2.d/S20chef - /etc/rc3.d/S20chef - /etc/rc4.d/S20chef - /etc/rc5.d/S20chef - /etc/rc6.d/K20chef - STDOUT - "stderr" => "", - "priorities" => { - "0" => [:stop, "20"], - "1" => [:stop, "20"], - "2" => [:start, "20"], - "3" => [:start, "20"], - "4" => [:start, "20"], - "5" => [:start, "20"], - "6" => [:stop, "20"], - }, - }, - "not linked" => { - "stdout" => " Removing any system startup links for /etc/init.d/chef ...", - "stderr" => "", - }, - }, - "Debian/Squeeze and earlier" => { - "linked" => { - "stdout" => "update-rc.d: using dependency based boot sequencing", - "stderr" => <<-STDERR, -insserv: remove service /etc/init.d/../rc0.d/K20chef-client - insserv: remove service /etc/init.d/../rc1.d/K20chef-client - insserv: remove service /etc/init.d/../rc2.d/S20chef-client - insserv: remove service /etc/init.d/../rc3.d/S20chef-client - insserv: remove service /etc/init.d/../rc4.d/S20chef-client - insserv: remove service /etc/init.d/../rc5.d/S20chef-client - insserv: remove service /etc/init.d/../rc6.d/K20chef-client - insserv: dryrun, not creating .depend.boot, .depend.start, and .depend.stop - STDERR - "priorities" => { - "0" => [:stop, "20"], - "1" => [:stop, "20"], - "2" => [:start, "20"], - "3" => [:start, "20"], - "4" => [:start, "20"], - "5" => [:start, "20"], - "6" => [:stop, "20"], - }, - }, - "not linked" => { - "stdout" => "update-rc.d: using dependency based boot sequencing", - "stderr" => "", - }, - }, - "Debian/Wheezy and earlier, a service only starting at run level S" => { - "linked" => { - "stdout" => "", - "stderr" => <<-STDERR, -insserv: remove service /etc/init.d/../rc0.d/K06rpcbind -insserv: remove service /etc/init.d/../rc1.d/K06rpcbind -insserv: remove service /etc/init.d/../rc6.d/K06rpcbind -insserv: remove service /etc/init.d/../rcS.d/S13rpcbind -insserv: dryrun, not creating .depend.boot, .depend.start, and .depend.stop - STDERR - "priorities" => { - "0" => [:stop, "06"], - "1" => [:stop, "06"], - "6" => [:stop, "06"], - "S" => [:start, "13"], - }, - }, - "not linked" => { - "stdout" => "", - "stderr" => "insserv: dryrun, not creating .depend.boot, .depend.start, and .depend.stop", - }, - }, - }.each do |model, expected_results| - context "on #{model}" do - context "when update-rc.d shows init linked to rc*.d/" do - before do - allow(@provider).to receive(:assert_update_rcd_available) - - @stdout = expected_results["linked"]["stdout"] - @stderr = expected_results["linked"]["stderr"] - @status = double("Status", exitstatus: 0, stdout: @stdout, stderr: @stderr) - allow(@provider).to receive(:shell_out!).and_return(@status) - end - - it "says the service is enabled" do - expect(@provider.service_currently_enabled?(@provider.get_priority)).to be_truthy - end - - it "stores the 'enabled' state" do - allow(Chef::Resource::Service).to receive(:new).and_return(@current_resource) - expect(@provider.load_current_resource).to equal(@current_resource) - expect(@current_resource.enabled).to be_truthy - end - - it "stores the start/stop priorities of the service" do - @provider.load_current_resource - expect(@provider.current_resource.priority).to eq(expected_results["linked"]["priorities"]) - end - end - - context "when update-rc.d shows init isn't linked to rc*.d/" do - before do - allow(@provider).to receive(:assert_update_rcd_available) - @stdout = expected_results["not linked"]["stdout"] - @stderr = expected_results["not linked"]["stderr"] - @status = double("Status", exitstatus: 0, stdout: @stdout, stderr: @stderr) - allow(@provider).to receive(:shell_out!).and_return(@status) - end - - it "says the service is disabled" do - expect(@provider.service_currently_enabled?(@provider.get_priority)).to be_falsey - end - - it "stores the 'disabled' state" do - allow(Chef::Resource::Service).to receive(:new).and_return(@current_resource) - expect(@provider.load_current_resource).to equal(@current_resource) - expect(@current_resource.enabled).to be_falsey - end - end - end - end - end describe "action_enable" do -- cgit v1.2.1