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
|
require 'timeout'
# AIX System Resource controller (SRC)
Puppet::Type.type(:service).provide :src, :parent => :base do
desc "Support for AIX's System Resource controller.
Services are started/stopped based on the `stopsrc` and `startsrc`
commands, and some services can be refreshed with `refresh` command.
Enabling and disabling services is not supported, as it requires
modifications to `/etc/inittab`. Starting and stopping groups of subsystems
is not yet supported.
"
defaultfor :operatingsystem => :aix
confine :operatingsystem => :aix
optional_commands :stopsrc => "/usr/bin/stopsrc",
:startsrc => "/usr/bin/startsrc",
:refresh => "/usr/bin/refresh",
:lssrc => "/usr/bin/lssrc",
:lsitab => "/usr/sbin/lsitab",
:mkitab => "/usr/sbin/mkitab",
:rmitab => "/usr/sbin/rmitab",
:chitab => "/usr/sbin/chitab"
has_feature :refreshable
def self.instances
services = lssrc('-S')
services.split("\n").reject { |x| x.strip.start_with? '#' }.collect do |line|
data = line.split(':')
service_name = data[0]
new(:name => service_name)
end
end
def startcmd
[command(:startsrc), "-s", @resource[:name]]
end
def stopcmd
[command(:stopsrc), "-s", @resource[:name]]
end
def default_runlevel
"2"
end
def default_action
"once"
end
def enabled?
output = execute([command(:lsitab), @resource[:name]], {:failonfail => false, :combine => true})
output.exitstatus == 0 ? :true : :false
end
def enable
mkitab("%s:%s:%s:%s" % [@resource[:name], default_runlevel, default_action, startcmd.join(" ")])
end
def disable
rmitab(@resource[:name])
end
# Wait for the service to transition into the specified state before returning.
# This is necessary due to the asynchronous nature of AIX services.
# desired_state should either be :running or :stopped.
def wait(desired_state)
Timeout.timeout(60) do
loop do
status = self.status
break if status == desired_state.to_sym
sleep(1)
end
end
rescue Timeout::Error
raise Puppet::Error.new("Timed out waiting for #{@resource[:name]} to transition states")
end
def start
super
self.wait(:running)
end
def stop
super
self.wait(:stopped)
end
def restart
execute([command(:lssrc), "-Ss", @resource[:name]]).each_line do |line|
args = line.split(":")
next unless args[0] == @resource[:name]
# Subsystems with the -K flag can get refreshed (HUPed)
# While subsystems with -S (signals) must be stopped/started
method = args[11]
do_refresh = case method
when "-K" then :true
when "-S" then :false
else self.fail("Unknown service communication method #{method}")
end
begin
if do_refresh == :true
execute([command(:refresh), "-s", @resource[:name]])
else
self.stop
self.start
end
return :true
rescue Puppet::ExecutionFailure => detail
raise Puppet::Error.new("Unable to restart service #{@resource[:name]}, error was: #{detail}", detail )
end
end
self.fail("No such service found")
rescue Puppet::ExecutionFailure => detail
raise Puppet::Error.new("Cannot get status of #{@resource[:name]}, error was: #{detail}", detail )
end
def status
execute([command(:lssrc), "-s", @resource[:name]]).each_line do |line|
args = line.split
# This is the header line
next unless args[0] == @resource[:name]
# PID is the 3rd field, but inoperative subsystems
# skip this so split doesn't work right
state = case args[-1]
when "active" then :running
when "inoperative" then :stopped
end
Puppet.debug("Service #{@resource[:name]} is #{args[-1]}")
return state
end
rescue Puppet::ExecutionFailure => detail
self.debug(detail.message)
return :stopped
end
end
|