lib/autoloads/genova/ecs/deployer/run_task/client.rb
module Genova
module Ecs
module Deployer
module RunTask
class Client
LOG_SEPARATOR = '-' * 96
def initialize(deploy_job, logger)
@deploy_job = deploy_job
@logger = logger
@ecs_client = Aws::ECS::Client.new
end
def execute(task_definition_arn, params = {})
@logger.info("Execute run task. (#{task_definition_arn})")
options = {}
options[:launch_type] = params[:launch_type]
options[:cluster] = @deploy_job.cluster
options[:task_definition] = task_definition_arn
options[:count] = params[:desired_count].present? ? params[:desired_count] : 1
options[:group] = params[:group]
options[:network_configuration] = params[:network_configuration]
options[:overrides] = {
container_overrides: params[:container_overrides],
task_role_arn: params[:task_role_arn],
execution_role_arn: params[:task_execution_role_arn]
}
results = @ecs_client.run_task(options)
if results[:failures].present?
message = ''
results[:failures].each do |failure|
message += "#{failure[:reason]} occurred and execution failed. [#{failure[:arn]}]"
end
raise Exceptions::RunTaskError, message
end
task_arns = results[:tasks].map { |key| key[:task_arn] }
wait(task_arns)
@deploy_job.update_status_complate(
task_definition_arn:,
task_arns:
)
@deploy_job.finished
end
private
def wait(task_arns)
@logger.info('Wait for the Run task execution to complete.')
@logger.info(task_arns.join(', '))
@logger.info(LOG_SEPARATOR)
wait_time = 0
stopped_tasks = []
loop do
describe_tasks = @ecs_client.describe_tasks(cluster: @deploy_job.cluster, tasks: task_arns)
run_task_size = describe_tasks[:tasks].size
describe_tasks[:tasks].each do |task|
raise Exceptions::DeployTimeoutError, "Monitoring run task, timeout reached. [#{task[:task_arn]}]" if wait_time > Settings.ecs.wait_timeout
sleep(Settings.ecs.polling_interval)
wait_time += Settings.ecs.polling_interval
@logger.info("Waiting for run task execution... (#{wait_time}s elapsed)")
@logger.info(LOG_SEPARATOR)
@logger.info("#{task[:task_arn]} [#{task[:last_status]}]")
next unless task[:last_status] == 'STOPPED' && !stopped_tasks.include?(task[:task_arn])
stopped_tasks << task[:task_arn]
@logger.info("Stopped reason: #{task[:stopped_reason]}")
task[:containers].each do |container|
next if container[:exit_code].zero?
raise Exceptions::RunTaskError, "Error detected in container exit status. [#{container[:name]}]"
end
end
break if run_task_size == stopped_tasks.size
end
@logger.info('All run tasks have been completed.')
end
end
end
end
end
end