rollo 0.6.0 → 0.8.0.pre.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'thor'
2
4
  require_relative '../model'
3
5
 
4
6
  module Rollo
5
7
  module Commands
8
+ # rubocop:disable Metrics/ClassLength
6
9
  class Services < Thor
7
10
  namespace :services
8
11
 
@@ -11,128 +14,160 @@ module Rollo
11
14
  end
12
15
 
13
16
  desc(
14
- 'expand REGION ASG_NAME ECS_CLUSTER_NAME',
15
- 'Expands the service cluster by one batch.')
17
+ 'expand REGION ASG_NAME ECS_CLUSTER_NAME',
18
+ 'Expands the service cluster by one batch.'
19
+ )
16
20
  method_option(
17
- :batch_size,
18
- aliases: '-b',
19
- type: :numeric,
20
- default: 3,
21
- desc: 'The number of service instances to add at a time.')
21
+ :batch_size,
22
+ aliases: '-b',
23
+ type: :numeric,
24
+ default: 3,
25
+ desc: 'The number of service instances to add at a time.'
26
+ )
22
27
  method_option(
23
- :startup_time,
24
- aliases: '-t',
25
- type: :numeric,
26
- default: 2,
27
- desc: 'The number of minutes to wait for services to start up.')
28
+ :startup_time,
29
+ aliases: '-t',
30
+ type: :numeric,
31
+ default: 2,
32
+ desc: 'The number of minutes to wait for services to start up.'
33
+ )
28
34
  method_option(
29
- :maximum_instances,
30
- aliases: '-mx',
31
- type: :numeric,
32
- desc: 'The maximum number of service instances to expand to.')
33
-
35
+ :maximum_instances,
36
+ aliases: '-mx',
37
+ type: :numeric,
38
+ desc: 'The maximum number of service instances to expand to.'
39
+ )
40
+ # rubocop:disable Metrics/AbcSize
41
+ # rubocop:disable Metrics/MethodLength
34
42
  def expand(
35
- region, _, ecs_cluster_name,
36
- service_cluster = nil)
43
+ region, _, ecs_cluster_name,
44
+ service_cluster = nil
45
+ )
37
46
  batch_size = options[:batch_size]
38
47
  maximum_instances = options[:maximum_instances]
39
48
  service_start_wait_minutes = options[:startup_time]
40
49
  service_start_wait_seconds = 60 * service_start_wait_minutes
41
50
 
42
- service_cluster = service_cluster ||
43
- Rollo::Model::ServiceCluster.new(ecs_cluster_name, region)
51
+ service_cluster ||= Rollo::Model::ServiceCluster.new(ecs_cluster_name,
52
+ region)
44
53
 
45
54
  say("Increasing service instance counts by #{batch_size}...")
55
+ # rubocop:disable Metrics/BlockLength
46
56
  with_padding do
47
57
  service_cluster.with_replica_services do |on|
48
58
  on.start do |services|
49
59
  say(
50
- 'Service cluster contains services:' +
51
- "\n\t\t[#{services.map(&:name).join(",\n\t\t ")}]")
60
+ 'Service cluster contains services:' \
61
+ "\n\t\t[#{services.map(&:name).join(",\n\t\t ")}]"
62
+ )
52
63
  end
53
64
  on.each_service do |service|
54
65
  say(
55
- "Increasing instance count by #{batch_size} " +
56
- "for #{service.name}")
66
+ "Increasing instance count by #{batch_size} " \
67
+ "for #{service.name}"
68
+ )
69
+ # rubocop:disable Lint/ShadowingOuterLocalVariable
57
70
  with_padding do
58
71
  service.increase_instance_count_by(
59
- batch_size, maximum_instances: maximum_instances) do |on|
72
+ batch_size, maximum_instances: maximum_instances
73
+ ) do |on|
60
74
  on.prepare do |current, target|
61
75
  say(
62
- "Changing instance count from #{current} " +
63
- "to #{target}...")
76
+ "Changing instance count from #{current} " \
77
+ "to #{target}..."
78
+ )
64
79
  end
65
80
  on.waiting_for_health do |attempt|
66
81
  say(
67
- "Waiting for service to reach a steady state " +
68
- "(attempt #{attempt})...")
82
+ 'Waiting for service to reach a steady state ' \
83
+ "(attempt #{attempt})..."
84
+ )
69
85
  end
