hako 0.4.0 → 0.5.0
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/examples/hello-lb.yml +13 -10
- data/examples/hello.yml +13 -10
- data/lib/hako/app_container.rb +13 -0
- data/lib/hako/commander.rb +11 -45
- data/lib/hako/container.rb +22 -0
- data/lib/hako/front.rb +36 -4
- data/lib/hako/fronts/nginx.rb +2 -2
- data/lib/hako/loader.rb +19 -0
- data/lib/hako/scheduler.rb +2 -2
- data/lib/hako/schedulers/ecs.rb +21 -28
- data/lib/hako/version.rb +1 -1
- metadata +4 -3
- data/lib/hako/front_config.rb +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6faa5dea73adc01c789baffd7ecf6823bb86a77f
|
4
|
+
data.tar.gz: 38c6d1baa569e5b4872762b5e6a6fd2e28e11a00
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d090b3321ef8fb21bdc24ff19079e30915b067e3555025c9f83ce3dd0377e002c48318bfa525896e92b1c0a16b2bbf404eb3fd3e99b0d62d233afc770943327d
|
7
|
+
data.tar.gz: 4bc41461ca3a40958699833cd99d9b5c0d5108c6e01255a9769919f55520ef4baef4aee2a5a6d86a9b78d4e140356f3df61fa0d480c62562d787697d9d745732
|
data/examples/hello-lb.yml
CHANGED
@@ -1,16 +1,6 @@
|
|
1
|
-
image: ryotarai/hello-sinatra
|
2
|
-
env:
|
3
|
-
$providers:
|
4
|
-
- type: file
|
5
|
-
path: examples/hello.env
|
6
|
-
PORT: 3000
|
7
|
-
MESSAGE: '#{username}-san'
|
8
|
-
port: 3000
|
9
1
|
scheduler:
|
10
2
|
type: ecs
|
11
3
|
region: ap-northeast-1
|
12
|
-
memory: 100
|
13
|
-
cpu: 100
|
14
4
|
cluster: eagletmt
|
15
5
|
desired_count: 2
|
16
6
|
role: ecsServiceRole
|
@@ -23,9 +13,22 @@ scheduler:
|
|
23
13
|
- subnet-YYYYYYYY
|
24
14
|
security_groups:
|
25
15
|
- sg-ZZZZZZZZ
|
16
|
+
app:
|
17
|
+
image: ryotarai/hello-sinatra
|
18
|
+
memory: 100
|
19
|
+
cpu: 100
|
20
|
+
port: 3000
|
21
|
+
env:
|
22
|
+
$providers:
|
23
|
+
- type: file
|
24
|
+
path: examples/hello.env
|
25
|
+
PORT: 3000
|
26
|
+
MESSAGE: '#{username}-san'
|
26
27
|
front:
|
27
28
|
type: nginx
|
28
29
|
image_tag: hako-nginx
|
30
|
+
memory: 100
|
31
|
+
cpu: 100
|
29
32
|
s3:
|
30
33
|
region: ap-northeast-1
|
31
34
|
bucket: nanika
|
data/examples/hello.yml
CHANGED
@@ -1,21 +1,24 @@
|
|
1
|
-
image: ryotarai/hello-sinatra
|
2
|
-
env:
|
3
|
-
$providers:
|
4
|
-
- type: file
|
5
|
-
path: hello.env
|
6
|
-
PORT: 3000
|
7
|
-
MESSAGE: '#{username}-san'
|
8
|
-
port: 3000
|
9
1
|
scheduler:
|
10
2
|
type: ecs
|
11
3
|
region: ap-northeast-1
|
12
|
-
memory: 100
|
13
|
-
cpu: 100
|
14
4
|
cluster: eagletmt
|
15
5
|
desired_count: 2
|
6
|
+
app:
|
7
|
+
image: ryotarai/hello-sinatra
|
8
|
+
memory: 100
|
9
|
+
cpu: 100
|
10
|
+
port: 3000
|
11
|
+
env:
|
12
|
+
$providers:
|
13
|
+
- type: file
|
14
|
+
path: hello.env
|
15
|
+
PORT: 3000
|
16
|
+
MESSAGE: '#{username}-san'
|
16
17
|
front:
|
17
18
|
type: nginx
|
18
19
|
image_tag: hako-nginx
|
20
|
+
memory: 100
|
21
|
+
cpu: 100
|
19
22
|
s3:
|
20
23
|
region: ap-northeast-1
|
21
24
|
bucket: nanika
|
data/lib/hako/commander.rb
CHANGED
@@ -1,43 +1,33 @@
|
|
1
|
-
require 'hako/
|
1
|
+
require 'hako/app_container'
|
2
2
|
require 'hako/env_expander'
|
3
3
|
require 'hako/error'
|
4
|
-
require 'hako/front_config'
|
5
4
|
require 'hako/fronts'
|
5
|
+
require 'hako/loader'
|
6
6
|
require 'hako/schedulers'
|
7
7
|
require 'hako/scripts'
|
8
8
|
|
9
9
|
module Hako
|
10
10
|
class Commander
|
11
|
-
PROVIDERS_KEY = '$providers'.freeze
|
12
|
-
|
13
11
|
def initialize(app)
|
14
12
|
@app = app
|
15
13
|
end
|
16
14
|
|
17
15
|
def deploy(force: false, tag: 'latest')
|
18
|
-
|
16
|
+
app = AppContainer.new(@app.yaml['app'].merge('tag' => tag))
|
19
17
|
front = load_front(@app.yaml['front'])
|
20
18
|
scheduler = load_scheduler(@app.yaml['scheduler'])
|
21
|
-
app_port = @app.yaml.fetch('port', nil)
|
22
|
-
image = @app.yaml.fetch('image') { raise Error.new('image must be set') }
|
23
|
-
app = Container.new(
|
24
|
-
'image_tag' => "#{image}:#{tag}",
|
25
|
-
'docker_labels' => @app.yaml.fetch('docker_labels', {}),
|
26
|
-
)
|
27
19
|
scripts = @app.yaml.fetch('scripts', []).map { |config| load_script(config) }
|
28
20
|
|
29
21
|
containers = { 'app' => app, 'front' => front }
|
30
22
|
scripts.each { |script| script.before_deploy(containers) }
|
31
|
-
scheduler.deploy(containers,
|
23
|
+
scheduler.deploy(containers, force: force)
|
32
24
|
scripts.each { |script| script.after_deploy(containers) }
|
33
25
|
end
|
34
26
|
|
35
27
|
def oneshot(commands, tag: 'latest')
|
36
|
-
|
28
|
+
app = AppContainer.new(@app.yaml['app'].merge('tag' => tag))
|
37
29
|
scheduler = load_scheduler(@app.yaml['scheduler'])
|
38
|
-
|
39
|
-
image_tag = "#{image}:#{tag}"
|
40
|
-
exit scheduler.oneshot(Container.new('image_tag' => image_tag), env, commands)
|
30
|
+
exit scheduler.oneshot(app, commands)
|
41
31
|
end
|
42
32
|
|
43
33
|
def status
|
@@ -58,40 +48,16 @@ module Hako
|
|
58
48
|
EnvExpander.new(providers).expand(env)
|
59
49
|
end
|
60
50
|
|
61
|
-
def
|
62
|
-
|
63
|
-
type = config['type']
|
64
|
-
unless type
|
65
|
-
raise Error.new("type must be set in each #{PROVIDERS_KEY} element")
|
66
|
-
end
|
67
|
-
require "hako/env_providers/#{type}"
|
68
|
-
Hako::EnvProviders.const_get(camelize(type)).new(@app.root_path, config)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def load_scheduler(scheduler_config)
|
73
|
-
type = scheduler_config['type']
|
74
|
-
unless type
|
75
|
-
raise Error.new('type must be set in scheduler')
|
76
|
-
end
|
77
|
-
require "hako/schedulers/#{type}"
|
78
|
-
Hako::Schedulers.const_get(camelize(type)).new(@app.id, scheduler_config)
|
51
|
+
def load_scheduler(yaml)
|
52
|
+
Loader.new(Hako::Schedulers, 'hako/schedulers').load(yaml.fetch('type')).new(@app.id, yaml)
|
79
53
|
end
|
80
54
|
|
81
55
|
def load_front(yaml)
|
82
|
-
|
83
|
-
require "hako/fronts/#{front_config.type}"
|
84
|
-
Hako::Fronts.const_get(camelize(front_config.type)).new(front_config)
|
85
|
-
end
|
86
|
-
|
87
|
-
def load_script(config)
|
88
|
-
type = config.fetch('type')
|
89
|
-
require "hako/scripts/#{type}"
|
90
|
-
Hako::Scripts.const_get(camelize(type)).new(@app, config)
|
56
|
+
Loader.new(Hako::Fronts, 'hako/fronts').load(yaml.fetch('type')).new(@app.id, yaml)
|
91
57
|
end
|
92
58
|
|
93
|
-
def
|
94
|
-
|
59
|
+
def load_script(yaml)
|
60
|
+
Loader.new(Hako::Scripts, 'hako/scripts').load(yaml.fetch('type')).new(@app, yaml)
|
95
61
|
end
|
96
62
|
end
|
97
63
|
end
|
data/lib/hako/container.rb
CHANGED
@@ -11,6 +11,8 @@ module Hako
|
|
11
11
|
%w[
|
12
12
|
image_tag
|
13
13
|
docker_labels
|
14
|
+
cpu
|
15
|
+
memory
|
14
16
|
].each do |name|
|
15
17
|
define_method(name) do
|
16
18
|
@definition[name]
|
@@ -20,5 +22,25 @@ module Hako
|
|
20
22
|
@definition[name] = val
|
21
23
|
end
|
22
24
|
end
|
25
|
+
|
26
|
+
def env
|
27
|
+
@expanded_env ||= expand_env(@definition.fetch('env', {}))
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
PROVIDERS_KEY = '$providers'.freeze
|
33
|
+
|
34
|
+
def expand_env(env)
|
35
|
+
env = env.dup
|
36
|
+
providers = load_providers(env.delete(PROVIDERS_KEY) || [])
|
37
|
+
EnvExpander.new(providers).expand(env)
|
38
|
+
end
|
39
|
+
|
40
|
+
def load_providers(provider_configs)
|
41
|
+
provider_configs.map do |yaml|
|
42
|
+
Loader.new(Hako::EnvProviders, 'hako/env_providers').load(yaml.fetch('type')).new(@app.root_path, yaml)
|
43
|
+
end
|
44
|
+
end
|
23
45
|
end
|
24
46
|
end
|
data/lib/hako/front.rb
CHANGED
@@ -1,9 +1,41 @@
|
|
1
|
+
require 'hako/container'
|
2
|
+
|
1
3
|
module Hako
|
2
|
-
class Front
|
3
|
-
|
4
|
+
class Front < Container
|
5
|
+
S3Config = Struct.new(:region, :bucket, :prefix) do
|
6
|
+
def initialize(options)
|
7
|
+
self.region = options.fetch('region')
|
8
|
+
self.bucket = options.fetch('bucket')
|
9
|
+
self.prefix = options.fetch('prefix', nil)
|
10
|
+
end
|
11
|
+
|
12
|
+
def key(app_id)
|
13
|
+
if prefix
|
14
|
+
"#{prefix}/#{app_id}.conf"
|
15
|
+
else
|
16
|
+
"#{app_id}.conf"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :s3
|
22
|
+
|
23
|
+
def initialize(app_id, config)
|
24
|
+
super(config)
|
25
|
+
@app_id = app_id
|
26
|
+
@s3 = S3Config.new(@definition.fetch('s3'))
|
27
|
+
end
|
28
|
+
|
29
|
+
def env
|
30
|
+
super.merge(
|
31
|
+
'AWS_DEFAULT_REGION' => @s3.region,
|
32
|
+
'S3_CONFIG_BUCKET' => @s3.bucket,
|
33
|
+
'S3_CONFIG_KEY' => @s3.key(@app_id),
|
34
|
+
)
|
35
|
+
end
|
4
36
|
|
5
|
-
def
|
6
|
-
@
|
37
|
+
def extra
|
38
|
+
@definition.fetch('extra', {})
|
7
39
|
end
|
8
40
|
|
9
41
|
def generate_config(_app_port)
|
data/lib/hako/fronts/nginx.rb
CHANGED
@@ -24,7 +24,7 @@ module Hako
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def locations
|
27
|
-
locs =
|
27
|
+
locs = extra.fetch('locations', {}).dup
|
28
28
|
locs['/'] ||= {}
|
29
29
|
locs.keys.each do |k|
|
30
30
|
locs[k] = Location.new(locs[k])
|
@@ -33,7 +33,7 @@ module Hako
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def client_max_body_size
|
36
|
-
|
36
|
+
extra.fetch('client_max_body_size', nil)
|
37
37
|
end
|
38
38
|
|
39
39
|
def render_location(listen_spec, location)
|
data/lib/hako/loader.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Hako
|
2
|
+
class Loader
|
3
|
+
def initialize(base_module, base_path)
|
4
|
+
@base_module = base_module
|
5
|
+
@base_path = base_path
|
6
|
+
end
|
7
|
+
|
8
|
+
def load(name)
|
9
|
+
require "#{@base_path}/#{name}"
|
10
|
+
@base_module.const_get(camelize(name))
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def camelize(name)
|
16
|
+
name.split('_').map(&:capitalize).join('')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/hako/scheduler.rb
CHANGED
@@ -8,7 +8,7 @@ module Hako
|
|
8
8
|
def initialize(_app_id, _options)
|
9
9
|
end
|
10
10
|
|
11
|
-
def deploy(_containers,
|
11
|
+
def deploy(_containers, _options)
|
12
12
|
raise NotImplementedError
|
13
13
|
end
|
14
14
|
|
@@ -22,7 +22,7 @@ module Hako
|
|
22
22
|
|
23
23
|
def upload_front_config(app_id, front, app_port)
|
24
24
|
front_conf = front.generate_config(app_port)
|
25
|
-
s3_config = front.
|
25
|
+
s3_config = front.s3
|
26
26
|
s3 = Aws::S3::Client.new(region: s3_config.region)
|
27
27
|
s3.put_object(
|
28
28
|
body: front_conf,
|
data/lib/hako/schedulers/ecs.rb
CHANGED
@@ -14,8 +14,6 @@ module Hako
|
|
14
14
|
@app_id = app_id
|
15
15
|
@cluster = options.fetch('cluster', DEFAULT_CLUSTER)
|
16
16
|
@desired_count = options.fetch('desired_count') { validation_error!('desired_count must be set') }
|
17
|
-
@cpu = options.fetch('cpu') { validation_error!('cpu must be set') }
|
18
|
-
@memory = options.fetch('memory') { validation_error!('memory must be set') }
|
19
17
|
region = options.fetch('region') { validation_error!('region must be set') }
|
20
18
|
@role = options.fetch('role', nil)
|
21
19
|
@ecs = Aws::ECS::Client.new(region: region)
|
@@ -23,24 +21,19 @@ module Hako
|
|
23
21
|
@ec2 = Aws::EC2::Client.new(region: region)
|
24
22
|
end
|
25
23
|
|
26
|
-
def deploy(containers,
|
24
|
+
def deploy(containers, force: false)
|
27
25
|
@force_mode = force
|
28
26
|
app = containers.fetch('app')
|
29
27
|
front = containers.fetch('front')
|
30
|
-
front_env = {
|
31
|
-
'AWS_DEFAULT_REGION' => front.config.s3.region,
|
32
|
-
'S3_CONFIG_BUCKET' => front.config.s3.bucket,
|
33
|
-
'S3_CONFIG_KEY' => front.config.s3.key(@app_id),
|
34
|
-
}
|
35
28
|
front_port = determine_front_port
|
36
|
-
task_definition = register_task_definition(
|
29
|
+
task_definition = register_task_definition(containers, front_port)
|
37
30
|
if task_definition == :noop
|
38
31
|
Hako.logger.info "Task definition isn't changed"
|
39
32
|
task_definition = @ecs.describe_task_definition(task_definition: @app_id).task_definition
|
40
33
|
else
|
41
34
|
Hako.logger.info "Registered task definition: #{task_definition.task_definition_arn}"
|
42
|
-
upload_front_config(@app_id, front,
|
43
|
-
Hako.logger.info "Uploaded front configuration to s3://#{front.
|
35
|
+
upload_front_config(@app_id, front, app.port)
|
36
|
+
Hako.logger.info "Uploaded front configuration to s3://#{front.s3.bucket}/#{front.s3.key(@app_id)}"
|
44
37
|
end
|
45
38
|
service = create_or_update_service(task_definition.task_definition_arn, front_port)
|
46
39
|
if service == :noop
|
@@ -52,10 +45,10 @@ module Hako
|
|
52
45
|
Hako.logger.info 'Deployment completed'
|
53
46
|
end
|
54
47
|
|
55
|
-
def oneshot(app,
|
48
|
+
def oneshot(app, commands)
|
56
49
|
task_definition = register_task_definition_for_oneshot(app)
|
57
50
|
Hako.logger.info "Registered task definition: #{task_definition.task_definition_arn}"
|
58
|
-
task = run_task(task_definition, env, commands)
|
51
|
+
task = run_task(task_definition, app.env, commands)
|
59
52
|
Hako.logger.info "Started task: #{task.task_arn}"
|
60
53
|
exit_code = wait_for_task(task)
|
61
54
|
Hako.logger.info 'Oneshot task finished'
|
@@ -197,9 +190,9 @@ module Hako
|
|
197
190
|
EcsDefinitionComparator.new(expected_container).different?(actual_container)
|
198
191
|
end
|
199
192
|
|
200
|
-
def register_task_definition(
|
201
|
-
front_def = front_container(
|
202
|
-
app_def = app_container(app
|
193
|
+
def register_task_definition(containers, front_port)
|
194
|
+
front_def = front_container(containers.fetch('front'), front_port)
|
195
|
+
app_def = app_container(containers.fetch('app'))
|
203
196
|
if task_definition_changed?(front_def, app_def)
|
204
197
|
@ecs.register_task_definition(
|
205
198
|
family: @app_id,
|
@@ -217,8 +210,8 @@ module Hako
|
|
217
210
|
{
|
218
211
|
name: 'oneshot',
|
219
212
|
image: app.image_tag,
|
220
|
-
cpu:
|
221
|
-
memory:
|
213
|
+
cpu: app.cpu,
|
214
|
+
memory: app.memory,
|
222
215
|
links: [],
|
223
216
|
port_mappings: [],
|
224
217
|
environment: [],
|
@@ -227,28 +220,28 @@ module Hako
|
|
227
220
|
).task_definition
|
228
221
|
end
|
229
222
|
|
230
|
-
def front_container(
|
231
|
-
environment = env.map { |k, v| { name: k, value: v } }
|
223
|
+
def front_container(front, front_port)
|
224
|
+
environment = front.env.map { |k, v| { name: k, value: v } }
|
232
225
|
{
|
233
226
|
name: 'front',
|
234
|
-
image:
|
235
|
-
cpu:
|
236
|
-
memory:
|
227
|
+
image: front.image_tag,
|
228
|
+
cpu: front.cpu,
|
229
|
+
memory: front.memory,
|
237
230
|
links: ['app:app'],
|
238
231
|
port_mappings: [{ container_port: 80, host_port: front_port, protocol: 'tcp' }],
|
239
232
|
essential: true,
|
240
233
|
environment: environment,
|
241
|
-
docker_labels:
|
234
|
+
docker_labels: front.docker_labels,
|
242
235
|
}
|
243
236
|
end
|
244
237
|
|
245
|
-
def app_container(app
|
246
|
-
environment = env.map { |k, v| { name: k, value: v } }
|
238
|
+
def app_container(app)
|
239
|
+
environment = app.env.map { |k, v| { name: k, value: v } }
|
247
240
|
{
|
248
241
|
name: 'app',
|
249
242
|
image: app.image_tag,
|
250
|
-
cpu:
|
251
|
-
memory:
|
243
|
+
cpu: app.cpu,
|
244
|
+
memory: app.memory,
|
252
245
|
links: [],
|
253
246
|
port_mappings: [],
|
254
247
|
essential: true,
|
data/lib/hako/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hako
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kohei Suzuki
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-02-
|
11
|
+
date: 2016-02-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|
@@ -118,6 +118,7 @@ files:
|
|
118
118
|
- exe/hako
|
119
119
|
- hako.gemspec
|
120
120
|
- lib/hako.rb
|
121
|
+
- lib/hako/app_container.rb
|
121
122
|
- lib/hako/application.rb
|
122
123
|
- lib/hako/cli.rb
|
123
124
|
- lib/hako/commander.rb
|
@@ -128,9 +129,9 @@ files:
|
|
128
129
|
- lib/hako/env_providers/file.rb
|
129
130
|
- lib/hako/error.rb
|
130
131
|
- lib/hako/front.rb
|
131
|
-
- lib/hako/front_config.rb
|
132
132
|
- lib/hako/fronts.rb
|
133
133
|
- lib/hako/fronts/nginx.rb
|
134
|
+
- lib/hako/loader.rb
|
134
135
|
- lib/hako/scheduler.rb
|
135
136
|
- lib/hako/schedulers.rb
|
136
137
|
- lib/hako/schedulers/echo.rb
|
data/lib/hako/front_config.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
require 'erb'
|
2
|
-
require 'hako/container'
|
3
|
-
|
4
|
-
module Hako
|
5
|
-
FrontConfig = Struct.new(:type, :container, :s3, :extra)
|
6
|
-
class FrontConfig
|
7
|
-
S3Config = Struct.new(:region, :bucket, :prefix) do
|
8
|
-
def initialize(options)
|
9
|
-
self.region = options.fetch('region')
|
10
|
-
self.bucket = options.fetch('bucket')
|
11
|
-
self.prefix = options.fetch('prefix', nil)
|
12
|
-
end
|
13
|
-
|
14
|
-
def key(app_id)
|
15
|
-
if prefix
|
16
|
-
"#{prefix}/#{app_id}.conf"
|
17
|
-
else
|
18
|
-
"#{app_id}.conf"
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def initialize(options)
|
24
|
-
self.type = options.fetch('type')
|
25
|
-
self.container = Container.new(
|
26
|
-
'image_tag' => options.fetch('image_tag'),
|
27
|
-
)
|
28
|
-
self.s3 = S3Config.new(options.fetch('s3'))
|
29
|
-
self.extra = options.fetch('extra', {})
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|