diff options
author | Michael Brown <mcb30@ipxe.org> | 2023-11-07 18:05:45 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2023-11-07 18:05:45 +0000 |
commit | 77b07ea4fdc259d7253c6f9df2beda6e6c7a9d85 (patch) | |
tree | 1bfef5dcace38b30337edad88d6f605c9fc8e89b | |
parent | d8f9c221ede6d67a251134989a30bb850f8709e6 (diff) | |
download | ipxe-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-x | contrib/cloud/aws-int13con | 68 |
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) |