module AIDS
- RUNLEVEL_SINGLE = 'S'
- RUNLEVEL_MULTI_TO_SINGLE = '1'
- RUNLEVEL_MULTI = '2'
- RUNLEVEL_HALT = '0'
- RUNLEVEL_REBOOT = '6'
+ RUNLEVEL_SINGLE = :'S'
+ RUNLEVEL_MULTI_TO_SINGLE = :'1'
+ RUNLEVEL_MULTI = :'2'
+ RUNLEVEL_MULTI_ALL = [:'2',:'3',:'4',:'5']
+ RUNLEVEL_HALT = :'0'
+ RUNLEVEL_REBOOT = :'6'
+ RUNLEVEL_ALL = [:'0',:'1',:'2',:'3',:'4',:'5',:'6',:'S']
class Service
attr_reader :name
def initialize(name)
if name.nil? or name.empty? or not name.is_a?(String)
- raise Exception.new("Service name must be a non-empty string, got #{name.inspect}.")
+ raise AIDS::Infection.new("Service name must be a non-empty string, got #{name.inspect}.")
end
name = $1 if name =~ %r{^/etc/init\.d/(.+)$}
if name =~ /[^[:alnum:]\-.]/
- raise Exception.new("Invalid init script name: #{name}.")
+ raise AIDS::Infection.new("Invalid init script name: #{name}.")
end
unless File.exist?("/etc/init.d/#{name}")
- raise Exception.new("Unknown service: #{name}.")
+ raise AIDS::Infection.new("Unknown service: #{name}.")
end
@name = name
end
def enable!
- start_on_runlevel!(RUNLEVEL_MULTI)
+ start_on_runlevels!(RUNLEVEL_MULTI_ALL)
end
def disable!
- stop_on_runlevel!(RUNLEVEL_MULTI)
+ stop_on_runlevels!(RUNLEVEL_MULTI_ALL)
end
def enabled?
end
def status
- if started_on_runlevel?(RUNLEVEL_MULTI)
- :enabled
- elsif stopped_on_runlevel?(RUNLEVEL_MULTI)
- :disabled
- else
- :unknown
+ status = {}
+ RUNLEVEL_ALL.each do |r|
+ if started_on_runlevel?(r)
+ status[r] = :start
+ elsif stopped_on_runlevel?(r)
+ status[r] = :stop
+ else
+ status[r] = :none
+ end
end
+ status
end
private
not Dir.glob("/etc/rc#{runlevel}.d/K[0-9][0-9]#{@name}").empty?
end
- def start_on_runlevel!(runlevel)
- AIDS.validate_runlevel(runlevel)
- return true if started_on_runlevel?(runlevel)
- updatercd(:enable, runlevel)
+ def start_on_runlevels!(runlevels)
+ [runlevels].flatten.each do |r|
+ AIDS.validate_runlevel(r)
+ next if started_on_runlevel?(r)
+ updatercd(:enable, r)
+ end
end
- def stop_on_runlevel!(runlevel)
- AIDS.validate_runlevel(runlevel)
- return true if stopped_on_runlevel?(runlevel)
- updatercd(:disable, runlevel)
+ def stop_on_runlevels!(runlevels)
+ [runlevels].flatten.each do |r|
+ AIDS.validate_runlevel(r)
+ next if stopped_on_runlevel?(r)
+ updatercd(:disable, r)
+ end
end
def set_default_runlevels!
def updatercd(action, runlevel=nil)
unless [:enable, :disable, :remove, :defaults].include?(action)
- raise Exception.new("Invalid action for updatercd: #{action}.")
+ raise AIDS::Infection.new("Invalid action for updatercd: #{action}.")
end
AIDS.validate_runlevel(runlevel) if runlevel
# update-rc.d will baulk at being told to do anything with
# these runlevels.
- if ['0', '1', '6'].include?(runlevel.to_s)
- raise Exception.new("Unable to comply: update-rc.d is balls.")
+ if [:'0',:'1',:'6'].include?(runlevel)
+ raise AIDS::Infection.new("Unable to comply: update-rc.d is balls.")
end
pid = Process.fork do
$stdout.close
end
Process.wait(pid)
if (rc = $?.exitstatus) != 0
- raise Exception.new("update-rc.d returned #{rc}")
+ raise AIDS::Infection.new("update-rc.d returned #{rc}")
end
end
end
+ class Infection < Exception
+ end
+
def self.get_all_services
Dir.glob("/etc/init.d/*").map do |f|
next unless File.executable?(f)
end.compact
end
+ private
+
def self.validate_runlevel(runlevel)
- unless ['0', '1', '2', '3', '4', '5', '6', 'S'].include?(runlevel.to_s)
- raise Exception.new("Invalid runlevel: #{runlevel}.")
+ unless RUNLEVEL_ALL.include?(runlevel)
+ raise AIDS::Infection.new("Invalid runlevel: #{runlevel}.")
end
end
end