@codions/portta 0.0.0-develop.155.sha-e6e3870 → 0.0.0-develop.157.sha-ae5ce5e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +92 -64
- package/dist/documentation.json +1 -1
- package/dist/host.js +1 -1
- package/dist/runtime/.env.example +30 -17
- package/dist/runtime/VERSION +1 -1
- package/dist/runtime/docker/compose/features/panel-public.yaml +6 -8
- package/dist/runtime/docker/compose/features/web.yaml +8 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -22364,7 +22364,7 @@ var init_package = __esm({
|
|
|
22364
22364
|
"package.json"() {
|
|
22365
22365
|
package_default = {
|
|
22366
22366
|
name: "@codions/portta",
|
|
22367
|
-
version: "0.0.0-develop.
|
|
22367
|
+
version: "0.0.0-develop.157.sha-ae5ce5e",
|
|
22368
22368
|
description: "Machine-first CLI for a shared Docker development gateway",
|
|
22369
22369
|
license: "MIT",
|
|
22370
22370
|
type: "module",
|
|
@@ -22438,7 +22438,7 @@ var init_version = __esm({
|
|
|
22438
22438
|
"use strict";
|
|
22439
22439
|
init_package();
|
|
22440
22440
|
CLI_VERSION = package_default.version;
|
|
22441
|
-
CLI_BUILD_DATE = true ? "2026-09-
|
|
22441
|
+
CLI_BUILD_DATE = true ? "2026-09-16T21:32:25Z" : void 0;
|
|
22442
22442
|
}
|
|
22443
22443
|
});
|
|
22444
22444
|
|
|
@@ -89799,7 +89799,7 @@ function createDaemonTaskflowHost(context) {
|
|
|
89799
89799
|
port: hostListen(env).port,
|
|
89800
89800
|
workflowBuiltinsDir: taskflowAssets(env).workflowBuiltinsDir,
|
|
89801
89801
|
version: env.PORTTA_VERSION || "0.0.0-local",
|
|
89802
|
-
buildDate: true ? "2026-09-
|
|
89802
|
+
buildDate: true ? "2026-09-16T21:32:25Z" : (/* @__PURE__ */ new Date()).toISOString(),
|
|
89803
89803
|
environmentStore: createEnvironmentStore(paths3.database),
|
|
89804
89804
|
hostEnvironmentProvider: new HostEnvironmentProvider(),
|
|
89805
89805
|
devContainerProvider: new DevContainerProvider(),
|
|
@@ -100395,7 +100395,7 @@ var require_network = __commonJS({
|
|
|
100395
100395
|
var exec3 = __require("child_process").exec;
|
|
100396
100396
|
var execSync = __require("child_process").execSync;
|
|
100397
100397
|
var execFileSync2 = __require("child_process").execFileSync;
|
|
100398
|
-
var
|
|
100398
|
+
var readFileSync39 = __require("fs").readFileSync;
|
|
100399
100399
|
var fs = __require("fs");
|
|
100400
100400
|
var util2 = require_util2();
|
|
100401
100401
|
var _platform = process.platform;
|
|
@@ -100883,7 +100883,7 @@ var require_network = __commonJS({
|
|
|
100883
100883
|
return result;
|
|
100884
100884
|
}
|
|
100885
100885
|
try {
|
|
100886
|
-
const content =
|
|
100886
|
+
const content = readFileSync39(file2, { encoding: "utf8" });
|
|
100887
100887
|
const lines = content.split("\n").filter((l) => /iface|source/.test(l));
|
|
100888
100888
|
lines.forEach((line4) => {
|
|
100889
100889
|
const parts2 = line4.replace(/\s+/g, " ").trim().split(" ");
|
|
@@ -120141,7 +120141,7 @@ async function runtimeAction(action, options, command) {
|
|
|
120141
120141
|
init_src();
|
|
120142
120142
|
init_src();
|
|
120143
120143
|
init_context();
|
|
120144
|
-
import { chmodSync as chmodSync9, existsSync as existsSync38, mkdirSync as mkdirSync18, readFileSync as
|
|
120144
|
+
import { chmodSync as chmodSync9, existsSync as existsSync38, mkdirSync as mkdirSync18, readFileSync as readFileSync31, readdirSync as readdirSync8, rmSync as rmSync10 } from "node:fs";
|
|
120145
120145
|
import { join as join57 } from "node:path";
|
|
120146
120146
|
init_errors3();
|
|
120147
120147
|
init_version();
|
|
@@ -120763,35 +120763,9 @@ async function runDoctor(context) {
|
|
|
120763
120763
|
const socket = (proxy.mounts ?? []).find((mount) => mount.source.includes("docker.sock"));
|
|
120764
120764
|
add(!socket ? check2("proxy.socket", "warn", "docker socket mount", "could not determine mount mode") : socket.readWrite ? check2("proxy.socket", "fail", "docker socket mount", "mounted read-write", "mount /var/run/docker.sock read-only (:ro)") : check2("proxy.socket", "pass", "docker socket mount", "read-only"));
|
|
120765
120765
|
}
|
|
120766
|
-
|
|
120767
|
-
|
|
120768
|
-
|
|
120769
|
-
add(database.state === "running" ? check2("db.state", "pass", "panel database", "running") : config3.webEnabled ? check2("db.state", "fail", "panel database", `state=${database.state}; the panel refuses to start without it`, "portta web up") : check2("db.state", "warn", "panel database", `state=${database.state}; the panel is off, so nothing needs it`, "portta web up"));
|
|
120770
|
-
const dbPublished = publishedBindings(database);
|
|
120771
|
-
add(dbPublished ? check2(
|
|
120772
|
-
"db.exposure",
|
|
120773
|
-
"fail",
|
|
120774
|
-
"panel database exposure",
|
|
120775
|
-
`publishes host ports: ${dbPublished}`,
|
|
120776
|
-
"remove every ports entry from docker/compose/features/db.yaml and recreate the database container"
|
|
120777
|
-
) : check2("db.exposure", "pass", "panel database exposure", "no host ports published"));
|
|
120778
|
-
add(database.networks.includes(config3.network) ? check2(
|
|
120779
|
-
"db.network.shared",
|
|
120780
|
-
"fail",
|
|
120781
|
-
"panel database network",
|
|
120782
|
-
`attached to the shared HTTP network '${config3.network}'`,
|
|
120783
|
-
`detach it; the panel database belongs only on '${dbNetwork}'`
|
|
120784
|
-
) : check2("db.network.shared", "pass", "panel database network", "off the shared HTTP network"));
|
|
120785
|
-
const data = await networkFacts(dbNetwork);
|
|
120786
|
-
add(!data.exists ? check2("db.network.internal", "warn", "panel data network", "not created yet", "portta web up") : data.internal ? check2("db.network.internal", "pass", "panel data network", `${dbNetwork} (internal)`) : check2(
|
|
120787
|
-
"db.network.internal",
|
|
120788
|
-
"fail",
|
|
120789
|
-
"panel data network",
|
|
120790
|
-
`${dbNetwork} is not internal`,
|
|
120791
|
-
"recreate the panel database network from docker/compose/features/db.yaml"
|
|
120792
|
-
));
|
|
120793
|
-
} else if (config3.webEnabled) {
|
|
120794
|
-
add(check2("db.state", "warn", "panel database", "container not created; the panel will refuse to start without it", "portta web up"));
|
|
120766
|
+
if (config3.webEnabled) {
|
|
120767
|
+
const databaseFile = databaseFileFor(root2);
|
|
120768
|
+
add(existsSync33(databaseFile) ? check2("db.file", "pass", "panel database", databaseFile) : check2("db.file", "warn", "panel database", `${databaseFile} not created yet; the panel creates it on first boot`, "portta web up"));
|
|
120795
120769
|
}
|
|
120796
120770
|
const panelIsPublic = (env["PORTTA_WEB_EXPOSE"] || "local") === "public";
|
|
120797
120771
|
if (traefik && traefik.state === "running") {
|
|
@@ -121380,7 +121354,7 @@ async function reexecBuiltCli(root2) {
|
|
|
121380
121354
|
init_src();
|
|
121381
121355
|
init_context();
|
|
121382
121356
|
init_errors3();
|
|
121383
|
-
import { existsSync as existsSync37, readdirSync as readdirSync7 } from "node:fs";
|
|
121357
|
+
import { existsSync as existsSync37, readdirSync as readdirSync7, readFileSync as readFileSync30 } from "node:fs";
|
|
121384
121358
|
import { basename as basename19, join as join56 } from "node:path";
|
|
121385
121359
|
var PORTTA_DIRECTORY = ".portta";
|
|
121386
121360
|
var OVERLAY_FILE = "compose.portta.yaml";
|
|
@@ -121388,6 +121362,7 @@ var COMPOSE_FILE = "compose.yaml";
|
|
|
121388
121362
|
var PANEL_WAIT_MS2 = 12e4;
|
|
121389
121363
|
var PANEL_POLL_MS2 = 500;
|
|
121390
121364
|
var DEMO_DIRECTORY_PREFIX = "portta-demo-";
|
|
121365
|
+
var MANIFEST_FILE = "portta.example.json";
|
|
121391
121366
|
function demoDirectories(home2) {
|
|
121392
121367
|
if (!existsSync37(home2)) return [];
|
|
121393
121368
|
return readdirSync7(home2, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.startsWith(DEMO_DIRECTORY_PREFIX)).map((entry) => join56(home2, entry.name)).sort();
|
|
@@ -121410,6 +121385,48 @@ function demoComposeArgs(stack, action) {
|
|
|
121410
121385
|
if (action === "up") return ["compose", ...files, "up", "-d"];
|
|
121411
121386
|
return ["compose", ...files, "down", "-v"];
|
|
121412
121387
|
}
|
|
121388
|
+
function readDemoProject(stackDir) {
|
|
121389
|
+
const path7 = join56(stackDir, PORTTA_DIRECTORY, MANIFEST_FILE);
|
|
121390
|
+
if (!existsSync37(path7)) return null;
|
|
121391
|
+
try {
|
|
121392
|
+
const manifest = JSON.parse(readFileSync30(path7, "utf8"));
|
|
121393
|
+
const project2 = manifest.project;
|
|
121394
|
+
if (typeof project2?.["slug"] !== "string" || typeof project2["name"] !== "string") return null;
|
|
121395
|
+
const repositories = (Array.isArray(manifest.repositories) ? manifest.repositories : []).filter((repository) => typeof repository?.["name"] === "string" && typeof repository["relativePath"] === "string").map((repository) => ({
|
|
121396
|
+
name: repository["name"],
|
|
121397
|
+
role: typeof repository["role"] === "string" ? repository["role"] : null,
|
|
121398
|
+
relativePath: repository["relativePath"]
|
|
121399
|
+
}));
|
|
121400
|
+
return {
|
|
121401
|
+
slug: project2["slug"],
|
|
121402
|
+
name: project2["name"],
|
|
121403
|
+
description: typeof project2["description"] === "string" ? project2["description"] : null,
|
|
121404
|
+
relativePath: typeof project2["relativePath"] === "string" ? project2["relativePath"] : basename19(stackDir),
|
|
121405
|
+
repositories
|
|
121406
|
+
};
|
|
121407
|
+
} catch {
|
|
121408
|
+
return null;
|
|
121409
|
+
}
|
|
121410
|
+
}
|
|
121411
|
+
async function registerDemoProjects(command, stacks, token) {
|
|
121412
|
+
const projects2 = stacks.map((stack) => readDemoProject(stack.dir)).filter((project2) => project2 !== null);
|
|
121413
|
+
if (projects2.length === 0) return;
|
|
121414
|
+
const { client, output: output2 } = clientFor(command, { actor: void 0, actorKind: "human", ...token ? { token } : {} });
|
|
121415
|
+
for (const { repositories, ...project2 } of projects2) {
|
|
121416
|
+
const created = await client.answer("POST", "/projects", project2);
|
|
121417
|
+
if (created.ok) output2.progress(`registered Project ${project2.name} (${project2.slug})`);
|
|
121418
|
+
else if (created.status === 409) output2.progress(`Project ${project2.slug} already registered`);
|
|
121419
|
+
else {
|
|
121420
|
+
output2.warning(`could not register Project ${project2.slug}: the panel answered ${created.status}`);
|
|
121421
|
+
output2.hint(`portta projects create --slug ${project2.slug} --path ${project2.relativePath}`);
|
|
121422
|
+
continue;
|
|
121423
|
+
}
|
|
121424
|
+
for (const repository of repositories) {
|
|
121425
|
+
const added = await client.answer("POST", `/projects/${encodeURIComponent(project2.slug)}/repositories`, repository);
|
|
121426
|
+
if (!added.ok && added.status !== 409) output2.warning(`could not register repository ${repository.name} on ${project2.slug}: the panel answered ${added.status}`);
|
|
121427
|
+
}
|
|
121428
|
+
}
|
|
121429
|
+
}
|
|
121413
121430
|
function outputFor(command) {
|
|
121414
121431
|
return new Output(workGlobals(command));
|
|
121415
121432
|
}
|
|
@@ -121419,15 +121436,24 @@ function demoHome(command) {
|
|
|
121419
121436
|
const configured = context.env["PORTTA_PROJECTS_HOME"]?.trim() || defaultProjectsHome(userHome, typeof process.getuid === "function" && process.getuid() === 0);
|
|
121420
121437
|
return normalizeProjectsHome(configured, context.root, userHome);
|
|
121421
121438
|
}
|
|
121422
|
-
|
|
121439
|
+
function requireDemoStacks(command) {
|
|
121440
|
+
const home2 = demoHome(command);
|
|
121441
|
+
const stacks = findDemoStacks(home2);
|
|
121442
|
+
if (stacks.length > 0) return stacks;
|
|
121443
|
+
throw new PreconditionError(
|
|
121444
|
+
`--demo found no portta-demo-* Compose project in ${home2}`,
|
|
121445
|
+
"clone the example repositories there, or set PORTTA_PROJECTS_HOME in .env to the directory that holds them"
|
|
121446
|
+
);
|
|
121447
|
+
}
|
|
121448
|
+
async function demoStacksUp(command, token) {
|
|
121423
121449
|
const output2 = outputFor(command);
|
|
121424
|
-
const stacks =
|
|
121425
|
-
if (stacks.length === 0) return;
|
|
121450
|
+
const stacks = requireDemoStacks(command);
|
|
121426
121451
|
output2.step("demo stacks");
|
|
121427
121452
|
for (const stack of stacks) {
|
|
121428
121453
|
output2.progress(`starting ${stack.name}`);
|
|
121429
121454
|
await runProcess("docker", demoComposeArgs(stack, "up"), { cwd: stack.dir, stdio: "inherit" });
|
|
121430
121455
|
}
|
|
121456
|
+
await registerDemoProjects(command, stacks, token);
|
|
121431
121457
|
}
|
|
121432
121458
|
async function demoStacksDown(command) {
|
|
121433
121459
|
const output2 = outputFor(command);
|
|
@@ -121625,6 +121651,7 @@ async function upCommand(profile, options, command) {
|
|
|
121625
121651
|
if (options.localRelease) selectLocalRelease(gatewayContext({ profile: profile ?? globals8(command).profile }));
|
|
121626
121652
|
const context = gatewayContext({ profile: profile ?? globals8(command).profile });
|
|
121627
121653
|
if (options.localRelease) context.env["PORTTA_LOCAL_RELEASE"] = "true";
|
|
121654
|
+
if (options.demo) requireDemoStacks(command);
|
|
121628
121655
|
if (context.config.profile === "remote-public" && context.config.tcpEnabled) throw new RefusedError("TCP entrypoints must not run on the remote-public profile");
|
|
121629
121656
|
if (context.config.profile === "remote-public" && context.config.webEnabled && context.config.webExpose === "vpn") {
|
|
121630
121657
|
throw new RefusedError(
|
|
@@ -121683,6 +121710,7 @@ async function devCommand(profile, options, command) {
|
|
|
121683
121710
|
await reexecBuiltCli(existing.root);
|
|
121684
121711
|
return;
|
|
121685
121712
|
}
|
|
121713
|
+
if (options.demo) requireDemoStacks(command);
|
|
121686
121714
|
const needsBootstrap = !existsSync38(join57(existing.root, ".env"));
|
|
121687
121715
|
output2.progress(`dev runs: ${[
|
|
121688
121716
|
...options.reset ? ["wipe Portta-managed containers and volumes"] : [],
|
|
@@ -121704,7 +121732,7 @@ async function devCommand(profile, options, command) {
|
|
|
121704
121732
|
await waitForPanel(command);
|
|
121705
121733
|
const demoToken = await ensureDevDemoOwner(command);
|
|
121706
121734
|
await finishWebUp(panel, command, false, demoToken);
|
|
121707
|
-
if (options.demo) await demoStacksUp(command);
|
|
121735
|
+
if (options.demo) await demoStacksUp(command, demoToken);
|
|
121708
121736
|
await urlsCommand({}, command);
|
|
121709
121737
|
}
|
|
121710
121738
|
async function downCommand(options, command) {
|
|
@@ -121886,7 +121914,7 @@ function readAliases(root2) {
|
|
|
121886
121914
|
const path7 = join57(root2, "config/traefik/dynamic/portta-aliases.yaml");
|
|
121887
121915
|
if (!existsSync38(path7)) return [];
|
|
121888
121916
|
try {
|
|
121889
|
-
return parseAliases(
|
|
121917
|
+
return parseAliases(readFileSync31(path7, "utf8"));
|
|
121890
121918
|
} catch {
|
|
121891
121919
|
return [];
|
|
121892
121920
|
}
|
|
@@ -122039,7 +122067,7 @@ async function dnsSetup(options, command) {
|
|
|
122039
122067
|
|
|
122040
122068
|
// src/commands/host-service.ts
|
|
122041
122069
|
init_config2();
|
|
122042
|
-
import { chmodSync as chmodSync10, existsSync as existsSync39, mkdirSync as mkdirSync19, readFileSync as
|
|
122070
|
+
import { chmodSync as chmodSync10, existsSync as existsSync39, mkdirSync as mkdirSync19, readFileSync as readFileSync32, realpathSync as realpathSync7, unlinkSync as unlinkSync6, writeFileSync as writeFileSync15 } from "node:fs";
|
|
122043
122071
|
import { homedir as homedir10 } from "node:os";
|
|
122044
122072
|
import { dirname as dirname29, join as join59 } from "node:path";
|
|
122045
122073
|
init_context();
|
|
@@ -122120,7 +122148,7 @@ var LAUNCHD_ENV_ENTRY_RE = /<key>([^<]+)<\/key>\s*<string>([^<]*)<\/string>/g;
|
|
|
122120
122148
|
function readEnvVarsFromUnit(filePath, platform4) {
|
|
122121
122149
|
let text;
|
|
122122
122150
|
try {
|
|
122123
|
-
text =
|
|
122151
|
+
text = readFileSync32(filePath, "utf8");
|
|
122124
122152
|
} catch {
|
|
122125
122153
|
return {};
|
|
122126
122154
|
}
|
|
@@ -122357,7 +122385,7 @@ async function configGet(name, command) {
|
|
|
122357
122385
|
const global3 = globals10(command);
|
|
122358
122386
|
const context = gatewayContext({ profile: global3.profile });
|
|
122359
122387
|
const item = setting(name);
|
|
122360
|
-
if (SECRETS.has(item.key)) throw new RefusedError(`${name} is a secret and is never printed`, "portta
|
|
122388
|
+
if (SECRETS.has(item.key)) throw new RefusedError(`${name} is a secret and is never printed`, "portta doctor reports whether it is set");
|
|
122361
122389
|
const value3 = context.env[item.key] ?? "";
|
|
122362
122390
|
const output2 = new Output(global3);
|
|
122363
122391
|
if (output2.json) output2.data({ setting: name, variable: item.key, value: value3 });
|
|
@@ -122521,7 +122549,7 @@ async function configSet(name, value3, options, command) {
|
|
|
122521
122549
|
const output2 = new Output(global3);
|
|
122522
122550
|
const context = gatewayContext({ profile: global3.profile });
|
|
122523
122551
|
const item = setting(name);
|
|
122524
|
-
if (SECRETS.has(item.key)) throw new RefusedError(`${name} is a secret and is not set this way`, "portta web
|
|
122552
|
+
if (SECRETS.has(item.key)) throw new RefusedError(`${name} is a secret and is not set this way`, "edit .env; portta web up generates PORTTA_AUTH_SECRET when it is empty");
|
|
122525
122553
|
if (item.allowed && !item.allowed.includes(value3)) throw new UsageError(`${name} must be one of: ${item.allowed.join(", ")}`);
|
|
122526
122554
|
let values;
|
|
122527
122555
|
if (name === "panel.access") values = await setPanelAccess(context.root, value3, output2);
|
|
@@ -122644,7 +122672,7 @@ async function setupCommand(options, command) {
|
|
|
122644
122672
|
const envFile = join61(target, ".env");
|
|
122645
122673
|
prepareEnvFile(envFile);
|
|
122646
122674
|
record6("environment", "updated", "environment prepared from .env.example");
|
|
122647
|
-
for (const directory of ["state", "state/auth", "state/ssh", "state/runner", "state/access", "state/cloudflared", "state/git", "state/
|
|
122675
|
+
for (const directory of ["state", "state/auth", "state/ssh", "state/runner", "state/access", "state/cloudflared", "state/git", "state/metrics", "state/environment", "state/logs", "config/tls", "config/traefik/dynamic"]) mkdirSync20(join61(target, directory), { recursive: true });
|
|
122648
122676
|
for (const directory of ["state/auth", "state/ssh", "state/runner", "state/cloudflared"]) chmodSync11(join61(target, directory), 448);
|
|
122649
122677
|
record6("directories", "ok", "gateway state directories");
|
|
122650
122678
|
const context = gatewayContext({ root: target, profile });
|
|
@@ -122666,7 +122694,7 @@ async function setupCommand(options, command) {
|
|
|
122666
122694
|
// src/commands/auth.ts
|
|
122667
122695
|
init_context();
|
|
122668
122696
|
init_errors3();
|
|
122669
|
-
import { readFileSync as
|
|
122697
|
+
import { readFileSync as readFileSync33 } from "node:fs";
|
|
122670
122698
|
function globals12(command) {
|
|
122671
122699
|
return command.optsWithGlobals();
|
|
122672
122700
|
}
|
|
@@ -122681,7 +122709,7 @@ function panelUrlFor2(command) {
|
|
|
122681
122709
|
}
|
|
122682
122710
|
async function authBootstrap(options, command) {
|
|
122683
122711
|
if (!options.name || !options.email) throw new UsageError("--name and --email are required");
|
|
122684
|
-
const password = options.passwordStdin ?
|
|
122712
|
+
const password = options.passwordStdin ? readFileSync33(0, "utf8").trim() : "";
|
|
122685
122713
|
if (!password) throw new UsageError("the password is read from stdin", 'printf %s "$PASSWORD" | portta auth bootstrap --name \u2026 --email \u2026 --password-stdin');
|
|
122686
122714
|
if (password.length < 10) throw new UsageError("the password must be at least 10 characters");
|
|
122687
122715
|
const { client, output: output2 } = clientFor(command, { actor: void 0, actorKind: "human" });
|
|
@@ -122714,7 +122742,7 @@ async function authLogin(options, command) {
|
|
|
122714
122742
|
}
|
|
122715
122743
|
async function readSecret() {
|
|
122716
122744
|
if (!process.stdin.isTTY) {
|
|
122717
|
-
const piped =
|
|
122745
|
+
const piped = readFileSync33(0, "utf8").trim();
|
|
122718
122746
|
if (piped) return piped;
|
|
122719
122747
|
throw new UsageError("no token on stdin", "pass --token, or run this in a terminal");
|
|
122720
122748
|
}
|
|
@@ -122853,7 +122881,7 @@ init_src();
|
|
|
122853
122881
|
init_context();
|
|
122854
122882
|
init_errors3();
|
|
122855
122883
|
import { randomBytes as randomBytes8 } from "node:crypto";
|
|
122856
|
-
import { chmodSync as chmodSync12, mkdirSync as mkdirSync21, readFileSync as
|
|
122884
|
+
import { chmodSync as chmodSync12, mkdirSync as mkdirSync21, readFileSync as readFileSync34 } from "node:fs";
|
|
122857
122885
|
import { dirname as dirname31, join as join62 } from "node:path";
|
|
122858
122886
|
function globals13(command) {
|
|
122859
122887
|
return command.optsWithGlobals();
|
|
@@ -122885,7 +122913,7 @@ async function protectHost(hostInput, options, command) {
|
|
|
122885
122913
|
const entryPoint = options.entrypoint ?? (gatewayContext({ profile: globals13(command).profile }).config.tlsEnabled ? "websecure" : "web");
|
|
122886
122914
|
if (!/^[A-Za-z0-9_-]+$/.test(entryPoint)) throw new UsageError(`invalid entrypoint: ${entryPoint}`);
|
|
122887
122915
|
const generated = options.passwordStdin !== true;
|
|
122888
|
-
const password = generated ? randomBytes8(20).toString("base64url").slice(0, 20).match(/.{1,5}/g).join("-") :
|
|
122916
|
+
const password = generated ? randomBytes8(20).toString("base64url").slice(0, 20).match(/.{1,5}/g).join("-") : readFileSync34(0, "utf8").trim();
|
|
122889
122917
|
if (!password) throw new UsageError("no password on stdin");
|
|
122890
122918
|
const target = paths(command);
|
|
122891
122919
|
const existing = readProtectionStore(target.store);
|
|
@@ -122938,11 +122966,11 @@ async function protectStatus(hostInput, command) {
|
|
|
122938
122966
|
init_src();
|
|
122939
122967
|
init_errors3();
|
|
122940
122968
|
init_context();
|
|
122941
|
-
import { readFileSync as
|
|
122969
|
+
import { readFileSync as readFileSync35 } from "node:fs";
|
|
122942
122970
|
import { randomBytes as randomBytes9 } from "node:crypto";
|
|
122943
122971
|
function passwordFrom(options) {
|
|
122944
122972
|
if (options.passwordStdin) {
|
|
122945
|
-
const password2 =
|
|
122973
|
+
const password2 = readFileSync35(0, "utf8").trim();
|
|
122946
122974
|
if (!password2) throw new UsageError("no password on stdin");
|
|
122947
122975
|
if (password2.length < 10) throw new UsageError("the password must be at least 10 characters");
|
|
122948
122976
|
return { password: password2, generated: false };
|
|
@@ -123335,7 +123363,7 @@ function paths2(root2) {
|
|
|
123335
123363
|
init_src();
|
|
123336
123364
|
init_context();
|
|
123337
123365
|
init_errors3();
|
|
123338
|
-
import { chmodSync as chmodSync14, copyFileSync as copyFileSync5, cpSync as cpSync2, existsSync as existsSync43, mkdirSync as mkdirSync23, mkdtempSync as mkdtempSync3, readFileSync as
|
|
123366
|
+
import { chmodSync as chmodSync14, copyFileSync as copyFileSync5, cpSync as cpSync2, existsSync as existsSync43, mkdirSync as mkdirSync23, mkdtempSync as mkdtempSync3, readFileSync as readFileSync36, rmSync as rmSync12, statSync as statSync12, writeFileSync as writeFileSync17 } from "node:fs";
|
|
123339
123367
|
import { hostname as hostname3, tmpdir as tmpdir5 } from "node:os";
|
|
123340
123368
|
import { dirname as dirname32, join as join65 } from "node:path";
|
|
123341
123369
|
function globals16(command) {
|
|
@@ -123398,7 +123426,7 @@ async function backupCommand(options, command) {
|
|
|
123398
123426
|
database = await dumpDatabase(context, join65(staging, "panel.db"));
|
|
123399
123427
|
if (!database) {
|
|
123400
123428
|
output2.warning("the panel database was not included");
|
|
123401
|
-
output2.hint("it
|
|
123429
|
+
output2.hint("it exists once the panel has started, and copying it needs sqlite3 on this host; --no-database silences this");
|
|
123402
123430
|
}
|
|
123403
123431
|
}
|
|
123404
123432
|
const previous = process.umask(63);
|
|
@@ -123447,7 +123475,7 @@ async function restoreCommand(archive, options, command) {
|
|
|
123447
123475
|
if (extracted.failed) throw new UsageError("that file is not a Portta backup");
|
|
123448
123476
|
const manifestPath2 = join65(staging, "portta-backup.json");
|
|
123449
123477
|
if (!existsSync43(manifestPath2)) throw new UsageError("that archive has no Portta manifest");
|
|
123450
|
-
const manifest = parseManifest(
|
|
123478
|
+
const manifest = parseManifest(readFileSync36(manifestPath2, "utf8"));
|
|
123451
123479
|
if (!manifest) throw new UsageError("that archive has an unreadable Portta manifest");
|
|
123452
123480
|
output2.progress(`restoring a backup taken from Portta ${manifest.portta}`);
|
|
123453
123481
|
if (!options.force && await containerRunning(`${context.env["PORTTA_PROJECT_NAME"] || "portta"}-traefik-1`)) {
|
|
@@ -128559,7 +128587,7 @@ async function buildCommand(command) {
|
|
|
128559
128587
|
|
|
128560
128588
|
// src/commands/remote.ts
|
|
128561
128589
|
init_src();
|
|
128562
|
-
import { existsSync as existsSync44, mkdirSync as mkdirSync24, readFileSync as
|
|
128590
|
+
import { existsSync as existsSync44, mkdirSync as mkdirSync24, readFileSync as readFileSync37, readdirSync as readdirSync10, rmSync as rmSync13, writeFileSync as writeFileSync18 } from "node:fs";
|
|
128563
128591
|
import { basename as basename20, join as join67 } from "node:path";
|
|
128564
128592
|
import { createServer as createServer3 } from "node:net";
|
|
128565
128593
|
import { randomBytes as randomBytes10 } from "node:crypto";
|
|
@@ -128770,7 +128798,7 @@ function readTunnels(root2) {
|
|
|
128770
128798
|
for (const name of readdirSync10(directory).filter((entry) => entry.endsWith(".json"))) {
|
|
128771
128799
|
const path7 = join67(directory, name);
|
|
128772
128800
|
try {
|
|
128773
|
-
const record6 = parseTunnelRecord(basename20(name, ".json"),
|
|
128801
|
+
const record6 = parseTunnelRecord(basename20(name, ".json"), readFileSync37(path7, "utf8"));
|
|
128774
128802
|
if (record6) records.push(record6);
|
|
128775
128803
|
} catch {
|
|
128776
128804
|
}
|
|
@@ -128904,7 +128932,7 @@ init_src();
|
|
|
128904
128932
|
init_src();
|
|
128905
128933
|
init_context();
|
|
128906
128934
|
init_errors3();
|
|
128907
|
-
import { chmodSync as chmodSync15, closeSync as closeSync3, existsSync as existsSync45, mkdirSync as mkdirSync25, openSync as openSync3, readFileSync as
|
|
128935
|
+
import { chmodSync as chmodSync15, closeSync as closeSync3, existsSync as existsSync45, mkdirSync as mkdirSync25, openSync as openSync3, readFileSync as readFileSync38, rmSync as rmSync14, writeFileSync as writeFileSync19 } from "node:fs";
|
|
128908
128936
|
import { ReadStream } from "node:tty";
|
|
128909
128937
|
import { join as join68 } from "node:path";
|
|
128910
128938
|
function globals20(command) {
|
|
@@ -129047,7 +129075,7 @@ async function tunnelSetup(options, command) {
|
|
|
129047
129075
|
let token;
|
|
129048
129076
|
if (options.tokenFile) {
|
|
129049
129077
|
if (!existsSync45(options.tokenFile)) throw new UsageError(`no such file: ${options.tokenFile}`);
|
|
129050
|
-
token =
|
|
129078
|
+
token = readFileSync38(options.tokenFile, "utf8").replace(/\s+/g, "");
|
|
129051
129079
|
} else {
|
|
129052
129080
|
token = await promptForToken();
|
|
129053
129081
|
}
|
|
@@ -129225,10 +129253,10 @@ describe3(program2.command("version"), "Print the installed version").action((_o
|
|
|
129225
129253
|
describe3(program2.command("setup"), "Install or update a gateway from the packaged runtime").option("--dir <path>", "gateway installation directory").option("--dry-run", "print the idempotent plan without changing anything").option("--skip-pull", "do not pull images").action(setupCommand);
|
|
129226
129254
|
describe3(program2.command("bootstrap"), "Prepare this installation and run diagnostics").option("--skip-pull", "do not pull component images").action(bootstrapCommand);
|
|
129227
129255
|
describe3(program2.command("build"), "Build every local Portta image for this checkout").action((_options, command) => buildCommand(command));
|
|
129228
|
-
describe3(program2.command("up [profile]"), "Start gateway components").option("--local-release", "use the locally built image for this checkout").option("--attach", "run in the foreground").option("--demo", "also start portta-demo-* projects from PORTTA_PROJECTS_HOME
|
|
129229
|
-
describe3(program2.command("dev [profile]"), "Start a checkout from local Dockerfiles, never the published images").option("--reset", "stop every Portta-managed stack, drop their volumes, and start as if this checkout were new").option("--demo", "also start portta-demo-* projects from PORTTA_PROJECTS_HOME
|
|
129256
|
+
describe3(program2.command("up [profile]"), "Start gateway components").option("--local-release", "use the locally built image for this checkout").option("--attach", "run in the foreground").option("--demo", "also start portta-demo-* projects from PORTTA_PROJECTS_HOME").action((profile, options, command) => hasComposeRuntime() ? runtimeAction("up", {}, command) : upCommand(profile, options, command));
|
|
129257
|
+
describe3(program2.command("dev [profile]"), "Start a checkout from local Dockerfiles, never the published images").option("--reset", "stop every Portta-managed stack, drop their volumes, and start as if this checkout were new").option("--demo", "also start portta-demo-* projects from PORTTA_PROJECTS_HOME").action((profile, options, command) => devCommand(profile, options, command));
|
|
129230
129258
|
describe3(program2.command("down"), "Stop the current Compose runtime, or gateway components; keep projects and data").option("--demo", "also stop portta-demo-* projects from PORTTA_PROJECTS_HOME and drop their volumes").action((options, command) => hasComposeRuntime() ? runtimeAction("down", {}, command) : downCommand(options, command));
|
|
129231
|
-
describe3(program2.command("reset"), "Stop every Portta-managed stack, drop their volumes, and restart this checkout as if it were new").option("--demo", "also recreate portta-demo-* projects from PORTTA_PROJECTS_HOME
|
|
129259
|
+
describe3(program2.command("reset"), "Stop every Portta-managed stack, drop their volumes, and restart this checkout as if it were new").option("--demo", "also recreate portta-demo-* projects from PORTTA_PROJECTS_HOME").action((options, command) => resetCommand(options, command));
|
|
129232
129260
|
describe3(program2.command("restart"), "Restart the current Compose runtime, or recreate gateway components").action((_options, command) => hasComposeRuntime() ? runtimeAction("restart", {}, command) : restartCommand(command));
|
|
129233
129261
|
describe3(program2.command("status"), "Show the current Compose runtime, or gateway status").action((_options, command) => hasComposeRuntime() ? runtimeAction("status", {}, command) : statusCommand(command));
|
|
129234
129262
|
describe3(program2.command("doctor"), "Run read-only host and gateway diagnostics").action((_options, command) => doctorCommand(command));
|
|
@@ -129297,7 +129325,7 @@ describe3(dns.command("check"), "Resolve a wildcard probe").action((_options, co
|
|
|
129297
129325
|
describe3(dns.command("status"), "Show DNS configuration without secrets").action((_options, command) => dnsStatus(command));
|
|
129298
129326
|
describe3(dns.command("setup"), "Plan or apply a Cloudflare wildcard record").option("--target <ip>").option("--dry-run").action(dnsSetup);
|
|
129299
129327
|
var web = describe3(program2.command("web"), "Run the optional administration panel").option("--local-release", "use the locally built image for this checkout");
|
|
129300
|
-
describe3(web.command("up"), "Enable and start the panel").option("--expose <scope>", "local, tailscale, public or
|
|
129328
|
+
describe3(web.command("up"), "Enable and start the panel").option("--expose <scope>", "local, tailscale, vpn, public or domain").option("--port <number>").option("--read-only").option("--writable").action((options, command) => webUp({ ...options, localRelease: command.optsWithGlobals().localRelease }, command));
|
|
129301
129329
|
describe3(web.command("dev"), "Start the panel with hot reload").option("--expose <scope>").option("--port <number>").option("--read-only").option("--writable").action((options, command) => webUp({ ...options, dev: true }, command));
|
|
129302
129330
|
describe3(web.command("down"), "Stop the panel only").action((_options, command) => webDown(command));
|
|
129303
129331
|
describe3(web.command("disable"), "Stop and disable the panel").action((_options, command) => webDisable(command));
|