// Libvirt network management for integration tests. import { execSync, spawnSync } from "node:child_process"; import { writeFileSync, unlinkSync } from "node:fs"; import { log } from "./libvirt.js"; export const TEST_NETWORK_NAME = "lab-test"; export const TEST_NETWORK_BRIDGE = "virbr-lab"; export const TEST_NETWORK_SUBNET = "192.168.250"; export const TEST_NETWORK_GATEWAY = `${TEST_NETWORK_SUBNET}.1`; const IS_ROOT = process.getuid?.() === 0; function run(cmd: string): string { const full = IS_ROOT ? cmd : `sudo ${cmd}`; return execSync(full, { encoding: "utf-8", stdio: "pipe" }); } function virsh(...args: string[]): { status: number; stdout: string } { const cmd = IS_ROOT ? "virsh" : "sudo"; const finalArgs = IS_ROOT ? args : ["virsh", ...args]; const result = spawnSync(cmd, finalArgs, { encoding: "utf-8", stdio: "pipe" }); return { status: result.status ?? 1, stdout: result.stdout ?? "" }; } const NETWORK_XML = ` ${TEST_NETWORK_NAME} `; /** Ensure the test libvirt network exists and is active. */ export function ensureTestNetwork(): void { const result = virsh("net-info", TEST_NETWORK_NAME); if (result.status === 0 && result.stdout.includes("Active: yes")) { log(`Network ${TEST_NETWORK_NAME} already active`); return; } // Destroy existing if present but inactive if (result.status === 0) { virsh("net-destroy", TEST_NETWORK_NAME); virsh("net-undefine", TEST_NETWORK_NAME); } const xmlPath = `/tmp/lab-test-network.xml`; writeFileSync(xmlPath, NETWORK_XML); log(`Creating libvirt network: ${TEST_NETWORK_NAME} (${TEST_NETWORK_SUBNET}.0/24)`); run(`virsh net-define "${xmlPath}"`); run(`virsh net-start "${TEST_NETWORK_NAME}"`); try { unlinkSync(xmlPath); } catch { /* ignore */ } log(`Network ${TEST_NETWORK_NAME} created and active`); } /** Destroy the test network. */ export function destroyTestNetwork(): void { log(`Destroying network: ${TEST_NETWORK_NAME}`); virsh("net-destroy", TEST_NETWORK_NAME); virsh("net-undefine", TEST_NETWORK_NAME); }