| OLD | NEW |
| 1 # Copyright 2016 The LUCI Authors. All rights reserved. | 1 # Copyright 2016 The LUCI Authors. All rights reserved. |
| 2 # Use of this source code is governed under the Apache License, Version 2.0 | 2 # Use of this source code is governed under the Apache License, Version 2.0 |
| 3 # that can be found in the LICENSE file. | 3 # that can be found in the LICENSE file. |
| 4 | 4 |
| 5 """Utilities for operating on instance group managers.""" | 5 """Utilities for operating on instance group managers.""" |
| 6 | 6 |
| 7 import collections | 7 import collections |
| 8 import json | 8 import json |
| 9 import logging | 9 import logging |
| 10 | 10 |
| 11 from google.appengine.ext import ndb | 11 from google.appengine.ext import ndb |
| 12 | 12 |
| 13 from components import gce | 13 from components import gce |
| 14 from components import net | 14 from components import net |
| 15 from components import utils | |
| 16 | 15 |
| 17 import instance_templates | 16 import instance_templates |
| 18 import models | 17 import models |
| 18 import utilities |
| 19 | 19 |
| 20 | 20 |
| 21 def get_instance_group_manager_key(base_name, revision, zone): | 21 def get_instance_group_manager_key(base_name, revision, zone): |
| 22 """Returns a key for an InstanceTemplateGroupManager. | 22 """Returns a key for an InstanceTemplateGroupManager. |
| 23 | 23 |
| 24 Args: | 24 Args: |
| 25 base_name: Base name for the models.InstanceTemplate. | 25 base_name: Base name for the models.InstanceTemplate. |
| 26 revision: Revision string for the models.InstanceTemplateRevision. | 26 revision: Revision string for the models.InstanceTemplateRevision. |
| 27 zone: Zone for the models.InstanceGroupManager. | 27 zone: Zone for the models.InstanceGroupManager. |
| 28 | 28 |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 # InstanceGroupManager could be out of date and may already have a task | 184 # InstanceGroupManager could be out of date and may already have a task |
| 185 # scheduled/completed. In either case it doesn't matter since we make | 185 # scheduled/completed. In either case it doesn't matter since we make |
| 186 # creating an instance group manager and updating the URL idempotent. | 186 # creating an instance group manager and updating the URL idempotent. |
| 187 for instance_template in models.InstanceTemplate.query(): | 187 for instance_template in models.InstanceTemplate.query(): |
| 188 if instance_template.active: | 188 if instance_template.active: |
| 189 instance_template_revision = instance_template.active.get() | 189 instance_template_revision = instance_template.active.get() |
| 190 if instance_template_revision and instance_template_revision.url: | 190 if instance_template_revision and instance_template_revision.url: |
| 191 for instance_group_manager_key in instance_template_revision.active: | 191 for instance_group_manager_key in instance_template_revision.active: |
| 192 instance_group_manager = instance_group_manager_key.get() | 192 instance_group_manager = instance_group_manager_key.get() |
| 193 if instance_group_manager and not instance_group_manager.url: | 193 if instance_group_manager and not instance_group_manager.url: |
| 194 if not utils.enqueue_task( | 194 utilities.enqueue_task( |
| 195 '/internal/queues/create-instance-group-manager', | 195 'create-instance-group-manager', instance_group_manager_key) |
| 196 'create-instance-group-manager', | |
| 197 params={ | |
| 198 'key': instance_group_manager_key.urlsafe(), | |
| 199 }, | |
| 200 ): | |
| 201 logging.warning( | |
| 202 'Failed to enqueue task for InstanceGroupManager: %s', | |
| 203 instance_group_manager_key, | |
| 204 ) | |
| 205 | 196 |
| 206 | 197 |
| 207 def get_instance_group_manager_to_delete(key): | 198 def get_instance_group_manager_to_delete(key): |
| 208 """Returns the URL of the instance group manager to delete. | 199 """Returns the URL of the instance group manager to delete. |
| 209 | 200 |
| 210 Args: | 201 Args: |
| 211 key: ndb.Key for a models.InstanceGroupManager entity. | 202 key: ndb.Key for a models.InstanceGroupManager entity. |
| 212 | 203 |
| 213 Returns: | 204 Returns: |
| 214 The URL of the instance group manager to delete, or None if there isn't one. | 205 The URL of the instance group manager to delete, or None if there isn't one. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 | 274 |
| 284 return keys | 275 return keys |
| 285 | 276 |
| 286 | 277 |
| 287 def schedule_deletion(): | 278 def schedule_deletion(): |
| 288 """Enqueues tasks to delete drained instance group managers.""" | 279 """Enqueues tasks to delete drained instance group managers.""" |
| 289 for key in get_drained_instance_group_managers(): | 280 for key in get_drained_instance_group_managers(): |
| 290 instance_group_manager = key.get() | 281 instance_group_manager = key.get() |
| 291 if instance_group_manager: | 282 if instance_group_manager: |
| 292 if instance_group_manager.url and not instance_group_manager.instances: | 283 if instance_group_manager.url and not instance_group_manager.instances: |
| 293 if not utils.enqueue_task( | 284 utilities.enqueue_task('delete-instance-group-manager', key) |
| 294 '/internal/queues/delete-instance-group-manager', | |
| 295 'delete-instance-group-manager', | |
| 296 params={ | |
| 297 'key': key.urlsafe(), | |
| 298 }, | |
| 299 ): | |
| 300 logging.warning( | |
| 301 'Failed to enqueue task for InstanceGroupManager: %s', key) | |
| 302 | 285 |
| 303 | 286 |
| 304 def resize(key): | 287 def resize(key): |
| 305 """Resizes the given instance group manager. | 288 """Resizes the given instance group manager. |
| 306 | 289 |
| 307 Args: | 290 Args: |
| 308 key: ndb.Key for a models.InstanceGroupManager entity. | 291 key: ndb.Key for a models.InstanceGroupManager entity. |
| 309 """ | 292 """ |
| 310 # To avoid a massive resize, impose a limit on how much larger we can | 293 # To avoid a massive resize, impose a limit on how much larger we can |
| 311 # resize the instance group. Repeated calls will eventually allow the | 294 # resize the instance group. Repeated calls will eventually allow the |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 api.resize_managed_instance_group(response['name'], key.id(), target_size) | 363 api.resize_managed_instance_group(response['name'], key.id(), target_size) |
| 381 | 364 |
| 382 | 365 |
| 383 def schedule_resize(): | 366 def schedule_resize(): |
| 384 """Enqueues tasks to resize instance group managers.""" | 367 """Enqueues tasks to resize instance group managers.""" |
| 385 for instance_template in models.InstanceTemplate.query(): | 368 for instance_template in models.InstanceTemplate.query(): |
| 386 if instance_template.active: | 369 if instance_template.active: |
| 387 instance_template_revision = instance_template.active.get() | 370 instance_template_revision = instance_template.active.get() |
| 388 if instance_template_revision: | 371 if instance_template_revision: |
| 389 for instance_group_manager_key in instance_template_revision.active: | 372 for instance_group_manager_key in instance_template_revision.active: |
| 390 if not utils.enqueue_task( | 373 utilities.enqueue_task( |
| 391 '/internal/queues/resize-instance-group', | 374 'resize-instance-group', instance_group_manager_key) |
| 392 'resize-instance-group', | |
| 393 params={ | |
| 394 'key': instance_group_manager_key.urlsafe(), | |
| 395 }, | |
| 396 ): | |
| 397 logging.warning( | |
| 398 'Failed to enqueue task for InstanceGroupManager: %s', | |
| 399 instance_group_manager_key, | |
| 400 ) | |
| 401 | 375 |
| 402 | 376 |
| 403 def count_instances(): | 377 def count_instances(): |
| 404 """Counts the number of instances owned by each instance template. | 378 """Counts the number of instances owned by each instance template. |
| 405 | 379 |
| 406 Returns: | 380 Returns: |
| 407 A dict mapping instance template name to count of instances. | 381 A dict mapping instance template name to count of instances. |
| 408 """ | 382 """ |
| 409 # Aggregate the number of instances owned by each instance group manager | 383 # Aggregate the number of instances owned by each instance group manager |
| 410 # created for each instance template. | 384 # created for each instance template. |
| 411 totals = collections.defaultdict(int) | 385 totals = collections.defaultdict(int) |
| 412 for instance_group_manager in models.InstanceGroupManager.query(): | 386 for instance_group_manager in models.InstanceGroupManager.query(): |
| 413 instance_template_name = instance_group_manager.key.parent().parent().id() | 387 instance_template_name = instance_group_manager.key.parent().parent().id() |
| 414 totals[instance_template_name] += len(instance_group_manager.instances) | 388 totals[instance_template_name] += len(instance_group_manager.instances) |
| 415 return totals | 389 return totals |
| OLD | NEW |