[cloud] Allow multiple images to be imported simultaneously

Allow both x86_64 and arm64 images to be imported in a single import
command, thereby allowing for e.g.

  make CONFIG=cloud EMBED=config/cloud/aws.ipxe bin/ipxe.usb

  make CONFIG=cloud EMBED=config/cloud/aws.ipxe \
       CROSS=aarch64-linux-gnu- bin-arm64-efi/ipxe.usb

  ../contrib/cloud/aws-import -w amilist.txt -p \
       bin/ipxe.usb bin-arm64-efi/ipxe.usb

This simplifies the process of generating a single amilist.txt file
for inclusion in the documentation at https://ipxe.org/howto/ec2

Signed-off-by: Michael Brown <mcb30@ipxe.org>
pull/373/head
Michael Brown 2021-05-02 12:23:00 +01:00
parent 1dfc05622d
commit 106f4c5391
1 changed files with 19 additions and 19 deletions

View File

@ -92,33 +92,31 @@ parser.add_argument('--region', '-r', action='append',
help="AWS region(s)") help="AWS region(s)")
parser.add_argument('--wiki', '-w', metavar='FILE', parser.add_argument('--wiki', '-w', metavar='FILE',
help="Generate Dokuwiki table") help="Generate Dokuwiki table")
parser.add_argument('image', help="iPXE disk image") parser.add_argument('image', nargs='+', help="iPXE disk image")
args = parser.parse_args() args = parser.parse_args()
# Detect CPU architecture # Detect CPU architectures
architecture = detect_architecture(args.image) architectures = {image: detect_architecture(image) for image in args.image}
# Use default name if none specified # Use default name if none specified
if not args.name: if not args.name:
args.name = 'iPXE (%s %s)' % ( args.name = 'iPXE (%s)' % date.today().strftime('%Y-%m-%d')
date.today().strftime('%Y-%m-%d'),
architecture,
)
# Use all regions if none specified # Use all regions if none specified
if not args.region: if not args.region:
args.region = sorted(x['RegionName'] for x in args.region = sorted(x['RegionName'] for x in
boto3.client('ec2').describe_regions()['Regions']) boto3.client('ec2').describe_regions()['Regions'])
# Use one thread per region to maximise parallelism # Use one thread per import to maximise parallelism
with ThreadPoolExecutor(max_workers=len(args.region)) as executor: imports = [(region, image) for region in args.region for image in args.image]
with ThreadPoolExecutor(max_workers=len(imports)) as executor:
futures = {executor.submit(import_image, futures = {executor.submit(import_image,
region=region, region=region,
name=args.name, name=args.name,
architecture=architecture, architecture=architectures[image],
image=args.image, image=image,
public=args.public): region public=args.public): (region, image)
for region in args.region} for region, image in imports}
results = {futures[future]: future.result() results = {futures[future]: future.result()
for future in as_completed(futures)} for future in as_completed(futures)}
@ -126,14 +124,16 @@ with ThreadPoolExecutor(max_workers=len(args.region)) as executor:
wikitab = ["^ AWS region ^ CPU architecture ^ AMI ID ^\n"] + list( wikitab = ["^ AWS region ^ CPU architecture ^ AMI ID ^\n"] + list(
"| ''%s'' | ''%s'' | ''[[%s|%s]]'' |\n" % ( "| ''%s'' | ''%s'' | ''[[%s|%s]]'' |\n" % (
region, region,
architecture, architectures[image],
launch_link(region, results[region]), launch_link(region, results[(region, image)]),
results[region], results[(region, image)],
) for region in args.region) ) for region, image in imports)
if args.wiki: if args.wiki:
with open(args.wiki, 'wt') as fh: with open(args.wiki, 'wt') as fh:
fh.writelines(wikitab) fh.writelines(wikitab)
# Show created images # Show created images
for region in args.region: for region, image in imports:
print("%s %s %s" % (region, architecture, results[region])) print("%s %s %s %s" % (
region, image, architectures[image], results[(region, image)]
))