From eca4877200a5d557171539a17117ae3dbd6c9c5f Mon Sep 17 00:00:00 2001 From: Michael Armijo Date: Fri, 3 Oct 2025 15:22:47 -0600 Subject: [PATCH] cosalib/aws: only replicate WinLI AMIs when --winli is specified The current logic always considers the `aws-winli` buildmeta key when present, which causes WinLI AMIs to be replicated in both the standard AWS and GovCloud cases. Restore `aws_run_ore_replicate`[1] to only work on the 'amis' buildmeta key and switch to aws-winli when `--winli` is used. This ensures WinLI replication happens only when explicitly requested. Also update the CLI help text for `--winli` to clarify that it applies to replication as well as creation. [1]: https://github.com/coreos/coreos-assembler/pull/4069/commits/a5bfbdefe999d5cf4ec5b6d4c1de28798b6322d6 --- src/cosalib/aws.py | 144 ++++++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/src/cosalib/aws.py b/src/cosalib/aws.py index fce0484da7..ee32e3d9e4 100644 --- a/src/cosalib/aws.py +++ b/src/cosalib/aws.py @@ -1,6 +1,7 @@ import json import os import subprocess +import sys from cosalib.builds import Builds from cosalib.cmdlib import runcmd @@ -31,81 +32,80 @@ def deregister_aws_resource(ami, snapshot, region, credentials_file): def aws_run_ore_replicate(build, args): build.refresh_meta() buildmeta = build.meta - buildmeta_keys = ["amis"] - if len(buildmeta.get(buildmeta_keys[0], [])) < 1: + # only replicate winli AMIs if `--winli` is used + # otherwise, replicate only the AMIs in the 'amis' section of build meta + meta_key = "aws-winli" if args.winli else "amis" + if len(buildmeta.get(meta_key, [])) < 1: raise SystemExit(("buildmeta doesn't contain source AMIs." " Run buildextend-aws --upload first")) - if len(buildmeta.get('aws-winli', [])) > 0: - buildmeta_keys.append("aws-winli") - - for key in buildmeta_keys: - # Determine which region to copy from - if not args.source_region: - args.source_region = buildmeta[key][0]['name'] - - ore_args = ['ore', 'aws', '--region', args.source_region] - if args.log_level: - ore_args.extend(['--log-level', args.log_level]) - if args.credentials_file: - ore_args.extend(['--credentials-file', args.credentials_file]) - - # If no region specified then autodetect the regions to replicate to. - # Specify --region=args.source_region here so ore knows to talk to - # a region that exists (i.e. it will talk to govcloud if copying - # from a govcloud region). - if not args.region: - args.region = subprocess.check_output( - ore_args + ['list-regions']).decode().strip().split() - - # only replicate to regions that don't already exist - existing_regions = [item['name'] for item in buildmeta[key]] - duplicates = list(set(args.region).intersection(existing_regions)) - if len(duplicates) > 0: - print((f"AMIs already exist in {duplicates} region(s), " - "skipping listed region(s)...")) - - region_list = list(set(args.region) - set(duplicates)) - if len(region_list) == 0: - print("no new regions detected") - continue - source_image = None - for a in buildmeta[key]: - if a['name'] == args.source_region: - source_image = a['hvm'] - break + # Determine which region to copy from + if not args.source_region: + args.source_region = buildmeta[meta_key][0]['name'] - if source_image is None: - raise Exception(("Unable to find AMI ID for " - f"{args.source_region} region")) - - ore_args.extend(['copy-image', '--image', source_image]) - ore_args.extend(region_list) - print("+ {}".format(subprocess.list2cmdline(ore_args))) - - ore_data = "" - try: - ore_data = subprocess.check_output(ore_args, encoding='utf-8') - except subprocess.CalledProcessError as e: - ore_data = e.output or "" - raise e - finally: - ore_data = ore_data.strip() - if len(ore_data) > 0: - for line in ore_data.split('\n'): - j = json.loads(line) - # This matches the Container Linux schema: - # https://stable.release.core-os.net/amd64-usr/current/coreos_production_ami_all.json - ami_data = [{'name': region, - 'hvm': vals['ami'], - 'snapshot': vals['snapshot']} - for region, vals in j.items()] - buildmeta[key].extend(ami_data) - - # Record the AMI's that have been replicated as they happen. - # When re-running the replication, we don't want to be lose - # what has been done. - build.meta_write() + ore_args = ['ore', 'aws', '--region', args.source_region] + if args.log_level: + ore_args.extend(['--log-level', args.log_level]) + if args.credentials_file: + ore_args.extend(['--credentials-file', args.credentials_file]) + + # If no region specified then autodetect the regions to replicate to. + # Specify --region=args.source_region here so ore knows to talk to + # a region that exists (i.e. it will talk to govcloud if copying + # from a govcloud region). + if not args.region: + args.region = subprocess.check_output( + ore_args + ['list-regions']).decode().strip().split() + + # only replicate to regions that don't already exist + existing_regions = [item['name'] for item in buildmeta[meta_key]] + duplicates = list(set(args.region).intersection(existing_regions)) + if len(duplicates) > 0: + print((f"AMIs already exist in {duplicates} region(s), " + "skipping listed region(s)...")) + + region_list = list(set(args.region) - set(duplicates)) + if len(region_list) == 0: + print("no new regions detected") + sys.exit(0) + + source_image = None + for a in buildmeta[meta_key]: + if a['name'] == args.source_region: + source_image = a['hvm'] + break + + if source_image is None: + raise Exception(("Unable to find AMI ID for " + f"{args.source_region} region")) + + ore_args.extend(['copy-image', '--image', source_image]) + ore_args.extend(region_list) + print("+ {}".format(subprocess.list2cmdline(ore_args))) + + ore_data = "" + try: + ore_data = subprocess.check_output(ore_args, encoding='utf-8') + except subprocess.CalledProcessError as e: + ore_data = e.output or "" + raise e + finally: + ore_data = ore_data.strip() + if len(ore_data) > 0: + for line in ore_data.split('\n'): + j = json.loads(line) + # This matches the Container Linux schema: + # https://stable.release.core-os.net/amd64-usr/current/coreos_production_ami_all.json + ami_data = [{'name': region, + 'hvm': vals['ami'], + 'snapshot': vals['snapshot']} + for region, vals in j.items()] + buildmeta[meta_key].extend(ami_data) + + # Record the AMI's that have been replicated as they happen. + # When re-running the replication, we don't want to be lose + # what has been done. + build.meta_write() @retry(reraise=True, stop=stop_after_attempt(3)) @@ -226,6 +226,6 @@ def aws_cli(parser): parser.add_argument("--public", action="store_true", help="Mark images as publicly available") parser.add_argument("--tags", help="list of key=value tags to attach to the AMI", action='append', default=[]) - parser.add_argument("--winli", action="store_true", help="create an AWS Windows LI Ami") + parser.add_argument("--winli", action="store_true", help="create or replicate an AWS Windows LI Ami") parser.add_argument("--winli-billing-product", help="Windows billing product code used to create a Windows LI AMI") return parser