// wrapper import { log_from, sleep } from "./utils.ts"; import { ContainerConfigRedirection } from "./config.ts"; const log = log_from("nspawn"); export function container_command(name: string, directory: string, opts?: { veth?: boolean; boot?: boolean; redirections?: ContainerConfigRedirection[]; cmd_opts?: Deno.CommandOptions; syscall_filter?: string[]; }) { const args = [ `--machine=${name}`, `--directory=${directory}`, ]; if (opts?.veth ?? false) args.push("--network-veth"); if (opts?.boot ?? false) args.push("--boot"); for (const redir of opts?.redirections ?? []) { if (redir.kind === "http") args.push(`--port=${redir.port}`); if (redir.kind === "port") { args.push(`--port=tcp:${redir.from}:${redir.to}`); args.push(`--port=udp:${redir.from}:${redir.to}`); } } for (const call of opts?.syscall_filter ?? []) args.push(`--system-call-filter=${call}`); const command = new Deno.Command("systemd-nspawn", { ...opts?.cmd_opts, args }); return command; } export async function get_container_addresses(name: string) { const command = new Deno.Command("machinectl", { args: ["status", name], stdout: "piped" }); while (true) { await sleep(500); log("getting address of", name); const { code, stdout } = await command.output(); if (code != 0) continue; const output = new TextDecoder().decode(stdout); const [_, rest] = output.split(" Address: "); if (rest === undefined) continue; const [raw] = rest.split(" OS: "); const addresses = raw.trim().split("\n").map((l) => l.trim()); if (addresses.length === 0) continue; return addresses; } }