Class: Putpaws::Ecs::RunCommand
- Inherits:
-
Object
- Object
- Putpaws::Ecs::RunCommand
- Defined in:
- lib/putpaws/ecs/run_command.rb
Constant Summary collapse
- DEFAULT_TTL =
'30m'- SECONDS =
{ 's' => 1, 'm' => 60, 'h' => 60 * 60, }
Instance Attribute Summary collapse
-
#ecs_client ⇒ Object
readonly
Returns the value of attribute ecs_client.
-
#network ⇒ Object
readonly
Returns the value of attribute network.
-
#region ⇒ Object
readonly
Returns the value of attribute region.
-
#target ⇒ Object
readonly
Returns the value of attribute target.
Class Method Summary collapse
- .config(config) ⇒ Object
-
.parse_ttl(ut) ⇒ Object
"45" and "45m" mean 45 minutes.
Instance Method Summary collapse
- #cluster_name ⇒ Object
- #container_name ⇒ Object
-
#initialize(region:, network:, target:) ⇒ RunCommand
constructor
A new instance of RunCommand.
-
#run_ecs_task(command:, started_by:, group:, container: nil) ⇒ Object
Launch a temporary task whose main process is overridden with the given command, so that the task terminates itself when the command finishes.
- #stop_ecs_task(task_arn, reason: 'Stopped by putpaws') ⇒ Object
- #wait_until_attachable(task_arn, timeout: 600, interval: 5) ⇒ Object
- #wait_until_stopped(task_arn, timeout: 3600, interval: 10) ⇒ Object
Constructor Details
#initialize(region:, network:, target:) ⇒ RunCommand
Returns a new instance of RunCommand.
35 36 37 38 39 40 |
# File 'lib/putpaws/ecs/run_command.rb', line 35 def initialize(region:, network:, target:) @ecs_client = Aws::ECS::Client.new({region: region}) @region = region @network = network @target = target end |
Instance Attribute Details
#ecs_client ⇒ Object (readonly)
Returns the value of attribute ecs_client.
33 34 35 |
# File 'lib/putpaws/ecs/run_command.rb', line 33 def ecs_client @ecs_client end |
#network ⇒ Object (readonly)
Returns the value of attribute network.
34 35 36 |
# File 'lib/putpaws/ecs/run_command.rb', line 34 def network @network end |
#region ⇒ Object (readonly)
Returns the value of attribute region.
34 35 36 |
# File 'lib/putpaws/ecs/run_command.rb', line 34 def region @region end |
#target ⇒ Object (readonly)
Returns the value of attribute target.
34 35 36 |
# File 'lib/putpaws/ecs/run_command.rb', line 34 def target @target end |
Class Method Details
.config(config) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/putpaws/ecs/run_command.rb', line 12 def self.config(config) unless config.network && config.target raise "Please set `network` and `target` at .putpaws/application.json\n" + "They refer to `network` and `target` sections at .putpaws/infra.json\n" + "(Ex) \"network\": \"awesome-private-staging\", \"target\": \"awesome-staging\"" end new( region: config.ecs_region || config.region, network: config.network, target: config.target, ) end |
.parse_ttl(ut) ⇒ Object
"45" and "45m" mean 45 minutes. "90s" and "2h" are also acceptable.
26 27 28 29 30 31 |
# File 'lib/putpaws/ecs/run_command.rb', line 26 def self.parse_ttl(ut) ut = DEFAULT_TTL if ut.nil? || ut.strip.empty? matched, number, unit = ut.strip.match(/\A(\d+)([smh])?\z/).to_a raise "Invalid ttl: #{ut} (Ex) ttl=30m ttl=2h ttl=90s" unless matched number.to_i * SECONDS[unit || 'm'] end |
Instance Method Details
#cluster_name ⇒ Object
42 43 44 |
# File 'lib/putpaws/ecs/run_command.rb', line 42 def cluster_name target.cluster.split('/').last end |
#container_name ⇒ Object
46 47 48 |
# File 'lib/putpaws/ecs/run_command.rb', line 46 def container_name target.container_name || 'app' end |
#run_ecs_task(command:, started_by:, group:, container: nil) ⇒ Object
Launch a temporary task whose main process is overridden with the given command, so that the task terminates itself when the command finishes. started_by and group are set so that temporary tasks are identifiable.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/putpaws/ecs/run_command.rb', line 53 def run_ecs_task(command:, started_by:, group:, container: nil) res = ecs_client.run_task({ cluster: target.cluster, task_definition: target.task_definition, count: 1, launch_type: 'FARGATE', enable_execute_command: true, started_by: started_by, group: group, network_configuration: { awsvpc_configuration: { subnets: network.subnets, security_groups: network.security_groups, assign_public_ip: network.assign_public_ip, } }, overrides: { container_overrides: [ { name: container || container_name, command: ['/bin/sh', '-c', command], } ] }, }) failure = res.failures.first raise "Failed to run task: #{failure.reason} #{failure.detail}" if failure res.tasks.first end |
#stop_ecs_task(task_arn, reason: 'Stopped by putpaws') ⇒ Object
111 112 113 |
# File 'lib/putpaws/ecs/run_command.rb', line 111 def stop_ecs_task(task_arn, reason: 'Stopped by putpaws') ecs_client.stop_task(cluster: target.cluster, task: task_arn, reason: reason) end |
#wait_until_attachable(task_arn, timeout: 600, interval: 5) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/putpaws/ecs/run_command.rb', line 83 def wait_until_attachable(task_arn, timeout: 600, interval: 5) deadline = Time.now + timeout loop do res = ecs_client.describe_tasks(cluster: target.cluster, tasks: [task_arn]) task = res.tasks.first if task.nil? || task.last_status == 'STOPPED' raise "Task was stopped: #{task && task.stopped_reason}" end ctn = task.containers.detect{|c| c.name == container_name} agent = ctn && (ctn.managed_agents || []).detect{|a| a.name == 'ExecuteCommandAgent'} return task if task.last_status == 'RUNNING' && agent && agent.last_status == 'RUNNING' raise "Timed out waiting for task to be attachable: #{task_arn}" if Time.now > deadline sleep interval end end |
#wait_until_stopped(task_arn, timeout: 3600, interval: 10) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/putpaws/ecs/run_command.rb', line 99 def wait_until_stopped(task_arn, timeout: 3600, interval: 10) deadline = Time.now + timeout loop do res = ecs_client.describe_tasks(cluster: target.cluster, tasks: [task_arn]) task = res.tasks.first raise "Task not found: #{task_arn}" unless task return task if task.last_status == 'STOPPED' raise "Timed out waiting for task to stop: #{task_arn}" if Time.now > deadline sleep interval end end |