diff options
author | Lamont Granquist <lamont@scriptkiddie.org> | 2015-08-19 14:55:35 -0700 |
---|---|---|
committer | Lamont Granquist <lamont@scriptkiddie.org> | 2015-08-19 14:55:35 -0700 |
commit | 214771ccc2564d3bf866fc5d0590cfa84d24df5f (patch) | |
tree | 9c6a73aea0d50d818b6689b892b35517ce92a477 | |
parent | b39409b4e3506c658b68f2b39a1005b7d5e36651 (diff) | |
parent | 7cf6d3ec000a5de116d31bb53ecd235392ea7050 (diff) | |
download | chef-214771ccc2564d3bf866fc5d0590cfa84d24df5f.tar.gz |
Merge pull request #3793 from chef/lcg/run_levels
Lcg/run levels
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | lib/chef/provider/service/redhat.rb | 55 | ||||
-rw-r--r-- | lib/chef/resource/service.rb | 10 | ||||
-rw-r--r-- | spec/unit/provider/service/redhat_spec.rb | 72 |
4 files changed, 123 insertions, 16 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 032fca2bac..789df8cd81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ * [**James Belchamber**](https://github.com/JamesBelchamber): [pr#1796](https://github.com/chef/chef/pull/1796): make mount options aware - +* [pr#3793](https://github.com/chef/chef/pull/3793) CHEF-5372: Support specific `run_levels` for RedHat service * [pr#2460](https://github.com/chef/chef/pull/2460) add privacy flag * [pr#1259](https://github.com/chef/chef/pull/1259) CHEF-5012: add methods for template breadcrumbs * [pr#3656](https://github.com/chef/chef/pull/3656) remove use of self.provides? diff --git a/lib/chef/provider/service/redhat.rb b/lib/chef/provider/service/redhat.rb index 19cd2aa485..da86b2e2fc 100644 --- a/lib/chef/provider/service/redhat.rb +++ b/lib/chef/provider/service/redhat.rb @@ -1,6 +1,6 @@ # # Author:: AJ Christensen (<aj@hjksolutions.com>) -# Copyright:: Copyright (c) 2008 Opscode, Inc. +# Copyright:: Copyright (c) 2008-2015 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,6 +23,11 @@ class Chef class Service class Redhat < Chef::Provider::Service::Init + # @api private + attr_accessor :service_missing + # @api private + attr_accessor :current_run_levels + provides :service, platform_family: %w(rhel fedora suse) do |node| Chef::Platform::ServiceHelpers.service_resource_providers.include?(:redhat) end @@ -36,9 +41,15 @@ class Chef def initialize(new_resource, run_context) super - @init_command = "/sbin/service #{@new_resource.service_name}" - @new_resource.supports[:status] = true + @init_command = "/sbin/service #{new_resource.service_name}" + new_resource.supports[:status] = true @service_missing = false + @current_run_levels = [] + end + + # @api private + def run_levels + new_resource.run_levels end def define_resource_requirements @@ -47,12 +58,12 @@ class Chef requirements.assert(:all_actions) do |a| chkconfig_file = "/sbin/chkconfig" a.assertion { ::File.exists? chkconfig_file } - a.failure_message Chef::Exceptions::Service, "#{chkconfig_file} does not exist!" + a.failure_message Chef::Exceptions::Service, "#{chkconfig_file} dbleoes not exist!" end requirements.assert(:start, :enable, :reload, :restart) do |a| a.assertion { !@service_missing } - a.failure_message Chef::Exceptions::Service, "#{@new_resource}: unable to locate the init.d script!" + a.failure_message Chef::Exceptions::Service, "#{new_resource}: unable to locate the init.d script!" a.whyrun "Assuming service would be disabled. The init script is not presently installed." end end @@ -61,20 +72,44 @@ class Chef super if ::File.exists?("/sbin/chkconfig") - chkconfig = shell_out!("/sbin/chkconfig --list #{@current_resource.service_name}", :returns => [0,1]) - @current_resource.enabled(!!(chkconfig.stdout =~ CHKCONFIG_ON)) + chkconfig = shell_out!("/sbin/chkconfig --list #{current_resource.service_name}", :returns => [0,1]) + unless run_levels.nil? or run_levels.empty? + all_levels_match = true + chkconfig.stdout.split(/\s+/)[1..-1].each do |level| + index = level.split(':').first + status = level.split(':').last + if level =~ CHKCONFIG_ON + @current_run_levels << index.to_i + all_levels_match = false unless run_levels.include?(index.to_i) + else + all_levels_match = false if run_levels.include?(index.to_i) + end + end + current_resource.enabled(all_levels_match) + else + current_resource.enabled(!!(chkconfig.stdout =~ CHKCONFIG_ON)) + end @service_missing = !!(chkconfig.stderr =~ CHKCONFIG_MISSING) end - @current_resource + current_resource + end + + # @api private + def levels + (run_levels.nil? or run_levels.empty?) ? "" : "--level #{run_levels.join('')} " end def enable_service() - shell_out! "/sbin/chkconfig #{@new_resource.service_name} on" + unless run_levels.nil? or run_levels.empty? + disable_levels = current_run_levels - run_levels + shell_out! "/sbin/chkconfig --level #{disable_levels.join('')} #{new_resource.service_name} off" unless disable_levels.empty? + end + shell_out! "/sbin/chkconfig #{levels}#{new_resource.service_name} on" end def disable_service() - shell_out! "/sbin/chkconfig #{@new_resource.service_name} off" + shell_out! "/sbin/chkconfig #{levels}#{new_resource.service_name} off" end end end diff --git a/lib/chef/resource/service.rb b/lib/chef/resource/service.rb index aa59b543be..1485a10eb1 100644 --- a/lib/chef/resource/service.rb +++ b/lib/chef/resource/service.rb @@ -1,7 +1,7 @@ # # Author:: AJ Christensen (<aj@hjksolutions.com>) # Author:: Tyler Cloke (<tyler@opscode.com>) -# Copyright:: Copyright (c) 2008 Opscode, Inc. +# Copyright:: Copyright (c) 2008-2015 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -44,6 +44,7 @@ class Chef @init_command = nil @priority = nil @timeout = nil + @run_levels = nil @supports = { :restart => false, :reload => false, :status => false } end @@ -174,6 +175,13 @@ class Chef ) end + def run_levels(arg=nil) + set_or_return( + :run_levels, + arg, + :kind_of => [ Array ] ) + end + def supports(args={}) if args.is_a? Array args.each { |arg| @supports[arg] = true } diff --git a/spec/unit/provider/service/redhat_spec.rb b/spec/unit/provider/service/redhat_spec.rb index 73cfec8a6f..1cb985714f 100644 --- a/spec/unit/provider/service/redhat_spec.rb +++ b/spec/unit/provider/service/redhat_spec.rb @@ -69,9 +69,9 @@ describe "Chef::Provider::Service::Redhat" do expect(@provider).to receive(:shell_out).with("/sbin/service chef status").and_return(status) chkconfig = double("Chkconfig", :exitstatus => 0, :stdout => "chef 0:off 1:off 2:off 3:off 4:off 5:on 6:off", :stderr => "") expect(@provider).to receive(:shell_out!).with("/sbin/chkconfig --list chef", :returns => [0,1]).and_return(chkconfig) - expect(@provider.instance_variable_get("@service_missing")).to be_falsey + expect(@provider.service_missing).to be false @provider.load_current_resource - expect(@current_resource.enabled).to be_truthy + expect(@current_resource.enabled).to be true end it "sets the current enabled status to false if the regex does not match" do @@ -79,9 +79,45 @@ describe "Chef::Provider::Service::Redhat" do expect(@provider).to receive(:shell_out).with("/sbin/service chef status").and_return(status) chkconfig = double("Chkconfig", :exitstatus => 0, :stdout => "chef 0:off 1:off 2:off 3:off 4:off 5:off 6:off", :stderr => "") expect(@provider).to receive(:shell_out!).with("/sbin/chkconfig --list chef", :returns => [0,1]).and_return(chkconfig) - expect(@provider.instance_variable_get("@service_missing")).to be_falsey + expect(@provider.service_missing).to be false expect(@provider.load_current_resource).to eql(@current_resource) - expect(@current_resource.enabled).to be_falsey + expect(@current_resource.enabled).to be false + end + + it "sets the current enabled status to true if the service is enabled at specified run levels" do + status = double("Status", :exitstatus => 0, :stdout => "" , :stderr => "") + @new_resource.run_levels([1, 2]) + expect(@provider).to receive(:shell_out).with("/sbin/service chef status").and_return(status) + chkconfig = double("Chkconfig", :exitstatus => 0, :stdout => "chef 0:off 1:on 2:on 3:off 4:off 5:off 6:off", :stderr => "") + expect(@provider).to receive(:shell_out!).with("/sbin/chkconfig --list chef", :returns => [0,1]).and_return(chkconfig) + expect(@provider.service_missing).to be false + @provider.load_current_resource + expect(@current_resource.enabled).to be true + expect(@provider.current_run_levels).to eql([1, 2]) + end + + it "sets the current enabled status to false if the service is enabled at a run level it should not" do + status = double("Status", :exitstatus => 0, :stdout => "" , :stderr => "") + @new_resource.run_levels([1, 2]) + expect(@provider).to receive(:shell_out).with("/sbin/service chef status").and_return(status) + chkconfig = double("Chkconfig", :exitstatus => 0, :stdout => "chef 0:off 1:on 2:on 3:on 4:off 5:off 6:off", :stderr => "") + expect(@provider).to receive(:shell_out!).with("/sbin/chkconfig --list chef", :returns => [0,1]).and_return(chkconfig) + expect(@provider.service_missing).to be false + @provider.load_current_resource + expect(@current_resource.enabled).to be false + expect(@provider.current_run_levels).to eql([1, 2, 3]) + end + + it "sets the current enabled status to false if the service is not enabled at specified run levels" do + status = double("Status", :exitstatus => 0, :stdout => "" , :stderr => "") + @new_resource.run_levels([ 2 ]) + expect(@provider).to receive(:shell_out).with("/sbin/service chef status").and_return(status) + chkconfig = double("Chkconfig", :exitstatus => 0, :stdout => "chef 0:off 1:on 2:off 3:off 4:off 5:off 6:off", :stderr => "") + expect(@provider).to receive(:shell_out!).with("/sbin/chkconfig --list chef", :returns => [0,1]).and_return(chkconfig) + expect(@provider.service_missing).to be false + @provider.load_current_resource + expect(@current_resource.enabled).to be false + expect(@provider.current_run_levels).to eql([1]) end end @@ -144,6 +180,28 @@ describe "Chef::Provider::Service::Redhat" do expect(@provider).to receive(:shell_out!).with("/sbin/chkconfig #{@new_resource.service_name} on") @provider.enable_service end + + it "should call chkconfig to add 'service_name' at specified run_levels" do + allow(@provider).to receive(:run_levels).and_return([1, 2]) + expect(@provider).to receive(:shell_out!).with("/sbin/chkconfig --level 12 #{@new_resource.service_name} on") + @provider.enable_service + end + + it "should call chkconfig to add 'service_name' at specified run_levels when run_levels do not match" do + allow(@provider).to receive(:run_levels).and_return([1, 2]) + allow(@provider).to receive(:current_run_levels).and_return([1, 3]) + expect(@provider).to receive(:shell_out!).with("/sbin/chkconfig --level 12 #{@new_resource.service_name} on") + expect(@provider).to receive(:shell_out!).with("/sbin/chkconfig --level 3 #{@new_resource.service_name} off") + @provider.enable_service + end + + it "should call chkconfig to add 'service_name' at specified run_levels if there is an extra run_level" do + allow(@provider).to receive(:run_levels).and_return([1, 2]) + allow(@provider).to receive(:current_run_levels).and_return([1, 2, 3]) + expect(@provider).to receive(:shell_out!).with("/sbin/chkconfig --level 12 #{@new_resource.service_name} on") + expect(@provider).to receive(:shell_out!).with("/sbin/chkconfig --level 3 #{@new_resource.service_name} off") + @provider.enable_service + end end describe "disable_service" do @@ -151,6 +209,12 @@ describe "Chef::Provider::Service::Redhat" do expect(@provider).to receive(:shell_out!).with("/sbin/chkconfig #{@new_resource.service_name} off") @provider.disable_service end + + it "should call chkconfig to del 'service_name' at specified run_levels" do + allow(@provider).to receive(:run_levels).and_return([1, 2]) + expect(@provider).to receive(:shell_out!).with("/sbin/chkconfig --level 12 #{@new_resource.service_name} off") + @provider.disable_service + end end end |