[Pkg-puppet-devel] [SCM] Puppet packaging for Debian branch, master, updated. debian/0.24.6-1-356-g5718585

James Turnbull james at lovedthanlost.net
Fri Jan 23 14:20:53 UTC 2009


The following commit has been merged in the master branch:
commit aae0793eb3632c6dea56f5d573d201c475786f8c
Author: Brice Figureau <brice-puppet at daysofwonder.com>
Date:   Tue Aug 26 20:47:10 2008 +0200

    Daemontools service provider
    
    This provider manages daemons running supervised under D.J.Bernstein
    daemontools.
    It tries to detect the service directory, with by order of preference:
     * /service
     * /etc/service
     * /var/lib/svscan
    
    The daemon directory should be placed in a directory that can be
    by default in:
     * /var/lib/service
     * /etc
    or this can be overriden in the service resource parameters:
    service {
     "myservice":
       provider => "daemontools", path => "/path/to/daemons";
    }
    
    This provider supports out of the box:
     * start/stop (mapped to enable/disable)
     * enable/disable
     * restart
     * status
    
    Signed-off-by: Brice Figureau <brice-puppet at daysofwonder.com>

diff --git a/lib/puppet/provider/service/daemontools.rb b/lib/puppet/provider/service/daemontools.rb
new file mode 100644
index 0000000..52d8c6b
--- /dev/null
+++ b/lib/puppet/provider/service/daemontools.rb
@@ -0,0 +1,154 @@
+# Daemontools service management
+#
+# author Brice Figureau <brice-puppet at daysofwonder.com>
+Puppet::Type.type(:service).provide :daemontools, :parent => :base do
+    desc "Daemontools service management.
+    This provider manages daemons running supervised by D.J.Bernstein daemontools.
+    It tries to detect the service directory, with by order of preference:
+     * /service
+     * /etc/service
+     * /var/lib/svscan
+    The daemon directory should be placed in a directory that can be 
+    by default in:
+     * /var/lib/service
+     * /etc
+    or this can be overriden in the service resource parameters:
+    service {
+     \"myservice\":
+       provider => \"daemontools\", path => \"/path/to/daemons\";
+    }
+
+    This provider supports out of the box:
+     * start/stop (mapped to enable/disable)
+     * enable/disable
+     * restart
+     * status"
+
+    commands :svc  => "/usr/bin/svc"
+    commands :svstat => "/usr/bin/svstat"
+
+    class << self
+        attr_writer :defpath
+        
+        # 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
+                ["/var/lib/service", "/etc"].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
+
+    attr_writer :servicedir
+
+    # returns all providers for all existing services in @defpath
+    # ie enabled or not
+    def self.instances
+        path = self.defpath
+        unless FileTest.directory?(path)
+            Puppet.notice "Service path %s does not exist" % path
+            next
+        end
+
+        # reject entries that aren't either a directory
+        # or don't contain a run file
+        Dir.entries(path).reject { |e|
+            fullpath = File.join(path, e)
+            e =~ /^\./ or ! FileTest.directory?(fullpath) or ! FileTest.exist?(File.join(fullpath,"run"))
+        }.collect do |name|
+            new(:name => name, :path => path)
+        end
+    end
+
+    # returns the daemon dir on this node
+    def self.daemondir
+        self.defpath
+    end
+
+    # find the service dir on this node
+    def servicedir
+      unless defined?(@servicedir) and @servicedir
+        ["/service", "/etc/service","/var/lib/svscan"].each do |path|
+            if FileTest.exist?(path)
+                @servicedir = path
+                break
+            end
+        end
+        raise "Could not find service directory" unless @servicedir
+      end
+      @servicedir
+    end
+
+    # returns the full path of this service when enabled
+    # (ie in the service directory)
+    def service
+        File.join(self.servicedir, resource[:name])
+    end
+
+    # returns the full path to the current daemon directory
+    # note that this path can be overriden in the resource
+    # definition
+    def daemon
+        File.join(resource[:path], resource[:name])
+    end
+    
+    def restartcmd
+        [ command(:svc), "-t", self.service]
+    end
+
+    # The start command does nothing, service are automatically started
+    # when enabled by svscan. But, forces an enable if necessary
+    def start
+        # to start make sure the sevice is enabled
+        self.enable
+        # start is then automatic
+    end
+
+    def status
+        begin
+            output = svstat self.service
+            return :running if output =~ /\bup\b/
+        rescue Puppet::ExecutionFailure => detail
+            raise Puppet::Error.new( "Could not get status for service %s: %s" % [ resource.ref, detail] )
+        end
+        return :stopped
+    end
+
+    # unfortunately it is not possible
+    # to stop without disabling the service
+    def stop
+        self.disable
+    end
+
+    # disable by stopping the service
+    # and removing the symlink so that svscan
+    # doesn't restart our service behind our back
+    def disable
+        # should stop the service
+        # stop the log subservice if any
+        log = File.join(self.service, "log")
+        texecute("stop log", [ command(:svc) , '-dx', log] ) if FileTest.directory?(log)
+        
+        # stop the main resource
+        texecute("stop", [command(:svc), '-dx', self.service] )
+
+        # unlink the daemon symlink to disable it
+        File.unlink(self.service) if FileTest.symlink?(self.service)
+    end
+
+    def enabled?
+        FileTest.symlink?(self.service)
+    end
+
+    def enable
+        File.symlink(self.daemon, self.service) if ! FileTest.symlink?(self.service)
+    end
+end
+
diff --git a/spec/unit/provider/service/daemontools.rb b/spec/unit/provider/service/daemontools.rb
new file mode 100644
index 0000000..29e9dd5
--- /dev/null
+++ b/spec/unit/provider/service/daemontools.rb
@@ -0,0 +1,124 @@
+#!/usr/bin/env ruby
+# 
+# Unit testing for the Daemontools service Provider
+#
+# author Brice Figureau
+#
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+provider_class = Puppet::Type.type(:service).provider(:daemontools)
+
+describe provider_class do
+
+    before(:each) do
+        # Create a mock resource
+        @resource = stub 'resource'
+
+        @provider = provider_class.new
+        @servicedir = "/etc/service"
+        @provider.servicedir=@servicedir
+        @daemondir = "/var/lib/service"
+        @provider.class.defpath=@daemondir
+
+        # A catch all; no parameters set
+        @resource.stubs(:[]).returns(nil)
+
+        # But set name, source and path (because we won't run
+        # the thing that will fetch the resource path from the provider)
+        @resource.stubs(:[]).with(:name).returns "myservice"
+        @resource.stubs(:[]).with(:ensure).returns :enabled
+        @resource.stubs(:[]).with(:path).returns @daemondir
+        @resource.stubs(:ref).returns "Service[myservice]"
+
+        @provider.stubs(:resource).returns @resource
+    end
+    
+    it "should have a restartcmd method" do
+        @provider.should respond_to(:restartcmd)
+    end
+
+    it "should have a start method" do
+        @provider.should respond_to(:start)
+    end
+
+    it "should have a stop method" do
+        @provider.should respond_to(:stop)
+    end
+
+    it "should have an enabled? method" do
+        @provider.should respond_to(:enabled?)
+    end
+
+    it "should have an enable method" do
+        @provider.should respond_to(:enable)
+    end
+
+    it "should have a disable method" do
+        @provider.should respond_to(:disable)
+    end
+
+    describe "when starting" do
+        it "should call enable" do
+            @provider.expects(:enable)
+            @provider.start
+        end
+    end
+
+    describe "when stopping" do
+        it "should call disable" do
+            @provider.expects(:disable)
+            @provider.stop
+        end
+    end
+
+    describe "when enabling" do
+        it "should create a symlink between daemon dir and service dir" do
+            FileTest.stubs(:symlink?).returns(false)
+            File.expects(:symlink).with(File.join(@daemondir,"myservice"), File.join(@servicedir,"myservice")).returns(0)
+            @provider.enable
+        end
+    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
+            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"))
+            @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')
+        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")
+            @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
+        end
+    end
+
+ end

-- 
Puppet packaging for Debian



More information about the Pkg-puppet-devel mailing list