summaryrefslogtreecommitdiffstats
path: root/contrib/cloud
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cloud')
-rwxr-xr-xcontrib/cloud/aws-import15
-rwxr-xr-xcontrib/cloud/aws-int13con68
2 files changed, 81 insertions, 2 deletions
diff --git a/contrib/cloud/aws-import b/contrib/cloud/aws-import
index b9a350f6..ace00587 100755
--- a/contrib/cloud/aws-import
+++ b/contrib/cloud/aws-import
@@ -46,11 +46,19 @@ def create_snapshot(region, description, image):
return snapshot_id
-def import_image(region, name, architecture, image, public):
+def import_image(region, name, architecture, image, public, overwrite):
"""Import an AMI image"""
client = boto3.client('ec2', region_name=region)
resource = boto3.resource('ec2', region_name=region)
description = '%s (%s)' % (name, 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()
snapshot_id = create_snapshot(region=region, description=description,
image=image)
client.get_waiter('snapshot_completed').wait(SnapshotIds=[snapshot_id])
@@ -88,6 +96,8 @@ parser.add_argument('--name', '-n',
help="Image name")
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('--region', '-r', action='append',
help="AWS region(s)")
parser.add_argument('--wiki', '-w', metavar='FILE',
@@ -115,7 +125,8 @@ with ThreadPoolExecutor(max_workers=len(imports)) as executor:
name=args.name,
architecture=architectures[image],
image=image,
- public=args.public): (region, image)
+ public=args.public,
+ overwrite=args.overwrite): (region, image)
for region, image in imports}
results = {futures[future]: future.result()
for future in as_completed(futures)}
diff --git a/contrib/cloud/aws-int13con b/contrib/cloud/aws-int13con
new file mode 100755
index 00000000..b79b4065
--- /dev/null
+++ b/contrib/cloud/aws-int13con
@@ -0,0 +1,68 @@
+#!/usr/bin/env python3
+
+import argparse
+
+import boto3
+
+BLOCKSIZE = 512 * 1024
+
+IPXELOG_OFFSET = 16 * 1024
+
+IPXELOG_MAGIC = b'iPXE LOG'
+
+
+def create_snapshot(region, instance_id):
+ """Create root volume snapshot"""
+ client = boto3.client('ec2', region_name=region)
+ resource = boto3.resource('ec2', region_name=region)
+ instance = resource.Instance(instance_id)
+ volumes = list(instance.volumes.all())
+ snapshot = volumes[0].create_snapshot()
+ snapshot.wait_until_completed()
+ return snapshot.id
+
+
+def get_snapshot_block(region, snapshot_id, index):
+ """Get block content from snapshot"""
+ client = boto3.client('ebs', region_name=region)
+ blocks = client.list_snapshot_blocks(SnapshotId=snapshot_id,
+ StartingBlockIndex=index)
+ token = blocks['Blocks'][0]['BlockToken']
+ block = client.get_snapshot_block(SnapshotId=snapshot_id,
+ BlockIndex=index,
+ BlockToken=token)
+ return block['BlockData'].read()
+
+
+def get_block0_content(region, instance_id):
+ """Get content of root volume block zero from instance"""
+ client = boto3.client('ec2', region_name=region)
+ resource = boto3.resource('ec2', region_name=region)
+ snapshot_id = create_snapshot(region, instance_id)
+ block = get_snapshot_block(region, snapshot_id, 0)
+ resource.Snapshot(snapshot_id).delete()
+ return block
+
+
+def get_int13con_output(region, instance_id):
+ """Get INT13 console output"""
+ block = get_block0_content(region, instance_id)
+ logpart = block[IPXELOG_OFFSET:]
+ magic = logpart[:len(IPXELOG_MAGIC)]
+ if magic != IPXELOG_MAGIC:
+ raise ValueError("Invalid log magic signature")
+ log = logpart[len(IPXELOG_MAGIC):].split(b'\0')[0]
+ return log.decode()
+
+
+# Parse command-line arguments
+parser = argparse.ArgumentParser(description="Get AWS INT13 console output")
+parser.add_argument('--region', '-r', help="AWS region")
+parser.add_argument('id', help="Instance ID")
+args = parser.parse_args()
+
+# Get console output from INT13CON partition
+output = get_int13con_output(args.region, args.id)
+
+# Print console output
+print(output)