151 lines
3.1 KiB
Crystal
151 lines
3.1 KiB
Crystal
require "weird-crystal-base"
|
|
|
|
class Service
|
|
end
|
|
|
|
class Service::Context < Weird::Base
|
|
property pid_directory = PID_DIRECTORY
|
|
property log_directory = LOG_DIRECTORY
|
|
property services_directory = RC_DIRECTORY
|
|
property service_definitions_directory = SERVICES_DIRECTORY
|
|
property environments_directory = ENVIRONMENTS_DIRECTORY
|
|
|
|
# FIXME: Namespaces. 😬
|
|
getter services = [] of Service
|
|
getter service_definitions = [] of ServiceDefinition
|
|
getter environments = [] of Environment
|
|
|
|
def initialize
|
|
@environments = [Environment.new self]
|
|
end
|
|
def root_environment
|
|
@environments[0]
|
|
end
|
|
|
|
def load_services
|
|
path = services_directory
|
|
|
|
return unless Dir.exists? path
|
|
|
|
Dir.each_child path do |child|
|
|
unless child.match /\.spec$/
|
|
next
|
|
end
|
|
|
|
begin
|
|
specs = SpecParser.parse(File.read "#{path}/#{child}").not_nil!
|
|
rescue
|
|
next
|
|
end
|
|
|
|
@services << Service.new self, specs
|
|
end
|
|
end
|
|
|
|
def load_environments
|
|
path = environments_directory
|
|
|
|
return unless Dir.exists? path
|
|
|
|
Dir.each_child path do |child|
|
|
unless child.match /\.spec$/
|
|
next
|
|
end
|
|
|
|
file_path = "#{path}/#{child}"
|
|
|
|
begin
|
|
name = File.basename(child, ".spec")
|
|
specs = SpecParser.parse File.read(file_path)
|
|
|
|
environment = Environment.new self, name, specs
|
|
rescue e
|
|
STDERR << "error loading #{file_path}: " << e << "\n"
|
|
# FIXME: Print stacktrace? Debug mode?
|
|
next
|
|
end
|
|
|
|
@environments << environment
|
|
end
|
|
end
|
|
|
|
def load_service_definitions
|
|
path = service_definitions_directory
|
|
|
|
Dir.each_child path do |child|
|
|
if child.match /\.spec$/
|
|
name = File.basename(child, ".spec")
|
|
specs = SpecParser.parse File.read "#{path}/#{child}"
|
|
|
|
@service_definitions << ServiceDefinition.new name, specs
|
|
else
|
|
next
|
|
end
|
|
end
|
|
end
|
|
|
|
def load
|
|
load_service_definitions
|
|
load_environments
|
|
load_services
|
|
end
|
|
|
|
def get_service_by_id(id : String) : Service?
|
|
matches = id.match /[^\/]*/
|
|
unless matches # Should not happen, above regex would always match.
|
|
raise Exception.new "FIXME"
|
|
end
|
|
environment_name, service_name = Service.parse_id id
|
|
|
|
@services.find do |service|
|
|
service.name == service_name && service.environment.name == environment_name
|
|
end
|
|
end
|
|
|
|
def get_environment_by_name(name : String) : Environment
|
|
_def = @environments.find &.name.==(name)
|
|
|
|
if _def.nil?
|
|
raise ::Service::Exception.new "Environment '#{name}' does not exist."
|
|
end
|
|
|
|
_def
|
|
end
|
|
|
|
def get_used_ports(other_reservations = Array(Int32).new)
|
|
services.map(&.ports.to_a)
|
|
.flatten
|
|
.map { |k, v| v }
|
|
.+(other_reservations)
|
|
end
|
|
|
|
def get_free_port(other_reservations = Array(Int32).new)
|
|
port = 49152
|
|
|
|
used_ports = get_used_ports other_reservations
|
|
|
|
while used_ports.any? &.==(port)
|
|
port = port + 1
|
|
end
|
|
|
|
port
|
|
end
|
|
|
|
def get_service_definition_by_name(name : String) : ServiceDefinition
|
|
_def = @service_definitions.find &.name.==(name)
|
|
|
|
if _def.nil?
|
|
raise Exception.new "Service '#{name}' does not exist."
|
|
end
|
|
|
|
_def
|
|
end
|
|
|
|
def is_port_used(port, other_reservations = Array(Int32).new)
|
|
used_ports = get_used_ports other_reservations
|
|
|
|
used_ports.any? &.==(port)
|
|
end
|
|
end
|
|
|