2019-06-09 16:59:05 +02:00
|
|
|
|
require "yaml"
|
2019-10-19 18:08:34 +02:00
|
|
|
|
require "specparser"
|
2019-06-09 16:59:05 +02:00
|
|
|
|
|
|
|
|
|
class ServiceDefinition
|
|
|
|
|
struct Consumes
|
2019-08-10 17:16:24 +02:00
|
|
|
|
getter token : String
|
2019-10-28 14:06:05 +01:00
|
|
|
|
getter optional : Bool
|
2019-08-10 17:16:24 +02:00
|
|
|
|
def initialize(@token)
|
2019-08-08 17:12:23 +02:00
|
|
|
|
@optional = false
|
|
|
|
|
|
|
|
|
|
if @token.match /\?$/
|
|
|
|
|
@token = @token.gsub /\?$/, ""
|
|
|
|
|
@optional = true
|
|
|
|
|
end
|
|
|
|
|
end
|
2019-06-09 16:59:05 +02:00
|
|
|
|
end
|
|
|
|
|
struct Provides
|
2019-08-10 17:16:24 +02:00
|
|
|
|
getter token : String
|
|
|
|
|
def initialize(@token)
|
2019-08-08 17:12:23 +02:00
|
|
|
|
end
|
2019-06-09 16:59:05 +02:00
|
|
|
|
end
|
2019-11-08 14:36:59 +01:00
|
|
|
|
struct FileDefinition
|
2019-08-10 17:16:24 +02:00
|
|
|
|
getter name : String
|
2019-11-08 14:36:59 +01:00
|
|
|
|
getter file_path : String
|
2019-08-10 17:16:24 +02:00
|
|
|
|
|
2019-11-08 14:36:59 +01:00
|
|
|
|
getter creation_command : String?
|
|
|
|
|
getter deletion_command : String?
|
|
|
|
|
getter export_command : String?
|
|
|
|
|
|
|
|
|
|
@configuration = false
|
|
|
|
|
|
|
|
|
|
def initialize(@file_path, @name = @file_path,
|
|
|
|
|
@creation_command = nil,
|
|
|
|
|
@deletion_command = nil,
|
|
|
|
|
@export_command = nil,
|
|
|
|
|
@configuration = false)
|
2019-08-10 17:16:24 +02:00
|
|
|
|
end
|
2019-10-19 18:08:34 +02:00
|
|
|
|
def initialize(section : SpecParser::Section)
|
2019-11-08 14:36:59 +01:00
|
|
|
|
@file_path = section.options[0]
|
|
|
|
|
@name = section.content["name"]?.try(&.as_s) || @file_path
|
2019-10-26 14:50:03 +02:00
|
|
|
|
|
2019-11-16 21:41:12 +01:00
|
|
|
|
@configuration = section.content["configuration"]?
|
|
|
|
|
.try(&.as_s)
|
|
|
|
|
.==("true")
|
|
|
|
|
|
2019-11-08 14:36:59 +01:00
|
|
|
|
@creation_command = section.content["creation-command"]?
|
|
|
|
|
.try &.as_s
|
|
|
|
|
@deletion_command = section.content["deletion-command"]?
|
2019-10-26 14:50:03 +02:00
|
|
|
|
.try &.as_s
|
2019-11-08 14:36:59 +01:00
|
|
|
|
@export_command = section.content["export-command"]?
|
|
|
|
|
.try &.as_s
|
|
|
|
|
|
|
|
|
|
#@unless_directory = section.content["unless-directory"]?
|
|
|
|
|
# .try &.as_s
|
|
|
|
|
#@unless_file = section.content["unless-file"]?.try &.as_s
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def is_configuration?
|
|
|
|
|
@configuration
|
2019-08-08 17:12:23 +02:00
|
|
|
|
end
|
2019-06-09 16:59:05 +02:00
|
|
|
|
end
|
|
|
|
|
|
2019-10-29 12:32:49 +01:00
|
|
|
|
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
|
|
|
|
|
|
2019-06-09 16:59:05 +02:00
|
|
|
|
class_getter all = [] of ServiceDefinition
|
|
|
|
|
|
2019-08-10 17:16:24 +02:00
|
|
|
|
getter name : String
|
|
|
|
|
getter command : String
|
|
|
|
|
getter stop_command : String?
|
2019-11-09 21:52:43 +01:00
|
|
|
|
getter reload_command : String?
|
2019-11-11 16:52:40 +01:00
|
|
|
|
getter readiness_check_command : String?
|
2019-08-10 17:16:24 +02:00
|
|
|
|
getter directory : String?
|
|
|
|
|
getter user : String?
|
2020-01-04 16:15:44 +01:00
|
|
|
|
getter group : String?
|
2020-01-04 16:26:05 +01:00
|
|
|
|
getter start_as_root : Bool?
|
2019-08-10 17:16:24 +02:00
|
|
|
|
getter provides : String?
|
|
|
|
|
getter consumes : Array(Consumes)
|
|
|
|
|
getter environment_variables : Array(String)
|
2019-11-08 14:36:59 +01:00
|
|
|
|
getter files : Array(FileDefinition)
|
2019-08-10 17:16:24 +02:00
|
|
|
|
getter provides : Array(Provides)
|
2019-10-29 12:32:49 +01:00
|
|
|
|
getter port_definitions : Array(PortDefinition)
|
2019-11-08 01:08:57 +01:00
|
|
|
|
getter non_runnable : Bool
|
2019-08-10 17:16:24 +02:00
|
|
|
|
|
2019-10-28 13:22:15 +01:00
|
|
|
|
getter requires_domain = false
|
|
|
|
|
|
2019-10-25 12:24:25 +02:00
|
|
|
|
def initialize(@name, specs : SpecParser)
|
2019-08-08 17:12:23 +02:00
|
|
|
|
sections = specs.sections
|
|
|
|
|
specs = specs.assignments
|
|
|
|
|
@command = specs["command"].as_s
|
2019-11-08 01:08:57 +01:00
|
|
|
|
@non_runnable = (@command == "none")
|
2019-08-08 17:12:23 +02:00
|
|
|
|
@stop_command = specs["stop-command"]?.try &.as_s
|
2019-11-09 21:52:43 +01:00
|
|
|
|
@reload_command = specs["reload-command"]?.try &.as_s
|
2019-11-11 16:52:40 +01:00
|
|
|
|
@readiness_check_command = specs["readiness-check-command"]?.try &.as_s
|
2019-08-08 17:12:23 +02:00
|
|
|
|
@directory = specs["directory"]?.try &.as_s
|
2019-08-10 17:16:24 +02:00
|
|
|
|
@user = specs["user"]?.try &.as_s
|
2020-01-04 16:15:44 +01:00
|
|
|
|
@group = specs["group"]?.try &.as_s
|
2020-01-04 16:26:05 +01:00
|
|
|
|
@start_as_root = specs["start-as-root"]?.try(&.as_s).try(&.==("true")) || false
|
2019-08-08 17:12:23 +02:00
|
|
|
|
@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
|
2019-10-26 14:50:03 +02:00
|
|
|
|
|
2019-10-29 12:32:49 +01:00
|
|
|
|
@port_definitions = specs["ports"]?.try &.as_a_or_s.map { |x| PortDefinition.new x } || Array(PortDefinition).new
|
|
|
|
|
|
2019-10-28 13:22:15 +01:00
|
|
|
|
# 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
|
|
|
|
|
|
2019-11-08 14:36:59 +01:00
|
|
|
|
@files = Array(FileDefinition).new
|
2019-10-26 15:24:22 +02:00
|
|
|
|
|
|
|
|
|
sections.each do |section|
|
|
|
|
|
case section.name
|
2019-11-08 14:36:59 +01:00
|
|
|
|
when "file", "directory"
|
|
|
|
|
@files << FileDefinition.new section
|
2019-10-26 15:24:22 +02:00
|
|
|
|
when "configuration"
|
|
|
|
|
options = section.options[0].split /[ \t]/
|
|
|
|
|
|
|
|
|
|
template = options[0]?
|
2019-11-08 14:36:59 +01:00
|
|
|
|
|
2019-10-26 15:24:22 +02:00
|
|
|
|
name = section.content["name"]?.try &.as_s
|
|
|
|
|
|
2019-11-08 14:36:59 +01:00
|
|
|
|
if template.nil?
|
|
|
|
|
STDERR.puts "warning: (#{@name}) %configuration wasn’t provided a target."
|
2019-10-26 15:24:22 +02:00
|
|
|
|
next
|
|
|
|
|
end
|
|
|
|
|
|
2019-11-08 14:36:59 +01:00
|
|
|
|
target = options[1]?
|
|
|
|
|
unless target
|
|
|
|
|
target = template
|
|
|
|
|
template = File.basename target
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
files << FileDefinition.new target, (name || target),
|
|
|
|
|
creation_command: "gen-config \"#{template}\" \"#{target}\"",
|
|
|
|
|
deletion_command: "rm \"#{target}\"",
|
|
|
|
|
configuration: true
|
|
|
|
|
when "database"
|
|
|
|
|
options = section.options[0].split /[ \t]/
|
|
|
|
|
type = options[0]? || section.content["type"]?.try &.as_s
|
|
|
|
|
|
|
|
|
|
# FIXME: %database is not currently implemented.
|
2019-10-26 15:24:22 +02:00
|
|
|
|
end
|
|
|
|
|
end
|
2019-08-08 17:12:23 +02:00
|
|
|
|
end
|
|
|
|
|
|
2019-06-09 16:59:05 +02:00
|
|
|
|
def to_s
|
|
|
|
|
name
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|