ufo 1.2.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +7 -7
- data/README.md +8 -8
- data/bin/ufo +7 -0
- data/lib/ufo.rb +12 -16
- data/lib/ufo/cli.rb +48 -90
- data/lib/ufo/cli/help.rb +23 -80
- data/lib/ufo/destroy.rb +1 -1
- data/lib/ufo/docker.rb +48 -0
- data/lib/ufo/{docker_builder.rb → docker/builder.rb} +14 -6
- data/lib/ufo/{docker_cleaner.rb → docker/cleaner.rb} +2 -2
- data/lib/ufo/{dockerfile_updater.rb → docker/dockerfile.rb} +1 -1
- data/lib/ufo/docker/help.rb +65 -0
- data/lib/ufo/dsl.rb +31 -1
- data/lib/ufo/dsl/helper.rb +1 -1
- data/lib/ufo/ecr.rb +6 -0
- data/lib/ufo/{ecr_auth.rb → ecr/auth.rb} +1 -1
- data/lib/ufo/{ecr_cleaner.rb → ecr/cleaner.rb} +2 -2
- data/lib/ufo/init.rb +1 -1
- data/lib/ufo/ship.rb +12 -5
- data/lib/ufo/tasks.rb +20 -0
- data/lib/ufo/{tasks_builder.rb → tasks/builder.rb} +11 -2
- data/lib/ufo/tasks/help.rb +26 -0
- data/lib/ufo/{tasks_register.rb → tasks/register.rb} +2 -2
- data/lib/ufo/{execute.rb → util.rb} +12 -1
- data/lib/ufo/version.rb +1 -1
- data/spec/fixtures/home_existing/.aws/config +3 -0
- data/spec/lib/cli_spec.rb +10 -0
- data/spec/lib/ecr_auth_spec.rb +3 -4
- data/spec/lib/ecr_cleaner_spec.rb +2 -2
- metadata +17 -11
- data/lib/ufo/pretty_time.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88ffa32343a3f2d384a43df599aab3521141bd03
|
4
|
+
data.tar.gz: d305e9b86ea4dbb552014b1c1ea4ee67d79dd4f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 200363f4ff73473eb9ca774ded09805f459af00d01130a9a4e7f9dee41238b5d0522be360908ba63f56b480f33f7e171f6fd7f3267e49af00c529fc43916911f
|
7
|
+
data.tar.gz: 0c1c498e29e3669907137abc93dbb9aa5b914a764ef506ec310e395124950171d8c78b39dbe7dfdaae74e93df743d99dcc0e5e063b4925b5fb5d5a4675134fcc
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,12 @@
|
|
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
|
+
## [1.5.0]
|
7
|
+
* add ufo ships command
|
8
|
+
* refactor code into modules: ecr, docker, tasks
|
9
|
+
* improve error message when task_definitions.rb evaluation errors
|
10
|
+
* rename --force option to --sure
|
11
|
+
|
6
12
|
## [1.2.0]
|
7
13
|
|
8
14
|
* allow -h, --help, help options at the end of the command
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ufo (1.
|
4
|
+
ufo (1.2.0)
|
5
5
|
aws-sdk
|
6
6
|
colorize
|
7
7
|
deep_merge
|
@@ -20,13 +20,13 @@ GEM
|
|
20
20
|
minitest (~> 5.1)
|
21
21
|
thread_safe (~> 0.3, >= 0.3.4)
|
22
22
|
tzinfo (~> 1.1)
|
23
|
-
aws-sdk (2.9.
|
24
|
-
aws-sdk-resources (= 2.9.
|
25
|
-
aws-sdk-core (2.9.
|
23
|
+
aws-sdk (2.9.28)
|
24
|
+
aws-sdk-resources (= 2.9.28)
|
25
|
+
aws-sdk-core (2.9.28)
|
26
26
|
aws-sigv4 (~> 1.0)
|
27
27
|
jmespath (~> 1.0)
|
28
|
-
aws-sdk-resources (2.9.
|
29
|
-
aws-sdk-core (= 2.9.
|
28
|
+
aws-sdk-resources (2.9.28)
|
29
|
+
aws-sdk-core (= 2.9.28)
|
30
30
|
aws-sigv4 (1.0.0)
|
31
31
|
builder (3.2.3)
|
32
32
|
byebug (9.0.6)
|
@@ -37,7 +37,7 @@ GEM
|
|
37
37
|
diff-lcs (1.3)
|
38
38
|
docile (1.1.5)
|
39
39
|
hashie (3.5.5)
|
40
|
-
i18n (0.8.
|
40
|
+
i18n (0.8.4)
|
41
41
|
jmespath (1.3.1)
|
42
42
|
json (2.1.0)
|
43
43
|
minitest (5.10.2)
|
data/README.md
CHANGED
@@ -158,7 +158,7 @@ task_definition "hi-web-prod" do
|
|
158
158
|
family: task_definition_name,
|
159
159
|
# image: tongueroo/hi:ufo-[timestamp]=[sha]
|
160
160
|
image: helper.full_image_name,
|
161
|
-
environment: env_file('.env.prod')
|
161
|
+
environment: helper.env_file('.env.prod')
|
162
162
|
name: "web",
|
163
163
|
container_port: helper.dockerfile_port,
|
164
164
|
command: ["bin/web"]
|
@@ -170,8 +170,8 @@ The task\_definitions.rb file has some special variables and helper methods avai
|
|
170
170
|
|
171
171
|
* **helper.full\_image\_name** — The full docker image name that ufo builds. The “base” portion of the docker image name is defined in ufo/settings.yml. For example, the base portion is `tongueroo/hi` and the full image name is `tongueroo/hi:ufo-[timestamp]-[sha]`. The base name does not include the generated Docker tag, which contains a timestamp and git sha of the Dockerfile that is used.
|
172
172
|
* **helper.dockerfile\_port** — Exposed port extracted from the Dockerfile of the project.
|
173
|
-
* **env_vars(text)** — This method takes a block of text that contains the env values in key=value format and converts that block of text to the proper task definition json format.
|
174
|
-
* **env_file(path)** — This method takes an `.env` file which contains a simple key value list of environment variables and converts the list to the proper task definition json format.
|
173
|
+
* **helper.env_vars(text)** — This method takes a block of text that contains the env values in key=value format and converts that block of text to the proper task definition json format.
|
174
|
+
* **helper.env_file(path)** — This method takes an `.env` file which contains a simple key value list of environment variables and converts the list to the proper task definition json format.
|
175
175
|
|
176
176
|
The 2 classes which provide these special helper methods are in [ufo/dsl.rb](https://github.com/tongueroo/ufo/blob/master/lib/ufo/dsl.rb) and [ufo/dsl/helper.rb](https://github.com/tongueroo/ufo/blob/master/lib/ufo/dsl/helper.rb). Refer to these classes for the full list of the special variables and methods.
|
177
177
|
|
@@ -184,9 +184,9 @@ This is easily accomplished with the `bin/deploy` wrapper script that the `ufo i
|
|
184
184
|
```bash
|
185
185
|
#!/bin/bash -xe
|
186
186
|
|
187
|
-
ufo ship hi-worker-prod --cluster
|
188
|
-
ufo ship hi-clock-prod --cluster
|
189
|
-
ufo ship hi-web-prod --cluster
|
187
|
+
ufo ship hi-worker-prod --cluster prod --no-wait
|
188
|
+
ufo ship hi-clock-prod --cluster prod --no-wait --no-docker
|
189
|
+
ufo ship hi-web-prod --cluster prod --no-docker
|
190
190
|
```
|
191
191
|
|
192
192
|
The first `ufo ship hi-worker-prod` command build and ships docker image to ECS, but the following two `ufo ship` commands use the `--no-docker` flag to skip the `docker build` step. `ufo ship` will use the last built docker image as the image to be shipped. For those curious, this is stored in `ufo/docker_image_name_ufo.txt`.
|
@@ -196,7 +196,7 @@ The first `ufo ship hi-worker-prod` command build and ships docker image to ECS,
|
|
196
196
|
Ufo assumes a convention that service\_name and the task\_name are the same. If you would like to override this convention then you can specify the task name.
|
197
197
|
|
198
198
|
```
|
199
|
-
ufo ship hi-web-prod--task my-task
|
199
|
+
ufo ship hi-web-prod --task my-task
|
200
200
|
```
|
201
201
|
|
202
202
|
This means that in the task_definition.rb you will also defined it with `my-task`. For example:
|
@@ -233,7 +233,7 @@ ufo tasks register # will register all genreated task definitinos in the ufo/out
|
|
233
233
|
Skips all the build docker phases of a deploy sequence and only update the service with the task definitions.
|
234
234
|
|
235
235
|
```bash
|
236
|
-
ufo ship hi-web-prod--no-docker
|
236
|
+
ufo ship hi-web-prod --no-docker
|
237
237
|
```
|
238
238
|
Note if you use the `--no-docker` option you should ensure that you have already push a docker image to your docker register. Or else the task will not be able to spin up because the docker image does not exist. I recommend that you normally use `ufo ship` most of the time.
|
239
239
|
|
data/bin/ufo
CHANGED
data/lib/ufo.rb
CHANGED
@@ -1,28 +1,24 @@
|
|
1
|
-
$:.unshift(File.expand_path(
|
2
|
-
require
|
3
|
-
require "pp"
|
1
|
+
$:.unshift(File.expand_path('../', __FILE__))
|
2
|
+
require 'ufo/version'
|
4
3
|
require 'deep_merge'
|
5
|
-
require
|
4
|
+
require 'colorize'
|
5
|
+
require 'fileutils'
|
6
6
|
|
7
7
|
module Ufo
|
8
|
+
autoload :Defaults, 'ufo/defaults'
|
9
|
+
autoload :AwsServices, 'ufo/aws_services'
|
8
10
|
autoload :Command, 'ufo/command'
|
9
11
|
autoload :Settings, 'ufo/settings'
|
10
|
-
autoload :
|
11
|
-
autoload :Execute, 'ufo/execute'
|
12
|
+
autoload :Util, 'ufo/util'
|
12
13
|
autoload :Init, 'ufo/init'
|
13
|
-
autoload :EcrAuth, 'ufo/ecr_auth'
|
14
14
|
autoload :CLI, 'ufo/cli'
|
15
|
-
autoload :DockerBuilder, 'ufo/docker_builder'
|
16
|
-
autoload :DockerfileUpdater, 'ufo/dockerfile_updater'
|
17
|
-
autoload :DockerCleaner, 'ufo/docker_cleaner'
|
18
|
-
autoload :TasksBuilder, 'ufo/tasks_builder'
|
19
|
-
autoload :TasksRegister, 'ufo/tasks_register'
|
20
15
|
autoload :Ship, 'ufo/ship'
|
21
16
|
autoload :Task, 'ufo/task'
|
22
|
-
autoload :EcrCleaner, 'ufo/ecr_cleaner'
|
23
17
|
autoload :Destroy, 'ufo/destroy'
|
18
|
+
autoload :DSL, 'ufo/dsl'
|
24
19
|
autoload :Scale, 'ufo/scale'
|
25
|
-
|
26
|
-
autoload :
|
27
|
-
autoload :
|
20
|
+
|
21
|
+
autoload :Docker, 'ufo/docker'
|
22
|
+
autoload :Ecr, 'ufo/ecr'
|
23
|
+
autoload :Tasks, 'ufo/tasks'
|
28
24
|
end
|
data/lib/ufo/cli.rb
CHANGED
@@ -3,63 +3,6 @@ require 'ufo/command'
|
|
3
3
|
require 'ufo/cli/help'
|
4
4
|
|
5
5
|
module Ufo
|
6
|
-
class Docker < Command
|
7
|
-
desc "build", "builds docker image"
|
8
|
-
long_desc CLI::Help.docker_build
|
9
|
-
option :push, type: :boolean, default: false
|
10
|
-
def build
|
11
|
-
builder = DockerBuilder.new(options)
|
12
|
-
builder.build
|
13
|
-
builder.push if options[:push]
|
14
|
-
end
|
15
|
-
|
16
|
-
desc "base", "builds docker image from Dockerfile.base and update current Dockerfile"
|
17
|
-
long_desc CLI::Help.docker_base
|
18
|
-
option :push, type: :boolean, default: true
|
19
|
-
def base
|
20
|
-
builder = DockerBuilder.new(options.dup.merge(
|
21
|
-
image_namespace: "base",
|
22
|
-
dockerfile: "Dockerfile.base"
|
23
|
-
))
|
24
|
-
builder.build
|
25
|
-
builder.push if options[:push]
|
26
|
-
builder.update_dockerfile
|
27
|
-
DockerCleaner.new(builder.image_name, options.merge(tag_prefix: "base")).cleanup
|
28
|
-
EcrCleaner.new(builder.image_name, options.merge(tag_prefix: "base")).cleanup
|
29
|
-
end
|
30
|
-
|
31
|
-
desc "image_name", "displays the full docker image with tag that will be generated"
|
32
|
-
option :generate, type: :boolean, default: false, desc: "Generate a name without storing it"
|
33
|
-
long_desc CLI::Help.docker_full_image_name
|
34
|
-
def image_name
|
35
|
-
full_image_name = DockerBuilder.new(options).full_image_name
|
36
|
-
puts full_image_name
|
37
|
-
end
|
38
|
-
|
39
|
-
desc "cleanup IMAGE_NAME", "Cleans up old images. Keeps a specified amount."
|
40
|
-
option :keep, type: :numeric, default: 3
|
41
|
-
option :tag_prefix, default: "ufo"
|
42
|
-
long_desc CLI::Help.docker_cleanup
|
43
|
-
def cleanup(image_name)
|
44
|
-
DockerCleaner.new(image_name, options).cleanup
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
class Tasks < Command
|
49
|
-
desc "build", "builds task definitions"
|
50
|
-
long_desc CLI::Help.tasks_build
|
51
|
-
option :pretty, type: :boolean, default: true, desc: "Pretty format the json for the task definitions"
|
52
|
-
def build
|
53
|
-
TasksBuilder.new(options).build
|
54
|
-
end
|
55
|
-
|
56
|
-
desc "register", "register all built task definitions in ufo/output"
|
57
|
-
long_desc CLI::Help.tasks_register
|
58
|
-
def register
|
59
|
-
TasksRegister.register(:all, options)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
6
|
class CLI < Command
|
64
7
|
class_option :verbose, type: :boolean
|
65
8
|
class_option :mute, type: :boolean
|
@@ -67,11 +10,11 @@ module Ufo
|
|
67
10
|
class_option :project_root, type: :string, default: '.'
|
68
11
|
class_option :cluster, desc: "Cluster. Overrides ufo/settings.yml."
|
69
12
|
|
70
|
-
desc "docker ACTION", "docker related tasks"
|
13
|
+
desc "docker [ACTION]", "docker related tasks"
|
71
14
|
long_desc Help.docker
|
72
15
|
subcommand "docker", Docker
|
73
16
|
|
74
|
-
desc "tasks ACTION", "task definition related tasks"
|
17
|
+
desc "tasks [ACTION]", "task definition related tasks"
|
75
18
|
long_desc Help.tasks
|
76
19
|
subcommand "tasks", Tasks
|
77
20
|
|
@@ -84,30 +27,48 @@ module Ufo
|
|
84
27
|
Init.new(options).setup
|
85
28
|
end
|
86
29
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
30
|
+
# common options to ship and ships command
|
31
|
+
ship_options = Proc.new do
|
32
|
+
option :task, desc: "ECS task name, to override the task name convention."
|
33
|
+
option :target_group, desc: "ELB Target Group ARN."
|
34
|
+
option :elb, desc: "ELB Name associated with the target_group. Assumes first "
|
35
|
+
option :elb_prompt, type: :boolean, desc: "Enable ELB prompt", default: true
|
36
|
+
option :docker, type: :boolean, desc: "Enable docker build and push", default: true
|
37
|
+
option :wait, type: :boolean, desc: "Wait for deployment to complete", default: false
|
38
|
+
option :pretty, type: :boolean, default: true, desc: "Pretty format the json for the task definitions"
|
39
|
+
option :stop_old_tasks, type: :boolean, default: false, desc: "Stop old tasks after waiting for deploying to complete"
|
40
|
+
option :ecr_keep, type: :numeric, desc: "ECR specific cleanup of old images. Specifies how many images to keep. Only runs if the images are ECR images. Defaults to keeping all the images."
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "ship [SERVICE]", "builds and ships container image to the ECS service"
|
97
44
|
long_desc Help.ship
|
45
|
+
ship_options.call
|
98
46
|
def ship(service)
|
99
|
-
builder = build_docker
|
100
|
-
task_definition = options[:task] || service # convention
|
101
|
-
register_task(task_definition, options)
|
102
|
-
return if ENV['TEST'] # allows quick testing of the ship CLI portion only
|
47
|
+
builder = build_docker
|
103
48
|
|
49
|
+
task_definition = options[:task] || service # convention
|
50
|
+
Tasks::Builder.register(task_definition, options)
|
104
51
|
ship = Ship.new(service, task_definition, options)
|
105
52
|
ship.deploy
|
106
|
-
|
107
|
-
|
108
|
-
|
53
|
+
|
54
|
+
cleanup(builder.image_name)
|
55
|
+
end
|
56
|
+
|
57
|
+
desc "ships [LIST-OF-SERVICES]", "builds and ships same container image to multiple ECS services"
|
58
|
+
long_desc Help.ships
|
59
|
+
ship_options.call
|
60
|
+
def ships(*services)
|
61
|
+
builder = build_docker
|
62
|
+
|
63
|
+
services.each_with_index do |service|
|
64
|
+
service_name, task_defintion_name = service.split(':')
|
65
|
+
task_definition = task_defintion_name || service_name # convention
|
66
|
+
Tasks::Builder.register(task_definition, options)
|
67
|
+
ship = Ship.new(service, task_definition, options)
|
68
|
+
ship.deploy
|
109
69
|
end
|
110
|
-
|
70
|
+
|
71
|
+
cleanup(builder.image_name)
|
111
72
|
end
|
112
73
|
|
113
74
|
desc "task [TASK_DEFINITION]", "runs a one time task"
|
@@ -115,14 +76,14 @@ module Ufo
|
|
115
76
|
option :docker, type: :boolean, desc: "Enable docker build and push", default: true
|
116
77
|
option :command, type: :array, desc: "Override the command used for the container"
|
117
78
|
def task(task_definition)
|
118
|
-
|
119
|
-
|
79
|
+
Docker::Builder.build(options)
|
80
|
+
Tasks::Builder.register(task_definition, options)
|
120
81
|
Task.new(task_definition, options).run
|
121
82
|
end
|
122
83
|
|
123
84
|
desc "destroy [SERVICE]", "destroys the ECS service"
|
124
85
|
long_desc Help.destroy
|
125
|
-
option :
|
86
|
+
option :sure, type: :boolean, desc: "By pass are you sure prompt."
|
126
87
|
def destroy(service)
|
127
88
|
task_definition = options[:task] || service # convention
|
128
89
|
Destroy.new(service, options).bye
|
@@ -140,8 +101,8 @@ module Ufo
|
|
140
101
|
end
|
141
102
|
|
142
103
|
no_tasks do
|
143
|
-
def build_docker
|
144
|
-
builder =
|
104
|
+
def build_docker
|
105
|
+
builder = Docker::Builder.new(options)
|
145
106
|
if options[:docker]
|
146
107
|
builder.build
|
147
108
|
builder.push
|
@@ -149,14 +110,11 @@ module Ufo
|
|
149
110
|
builder
|
150
111
|
end
|
151
112
|
|
152
|
-
def
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
# So we always call these together.
|
158
|
-
TasksBuilder.new(options).build
|
159
|
-
TasksRegister.register(task_definition, options)
|
113
|
+
def cleanup(image_name)
|
114
|
+
return unless options[:docker]
|
115
|
+
|
116
|
+
Docker::Cleaner.new(image_name, options).cleanup
|
117
|
+
Ecr::Cleaner.new(image_name, options).cleanup
|
160
118
|
end
|
161
119
|
end
|
162
120
|
end
|
data/lib/ufo/cli/help.rb
CHANGED
@@ -22,66 +22,6 @@ $ ufo docker tag
|
|
22
22
|
EOL
|
23
23
|
end
|
24
24
|
|
25
|
-
def docker_base
|
26
|
-
<<-EOL
|
27
|
-
|
28
|
-
The docker cache task builds a docker image using the Dockerfile.base file and
|
29
|
-
updates the FROM Dockerfile image with the generated image from Dockerfile.base.
|
30
|
-
|
31
|
-
Examples:
|
32
|
-
|
33
|
-
$ ufo docker base
|
34
|
-
|
35
|
-
$ ufo docker base --no-push # do not push the image to the registry
|
36
|
-
|
37
|
-
Docker image tongueroo/hi:base-2016-10-21T15-50-57-88071f5 built.
|
38
|
-
EOL
|
39
|
-
end
|
40
|
-
|
41
|
-
def docker_build
|
42
|
-
<<-EOL
|
43
|
-
Examples:
|
44
|
-
|
45
|
-
$ ufo docker build
|
46
|
-
|
47
|
-
$ ufo docker build --push # also pushes the image to the docker registry
|
48
|
-
|
49
|
-
Docker image tongueroo/hi:ufo-2016-10-21T15-50-57-88071f5 built.
|
50
|
-
EOL
|
51
|
-
end
|
52
|
-
|
53
|
-
def docker_full_image_name
|
54
|
-
<<-EOL
|
55
|
-
Examples:
|
56
|
-
|
57
|
-
$ ufo docker full_image_name
|
58
|
-
|
59
|
-
Docker image name that will be used: tongueroo/hi:ufo-2016-10-15T19-29-06-88071f5
|
60
|
-
EOL
|
61
|
-
end
|
62
|
-
|
63
|
-
def docker_cleanup
|
64
|
-
<<-EOL
|
65
|
-
Examples:
|
66
|
-
|
67
|
-
Say you currently have these images:
|
68
|
-
|
69
|
-
* tongueroo/hi:ufo-2016-10-15T19-29-06-88071f5
|
70
|
-
|
71
|
-
* tongueroo/hi:ufo-2016-10-16T19-29-06-88071f5
|
72
|
-
|
73
|
-
* tongueroo/hi:ufo-2016-10-17T19-29-06-88071f5
|
74
|
-
|
75
|
-
* tongueroo/hi:ufo-2016-10-18T19-29-06-88071f5
|
76
|
-
|
77
|
-
To clean them up and keep the 3 more recent:
|
78
|
-
|
79
|
-
$ ufo docker cleanup tongueroo/hi
|
80
|
-
|
81
|
-
This will remove tongueroo/hi:ufo-2016-10-15T19-29-06-88071f5.
|
82
|
-
EOL
|
83
|
-
end
|
84
|
-
|
85
25
|
def tasks
|
86
26
|
<<-EOL
|
87
27
|
Examples:
|
@@ -94,46 +34,49 @@ Note all the existing ufo/output generated task defintions are wiped out.
|
|
94
34
|
EOL
|
95
35
|
end
|
96
36
|
|
97
|
-
def
|
37
|
+
def ship
|
98
38
|
<<-EOL
|
99
39
|
Examples:
|
100
40
|
|
101
|
-
|
41
|
+
To build the docker image, generate the task definition and ship it, run:
|
102
42
|
|
103
|
-
|
43
|
+
$ ufo ship hi-web-prod
|
104
44
|
|
105
|
-
|
106
|
-
EOL
|
107
|
-
end
|
45
|
+
By convention the task and service names match. If you need override to this convention then you can specific the task. For example if you want to ship to the `hi-web-prod-1` service and use the `hi-web-prod` task, run:
|
108
46
|
|
109
|
-
|
110
|
-
<<-EOL
|
111
|
-
Examples:
|
47
|
+
$ ufo ship hi-web-prod-1 --task hi-web-prod
|
112
48
|
|
113
|
-
|
114
|
-
|
49
|
+
The deploy will also created the ECS service if the service does not yet exist on the cluster. The deploy will prompt you for the ELB `--target-group` if you are shipping a web container that does not yet exist. If it is not a web container the `--target-group` option gets ignored.
|
50
|
+
|
51
|
+
The prommpt can be bypassed by specifying a valid `--target-group` option or specifying the `---no-elb-prompt` option.
|
52
|
+
|
53
|
+
$ ufo ship hi-web-prod --target-group arn:aws:elasticloadbalancing:us-east-1:123456789:targetgroup/hi-web-prod/jsdlfjsdkd
|
54
|
+
|
55
|
+
$ ufo ship hi-web-prod --no-elb-prompt
|
115
56
|
EOL
|
116
57
|
end
|
117
58
|
|
118
|
-
def
|
59
|
+
def ships
|
119
60
|
<<-EOL
|
61
|
+
Builds docker image, registers it and ships it to multiple services. This deploys the same docker image to multiple ECS services.
|
62
|
+
|
120
63
|
Examples:
|
121
64
|
|
122
|
-
|
65
|
+
$ ufo ships hi-web-prod hi-clock-prod hi-worker-prod
|
123
66
|
|
124
|
-
|
67
|
+
By convention the task definition and service names match for each of the services you ship. If you need to override to this convention then you can specify the task definition for each service with a special syntax. In the special syntax the service and task definition is separated by a colon. Example:
|
125
68
|
|
126
|
-
|
69
|
+
$ ufo ships hi-web-prod-1:hi-web-prod hi-clock-prod-1 hi-worker-prod-1
|
127
70
|
|
128
|
-
|
71
|
+
Here ufo will deploy to the hi-web-prod-1 ECS Service using the hi-web-prod task definition, but use the convention for the rest of the service.
|
129
72
|
|
130
|
-
|
73
|
+
For each service being deployed to, ufo will create the ECS service if the service does not yet exist on the cluster. The deploy process will prompt you for the ELB `--target-group` if you are deploying to a 'web' service that does not yet exist. Ufo determines that it is a web service by the name of the service. If the service has 'web' in the name then it is considered a web service. If it is not a web service then the `--target-group` option gets ignored.
|
131
74
|
|
132
|
-
The prommpt can be bypassed by specifying a valid `--target-group` option or specifying the `---no-elb-prompt` option.
|
75
|
+
The prommpt can be bypassed by specifying a valid `--target-group` option or specifying the `---no-elb-prompt` option. Examples:
|
133
76
|
|
134
|
-
$ ufo
|
77
|
+
$ ufo ships hi-web-prod hi-clock-prod hi-worker-prod --target-group arn:aws:elasticloadbalancing:us-east-1:123456789:targetgroup/hi-web-prod/jsdlfjsdkd
|
135
78
|
|
136
|
-
$ ufo
|
79
|
+
$ ufo ships hi-web-prod hi-clock-prod hi-worker-prod --no-elb-prompt
|
137
80
|
EOL
|
138
81
|
end
|
139
82
|
|
data/lib/ufo/destroy.rb
CHANGED
@@ -50,7 +50,7 @@ module Ufo
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def are_you_sure?
|
53
|
-
return true if @options[:
|
53
|
+
return true if @options[:sure]
|
54
54
|
puts "You are about to destroy #{@service} service on #{@cluster} cluster."
|
55
55
|
print "Are you sure you want to do this? (y/n) "
|
56
56
|
answer = $stdin.gets.strip
|
data/lib/ufo/docker.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module Ufo
|
2
|
+
class Docker < Command
|
3
|
+
autoload :Help, 'ufo/docker/help'
|
4
|
+
autoload :Builder, 'ufo/docker/builder'
|
5
|
+
autoload :Dockerfile, 'ufo/docker/dockerfile'
|
6
|
+
autoload :Cleaner, 'ufo/docker/cleaner'
|
7
|
+
|
8
|
+
desc "build", "builds docker image"
|
9
|
+
long_desc Help.build
|
10
|
+
option :push, type: :boolean, default: false
|
11
|
+
def build
|
12
|
+
builder = Docker::Builder.new(options)
|
13
|
+
builder.build
|
14
|
+
builder.push if options[:push]
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "base", "builds docker image from Dockerfile.base and update current Dockerfile"
|
18
|
+
long_desc Help.base
|
19
|
+
option :push, type: :boolean, default: true
|
20
|
+
def base
|
21
|
+
builder = Docker::Builder.new(options.dup.merge(
|
22
|
+
image_namespace: "base",
|
23
|
+
dockerfile: "Dockerfile.base"
|
24
|
+
))
|
25
|
+
builder.build
|
26
|
+
builder.push if options[:push]
|
27
|
+
builder.update_dockerfile
|
28
|
+
Docker::Cleaner.new(builder.image_name, options.merge(tag_prefix: "base")).cleanup
|
29
|
+
Ecr::Cleaner.new(builder.image_name, options.merge(tag_prefix: "base")).cleanup
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "image_name", "displays the full docker image with tag that will be generated"
|
33
|
+
option :generate, type: :boolean, default: false, desc: "Generate a name without storing it"
|
34
|
+
long_desc Help.full_image_name
|
35
|
+
def image_name
|
36
|
+
full_image_name = Docker::Builder.new(options).full_image_name
|
37
|
+
puts full_image_name
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "cleanup IMAGE_NAME", "Cleans up old images. Keeps a specified amount."
|
41
|
+
option :keep, type: :numeric, default: 3
|
42
|
+
option :tag_prefix, default: "ufo"
|
43
|
+
long_desc Help.cleanup
|
44
|
+
def cleanup(image_name)
|
45
|
+
Docker::Cleaner.new(image_name, options).cleanup
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -1,7 +1,15 @@
|
|
1
1
|
module Ufo
|
2
|
-
class
|
3
|
-
include
|
4
|
-
|
2
|
+
class Docker::Builder
|
3
|
+
include Util
|
4
|
+
|
5
|
+
def self.build(options)
|
6
|
+
builder = Docker::Builder.new(options) # outside if because it need builder.full_image_name
|
7
|
+
if options[:docker]
|
8
|
+
builder.build
|
9
|
+
builder.push
|
10
|
+
end
|
11
|
+
builder
|
12
|
+
end
|
5
13
|
|
6
14
|
def initialize(options={})
|
7
15
|
@options = options
|
@@ -54,7 +62,7 @@ module Ufo
|
|
54
62
|
def update_auth_token
|
55
63
|
return unless ecr_image?
|
56
64
|
repo_domain = "https://#{image_name.split('/').first}"
|
57
|
-
auth =
|
65
|
+
auth = Ecr::Auth.new(repo_domain)
|
58
66
|
auth.update
|
59
67
|
end
|
60
68
|
|
@@ -117,8 +125,8 @@ module Ufo
|
|
117
125
|
end
|
118
126
|
|
119
127
|
def update_dockerfile
|
120
|
-
|
121
|
-
|
128
|
+
dockerfile = Docker::Dockerfile.new(full_image_name, @options)
|
129
|
+
dockerfile.update
|
122
130
|
end
|
123
131
|
|
124
132
|
def say(msg)
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Ufo
|
2
|
+
module Docker::Help
|
3
|
+
def base
|
4
|
+
<<-EOL
|
5
|
+
|
6
|
+
The docker cache task builds a docker image using the Dockerfile.base file and
|
7
|
+
updates the FROM Dockerfile image with the generated image from Dockerfile.base.
|
8
|
+
|
9
|
+
Examples:
|
10
|
+
|
11
|
+
$ ufo docker base
|
12
|
+
|
13
|
+
$ ufo docker base --no-push # do not push the image to the registry
|
14
|
+
|
15
|
+
Docker image tongueroo/hi:base-2016-10-21T15-50-57-88071f5 built.
|
16
|
+
EOL
|
17
|
+
end
|
18
|
+
|
19
|
+
def build
|
20
|
+
<<-EOL
|
21
|
+
Examples:
|
22
|
+
|
23
|
+
$ ufo docker build
|
24
|
+
|
25
|
+
$ ufo docker build --push # also pushes the image to the docker registry
|
26
|
+
|
27
|
+
Docker image tongueroo/hi:ufo-2016-10-21T15-50-57-88071f5 built.
|
28
|
+
EOL
|
29
|
+
end
|
30
|
+
|
31
|
+
def full_image_name
|
32
|
+
<<-EOL
|
33
|
+
Examples:
|
34
|
+
|
35
|
+
$ ufo docker full_image_name
|
36
|
+
|
37
|
+
Docker image name that will be used: tongueroo/hi:ufo-2016-10-15T19-29-06-88071f5
|
38
|
+
EOL
|
39
|
+
end
|
40
|
+
|
41
|
+
def cleanup
|
42
|
+
<<-EOL
|
43
|
+
Examples:
|
44
|
+
|
45
|
+
Say you currently have these images:
|
46
|
+
|
47
|
+
* tongueroo/hi:ufo-2016-10-15T19-29-06-88071f5
|
48
|
+
|
49
|
+
* tongueroo/hi:ufo-2016-10-16T19-29-06-88071f5
|
50
|
+
|
51
|
+
* tongueroo/hi:ufo-2016-10-17T19-29-06-88071f5
|
52
|
+
|
53
|
+
* tongueroo/hi:ufo-2016-10-18T19-29-06-88071f5
|
54
|
+
|
55
|
+
To clean them up and keep the 3 more recent:
|
56
|
+
|
57
|
+
$ ufo docker cleanup tongueroo/hi
|
58
|
+
|
59
|
+
This will remove tongueroo/hi:ufo-2016-10-15T19-29-06-88071f5.
|
60
|
+
EOL
|
61
|
+
end
|
62
|
+
|
63
|
+
extend self
|
64
|
+
end
|
65
|
+
end
|
data/lib/ufo/dsl.rb
CHANGED
@@ -25,7 +25,37 @@ module Ufo
|
|
25
25
|
# of this class.
|
26
26
|
def evaluate_template_definitions
|
27
27
|
source_code = IO.read(@template_definitions_path)
|
28
|
-
|
28
|
+
begin
|
29
|
+
instance_eval(source_code, @template_definitions_path)
|
30
|
+
rescue Exception => e
|
31
|
+
task_definition_error(e)
|
32
|
+
puts "\nFull error:"
|
33
|
+
raise
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Prints out a user friendly task_definition error message
|
38
|
+
def task_definition_error(e)
|
39
|
+
error_info = e.backtrace.first
|
40
|
+
path, line_no, _ = error_info.split(':')
|
41
|
+
line_no = line_no.to_i
|
42
|
+
puts "Error evaluating #{path}:".colorize(:red)
|
43
|
+
puts e.message
|
44
|
+
puts "Here's the line in #{path} with the error:\n\n"
|
45
|
+
|
46
|
+
contents = IO.read(path)
|
47
|
+
content_lines = contents.split("\n")
|
48
|
+
context = 5 # lines of context
|
49
|
+
top, bottom = [line_no-context-1, 0].max, line_no+context-1
|
50
|
+
spacing = content_lines.size.to_s.size
|
51
|
+
content_lines[top..bottom].each_with_index do |line_content, index|
|
52
|
+
line_number = top+index+1
|
53
|
+
if line_number == line_no
|
54
|
+
printf("%#{spacing}d %s\n".colorize(:red), line_number, line_content)
|
55
|
+
else
|
56
|
+
printf("%#{spacing}d %s\n", line_number, line_content)
|
57
|
+
end
|
58
|
+
end
|
29
59
|
end
|
30
60
|
|
31
61
|
def build_task_definitions
|
data/lib/ufo/dsl/helper.rb
CHANGED
data/lib/ufo/ecr.rb
ADDED
@@ -4,7 +4,7 @@ require "json"
|
|
4
4
|
#
|
5
5
|
# ufo ship app-web --cluster prod --noop
|
6
6
|
module Ufo
|
7
|
-
class
|
7
|
+
class Ecr::Cleaner
|
8
8
|
include AwsServices
|
9
9
|
include Defaults
|
10
10
|
|
@@ -50,7 +50,7 @@ module Ufo
|
|
50
50
|
|
51
51
|
def update_auth_token
|
52
52
|
repo_domain = "https://#{@docker_image_name.split('/').first}"
|
53
|
-
auth =
|
53
|
+
auth = Ecr::Auth.new(repo_domain)
|
54
54
|
auth.update
|
55
55
|
end
|
56
56
|
|
data/lib/ufo/init.rb
CHANGED
@@ -21,7 +21,7 @@ module Ufo
|
|
21
21
|
dest = src.gsub(%r{.*starter_project/},'')
|
22
22
|
dest = "#{@project_root}/#{dest}"
|
23
23
|
|
24
|
-
if File.exist?(dest) and !@options[:
|
24
|
+
if File.exist?(dest) and !@options[:sure]
|
25
25
|
puts "exists: #{dest}".yellow unless @options[:quiet]
|
26
26
|
else
|
27
27
|
dirname = File.dirname(dest)
|
data/lib/ufo/ship.rb
CHANGED
@@ -24,9 +24,8 @@ module Ufo
|
|
24
24
|
class Ship
|
25
25
|
include Defaults
|
26
26
|
include AwsServices
|
27
|
-
include
|
27
|
+
include Util
|
28
28
|
|
29
|
-
# service can be a pattern
|
30
29
|
def initialize(service, task_definition, options={})
|
31
30
|
@service = service
|
32
31
|
@task_definition = task_definition
|
@@ -51,7 +50,15 @@ module Ufo
|
|
51
50
|
# Example:
|
52
51
|
# No way to map: hi-.*-prod -> hi-web-prod hi-worker-prod hi-clock-prod
|
53
52
|
def deploy
|
54
|
-
|
53
|
+
message = "Shipping #{@service}..."
|
54
|
+
unless @options[:mute]
|
55
|
+
if @options[:noop]
|
56
|
+
puts "NOOP: #{message}"
|
57
|
+
return
|
58
|
+
else
|
59
|
+
puts message.green
|
60
|
+
end
|
61
|
+
end
|
55
62
|
|
56
63
|
ensure_cluster_exist
|
57
64
|
process_single_service
|
@@ -333,8 +340,8 @@ module Ufo
|
|
333
340
|
task_definition_path = "ufo/output/#{task_definition}.json"
|
334
341
|
task_definition_full_path = "#{@project_root}/#{task_definition_path}"
|
335
342
|
unless File.exist?(task_definition_full_path)
|
336
|
-
puts "ERROR: Unable to find the task definition at #{task_definition_path}."
|
337
|
-
puts "Are you sure you have defined it in ufo/template_definitions.rb?"
|
343
|
+
puts "ERROR: Unable to find the task definition at #{task_definition_path}.".colorize(:red)
|
344
|
+
puts "Are you sure you have defined it in ufo/template_definitions.rb?".colorize(:red)
|
338
345
|
exit
|
339
346
|
end
|
340
347
|
task_definition = JSON.load(IO.read(task_definition_full_path))
|
data/lib/ufo/tasks.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Ufo
|
2
|
+
class Tasks < Command
|
3
|
+
autoload :Help, 'ufo/tasks/help'
|
4
|
+
autoload :Builder, 'ufo/tasks/builder'
|
5
|
+
autoload :Register, 'ufo/tasks/register'
|
6
|
+
|
7
|
+
desc "build", "builds task definitions"
|
8
|
+
long_desc Help.build
|
9
|
+
option :pretty, type: :boolean, default: true, desc: "Pretty format the json for the task definitions"
|
10
|
+
def build
|
11
|
+
Tasks::Builder.new(options).build
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "register", "register all built task definitions in ufo/output"
|
15
|
+
long_desc Help.register
|
16
|
+
def register
|
17
|
+
Tasks::Register.register(:all, options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,7 +1,16 @@
|
|
1
1
|
module Ufo
|
2
|
-
|
2
|
+
class Tasks::Builder
|
3
|
+
# build and registers together
|
4
|
+
def self.register(task_definition, options)
|
5
|
+
# task definition and deploy logic are coupled in the Ship class.
|
6
|
+
# Example: We need to know if the task defintion is a web service to see if we need to
|
7
|
+
# add the elb target group. The web service information is in the Tasks::Builder
|
8
|
+
# and the elb target group gets set in the Ship class.
|
9
|
+
# So we always call these together.
|
10
|
+
Tasks::Builder.new(options).build
|
11
|
+
Tasks::Register.register(task_definition, options)
|
12
|
+
end
|
3
13
|
|
4
|
-
class TasksBuilder
|
5
14
|
def initialize(options={})
|
6
15
|
@options = options
|
7
16
|
@project_root = options[:project_root] || '.'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Ufo
|
2
|
+
module Tasks::Help
|
3
|
+
def build
|
4
|
+
<<-EOL
|
5
|
+
Examples:
|
6
|
+
|
7
|
+
$ ufo tasks build
|
8
|
+
|
9
|
+
Builds all the task defintiions.
|
10
|
+
|
11
|
+
Note all the existing ufo/output generated task defintions are wiped out.
|
12
|
+
EOL
|
13
|
+
end
|
14
|
+
|
15
|
+
def register
|
16
|
+
<<-EOL
|
17
|
+
Examples:
|
18
|
+
|
19
|
+
$ ufo tasks register
|
20
|
+
All the task defintiions in ufo/output registered.
|
21
|
+
EOL
|
22
|
+
end
|
23
|
+
|
24
|
+
extend self
|
25
|
+
end
|
26
|
+
end
|
@@ -2,14 +2,14 @@ require 'plissken' # Hash#to_snake_keys
|
|
2
2
|
require 'json'
|
3
3
|
|
4
4
|
module Ufo
|
5
|
-
class
|
5
|
+
class Tasks::Register
|
6
6
|
include AwsServices
|
7
7
|
|
8
8
|
def self.register(task_name, options={})
|
9
9
|
project_root = options[:project_root] || '.'
|
10
10
|
Dir.glob("#{project_root}/ufo/output/*").each do |path|
|
11
11
|
if task_name == :all or path.include?(task_name)
|
12
|
-
task_register =
|
12
|
+
task_register = Tasks::Register.new(path, options)
|
13
13
|
task_register.register
|
14
14
|
end
|
15
15
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Ufo
|
2
|
-
module
|
2
|
+
module Util
|
3
3
|
def execute(command, local_options={})
|
4
4
|
command = "cd #{@project_root} && #{command}"
|
5
5
|
# local_options[:live] overrides the global @options[:noop]
|
@@ -15,5 +15,16 @@ module Ufo
|
|
15
15
|
end
|
16
16
|
result
|
17
17
|
end
|
18
|
+
|
19
|
+
# http://stackoverflow.com/questions/4175733/convert-duration-to-hoursminutesseconds-or-similar-in-rails-3-or-ruby
|
20
|
+
def pretty_time(total_seconds)
|
21
|
+
minutes = (total_seconds / 60) % 60
|
22
|
+
seconds = total_seconds % 60
|
23
|
+
if total_seconds < 60
|
24
|
+
"#{seconds.to_i}s"
|
25
|
+
else
|
26
|
+
"#{minutes.to_i}m #{seconds.to_i}s"
|
27
|
+
end
|
28
|
+
end
|
18
29
|
end
|
19
30
|
end
|
data/lib/ufo/version.rb
CHANGED
data/spec/lib/cli_spec.rb
CHANGED
@@ -47,6 +47,16 @@ describe Ufo::CLI do
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
+
context "ships" do
|
51
|
+
it "deploys software to multiple services" do
|
52
|
+
out = execute("bin/ufo ships hi-web-prod hi-worker-prod #{@args} --no-wait")
|
53
|
+
# cannot look for Software shipped! because
|
54
|
+
# ship.deploy unless ENV['TEST'] # to allow me to quickly test CLI portion only
|
55
|
+
# just testing the CLI portion. The ship class itself is tested via ship_spec.rb
|
56
|
+
expect(out).to include("Task Definitions built")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
50
60
|
context "task" do
|
51
61
|
it "runs one time task" do
|
52
62
|
out = execute("bin/ufo task hi-migrate-prod #{@args}")
|
data/spec/lib/ecr_auth_spec.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Ufo::
|
3
|
+
describe Ufo::Ecr::Auth do
|
4
4
|
let(:repo_domain) { "https://123456789.dkr.ecr.us-east-1.amazonaws.com" }
|
5
|
-
let(:auth) { Ufo::
|
5
|
+
let(:auth) { Ufo::Ecr::Auth.new(repo_domain) }
|
6
6
|
before(:each) do
|
7
7
|
allow(auth).to receive(:fetch_auth_token).and_return("opensesame")
|
8
8
|
end
|
@@ -10,7 +10,6 @@ describe Ufo::EcrAuth do
|
|
10
10
|
context("update") do
|
11
11
|
before(:each) do
|
12
12
|
clean_home
|
13
|
-
ENV['HOME'] = "spec/fixtures/home"
|
14
13
|
end
|
15
14
|
|
16
15
|
context("missing ~/.docker/config.json") do
|
@@ -24,7 +23,6 @@ describe Ufo::EcrAuth do
|
|
24
23
|
|
25
24
|
context("existing ~/.docker/config.json") do
|
26
25
|
it "should update the auth token" do
|
27
|
-
FileUtils.cp_r("spec/fixtures/home_existing", "spec/fixtures/home")
|
28
26
|
auth.update
|
29
27
|
data = JSON.load(IO.read("spec/fixtures/home/.docker/config.json"))
|
30
28
|
auth_token = data["auths"][repo_domain]["auth"]
|
@@ -35,5 +33,6 @@ describe Ufo::EcrAuth do
|
|
35
33
|
|
36
34
|
def clean_home
|
37
35
|
FileUtils.rm_rf("spec/fixtures/home")
|
36
|
+
FileUtils.cp_r("spec/fixtures/home_existing", "spec/fixtures/home")
|
38
37
|
end
|
39
38
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Ufo::
|
3
|
+
describe Ufo::Ecr::Cleaner do
|
4
4
|
let(:docker_image_name) { "123456789.dkr.ecr.us-east-1.amazonaws.com/my-name" }
|
5
5
|
let(:repo_domain) { "https://123456789.dkr.ecr.us-east-1.amazonaws.com" }
|
6
6
|
let(:cleaner) do
|
7
|
-
Ufo::
|
7
|
+
Ufo::Ecr::Cleaner.new(docker_image_name,
|
8
8
|
project_root: "spec/fixtures/hi",
|
9
9
|
ecr_keep: 3, # using 3 to test, default is 30
|
10
10
|
mute: true
|
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: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tung Nguyen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-06-
|
11
|
+
date: 2017-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -181,26 +181,31 @@ files:
|
|
181
181
|
- lib/ufo/command.rb
|
182
182
|
- lib/ufo/defaults.rb
|
183
183
|
- lib/ufo/destroy.rb
|
184
|
-
- lib/ufo/
|
185
|
-
- lib/ufo/
|
186
|
-
- lib/ufo/
|
184
|
+
- lib/ufo/docker.rb
|
185
|
+
- lib/ufo/docker/builder.rb
|
186
|
+
- lib/ufo/docker/cleaner.rb
|
187
|
+
- lib/ufo/docker/dockerfile.rb
|
188
|
+
- lib/ufo/docker/help.rb
|
187
189
|
- lib/ufo/dsl.rb
|
188
190
|
- lib/ufo/dsl/helper.rb
|
189
191
|
- lib/ufo/dsl/outputter.rb
|
190
192
|
- lib/ufo/dsl/task_definition.rb
|
191
|
-
- lib/ufo/
|
192
|
-
- lib/ufo/
|
193
|
-
- lib/ufo/
|
193
|
+
- lib/ufo/ecr.rb
|
194
|
+
- lib/ufo/ecr/auth.rb
|
195
|
+
- lib/ufo/ecr/cleaner.rb
|
194
196
|
- lib/ufo/init.rb
|
195
|
-
- lib/ufo/pretty_time.rb
|
196
197
|
- lib/ufo/scale.rb
|
197
198
|
- lib/ufo/settings.rb
|
198
199
|
- lib/ufo/ship.rb
|
199
200
|
- lib/ufo/task.rb
|
200
|
-
- lib/ufo/
|
201
|
-
- lib/ufo/
|
201
|
+
- lib/ufo/tasks.rb
|
202
|
+
- lib/ufo/tasks/builder.rb
|
203
|
+
- lib/ufo/tasks/help.rb
|
204
|
+
- lib/ufo/tasks/register.rb
|
202
205
|
- lib/ufo/templates/default.json.erb
|
206
|
+
- lib/ufo/util.rb
|
203
207
|
- lib/ufo/version.rb
|
208
|
+
- spec/fixtures/home_existing/.aws/config
|
204
209
|
- spec/fixtures/home_existing/.docker/config.json
|
205
210
|
- spec/lib/cli_spec.rb
|
206
211
|
- spec/lib/ecr_auth_spec.rb
|
@@ -234,6 +239,7 @@ signing_key:
|
|
234
239
|
specification_version: 4
|
235
240
|
summary: Build Docker Containers and Ship Them to AWS ECS
|
236
241
|
test_files:
|
242
|
+
- spec/fixtures/home_existing/.aws/config
|
237
243
|
- spec/fixtures/home_existing/.docker/config.json
|
238
244
|
- spec/lib/cli_spec.rb
|
239
245
|
- spec/lib/ecr_auth_spec.rb
|
data/lib/ufo/pretty_time.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
module Ufo
|
2
|
-
module PrettyTime
|
3
|
-
# http://stackoverflow.com/questions/4175733/convert-duration-to-hoursminutesseconds-or-similar-in-rails-3-or-ruby
|
4
|
-
def pretty_time(total_seconds)
|
5
|
-
minutes = (total_seconds / 60) % 60
|
6
|
-
seconds = total_seconds % 60
|
7
|
-
if total_seconds < 60
|
8
|
-
"#{seconds.to_i}s"
|
9
|
-
else
|
10
|
-
"#{minutes.to_i}m #{seconds.to_i}s"
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|