From 73abf06a65c2707cce9a4a3d5931c95c6fe3e205 Mon Sep 17 00:00:00 2001 From: Luka Vandervelden Date: Sun, 9 Jun 2019 14:52:29 +0200 Subject: [PATCH] Improved checks. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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. --- src/main.cr | 54 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/src/main.cr b/src/main.cr index df7ab99..4b4692f 100644 --- a/src/main.cr +++ b/src/main.cr @@ -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}"