service/src/service/service_definition.cr

168 lines
4.4 KiB
Crystal
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 FileDefinition
getter name : String
getter file_path : String
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)
end
def initialize(section : SpecParser::Section)
@file_path = section.options[0]
@name = section.content["name"]?.try(&.as_s) || @file_path
@configuration = section.content["configuration"]?
.try(&.as_s)
.==("true")
@creation_command = section.content["creation-command"]?
.try &.as_s
@deletion_command = section.content["deletion-command"]?
.try &.as_s
@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
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 reload_command : String?
getter readiness_check_command : String?
getter directory : String?
getter user : String?
getter group : String?
getter start_as_root : Bool?
getter provides : String?
getter consumes : Array(Consumes)
getter environment_variables : Array(String)
getter files : Array(FileDefinition)
getter provides : Array(Provides)
getter port_definitions : Array(PortDefinition)
getter non_runnable : Bool
getter requires_domain = false
def initialize(@name, specs : SpecParser)
sections = specs.sections
specs = specs.assignments
@command = specs["command"].as_s
@non_runnable = (@command == "none")
@stop_command = specs["stop-command"]?.try &.as_s
@reload_command = specs["reload-command"]?.try &.as_s
@readiness_check_command = specs["readiness-check-command"]?.try &.as_s
@directory = specs["directory"]?.try &.as_s
@user = specs["user"]?.try &.as_s
@group = specs["group"]?.try &.as_s
@start_as_root = specs["start-as-root"]?.try(&.as_s).try(&.==("true")) || false
@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
@files = Array(FileDefinition).new
sections.each do |section|
case section.name
when "file", "directory"
@files << FileDefinition.new section
when "configuration"
options = section.options[0].split /[ \t]/
template = options[0]?
name = section.content["name"]?.try &.as_s
if template.nil?
STDERR.puts "warning: (#{@name}) %configuration wasnt provided a target."
next
end
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.
end
end
end
def to_s
name
end
end