hako 0.22.0 → 0.23.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: 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