hako 0.22.0 → 0.23.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: f7e905ba26a5f96fbc2aa0e452d7802a6253b293
4
- data.tar.gz: eb043950033d3d9367cbfcc57704238fd9a0f645
3
+ metadata.gz: 23c0c6350f347bcf8bc3a4462c6284e2d3135f22
4
+ data.tar.gz: 9ddd98e7ce10875ac654fcc2c425de3264d392e4
5
5
  SHA512:
6
- metadata.gz: 2b259b71edbdfe3fa4e29894cfcb3d70a4cbbb316943701a511083a065d172398bd29846e1b06d437c315c81a56328631598894bee4abfbfccdf20a4036d544f
7
- data.tar.gz: 8b7d739da8bbefb071376e82fec854b96e1b093bf4b24acdec4289e1e364a72c5a666467f8917cf886752be77b28bd7988301889d3cc28441cf40c6bb58f82fe
6
+ metadata.gz: 1597dd9361d1ec0fbee733dc89f18a1856a0c49527a0b5b55a5982c31520c9d9483ba42fcbb36df9dbf3a81789d32c2336cf3e0f38dd7bf4c670b39dc7582821
7
+ data.tar.gz: a0dba22ad43958e5092b3a130fcb5a53d01328418feec37d57edbeef41b95f2350fe8577e1789d30c6a58dcfda8bdedc0a23de0ea66b0525a5f898763c22becc
data/lib/hako/cli.rb CHANGED
@@ -65,14 +65,17 @@ module Hako
65
65
  Hako.logger.level = Logger::DEBUG
66
66
  end
67
67
 
68
- Commander.new(Application.new(@yaml_path)).deploy(force: @force, tag: @tag, dry_run: @dry_run)
68
+ Commander.new(Application.new(@yaml_path)).deploy(force: @force, tag: @tag, dry_run: @dry_run, timeout: @timeout)
69
69
  end
70
70
 
71
+ DEFAULT_TIMEOUT = 1200 # 20 minutes
72
+
71
73
  def parse!(argv)
72
74
  @force = false
73
75
  @tag = 'latest'
74
76
  @dry_run = false
75
77
  @verbose = false
78
+ @timeout = DEFAULT_TIMEOUT
76
79
  parser.parse!(argv)
77
80
  @yaml_path = argv.first
78
81
 
@@ -90,6 +93,7 @@ module Hako
90
93
  opts.on('-t', '--tag=TAG', 'Specify tag (default: latest)') { |v| @tag = v }
91
94
  opts.on('-n', '--dry-run', 'Enable dry-run mode') { @dry_run = true }
92
95
  opts.on('-v', '--verbose', 'Enable verbose logging') { @verbose = true }
96
+ opts.on('--timeout=TIMEOUT_SEC', "Timeout deployment after TIMEOUT_SEC seconds (default: #{DEFAULT_TIMEOUT})") { |v| @timeout = v.to_i }
93
97
  end
94
98
  end
95
99
  end
@@ -17,11 +17,11 @@ module Hako
17
17
  # @param [String] tag
18
18
  # @param [Boolean] dry_run
19
19
  # @return [nil]
20
- def deploy(force: false, tag: 'latest', dry_run: false)
20
+ def deploy(force: false, tag: 'latest', dry_run: false, timeout:)
21
21
  containers = load_containers(tag, dry_run: dry_run)
22
22
  scripts = @app.yaml.fetch('scripts', []).map { |config| load_script(config, dry_run: dry_run) }
23
23
  volumes = @app.yaml.fetch('volumes', [])
24
- scheduler = load_scheduler(@app.yaml['scheduler'], scripts, volumes: volumes, force: force, dry_run: dry_run)
24
+ scheduler = load_scheduler(@app.yaml['scheduler'], scripts, volumes: volumes, force: force, dry_run: dry_run, timeout: timeout)
25
25
 
26
26
  scripts.each { |script| script.deploy_starting(containers) }
27
27
  scheduler.deploy(containers)
@@ -118,9 +118,10 @@ module Hako
118
118
  # @param [Hash] volumes
119
119
  # @param [Boolean] force
120
120
  # @param [Boolean] dry_run
