diff --git a/scripts/integration-vm.py b/scripts/integration-vm.py index c7c0248..bc879ee 100644 --- a/scripts/integration-vm.py +++ b/scripts/integration-vm.py @@ -306,6 +306,69 @@ def dump_diagnostics(name, ip): print(f"diagnostics written to {d}", file=sys.stderr) +def _destroy(name): + sh(["virsh", "destroy", name], check=False) + sh(["virsh", "undefine", name, "--nvram"], check=False) + for f in RUN_DIR.glob(f"{name}*"): + f.unlink(missing_ok=True) + + +def down(host=None, keep=False): + if keep: + print("--keep: leaving the VM running for inspection") + return + cur = RUN_DIR / "current" + if cur.exists(): + name = cur.read_text().splitlines()[0] + _destroy(name) + cur.unlink(missing_ok=True) + print(f"destroyed {name}") + + +def prune(): + running = sh(["virsh", "list", "--all", "--name"], capture=True).stdout.split() + for n in running: + if n.startswith(NAME_PREFIX): + _destroy(n) + print(f"pruned {n}") + (RUN_DIR / "current").unlink(missing_ok=True) + + +def console(): + name = (RUN_DIR / "current").read_text().splitlines()[0] + log = DIAG_ROOT / f"{name}-console.log" + print(log.read_text() if log.exists() else f"no console log at {log}") + + +def cycle(host, certs, keep=False, no_reboot=False): + ok = False + try: + up(host) + apply(host, certs) + if not no_reboot: + reboot_vm() + run_assert(host, certs) + ok = True + finally: + if ok and not keep: + down(host) + elif not ok: + print("FAILED — VM left up for inspection; `integration-vm prune` to clean.", + file=sys.stderr) + + +DISPATCH = { + "up": lambda a: (up(a.host), None)[1], + "apply": lambda a: apply(a.host, a.certs), + "reboot": lambda a: reboot_vm(), + "assert": lambda a: run_assert(a.host, a.certs), + "down": lambda a: down(a.host, a.keep), + "console": lambda a: console(), + "prune": lambda a: prune(), + "cycle": lambda a: cycle(a.host, a.certs, a.keep, a.no_reboot), +} + + def main(argv=None): p = argparse.ArgumentParser(prog="integration-vm", description=__doc__) sub = p.add_subparsers(dest="cmd", required=True)