stabilize, add daemon state, add base build script

This commit is contained in:
JOLIMAITRE Matthieu 2023-12-10 22:04:40 +01:00
parent a1963cf491
commit 241d50e42a
12 changed files with 512 additions and 46 deletions

View file

@ -1,6 +1,13 @@
export type { Base, BaseContext } from "./lib/create.ts";
import { toText } from "https://deno.land/std@0.208.0/streams/to_text.ts";
import { lines } from "./lib/utils.ts";
import { lines, log_from, loop_process, LoopProcess, run, sleep } from "./lib/utils.ts";
import { ContainerConfig } from "./lib/config.ts";
import { container_paths } from "./lib/paths.ts";
import { container_command, get_container_addresses } from "./lib/nspawn.ts";
import { proxy_command } from "./bin/proxy.ts";
const log = log_from("lib");
export type CmdStatus = ReturnType<typeof new_cmd_status>;
export function new_cmd_status() {
@ -17,15 +24,22 @@ export function new_cmd_disable(name: string) {
return { kind: "disable" as const, name };
}
export type CmdReload = ReturnType<typeof new_cmd_reload>;
export function new_cmd_reload(name: string) {
return { kind: "reload" as const, name };
}
export type CmdStop = ReturnType<typeof new_cmd_stop>;
export function new_cmd_stop() {
return { kind: "stop" as const };
}
export type Cmd = CmdStatus | CmdEnable | CmdDisable | CmdStop;
export type Cmd = CmdStatus | CmdEnable | CmdDisable | CmdReload | CmdStop;
export function daemon_listen(sock_path: string) {
export async function daemon_listen(sock_path: string) {
const server = Deno.listen({ transport: "unix", path: sock_path });
await Deno.chmod(sock_path, 0o775);
await run("chgrp", "wheel", sock_path);
const generator = async function* () {
for await (const request of server) {
const respond = async (message: string) => {
@ -53,12 +67,52 @@ export async function daemon_send(sock_path: string, command: Cmd) {
return await toText(request.readable);
}
export type Runner = ReturnType<typeof start_runner>;
export type Runner = Awaited<ReturnType<typeof start_runner>>;
export function start_runner(config: ContainerConfig) {
const { name } = config;
const paths = container_paths(name);
const command = container_command(name, paths.root, {
boot: true,
veth: true,
cmd_opts: {
stdin: "null",
stdout: "null",
},
});
const proxies = [] as LoopProcess[];
const container_loop = loop_process(command, {
on_start: () => {
log("container", name, "started");
(async () => {
await sleep(1_000);
const [address] = await get_container_addresses(name);
proxies.push(...start_proxies(address, config.redirects));
})();
},
on_stop: async () => {
log("container", name, "stopped");
for (const p of proxies) await p.kill();
await sleep(500);
proxies.splice(0, proxies.length);
},
});
return {
name: config.name,
name,
config,
container_loop,
stop: async () => {
// TODO
for (const p of proxies) await p.kill();
await container_loop.kill();
},
};
}
function start_proxies(address: string, redirects: [number, number][]) {
const redirections = redirects
.map(([from_port, to_port]) => {
return loop_process(proxy_command(from_port, address, to_port), {
on_start: () => console.log("starting proxy", from_port, "to", address, "port", to_port),
});
});
return redirections;
}