Improved checks.

- Environments can have checks, that are run before the service’s
    checks.
  - Directories can now be checked as well as files.
  - Failing checks now stop the start process with a Service::Exception.
  - Some variable substitution is done in check commands and tests.
  - Some environment variables related to the environment to run the
    service in are also exported.
master
Luka Vandervelden 2019-06-09 14:52:29 +02:00
parent b17a258bc8
commit 73abf06a65
1 changed files with 48 additions and 6 deletions

View File

@ -39,7 +39,8 @@ class ServiceDefinition
struct Checks
YAML.mapping({
name: String,
file: String, # FIXME: -> String? and add directory:?
file: String?,
directory: String?,
command: String
})
end
@ -115,12 +116,25 @@ class Environment
domain_name: {
type: String?,
key: "domain-name"
},
checks: {
# FIXME: Would probably need a more neutral namespace.
type: Array(ServiceDefinition::Checks),
default: Array(ServiceDefinition::Checks).new
}
})
def initialize()
@name = "root"
@type = Type::Prefix
@checks = Array(ServiceDefinition::Checks).new
# FIXME: Should this *really* be here?
@checks << ServiceDefinition::Checks.from_yaml <<-EOF
name: Creating data directory
directory: /srv/%{ENVIRONMENT}
command: mkdir -p /srv/%{ENVIRONMENT} && chmod a+rwt /srv/%{ENVIRONMENT}
EOF
end
class_getter root = Environment.new
@ -242,13 +256,34 @@ class Service
@reference.provides
end
def export_environment_variables
ENV["SERVICE_ENVIRONMENT"] = @environment.name
ENV["SERVICE_ENVIRONMENT_TYPE"] = @environment.type.to_s
end
private def evaluate(string)
string.sub /%{[a-zA-Z]+}/ do |match|
match = match[2..match.size-2]
if match.downcase == "environment"
@environment.name
else
""
end
end
end
def start(pid_dir : String, log_dir : String)
@reference.checks.each do |check|
export_environment_variables
(@environment.checks + @reference.checks).each do |check|
run_check = false
# Other tests will likely come later.
if check.file && ! File.exists? check.file
run_check = true
check.file.try do |file|
run_check = true if ! File.exists? evaluate file
end
check.directory.try do |directory|
run_check = true if ! Dir.exists? evaluate directory
end
unless run_check
@ -258,10 +293,17 @@ class Service
puts " - #{check.name}"
# FIXME: Output? Only in debug mode?
Process.run "sh", ["-c", check.command], output: Process::Redirect::Inherit, error: Process::Redirect::Inherit
child = Process.run "sh", ["-c", evaluate check.command], output: Process::Redirect::Inherit, error: Process::Redirect::Inherit
if child.exit_status != 0
raise Service::Exception.new "Child process exited with status “#{child.exit_status}”."
break
end
end
# FIXME: Should evaluate be used in split_command? What namespace should split_command use?
command, args = split_command command
args.map! do |arg| evaluate arg end
process = Process.fork do
base_log_name = "#{log_dir}/#{name}.#{@environment.name}"