This provider manages daemons running supervised by Runit[1].
It tries to detect the service directory, with by order of preference:
* /service
* /var/service
* /etc/service
The daemon directory should be placed in a directory that can be
by default in:
* /etc/sv
* /var/lib/service
or this can be overriden in the service resource parameters:
service {
"myservice":
provider => "runit", path => "/path/to/daemons";
}
This provider supports out of the box:
* start/stop
* enable/disable
* restart
* status
[1]: http://smarden.sunsite.dk/runit/
Signed-off-by: Brice Figureau <[EMAIL PROTECTED]>
---
lib/puppet/provider/service/runit.rb | 93 ++++++++++++++++++++
.../provider/service/{daemontools.rb => runit.rb} | 45 ++++------
2 files changed, 110 insertions(+), 28 deletions(-)
create mode 100644 lib/puppet/provider/service/runit.rb
copy spec/unit/provider/service/{daemontools.rb => runit.rb} (62%)
diff --git a/lib/puppet/provider/service/runit.rb
b/lib/puppet/provider/service/runit.rb
new file mode 100644
index 0000000..edd6587
--- /dev/null
+++ b/lib/puppet/provider/service/runit.rb
@@ -0,0 +1,93 @@
+# Daemontools service management
+#
+# author Brice Figureau <[EMAIL PROTECTED]>
+Puppet::Type.type(:service).provide :runit, :parent => :daemontools do
+ desc "Runit service management.
+ This provider manages daemons running supervised by Runit.
+ It tries to detect the service directory, with by order of preference:
+ * /service
+ * /var/service
+ * /etc/service
+ The daemon directory should be placed in a directory that can be
+ by default in:
+ * /etc/sv
+ or this can be overriden in the service resource parameters:
+ service {
+ \"myservice\":
+ provider => \"runit\", path => \"/path/to/daemons\";
+ }
+
+ This provider supports out of the box:
+ * start/stop
+ * enable/disable
+ * restart
+ * status"
+
+ commands :sv => "/usr/bin/sv"
+
+ class << self
+ # this is necessary to autodetect a valid resource
+ # default path, since there is no standard for such directory.
+ def defpath
+ unless defined?(@defpath) and @defpath
+ ["/etc/sv", "/var/lib/service"].each do |path|
+ if FileTest.exist?(path)
+ @defpath = path
+ break
+ end
+ end
+ raise "Could not find the daemon directory (tested
[/var/lib/service,/etc])" unless @defpath
+ end
+ @defpath
+ end
+ end
+
+ # find the service dir on this node
+ def servicedir
+ unless defined?(@servicedir) and @servicedir
+ ["/service", "/etc/service","/var/service"].each do |path|
+ if FileTest.exist?(path)
+ @servicedir = path
+ break
+ end
+ end
+ raise "Could not find service directory" unless @servicedir
+ end
+ @servicedir
+ end
+
+ def restartcmd
+ [ command(:sv), "restart", self.service]
+ end
+
+ def status
+ begin
+ output = sv "status", self.service
+ return :running if output =~ /^run: /
+ rescue Puppet::ExecutionFailure => detail
+ unless detail =~ /runsv not running$/
+ raise Puppet::Error.new( "Could not get status for service %s:
%s" % [ resource.ref, detail] )
+ end
+ end
+ return :stopped
+ end
+
+ # relay to the stopcmd
+ def stop
+ ucommand( :stop )
+ end
+
+ def stopcmd
+ [ command(:sv), "stop", self.service]
+ end
+
+ # disable by removing the symlink so that runit
+ # doesn't restart our service behind our back
+ # note that runit doesn't need to perform a stop
+ # before a disable
+ def disable
+ # unlink the daemon symlink to disable it
+ File.unlink(self.service) if FileTest.symlink?(self.service)
+ end
+end
+
diff --git a/spec/unit/provider/service/daemontools.rb
b/spec/unit/provider/service/runit.rb
similarity index 62%
copy from spec/unit/provider/service/daemontools.rb
copy to spec/unit/provider/service/runit.rb
index 29e9dd5..d32cca5 100644
--- a/spec/unit/provider/service/daemontools.rb
+++ b/spec/unit/provider/service/runit.rb
@@ -1,12 +1,12 @@
#!/usr/bin/env ruby
#
-# Unit testing for the Daemontools service Provider
+# Unit testing for the Runit service Provider
#
# author Brice Figureau
#
require File.dirname(__FILE__) + '/../../../spec_helper'
-provider_class = Puppet::Type.type(:service).provider(:daemontools)
+provider_class = Puppet::Type.type(:service).provider(:runit)
describe provider_class do
@@ -17,7 +17,7 @@ describe provider_class do
@provider = provider_class.new
@servicedir = "/etc/service"
@[EMAIL PROTECTED]
- @daemondir = "/var/lib/service"
+ @daemondir = "/etc/sv"
@[EMAIL PROTECTED]
# A catch all; no parameters set
@@ -32,7 +32,7 @@ describe provider_class do
@provider.stubs(:resource).returns @resource
end
-
+
it "should have a restartcmd method" do
@provider.should respond_to(:restartcmd)
end
@@ -65,8 +65,8 @@ describe provider_class do
end
describe "when stopping" do
- it "should call disable" do
- @provider.expects(:disable)
+ it "should execute external command 'sv stop /etc/service/myservice'"
do
+ @provider.expects(:ucommand).with(:stop).returns("")
@provider.stop
end
end
@@ -80,44 +80,33 @@ describe provider_class do
end
describe "when disabling" do
- it "should stop and then remove the symlink between daemon dir and
service dir" do
- FileTest.stubs(:directory?).returns(false)
- FileTest.stubs(:symlink?).returns(true)
-
File.expects(:unlink).with(File.join(@servicedir,"myservice")).returns(0)
- @provider.stubs(:texecute).returns("")
- @provider.disable
- end
- end
-
- describe "when disabling" do
- it "should also call 'svc -dx /etc/service/myservice'" do
+ it "should remove the '/etc/service/myservice' symlink" do
FileTest.stubs(:directory?).returns(false)
FileTest.stubs(:symlink?).returns(true)
File.expects(:unlink).with(File.join(@servicedir,"myservice")).returns(0)
- @provider.expects(:texecute).with("stop", [nil, '-dx',
File.join(@servicedir,"myservice")]).returns ""
@provider.disable
end
end
describe "when checking status" do
- it "should call the external command 'svstat /etc/service/myservice'"
do
- @provider.expects(:svstat).with(File.join(@servicedir,"myservice"))
+ it "should call the external command 'sv status
/etc/service/myservice'" do
+
@provider.expects(:sv).with('status',File.join(@servicedir,"myservice"))
@provider.status
end
end
describe "when checking status" do
- it "and svstat fails, properly raise a Puppet::Error" do
-
@provider.expects(:svstat).with(File.join(@servicedir,"myservice")).raises(Puppet::ExecutionFailure,
"failure")
- lambda { @provider.status }.should raise_error(Puppet::Error,
'Could not get status for service Service[myservice]: failure')
+ it "and sv status fails, properly raise a Puppet::Error" do
+
@provider.expects(:sv).with('status',File.join(@servicedir,"myservice")).raises(Puppet::ExecutionFailure,
"fail: /etc/service/myservice: file not found")
+ lambda { @provider.status }.should raise_error(Puppet::Error,
'Could not get status for service Service[myservice]: fail:
/etc/service/myservice: file not found')
end
- it "and svstat returns up, then return :running" do
-
@provider.expects(:svstat).with(File.join(@servicedir,"myservice")).returns("/etc/service/myservice:
up (pid 454) 954326 seconds")
+ it "and sv status returns up, then return :running" do
+
@provider.expects(:sv).with('status',File.join(@servicedir,"myservice")).returns("run:
/etc/service/myservice: (pid 9029) 6s")
@provider.status.should == :running
end
- it "and svstat returns not running, then return :stopped" do
-
@provider.expects(:svstat).with(File.join(@servicedir,"myservice")).returns("/etc/service/myservice:
supervise not running")
- @provider.status.should == :stopped
+ it "and sv status returns not running, then return :stopped" do
+
@provider.expects(:sv).with('status',File.join(@servicedir,"myservice")).returns("fail:
/etc/service/myservice: runsv not running")
+ @provider.status.should == :stopped
end
end
--
1.5.6.5
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Puppet Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/puppet-dev?hl=en
-~----------~----~----~----~------~----~------~--~---