summaryrefslogtreecommitdiffstats
path: root/lib/puppet/provider/service/init.rb
blob: 5804732ede627e65573b4a2f364df0abb36628b9 (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
# 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 no ``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", "/usr/local/etc/rc.d"]
    when "HP-UX"
        @defpath = "/sbin/init.d"
    else
        @defpath = "/etc/init.d"
    end

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

    # List all services of this type.
    def self.instances
        get_services(self.defpath)
    end

    def self.get_services(defpath, exclude=[])
        defpath = [defpath] unless defpath.is_a? Array
        instances = []
        defpath.each do |path|
            unless FileTest.directory?(path)
                Puppet.debug "Service path %s does not exist" % path
                next
            end

            check = [:ensure]

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

            Dir.entries(path).each do |name|
                fullpath = File.join(path, name)
                next if name =~ /^\./
                next if exclude.include? name
                next if not FileTest.executable?(fullpath)
                instances << new(:name => name, :path => path, :hasstatus => true)
            end
        end
        instances
    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
        @initscript ||= self.search(@resource[:name])
    end

    def paths
        @paths ||= @resource[:path].find_all do |path|
            if File.directory?(path)
                true
            else
                if File.exist?(path) and ! File.directory?(path)
                    self.debug "Search path #{path} is not a directory"
                else
                    self.debug "Search path #{path} does not exist"
                end
                false
            end
        end
    end

    def search(name)
        paths.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
        }

        paths.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
        [initscript, :start]
    end

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

    def restartcmd
        (@resource[:hasrestart] == :true) && [initscript, :restart]
    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
        (@resource[:hasstatus] == :true) && [initscript, :status]
    end

end