From be7dc0ecf87587063492da81191dbb308b7b9848 Mon Sep 17 00:00:00 2001 From: Matt Pryor Date: Fri, 19 Jan 2024 21:43:19 +0000 Subject: [PATCH] Read config drive without mounting (#130) * Read config drive without mounting * Remove redundant latest --- .../files/openstack-disk-tag | 66 ++++++++----------- .../roles/linux-volumes-by-tag/tasks/main.yml | 11 ++++ 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/ansible/roles/linux-volumes-by-tag/files/openstack-disk-tag b/ansible/roles/linux-volumes-by-tag/files/openstack-disk-tag index f3cb3d36..f1ef8643 100755 --- a/ansible/roles/linux-volumes-by-tag/files/openstack-disk-tag +++ b/ansible/roles/linux-volumes-by-tag/files/openstack-disk-tag @@ -2,12 +2,13 @@ import argparse import contextlib +import io import json import logging -import pathlib -import tempfile import subprocess +import pycdlib + logging.basicConfig( filename = "/var/log/openstack-disk-tag.log", @@ -19,55 +20,42 @@ logging.basicConfig( logger = logging.getLogger(__name__) -def run_cmd(*cmd): - logger.info(f"executing command - {' '.join(str(p) for p in cmd)}") - proc = subprocess.run(cmd, capture_output = True, check = True) - return proc.stdout.strip().decode() - - def get_config_device(): - return pathlib.Path( - run_cmd( + logger.info("attempting to locate config device") + proc = subprocess.run( + [ "/usr/sbin/blkid", "-t", "LABEL=config-2", "-o", "device" - ) + ], + capture_output = True ) + if proc.returncode == 0: + return proc.stdout.decode().strip() + else: + logger.warn("failed to locate config device") + return None @contextlib.contextmanager -def temporary_directory(dir = None): - with tempfile.TemporaryDirectory(dir = dir) as mnt_dir: - yield pathlib.Path(mnt_dir) - - -@contextlib.contextmanager -def mount(device, mnt_dir): - run_cmd( - "/usr/bin/mount", - "--read-only", - device, - mnt_dir - ) - try: - yield - finally: - run_cmd("/usr/bin/umount", mnt_dir) +def iso_open(path): + with open(path, "rb") as fp: + iso = pycdlib.PyCdlib() + iso.open_fp(fp) + try: + yield iso + finally: + iso.close() def get_instance_metadata(config_device): - # We mount the config device on a temporary directory - # Once it is mounted, we can extract the metadata - run_dir = pathlib.Path("/run/openstack-disk-tag") - run_dir.mkdir(mode = 0o755, parents = True, exist_ok = True) - with temporary_directory(run_dir) as mnt_dir: - with mount(config_device, mnt_dir): - metadata_path = mnt_dir / "openstack" / "latest" / "meta_data.json" - logger.info(f"loading metadata from {metadata_path}") - with metadata_path.open() as fd: - return json.load(fd) + logger.info(f"loading instance metadata from config device - {config_device}") + with iso_open(config_device) as iso: + data = io.BytesIO() + iso.get_file_from_iso_fp(data, iso_path = "/openstack/latest/meta_data.json;1") + return json.loads(data.getvalue()) def find_device_for_serial(metadata, serial): @@ -103,6 +91,8 @@ def main(): logger.info(f"running for device with serial number - {args.serial}") config_device = get_config_device() + if not config_device: + return metadata = get_instance_metadata(config_device) device = find_device_for_serial(metadata, args.serial) if device: diff --git a/ansible/roles/linux-volumes-by-tag/tasks/main.yml b/ansible/roles/linux-volumes-by-tag/tasks/main.yml index 23f2011e..dfdc14c4 100644 --- a/ansible/roles/linux-volumes-by-tag/tasks/main.yml +++ b/ansible/roles/linux-volumes-by-tag/tasks/main.yml @@ -1,5 +1,16 @@ --- +- name: Install pip + apt: + name: python3-pip + update_cache: yes + +- name: Install pycdlib + pip: + name: pycdlib + # Install into the distribution packages so that udev picks it up + extra_args: "--target /usr/lib/python3/dist-packages" + - name: Install openstack-disk-tag script copy: src: openstack-disk-tag