121
+ # @param [Integer] timeout
121
122
  # @return [Scheduler]
122
- def load_scheduler(yaml, scripts, volumes: [], force: false, dry_run:)
123
- Loader.new(Hako::Schedulers, 'hako/schedulers').load(yaml.fetch('type')).new(@app.id, yaml, volumes: volumes, scripts: scripts, force: force, dry_run: dry_run)
123
+ def load_scheduler(yaml, scripts, volumes: [], force: false, dry_run:, timeout: nil)
124
+ Loader.new(Hako::Schedulers, 'hako/schedulers').load(yaml.fetch('type')).new(@app.id, yaml, volumes: volumes, scripts: scripts, force: force, dry_run: dry_run, timeout: timeout)
124
125
  end
125
126
 
126
127
  # @param [Hash] yaml
@@ -12,12 +12,14 @@ module Hako
12
12
  # @param [Array<Script>] scripts
13
13
  # @param [Boolean] dry_run
14
14
  # @param [Boolean] force
15
- def initialize(app_id, options, volumes:, scripts:, dry_run:, force:)
15
+ # @param [Integer] timeout in seconds
16
+ def initialize(app_id, options, volumes:, scripts:, dry_run:, force:, timeout:)
16
17
  @app_id = app_id
17
18
  @volumes = volumes
18
19
  @scripts = scripts
19
20
  @dry_run = dry_run
20
21
  @force = force
22
+ @timeout = timeout
21
23
  configure(options)
22
24
  end
23
25
 
@@ -64,25 +64,38 @@ module Hako
64
64
  @autoscaling.apply(Aws::ECS::Types::Service.new(cluster_arn: @cluster, service_name: @app_id))
65
65
  end
66
66
  else
67
+ current_service = describe_service
67
68
  task_definition = register_task_definition(definitions)
68
- if task_definition == :noop
69
+ task_definition_changed = task_definition != :noop
70
+ if task_definition_changed
71
+ Hako.logger.info "Registered task definition: #{task_definition.task_definition_arn}"
72
+ else
69
73
  Hako.logger.info "Task definition isn't changed"
70
74
  task_definition = ecs_client.describe_task_definition(task_definition: @app_id).task_definition
71
- else
72
- Hako.logger.info "Registered task definition: #{task_definition.task_definition_arn}"
73
75
  end
74
- service = create_or_update_service(task_definition.task_definition_arn, front_port)
76
+ unless current_service
77
+ current_service = create_initial_service(task_definition.task_definition_arn, front_port)
78
+ end
79
+ service = update_service(current_service, task_definition.task_definition_arn)
75
80
  if service == :noop
76
81
  Hako.logger.info "Service isn't changed"
77
82
  if @autoscaling
78
- @autoscaling.apply(describe_service)
83
+ @autoscaling.apply(current_service)
79
84
  end
80
85
  else
81
86
  Hako.logger.info "Updated service: #{service.service_arn}"
82
87
  if @autoscaling
83
88
  @autoscaling.apply(service)
84
89
  end
85
- wait_for_ready(service)
90
+ unless wait_for_ready(service)
91
+ if task_definition_changed
92
+ Hako.logger.error("Rolling back to #{current_service.task_definition}")
93
+ update_service(service, current_service.task_definition)
94
+ ecs_client.deregister_task_definition(task_definition: service.task_definition)
95
+ Hako.logger.debug "Deregistered #{service.task_definition}"
96
+ end
97
+ raise Error.new('Deployment cancelled')
98
+ end
86
99
  end
87
100
  Hako.logger.info 'Deployment completed'
88
101
  end
@@ -569,44 +582,46 @@ module Hako
569
582
  Hako.logger.info "Container instance is #{container_instance_arn} (#{container_instance.ec2_instance_id})"
570
583
  end
571
584
 
585
+ # @param [Aws::ECS::Types::Service] task_definition_arn
572
586
  # @param [String] task_definition_arn
573
- # @param [Fixnum] front_port
574
587
  # @return [Aws::ECS::Types::Service, Symbol]