70
86
  end
71
87
  end
88
+ # rubocop:enable Lint/ShadowingOuterLocalVariable
72
89
  end
73
90
  end
74
91
  end
92
+ # rubocop:enable Metrics/BlockLength
75
93
  say(
76
- "Waiting #{service_start_wait_minutes} minute(s) for " +
77
- 'services to finish starting...')
94
+ "Waiting #{service_start_wait_minutes} minute(s) for " \
95
+ 'services to finish starting...'
96
+ )
78
97
  with_padding do
79
98
  sleep(service_start_wait_seconds)
80
99
  say(
81
- "Waited #{service_start_wait_minutes} minute(s). " +
82
- 'Continuing...')
100
+ "Waited #{service_start_wait_minutes} minute(s). " \
101
+ 'Continuing...'
102
+ )
83
103
  end
84
104
  say('Service instance counts increased, continuing...')
85
105
  end
106
+ # rubocop:enable Metrics/AbcSize
107
+ # rubocop:enable Metrics/MethodLength
86
108
 
87
109
  desc(
88
- 'contract REGION ASG_NAME ECS_CLUSTER_NAME',
89
- 'Contracts the service cluster by one batch.')
110
+ 'contract REGION ASG_NAME ECS_CLUSTER_NAME',
111
+ 'Contracts the service cluster by one batch.'
112
+ )
90
113
  method_option(
91
- :batch_size,
92
- aliases: '-b',
93
- type: :numeric,
94
- default: 3,
95
- desc: 'The number of service instances to remove at a time.')
114
+ :batch_size,
115
+ aliases: '-b',
116
+ type: :numeric,
117
+ default: 3,
118
+ desc: 'The number of service instances to remove at a time.'
119
+ )
96
120
  method_option(
97
- :minimum_instances,
98
- aliases: '-mn',
99
- type: :numeric,
100
- desc: 'The minimum number of service instances to contract to.')
101
-
121
+ :minimum_instances,
122
+ aliases: '-mn',
123
+ type: :numeric,
124
+ desc: 'The minimum number of service instances to contract to.'
125
+ )
126
+ # rubocop:disable Metrics/AbcSize
127
+ # rubocop:disable Metrics/MethodLength
102
128
  def contract(
103
- region, _, ecs_cluster_name,
104
- service_cluster = nil)
129
+ region, _, ecs_cluster_name,
130
+ service_cluster = nil
131
+ )
105
132
  batch_size = options[:batch_size]
106
133
 
107
- service_cluster = service_cluster ||
108
- Rollo::Model::ServiceCluster.new(ecs_cluster_name, region)
134
+ service_cluster ||= Rollo::Model::ServiceCluster.new(ecs_cluster_name,
135
+ region)
109
136
 
110
137
  say("Decreasing service instance counts by #{batch_size}...")
111
138
  with_padding do
112
139
  service_cluster.with_replica_services do |on|
113
140
  on.each_service do |service|
114
141
  say(
115
- "Decreasing instance count by #{batch_size} " +
116
- "for #{service.name}")
142
+ "Decreasing instance count by #{batch_size} " \
143
+ "for #{service.name}"
144
+ )
145
+ # rubocop:disable Lint/ShadowingOuterLocalVariable
117
146
  with_padding do
118
147
  service.decrease_instance_count_by(batch_size) do |on|
119
148
  on.prepare do |current, target|
120
149
  say(
121
- "Changing instance count from #{current} " +
122
- "to #{target}...")
150
+ "Changing instance count from #{current} " \
151
+ "to #{target}..."
152
+ )
123
153
  end
124
154
  on.waiting_for_health do |attempt|
125
155
  say(
126
- 'Waiting for service to reach a steady state ' +
127
- "(attempt #{attempt})...")
156
+ 'Waiting for service to reach a steady state ' \
157
+ "(attempt #{attempt})..."
158
+ )
128
159
  end
129
160
  end
130
161
  end
162
+ # rubocop:enable Lint/ShadowingOuterLocalVariable
131
163
  end
132
164
  end
133
165
  end
134
- say("Service instance counts decreased, continuing...")
166
+ say('Service instance counts decreased, continuing...')
135
167
  end
