summaryrefslogtreecommitdiffstats
path: root/lib/puppet/provider/service/init.rb
blob: 447c01aa5db4f796618e5ee28a0129df14120aa8 (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
# 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 #{path} does not exist"
        next
      end

      check = [:ensure]

      check << :enable if public_method_defined? :enabled?

      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 #{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 #{name} in #{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 #{name}.sh in #{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 '#{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