A convenient CLI tool to quickly spin up DragonflyBSD virtual machines using QEMU with sensible defaults.
at main 111 lines 2.9 kB view raw
1import { Data, Effect } from "effect"; 2import type { DeleteResult, InsertResult, UpdateResult } from "kysely"; 3import { ctx } from "./context.ts"; 4import type { VirtualMachine } from "./db.ts"; 5import type { STATUS } from "./types.ts"; 6 7export class DbError extends Data.TaggedError("DatabaseError")<{ 8 cause?: unknown; 9}> {} 10 11export class InstanceNotFoundError 12 extends Data.TaggedError("InstanceNotFoundError")<{ 13 name: string; 14 message?: string; 15 }> {} 16 17export const saveInstanceState = ( 18 vm: VirtualMachine, 19): Effect.Effect<InsertResult[], DbError, never> => 20 Effect.tryPromise({ 21 try: () => 22 ctx.db.insertInto("virtual_machines") 23 .values(vm) 24 .execute(), 25 catch: (error) => new DbError({ cause: error }), 26 }); 27 28export const updateInstanceState = ( 29 name: string, 30 status: STATUS, 31 pid?: number, 32): Effect.Effect<UpdateResult[], DbError, never> => 33 Effect.tryPromise({ 34 try: () => 35 ctx.db.updateTable("virtual_machines") 36 .set({ 37 status, 38 pid, 39 updatedAt: new Date().toISOString(), 40 }) 41 .where((eb) => 42 eb.or([ 43 eb("name", "=", name), 44 eb("id", "=", name), 45 ]) 46 ) 47 .execute(), 48 catch: (error) => new DbError({ cause: error }), 49 }); 50 51export const removeInstanceState = ( 52 name: string, 53): Effect.Effect<DeleteResult[], DbError, never> => 54 Effect.tryPromise({ 55 try: () => 56 ctx.db.deleteFrom("virtual_machines") 57 .where((eb) => 58 eb.or([ 59 eb("name", "=", name), 60 eb("id", "=", name), 61 ]) 62 ) 63 .execute(), 64 catch: (error) => new DbError({ cause: error }), 65 }); 66 67export const getInstanceState = ( 68 name: string, 69): Effect.Effect<VirtualMachine | undefined, DbError, never> => 70 Effect.tryPromise({ 71 try: () => 72 ctx.db.selectFrom("virtual_machines") 73 .selectAll() 74 .where((eb) => 75 eb.or([ 76 eb("name", "=", name), 77 eb("id", "=", name), 78 ]) 79 ) 80 .executeTakeFirst(), 81 catch: (error) => new DbError({ cause: error }), 82 }); 83 84export const getInstanceStateOrFail = (name: string) => 85 Effect.flatMap( 86 getInstanceState(name), 87 (vm) => 88 vm ? Effect.succeed(vm) : Effect.fail( 89 new InstanceNotFoundError({ 90 name, 91 message: `Instance not found: ${name}`, 92 }), 93 ), 94 ); 95 96export const listInstances = ( 97 all: boolean, 98): Effect.Effect<VirtualMachine[], DbError, never> => 99 Effect.tryPromise({ 100 try: () => 101 ctx.db.selectFrom("virtual_machines") 102 .selectAll() 103 .where((eb) => { 104 if (all) { 105 return eb("id", "!=", ""); 106 } 107 return eb("status", "=", "RUNNING"); 108 }) 109 .execute(), 110 catch: (error) => new DbError({ cause: error }), 111 });