168
+ # rubocop:enable Metrics/AbcSize
169
+ # rubocop:enable Metrics/MethodLength
136
170
  end
171
+ # rubocop:enable Metrics/ClassLength
137
172
  end
138
173
  end
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'commands/main'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rollo
2
4
  module Model
3
5
  class Host
@@ -13,11 +15,11 @@ module Rollo
13
15
  @instance.terminate(should_decrement_desired_capacity: false)
14
16
  end
15
17
 
16
- def is_in_service?
18
+ def in_service?
17
19
  @instance.lifecycle_state == 'InService'
18
20
  end
19
21
 
20
- def is_healthy?
22
+ def healthy?
21
23
  @instance.health_status == 'Healthy'
22
24
  end
23
25
  end
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'aws-sdk'
2
4
  require 'hollerback'
5
+ require 'wait'
3
6
 
4
7
  require_relative './scaling_activity'
5
8
  require_relative './host'
@@ -13,11 +16,11 @@ module Rollo
13
16
  @region = region
14
17
  @asg_name = asg_name
15
18
  @asg_resource = asg_resource ||
16
- Aws::AutoScaling::Resource.new(region: region)
19
+ Aws::AutoScaling::Resource.new(region: region)
17
20
  @asg = @asg_resource.group(@asg_name)
18
21
  record_latest_scaling_activity
19
22
 
20
- @waiter = waiter || Wait.new(attempts: 300, timeout: 30, delay: 5)
23
+ @waiter = waiter || Wait.new(attempts: 720, timeout: 30, delay: 5)
21
24
  end
22
25
 
23
26
  def reload
@@ -33,30 +36,30 @@ module Rollo
33
36
  end
34
37
 
35
38
  def desired_capacity=(capacity)
36
- @asg.set_desired_capacity({desired_capacity: capacity})
39
+ @asg.set_desired_capacity({ desired_capacity: capacity })
37
40
  end
38
41
 
39
- def has_desired_capacity?
42
+ def desired_capacity?
40
43
  hosts.size == desired_capacity &&
41
- hosts.all? {|h| h.is_in_service? && h.is_healthy?}
44
+ hosts.all? { |h| h.in_service? && h.healthy? }
42
45
  end
43
46
 
44
47
  def scaling_activities
45
- @asg.activities.collect {|a| ScalingActivity.new(a)}
48
+ @asg.activities.collect { |a| ScalingActivity.new(a) }
46
49
  end
47
50
 
48
- def has_started_changing_capacity?
51
+ def started_changing_capacity?
49
52
  scaling_activities
50
- .select {|a| a.started_after_completion_of?(@last_scaling_activity)}
51
- .size > 0
53
+ .select { |a| a.started_after_completion_of?(@last_scaling_activity) }
54
+ .size.positive?
52
55
  end
53
56
 
54
- def has_completed_changing_capacity?
55
- scaling_activities.all?(&:is_complete?)
57
+ def completed_changing_capacity?
58
+ scaling_activities.all?(&:complete?)
56
59
  end
57
60
 
58
61
  def hosts
59
- @asg.instances.collect {|h| Host.new(h)}
62
+ @asg.instances.collect { |h| Host.new(h) }
60
63
  end
61
64
 
62
65
  def increase_capacity_by(capacity_delta, &block)
@@ -64,7 +67,8 @@ module Rollo
64
67
  increased = initial + capacity_delta
65
68
 
66
69
  callbacks_for(block).try_respond_with(
67
- :prepare, initial, increased)
70
+ :prepare, initial, increased
71
+ )
68
72
 
69
73
  ensure_capacity_changed_to(increased, &block)
70
74
  end
@@ -74,7 +78,8 @@ module Rollo
74
78
  decreased = initial - capacity_delta
75
79
 
76
80
  callbacks_for(block).try_respond_with(
77
- :prepare, initial, decreased)
81
+ :prepare, initial, decreased
82
+ )
78
83
 
79
84
  ensure_capacity_changed_to(decreased, &block)
80
85
  end
@@ -90,27 +95,33 @@ module Rollo
90
95
  def wait_for_capacity_change_start(&block)
91
96
  @waiter.until do |attempt|
92
97
  reload
