@codions/portta 0.0.0-develop.154.sha-cf86996 → 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 +95 -66
- 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(" ");
|
|
@@ -119202,10 +119202,11 @@ async function panelSetupState(apiUrl) {
|
|
|
119202
119202
|
return null;
|
|
119203
119203
|
}
|
|
119204
119204
|
}
|
|
119205
|
+
var PANEL_SERVICES = ["web", "web-socket-proxy"];
|
|
119205
119206
|
async function webDown(command) {
|
|
119206
119207
|
const context = gatewayContext({ profile: globals4(command).profile, overrides: { ...PANEL_OVERRIDES, PORTTA_WEB_DEV: "true" } });
|
|
119207
119208
|
const env = { ...context.env, PORTTA_WEB: "true", PORTTA_WEB_DEV: "true" };
|
|
119208
|
-
const services =
|
|
119209
|
+
const services = PANEL_SERVICES;
|
|
119209
119210
|
await runProcess("docker", ["compose", ...composeArguments({ ...context, env }), "stop", ...services], { cwd: context.root, env, reject: false });
|
|
119210
119211
|
await runProcess("docker", ["compose", ...composeArguments({ ...context, env }), "rm", "-f", ...services], { cwd: context.root, env, reject: false });
|
|
119211
119212
|
const output2 = new Output(globals4(command));
|
|
@@ -119222,7 +119223,7 @@ async function webRestart(command) {
|
|
|
119222
119223
|
}
|
|
119223
119224
|
async function webLogs(service2, command) {
|
|
119224
119225
|
const target = service2 ?? "web";
|
|
119225
|
-
if (!["web", "web-socket-proxy", "
|
|
119226
|
+
if (!["web", "web-socket-proxy", "portta-auth"].includes(target)) throw new UsageError(`unknown panel service: ${target}`);
|
|
119226
119227
|
const global3 = globals4(command);
|
|
119227
119228
|
if (global3.json) {
|
|
119228
119229
|
const result = await webCompose(command, ["logs", "--no-color", "--no-log-prefix", "--tail", "100", target], {}, "pipe");
|
|
@@ -120140,7 +120141,7 @@ async function runtimeAction(action, options, command) {
|
|
|
120140
120141
|
init_src();
|
|
120141
120142
|
init_src();
|
|
120142
120143
|
init_context();
|
|
120143
|
-
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";
|
|
120144
120145
|
import { join as join57 } from "node:path";
|
|
120145
120146
|
init_errors3();
|
|
120146
120147
|
init_version();
|
|
@@ -120762,35 +120763,9 @@ async function runDoctor(context) {
|
|
|
120762
120763
|
const socket = (proxy.mounts ?? []).find((mount) => mount.source.includes("docker.sock"));
|
|
120763
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"));
|
|
120764
120765
|
}
|
|
120765
|
-
|
|
120766
|
-
|
|
120767
|
-
|
|
120768
|
-
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"));
|
|
120769
|
-
const dbPublished = publishedBindings(database);
|
|
120770
|
-
add(dbPublished ? check2(
|
|
120771
|
-
"db.exposure",
|
|
120772
|
-
"fail",
|
|
120773
|
-
"panel database exposure",
|
|
120774
|
-
`publishes host ports: ${dbPublished}`,
|
|
120775
|
-
"remove every ports entry from docker/compose/features/db.yaml and recreate the database container"
|
|
120776
|
-
) : check2("db.exposure", "pass", "panel database exposure", "no host ports published"));
|
|
120777
|
-
add(database.networks.includes(config3.network) ? check2(
|
|
120778
|
-
"db.network.shared",
|
|
120779
|
-
"fail",
|
|
120780
|
-
"panel database network",
|
|
120781
|
-
`attached to the shared HTTP network '${config3.network}'`,
|
|
120782
|
-
`detach it; the panel database belongs only on '${dbNetwork}'`
|
|
120783
|
-
) : check2("db.network.shared", "pass", "panel database network", "off the shared HTTP network"));
|
|
120784
|
-
const data = await networkFacts(dbNetwork);
|
|
120785
|
-
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(
|
|
120786
|
-
"db.network.internal",
|
|
120787
|
-
"fail",
|
|
120788
|
-
"panel data network",
|
|
120789
|
-
`${dbNetwork} is not internal`,
|
|
120790
|
-
"recreate the panel database network from docker/compose/features/db.yaml"
|
|
120791
|
-
));
|
|
120792
|
-
} else if (config3.webEnabled) {
|
|
120793
|
-
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"));
|
|
120794
120769
|
}
|
|
120795
120770
|
const panelIsPublic = (env["PORTTA_WEB_EXPOSE"] || "local") === "public";
|
|
120796
120771
|
if (traefik && traefik.state === "running") {
|
|
@@ -121379,7 +121354,7 @@ async function reexecBuiltCli(root2) {
|
|
|
121379
121354
|
init_src();
|
|
121380
121355
|
init_context();
|
|
121381
121356
|
init_errors3();
|
|
121382
|
-
import { existsSync as existsSync37, readdirSync as readdirSync7 } from "node:fs";
|
|
121357
|
+
import { existsSync as existsSync37, readdirSync as readdirSync7, readFileSync as readFileSync30 } from "node:fs";
|
|
121383
121358
|
import { basename as basename19, join as join56 } from "node:path";
|
|
121384
121359
|
var PORTTA_DIRECTORY = ".portta";
|
|
121385
121360
|
var OVERLAY_FILE = "compose.portta.yaml";
|
|
@@ -121387,6 +121362,7 @@ var COMPOSE_FILE = "compose.yaml";
|
|
|
121387
121362
|
var PANEL_WAIT_MS2 = 12e4;
|
|
121388
121363
|
var PANEL_POLL_MS2 = 500;
|
|
121389
121364
|
var DEMO_DIRECTORY_PREFIX = "portta-demo-";
|
|
121365
|
+
var MANIFEST_FILE = "portta.example.json";
|
|
121390
121366
|
function demoDirectories(home2) {
|
|
121391
121367
|
if (!existsSync37(home2)) return [];
|
|
121392
121368
|
return readdirSync7(home2, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.startsWith(DEMO_DIRECTORY_PREFIX)).map((entry) => join56(home2, entry.name)).sort();
|
|
@@ -121409,6 +121385,48 @@ function demoComposeArgs(stack, action) {
|
|
|
121409
121385
|
if (action === "up") return ["compose", ...files, "up", "-d"];
|
|
121410
121386
|
return ["compose", ...files, "down", "-v"];
|
|
121411
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
|
+
}
|
|
121412
121430
|
function outputFor(command) {
|
|
121413
121431
|
return new Output(workGlobals(command));
|
|
121414
121432
|
}
|
|
@@ -121418,15 +121436,24 @@ function demoHome(command) {
|
|
|
121418
121436
|
const configured = context.env["PORTTA_PROJECTS_HOME"]?.trim() || defaultProjectsHome(userHome, typeof process.getuid === "function" && process.getuid() === 0);
|
|
121419
121437
|
return normalizeProjectsHome(configured, context.root, userHome);
|
|
121420
121438
|
}
|
|
121421
|
-
|
|
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) {
|
|
121422
121449
|
const output2 = outputFor(command);
|
|
121423
|
-
const stacks =
|
|
121424
|
-
if (stacks.length === 0) return;
|
|
121450
|
+
const stacks = requireDemoStacks(command);
|
|
121425
121451
|
output2.step("demo stacks");
|
|
121426
121452
|
for (const stack of stacks) {
|
|
121427
121453
|
output2.progress(`starting ${stack.name}`);
|
|
121428
121454
|
await runProcess("docker", demoComposeArgs(stack, "up"), { cwd: stack.dir, stdio: "inherit" });
|
|
121429
121455
|
}
|
|
121456
|
+
await registerDemoProjects(command, stacks, token);
|
|
121430
121457
|
}
|
|
121431
121458
|
async function demoStacksDown(command) {
|
|
121432
121459
|
const output2 = outputFor(command);
|
|
@@ -121624,6 +121651,7 @@ async function upCommand(profile, options, command) {
|
|
|
121624
121651
|
if (options.localRelease) selectLocalRelease(gatewayContext({ profile: profile ?? globals8(command).profile }));
|
|
121625
121652
|
const context = gatewayContext({ profile: profile ?? globals8(command).profile });
|
|
121626
121653
|
if (options.localRelease) context.env["PORTTA_LOCAL_RELEASE"] = "true";
|
|
121654
|
+
if (options.demo) requireDemoStacks(command);
|
|
121627
121655
|
if (context.config.profile === "remote-public" && context.config.tcpEnabled) throw new RefusedError("TCP entrypoints must not run on the remote-public profile");
|
|
121628
121656
|
if (context.config.profile === "remote-public" && context.config.webEnabled && context.config.webExpose === "vpn") {
|
|
121629
121657
|
throw new RefusedError(
|
|
@@ -121682,6 +121710,7 @@ async function devCommand(profile, options, command) {
|
|
|
121682
121710
|
await reexecBuiltCli(existing.root);
|
|
121683
121711
|
return;
|
|
121684
121712
|
}
|
|
121713
|
+
if (options.demo) requireDemoStacks(command);
|
|
121685
121714
|
const needsBootstrap = !existsSync38(join57(existing.root, ".env"));
|
|
121686
121715
|
output2.progress(`dev runs: ${[
|
|
121687
121716
|
...options.reset ? ["wipe Portta-managed containers and volumes"] : [],
|
|
@@ -121703,7 +121732,7 @@ async function devCommand(profile, options, command) {
|
|
|
121703
121732
|
await waitForPanel(command);
|
|
121704
121733
|
const demoToken = await ensureDevDemoOwner(command);
|
|
121705
121734
|
await finishWebUp(panel, command, false, demoToken);
|
|
121706
|
-
if (options.demo) await demoStacksUp(command);
|
|
121735
|
+
if (options.demo) await demoStacksUp(command, demoToken);
|
|
121707
121736
|
await urlsCommand({}, command);
|
|
121708
121737
|
}
|
|
121709
121738
|
async function downCommand(options, command) {
|
|
@@ -121885,7 +121914,7 @@ function readAliases(root2) {
|
|
|
121885
121914
|
const path7 = join57(root2, "config/traefik/dynamic/portta-aliases.yaml");
|
|
121886
121915
|
if (!existsSync38(path7)) return [];
|
|
121887
121916
|
try {
|
|
121888
|
-
return parseAliases(
|
|
121917
|
+
return parseAliases(readFileSync31(path7, "utf8"));
|
|
121889
121918
|
} catch {
|
|
121890
121919
|
return [];
|
|
121891
121920
|
}
|
|
@@ -122038,7 +122067,7 @@ async function dnsSetup(options, command) {
|
|
|
122038
122067
|
|
|
122039
122068
|
// src/commands/host-service.ts
|
|
122040
122069
|
init_config2();
|
|
122041
|
-
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";
|
|
122042
122071
|
import { homedir as homedir10 } from "node:os";
|
|
122043
122072
|
import { dirname as dirname29, join as join59 } from "node:path";
|
|
122044
122073
|
init_context();
|
|
@@ -122119,7 +122148,7 @@ var LAUNCHD_ENV_ENTRY_RE = /<key>([^<]+)<\/key>\s*<string>([^<]*)<\/string>/g;
|
|
|
122119
122148
|
function readEnvVarsFromUnit(filePath, platform4) {
|
|
122120
122149
|
let text;
|
|
122121
122150
|
try {
|
|
122122
|
-
text =
|
|
122151
|
+
text = readFileSync32(filePath, "utf8");
|
|
122123
122152
|
} catch {
|
|
122124
122153
|
return {};
|
|
122125
122154
|
}
|
|
@@ -122356,7 +122385,7 @@ async function configGet(name, command) {
|
|
|
122356
122385
|
const global3 = globals10(command);
|
|
122357
122386
|
const context = gatewayContext({ profile: global3.profile });
|
|
122358
122387
|
const item = setting(name);
|
|
122359
|
-
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");
|
|
122360
122389
|
const value3 = context.env[item.key] ?? "";
|
|
122361
122390
|
const output2 = new Output(global3);
|
|
122362
122391
|
if (output2.json) output2.data({ setting: name, variable: item.key, value: value3 });
|
|
@@ -122520,7 +122549,7 @@ async function configSet(name, value3, options, command) {
|
|
|
122520
122549
|
const output2 = new Output(global3);
|
|
122521
122550
|
const context = gatewayContext({ profile: global3.profile });
|
|
122522
122551
|
const item = setting(name);
|
|
122523
|
-
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");
|
|
122524
122553
|
if (item.allowed && !item.allowed.includes(value3)) throw new UsageError(`${name} must be one of: ${item.allowed.join(", ")}`);
|
|
122525
122554
|
let values;
|
|
122526
122555
|
if (name === "panel.access") values = await setPanelAccess(context.root, value3, output2);
|
|
@@ -122643,7 +122672,7 @@ async function setupCommand(options, command) {
|
|
|
122643
122672
|
const envFile = join61(target, ".env");
|
|
122644
122673
|
prepareEnvFile(envFile);
|
|
122645
122674
|
record6("environment", "updated", "environment prepared from .env.example");
|
|
122646
|
-
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 });
|
|
122647
122676
|
for (const directory of ["state/auth", "state/ssh", "state/runner", "state/cloudflared"]) chmodSync11(join61(target, directory), 448);
|
|
122648
122677
|
record6("directories", "ok", "gateway state directories");
|
|
122649
122678
|
const context = gatewayContext({ root: target, profile });
|
|
@@ -122665,7 +122694,7 @@ async function setupCommand(options, command) {
|
|
|
122665
122694
|
// src/commands/auth.ts
|
|
122666
122695
|
init_context();
|
|
122667
122696
|
init_errors3();
|
|
122668
|
-
import { readFileSync as
|
|
122697
|
+
import { readFileSync as readFileSync33 } from "node:fs";
|
|
122669
122698
|
function globals12(command) {
|
|
122670
122699
|
return command.optsWithGlobals();
|
|
122671
122700
|
}
|
|
@@ -122680,7 +122709,7 @@ function panelUrlFor2(command) {
|
|
|
122680
122709
|
}
|
|
122681
122710
|
async function authBootstrap(options, command) {
|
|
122682
122711
|
if (!options.name || !options.email) throw new UsageError("--name and --email are required");
|
|
122683
|
-
const password = options.passwordStdin ?
|
|
122712
|
+
const password = options.passwordStdin ? readFileSync33(0, "utf8").trim() : "";
|
|
122684
122713
|
if (!password) throw new UsageError("the password is read from stdin", 'printf %s "$PASSWORD" | portta auth bootstrap --name \u2026 --email \u2026 --password-stdin');
|
|
122685
122714
|
if (password.length < 10) throw new UsageError("the password must be at least 10 characters");
|
|
122686
122715
|
const { client, output: output2 } = clientFor(command, { actor: void 0, actorKind: "human" });
|
|
@@ -122713,7 +122742,7 @@ async function authLogin(options, command) {
|
|
|
122713
122742
|
}
|
|
122714
122743
|
async function readSecret() {
|
|
122715
122744
|
if (!process.stdin.isTTY) {
|
|
122716
|
-
const piped =
|
|
122745
|
+
const piped = readFileSync33(0, "utf8").trim();
|
|
122717
122746
|
if (piped) return piped;
|
|
122718
122747
|
throw new UsageError("no token on stdin", "pass --token, or run this in a terminal");
|
|
122719
122748
|
}
|
|
@@ -122852,7 +122881,7 @@ init_src();
|
|
|
122852
122881
|
init_context();
|
|
122853
122882
|
init_errors3();
|
|
122854
122883
|
import { randomBytes as randomBytes8 } from "node:crypto";
|
|
122855
|
-
import { chmodSync as chmodSync12, mkdirSync as mkdirSync21, readFileSync as
|
|
122884
|
+
import { chmodSync as chmodSync12, mkdirSync as mkdirSync21, readFileSync as readFileSync34 } from "node:fs";
|
|
122856
122885
|
import { dirname as dirname31, join as join62 } from "node:path";
|
|
122857
122886
|
function globals13(command) {
|
|
122858
122887
|
return command.optsWithGlobals();
|
|
@@ -122884,7 +122913,7 @@ async function protectHost(hostInput, options, command) {
|
|
|
122884
122913
|
const entryPoint = options.entrypoint ?? (gatewayContext({ profile: globals13(command).profile }).config.tlsEnabled ? "websecure" : "web");
|
|
122885
122914
|
if (!/^[A-Za-z0-9_-]+$/.test(entryPoint)) throw new UsageError(`invalid entrypoint: ${entryPoint}`);
|
|
122886
122915
|
const generated = options.passwordStdin !== true;
|
|
122887
|
-
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();
|
|
122888
122917
|
if (!password) throw new UsageError("no password on stdin");
|
|
122889
122918
|
const target = paths(command);
|
|
122890
122919
|
const existing = readProtectionStore(target.store);
|
|
@@ -122937,11 +122966,11 @@ async function protectStatus(hostInput, command) {
|
|
|
122937
122966
|
init_src();
|
|
122938
122967
|
init_errors3();
|
|
122939
122968
|
init_context();
|
|
122940
|
-
import { readFileSync as
|
|
122969
|
+
import { readFileSync as readFileSync35 } from "node:fs";
|
|
122941
122970
|
import { randomBytes as randomBytes9 } from "node:crypto";
|
|
122942
122971
|
function passwordFrom(options) {
|
|
122943
122972
|
if (options.passwordStdin) {
|
|
122944
|
-
const password2 =
|
|
122973
|
+
const password2 = readFileSync35(0, "utf8").trim();
|
|
122945
122974
|
if (!password2) throw new UsageError("no password on stdin");
|
|
122946
122975
|
if (password2.length < 10) throw new UsageError("the password must be at least 10 characters");
|
|
122947
122976
|
return { password: password2, generated: false };
|
|
@@ -123334,7 +123363,7 @@ function paths2(root2) {
|
|
|
123334
123363
|
init_src();
|
|
123335
123364
|
init_context();
|
|
123336
123365
|
init_errors3();
|
|
123337
|
-
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";
|
|
123338
123367
|
import { hostname as hostname3, tmpdir as tmpdir5 } from "node:os";
|
|
123339
123368
|
import { dirname as dirname32, join as join65 } from "node:path";
|
|
123340
123369
|
function globals16(command) {
|
|
@@ -123397,7 +123426,7 @@ async function backupCommand(options, command) {
|
|
|
123397
123426
|
database = await dumpDatabase(context, join65(staging, "panel.db"));
|
|
123398
123427
|
if (!database) {
|
|
123399
123428
|
output2.warning("the panel database was not included");
|
|
123400
|
-
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");
|
|
123401
123430
|
}
|
|
123402
123431
|
}
|
|
123403
123432
|
const previous = process.umask(63);
|
|
@@ -123446,7 +123475,7 @@ async function restoreCommand(archive, options, command) {
|
|
|
123446
123475
|
if (extracted.failed) throw new UsageError("that file is not a Portta backup");
|
|
123447
123476
|
const manifestPath2 = join65(staging, "portta-backup.json");
|
|
123448
123477
|
if (!existsSync43(manifestPath2)) throw new UsageError("that archive has no Portta manifest");
|
|
123449
|
-
const manifest = parseManifest(
|
|
123478
|
+
const manifest = parseManifest(readFileSync36(manifestPath2, "utf8"));
|
|
123450
123479
|
if (!manifest) throw new UsageError("that archive has an unreadable Portta manifest");
|
|
123451
123480
|
output2.progress(`restoring a backup taken from Portta ${manifest.portta}`);
|
|
123452
123481
|
if (!options.force && await containerRunning(`${context.env["PORTTA_PROJECT_NAME"] || "portta"}-traefik-1`)) {
|
|
@@ -128558,7 +128587,7 @@ async function buildCommand(command) {
|
|
|
128558
128587
|
|
|
128559
128588
|
// src/commands/remote.ts
|
|
128560
128589
|
init_src();
|
|
128561
|
-
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";
|
|
128562
128591
|
import { basename as basename20, join as join67 } from "node:path";
|
|
128563
128592
|
import { createServer as createServer3 } from "node:net";
|
|
128564
128593
|
import { randomBytes as randomBytes10 } from "node:crypto";
|
|
@@ -128769,7 +128798,7 @@ function readTunnels(root2) {
|
|
|
128769
128798
|
for (const name of readdirSync10(directory).filter((entry) => entry.endsWith(".json"))) {
|
|
128770
128799
|
const path7 = join67(directory, name);
|
|
128771
128800
|
try {
|
|
128772
|
-
const record6 = parseTunnelRecord(basename20(name, ".json"),
|
|
128801
|
+
const record6 = parseTunnelRecord(basename20(name, ".json"), readFileSync37(path7, "utf8"));
|
|
128773
128802
|
if (record6) records.push(record6);
|
|
128774
128803
|
} catch {
|
|
128775
128804
|
}
|
|
@@ -128903,7 +128932,7 @@ init_src();
|
|
|
128903
128932
|
init_src();
|
|
128904
128933
|
init_context();
|
|
128905
128934
|
init_errors3();
|
|
128906
|
-
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";
|
|
128907
128936
|
import { ReadStream } from "node:tty";
|
|
128908
128937
|
import { join as join68 } from "node:path";
|
|
128909
128938
|
function globals20(command) {
|
|
@@ -129046,7 +129075,7 @@ async function tunnelSetup(options, command) {
|
|
|
129046
129075
|
let token;
|
|
129047
129076
|
if (options.tokenFile) {
|
|
129048
129077
|
if (!existsSync45(options.tokenFile)) throw new UsageError(`no such file: ${options.tokenFile}`);
|
|
129049
|
-
token =
|
|
129078
|
+
token = readFileSync38(options.tokenFile, "utf8").replace(/\s+/g, "");
|
|
129050
129079
|
} else {
|
|
129051
129080
|
token = await promptForToken();
|
|
129052
129081
|
}
|
|
@@ -129224,10 +129253,10 @@ describe3(program2.command("version"), "Print the installed version").action((_o
|
|
|
129224
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);
|
|
129225
129254
|
describe3(program2.command("bootstrap"), "Prepare this installation and run diagnostics").option("--skip-pull", "do not pull component images").action(bootstrapCommand);
|
|
129226
129255
|
describe3(program2.command("build"), "Build every local Portta image for this checkout").action((_options, command) => buildCommand(command));
|
|
129227
|
-
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
|
|
129228
|
-
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));
|
|
129229
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));
|
|
129230
|
-
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));
|
|
129231
129260
|
describe3(program2.command("restart"), "Restart the current Compose runtime, or recreate gateway components").action((_options, command) => hasComposeRuntime() ? runtimeAction("restart", {}, command) : restartCommand(command));
|
|
129232
129261
|
describe3(program2.command("status"), "Show the current Compose runtime, or gateway status").action((_options, command) => hasComposeRuntime() ? runtimeAction("status", {}, command) : statusCommand(command));
|
|
129233
129262
|
describe3(program2.command("doctor"), "Run read-only host and gateway diagnostics").action((_options, command) => doctorCommand(command));
|
|
@@ -129296,7 +129325,7 @@ describe3(dns.command("check"), "Resolve a wildcard probe").action((_options, co
|
|
|
129296
129325
|
describe3(dns.command("status"), "Show DNS configuration without secrets").action((_options, command) => dnsStatus(command));
|
|
129297
129326
|
describe3(dns.command("setup"), "Plan or apply a Cloudflare wildcard record").option("--target <ip>").option("--dry-run").action(dnsSetup);
|
|
129298
129327
|
var web = describe3(program2.command("web"), "Run the optional administration panel").option("--local-release", "use the locally built image for this checkout");
|
|
129299
|
-
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));
|
|
129300
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));
|
|
129301
129330
|
describe3(web.command("down"), "Stop the panel only").action((_options, command) => webDown(command));
|
|
129302
129331
|
describe3(web.command("disable"), "Stop and disable the panel").action((_options, command) => webDisable(command));
|