service/src/service/context.cr

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