service/src/service.cr

135 lines
3.2 KiB
Crystal

require "option_parser"
require "yaml"
require "colorize"
require "./config.cr"
# TODO:
# - Be more declarative about the definition of commands.
require "./service/*"
args = [] of String
parser = OptionParser.parse! do |parser|
parser.banner = "usage: service <command> [options]\n" +
"\n" +
"commands:\n" +
" start Starts a stopped or dead service.\n" +
" stop Stops a running service.\n" +
" status Shows the current state of a service.\n" +
" show Describe a service in detail.\n" +
" add Add a service to an environment.\n" +
" del Remove a service from an environment.\n" +
" list Lists registered services.\n" +
" list-environments Lists registered environments.\n" +
"\n" +
"options:\n"
parser.on "-h", "--help", "Prints this help message." do
puts parser
exit 0
end
parser.unknown_args do |x|
args = x
end
end
command = args[0]?
if command.nil?
STDERR << parser << "\n"
exit 1
end
ServiceDefinition.load SERVICES_DIRECTORY
Environment.load ENVIRONMENTS_DIRECTORY
Service.load RC_DIRECTORY
begin
if args[0] == "help"
puts parser
elsif args[0] == "add"
Service.new(args[1], args[2]?).write RC_DIRECTORY
elsif args[0] == "del"
Service.new(args[1], args[2]?).remove RC_DIRECTORY
elsif args[0] == "start"
services = args[1..args.size].map do |arg|
service = Service.get_by_id(arg)
unless service
raise Service::Exception.new "Service '#{arg}' does not exist."
end
service
end
services.each do |service|
service.dependency_tree.flatten.reverse.each do |service|
next if service.running? PID_DIRECTORY
puts "starting #{service.to_s}"
service.start PID_DIRECTORY, LOG_DIRECTORY
end
end
elsif args[0] == "stop"
services = args[1..args.size].map do |arg|
service = Service.get_by_id(arg)
unless service
raise Service::Exception.new "Service '#{arg}' does not exist."
end
service
end
services.each do |service|
# FIXME: Build revdep tree and stop services started as dependencies?
next if ! service.running? PID_DIRECTORY
# FIXME: Should we remove duplicate services from the
# tree once flattened?
service.reverse_dependency_tree.flatten.reverse.each do |service|
next if ! service.running? PID_DIRECTORY
puts "stopping #{service.to_s}"
service.stop PID_DIRECTORY
end
end
elsif args[0] == "status"
puts Service.new(args[1], args[2]?).status PID_DIRECTORY
elsif args[0] == "show"
service = Service.all.find do |service|
unless service.name == args[1]
next false
end
env = args[2]? || "root"
if service.environment.name != env
next false
end
true
end
if service
puts service.summary
else
STDERR << "No such service is registered.\n"
exit 2
end
elsif args[0] == "list"
Service.all.map do |service|
puts service.to_s
end
elsif args[0] == "list-environments"
Environment.all.map do |env|
puts env.to_s
end
else
STDERR << parser << "\n"
exit 1
end
rescue e : Service::Exception
STDERR << e.message << "\n"
exit 2
end