ufo 4.1.7 → 4.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +18 -18
- data/docs/_docs/fargate.md +2 -2
- data/docs/_reference/ufo-task.md +3 -0
- data/docs/quick-start.md +24 -10
- data/lib/ufo/cli.rb +2 -0
- data/lib/ufo/task.rb +38 -3
- data/lib/ufo/version.rb +1 -1
- data/spec/lib/task_spec.rb +25 -6
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fbed0337ef427b9207e2519ea203529f4f2db33c8b3b8a2566e53ad88da9456b
|
|
4
|
+
data.tar.gz: c4f46be9a77ab2946db88193429b0c9317fd5b9c61b909c2861514312dbc894f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9e6cd3faba4289427dfbbdd1fc65785ad563bab135a9e3816b4094ba93a4c97392e3591bd0aeeed909759ceef1fc27cfced0bacf6be33896da90ceb052418f91
|
|
7
|
+
data.tar.gz: 0452d37d8a1e785ca5f9bf0d91995d16e575d61ca0d7563f6d17ea556ae35bb03f155fde9917efb1a83c73cce1dca852702a85191f952822935c4cae644dafa1
|
data/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
This project *tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
|
|
5
5
|
|
|
6
|
+
## [4.1.8]
|
|
7
|
+
- Merge pull request #59 from everplays/58-ability-to-wait-for-one-off-task-to-finish
|
|
8
|
+
- Merge pull request #60 from tongueroo/wait-exit-code
|
|
9
|
+
|
|
6
10
|
## [4.1.7]
|
|
7
11
|
- add scheduling-strategy option #55 from tongueroo/scheduling-strategy
|
|
8
12
|
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
ufo (4.1.
|
|
4
|
+
ufo (4.1.8)
|
|
5
5
|
aws-sdk-cloudformation
|
|
6
6
|
aws-sdk-cloudwatchlogs
|
|
7
7
|
aws-sdk-ec2
|
|
@@ -19,35 +19,35 @@ PATH
|
|
|
19
19
|
GEM
|
|
20
20
|
remote: https://rubygems.org/
|
|
21
21
|
specs:
|
|
22
|
-
activesupport (5.2.1)
|
|
22
|
+
activesupport (5.2.1.1)
|
|
23
23
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
24
24
|
i18n (>= 0.7, < 2)
|
|
25
25
|
minitest (~> 5.1)
|
|
26
26
|
tzinfo (~> 1.1)
|
|
27
27
|
aws-eventstream (1.0.1)
|
|
28
|
-
aws-partitions (1.
|
|
29
|
-
aws-sdk-cloudformation (1.
|
|
30
|
-
aws-sdk-core (~> 3, >= 3.
|
|
28
|
+
aws-partitions (1.121.0)
|
|
29
|
+
aws-sdk-cloudformation (1.13.0)
|
|
30
|
+
aws-sdk-core (~> 3, >= 3.39.0)
|
|
31
31
|
aws-sigv4 (~> 1.0)
|
|
32
|
-
aws-sdk-cloudwatchlogs (1.
|
|
33
|
-
aws-sdk-core (~> 3, >= 3.
|
|
32
|
+
aws-sdk-cloudwatchlogs (1.12.0)
|
|
33
|
+
aws-sdk-core (~> 3, >= 3.39.0)
|
|
34
34
|
aws-sigv4 (~> 1.0)
|
|
35
|
-
aws-sdk-core (3.
|
|
35
|
+
aws-sdk-core (3.42.0)
|
|
36
36
|
aws-eventstream (~> 1.0)
|
|
37
37
|
aws-partitions (~> 1.0)
|
|
38
38
|
aws-sigv4 (~> 1.0)
|
|
39
39
|
jmespath (~> 1.0)
|
|
40
|
-
aws-sdk-ec2 (1.
|
|
41
|
-
aws-sdk-core (~> 3, >= 3.
|
|
40
|
+
aws-sdk-ec2 (1.62.0)
|
|
41
|
+
aws-sdk-core (~> 3, >= 3.39.0)
|
|
42
42
|
aws-sigv4 (~> 1.0)
|
|
43
|
-
aws-sdk-ecr (1.
|
|
44
|
-
aws-sdk-core (~> 3, >= 3.
|
|
43
|
+
aws-sdk-ecr (1.9.0)
|
|
44
|
+
aws-sdk-core (~> 3, >= 3.39.0)
|
|
45
45
|
aws-sigv4 (~> 1.0)
|
|
46
|
-
aws-sdk-ecs (1.
|
|
47
|
-
aws-sdk-core (~> 3, >= 3.
|
|
46
|
+
aws-sdk-ecs (1.26.0)
|
|
47
|
+
aws-sdk-core (~> 3, >= 3.39.0)
|
|
48
48
|
aws-sigv4 (~> 1.0)
|
|
49
|
-
aws-sdk-elasticloadbalancingv2 (1.
|
|
50
|
-
aws-sdk-core (~> 3, >= 3.
|
|
49
|
+
aws-sdk-elasticloadbalancingv2 (1.18.0)
|
|
50
|
+
aws-sdk-core (~> 3, >= 3.39.0)
|
|
51
51
|
aws-sigv4 (~> 1.0)
|
|
52
52
|
aws-sigv4 (1.0.3)
|
|
53
53
|
byebug (10.0.2)
|
|
@@ -92,7 +92,7 @@ GEM
|
|
|
92
92
|
text-table (1.2.4)
|
|
93
93
|
thor (0.20.3)
|
|
94
94
|
thread_safe (0.3.6)
|
|
95
|
-
tilt (2.0.
|
|
95
|
+
tilt (2.0.9)
|
|
96
96
|
tzinfo (1.2.5)
|
|
97
97
|
thread_safe (~> 0.1)
|
|
98
98
|
|
|
@@ -109,4 +109,4 @@ DEPENDENCIES
|
|
|
109
109
|
ufo!
|
|
110
110
|
|
|
111
111
|
BUNDLED WITH
|
|
112
|
-
1.
|
|
112
|
+
1.17.1
|
data/docs/_docs/fargate.md
CHANGED
|
@@ -18,11 +18,11 @@ Here's an example of creating web service with Fargate.
|
|
|
18
18
|
|
|
19
19
|
git clone https://github.com/tongueroo/demo-ufo demo
|
|
20
20
|
cd demo
|
|
21
|
-
ufo init --image tongueroo/demo-ufo --launch-type fargate --execution-role-arn arn:aws:iam::
|
|
21
|
+
ufo init --image tongueroo/demo-ufo --launch-type fargate --execution-role-arn arn:aws:iam::112233445566:role/ecsTaskExecutionRole
|
|
22
22
|
ufo current --service demo-web
|
|
23
23
|
ufo ship
|
|
24
24
|
|
|
25
|
-
Replace the `--execution-role-arn` with the ecsTaskExecutionRole associated with your account. If you do not have an ecsTaskExecutionRole yet, create one by following [Amazon ECS Task Execution IAM Role](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_execution_IAM_role.html) guide.
|
|
25
|
+
**IMPORTANT**: Replace the `--execution-role-arn` with the ecsTaskExecutionRole associated with your account. If you do not have an ecsTaskExecutionRole yet, create one by following [Amazon ECS Task Execution IAM Role](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_execution_IAM_role.html) guide.
|
|
26
26
|
|
|
27
27
|
You should see output similiar to this. Some output has been removed for conciseness.
|
|
28
28
|
|
data/docs/_reference/ufo-task.md
CHANGED
|
@@ -34,6 +34,9 @@ The `--task-only` option is useful. By default, the `ufo task` command will buil
|
|
|
34
34
|
|
|
35
35
|
```
|
|
36
36
|
[--task-only], [--no-task-only] # Skip docker and task register steps. Only run the task.
|
|
37
|
+
w, [--wait], [--no-wait] # Wait for task to finish.
|
|
38
|
+
t, [--timeout=N] # How long to wait for task to finish.
|
|
39
|
+
# Default: 600
|
|
37
40
|
c, [--command=one two three] # Override the command used for the container
|
|
38
41
|
[--verbose], [--no-verbose]
|
|
39
42
|
[--mute], [--no-mute]
|
data/docs/quick-start.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
title: Quick Start
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
In a hurry? No sweat! Here's a quick start to using ufo that takes only a few minutes. For this example, we will use a
|
|
5
|
+
In a hurry? No sweat! Here's a quick start to using ufo that takes only a few minutes. For this example, we will use a Sinatra app from [tongueroo/demo-ufo](https://github.com/tongueroo/demo-ufo). The `ufo init` command sets up the ufo directory structure in your project. The `ufo ship` command deploys your code to an AWS ECS service. The `ufo ps` and `ufo scale` command shows you how to verify and scale additional containers.
|
|
6
6
|
|
|
7
7
|
gem install ufo
|
|
8
8
|
git clone https://github.com/tongueroo/demo-ufo.git demo
|
|
@@ -13,15 +13,7 @@ In a hurry? No sweat! Here's a quick start to using ufo that takes only a few mi
|
|
|
13
13
|
ufo ps
|
|
14
14
|
ufo scale 2
|
|
15
15
|
|
|
16
|
-
Note:
|
|
17
|
-
|
|
18
|
-
ufo init --image=yourusername/yourrepo # use your own account
|
|
19
|
-
|
|
20
|
-
Also, if you are using ECR instead, you can specific an ECR repo with the `--image` option. Example:
|
|
21
|
-
|
|
22
|
-
ufo init --image 123456789012.dkr.ecr.us-west-2.amazonaws.com/myimage
|
|
23
|
-
|
|
24
|
-
For more info, refer to the [ufo init](http://ufoships.com/reference/ufo-init/) reference docs.
|
|
16
|
+
Note: These quick start commands assume that you have push access to the repo. Refer to the Notes "Repo Push Access" section below for more info. It also assumes that you'd like to use ECS EC2 and assume that you have an ECS cluster with some EC2 Container instances running. Refer to the Notes "ECS EC2 vs ECS Fargate" section below for more info.
|
|
25
17
|
|
|
26
18
|
## What Happened
|
|
27
19
|
|
|
@@ -67,6 +59,28 @@ Congratulations! You have successfully deployed code to AWS ECS with ufo. It was
|
|
|
67
59
|
|
|
68
60
|
Note: This quick start requires a working Docker installation. For Docker installation instructions refer to to the [Docker installation guide](https://docs.docker.com/engine/installation/).
|
|
69
61
|
|
|
62
|
+
## Notes
|
|
63
|
+
|
|
64
|
+
### Repo Push Access
|
|
65
|
+
|
|
66
|
+
The quick start example pushes the Docker image to a Dockerhub repo. You need your own repo with push access. This repo could be your own Dockerhub account or ECR repo. You can control the setting with the `--image` option. Example:
|
|
67
|
+
|
|
68
|
+
ufo init --image=yourusername/yourrepo # use your own account
|
|
69
|
+
|
|
70
|
+
Also, if you are using ECR instead, you can specify an ECR repo with the `--image` option. Example:
|
|
71
|
+
|
|
72
|
+
ufo init --image 123456789012.dkr.ecr.us-west-2.amazonaws.com/myimage
|
|
73
|
+
|
|
74
|
+
For more info, refer to the [ufo init](http://ufoships.com/reference/ufo-init/) reference docs.
|
|
75
|
+
|
|
76
|
+
### ECS EC2 vs ECS Fargate
|
|
77
|
+
|
|
78
|
+
Ufo does not create the EC2 servers themselves to run the ECS tasks. If you use `ufo ship` to deploy an application to ECS EC2 and have not set up the EC2 servers, then the CloudFormation update will not be able to provision the ECS tasks and eventually roll back. Essentially it cannot create the ECS tasks because there are no EC2 servers to run them.
|
|
79
|
+
|
|
80
|
+
Refer to the AWS [Creating a Cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/create_cluster.html) docs to create an ECS cluster. Also refer to [ECS Terms Tutorial](https://blog.boltops.com/2017/09/08/aws-ecs-terms-tutorial) for an explanation of ECS terms.
|
|
81
|
+
|
|
82
|
+
If you would like not to manage the EC2 server fleet, you are looking for ECS Fargate instead of ECS EC2. ECS Fargate allows you to run ECS Tasks and AWS will manage the EC2 server fleet for you. Refer to the [Ufo Fargate]({% link _docs/fargate.md %}) docs and use those quick start like commands instead. The pricing for Fargate is more because AWS manages the server fleet for you. Refer to [Heroku vs ECS Fargate vs EC2 On-Demand vs EC2 Spot Pricing Comparison](https://blog.boltops.com/2018/04/22/heroku-vs-ecs-fargate-vs-ec2-on-demand-vs-ec2-spot-pricing-comparison) for a pricing comparison.
|
|
83
|
+
|
|
70
84
|
Learn more in the next sections.
|
|
71
85
|
|
|
72
86
|
<a id="next" class="btn btn-primary" href="{% link _docs/install.md %}">Next Step</a>
|
data/lib/ufo/cli.rb
CHANGED
|
@@ -105,6 +105,8 @@ module Ufo
|
|
|
105
105
|
desc "task TASK_DEFINITION", "Run a one-time task."
|
|
106
106
|
long_desc Help.text(:task)
|
|
107
107
|
option :task_only, type: :boolean, desc: "Skip docker and task register steps. Only run the task."
|
|
108
|
+
option :wait, type: :boolean, aliases: 'w', desc: "Wait for task to finish.", default: false
|
|
109
|
+
option :timeout, type: :numeric, aliases: 't', desc: "How long to wait for task to finish.", default: 600
|
|
108
110
|
option :command, type: :array, aliases: 'c', desc: "Override the command used for the container"
|
|
109
111
|
def task(task_definition)
|
|
110
112
|
Docker::Builder.build(options) unless @options[:task_only]
|
data/lib/ufo/task.rb
CHANGED
|
@@ -26,7 +26,7 @@ module Ufo
|
|
|
26
26
|
if @options[:command]
|
|
27
27
|
task_options.merge!(overrides: overrides)
|
|
28
28
|
puts "Running task with container overrides."
|
|
29
|
-
puts "Command: #{
|
|
29
|
+
puts "Command: #{command_in_human_readable_form}"
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
unless @options[:mute]
|
|
@@ -34,6 +34,8 @@ module Ufo
|
|
|
34
34
|
display_params(task_options)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
ensure_log_group_exist
|
|
38
|
+
|
|
37
39
|
resp = run_task(task_options)
|
|
38
40
|
exit_if_failures!(resp)
|
|
39
41
|
unless @options[:mute]
|
|
@@ -44,6 +46,10 @@ module Ufo
|
|
|
44
46
|
end
|
|
45
47
|
end
|
|
46
48
|
|
|
49
|
+
def ensure_log_group_exist
|
|
50
|
+
LogGroup.new(@task_definition, @options).create
|
|
51
|
+
end
|
|
52
|
+
|
|
47
53
|
# Pretty hard to produce this edge case. Happens when:
|
|
48
54
|
# launch_type: EC2
|
|
49
55
|
# network_mode: awsvpc
|
|
@@ -66,7 +72,13 @@ module Ufo
|
|
|
66
72
|
def run_task(options)
|
|
67
73
|
puts "Equivalent aws cli command:"
|
|
68
74
|
puts " aws ecs run-task --cluster #{@cluster} --task-definition #{options[:task_definition]}".colorize(:green)
|
|
69
|
-
ecs.run_task(options)
|
|
75
|
+
run_task_result = ecs.run_task(options)
|
|
76
|
+
if @options[:wait]
|
|
77
|
+
task_arn = run_task_result.tasks[0].task_arn
|
|
78
|
+
raise SystemExit, exit_status_of_task(task_arn)
|
|
79
|
+
else
|
|
80
|
+
run_task_result
|
|
81
|
+
end
|
|
70
82
|
rescue Aws::ECS::Errors::ClientException => e
|
|
71
83
|
if e.message =~ /ECS was unable to assume the role/
|
|
72
84
|
puts "ERROR: #{e.class} #{e.message}".colorize(:red)
|
|
@@ -172,7 +184,7 @@ module Ufo
|
|
|
172
184
|
arns = task_definition_arns(@task_definition)
|
|
173
185
|
# "arn:aws:ecs:us-east-1:<aws_account_id>:task-definition/wordpress:6",
|
|
174
186
|
last_definition_arn = arns.first
|
|
175
|
-
puts "last_definition_arn #{last_definition_arn}"
|
|
187
|
+
# puts "last_definition_arn #{last_definition_arn}"
|
|
176
188
|
task_name = last_definition_arn.split("/").last
|
|
177
189
|
resp = ecs.describe_task_definition(task_definition: task_name)
|
|
178
190
|
|
|
@@ -184,5 +196,28 @@ module Ufo
|
|
|
184
196
|
def container_definition
|
|
185
197
|
recent_task_definition.container_definitions[0].to_h
|
|
186
198
|
end
|
|
199
|
+
|
|
200
|
+
def exit_status_of_task(task_arn)
|
|
201
|
+
waiter_max_attempts = @options[:timeout] / 5
|
|
202
|
+
waiter_delay = 5 # seconds long polling.
|
|
203
|
+
|
|
204
|
+
print "Waiting for task to complete."
|
|
205
|
+
ecs.wait_until(:tasks_stopped, { cluster: @cluster, tasks: [task_arn] }) do |waiter|
|
|
206
|
+
waiter.before_wait { print '.' }
|
|
207
|
+
waiter.delay = waiter_delay
|
|
208
|
+
waiter.max_attempts = waiter_max_attempts
|
|
209
|
+
end
|
|
210
|
+
puts
|
|
211
|
+
container = ecs.describe_tasks(cluster: @cluster, tasks: [task_arn]).tasks[0].containers[0]
|
|
212
|
+
|
|
213
|
+
container.exit_code.nil? ? 1 : container.exit_code
|
|
214
|
+
rescue Aws::Waiters::Errors::WaiterFailed
|
|
215
|
+
puts "It took longer than #{options[:timeout]} seconds to run #{command_in_human_readable_form} (#{task_arn})"
|
|
216
|
+
exit 1
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def command_in_human_readable_form
|
|
220
|
+
@options[:command].join(' ')
|
|
221
|
+
end
|
|
187
222
|
end
|
|
188
223
|
end
|
data/lib/ufo/version.rb
CHANGED
data/spec/lib/task_spec.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
describe Ufo::
|
|
1
|
+
describe Ufo::Task do
|
|
2
2
|
before(:each) do
|
|
3
3
|
create_ufo_project
|
|
4
4
|
end
|
|
@@ -8,11 +8,6 @@ describe Ufo::Ship do
|
|
|
8
8
|
}
|
|
9
9
|
end
|
|
10
10
|
let(:task_definition) { "hi-migrate-prod" }
|
|
11
|
-
let(:task) do
|
|
12
|
-
task = Ufo::Task.new(task_definition, options)
|
|
13
|
-
allow(task).to receive(:ecs).and_return(ecs_client)
|
|
14
|
-
task
|
|
15
|
-
end
|
|
16
11
|
|
|
17
12
|
context "hi-migrate-prod" do
|
|
18
13
|
it "should migrate the database" do
|
|
@@ -20,15 +15,39 @@ describe Ufo::Ship do
|
|
|
20
15
|
|
|
21
16
|
expect(task.ecs).to have_received(:run_task)
|
|
22
17
|
end
|
|
18
|
+
|
|
19
|
+
it "should wait for the command to finish" do
|
|
20
|
+
expect do
|
|
21
|
+
task(wait: true, timeout: 600).run
|
|
22
|
+
expect(task.ecs).to have_received(:run_task)
|
|
23
|
+
end.to raise_error(SystemExit) do |error|
|
|
24
|
+
expect(error.status).to eq(5)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
23
27
|
end
|
|
24
28
|
|
|
25
29
|
# mocks
|
|
26
30
|
def ecs_client
|
|
27
31
|
ecs = double("ecs")
|
|
32
|
+
ecs_container = double("ecs_container")
|
|
28
33
|
fake_response = double('fake-response').as_null_object
|
|
29
34
|
allow(ecs).to receive(:run_task).and_return(fake_response)
|
|
35
|
+
allow(ecs).to receive(:wait_until).and_return(fake_response)
|
|
36
|
+
allow(ecs).to receive(:describe_tasks).and_return(OpenStruct.new({
|
|
37
|
+
tasks: [OpenStruct.new(containers: [ecs_container])]
|
|
38
|
+
}))
|
|
30
39
|
allow(ecs).to receive(:list_task_definitions).and_return(fake_response)
|
|
31
40
|
allow(ecs).to receive(:describe_task_definition).and_return(fake_response)
|
|
41
|
+
allow(ecs_container).to receive(:exit_code).and_return(5)
|
|
32
42
|
ecs
|
|
33
43
|
end
|
|
44
|
+
|
|
45
|
+
def task option_overwrites = {}
|
|
46
|
+
@task ||=
|
|
47
|
+
begin
|
|
48
|
+
result = Ufo::Task.new(task_definition, options.merge(option_overwrites))
|
|
49
|
+
allow(result).to receive(:ecs).and_return(ecs_client)
|
|
50
|
+
result
|
|
51
|
+
end
|
|
52
|
+
end
|
|
34
53
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ufo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.1.
|
|
4
|
+
version: 4.1.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tung Nguyen
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-
|
|
11
|
+
date: 2018-12-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: aws-sdk-cloudformation
|