2019-06-09 18:08:59 +02:00
|
|
|
require "option_parser"
|
2019-06-09 16:59:05 +02:00
|
|
|
require "yaml"
|
|
|
|
require "colorize"
|
|
|
|
|
2019-06-09 18:08:59 +02:00
|
|
|
require "./config.cr"
|
2019-06-09 17:14:18 +02:00
|
|
|
|
2019-06-09 18:08:59 +02:00
|
|
|
# TODO:
|
|
|
|
# - Be more declarative about the definition of commands.
|
2019-06-09 16:59:05 +02:00
|
|
|
|
2019-06-09 18:08:59 +02:00
|
|
|
require "./service/*"
|
2019-06-09 16:59:05 +02:00
|
|
|
|
2019-06-09 18:08:59 +02:00
|
|
|
args = [] of String
|
2019-06-09 16:59:05 +02:00
|
|
|
|
2019-10-19 18:08:34 +02:00
|
|
|
parser = OptionParser.parse do |parser|
|
2019-06-09 18:08:59 +02:00
|
|
|
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"
|
2019-06-09 16:59:05 +02:00
|
|
|
|
2019-06-09 18:08:59 +02:00
|
|
|
parser.on "-h", "--help", "Prints this help message." do
|
|
|
|
puts parser
|
|
|
|
exit 0
|
2019-06-09 16:59:05 +02:00
|
|
|
end
|
2019-06-09 18:08:59 +02:00
|
|
|
parser.unknown_args do |x|
|
|
|
|
args = x
|
2019-06-09 16:59:05 +02:00
|
|
|
end
|
2019-06-09 18:08:59 +02:00
|
|
|
end
|
2019-06-09 16:59:05 +02:00
|
|
|
|
2019-06-09 18:08:59 +02:00
|
|
|
command = args[0]?
|
|
|
|
if command.nil?
|
|
|
|
STDERR << parser << "\n"
|
|
|
|
exit 1
|
|
|
|
end
|
2019-06-09 16:59:05 +02:00
|
|
|
|
2019-06-09 18:08:59 +02:00
|
|
|
ServiceDefinition.load SERVICES_DIRECTORY
|
|
|
|
Environment.load ENVIRONMENTS_DIRECTORY
|
|
|
|
Service.load RC_DIRECTORY
|
|
|
|
|
|
|
|
begin
|
|
|
|
if args[0] == "help"
|
|
|
|
puts parser
|
|
|
|
elsif args[0] == "add"
|
2019-08-10 22:02:11 +02:00
|
|
|
environment : String? = nil
|
|
|
|
providers = Hash(String, String).new
|
|
|
|
|
|
|
|
args.each_with_index do |arg, i|
|
|
|
|
next if i == 0
|
|
|
|
|
|
|
|
match = arg.match /(.*)=(.*)/
|
|
|
|
|
|
|
|
if match.nil?
|
|
|
|
# FIXME: Check environment is not defined already.
|
|
|
|
environment = arg
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
|
|
|
providers[match[1]] = match[2]
|
|
|
|
end
|
|
|
|
|
|
|
|
Service.new(args[1], environment).tap do |service|
|
|
|
|
service.consumes.each do |token|
|
|
|
|
provider = providers[token.token]?
|
|
|
|
|
2019-08-10 22:29:11 +02:00
|
|
|
if provider.nil?
|
|
|
|
provider = service.get_default_provider token.token
|
|
|
|
end
|
|
|
|
|
2019-08-10 22:02:11 +02:00
|
|
|
if provider.nil?
|
|
|
|
STDERR.puts "This service consumes a “#{token.token}” token, but you have not specified what other service is supposed to provide it."
|
|
|
|
STDERR.puts "Use the `service add #{args[1]} #{token.token}=<provider>` syntax to specify it."
|
|
|
|
exit 1
|
|
|
|
end
|
|
|
|
|
|
|
|
service.providers[token.token] = provider
|
|
|
|
end
|
|
|
|
pp! service.providers
|
|
|
|
end.write RC_DIRECTORY
|
2019-06-09 18:08:59 +02:00
|
|
|
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)
|
2019-06-09 16:59:05 +02:00
|
|
|
|
2019-06-09 18:08:59 +02:00
|
|
|
unless service
|
|
|
|
raise Service::Exception.new "Service '#{arg}' does not exist."
|
|
|
|
end
|
2019-06-09 16:59:05 +02:00
|
|
|
|
2019-06-09 18:08:59 +02:00
|
|
|
service
|
2019-06-09 16:59:05 +02:00
|
|
|
end
|
|
|
|
|
2019-06-09 18:08:59 +02:00
|
|
|
services.each do |service|
|
|
|
|
service.dependency_tree.flatten.reverse.each do |service|
|
|
|
|
next if service.running? PID_DIRECTORY
|
2019-06-09 16:59:05 +02:00
|
|
|
|
2019-06-09 18:08:59 +02:00
|
|
|
puts "starting #{service.to_s}"
|
|
|
|
service.start PID_DIRECTORY, LOG_DIRECTORY
|
2019-06-09 16:59:05 +02:00
|
|
|
end
|
|
|
|
end
|
2019-06-09 18:08:59 +02:00
|
|
|
elsif args[0] == "stop"
|
|
|
|
services = args[1..args.size].map do |arg|
|
|
|
|
service = Service.get_by_id(arg)
|
2019-06-09 16:59:05 +02:00
|
|
|
|
2019-06-09 18:08:59 +02:00
|
|
|
unless service
|
|
|
|
raise Service::Exception.new "Service '#{arg}' does not exist."
|
2019-06-09 16:59:05 +02:00
|
|
|
end
|
|
|
|
|
2019-06-09 18:08:59 +02:00
|
|
|
service
|
2019-06-09 16:59:05 +02:00
|
|
|
end
|
|
|
|
|
2019-06-09 18:08:59 +02:00
|
|
|
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
|
2019-06-09 16:59:05 +02:00
|
|
|
|
2019-06-09 18:08:59 +02:00
|
|
|
puts "stopping #{service.to_s}"
|
|
|
|
service.stop PID_DIRECTORY
|
2019-06-09 16:59:05 +02:00
|
|
|
end
|
|
|
|
end
|
2019-06-09 18:08:59 +02:00
|
|
|
elsif args[0] == "status"
|
2019-06-10 14:32:30 +02:00
|
|
|
child = Process.run "#{OWN_LIBEXEC_DIR}/status", [args[1]],
|
|
|
|
output: Process::Redirect::Inherit,
|
|
|
|
error: Process::Redirect::Inherit
|
2019-10-19 18:08:34 +02:00
|
|
|
return_value = (child.exit_status / 256).to_i
|
2019-06-10 14:32:30 +02:00
|
|
|
|
|
|
|
# Errors not registered here should probably be verbose in `status`.
|
|
|
|
if return_value == 1
|
|
|
|
STDERR << "No such service.\n"
|
|
|
|
end
|
|
|
|
|
|
|
|
exit return_value
|
2019-06-09 18:08:59 +02:00
|
|
|
elsif args[0] == "show"
|
|
|
|
service = Service.all.find do |service|
|
|
|
|
unless service.name == args[1]
|
|
|
|
next false
|
2019-06-09 16:59:05 +02:00
|
|
|
end
|
|
|
|
|
2019-06-09 18:08:59 +02:00
|
|
|
env = args[2]? || "root"
|
|
|
|
if service.environment.name != env
|
|
|
|
next false
|
2019-06-09 16:59:05 +02:00
|
|
|
end
|
|
|
|
|
2019-06-09 18:08:59 +02:00
|
|
|
true
|
2019-06-09 16:59:05 +02:00
|
|
|
end
|
2019-06-09 18:08:59 +02:00
|
|
|
if service
|
|
|
|
puts service.summary
|
2019-06-09 16:59:05 +02:00
|
|
|
else
|
2019-06-09 18:08:59 +02:00
|
|
|
STDERR << "No such service is registered.\n"
|
|
|
|
exit 2
|
2019-06-09 16:59:05 +02:00
|
|
|
end
|
2019-06-09 18:08:59 +02:00
|
|
|
elsif args[0] == "list"
|
|
|
|
Service.all.map do |service|
|
|
|
|
puts service.to_s
|
2019-06-09 16:59:05 +02:00
|
|
|
end
|
2019-06-09 18:08:59 +02:00
|
|
|
elsif args[0] == "list-environments"
|
|
|
|
Environment.all.map do |env|
|
|
|
|
puts env.to_s
|
2019-06-09 16:59:05 +02:00
|
|
|
end
|
2019-06-09 18:08:59 +02:00
|
|
|
else
|
|
|
|
STDERR << parser << "\n"
|
|
|
|
exit 1
|
2019-06-09 16:59:05 +02:00
|
|
|
end
|
2019-06-09 18:08:59 +02:00
|
|
|
rescue e : Service::Exception
|
|
|
|
STDERR << e.message << "\n"
|
|
|
|
exit 2
|
2019-06-09 16:59:05 +02:00
|
|
|
end
|
|
|
|
|