48 lines
1.6 KiB
TypeScript
48 lines
1.6 KiB
TypeScript
// 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;
|
|
}
|
|
}
|