summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Eddy <dave@daveeddy.com>2015-04-02 18:06:56 -0400
committerLamont Granquist <lamont@scriptkiddie.org>2015-10-23 11:03:51 -0700
commitfe647990966bb2cd795fe896afb60cca1da7f85d (patch)
tree6b427ca49961d229eb670929b4cfad878cf3d55a
parentdacd899509a1e5b3a97441797a55e6ae3bcfdb3a (diff)
downloadchef-lcg/3187.tar.gz
overhaul solaris SMF service providerlcg/3187
-rw-r--r--lib/chef/provider/service/solaris.rb60
-rw-r--r--spec/unit/provider/service/solaris_smf_service_spec.rb149
2 files changed, 153 insertions, 56 deletions
diff --git a/lib/chef/provider/service/solaris.rb b/lib/chef/provider/service/solaris.rb
index eaea6bb1ab..7040503c6b 100644
--- a/lib/chef/provider/service/solaris.rb
+++ b/lib/chef/provider/service/solaris.rb
@@ -30,35 +30,39 @@ class Chef
def initialize(new_resource, run_context=nil)
super
- @init_command = "/usr/sbin/svcadm"
- @status_command = "/bin/svcs -l"
+ @init_command = "/usr/sbin/svcadm"
+ @status_command = "/bin/svcs"
@maintenace = false
end
def load_current_resource
@current_resource = Chef::Resource::Service.new(@new_resource.name)
@current_resource.service_name(@new_resource.service_name)
- unless ::File.exists? "/bin/svcs"
- raise Chef::Exceptions::Service, "/bin/svcs does not exist!"
+
+ [@init_command, @status_command].each do |cmd|
+ unless ::File.executable? cmd then
+ raise Chef::Exceptions::Service, "#{cmd} not executable!"
+ end
end
@status = service_status.enabled
+
@current_resource
end
def enable_service
- shell_out!("#{default_init_command} clear #{@new_resource.service_name}") if @maintenance
- shell_out!("#{default_init_command} enable -s #{@new_resource.service_name}")
+ shell_out!(default_init_command, "clear", @new_resource.service_name) if @maintenance
+ shell_out!(default_init_command, "enable", "-s", @new_resource.service_name)
end
def disable_service
- shell_out!("#{default_init_command} disable -s #{@new_resource.service_name}")
+ shell_out!(default_init_command, "disable", "-s", @new_resource.service_name)
end
alias_method :stop_service, :disable_service
alias_method :start_service, :enable_service
def reload_service
- shell_out_with_systems_locale!("#{default_init_command} refresh #{@new_resource.service_name}")
+ shell_out!(default_init_command, "refresh", @new_resource.service_name)
end
def restart_service
@@ -68,16 +72,38 @@ class Chef
end
def service_status
- status = shell_out!("#{@status_command} #{@current_resource.service_name}", :returns => [0, 1])
- status.stdout.each_line do |line|
- case line
- when /state\s+online/
- @current_resource.enabled(true)
- @current_resource.running(true)
- when /state\s+maintenance/
- @maintenance = true
- end
+ cmd = shell_out!(@status_command, "-l", @current_resource.service_name, :returns => [0, 1])
+ # Example output
+ # $ svcs -l rsyslog
+ # fmri svc:/application/rsyslog:default
+ # name rsyslog logging utility
+ # enabled true
+ # state online
+ # next_state none
+ # state_time April 2, 2015 04:25:19 PM EDT
+ # logfile /var/svc/log/application-rsyslog:default.log
+ # restarter svc:/system/svc/restarter:default
+ # contract_id 1115271
+ # dependency require_all/error svc:/milestone/multi-user:default (online)
+ # $
+
+ # load output into hash
+ status = {}
+ cmd.stdout.each_line do |line|
+ key, value = line.strip.split(/\s+/, 2)
+ status[key] = value
+ end
+
+ # check service state
+ @maintenance = false
+ case status['state']
+ when 'online'
+ @current_resource.enabled(true)
+ @current_resource.running(true)
+ when 'maintenance'
+ @maintenance = true
end
+
unless @current_resource.enabled
@current_resource.enabled(false)
@current_resource.running(false)
diff --git a/spec/unit/provider/service/solaris_smf_service_spec.rb b/spec/unit/provider/service/solaris_smf_service_spec.rb
index 2039408914..62c3ac6c6e 100644
--- a/spec/unit/provider/service/solaris_smf_service_spec.rb
+++ b/spec/unit/provider/service/solaris_smf_service_spec.rb
@@ -31,66 +31,126 @@ describe Chef::Provider::Service::Solaris do
@provider = Chef::Provider::Service::Solaris.new(@new_resource, @run_context)
allow(Chef::Resource::Service).to receive(:new).and_return(@current_resource)
- @stdin = StringIO.new
- @stdout = StringIO.new
- @stderr = StringIO.new
- @pid = 2342
- @stdout_string = "state disabled"
- allow(@stdout).to receive(:gets).and_return(@stdout_string)
- @status = double("Status", :exitstatus => 0, :stdout => @stdout)
- allow(@provider).to receive(:shell_out!).and_return(@status)
+ # enabled / started service (svcs -l chef)
+ enabled_svc_stdout = [
+ 'fmri svc:/application/chef:default',
+ 'name chef service',
+ 'enabled true',
+ 'state online',
+ 'next_state none',
+ 'state_time April 2, 2015 04:25:19 PM EDT',
+ 'logfile /var/svc/log/application-chef:default.log',
+ 'restarter svc:/system/svc/restarter:default',
+ 'contract_id 1115271',
+ 'dependency require_all/error svc:/milestone/multi-user:default (online)'
+ ].join("\n")
+
+ # disabled / stopped service (svcs -l chef)
+ disabled_svc_stdout = [
+ 'fmri svc:/application/chef:default',
+ 'name chef service',
+ 'enabled false',
+ 'state disabled',
+ 'next_state none',
+ 'state_time April 2, 2015 04:25:19 PM EDT',
+ 'logfile /var/svc/log/application-chef:default.log',
+ 'restarter svc:/system/svc/restarter:default',
+ 'contract_id 1115271',
+ 'dependency require_all/error svc:/milestone/multi-user:default (online)'
+ ].join("\n")
+
+ # disabled / stopped service (svcs -l chef)
+ maintenance_svc_stdout = [
+ 'fmri svc:/application/chef:default',
+ 'name chef service',
+ 'enabled true',
+ 'state maintenance',
+ 'next_state none',
+ 'state_time April 2, 2015 04:25:19 PM EDT',
+ 'logfile /var/svc/log/application-chef:default.log',
+ 'restarter svc:/system/svc/restarter:default',
+ 'contract_id 1115271',
+ 'dependency require_all/error svc:/milestone/multi-user:default (online)'
+ ].join("\n")
+
+ # shell_out! return value for a service that is running
+ @enabled_svc_status = double("Status", :exitstatus => 0, :stdout => enabled_svc_stdout, :stdin => '', :stderr => '')
+
+ # shell_out! return value for a service that is disabled
+ @disabled_svc_status = double("Status", :exitstatus => 0, :stdout => disabled_svc_stdout, :stdin => '', :stderr => '')
+
+ # shell_out! return value for a service that is in maintenance mode
+ @maintenance_svc_status = double("Status", :exitstatus => 0, :stdout => maintenance_svc_stdout, :stdin => '', :stderr => '')
+
+ # shell_out! return value for a service that does not exist
+ @no_svc_status = double("Status", :exitstatus => 1, :stdout => '', :stdin => '', :stderr => "svcs: Pattern 'chef' doesn't match any instances\n")
+
+ # shell_out! return value for a successful execution
+ @success = double("clear", :exitstatus => 0, :stdout => '', :stdin => '', :stderr => '')
end
- it "should raise an error if /bin/svcs does not exist" do
- expect(File).to receive(:exists?).with("/bin/svcs").and_return(false)
+ it "should raise an error if /bin/svcs and /usr/sbin/svcadm are not executable" do
+ allow(File).to receive(:executable?).with("/bin/svcs").and_return(false)
+ allow(File).to receive(:executable?).with("/usr/sbin/svcadm").and_return(false)
expect { @provider.load_current_resource }.to raise_error(Chef::Exceptions::Service)
end
- describe "on a host with /bin/svcs" do
+ it "should raise an error if /bin/svcs is not executable" do
+ allow(File).to receive(:executable?).with("/bin/svcs").and_return(false)
+ allow(File).to receive(:executable?).with("/usr/sbin/svcadm").and_return(true)
+ expect { @provider.load_current_resource }.to raise_error(Chef::Exceptions::Service)
+ end
+
+ it "should raise an error if /usr/sbin/svcadm is not executable" do
+ allow(File).to receive(:executable?).with("/bin/svcs").and_return(true)
+ allow(File).to receive(:executable?).with("/usr/sbin/svcadm").and_return(false)
+ expect { @provider.load_current_resource }.to raise_error(Chef::Exceptions::Service)
+ end
+
+ describe "on a host with /bin/svcs and /usr/sbin/svcadm" do
before do
- allow(File).to receive(:exists?).with('/bin/svcs').and_return(true)
+ allow(File).to receive(:executable?).with("/bin/svcs").and_return(true)
+ allow(File).to receive(:executable?).with("/usr/sbin/svcadm").and_return(true)
end
describe "when discovering the current service state" do
it "should create a current resource with the name of the new resource" do
- allow(@provider).to receive(:shell_out!).with("/bin/svcs -l chef").and_return(@status)
+ expect(@provider).to receive(:shell_out!).with("/bin/svcs", "-l", "chef", {:returns=>[0, 1]}).and_return(@enabled_svc_status)
expect(Chef::Resource::Service).to receive(:new).and_return(@current_resource)
@provider.load_current_resource
end
it "should return the current resource" do
- allow(@provider).to receive(:shell_out!).with("/bin/svcs -l chef").and_return(@status)
+ expect(@provider).to receive(:shell_out!).with("/bin/svcs", "-l", "chef", {:returns=>[0, 1]}).and_return(@enabled_svc_status)
expect(@provider.load_current_resource).to eql(@current_resource)
end
it "should call '/bin/svcs -l service_name'" do
- expect(@provider).to receive(:shell_out!).with("/bin/svcs -l chef", {:returns=>[0, 1]}).and_return(@status)
+ expect(@provider).to receive(:shell_out!).with("/bin/svcs", "-l", "chef", {:returns=>[0, 1]}).and_return(@enabled_svc_status)
@provider.load_current_resource
end
it "should mark service as not running" do
- allow(@provider).to receive(:shell_out!).and_return(@status)
+ expect(@provider).to receive(:shell_out!).and_return(@disabled_svc_status)
expect(@current_resource).to receive(:running).with(false)
@provider.load_current_resource
end
it "should mark service as running" do
- @status = double("Status", :exitstatus => 0, :stdout => 'state online')
- allow(@provider).to receive(:shell_out!).and_return(@status)
+ expect(@provider).to receive(:shell_out!).and_return(@enabled_svc_status)
expect(@current_resource).to receive(:running).with(true)
@provider.load_current_resource
end
it "should not mark service as maintenance" do
- allow(@provider).to receive(:shell_out!).and_return(@status)
+ expect(@provider).to receive(:shell_out!).and_return(@enabled_svc_status)
@provider.load_current_resource
expect(@provider.maintenance).to be_falsey
end
it "should mark service as maintenance" do
- @status = double("Status", :exitstatus => 0, :stdout => 'state maintenance')
- allow(@provider).to receive(:shell_out!).and_return(@status)
+ expect(@provider).to receive(:shell_out!).and_return(@maintenance_svc_status)
@provider.load_current_resource
expect(@provider.maintenance).to be_truthy
end
@@ -99,30 +159,41 @@ describe Chef::Provider::Service::Solaris do
describe "when enabling the service" do
before(:each) do
@provider.current_resource = @current_resource
- @current_resource.enabled(true)
end
it "should call svcadm enable -s chef" do
- expect(@provider).not_to receive(:shell_out!).with("/usr/sbin/svcadm clear #{@current_resource.service_name}")
- expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm enable -s #{@current_resource.service_name}").and_return(@status)
+ expect(@provider).to receive(:shell_out!).with("/bin/svcs", "-l", "chef", {:returns=>[0, 1]}).and_return(@enabled_svc_status)
+ expect(@provider).not_to receive(:shell_out!).with("/usr/sbin/svcadm", "clear", @current_resource.service_name)
+ expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm", "enable", "-s", @current_resource.service_name).and_return(@success)
+ @provider.load_current_resource
+
expect(@provider.enable_service).to be_truthy
expect(@current_resource.enabled).to be_truthy
end
it "should call svcadm enable -s chef for start_service" do
- expect(@provider).not_to receive(:shell_out!).with("/usr/sbin/svcadm clear #{@current_resource.service_name}")
- expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm enable -s #{@current_resource.service_name}").and_return(@status)
+ expect(@provider).to receive(:shell_out!).with("/bin/svcs", "-l", "chef", {:returns=>[0, 1]}).and_return(@enabled_svc_status)
+ expect(@provider).not_to receive(:shell_out!).with("/usr/sbin/svcadm", "clear", @current_resource.service_name)
+ expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm", "enable", "-s", @current_resource.service_name).and_return(@success)
+ @provider.load_current_resource
expect(@provider.start_service).to be_truthy
expect(@current_resource.enabled).to be_truthy
end
it "should call svcadm clear chef for start_service when state maintenance" do
- @status = double("Status", :exitstatus => 0, :stdout => 'state maintenance')
- allow(@provider).to receive(:shell_out!).and_return(@status)
+ # we are in maint mode
+ expect(@provider).to receive(:shell_out!).with("/bin/svcs", "-l", "chef", {:returns=>[0, 1]}).and_return(@maintenance_svc_status)
+ expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm", "clear", @current_resource.service_name).and_return(@success)
+ expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm", "enable", "-s", @current_resource.service_name).and_return(@success)
+
+ # load the resource, then enable it
@provider.load_current_resource
- expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm clear #{@current_resource.service_name}").and_return(@status)
- expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm enable -s #{@current_resource.service_name}").and_return(@status)
expect(@provider.enable_service).to be_truthy
+
+ # now we are enabled
+ expect(@provider).to receive(:shell_out!).with("/bin/svcs", "-l", "chef", {:returns=>[0, 1]}).and_return(@enabled_svc_status)
+ @provider.load_current_resource
+
expect(@current_resource.enabled).to be_truthy
end
end
@@ -130,17 +201,20 @@ describe Chef::Provider::Service::Solaris do
describe "when disabling the service" do
before(:each) do
@provider.current_resource = @current_resource
- @current_resource.enabled(false)
end
it "should call svcadm disable -s chef" do
- expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm disable -s chef").and_return(@status)
+ expect(@provider).to receive(:shell_out!).with("/bin/svcs", "-l", "chef", {:returns=>[0, 1]}).and_return(@disabled_svc_status)
+ expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm", "disable", "-s", "chef").and_return(@success)
+ @provider.load_current_resource
expect(@provider.disable_service).to be_truthy
expect(@current_resource.enabled).to be_falsey
end
it "should call svcadm disable -s chef for stop_service" do
- expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm disable -s chef").and_return(@status)
+ expect(@provider).to receive(:shell_out!).with("/bin/svcs", "-l", "chef", {:returns=>[0, 1]}).and_return(@disabled_svc_status)
+ expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm", "disable", "-s", "chef").and_return(@success)
+ @provider.load_current_resource
expect(@provider.stop_service).to be_truthy
expect(@current_resource.enabled).to be_falsey
end
@@ -149,12 +223,12 @@ describe Chef::Provider::Service::Solaris do
describe "when reloading the service" do
before(:each) do
- @status = double("Process::Status", :exitstatus => 0)
@provider.current_resource = @current_resource
+ allow(@provider).to receive(:shell_out!).with("/bin/svcs", "-l", "chef", {:returns=>[0, 1]}).and_return(@enabled_svc_status)
end
it "should call svcadm refresh chef" do
- expect(@provider).to receive(:shell_out_with_systems_locale!).with("/usr/sbin/svcadm refresh chef").and_return(@status)
+ expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm", "refresh", "chef")
@provider.reload_service
end
@@ -162,19 +236,16 @@ describe Chef::Provider::Service::Solaris do
describe "when the service doesn't exist" do
before(:each) do
- @stdout_string = ""
- @status = double("Status", :exitstatus => 1, :stdout => @stdout)
@provider.current_resource = @current_resource
+ expect(@provider).to receive(:shell_out!).with("/bin/svcs", "-l", "chef", {:returns=>[0, 1]}).and_return(@no_svc_status)
end
it "should be marked not running" do
- expect(@provider).to receive(:shell_out!).with("/bin/svcs -l chef", {:returns=>[0, 1]}).and_return(@status)
@provider.service_status
expect(@current_resource.running).to be_falsey
end
it "should be marked not enabled" do
- expect(@provider).to receive(:shell_out!).with("/bin/svcs -l chef", {:returns=>[0, 1]}).and_return(@status)
@provider.service_status
expect(@current_resource.enabled).to be_falsey
end