hako 0.6.1 → 0.7.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/.rubocop.yml +1 -0
- data/.travis.yml +3 -2
- data/examples/front.yml +8 -0
- data/examples/hello-lb.yml +1 -8
- data/examples/hello.yml +1 -8
- data/lib/hako/application.rb +2 -10
- data/lib/hako/cli.rb +2 -1
- data/lib/hako/commander.rb +21 -21
- data/lib/hako/container.rb +9 -3
- data/lib/hako/front.rb +2 -2
- data/lib/hako/schedulers/ecs.rb +40 -28
- data/lib/hako/version.rb +1 -1
- data/lib/hako/yaml_loader.rb +41 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fae55ff67c1a85f1505702a1264c3e9b4db5731c
|
4
|
+
data.tar.gz: 7daf5a6420831633edb17698ebd3ce2973fa8ca2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c78607e33a941e24056c06a2ca6dd155c54a66e7c90ff53fae76cb2eb4f7d4d0fe9af6c603fd5279a3c03a3cda70efd8d8d276392ccec12131d738e5a3044cd
|
7
|
+
data.tar.gz: b54c0b53e8ded575e36558e56205829e80441a7dea61b44f8d3db33e297d06e5bea2848f9f39d6a690622053ae487f6585592d8dfef649a7f2cdc6d05e41a5d2
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
data/examples/front.yml
ADDED
data/examples/hello-lb.yml
CHANGED
@@ -25,14 +25,7 @@ app:
|
|
25
25
|
PORT: 3000
|
26
26
|
MESSAGE: '#{username}-san'
|
27
27
|
front:
|
28
|
-
|
29
|
-
image_tag: hako-nginx
|
30
|
-
memory: 32
|
31
|
-
cpu: 32
|
32
|
-
s3:
|
33
|
-
region: ap-northeast-1
|
34
|
-
bucket: nanika
|
35
|
-
prefix: hako/front_config
|
28
|
+
<<: !include front.yml
|
36
29
|
extra:
|
37
30
|
locations:
|
38
31
|
/:
|
data/examples/hello.yml
CHANGED
@@ -17,14 +17,7 @@ app:
|
|
17
17
|
PORT: 3000
|
18
18
|
MESSAGE: '#{username}-san'
|
19
19
|
front:
|
20
|
-
|
21
|
-
image_tag: hako-nginx
|
22
|
-
memory: 32
|
23
|
-
cpu: 32
|
24
|
-
s3:
|
25
|
-
region: ap-northeast-1
|
26
|
-
bucket: nanika
|
27
|
-
prefix: hako/front_config
|
20
|
+
!include front.yml
|
28
21
|
additional_containers:
|
29
22
|
redis:
|
30
23
|
image_tag: redis:3.0
|
data/lib/hako/application.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'hako/yaml_loader'
|
2
2
|
|
3
3
|
module Hako
|
4
4
|
class Application
|
@@ -8,15 +8,7 @@ module Hako
|
|
8
8
|
path = Pathname.new(yaml_path)
|
9
9
|
@id = path.basename.sub_ext('').to_s
|
10
10
|
@root_path = path.parent
|
11
|
-
@yaml =
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def load_default_yaml(root_path)
|
17
|
-
root_path.join('default.yml').read
|
18
|
-
rescue Errno::ENOENT
|
19
|
-
''
|
11
|
+
@yaml = YamlLoader.load(path)
|
20
12
|
end
|
21
13
|
end
|
22
14
|
end
|
data/lib/hako/cli.rb
CHANGED
@@ -5,10 +5,11 @@ module Hako
|
|
5
5
|
desc 'deploy FILE', 'Run deployment'
|
6
6
|
option :force, aliases: %w[-f], type: :boolean, default: false, desc: 'Run deployment even if nothing is changed'
|
7
7
|
option :tag, aliases: %w[-t], type: :string, default: 'latest', desc: 'Specify tag (default: latest)'
|
8
|
+
option :dry_run, aliases: %w[-n], type: :boolean, default: false, desc: 'Enable dry-run mode'
|
8
9
|
def deploy(yaml_path)
|
9
10
|
require 'hako/application'
|
10
11
|
require 'hako/commander'
|
11
|
-
Commander.new(Application.new(yaml_path)).deploy(force: options[:force], tag: options[:tag])
|
12
|
+
Commander.new(Application.new(yaml_path)).deploy(force: options[:force], tag: options[:tag], dry_run: options[:dry_run])
|
12
13
|
end
|
13
14
|
|
14
15
|
desc 'oneshot FILE COMMAND ARG...', 'Run oneshot task'
|
data/lib/hako/commander.rb
CHANGED
@@ -13,18 +13,13 @@ module Hako
|
|
13
13
|
@app = app
|
14
14
|
end
|
15
15
|
|
16
|
-
def deploy(force: false, tag: 'latest')
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
scripts = @app.yaml.fetch('scripts', []).map { |config| load_script(config) }
|
16
|
+
def deploy(force: false, tag: 'latest', dry_run: false)
|
17
|
+
containers = load_containers(tag, dry_run: dry_run)
|
18
|
+
scheduler = load_scheduler(@app.yaml['scheduler'], force: force, dry_run: dry_run)
|
19
|
+
scripts = @app.yaml.fetch('scripts', []).map { |config| load_script(config, dry_run: dry_run) }
|
21
20
|
|
22
|
-
containers = { 'app' => app, 'front' => front }
|
23
|
-
@app.yaml.fetch('additional_containers', {}).each do |name, container|
|
24
|
-
containers[name] = Container.new(@app, container)
|
25
|
-
end
|
26
21
|
scripts.each { |script| script.before_deploy(containers) }
|
27
|
-
scheduler.deploy(containers
|
22
|
+
scheduler.deploy(containers)
|
28
23
|
scripts.each { |script| script.after_deploy(containers) }
|
29
24
|
end
|
30
25
|
|
@@ -39,29 +34,34 @@ module Hako
|
|
39
34
|
end
|
40
35
|
|
41
36
|
def remove
|
42
|
-
scripts = @app.yaml.fetch('scripts', []).map { |config| load_script(config) }
|
37
|
+
scripts = @app.yaml.fetch('scripts', []).map { |config| load_script(config, dry_run: dry_run) }
|
43
38
|
load_scheduler(@app.yaml['scheduler']).remove
|
44
39
|
scripts.each(&:after_remove)
|
45
40
|
end
|
46
41
|
|
47
42
|
private
|
48
43
|
|
49
|
-
def
|
50
|
-
|
51
|
-
|
52
|
-
|
44
|
+
def load_containers(tag, dry_run:)
|
45
|
+
app = AppContainer.new(@app, @app.yaml['app'].merge('tag' => tag), dry_run: dry_run)
|
46
|
+
front = load_front(@app.yaml['front'], dry_run: dry_run)
|
47
|
+
|
48
|
+
containers = { 'app' => app, 'front' => front }
|
49
|
+
@app.yaml.fetch('additional_containers', {}).each do |name, container|
|
50
|
+
containers[name] = Container.new(@app, container, dry_run: dry_run)
|
51
|
+
end
|
52
|
+
containers
|
53
53
|
end
|
54
54
|
|
55
|
-
def load_scheduler(yaml)
|
56
|
-
Loader.new(Hako::Schedulers, 'hako/schedulers').load(yaml.fetch('type')).new(@app.id, yaml)
|
55
|
+
def load_scheduler(yaml, force: false, dry_run: false)
|
56
|
+
Loader.new(Hako::Schedulers, 'hako/schedulers').load(yaml.fetch('type')).new(@app.id, yaml, force: force, dry_run: dry_run)
|
57
57
|
end
|
58
58
|
|
59
|
-
def load_front(yaml)
|
60
|
-
Loader.new(Hako::Fronts, 'hako/fronts').load(yaml.fetch('type')).new(@app, yaml)
|
59
|
+
def load_front(yaml, dry_run:)
|
60
|
+
Loader.new(Hako::Fronts, 'hako/fronts').load(yaml.fetch('type')).new(@app, yaml, dry_run: dry_run)
|
61
61
|
end
|
62
62
|
|
63
|
-
def load_script(yaml)
|
64
|
-
Loader.new(Hako::Scripts, 'hako/scripts').load(yaml.fetch('type')).new(@app, yaml)
|
63
|
+
def load_script(yaml, dry_run:)
|
64
|
+
Loader.new(Hako::Scripts, 'hako/scripts').load(yaml.fetch('type')).new(@app, yaml, dry_run: dry_run)
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
data/lib/hako/container.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
module Hako
|
2
2
|
class Container
|
3
|
-
def initialize(app, definition)
|
3
|
+
def initialize(app, definition, dry_run:)
|
4
4
|
@app = app
|
5
5
|
@definition = default_config.merge(definition)
|
6
|
+
@dry_run = dry_run
|
6
7
|
end
|
7
8
|
|
8
9
|
%w[
|
@@ -31,8 +32,13 @@ module Hako
|
|
31
32
|
|
32
33
|
def expand_env(env)
|
33
34
|
env = env.dup
|
34
|
-
|
35
|
-
|
35
|
+
provider_types = env.delete(PROVIDERS_KEY) || []
|
36
|
+
if @dry_run
|
37
|
+
env
|
38
|
+
else
|
39
|
+
providers = load_providers(provider_types)
|
40
|
+
EnvExpander.new(providers).expand(env)
|
41
|
+
end
|
36
42
|
end
|
37
43
|
|
38
44
|
def load_providers(provider_configs)
|
data/lib/hako/front.rb
CHANGED
data/lib/hako/schedulers/ecs.rb
CHANGED
@@ -10,7 +10,7 @@ module Hako
|
|
10
10
|
DEFAULT_CLUSTER = 'default'.freeze
|
11
11
|
DEFAULT_FRONT_PORT = 10000
|
12
12
|
|
13
|
-
def initialize(app_id, options)
|
13
|
+
def initialize(app_id, options, force:, dry_run:)
|
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') }
|
@@ -19,30 +19,39 @@ module Hako
|
|
19
19
|
@ecs = Aws::ECS::Client.new(region: region)
|
20
20
|
@elb = EcsElb.new(app_id, Aws::ElasticLoadBalancing::Client.new(region: region), options.fetch('elb', nil))
|
21
21
|
@ec2 = Aws::EC2::Client.new(region: region)
|
22
|
+
@force = force
|
23
|
+
@dry_run = dry_run
|
22
24
|
end
|
23
25
|
|
24
|
-
def deploy(containers
|
25
|
-
@force_mode = force
|
26
|
+
def deploy(containers)
|
26
27
|
app = containers.fetch('app')
|
27
28
|
front = containers.fetch('front')
|
28
29
|
front_port = determine_front_port
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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)}"
|
37
|
-
end
|
38
|
-
service = create_or_update_service(task_definition.task_definition_arn, front_port)
|
39
|
-
if service == :noop
|
40
|
-
Hako.logger.info "Service isn't changed"
|
30
|
+
definitions = create_definitions(containers, front_port)
|
31
|
+
|
32
|
+
if @dry_run
|
33
|
+
definitions.each do |d|
|
34
|
+
Hako.logger.info "Add container #{d}"
|
35
|
+
end
|
41
36
|
else
|
42
|
-
|
43
|
-
|
37
|
+
task_definition = register_task_definition(definitions)
|
38
|
+
if task_definition == :noop
|
39
|
+
Hako.logger.info "Task definition isn't changed"
|
40
|
+
task_definition = @ecs.describe_task_definition(task_definition: @app_id).task_definition
|
41
|
+
else
|
42
|
+
Hako.logger.info "Registered task definition: #{task_definition.task_definition_arn}"
|
43
|
+
upload_front_config(@app_id, front, app.port)
|
44
|
+
Hako.logger.info "Uploaded front configuration to s3://#{front.s3.bucket}/#{front.s3.key(@app_id)}"
|
45
|
+
end
|
46
|
+
service = create_or_update_service(task_definition.task_definition_arn, front_port)
|
47
|
+
if service == :noop
|
48
|
+
Hako.logger.info "Service isn't changed"
|
49
|
+
else
|
50
|
+
Hako.logger.info "Updated service: #{service.service_arn}"
|
51
|
+
wait_for_ready(service)
|
52
|
+
end
|
53
|
+
Hako.logger.info 'Deployment completed'
|
44
54
|
end
|
45
|
-
Hako.logger.info 'Deployment completed'
|
46
55
|
end
|
47
56
|
|
48
57
|
def oneshot(app, commands)
|
@@ -172,7 +181,7 @@ module Hako
|
|
172
181
|
end
|
173
182
|
|
174
183
|
def task_definition_changed?(definitions)
|
175
|
-
if @
|
184
|
+
if @force
|
176
185
|
return true
|
177
186
|
end
|
178
187
|
task_definition = @ecs.describe_task_definition(task_definition: @app_id).task_definition
|
@@ -193,15 +202,7 @@ module Hako
|
|
193
202
|
EcsDefinitionComparator.new(expected_container).different?(actual_container)
|
194
203
|
end
|
195
204
|
|
196
|
-
def register_task_definition(
|
197
|
-
definitions = containers.map do |name, container|
|
198
|
-
case name
|
199
|
-
when 'front'
|
200
|
-
front_container(container, front_port)
|
201
|
-
else
|
202
|
-
app_container(name, container)
|
203
|
-
end
|
204
|
-
end
|
205
|
+
def register_task_definition(definitions)
|
205
206
|
if task_definition_changed?(definitions)
|
206
207
|
@ecs.register_task_definition(
|
207
208
|
family: @app_id,
|
@@ -212,6 +213,17 @@ module Hako
|
|
212
213
|
end
|
213
214
|
end
|
214
215
|
|
216
|
+
def create_definitions(containers, front_port)
|
217
|
+
containers.map do |name, container|
|
218
|
+
case name
|
219
|
+
when 'front'
|
220
|
+
front_container(container, front_port)
|
221
|
+
else
|
222
|
+
app_container(name, container)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
215
227
|
def register_task_definition_for_oneshot(app)
|
216
228
|
@ecs.register_task_definition(
|
217
229
|
family: "#{@app_id}-oneshot",
|
data/lib/hako/version.rb
CHANGED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'psych'
|
2
|
+
|
3
|
+
module Hako
|
4
|
+
module YamlLoader
|
5
|
+
class << self
|
6
|
+
def load(path)
|
7
|
+
class_loader = Psych::ClassLoader.new
|
8
|
+
scanner = Psych::ScalarScanner.new(class_loader)
|
9
|
+
prev_path = @current_path
|
10
|
+
@current_path = path
|
11
|
+
visitor = Visitor.new(scanner, class_loader) do |_, val|
|
12
|
+
load(@current_path.parent.join(val))
|
13
|
+
end
|
14
|
+
path.open do |f|
|
15
|
+
visitor.accept(Psych.parse(f))
|
16
|
+
end
|
17
|
+
ensure
|
18
|
+
@current_path = prev_path
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Visitor < Psych::Visitors::ToRuby
|
23
|
+
INCLUDE_TAG = 'tag:include'.freeze
|
24
|
+
SHOVEL = '<<'.freeze
|
25
|
+
|
26
|
+
def initialize(scanner, class_loader, &block)
|
27
|
+
super(scanner, class_loader)
|
28
|
+
@domain_types[INCLUDE_TAG] = [INCLUDE_TAG, block]
|
29
|
+
end
|
30
|
+
|
31
|
+
def revive_hash(hash, o)
|
32
|
+
super(hash, o).tap do |r|
|
33
|
+
if r[SHOVEL].is_a?(Hash)
|
34
|
+
h = r.delete(SHOVEL)
|
35
|
+
r.merge!(h)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
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.7.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-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|
@@ -112,6 +112,7 @@ files:
|
|
112
112
|
- Rakefile
|
113
113
|
- bin/console
|
114
114
|
- bin/setup
|
115
|
+
- examples/front.yml
|
115
116
|
- examples/hello-lb.yml
|
116
117
|
- examples/hello.env
|
117
118
|
- examples/hello.yml
|
@@ -142,6 +143,7 @@ files:
|
|
142
143
|
- lib/hako/templates/nginx.conf.erb
|
143
144
|
- lib/hako/templates/nginx.location.conf.erb
|
144
145
|
- lib/hako/version.rb
|
146
|
+
- lib/hako/yaml_loader.rb
|
145
147
|
homepage: https://github.com/eagletmt/hako
|
146
148
|
licenses: []
|
147
149
|
metadata: {}
|