class Barbeque::Executor::Docker
Public Class Methods
new(_options)
click to toggle source
# File lib/barbeque/executor/docker.rb, line 12 def initialize(_options) end
Public Instance Methods
poll_execution(job_execution)
click to toggle source
@param [Barbeque::JobExecution] job_execution
# File lib/barbeque/executor/docker.rb, line 57 def poll_execution(job_execution) container = Barbeque::DockerContainer.find_by!(message_id: job_execution.message_id) info = inspect_container(container.container_id) if info['State'] && info['State']['Status'] != 'running' finished_at = Time.zone.parse(info['State']['FinishedAt']) exit_code = info['State']['ExitCode'] job_execution.update!(status: exit_code == 0 ? :success : :failed, finished_at: finished_at) stdout, stderr = get_logs(container.container_id) Barbeque::ExecutionLog.save_stdout_and_stderr(job_execution, stdout, stderr) Barbeque::SlackNotifier.notify_job_execution(job_execution) if exit_code != 0 job_execution.retry_if_possible! end end end
poll_retry(job_retry)
click to toggle source
@param [Barbeque::JobRetry] job_retry
# File lib/barbeque/executor/docker.rb, line 75 def poll_retry(job_retry) container = Barbeque::DockerContainer.find_by!(message_id: job_retry.message_id) job_execution = job_retry.job_execution info = inspect_container(container.container_id) if info['State'] && info['State']['Status'] != 'running' finished_at = Time.zone.parse(info['State']['FinishedAt']) exit_code = info['State']['ExitCode'] status = exit_code == 0 ? :success : :failed Barbeque::ApplicationRecord.transaction do job_retry.update!(status: status, finished_at: finished_at) job_execution.update!(status: status) end stdout, stderr = get_logs(container.container_id) Barbeque::ExecutionLog.save_stdout_and_stderr(job_retry, stdout, stderr) Barbeque::SlackNotifier.notify_job_retry(job_retry) if status == :failed job_execution.retry_if_possible! end end end
start_execution(job_execution, envs)
click to toggle source
@param [Barbeque::JobExecution] job_execution @param [Hash] envs
# File lib/barbeque/executor/docker.rb, line 17 def start_execution(job_execution, envs) docker_image = DockerImage.new(job_execution.job_definition.app.docker_image) cmd = build_docker_run_command(docker_image, job_execution.job_definition.command, envs) stdout, stderr, status = Open3.capture3(*cmd) if status.success? Barbeque::DockerContainer.create!(message_id: job_execution.message_id, container_id: stdout.chomp) job_execution.update!(status: :running) else Barbeque::ExecutionLog.try_save_stdout_and_stderr(job_execution, stdout, stderr) job_execution.update!(status: :failed, finished_at: Time.zone.now) Barbeque::SlackNotifier.notify_job_execution(job_execution) job_execution.retry_if_possible! end end
start_retry(job_retry, envs)
click to toggle source
@param [Barbeque::JobRetry] job_retry @param [Hash] envs
# File lib/barbeque/executor/docker.rb, line 34 def start_retry(job_retry, envs) job_execution = job_retry.job_execution docker_image = DockerImage.new(job_execution.job_definition.app.docker_image) cmd = build_docker_run_command(docker_image, job_execution.job_definition.command, envs) stdout, stderr, status = Open3.capture3(*cmd) if status.success? Barbeque::DockerContainer.create!(message_id: job_retry.message_id, container_id: stdout.chomp) Barbeque::ApplicationRecord.transaction do job_execution.update!(status: :retried) job_retry.update!(status: :running) end else Barbeque::ExecutionLog.try_save_stdout_and_stderr(job_retry, stdout, stderr) Barbeque::ApplicationRecord.transaction do job_retry.update!(status: :failed, finished_at: Time.zone.now) job_execution.update!(status: :failed) end Barbeque::SlackNotifier.notify_job_retry(job_retry) job_execution.retry_if_possible! end end
Private Instance Methods
build_docker_run_command(docker_image, command, envs)
click to toggle source
@param [Barbeque::DockerImage] docker_image @param [Array<String>] command @param [Hash] envs
# File lib/barbeque/executor/docker.rb, line 102 def build_docker_run_command(docker_image, command, envs) ['docker', 'run', '--detach', *env_options(envs), docker_image.to_s, *command] end
env_options(envs)
click to toggle source
# File lib/barbeque/executor/docker.rb, line 106 def env_options(envs) envs.flat_map do |key, value| ['--env', "#{key}=#{value}"] end end
get_logs(container_id)
click to toggle source
@param [String] container_id @return [String] stdout @return [String] stderr
# File lib/barbeque/executor/docker.rb, line 130 def get_logs(container_id) stdout, stderr, status = Open3.capture3('docker', 'logs', container_id) if status.success? [stdout, stderr] else raise DockerCommandError.new("Unable to get Docker container logs #{container.container_id}: STDOUT: #{stdout}; STDERR: #{stderr}") end end
inspect_container(container_id)
click to toggle source
@param [String] container_id @return [Hash] container info
# File lib/barbeque/executor/docker.rb, line 114 def inspect_container(container_id) stdout, stderr, status = Open3.capture3('docker', 'inspect', container_id) if status.success? begin JSON.parse(stdout)[0] rescue JSON::ParserError => e raise DockerCommandError.new("Unable to parse JSON: #{e.class}: #{e.message}: #{stdout}") end else raise DockerCommandError.new("Unable to inspect Docker container #{container.container_id}: STDOUT: #{stdout}; STDERR: #{stderr}") end end