From b3921d5c407dd12ad085a13fdb9d9769fa43cb41 Mon Sep 17 00:00:00 2001 From: "James E. Blair" Date: Tue, 5 Sep 2023 16:09:26 -0700 Subject: [PATCH] AWS: handle 'InvalidConversionTaskId.Malformed' error When we call the describe_import_image_tasks paginator with a task id specified and that task id does not exist, AWS can return a InvalidConversionTaskId.Malformed error instead of the expected empty list. Handle that case and add a test for it. Change-Id: I1a3a9297e123a50a4beeb7e18124b8cc17aa28bb --- nodepool/driver/aws/adapter.py | 17 +++++++++++++---- nodepool/tests/unit/fake_aws.py | 4 ++++ nodepool/tests/unit/test_driver_aws.py | 8 ++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/nodepool/driver/aws/adapter.py b/nodepool/driver/aws/adapter.py index 204ae35ac..8b1385a60 100644 --- a/nodepool/driver/aws/adapter.py +++ b/nodepool/driver/aws/adapter.py @@ -824,10 +824,19 @@ class AwsAdapter(statemachine.Adapter): paginator = self.ec2_client.get_paginator( 'describe_import_image_tasks') with self.non_mutating_rate_limiter: - for page in paginator.paginate(ImportTaskIds=[task_id]): - for task in page['ImportImageTasks']: - # Return the first and only task - return task + try: + for page in paginator.paginate(ImportTaskIds=[task_id]): + for task in page['ImportImageTasks']: + # Return the first and only task + return task + except botocore.exceptions.ClientError as error: + if (error.response['Error']['Code'] == + 'InvalidConversionTaskId.Malformed'): + # In practice, this can mean that the task no + # longer exists + pass + else: + raise return None def _listImportSnapshotTasks(self): diff --git a/nodepool/tests/unit/fake_aws.py b/nodepool/tests/unit/fake_aws.py index a7e2238d0..5a7deec94 100644 --- a/nodepool/tests/unit/fake_aws.py +++ b/nodepool/tests/unit/fake_aws.py @@ -120,6 +120,10 @@ class ImportImageTaskPaginator: if 'ImportTaskIds' in kw: tasks = [t for t in tasks if t['ImportTaskId'] in kw['ImportTaskIds']] + if not tasks: + raise botocore.exceptions.ClientError( + {'Error': {'Code': 'InvalidConversionTaskId.Malformed'}}, + 'DescribeImportImageTasks') # A page of tasks ret = [{'ImportImageTasks': tasks}] diff --git a/nodepool/tests/unit/test_driver_aws.py b/nodepool/tests/unit/test_driver_aws.py index 46633fa38..a0168b79f 100644 --- a/nodepool/tests/unit/test_driver_aws.py +++ b/nodepool/tests/unit/test_driver_aws.py @@ -1042,6 +1042,14 @@ class TestDriverAws(tests.DBTestCase): # Probably not found break + def test_aws_get_import_image_task(self): + # A unit test of the unusual error handling for missing tasks + configfile = self.setup_config('aws/diskimage.yaml') + pool = self.useNodepool(configfile, watermark_sleep=1) + self.startPool(pool) + adapter = pool.getProviderManager('ec2-us-west-2').adapter + self.assertIsNone(adapter._getImportImageTask("fake-id")) + def test_aws_provisioning_spot_instances(self): # Test creating a spot instances instead of an on-demand on. req = self.requestNode('aws/aws-spot.yaml', 'ubuntu1404-spot')