A convenient CLI tool to quickly spin up DragonflyBSD virtual machines using QEMU with sensible defaults.
at main 69 lines 1.9 kB view raw
1import { Effect, pipe } from "effect"; 2import { LOGS_DIR } from "../constants.ts"; 3 4const ensureLogsDirectory = () => 5 Effect.tryPromise({ 6 try: () => Deno.mkdir(LOGS_DIR, { recursive: true }), 7 catch: (cause) => new Error(`Failed to create logs directory: ${cause}`), 8 }); 9 10const buildLogPath = (name: string) => 11 Effect.sync(() => `${LOGS_DIR}/${name}.log`); 12 13const buildLogCommand = (follow: boolean, logPath: string) => 14 Effect.sync(() => ({ 15 command: follow ? "tail" : "cat", 16 args: [ 17 ...(follow ? ["-n", "100", "-f"] : []), 18 logPath, 19 ], 20 })); 21 22const executeLogCommand = (command: string, args: string[]) => 23 Effect.tryPromise({ 24 try: async () => { 25 const cmd = new Deno.Command(command, { 26 args, 27 stdin: "inherit", 28 stdout: "inherit", 29 stderr: "inherit", 30 }); 31 32 return await cmd.spawn().status; 33 }, 34 catch: (cause) => new Error(`Failed to execute log command: ${cause}`), 35 }); 36 37const validateLogCommandResult = (name: string, status: Deno.CommandStatus) => 38 Effect.sync(() => { 39 if (!status.success) { 40 throw new Error(`Failed to view logs for virtual machine ${name}`); 41 } 42 }); 43 44const viewVirtualMachineLogs = (name: string, follow: boolean) => 45 pipe( 46 ensureLogsDirectory(), 47 Effect.flatMap(() => buildLogPath(name)), 48 Effect.flatMap((logPath) => 49 pipe( 50 buildLogCommand(follow, logPath), 51 Effect.flatMap(({ command, args }) => executeLogCommand(command, args)), 52 Effect.flatMap((status) => validateLogCommandResult(name, status)), 53 ) 54 ), 55 ); 56 57export default async function (name: string, follow: boolean) { 58 const program = pipe( 59 viewVirtualMachineLogs(name, follow), 60 Effect.catchAll((error) => 61 Effect.sync(() => { 62 console.error(`Error: ${String(error)}`); 63 Deno.exit(1); 64 }) 65 ), 66 ); 67 68 await Effect.runPromise(program); 69}