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 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: {}