diff options
author | Michael Brown <mcb30@ipxe.org> | 2024-09-09 15:00:24 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2024-09-09 15:02:27 +0100 |
commit | a1830ff43c5f8ee2957eb537f24670265ebd233b (patch) | |
tree | cce9430f3478209b2cf166427e05470862c33e82 | |
parent | 49f9e036fffa33671a3ad16ab5fc0644a057218c (diff) | |
download | ipxe-master.zip ipxe-master.tar.gz ipxe-master.tar.bz2 |
Add the "--retain <N>" option to limit the number of retained old AMI
images (within the same family, architecture, and public visibility).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rwxr-xr-x | contrib/cloud/aws-import | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/contrib/cloud/aws-import b/contrib/cloud/aws-import index 64b2996..3b6b522 100755 --- a/contrib/cloud/aws-import +++ b/contrib/cloud/aws-import @@ -47,7 +47,22 @@ def create_snapshot(region, description, image, tags): return snapshot_id -def import_image(region, name, family, architecture, image, public, overwrite): +def delete_images(region, filters, retain): + client = boto3.client('ec2', region_name=region) + resource = boto3.resource('ec2', region_name=region) + images = client.describe_images(Owners=['self'], Filters=filters) + old_images = sorted(images['Images'], key=lambda x: x['CreationDate']) + if retain > 0: + old_images = old_images[:-retain] + for image in old_images: + image_id = image['ImageId'] + snapshot_id = image['BlockDeviceMappings'][0]['Ebs']['SnapshotId'] + resource.Image(image_id).deregister() + resource.Snapshot(snapshot_id).delete() + + +def import_image(region, name, family, architecture, image, public, overwrite, + retain): """Import an AMI image""" client = boto3.client('ec2', region_name=region) resource = boto3.resource('ec2', region_name=region) @@ -56,14 +71,16 @@ def import_image(region, name, family, architecture, image, public, overwrite): {'Key': 'family', 'Value': family}, {'Key': 'architecture', 'Value': architecture}, ] - images = client.describe_images(Filters=[{'Name': 'name', - 'Values': [description]}]) - if overwrite and images['Images']: - images = images['Images'][0] - image_id = images['ImageId'] - snapshot_id = images['BlockDeviceMappings'][0]['Ebs']['SnapshotId'] - resource.Image(image_id).deregister() - resource.Snapshot(snapshot_id).delete() + if overwrite: + filters = [{'Name': 'name', 'Values': [description]}] + delete_images(region=region, filters=filters, retain=0) + if retain is not None: + filters = [ + {'Name': 'tag:family', 'Values': [family]}, + {'Name': 'tag:architecture', 'Values': [architecture]}, + {'Name': 'is-public', 'Values': [str(public).lower()]}, + ] + delete_images(region=region, filters=filters, retain=retain) snapshot_id = create_snapshot(region=region, description=description, image=image, tags=tags) client.get_waiter('snapshot_completed').wait(SnapshotIds=[snapshot_id]) @@ -109,6 +126,8 @@ parser.add_argument('--public', '-p', action='store_true', help="Make image public") parser.add_argument('--overwrite', action='store_true', help="Overwrite any existing image with same name") +parser.add_argument('--retain', type=int, metavar='NUM', + help="Retain at most <NUM> old images") parser.add_argument('--region', '-r', action='append', help="AWS region(s)") parser.add_argument('--wiki', '-w', metavar='FILE', @@ -142,7 +161,8 @@ with ThreadPoolExecutor(max_workers=len(imports)) as executor: architecture=architectures[image], image=image, public=args.public, - overwrite=args.overwrite): (region, image) + overwrite=args.overwrite, + retain=args.retain): (region, image) for region, image in imports} results = {futures[future]: future.result() for future in as_completed(futures)} |