mirror of
https://github.com/ipxe/ipxe.git
synced 2026-05-04 20:06:30 +02:00
Update the descriptive text for the disk log console tools to remove
references to INT13, since these now work for both BIOS and UEFI disk
log consoles.
Leave the script names as {aws,gce,ali}-int13con, to avoid breaking
any existing tooling that might use these names.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
149 lines
5.7 KiB
Python
Executable File
149 lines
5.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import textwrap
|
|
import time
|
|
from uuid import uuid4
|
|
|
|
from google.cloud import compute
|
|
|
|
IPXE_LOG_PREFIX = 'ipxe-log-temp-'
|
|
IPXE_LOG_MAGIC = 'iPXE LOG'
|
|
IPXE_LOG_END = '----- END OF iPXE LOG -----'
|
|
|
|
def get_log_disk(instances, project, zone, name):
|
|
"""Get log disk source URL"""
|
|
instance = instances.get(project=project, zone=zone, instance=name)
|
|
disk = next(x for x in instance.disks if x.boot)
|
|
return disk.source
|
|
|
|
def delete_temp_snapshot(snapshots, project, name):
|
|
"""Delete temporary snapshot"""
|
|
assert name.startswith(IPXE_LOG_PREFIX)
|
|
snapshots.delete(project=project, snapshot=name)
|
|
|
|
def delete_temp_snapshots(snapshots, project):
|
|
"""Delete all old temporary snapshots"""
|
|
filter = "name eq %s.+" % IPXE_LOG_PREFIX
|
|
request = compute.ListSnapshotsRequest(project=project, filter=filter)
|
|
for snapshot in snapshots.list(request=request):
|
|
delete_temp_snapshot(snapshots, project, snapshot.name)
|
|
|
|
def create_temp_snapshot(snapshots, project, source):
|
|
"""Create temporary snapshot"""
|
|
name = '%s%s' % (IPXE_LOG_PREFIX, uuid4())
|
|
snapshot = compute.Snapshot(name=name, source_disk=source)
|
|
snapshots.insert(project=project, snapshot_resource=snapshot).result()
|
|
return name
|
|
|
|
def delete_temp_instance(instances, project, zone, name):
|
|
"""Delete log dumper temporary instance"""
|
|
assert name.startswith(IPXE_LOG_PREFIX)
|
|
instances.delete(project=project, zone=zone, instance=name)
|
|
|
|
def delete_temp_instances(instances, project, zone):
|
|
"""Delete all old log dumper temporary instances"""
|
|
filter = "name eq %s.+" % IPXE_LOG_PREFIX
|
|
request = compute.ListInstancesRequest(project=project, zone=zone,
|
|
filter=filter)
|
|
for instance in instances.list(request=request):
|
|
delete_temp_instance(instances, project, zone, instance.name)
|
|
|
|
def create_temp_instance(instances, project, zone, family, image, machine,
|
|
snapshot):
|
|
"""Create log dumper temporary instance"""
|
|
image = "projects/%s/global/images/family/%s" % (family, image)
|
|
machine_type = "zones/%s/machineTypes/%s" % (zone, machine)
|
|
logsource = "global/snapshots/%s" % snapshot
|
|
bootparams = compute.AttachedDiskInitializeParams(source_image=image)
|
|
bootdisk = compute.AttachedDisk(boot=True, auto_delete=True,
|
|
initialize_params=bootparams)
|
|
logparams = compute.AttachedDiskInitializeParams(source_snapshot=logsource)
|
|
logdisk = compute.AttachedDisk(boot=False, auto_delete=True,
|
|
initialize_params=logparams,
|
|
device_name="ipxelog")
|
|
nic = compute.NetworkInterface()
|
|
name = '%s%s' % (IPXE_LOG_PREFIX, uuid4())
|
|
script = textwrap.dedent(f"""
|
|
#!/bin/sh
|
|
tr -d '\\000' < /dev/disk/by-id/google-ipxelog-part3 > /dev/ttyS3
|
|
echo "{IPXE_LOG_END}" > /dev/ttyS3
|
|
""").strip()
|
|
items = compute.Items(key="startup-script", value=script)
|
|
metadata = compute.Metadata(items=[items])
|
|
instance = compute.Instance(name=name, machine_type=machine_type,
|
|
network_interfaces=[nic], metadata=metadata,
|
|
disks=[bootdisk, logdisk])
|
|
instances.insert(project=project, zone=zone,
|
|
instance_resource=instance).result()
|
|
return name
|
|
|
|
def get_log_output(instances, project, zone, name):
|
|
"""Get iPXE log output"""
|
|
request = compute.GetSerialPortOutputInstanceRequest(project=project,
|
|
zone=zone, port=4,
|
|
instance=name)
|
|
while True:
|
|
log = instances.get_serial_port_output(request=request).contents.strip()
|
|
if log.endswith(IPXE_LOG_END):
|
|
if log.startswith(IPXE_LOG_MAGIC):
|
|
return log[len(IPXE_LOG_MAGIC):-len(IPXE_LOG_END)]
|
|
else:
|
|
return log[:-len(IPXE_LOG_END)]
|
|
time.sleep(1)
|
|
|
|
# Parse command-line arguments
|
|
#
|
|
parser = argparse.ArgumentParser(
|
|
description="Get Google Cloud disk console output"
|
|
)
|
|
parser.add_argument('--project', '-j', default="ipxe-images",
|
|
help="Google Cloud project")
|
|
parser.add_argument('--zone', '-z', required=True,
|
|
help="Google Cloud zone")
|
|
parser.add_argument('--family', '-f', default="debian-cloud",
|
|
help="Helper OS image family")
|
|
parser.add_argument('--image', '-i', default="debian-12",
|
|
help="Helper OS image")
|
|
parser.add_argument('--machine', '-m', default="e2-micro",
|
|
help="Helper machine type")
|
|
parser.add_argument('instance', help="Instance name")
|
|
args = parser.parse_args()
|
|
|
|
# Construct client objects
|
|
#
|
|
instances = compute.InstancesClient()
|
|
snapshots = compute.SnapshotsClient()
|
|
|
|
# Clean up old temporary objects
|
|
#
|
|
delete_temp_instances(instances, project=args.project, zone=args.zone)
|
|
delete_temp_snapshots(snapshots, project=args.project)
|
|
|
|
# Create log disk snapshot
|
|
#
|
|
logdisk = get_log_disk(instances, project=args.project, zone=args.zone,
|
|
name=args.instance)
|
|
logsnap = create_temp_snapshot(snapshots, project=args.project, source=logdisk)
|
|
|
|
# Create log dumper instance
|
|
#
|
|
dumper = create_temp_instance(instances, project=args.project, zone=args.zone,
|
|
family=args.family, image=args.image,
|
|
machine=args.machine, snapshot=logsnap)
|
|
|
|
# Wait for log output
|
|
#
|
|
output = get_log_output(instances, project=args.project, zone=args.zone,
|
|
name=dumper)
|
|
|
|
# Print log output
|
|
#
|
|
print(output)
|
|
|
|
# Clean up
|
|
#
|
|
delete_temp_instance(instances, project=args.project, zone=args.zone,
|
|
name=dumper)
|
|
delete_temp_snapshot(snapshots, project=args.project, name=logsnap)
|