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, cpu: nil, memory: 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, cpu: nil, memory: 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. cpu/memory override the task-level size for this launch only (must be a valid Fargate combination).
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 82 83 84 85 86 87 |
# File 'lib/putpaws/ecs/run_command.rb', line 55 def run_ecs_task(command:, started_by:, group:, container: nil, cpu: nil, memory: nil) overrides = { container_overrides: [ { name: container || container_name, command: ['/bin/sh', '-c', command], } ] } overrides[:cpu] = cpu.to_s unless cpu.to_s.strip.empty? overrides[:memory] = memory.to_s unless memory.to_s.strip.empty? 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: overrides, }) 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
117 118 119 |
# File 'lib/putpaws/ecs/run_command.rb', line 117 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
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/putpaws/ecs/run_command.rb', line 89 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
105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/putpaws/ecs/run_command.rb', line 105 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 |