93
- callbacks_for(block)
94
- .try_respond_with(:waiting_for_start, attempt) if block
95
- has_started_changing_capacity?
98
+ if block
99
+ callbacks_for(block)
100
+ .try_respond_with(:waiting_for_start, attempt)
101
+ end
102
+ started_changing_capacity?
96
103
  end
97
104
  end
98
105
 
99
106
  def wait_for_capacity_change_end(&block)
100
107
  @waiter.until do |attempt|
101
108
  reload
102
- callbacks_for(block)
103
- .try_respond_with(:waiting_for_end, attempt) if block
104
- has_completed_changing_capacity?
109
+ if block
110
+ callbacks_for(block)
111
+ .try_respond_with(:waiting_for_end, attempt)
112
+ end
113
+ completed_changing_capacity?
105
114
  end
106
115
  end
107
116
 
108
117
  def wait_for_capacity_health(&block)
109
118
  @waiter.until do |attempt|
110
119
  reload
111
- callbacks_for(block)
112
- .try_respond_with(:waiting_for_health, attempt) if block
113
- has_desired_capacity?
120
+ if block
121
+ callbacks_for(block)
122
+ .try_respond_with(:waiting_for_health, attempt)
123
+ end
124
+ desired_capacity?
114
125
  end
115
126
  end
116
127
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rollo
2
4
  module Model
3
5
  class ScalingActivity
@@ -18,14 +20,14 @@ module Rollo
18
20
  end
19
21
 
20
22
  def started_after_completion_of?(other)
21
- self.id != other.id &&
22
- !self.start_time.nil? &&
23
- !other.end_time.nil? &&
24
- self.start_time > other.end_time
23
+ id != other.id &&
24
+ !start_time.nil? &&
25
+ !other.end_time.nil? &&
26
+ start_time > other.end_time
25
27
  end
26
28
 
27
- def is_complete?
28
- %w(Successful Failed Cancelled).include?(@activity.status_code)
29
+ def complete?
30
+ %w[Successful Failed Cancelled].include?(@activity.status_code)
29
31
  end
30
32
  end
31
33
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'aws-sdk'
2
4
  require 'wait'
3
5
  require 'hollerback'
@@ -6,14 +8,15 @@ module Rollo
6
8
  module Model
7
9
  class Service
8
10
  def initialize(
9
- ecs_cluster_name, ecs_service_arn, region,
10
- ecs_resource = nil, waiter = nil)
11
+ ecs_cluster_name, ecs_service_arn, region,
12
+ ecs_resource = nil, waiter = nil
13
+ )
11
14
  @ecs_cluster_name = ecs_cluster_name
12
15
  @ecs_service_arn = ecs_service_arn
13
16
  @ecs_resource = ecs_resource || Aws::ECS::Resource.new(region: region)
14
17
  reload
15
18
 
16
- @waiter = waiter || Wait.new(attempts: 300, timeout: 30, delay: 5)
19
+ @waiter = waiter || Wait.new(attempts: 720, timeout: 30, delay: 5)
17
20
  end
18
21
 
19
22
  def name
@@ -25,10 +28,10 @@ module Rollo
25
28
  end
26
29
 
27
30
  def reload
28
- @ecs_service = get_ecs_service
31
+ @ecs_service = ecs_service
29
32
  end
30
33
 
31
- def is_replica?
34
+ def replica?
32
35
  @ecs_service.scheduling_strategy == 'REPLICA'
33
36
  end
34
37
 
@@ -42,13 +45,14 @@ module Rollo
42
45
 
43
46
  def desired_count=(count)
44
47
  @ecs_resource.client
45
- .update_service(
46
- cluster: @ecs_cluster_name,
47
- service: @ecs_service_arn,
48
- desired_count: count)
48
+ .update_service(
49
+ cluster: @ecs_cluster_name,
50
+ service: @ecs_service_arn,
51
+ desired_count: count
52
+ )
49
53
  end
50
54
 
51
- def has_desired_count?
55
+ def desired_count_met?
52
56
  running_count == desired_count
53
57
  end
54
58
 
@@ -59,7 +63,8 @@ module Rollo
59
63
  target = [increased, maximum].min
60
64
 
61
65
  callbacks_for(block).try_respond_with(
62
- :prepare, initial, target)
66
+ :prepare, initial, target
67
+ )
63
68
 
64
69
  ensure_instance_count(target, &block)
