feat: auto create db folder & better errors
This commit is contained in:
parent
34a642f33b
commit
f94e0c3611
41
flake.lock
Normal file
41
flake.lock
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1710734606,
|
||||||
|
"narHash": "sha256-rFJl+WXfksu2NkWJWKGd5Km17ZGEjFg9hOQNwstsoU8=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "79bb4155141a5e68f2bdee2bf6af35b1d27d3a1d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs",
|
||||||
|
"systems": "systems"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
28
flake.nix
Normal file
28
flake.nix
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
inputs = {
|
||||||
|
systems.url = "github:nix-systems/default";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = {
|
||||||
|
systems,
|
||||||
|
nixpkgs,
|
||||||
|
...
|
||||||
|
} @ inputs: let
|
||||||
|
eachSystem = f:
|
||||||
|
nixpkgs.lib.genAttrs (import systems) (
|
||||||
|
system:
|
||||||
|
f nixpkgs.legacyPackages.${system}
|
||||||
|
);
|
||||||
|
in {
|
||||||
|
devShells = eachSystem (pkgs: {
|
||||||
|
default = pkgs.mkShell {
|
||||||
|
buildInputs = [
|
||||||
|
pkgs.nodejs_20
|
||||||
|
pkgs.nodePackages.pnpm
|
||||||
|
pkgs.nodePackages.typescript
|
||||||
|
pkgs.nodePackages.typescript-language-server
|
||||||
|
];
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
|
@ -26,7 +26,7 @@ export default async function DashboardHome() {
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<p className="text-primary-foreground/70">
|
<p className="text-primary-foreground/75">
|
||||||
<Check className="mr-2 inline-block" />
|
<Check className="mr-2 inline-block" />
|
||||||
Hostforge is up to date. (v1.0.0)
|
Hostforge is up to date. (v1.0.0)
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -17,7 +17,7 @@ export default function Error({
|
||||||
if (
|
if (
|
||||||
error.stack &&
|
error.stack &&
|
||||||
error.stack.split("\n")[0] ===
|
error.stack.split("\n")[0] ===
|
||||||
"TRPCClientError: You must be logged in to perform this action."
|
"TRPCClientError: You must be logged in to perform this action."
|
||||||
) {
|
) {
|
||||||
console.log("redirecting to login");
|
console.log("redirecting to login");
|
||||||
return redirect("/login");
|
return redirect("/login");
|
||||||
|
@ -35,6 +35,13 @@ export default function Error({
|
||||||
Please start the Docker daemon and reload the page.
|
Please start the Docker daemon and reload the page.
|
||||||
</p>
|
</p>
|
||||||
</Card>
|
</Card>
|
||||||
|
) : error.message.includes("This node is not a swarm manager.") ? (
|
||||||
|
<Card className="p-4">
|
||||||
|
<h2>Docker is not running in swarm mode.</h2>
|
||||||
|
<p className="text-sm">
|
||||||
|
Check our wiki for instructions on how to resolve this issue.
|
||||||
|
</p>
|
||||||
|
</Card>
|
||||||
) : (
|
) : (
|
||||||
<h2>
|
<h2>
|
||||||
An unexpected error has occured: <br /> {error.message}
|
An unexpected error has occured: <br /> {error.message}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import SQLite3 from "better-sqlite3";
|
import SQLite3 from "better-sqlite3";
|
||||||
|
import chalk from "chalk";
|
||||||
import { drizzle } from "drizzle-orm/better-sqlite3";
|
import { drizzle } from "drizzle-orm/better-sqlite3";
|
||||||
|
import fs from "node:fs";
|
||||||
|
import path from "node:path";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { env } from "~/env";
|
import { env } from "~/env";
|
||||||
import logger from "../utils/logger";
|
import logger from "../utils/logger";
|
||||||
|
@ -10,6 +13,37 @@ const globalForDB = globalThis as unknown as {
|
||||||
};
|
};
|
||||||
|
|
||||||
function createDatabaseInstance() {
|
function createDatabaseInstance() {
|
||||||
|
const LOGGER = logger.child({ module: "database" });
|
||||||
|
|
||||||
|
// Create database folder if does not exist
|
||||||
|
const databaseFolder = path.resolve(path.dirname(env.DATABASE_PATH));
|
||||||
|
|
||||||
|
if (!fs.existsSync(databaseFolder)) {
|
||||||
|
LOGGER.debug(
|
||||||
|
`Folder "${chalk.yellow(databaseFolder)}" does not exist, creating...`,
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.mkdirSync(databaseFolder, {
|
||||||
|
recursive: true,
|
||||||
|
mode: 0o700,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
LOGGER.error(
|
||||||
|
`Failed to create database directory. Either create it manually or check the permissions of the parent folder.`,
|
||||||
|
error,
|
||||||
|
);
|
||||||
|
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.info(
|
||||||
|
`Created previously non-existent database folder ${chalk.yellow(
|
||||||
|
databaseFolder,
|
||||||
|
)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const sqlite = new SQLite3(env.DATABASE_PATH);
|
const sqlite = new SQLite3(env.DATABASE_PATH);
|
||||||
|
|
||||||
// enable WAL mode
|
// enable WAL mode
|
||||||
|
@ -17,6 +51,14 @@ function createDatabaseInstance() {
|
||||||
|
|
||||||
// load uuidv7 extension
|
// load uuidv7 extension
|
||||||
// built from https://github.com/craigpastro/sqlite-uuidv7
|
// built from https://github.com/craigpastro/sqlite-uuidv7
|
||||||
|
if (env.SQLITE_UUIDV7_EXT_PATH) {
|
||||||
|
LOGGER.warn(
|
||||||
|
`Be careful when loading custom UUIDv7 extensions, currently Hostforge is set to load from: "${chalk.yellow(
|
||||||
|
path.resolve(env.SQLITE_UUIDV7_EXT_PATH),
|
||||||
|
)}"! Non-official extensions may contain backdoors or introduce new vulnerabilities.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
sqlite.loadExtension(
|
sqlite.loadExtension(
|
||||||
env.SQLITE_UUIDV7_EXT_PATH ??
|
env.SQLITE_UUIDV7_EXT_PATH ??
|
||||||
join(
|
join(
|
||||||
|
@ -30,7 +72,7 @@ function createDatabaseInstance() {
|
||||||
schema,
|
schema,
|
||||||
logger: {
|
logger: {
|
||||||
logQuery(query) {
|
logQuery(query) {
|
||||||
logger.child({ module: "database" }).debug(query);
|
LOGGER.debug(query);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue