Skip to content

Commit 4bf1bef

Browse files
committed
Add ability to set wait time base
This allows speeding/slowing things a bit, which may be helpful in some cases
1 parent f48e88f commit 4bf1bef

File tree

1 file changed

+21
-13
lines changed

1 file changed

+21
-13
lines changed

ecsroll.py

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
DEFAULT_PROFILE = 'default' # name of awscli / boto3 profile to target
1414
DEFAULT_CLUSTER = 'test-ecs-cluster' # name of ECS cluster to target
1515
DEFAULT_ACTION = 'replace' # 'reboot' or 'replace'
16+
DEFAULT_WAIT = 30
1617

18+
WAIT_TIME = DEFAULT_WAIT
1719

1820
INSTANCE_FIELDS = ['ec2InstanceId', 'containerInstanceArn', 'status', 'runningTasksCount', 'pendingTasksCount']
1921

@@ -34,7 +36,7 @@ def countdown(msg, t):
3436
print('{}...'.format(msg))
3537
while t:
3638
mins, secs = divmod(t, 60)
37-
timeformat = '{:02d}:{:02d}'.format(mins, secs)
39+
timeformat = '{:02d}:{:02d}'.format(int(mins), int(secs))
3840
print(timeformat, end='\r')
3941
sleep(1)
4042
t -= 1
@@ -106,8 +108,8 @@ def set_scalein_protection_for_instances(as_client, asg, cluster_instances, prot
106108
)
107109

108110

109-
def wait_until_instance_count(ecs_client, target_cluster, count, seconds=60):
110-
countdown('Waiting for cluster size change (expected instance count: {})'.format(count), seconds)
111+
def wait_until_instance_count(ecs_client, target_cluster, count, seconds=WAIT_TIME):
112+
countdown('Waiting for cluster size change (expected instance count: {})'.format(count), seconds*3)
111113
current_instances = get_cluster_instances(ecs_client, target_cluster)
112114
if len(current_instances) != count:
113115
yes_or_exit('There are currently {} instances, but expecting {} - keep waiting?'.format(
@@ -117,7 +119,7 @@ def wait_until_instance_count(ecs_client, target_cluster, count, seconds=60):
117119

118120

119121
def wait_until_instance_status(ecs_client, target_cluster, instance_id, status):
120-
countdown('Waiting for instance {} to have {} status'.format(instance_id, status), 30)
122+
countdown('Waiting for instance {} to have {} status'.format(instance_id, status), WAIT_TIME/2)
121123
current_instances = get_cluster_instances(ecs_client, target_cluster)
122124
for instance in current_instances:
123125
if instance[INSTANCE_FIELDS.index('ec2InstanceId')] == instance_id:
@@ -166,7 +168,7 @@ def wait_until_instance_drained(ecs_client, target_cluster, instance_id):
166168
running = len(response['taskArns'])
167169
drained = (running == 0)
168170
if not drained:
169-
countdown('Waiting for instance {} to drain; currently running {} tasks'.format(instance_id, running), 60)
171+
countdown('Waiting for instance {} to drain; currently running {} tasks'.format(instance_id, running), WAIT_TIME)
170172

171173

172174
def wait_until_instance_ec2_ok(ec2_client, ec2_instance_id):
@@ -176,7 +178,7 @@ def wait_until_instance_ec2_ok(ec2_client, ec2_instance_id):
176178
status = response['InstanceStatuses'][0]['InstanceStatus']['Status']
177179
ok = (status == 'ok')
178180
if not ok:
179-
countdown('Waiting for instance {} to be \'ok\'; currently \'{}\''.format(ec2_instance_id, status), 60)
181+
countdown('Waiting for instance {} to be \'ok\'; currently \'{}\''.format(ec2_instance_id, status), WAIT_TIME)
180182

181183

182184
def wait_until_instance_ecs_connected(ecs_client, ecs_instance_id, target_cluster):
@@ -252,7 +254,7 @@ def do_cluster_replace(profile, target_cluster):
252254
i+1, len(cluster_instances), ec2_instance_id, ecs_instance_id
253255
))
254256