65
70
  end
@@ -71,7 +76,8 @@ module Rollo
71
76
  target = [decreased, minimum].max
72
77
 
73
78
  callbacks_for(block).try_respond_with(
74
- :prepare, initial, target)
79
+ :prepare, initial, target
80
+ )
75
81
 
76
82
  ensure_instance_count(target, &block)
77
83
  end
@@ -84,20 +90,23 @@ module Rollo
84
90
  def wait_for_service_health(&block)
85
91
  @waiter.until do |attempt|
86
92
  reload
87
- callbacks_for(block)
88
- .try_respond_with(:waiting_for_health, attempt) if block
89
- has_desired_count?
93
+ if block
94
+ callbacks_for(block)
95
+ .try_respond_with(:waiting_for_health, attempt)
96
+ end
97
+ desired_count_met?
90
98
  end
91
99
  end
92
100
 
93
101
  private
94
102
 
95
- def get_ecs_service
103
+ def ecs_service
96
104
  @ecs_resource.client
97
- .describe_services(
98
- cluster: @ecs_cluster_name,
99
- services: [@ecs_service_arn])
100
- .services[0]
105
+ .describe_services(
106
+ cluster: @ecs_cluster_name,
107
+ services: [@ecs_service_arn]
108
+ )
109
+ .services[0]
101
110
  end
102
111
 
103
112
  def callbacks_for(block)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'aws-sdk'
2
4
  require 'hollerback'
3
5
 
@@ -10,7 +12,7 @@ module Rollo
10
12
  @region = region
11
13
  @ecs_cluster_name = ecs_cluster_name
12
14
  @ecs_resource = ecs_resource || Aws::ECS::Resource.new(region: region)
13
- @ecs_cluster = get_ecs_cluster
15
+ @ecs_cluster = ecs_cluster
14
16
  end
15
17
 
16
18
  def name
@@ -18,9 +20,9 @@ module Rollo
18
20
  end
19
21
 
20
22
  def replica_services
21
- get_ecs_service_arns
22
- .collect {|arn| Service.new(@ecs_cluster_name, arn, @region)}
23
- .select(&:is_replica?)
23
+ ecs_service_arns
24
+ .collect { |arn| Service.new(@ecs_cluster_name, arn, @region) }
25
+ .select(&:replica?)
24
26
  end
25
27
 
26
28
  def with_replica_services(&block)
@@ -28,7 +30,8 @@ module Rollo
28
30
 
29
31
  callbacks = Hollerback::Callbacks.new(block)
30
32
  callbacks.try_respond_with(
31
- :start, all_replica_services)
33
+ :start, all_replica_services
34
+ )
32
35
 
33
36
  all_replica_services.each do |service|
34
37
  callbacks.try_respond_with(:each_service, service)
@@ -37,17 +40,19 @@ module Rollo
37
40
 
38
41
  private
39
42
 
40
- def get_ecs_cluster
41
- @ecs_resource.client
42
- .describe_clusters(clusters: [@ecs_cluster_name])
43
- .clusters[0]
43
+ def ecs_cluster
44
+ @ecs_resource
45
+ .client
46
+ .describe_clusters(clusters: [@ecs_cluster_name])
47
+ .clusters[0]
44
48
  end
45
49
 
46
- def get_ecs_service_arns
47
- @ecs_resource.client
48
- .list_services(cluster: @ecs_cluster.cluster_name)
49
- .inject([]) {|arns, response| arns + response.service_arns}
50
+ def ecs_service_arns
51
+ @ecs_resource
52
+ .client
53
+ .list_services(cluster: @ecs_cluster.cluster_name)
54
+ .inject([]) { |arns, response| arns + response.service_arns }
50
55
  end
51
56
  end
52
57
  end
53
- end
58
+ end
data/lib/rollo/model.rb CHANGED
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'model/host_cluster'
2
4
  require_relative 'model/service_cluster'
data/lib/rollo/version.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rollo
2
- VERSION = "0.6.0"
4
+ VERSION = '0.8.0.pre.3'
3
5
  end
data/lib/rollo.rb CHANGED
@@ -1,4 +1,6 @@
1
- require_relative "rollo/version"
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'rollo/version'
2
4
  require_relative 'rollo/commands'
3
5
 
4
6
  module Rollo