summaryrefslogtreecommitdiffstats
path: root/lib/puppet/provider/service/init.rb
blob: 51a77a15730afe4702a0303c75075abb8de55df3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# The standard init-based service type.  Many other service types are
# customizations of this module.
Puppet::Type.type(:service).provide :init, :parent => :base do
    desc "Standard init service management.  This provider assumes that the
        init script has not ``status`` command, because so few scripts do,
        so you need to either provide a status command or specify via ``hasstatus``
        that one already exists in the init script."

    class << self
        attr_accessor :defpath
    end

    case Facter["operatingsystem"].value
    when "FreeBSD":
        @defpath = "/etc/rc.d"
    else
        @defpath = "/etc/init.d"
    end

    # We can't confine this here, because the init path can be overridden.
    #confine :exists => @defpath

    if self.suitable?
        # Add it to the search paths
        Puppet.type(:service).newpath(:init, defpath())

        # Set the default init directory.
        Puppet.type(:service).attrclass(:path).defaultto defpath()
    end

    # List all services of this type.
    def self.instances(name)
        # We need to find all paths specified for our type or any parent types
        paths = Puppet.type(:service).paths(name)

        # Now see if there are any included modules
        included_modules.each do |mod|
            next unless mod.respond_to? :name

            mname = mod.name

            if mpaths = Puppet.type(:service).paths(mname) and ! mpaths.empty?
                 paths += mpaths
            end
        end

        paths.collect do |path|
            unless FileTest.directory?(path)
                Puppet.notice "Service path %s does not exist" % path
                next
            end

            check = [:ensure]

            if public_method_defined? :enabled?
                check << :enable
            end

            Dir.entries(path).reject { |e|
                fullpath = File.join(path, e)
                e =~ /^\./ or ! FileTest.executable?(fullpath)
            }.collect do |name|
                new(:name => name, :path => path)
            end
        end
    end

    # Mark that our init script supports 'status' commands.
    def hasstatus=(value)
        case value
        when true, "true": @parameters[:hasstatus] = true
        when false, "false": @parameters[:hasstatus] = false
        else
            raise Puppet::Error, "Invalid 'hasstatus' value %s" %
                value.inspect
        end
    end

    # Where is our init script?
    def initscript
        if defined? @initscript
            return @initscript
        else
            @initscript = self.search(@resource[:name])
        end
    end

    def restart
        if @resource[:hasrestart] == :true
            command = [self.initscript, :restart]
            texecute("restart", command)
        else
            super
        end
    end

    def search(name)
        @resource[:path].each { |path|
            fqname = File.join(path,name)
            begin
                stat = File.stat(fqname)
            rescue
                # should probably rescue specific errors...
                self.debug("Could not find %s in %s" % [name,path])
                next
            end

            # if we've gotten this far, we found a valid script
            return fqname
        }
        @model[:path].each { |path|
            fqname_sh = File.join(path,"#{name}.sh")
            begin
                stat = File.stat(fqname_sh)
            rescue
                # should probably rescue specific errors...
                self.debug("Could not find %s.sh in %s" % [name,path])
                next
            end

            # if we've gotten this far, we found a valid script
            return fqname_sh
        }
        raise Puppet::Error, "Could not find init script for '%s'" % name
    end

    # The start command is just the init scriptwith 'start'.
    def startcmd
        [self.initscript, :start]
    end

    # If it was specified that the init script has a 'status' command, then
    # we just return that; otherwise, we return false, which causes it to
    # fallback to other mechanisms.
    def statuscmd
        if @resource[:hasstatus]
            return [self.initscript, :status]
        else
            return false
        end
    end

    # The stop command is just the init script with 'stop'.
    def stopcmd
        [self.initscript, :stop]
    end
end

# $Id$