aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2023-11-07 18:05:45 +0000
committerMichael Brown <mcb30@ipxe.org>2023-11-07 18:05:45 +0000
commit77b07ea4fdc259d7253c6f9df2beda6e6c7a9d85 (patch)
tree1bfef5dcace38b30337edad88d6f605c9fc8e89b
parentd8f9c221ede6d67a251134989a30bb850f8709e6 (diff)
downloadipxe-77b07ea4fdc259d7253c6f9df2beda6e6c7a9d85.zip
ipxe-77b07ea4fdc259d7253c6f9df2beda6e6c7a9d85.tar.gz
ipxe-77b07ea4fdc259d7253c6f9df2beda6e6c7a9d85.tar.bz2
[cloud] Add utility script to read iPXE output from INT13CON partition
Some AWS instance types still do not support serial console output or screenshots. For these instance types, the only viable way to extract debugging information is to use the INT13 console (which is already enabled via CONFIG=cloud for all AWS images). Obtaining the INT13 console output can be very cumbersome, since there is no direct way to read from an AWS volume. The simplest current approach is to stop the instance under test, detach its root volume, and reattach the volume to a Linux instance in the same region. Add a utility script aws-int13con to retrieve the INT13 console output by creating a temporary snapshot, reading the first block from the snapshot, and extracting the INT13 console partition content. Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rwxr-xr-xcontrib/cloud/aws-int13con68
1 files changed, 68 insertions, 0 deletions
diff --git a/contrib/cloud/aws-int13con b/contrib/cloud/aws-int13con
new file mode 100755
index 0000000..b79b406
--- /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)