hako 0.18.1 → 0.19.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 +4 -4
- data/.rubocop.yml +3 -0
- data/examples/hello-autoscaling-group.yml +14 -0
- data/lib/hako/env_expander.rb +1 -1
- data/lib/hako/schedulers/ecs.rb +76 -1
- data/lib/hako/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45f04940c4d0ff4ff960ea9619a525085aba342d
|
4
|
+
data.tar.gz: 67610aa17c6877ed84599ecd1be143c4c39d6a03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 92407332bca376bcba4e54248842d685568410cf92c4cb19aa7be30d1353a266e549db55da77b3f12c1cc7b5161a78de6edc0e0fc33a2f322822bb937870dbd2
|
7
|
+
data.tar.gz: 2599f5133827e410fb4cc2d068fe7fc09e52b654022f140549ab34abc620cade3bc111dae8c8bb861ec60c89768dc9e6e57eb13b89b8dc929dc50e8a0746d7e9
|
data/.rubocop.yml
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
scheduler:
|
2
|
+
type: ecs
|
3
|
+
region: ap-northeast-1
|
4
|
+
cluster: eagletmt
|
5
|
+
role: ecsServiceRole
|
6
|
+
autoscaling_group_for_oneshot: hako-batch-cluster
|
7
|
+
app:
|
8
|
+
image: ryotarai/hello-sinatra
|
9
|
+
memory: 128
|
10
|
+
cpu: 256
|
11
|
+
env:
|
12
|
+
PORT: 3000
|
13
|
+
MESSAGE: 'hello'
|
14
|
+
command: ['echo', 'heavy offline job']
|
data/lib/hako/env_expander.rb
CHANGED
@@ -43,7 +43,7 @@ module Hako
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
unless variables.empty?
|
46
|
-
raise ExpansionError.new("
|
46
|
+
raise ExpansionError.new("Could not resolve embedded variables from $providers=#{@providers}: #{variables.to_a}")
|
47
47
|
end
|
48
48
|
|
49
49
|
expanded_env = {}
|
data/lib/hako/schedulers/ecs.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'aws-sdk'
|
3
3
|
require 'hako'
|
4
|
+
require 'hako/error'
|
4
5
|
require 'hako/scheduler'
|
5
6
|
require 'hako/schedulers/ecs_definition_comparator'
|
6
7
|
require 'hako/schedulers/ecs_elb'
|
@@ -9,6 +10,9 @@ require 'hako/schedulers/ecs_autoscaling'
|
|
9
10
|
module Hako
|
10
11
|
module Schedulers
|
11
12
|
class Ecs < Scheduler
|
13
|
+
class NoTasksStarted < Error
|
14
|
+
end
|
15
|
+
|
12
16
|
DEFAULT_CLUSTER = 'default'
|
13
17
|
DEFAULT_FRONT_PORT = 10000
|
14
18
|
|
@@ -27,6 +31,7 @@ module Hako
|
|
27
31
|
end
|
28
32
|
@started_at = nil
|
29
33
|
@container_instance_arn = nil
|
34
|
+
@autoscaling_group_for_oneshot = options.fetch('autoscaling_group_for_oneshot', nil)
|
30
35
|
end
|
31
36
|
|
32
37
|
# @param [Hash<String, Container>] containers
|
@@ -450,9 +455,21 @@ module Hako
|
|
450
455
|
Hako.logger.error("#{failure.arn} #{failure.reason}")
|
451
456
|
end
|
452
457
|
if result.tasks.empty?
|
453
|
-
raise 'No tasks started'
|
458
|
+
raise NoTasksStarted.new('No tasks started')
|
454
459
|
end
|
455
460
|
result.tasks[0]
|
461
|
+
rescue Aws::ECS::Errors::InvalidParameterException => e
|
462
|
+
if e.message == 'No Container Instances were found in your cluster.' && on_no_tasks_started(task_definition)
|
463
|
+
retry
|
464
|
+
else
|
465
|
+
raise e
|
466
|
+
end
|
467
|
+
rescue NoTasksStarted => e
|
468
|
+
if on_no_tasks_started(task_definition)
|
469
|
+
retry
|
470
|
+
else
|
471
|
+
raise e
|
472
|
+
end
|
456
473
|
end
|
457
474
|
|
458
475
|
# @return [Fixnum]
|
@@ -643,6 +660,64 @@ module Hako
|
|
643
660
|
|
644
661
|
raise "Unable to find rollback target. #{task_definition.task_definition_arn} is INACTIVE?"
|
645
662
|
end
|
663
|
+
|
664
|
+
# @param [Aws::ECS::Types::TaskDefinition] task_definition
|
665
|
+
# @return [Boolean] true if the capacity is reserved
|
666
|
+
def on_no_tasks_started(task_definition)
|
667
|
+
unless @autoscaling_group_for_oneshot
|
668
|
+
return false
|
669
|
+
end
|
670
|
+
|
671
|
+
autoscaling = Aws::AutoScaling::Client.new
|
672
|
+
loop do
|
673
|
+
asg = autoscaling.describe_auto_scaling_groups(auto_scaling_group_names: [@autoscaling_group_for_oneshot]).auto_scaling_groups[0]
|
674
|
+
unless asg
|
675
|
+
raise Error.new("AutoScaling Group '#{@autoscaling_group_for_oneshot}' does not exist")
|
676
|
+
end
|
677
|
+
|
678
|
+
container_instances = ecs_client.list_container_instances(cluster: @cluster).flat_map { |c| ecs_client.describe_container_instances(cluster: @cluster, container_instances: c.container_instance_arns).container_instances }
|
679
|
+
if has_capacity?(task_definition, container_instances)
|
680
|
+
Hako.logger.info("There's remaining capacity. Start retrying...")
|
681
|
+
return true
|
682
|
+
end
|
683
|
+
|
684
|
+
# Check autoscaling group health
|
685
|
+
current = asg.instances.count { |i| i.lifecycle_state == 'InService' }
|
686
|
+
if asg.desired_capacity != current
|
687
|
+
Hako.logger.debug("#{asg.auto_scaling_group_name} isn't in desired state. desired_capacity=#{asg.desired_capacity} in-service instances=#{current}")
|
688
|
+
sleep 1
|
689
|
+
next
|
690
|
+
end
|
691
|
+
|
692
|
+
# Check out-of-service instances
|
693
|
+
out_instances = asg.instances.map(&:instance_id)
|
694
|
+
container_instances.each do |ci|
|
695
|
+
out_instances.delete(ci.ec2_instance_id)
|
696
|
+
end
|
697
|
+
unless out_instances.empty?
|
698
|
+
Hako.logger.debug("There's instances that is running but not registered as container instances: #{out_instances}")
|
699
|
+
sleep 1
|
700
|
+
next
|
701
|
+
end
|
702
|
+
|
703
|
+
# Scale out
|
704
|
+
desired = current + 1
|
705
|
+
Hako.logger.info("Increment desired_capacity of #{asg.auto_scaling_group_name} from #{current} to #{desired}")
|
706
|
+
autoscaling.set_desired_capacity(auto_scaling_group_name: asg.auto_scaling_group_name, desired_capacity: desired)
|
707
|
+
end
|
708
|
+
end
|
709
|
+
|
710
|
+
# @param [Aws::ECS::Types::TaskDefinition] task_definition
|
711
|
+
# @param [Array<Aws::ECS::Types::ContainerInstance>] container_instances
|
712
|
+
# @return [Boolean]
|
713
|
+
def has_capacity?(task_definition, container_instances)
|
714
|
+
required_cpu, required_memory = task_definition.container_definitions.inject([0, 0]) { |(cpu, memory), d| [cpu + d.cpu, memory + d.memory] }
|
715
|
+
container_instances.any? do |ci|
|
716
|
+
cpu = ci.remaining_resources.find { |r| r.name == 'CPU' }.integer_value
|
717
|
+
memory = ci.remaining_resources.find { |r| r.name == 'MEMORY' }.integer_value
|
718
|
+
required_cpu < cpu && required_memory < memory
|
719
|
+
end
|
720
|
+
end
|
646
721
|
end
|
647
722
|
end
|
648
723
|
end
|
data/lib/hako/version.rb
CHANGED
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.19.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-08-
|
11
|
+
date: 2016-08-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|
@@ -114,6 +114,7 @@ files:
|
|
114
114
|
- bin/console
|
115
115
|
- bin/setup
|
116
116
|
- examples/front.yml
|
117
|
+
- examples/hello-autoscaling-group.yml
|
117
118
|
- examples/hello-autoscaling.yml
|
118
119
|
- examples/hello-lb.yml
|
119
120
|
- examples/hello.env
|