hako 0.6.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: {}
|