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
parent
b17a258bc8
commit
73abf06a65
54
src/main.cr
54
src/main.cr
|
@ -39,7 +39,8 @@ class ServiceDefinition
|
||||||
struct Checks
|
struct Checks
|
||||||
YAML.mapping({
|
YAML.mapping({
|
||||||
name: String,
|
name: String,
|
||||||
file: String, # FIXME: -> String? and add directory:?
|
file: String?,
|
||||||
|
directory: String?,
|
||||||
command: String
|
command: String
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
@ -115,12 +116,25 @@ class Environment
|
||||||
domain_name: {
|
domain_name: {
|
||||||
type: String?,
|
type: String?,
|
||||||
key: "domain-name"
|
key: "domain-name"
|
||||||
|
},
|
||||||
|
checks: {
|
||||||
|
# FIXME: Would probably need a more neutral namespace.
|
||||||
|
type: Array(ServiceDefinition::Checks),
|
||||||
|
default: Array(ServiceDefinition::Checks).new
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
def initialize()
|
def initialize()
|
||||||
@name = "root"
|
@name = "root"
|
||||||
@type = Type::Prefix
|
@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
|
end
|
||||||
|
|
||||||
class_getter root = Environment.new
|
class_getter root = Environment.new
|
||||||
|
@ -242,13 +256,34 @@ class Service
|
||||||
@reference.provides
|
@reference.provides
|
||||||
end
|
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)
|
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
|
run_check = false
|
||||||
|
|
||||||
# Other tests will likely come later.
|
check.file.try do |file|
|
||||||
if check.file && ! File.exists? check.file
|
run_check = true if ! File.exists? evaluate file
|
||||||
run_check = true
|
end
|
||||||
|
|
||||||
|
check.directory.try do |directory|
|
||||||
|
run_check = true if ! Dir.exists? evaluate directory
|
||||||
end
|
end
|
||||||
|
|
||||||
unless run_check
|
unless run_check
|
||||||
|
@ -258,10 +293,17 @@ class Service
|
||||||
puts " - #{check.name}"
|
puts " - #{check.name}"
|
||||||
|
|
||||||
# FIXME: Output? Only in debug mode?
|
# 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
|
end
|
||||||
|
|
||||||
|
# FIXME: Should evaluate be used in split_command? What namespace should split_command use?
|
||||||
command, args = split_command command
|
command, args = split_command command
|
||||||
|
args.map! do |arg| evaluate arg end
|
||||||
|
|
||||||
process = Process.fork do
|
process = Process.fork do
|
||||||
base_log_name = "#{log_dir}/#{name}.#{@environment.name}"
|
base_log_name = "#{log_dir}/#{name}.#{@environment.name}"
|
||||||
|
|
Loading…
Reference in New Issue