575
- def create_or_update_service(task_definition_arn, front_port)
576
- service = describe_service
577
- if service.nil?
578
- params = {
579
- cluster: @cluster,
580
- service_name: @app_id,
581
- task_definition: task_definition_arn,
582
- desired_count: @desired_count,
583
- role: @role,
584
- deployment_configuration: @deployment_configuration,
585
- }
586
- if ecs_elb_client.find_or_create_load_balancer(front_port)
587
- params[:load_balancers] = [
588
- @ecs_elb_client.load_balancer_params_for_service.merge(container_name: 'front', container_port: 80),
589
- ]
590
- end
591
- ecs_client.create_service(params).service
588
+ def update_service(current_service, task_definition_arn)
589
+ params = {
590
+ cluster: @cluster,
591
+ service: @app_id,
592
+ desired_count: @desired_count,
593
+ task_definition: task_definition_arn,
594
+ deployment_configuration: @deployment_configuration,
595
+ }
596
+ if @autoscaling
597
+ # Keep current desired_count if autoscaling is enabled
598
+ params[:desired_count] = current_service.desired_count
599
+ end
600
+ if service_changed?(current_service, params)
601
+ ecs_client.update_service(params).service
592
602
  else
593
- params = {
594
- cluster: @cluster,
595
- service: @app_id,
596
- desired_count: @desired_count,
597
- task_definition: task_definition_arn,
598
- deployment_configuration: @deployment_configuration,
599
- }
600
- if @autoscaling
601
- # Keep current desired_count if autoscaling is enabled
602
- params[:desired_count] = service.desired_count
603
- end
604
- if service_changed?(service, params)
605
- ecs_client.update_service(params).service
606
- else
607
- :noop
608
- end
603
+ :noop
604
+ end
605
+ end
606
+
607
+ # @param [String] task_definition_arn
608
+ # @param [Fixnum] front_port
609
+ # @return [Aws::ECS::Types::Service]
610
+ def create_initial_service(task_definition_arn, front_port)
611
+ params = {
612
+ cluster: @cluster,
613
+ service_name: @app_id,
614
+ task_definition: task_definition_arn,
615
+ desired_count: 0,
616
+ role: @role,
617
+ deployment_configuration: @deployment_configuration,
618
+ }
619
+ if ecs_elb_client.find_or_create_load_balancer(front_port)
620
+ params[:load_balancers] = [
621
+ @ecs_elb_client.load_balancer_params_for_service.merge(container_name: 'front', container_port: 80),
622
+ ]
609
623
  end
624
+ ecs_client.create_service(params).service
610
625
  end
611
626
 
612
627
  # @param [Aws::ECS::Types::Service] service
@@ -617,11 +632,23 @@ module Hako
617
632
  end
618
633
 
619
634
  # @param [Aws::ECS::Types::Service] service
620
- # @return [nil]
635
+ # @return [Boolean]
621
636
  def wait_for_ready(service)
622
637
  latest_event_id = find_latest_event_id(service.events)
623
638
  Hako.logger.debug " latest_event_id=#{latest_event_id}"
639
+ started_at =
640
+ if @timeout
641
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
642
+ end
643
+
624
644
  loop do
645
+ if started_at
646
+ if Process.clock_gettime(Process::CLOCK_MONOTONIC) - started_at > @timeout
647
+ Hako.logger.error('Timed out')
648
+ return false
649
+ end
650
+ end
651
+
625
652
  s = ecs_client.describe_services(cluster: service.cluster_arn, services: [service.service_arn]).services[0]
626
653
  if s.nil?
627
654
  Hako.logger.debug "Service #{service.service_arn} could not be described"
@@ -640,7 +667,7 @@ module Hako
640
667
  primary = s.deployments.find { |d| d.status == 'PRIMARY' }
641
668
  primary_ready = primary && primary.running_count == primary.desired_count
642
669
  if no_active && primary_ready
643
- return
670
+ return true
644
671
  else
645
672
  sleep 1
646
673
  end
data/lib/hako/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Hako
3
- VERSION = '0.22.0'
3
+ VERSION = '0.23.0'
4
4
  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.22.0
4
+ version: 0.23.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-12-06 00:00:00.000000000 Z
11
+ date: 2016-12-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk