Archived
Add configurable Pi Web data directory
This commit is contained in:
@@ -220,10 +220,12 @@ Environment variables:
|
|||||||
|
|
||||||
- `PI_WEB_PORT` / `PORT` — web server port. Defaults to `8504`.
|
- `PI_WEB_PORT` / `PORT` — web server port. Defaults to `8504`.
|
||||||
- `PI_WEB_HOST` — web server bind host. Defaults to `127.0.0.1`.
|
- `PI_WEB_HOST` — web server bind host. Defaults to `127.0.0.1`.
|
||||||
- `PI_WEB_SESSIOND_SOCKET` — Unix socket path used by both the daemon and web process when `PI_WEB_SESSIOND_URL` is not set. Defaults to `~/.pi-web/sessiond.sock`.
|
- `PI_WEB_DATA_DIR` — Pi Web data directory. Defaults to `~/.pi-web`.
|
||||||
|
- `PI_WEB_SESSIOND_SOCKET` — Unix socket path used by both the daemon and web process when `PI_WEB_SESSIOND_URL` is not set. Defaults to `$PI_WEB_DATA_DIR/sessiond.sock`.
|
||||||
- `PI_WEB_SESSIOND_PORT` — optional TCP port for the daemon. If unset, the daemon listens on the Unix socket instead.
|
- `PI_WEB_SESSIOND_PORT` — optional TCP port for the daemon. If unset, the daemon listens on the Unix socket instead.
|
||||||
- `PI_WEB_SESSIOND_HOST` — daemon TCP bind host when `PI_WEB_SESSIOND_PORT` is set. Defaults to `127.0.0.1`.
|
- `PI_WEB_SESSIOND_HOST` — daemon TCP bind host when `PI_WEB_SESSIOND_PORT` is set. Defaults to `127.0.0.1`.
|
||||||
- `PI_WEB_SESSIOND_URL` — daemon URL used by the web process when connecting over TCP, for example `http://127.0.0.1:3001`. If you set `PI_WEB_SESSIOND_PORT`, set this for the web process too.
|
- `PI_WEB_SESSIOND_URL` — daemon URL used by the web process when connecting over TCP, for example `http://127.0.0.1:3001`. If you set `PI_WEB_SESSIOND_PORT`, set this for the web process too.
|
||||||
|
- `PI_WEB_PROJECTS_FILE` — optional override for the projects storage JSON file. Defaults to `$PI_WEB_DATA_DIR/projects.json`.
|
||||||
|
|
||||||
## systemd user services
|
## systemd user services
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,16 @@ export function defaultPiWebConfigPath(env: NodeJS.ProcessEnv = process.env): st
|
|||||||
return join(xdgConfigHome !== undefined && xdgConfigHome !== "" ? xdgConfigHome : join(homedir(), ".config"), "pi-web", "config.json");
|
return join(xdgConfigHome !== undefined && xdgConfigHome !== "" ? xdgConfigHome : join(homedir(), ".config"), "pi-web", "config.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function defaultPiWebDataDir(): string {
|
||||||
|
return join(homedir(), ".pi-web");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function piWebDataDir(env: NodeJS.ProcessEnv = process.env, cwd = process.cwd()): string {
|
||||||
|
const configured = env["PI_WEB_DATA_DIR"];
|
||||||
|
if (configured === undefined || configured === "") return defaultPiWebDataDir();
|
||||||
|
return resolve(cwd, configured);
|
||||||
|
}
|
||||||
|
|
||||||
export function piWebConfigPath(env: NodeJS.ProcessEnv = process.env, cwd = process.cwd()): string {
|
export function piWebConfigPath(env: NodeJS.ProcessEnv = process.env, cwd = process.cwd()): string {
|
||||||
const configured = env["PI_WEB_CONFIG"];
|
const configured = env["PI_WEB_CONFIG"];
|
||||||
if (configured === undefined || configured === "") return defaultPiWebConfigPath(env);
|
if (configured === undefined || configured === "") return defaultPiWebConfigPath(env);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { homedir } from "node:os";
|
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
|
import { piWebDataDir } from "../../config.js";
|
||||||
|
|
||||||
export function sessiondSocketPath(): string {
|
export function sessiondSocketPath(): string {
|
||||||
return process.env["PI_WEB_SESSIOND_SOCKET"] ?? join(homedir(), ".pi-web", "sessiond.sock");
|
return process.env["PI_WEB_SESSIOND_SOCKET"] ?? join(piWebDataDir(), "sessiond.sock");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sessiondHttpUrl(): string | undefined {
|
export function sessiondHttpUrl(): string | undefined {
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { join } from "node:path";
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { projectStorePath } from "./projectStore.js";
|
||||||
|
|
||||||
|
describe("projectStorePath", () => {
|
||||||
|
it("uses PI_WEB_DATA_DIR by default", () => {
|
||||||
|
expect(projectStorePath({ PI_WEB_DATA_DIR: "demo-data" }, "/tmp/pi-web")).toBe(join("/tmp/pi-web", "demo-data", "projects.json"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("uses PI_WEB_PROJECTS_FILE when configured", () => {
|
||||||
|
expect(projectStorePath({ PI_WEB_PROJECTS_FILE: "demo/projects.json" }, "/tmp/pi-web")).toBe(join("/tmp/pi-web", "demo/projects.json"));
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
||||||
import { dirname, join } from "node:path";
|
import { dirname, join, resolve } from "node:path";
|
||||||
import { homedir } from "node:os";
|
import { piWebDataDir } from "../../config.js";
|
||||||
import { randomUUID } from "node:crypto";
|
import { randomUUID } from "node:crypto";
|
||||||
import type { Project } from "../types.js";
|
import type { Project } from "../types.js";
|
||||||
|
|
||||||
@@ -31,8 +31,18 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|||||||
return typeof value === "object" && value !== null;
|
return typeof value === "object" && value !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function defaultProjectStorePath(env: NodeJS.ProcessEnv = process.env, cwd = process.cwd()): string {
|
||||||
|
return join(piWebDataDir(env, cwd), "projects.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function projectStorePath(env: NodeJS.ProcessEnv = process.env, cwd = process.cwd()): string {
|
||||||
|
const configured = env["PI_WEB_PROJECTS_FILE"];
|
||||||
|
if (configured === undefined || configured === "") return defaultProjectStorePath(env, cwd);
|
||||||
|
return resolve(cwd, configured);
|
||||||
|
}
|
||||||
|
|
||||||
export class ProjectStore {
|
export class ProjectStore {
|
||||||
constructor(private readonly filePath = join(homedir(), ".pi-web", "projects.json")) {}
|
constructor(private readonly filePath = projectStorePath()) {}
|
||||||
|
|
||||||
async list(): Promise<Project[]> {
|
async list(): Promise<Project[]> {
|
||||||
return (await this.read()).projects;
|
return (await this.read()).projects;
|
||||||
|
|||||||
Reference in New Issue
Block a user