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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: aa60150931b4feefab4ad228b97c82d3ba55ae15
4
- data.tar.gz: 7acd8ff5d8d24a8582ec86191f96b2b1c01c3b59
3
+ metadata.gz: fae55ff67c1a85f1505702a1264c3e9b4db5731c
4
+ data.tar.gz: 7daf5a6420831633edb17698ebd3ce2973fa8ca2
5
5
  SHA512:
6
- metadata.gz: 0cd2ecd94673857ac68323b2b2250f25587560d66873eea56fb926ac92496fd431fe342702f972cf44f31e7efb7119ef3f28f4328f5b06eea40766c999ae7ddc
7
- data.tar.gz: 1e77d755d310a60c7fb8981de62026ff805cad5b43f44b019052f8832dc280788548a777d6a709033b5af80827e6b6626b1575205f4b5e1283cdac7360565ae7
6
+ metadata.gz: 6c78607e33a941e24056c06a2ca6dd155c54a66e7c90ff53fae76cb2eb4f7d4d0fe9af6c603fd5279a3c03a3cda70efd8d8d276392ccec12131d738e5a3044cd
7
+ data.tar.gz: b54c0b53e8ded575e36558e56205829e80441a7dea61b44f8d3db33e297d06e5bea2848f9f39d6a690622053ae487f6585592d8dfef649a7f2cdc6d05e41a5d2
@@ -2,6 +2,7 @@ inherit_from: .rubocop_todo.yml
2
2
 
3
3
  AllCops:
4
4
  DisplayCopNames: true
5
+ TargetRubyVersion: 2.2 # TODO: Upgrade to 2.3
5
6
 
6
7
  Style/GuardClause:
7
8
  Enabled: false
@@ -1,8 +1,9 @@
1
1
  language: ruby
2
2
  sudo: false
3
3
  rvm:
4
- - 2.1
5
- - 2.2
4
+ - 2.1.8
5
+ - 2.2.4
6
+ - 2.3.0
6
7
  - ruby-head
7
8
  before_install:
8
9
  - gem install bundler
@@ -0,0 +1,8 @@
1
+ type: nginx
2
+ image_tag: hako-nginx
3
+ memory: 32
4
+ cpu: 32
5
+ s3:
6
+ region: ap-northeast-1
7
+ bucket: nanika
8
+ prefix: hako/front_config
@@ -25,14 +25,7 @@ app:
25
25
  PORT: 3000
26
26
  MESSAGE: '#{username}-san'
27
27
  front:
28
- type: nginx
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
  /:
@@ -17,14 +17,7 @@ app:
17
17
  PORT: 3000
18
18
  MESSAGE: '#{username}-san'
19
19
  front:
20
- type: nginx
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
@@ -1,4 +1,4 @@
1
- require 'yaml'
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 = YAML.load(load_default_yaml(@root_path) + path.read)
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
@@ -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'
@@ -13,18 +13,13 @@ module Hako
13
13
  @app = app
14
14
  end
15
15
 
16
- def deploy(force: false, tag: 'latest')
17
- app = AppContainer.new(@app, @app.yaml['app'].merge('tag' => tag))
18
- front = load_front(@app.yaml['front'])
19
- scheduler = load_scheduler(@app.yaml['scheduler'])
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, force: force)
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 load_environment(env)
50
- env = env.dup
51
- providers = load_providers(env.delete(PROVIDERS_KEY) || [])
52
- EnvExpander.new(providers).expand(env)
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
@@ -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
- providers = load_providers(env.delete(PROVIDERS_KEY) || [])
35
- EnvExpander.new(providers).expand(env)
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)
@@ -20,8 +20,8 @@ module Hako
20
20
 
21
21
  attr_reader :s3
22
22
 
23
- def initialize(app, config)
24
- super(app, config)
23
+ def initialize(*)
24
+ super
25
25
  @s3 = S3Config.new(@definition.fetch('s3'))
26
26
  end
27
27
 
@@ -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, force: false)
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
- task_definition = register_task_definition(containers, front_port)
30
- if task_definition == :noop
31
- Hako.logger.info "Task definition isn't changed"
32
- task_definition = @ecs.describe_task_definition(task_definition: @app_id).task_definition
33
- else
34
- Hako.logger.info "Registered task definition: #{task_definition.task_definition_arn}"
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
- Hako.logger.info "Updated service: #{service.service_arn}"
43
- wait_for_ready(service)
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 @force_mode
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(containers, front_port)
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",
@@ -1,3 +1,3 @@
1
1
  module Hako
2
- VERSION = '0.6.1'.freeze
2
+ VERSION = '0.7.0'.freeze
3
3
  end
@@ -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.6.1
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-22 00:00:00.000000000 Z
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: {}