158 lines
3.9 KiB
Crystal
158 lines
3.9 KiB
Crystal
require "yaml"
|
|
require "specparser"
|
|
|
|
class ServiceDefinition
|
|
struct Consumes
|
|
getter token : String
|
|
getter optional : Bool
|
|
def initialize(@token)
|
|
@optional = false
|
|
|
|
if @token.match /\?$/
|
|
@token = @token.gsub /\?$/, ""
|
|
@optional = true
|
|
end
|
|
end
|
|
end
|
|
struct Provides
|
|
getter token : String
|
|
def initialize(@token)
|
|
end
|
|
end
|
|
struct Hook
|
|
getter name : String
|
|
getter command : String
|
|
getter unless_directory : String?
|
|
getter unless_file : String?
|
|
|
|
def initialize(@name, @command, @unless_file = nil, @unless_directory = nil)
|
|
end
|
|
def initialize(section : SpecParser::Section)
|
|
@name = section.content["name"].as_s
|
|
@command = section.content["command"].as_s
|
|
|
|
@unless_directory = section.content["unless-directory"]?
|
|
.try &.as_s
|
|
@unless_file = section.content["unless-file"]?.try &.as_s
|
|
end
|
|
end
|
|
|
|
struct PortDefinition
|
|
getter name : String
|
|
getter default_value : Int32?
|
|
|
|
def initialize(string : String)
|
|
match = string.match(/([^?=]*)(=([^?]*))?/).not_nil!
|
|
|
|
@name = match[1]
|
|
@default_value = match[3]?.try &.to_i
|
|
end
|
|
end
|
|
|
|
class_getter all = [] of ServiceDefinition
|
|
|
|
getter name : String
|
|
getter command : String
|
|
getter stop_command : String?
|
|
getter directory : String?
|
|
getter user : String?
|
|
getter provides : String?
|
|
getter consumes : Array(Consumes)
|
|
getter environment_variables : Array(String)
|
|
getter pre_start_hooks : Array(Hook)
|
|
getter provides : Array(Provides)
|
|
getter port_definitions : Array(PortDefinition)
|
|
|
|
getter requires_domain = false
|
|
|
|
def initialize(@name, specs : SpecParser)
|
|
sections = specs.sections
|
|
specs = specs.assignments
|
|
@command = specs["command"].as_s
|
|
@stop_command = specs["stop-command"]?.try &.as_s
|
|
@directory = specs["directory"]?.try &.as_s
|
|
@user = specs["user"]?.try &.as_s
|
|
@provides = specs["provides"]?.try &.as_a_or_s.map { |x| Provides.new x } || Array(Provides).new
|
|
@consumes = specs["consumes"]?.try &.as_a_or_s.map { |x| Consumes.new x } || Array(Consumes).new
|
|
@environment_variables = specs["environment-variables"]?.try &.as_a_or_s || Array(String).new
|
|
|
|
@port_definitions = specs["ports"]?.try &.as_a_or_s.map { |x| PortDefinition.new x } || Array(PortDefinition).new
|
|
|
|
# FIXME: as_b?
|
|
requires_domain = specs["requires-domain"]?.try &.as_s
|
|
case requires_domain
|
|
when nil
|
|
when "true", "yes"
|
|
@requires_domain = true
|
|
when "false", "no"
|
|
@requires_domain = false
|
|
else
|
|
STDERR.puts "warning: definition '#{@name}' has a 'requires-domain' entry with an invalid value"
|
|
end
|
|
|
|
@pre_start_hooks = Array(Hook).new
|
|
|
|
sections.each do |section|
|
|
case section.name
|
|
when "pre-start"
|
|
@pre_start_hooks << Hook.new section
|
|
when "directory"
|
|
directory = section.options[0]?
|
|
name = section.content["name"]?.try &.as_s
|
|
|
|
if directory.nil?
|
|
STDERR.puts "warning: (#{@name}) %directory was not provided a path"
|
|
next
|
|
end
|
|
|
|
pre_start_hooks << Hook.new (name || "directory: #{directory}"),
|
|
"mkdir -p \"#{directory}\"",
|
|
unless_directory: directory
|
|
when "configuration"
|
|
options = section.options[0].split /[ \t]/
|
|
|
|
template = options[0]?
|
|
target = options[1]?
|
|
name = section.content["name"]?.try &.as_s
|
|
|
|
if template.nil? || target.nil?
|
|
STDERR.puts "warning: (#{@name}) %configuration received less than 2 options"
|
|
next
|
|
end
|
|
|
|
pre_start_hooks << Hook.new (name || "configuration file: #{template}"),
|
|
"gen-config \"#{template}\" \"#{target}\"",
|
|
unless_file: target
|
|
end
|
|
end
|
|
end
|
|
|
|
def self.load(path)
|
|
Dir.each_child path do |child|
|
|
if child.match /\.spec$/
|
|
name = File.basename(child, ".spec")
|
|
specs = SpecParser.parse File.read "#{path}/#{child}"
|
|
|
|
@@all << ServiceDefinition.new name, specs
|
|
else
|
|
next
|
|
end
|
|
end
|
|
end
|
|
|
|
def self.get(name) : ServiceDefinition
|
|
_def = @@all.find &.name.==(name)
|
|
|
|
if _def.nil?
|
|
raise ::Service::Exception.new "Service '#{name}' does not exist."
|
|
end
|
|
|
|
_def
|
|
end
|
|
|
|
def to_s
|
|
name
|
|
end
|
|
end
|
|
|