summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Haynes <sh@nomitor.com>2011-05-29 04:45:52 +0000
committerBryan McLellan <btm@opscode.com>2011-06-01 17:55:06 -0700
commite6420c0e3c5e27a900f214a32efc5e6f166066a0 (patch)
treefab8ab5ff3b0713380e902de6a4a6909e1c77a96
parent2c62426976dbe0e2a46fe99d35e8fc1062a6d028 (diff)
downloadchef-e6420c0e3c5e27a900f214a32efc5e6f166066a0.tar.gz
CHEF-2387: systemd service provider
-rw-r--r--chef/lib/chef/provider/service/systemd.rb102
-rw-r--r--chef/lib/chef/providers.rb1
-rw-r--r--chef/spec/unit/provider/service/systemd_service_spec.rb226
3 files changed, 329 insertions, 0 deletions
diff --git a/chef/lib/chef/provider/service/systemd.rb b/chef/lib/chef/provider/service/systemd.rb
new file mode 100644
index 0000000000..749cb3bfc6
--- /dev/null
+++ b/chef/lib/chef/provider/service/systemd.rb
@@ -0,0 +1,102 @@
+#
+# Author:: Stephen Haynes (<sh@nomitor.com>)
+# Copyright:: Copyright (c) 2011 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/provider/service'
+require 'chef/provider/service/simple'
+require 'chef/mixin/command'
+
+class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
+ def load_current_resource
+ @current_resource = Chef::Resource::Service.new(@new_resource.name)
+ @current_resource.service_name(@new_resource.service_name)
+
+ if @new_resource.status_command
+ Chef::Log.debug("#{@new_resource} you have specified a status command, running..")
+
+ begin
+ if run_command_with_systems_locale(:command => @new_resource.status_command) == 0
+ @current_resource.running(true)
+ end
+ rescue Chef::Exceptions::Exec
+ @current_resource.running(false)
+ nil
+ end
+ else
+ @current_resource.running(is_active?)
+ end
+
+ @current_resource.enabled(is_enabled?)
+ @current_resource
+ end
+
+ def start_service
+ if @current_resource.running
+ Chef::Log.debug("#{@new_resource} already running, not starting")
+ else
+ if @new_resource.start_command
+ super
+ else
+ run_command_with_systems_locale(:command => "/bin/systemctl start #{@new_resource.service_name}")
+ end
+ end
+ end
+
+ def stop_service
+ unless @current_resource.running
+ Chef::Log.debug("#{@new_resource} not running, not stopping")
+ else
+ if @new_resource.stop_command
+ super
+ else
+ run_command_with_systems_locale(:command => "/bin/systemctl stop #{@new_resource.service_name}")
+ end
+ end
+ end
+
+ def restart_service
+ if @new_resource.restart_command
+ super
+ else
+ run_command_with_systems_locale(:command => "/bin/systemctl restart #{@new_resource.service_name}")
+ end
+ end
+
+ def reload_service
+ if @new_resource.reload_command
+ super
+ else
+ run_command_with_systems_locale(:command => "/bin/systemctl reload #{@new_resource.service_name}")
+ end
+ end
+
+ def enable_service
+ run_command_with_systems_locale(:command => "/bin/systemctl enable #{@new_resource.service_name}")
+ end
+
+ def disable_service
+ run_command_with_systems_locale(:command => "/bin/systemctl disable #{@new_resource.service_name}")
+ end
+
+ def is_active?
+ run_command_with_systems_locale({:command => "/bin/systemctl is-active #{@new_resource.service_name}", :ignore_failure => true}) == 0
+ end
+
+ def is_enabled?
+ run_command_with_systems_locale({:command => "/bin/systemctl is-enabled #{@new_resource.service_name}", :ignore_failure => true}) == 0
+ end
+end
diff --git a/chef/lib/chef/providers.rb b/chef/lib/chef/providers.rb
index 9bc16470ef..94a7e7e1a7 100644
--- a/chef/lib/chef/providers.rb
+++ b/chef/lib/chef/providers.rb
@@ -69,6 +69,7 @@ require 'chef/provider/service/init'
require 'chef/provider/service/insserv'
require 'chef/provider/service/redhat'
require 'chef/provider/service/simple'
+require 'chef/provider/service/systemd'
require 'chef/provider/service/upstart'
require 'chef/provider/service/windows'
require 'chef/provider/service/solaris'
diff --git a/chef/spec/unit/provider/service/systemd_service_spec.rb b/chef/spec/unit/provider/service/systemd_service_spec.rb
new file mode 100644
index 0000000000..f47e73b11e
--- /dev/null
+++ b/chef/spec/unit/provider/service/systemd_service_spec.rb
@@ -0,0 +1,226 @@
+#
+# Author:: Stephen Haynes (<sh@nomitor.com>)
+# Copyright:: Copyright (c) 2011 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "spec_helper"))
+
+describe Chef::Provider::Service::Systemd do
+ before(:each) do
+ @node = Chef::Node.new
+ @run_context = Chef::RunContext.new(@node, {})
+ @new_resource = Chef::Resource::Service.new('rsyslog.service')
+ @provider = Chef::Provider::Service::Systemd.new(@new_resource, @run_context)
+ end
+
+ describe "load_current_resource" do
+ before(:each) do
+ @current_resource = Chef::Resource::Service.new('rsyslog.service')
+ Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+
+ @provider.stub!(:is_active?).and_return(false)
+ @provider.stub!(:is_enabled?).and_return(false)
+ end
+
+ it "should create a current resource with the name of the new resource" do
+ Chef::Resource::Service.should_receive(:new).and_return(@current_resource)
+ @provider.load_current_resource
+ end
+
+ it "should set the current resources service name to the new resources service name" do
+ @current_resource.should_receive(:service_name).with(@new_resource.service_name)
+ @provider.load_current_resource
+ end
+
+ it "should check if the service is running" do
+ @provider.should_receive(:is_active?)
+ @provider.load_current_resource
+ end
+
+ it "should set running to true if the service is running" do
+ @provider.stub!(:is_active?).and_return(true)
+ @current_resource.should_receive(:running).with(true)
+ @provider.load_current_resource
+ end
+
+ it "should set running to false if the service is not running" do
+ @provider.stub!(:is_active?).and_return(false)
+ @current_resource.should_receive(:running).with(false)
+ @provider.load_current_resource
+ end
+
+ describe "when a status command has been specified" do
+ before do
+ @new_resource.stub!(:status_command).and_return("/bin/chefhasmonkeypants status")
+ end
+
+ it "should run the services status command if one has been specified" do
+ @provider.stub!(:run_command_with_systems_locale).with({:command => "/bin/chefhasmonkeypants status"}).and_return(0)
+ @current_resource.should_receive(:running).with(true)
+ @provider.load_current_resource
+ end
+
+ it "should set running to false if it catches a Chef::Exceptions::Exec when using a status command" do
+ @provider.stub!(:run_command_with_systems_locale).and_raise(Chef::Exceptions::Exec)
+ @current_resource.should_receive(:running).with(false)
+ @provider.load_current_resource
+ end
+ end
+
+ it "should check if the service is enabled" do
+ @provider.should_receive(:is_enabled?)
+ @provider.load_current_resource
+ end
+
+ it "should set enabled to true if the service is enabled" do
+ @provider.stub!(:is_enabled?).and_return(true)
+ @current_resource.should_receive(:enabled).with(true)
+ @provider.load_current_resource
+ end
+
+ it "should set enabled to false if the service is not enabled" do
+ @provider.stub!(:is_enabled?).and_return(false)
+ @current_resource.should_receive(:enabled).with(false)
+ @provider.load_current_resource
+ end
+
+ it "should return the current resource" do
+ @provider.load_current_resource.should eql(@current_resource)
+ end
+ end
+
+ describe "start and stop service" do
+ before(:each) do
+ @current_resource = Chef::Resource::Service.new('rsyslog.service')
+ Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ @provider.current_resource = @current_resource
+ end
+
+ it "should call the start command if one is specified" do
+ @new_resource.stub!(:start_command).and_return("/sbin/rsyslog startyousillysally")
+ @provider.should_receive(:run_command).with({:command => "/sbin/rsyslog startyousillysally"}).and_return(0)
+ @provider.start_service
+ end
+
+ it "should call '/bin/systemctl start service_name' if no start command is specified" do
+ @provider.should_receive(:run_command_with_systems_locale).with({:command => "/bin/systemctl start #{@new_resource.service_name}"}).and_return(0)
+ @provider.start_service
+ end
+
+ it "should not call '/bin/systemctl start service_name' if it is already running" do
+ @current_resource.stub!(:running).and_return(true)
+ @provider.should_not_receive(:run_command_with_systems_locale).with({:command => "/bin/systemctl start #{@new_resource.service_name}"}).and_return(0)
+ @provider.start_service
+ end
+
+ it "should call the restart command if one is specified" do
+ @current_resource.stub!(:running).and_return(true)
+ @new_resource.stub!(:restart_command).and_return("/sbin/rsyslog restartyousillysally")
+ @provider.should_receive(:run_command).with({:command => "/sbin/rsyslog restartyousillysally"}).and_return(0)
+ @provider.restart_service
+ end
+
+ it "should call '/bin/systemctl restart service_name' if no restart command is specified" do
+ @current_resource.stub!(:running).and_return(true)
+ @provider.should_receive(:run_command_with_systems_locale).with({:command => "/bin/systemctl restart #{@new_resource.service_name}"}).and_return(0)
+ @provider.restart_service
+ end
+
+ it "should call the reload command if one is specified" do
+ @current_resource.stub!(:running).and_return(true)
+ @new_resource.stub!(:reload_command).and_return("/sbin/rsyslog reloadyousillysally")
+ @provider.should_receive(:run_command).with({:command => "/sbin/rsyslog reloadyousillysally"}).and_return(0)
+ @provider.reload_service
+ end
+
+ it "should call '/bin/systemctl reload service_name' if no reload command is specified" do
+ @current_resource.stub!(:running).and_return(true)
+ @provider.should_receive(:run_command_with_systems_locale).with({:command => "/bin/systemctl reload #{@new_resource.service_name}"}).and_return(0)
+ @provider.reload_service
+ end
+
+ it "should call the stop command if one is specified" do
+ @current_resource.stub!(:running).and_return(true)
+ @new_resource.stub!(:stop_command).and_return("/sbin/rsyslog stopyousillysally")
+ @provider.should_receive(:run_command).with({:command => "/sbin/rsyslog stopyousillysally"}).and_return(0)
+ @provider.stop_service
+ end
+
+ it "should call '/bin/systemctl stop service_name' if no stop command is specified" do
+ @current_resource.stub!(:running).and_return(true)
+ @provider.should_receive(:run_command_with_systems_locale).with({:command => "/bin/systemctl stop #{@new_resource.service_name}"}).and_return(0)
+ @provider.stop_service
+ end
+
+ it "should not call '/bin/systemctl stop service_name' if it is already stopped" do
+ @current_resource.stub!(:running).and_return(false)
+ @provider.should_not_receive(:run_command_with_systems_locale).with({:command => "/bin/systemctl stop #{@new_resource.service_name}"}).and_return(0)
+ @provider.stop_service
+ end
+ end
+
+ describe "enable and disable service" do
+ before(:each) do
+ @current_resource = Chef::Resource::Service.new('rsyslog.service')
+ Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ @provider.current_resource = @current_resource
+ end
+
+ it "should call '/bin/systemctl enable service_name' to enable the service" do
+ @provider.should_receive(:run_command_with_systems_locale).with({:command => "/bin/systemctl enable #{@new_resource.service_name}"}).and_return(0)
+ @provider.enable_service
+ end
+
+ it "should call '/bin/systemctl disable service_name' to disable the service" do
+ @provider.should_receive(:run_command_with_systems_locale).with({:command => "/bin/systemctl disable #{@new_resource.service_name}"}).and_return(0)
+ @provider.disable_service
+ end
+ end
+
+ describe "is_active?" do
+ before(:each) do
+ @current_resource = Chef::Resource::Service.new('rsyslog.service')
+ Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ end
+
+ it "should return true if '/bin/systemctl is-active service_name' returns 0" do
+ @provider.should_receive(:run_command_with_systems_locale).with({:command => '/bin/systemctl is-active rsyslog.service', :ignore_failure => true}).and_return(0)
+ @provider.is_active?.should be_true
+ end
+
+ it "should return false if '/bin/systemctl is-active service_name' returns anything except 0" do
+ @provider.should_receive(:run_command_with_systems_locale).with({:command => '/bin/systemctl is-active rsyslog.service', :ignore_failure => true}).and_return(1)
+ @provider.is_active?.should be_false
+ end
+ end
+
+ describe "is_enabled?" do
+ before(:each) do
+ @current_resource = Chef::Resource::Service.new('rsyslog.service')
+ Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ end
+
+ it "should return true if '/bin/systemctl is-enabled service_name' returns 0" do
+ @provider.should_receive(:run_command_with_systems_locale).with({:command => '/bin/systemctl is-enabled rsyslog.service', :ignore_failure => true}).and_return(0)
+ @provider.is_enabled?.should be_true
+ end
+
+ it "should return false if '/bin/systemctl is-enabled service_name' returns anything except 0" do
+ @provider.should_receive(:run_command_with_systems_locale).with({:command => '/bin/systemctl is-enabled rsyslog.service', :ignore_failure => true}).and_return(1)
+ @provider.is_enabled?.should be_false
+ end
+ end
+end