import logging import boto3 from botocore.exceptions import ClientError from labs.lab_manager_v2.tasks.base import BaseLabTask from labs.lab_manager_v2.exceptions import LabTaskRecoverableError from labs.lab_manager_v2.consts import get_region_metadata logger = logging.getLogger(__name__) class AWSCloudFormationStackDeleteTask(BaseLabTask): max_retries = 10 retry_interval_seconds = 60 def run(self): db_lab_instance = self.db_lab_instance lab_region = get_region_metadata(db_lab_instance.region_name) cfn = boto3.client("cloudformation", lab_region["region-code"]) try: resp = cfn.delete_stack(StackName=db_lab_instance.unique_tag) except ClientError as e: # Usually, it's due to API throttling, so we can retry. raise LabTaskRecoverableError( f"Failed to delete AWS CloudFormation stack for lab {db_lab_instance.unique_tag}, error: {e}" ) logger.info( f"Deleted AWS CloudFormation stack for lab {db_lab_instance.unique_tag}, resp: {resp}" ) # AWS always return 200 even if the stack does not exist, # so its safe to call delete_stack multiple times if resp.get("ResponseMetadata", {}).get("HTTPStatusCode") != 200: raise LabTaskRecoverableError( f"Failed to delete AWS CloudFormation stack for lab {db_lab_instance.unique_tag}" )