A simple, powerful CLI tool to spin up OpenIndiana virtual machines with QEMU
1import { Database as Sqlite } from "@db/sqlite";
2import { DenoSqlite3Dialect } from "@soapbox/kysely-deno-sqlite";
3import {
4 Kysely,
5 type Migration,
6 type MigrationProvider,
7 Migrator,
8 sql,
9} from "kysely";
10import { CONFIG_DIR } from "./constants.ts";
11import type { STATUS } from "./types.ts";
12
13export const createDb = (location: string): Database => {
14 Deno.mkdirSync(CONFIG_DIR, { recursive: true });
15 return new Kysely<DatabaseSchema>({
16 dialect: new DenoSqlite3Dialect({
17 database: new Sqlite(location),
18 }),
19 });
20};
21
22export type DatabaseSchema = {
23 virtual_machines: VirtualMachine;
24};
25
26export type VirtualMachine = {
27 id: string;
28 name: string;
29 bridge?: string;
30 macAddress: string;
31 memory: string;
32 cpus: number;
33 cpu: string;
34 diskSize: string;
35 drivePath?: string;
36 diskFormat: string;
37 isoPath?: string;
38 portForward?: string;
39 version: string;
40 status: STATUS;
41 pid: number;
42 createdAt?: string;
43 updatedAt?: string;
44};
45
46const migrations: Record<string, Migration> = {};
47
48const migrationProvider: MigrationProvider = {
49 // deno-lint-ignore require-await
50 async getMigrations() {
51 return migrations;
52 },
53};
54
55migrations["001"] = {
56 async up(db: Kysely<unknown>): Promise<void> {
57 await db.schema
58 .createTable("virtual_machines")
59 .addColumn("id", "varchar", (col) => col.primaryKey())
60 .addColumn("name", "varchar", (col) => col.notNull().unique())
61 .addColumn("bridge", "varchar")
62 .addColumn("macAddress", "varchar", (col) => col.notNull().unique())
63 .addColumn("memory", "varchar", (col) => col.notNull())
64 .addColumn("cpus", "integer", (col) => col.notNull())
65 .addColumn("cpu", "varchar", (col) => col.notNull())
66 .addColumn("diskSize", "varchar", (col) => col.notNull())
67 .addColumn("drivePath", "varchar")
68 .addColumn("version", "varchar", (col) => col.notNull())
69 .addColumn("diskFormat", "varchar")
70 .addColumn("isoPath", "varchar")
71 .addColumn("status", "varchar", (col) => col.notNull())
72 .addColumn("pid", "integer")
73 .addColumn(
74 "createdAt",
75 "varchar",
76 (col) => col.notNull().defaultTo(sql`CURRENT_TIMESTAMP`),
77 )
78 .addColumn(
79 "updatedAt",
80 "varchar",
81 (col) => col.notNull().defaultTo(sql`CURRENT_TIMESTAMP`),
82 )
83 .execute();
84 },
85
86 async down(db: Kysely<unknown>): Promise<void> {
87 await db.schema.dropTable("virtual_machines").execute();
88 },
89};
90
91migrations["002"] = {
92 async up(db: Kysely<unknown>): Promise<void> {
93 await db.schema
94 .alterTable("virtual_machines")
95 .addColumn("portForward", "varchar")
96 .execute();
97 },
98
99 async down(db: Kysely<unknown>): Promise<void> {
100 await db.schema
101 .alterTable("virtual_machines")
102 .dropColumn("portForward")
103 .execute();
104 },
105};
106
107export const migrateToLatest = async (db: Database): Promise<void> => {
108 const migrator = new Migrator({ db, provider: migrationProvider });
109 const { error } = await migrator.migrateToLatest();
110 if (error) throw error;
111};
112
113export type Database = Kysely<DatabaseSchema>;