mirror of
https://github.com/ipxe/ipxe.git
synced 2025-01-07 14:33:10 -06:00
77b07ea4fd
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>
69 lines
2.1 KiB
Python
Executable File
69 lines
2.1 KiB
Python
Executable File
#!/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)
|