255-
countdown('Waiting for ASG to rightsize ECS cluster', 60)
257+
countdown('Waiting for ASG to rightsize ECS cluster', WAIT_TIME)
256258
wait_until_instance_count(ecs_client, target_cluster, len(cluster_instances) + 1)
257259
new_instance = get_new_instance(
258260
cluster_instances, replacement_instances, get_cluster_instances(ecs_client, target_cluster)
@@ -276,12 +278,12 @@ def do_cluster_replace(profile, target_cluster):
276278
if i < (len(cluster_instances) - 1):
277279
# terminate an original instance
278280
ec2_client.terminate_instances(InstanceIds=[ec2_instance_id, ])
279-
countdown('Terminating original instance {} [{}]'.format(ec2_instance_id, ecs_instance_id), 60)
281+
countdown('Terminating original instance {} [{}]'.format(ec2_instance_id, ecs_instance_id), WAIT_TIME)
280282
else:
281283
# for the final instance, just downsize cluster & let AS / ECS handle it
282284
set_scalein_protection_for_instances(as_client, asg, replacement_instances, True)
283285
bump_autoscaling_group(as_client, asg, -1)
284-
countdown('Returned to original ASG size, waiting for ASG to downsize ECS cluster', 120)
286+
countdown('Returned to original ASG size, waiting for ASG to downsize ECS cluster', WAIT_TIME*2)
285287
wait_until_instance_count(ecs_client, target_cluster, len(cluster_instances))
286288
set_scalein_protection_for_instances(as_client, asg, replacement_instances, False)
287289

@@ -298,7 +300,7 @@ def do_cluster_reboot(profile, target_cluster):
298300

299301
print('Increasing ASG size by 1 to maintain cluster capacity during rolling reboot')
300302
bump_autoscaling_group(as_client, asg, 1)
301-
countdown('Waiting for ASG to upsize ECS cluster', 60)
303+
countdown('Waiting for ASG to upsize ECS cluster', WAIT_TIME)
302304
# wait until the additional instance joins the cluster
303305
wait_until_instance_count(ecs_client, target_cluster, len(cluster_instances) + 1)
304306

@@ -315,12 +317,12 @@ def do_cluster_reboot(profile, target_cluster):
315317
wait_until_instance_drained(ecs_client, target_cluster, ecs_instance_id)
316318
# 1st reboot instance (this picks up any unapplied security updates when it boots)
317319
ec2_client.reboot_instances(InstanceIds=[ec2_instance_id, ])
318-
countdown('Reboot (1/2) for instance {} [{}]'.format(ec2_instance_id, ecs_instance_id), 60)
320+
countdown('Reboot (1/2) for instance {} [{}]'.format(ec2_instance_id, ecs_instance_id), WAIT_TIME)
319321
wait_until_instance_ec2_ok(ec2_client, ec2_instance_id)
320322
wait_until_instance_ecs_connected(ecs_client, ecs_instance_id, target_cluster)
321323
# 2nd reboot of instance (boots to new kernel, if it was updated)
322324
ec2_client.reboot_instances(InstanceIds=[ec2_instance_id, ])
323-
countdown('Reboot (2/2) for instance {} [{}]'.format(ec2_instance_id, ecs_instance_id), 60)
325+
countdown('Reboot (2/2) for instance {} [{}]'.format(ec2_instance_id, ecs_instance_id), WAIT_TIME)
324326
wait_until_instance_ec2_ok(ec2_client, ec2_instance_id)
325327
wait_until_instance_ecs_connected(ecs_client, ecs_instance_id, target_cluster)
326328
# mark as ACTIVE and verify that it is
@@ -346,7 +348,7 @@ def do_cluster_reboot(profile, target_cluster):
346348
# downsize cluster & wait until overflow instance is gone
347349
set_scalein_protection_for_instances(as_client, asg, cluster_instances, True)
348350
bump_autoscaling_group(as_client, asg, -1)
349-
countdown('Returned to original ASG size, waiting for ASG to downsize ECS cluster', 60)
351+
countdown('Returned to original ASG size, waiting for ASG to downsize ECS cluster', WAIT_TIME)
350352
wait_until_instance_count(ecs_client, target_cluster, len(cluster_instances))
351353
set_scalein_protection_for_instances(as_client, asg, cluster_instances, False)
352354

@@ -365,6 +367,10 @@ def do_cluster_reboot(profile, target_cluster):
365367
'--profile', '-p', nargs='?', default=DEFAULT_PROFILE,
366368
help='Name of AWS profile to target (default: \'{0}\')'.format(DEFAULT_PROFILE)
367369
)
370+
parser.add_argument(
371+
'--wait', '-w', nargs='?', default=DEFAULT_WAIT, type=int,
372+
help='Base for timer to wait between actions (default: \'{0}\')'.format(DEFAULT_WAIT)
373+
)
368374
parser.add_argument(
369375
'--provider', '-r', nargs='?', default=DEFAULT_PROVIDER, choices=[PROVIDER_PROFILE, PROVIDER_ENV],
370376
help='AWS credential provider method to use (default: \'{0}\', choose from [\'{1}\',\'{2}\'])'.format(
@@ -376,6 +382,8 @@ def do_cluster_reboot(profile, target_cluster):
376382
)
377383
args = parser.parse_args()
378384

385+
WAIT_TIME = args.wait
386+
379387
if args.provider == PROVIDER_PROFILE:
380388
session = boto3.Session()
381389
if args.profile not in session.available_profiles:

0 commit comments

Comments
 (0)