A simple, zero-configuration script to quickly boot FreeBSD ISO images using QEMU
1import { Data, Effect } from "effect";
2import { ctx } from "./context.ts";
3import type { VirtualMachine } from "./db.ts";
4import type { STATUS } from "./types.ts";
5
6export class DbError extends Data.TaggedError("DatabaseError")<{
7 cause?: unknown;
8}> {}
9
10export const saveInstanceState = (
11 vm: VirtualMachine,
12) =>
13 Effect.tryPromise({
14 try: () =>
15 ctx.db.insertInto("virtual_machines")
16 .values(vm)
17 .execute(),
18 catch: (error) => new DbError({ cause: error }),
19 });
20
21export const updateInstanceState = (
22 name: string,
23 status: STATUS,
24 pid?: number,
25) =>
26 Effect.tryPromise({
27 try: () =>
28 ctx.db.updateTable("virtual_machines")
29 .set({
30 status,
31 pid,
32 updatedAt: new Date().toISOString(),
33 })
34 .where((eb) =>
35 eb.or([
36 eb("name", "=", name),
37 eb("id", "=", name),
38 ])
39 )
40 .execute(),
41 catch: (error) => new DbError({ cause: error }),
42 });
43
44export const removeInstanceState = (
45 name: string,
46) =>
47 Effect.tryPromise({
48 try: () =>
49 ctx.db.deleteFrom("virtual_machines")
50 .where((eb) =>
51 eb.or([
52 eb("name", "=", name),
53 eb("id", "=", name),
54 ])
55 )
56 .execute(),
57 catch: (error) => new DbError({ cause: error }),
58 });
59
60export const getInstanceState = (
61 name: string,
62): Effect.Effect<VirtualMachine | undefined, DbError, never> =>
63 Effect.tryPromise({
64 try: () =>
65 ctx.db.selectFrom("virtual_machines")
66 .selectAll()
67 .where((eb) =>
68 eb.or([
69 eb("name", "=", name),
70 eb("id", "=", name),
71 ])
72 )
73 .executeTakeFirst(),
74 catch: (error) => new DbError({ cause: error }),
75 });
76
77export const listInstances = (
78 all: boolean,
79): Effect.Effect<VirtualMachine[], DbError, never> =>
80 Effect.tryPromise({
81 try: () =>
82 ctx.db.selectFrom("virtual_machines")
83 .selectAll()
84 .where((eb) => {
85 if (all) {
86 return eb("id", "!=", "");
87 }
88 return eb("status", "=", "RUNNING");
89 })
90 .execute(),
91 catch: (error) => new DbError({ cause: error }),
92 });