A Docker-like CLI and HTTP API for managing headless VMs
1import { Effect } from "effect";
2import { ctx } from "./context.ts";
3import type { VirtualMachine } from "./db.ts";
4import { DbError } from "./errors.ts";
5import type { STATUS } from "./types.ts";
6
7export const saveInstanceState = (vm: VirtualMachine) =>
8 Effect.tryPromise({
9 try: () => ctx.db.insertInto("virtual_machines").values(vm).execute(),
10 catch: (error) => new DbError({ cause: error }),
11 });
12
13export const updateInstanceState = (
14 name: string,
15 status: STATUS,
16 pid?: number,
17) =>
18 Effect.tryPromise({
19 try: () =>
20 ctx.db
21 .updateTable("virtual_machines")
22 .set({
23 status,
24 pid,
25 updatedAt: new Date().toISOString(),
26 })
27 .where((eb) => eb.or([eb("name", "=", name), eb("id", "=", name)]))
28 .execute(),
29 catch: (error) => new DbError({ cause: error }),
30 });
31
32export const removeInstanceState = (name: string) =>
33 Effect.tryPromise({
34 try: () =>
35 ctx.db
36 .deleteFrom("virtual_machines")
37 .where((eb) => eb.or([eb("name", "=", name), eb("id", "=", name)]))
38 .execute(),
39 catch: (error) => new DbError({ cause: error }),
40 });
41
42export const getInstanceState = (
43 name: string,
44): Effect.Effect<VirtualMachine | undefined, DbError, never> =>
45 Effect.tryPromise({
46 try: () =>
47 ctx.db
48 .selectFrom("virtual_machines")
49 .selectAll()
50 .where((eb) => eb.or([eb("name", "=", name), eb("id", "=", name)]))
51 .executeTakeFirst(),
52 catch: (error) => new DbError({ cause: error }),
53 });
54
55export const listInstances = (
56 all: boolean,
57): Effect.Effect<VirtualMachine[], DbError, never> =>
58 Effect.tryPromise({
59 try: () =>
60 ctx.db
61 .selectFrom("virtual_machines")
62 .selectAll()
63 .where((eb) => {
64 if (all) {
65 return eb("id", "!=", "");
66 }
67 return eb("status", "=", "RUNNING");
68 })
69 .execute(),
70 catch: (error) => new DbError({ cause: error }),
71 });