@or3/cloud 0.1.70 → 0.1.72
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.mjs +23 -14
- package/package.json +4 -4
package/dist/cli.mjs
CHANGED
|
@@ -31,7 +31,7 @@ import { fileURLToPath } from "node:url";
|
|
|
31
31
|
import { createGunzip } from "node:zlib";
|
|
32
32
|
var execFile = promisify(execFileCallback);
|
|
33
33
|
var PACKAGE_ROOT = resolve(fileURLToPath(new URL("../", import.meta.url)));
|
|
34
|
-
var PACKAGE_VERSION = "0.1.
|
|
34
|
+
var PACKAGE_VERSION = "0.1.72";
|
|
35
35
|
var IMAGE_REPOSITORY = "ghcr.io/saluana/or3-chat";
|
|
36
36
|
var ASSET_ROOT = resolve(fileURLToPath(new URL("../assets/", import.meta.url)));
|
|
37
37
|
var LEGACY_STATE_SCHEMA_VERSION = 1;
|
|
@@ -368,8 +368,8 @@ async function run(command, args, cwd, environment) {
|
|
|
368
368
|
});
|
|
369
369
|
return {
|
|
370
370
|
ok: true,
|
|
371
|
-
stdout: result.stdout
|
|
372
|
-
stderr: result.stderr
|
|
371
|
+
stdout: result.stdout,
|
|
372
|
+
stderr: result.stderr,
|
|
373
373
|
command: printable,
|
|
374
374
|
exitCode: 0
|
|
375
375
|
};
|
|
@@ -494,7 +494,7 @@ function serializeCredentialValue(value) {
|
|
|
494
494
|
return serializeEnvValue(value);
|
|
495
495
|
}
|
|
496
496
|
function serializeEnv(values) {
|
|
497
|
-
return `${Object.entries(values).filter((
|
|
497
|
+
return `${Object.entries(values).filter((entry) => entry[1] !== undefined).map(([key, value]) => `${key}=${serializeEnvValue(value)}`).join(`
|
|
498
498
|
`)}
|
|
499
499
|
`;
|
|
500
500
|
}
|
|
@@ -1036,7 +1036,7 @@ async function removeManagedDataVolumeForRecreation(directory, state) {
|
|
|
1036
1036
|
} catch {
|
|
1037
1037
|
throw new Error(`Docker returned unreadable metadata for managed volume ${state.volumeName}.`);
|
|
1038
1038
|
}
|
|
1039
|
-
if (volume.Name !== state.volumeName || volume.Labels?.["com.docker.compose.project"] !== state.composeProject || volume.Labels
|
|
1039
|
+
if (volume.Name !== state.volumeName || volume.Labels?.["com.docker.compose.project"] !== state.composeProject || volume.Labels["com.docker.compose.volume"] !== "or3-data") {
|
|
1040
1040
|
throw new Error(`Volume ${state.volumeName} is not bound to this managed Compose deployment. Refusing to recreate it.`);
|
|
1041
1041
|
}
|
|
1042
1042
|
const removedVolume = await run("docker", ["volume", "rm", state.volumeName], directory);
|
|
@@ -1269,6 +1269,8 @@ async function assertImageReleaseIdentity(image, version) {
|
|
|
1269
1269
|
} catch {
|
|
1270
1270
|
throw new Error(`OR3 image ${image} has no readable release labels.`);
|
|
1271
1271
|
}
|
|
1272
|
+
if (!labels || typeof labels !== "object")
|
|
1273
|
+
throw new Error(`OR3 image ${image} has no readable release labels.`);
|
|
1272
1274
|
assertImageReleaseLabels(image, labels, version, packagedSourceRevision(version));
|
|
1273
1275
|
}
|
|
1274
1276
|
async function imageDigest(image) {
|
|
@@ -1636,6 +1638,7 @@ async function installManagedAssets(directory, assets) {
|
|
|
1636
1638
|
const token = randomBytes(4).toString("hex");
|
|
1637
1639
|
const staged = [];
|
|
1638
1640
|
let retainRollbackCopies = false;
|
|
1641
|
+
const canCleanRollback = () => !retainRollbackCopies;
|
|
1639
1642
|
try {
|
|
1640
1643
|
for (const [name, contents] of assets) {
|
|
1641
1644
|
const destination = join(directory, name);
|
|
@@ -1687,7 +1690,7 @@ async function installManagedAssets(directory, assets) {
|
|
|
1687
1690
|
await rm(entry.replacement, { force: true }).catch(() => {
|
|
1688
1691
|
return;
|
|
1689
1692
|
});
|
|
1690
|
-
if (entry.rollback &&
|
|
1693
|
+
if (entry.rollback && canCleanRollback())
|
|
1691
1694
|
await rm(entry.rollback, { force: true }).catch(() => {
|
|
1692
1695
|
return;
|
|
1693
1696
|
});
|
|
@@ -2330,6 +2333,7 @@ async function streamCommandToFile(command, args, destination, cwd, secrets = []
|
|
|
2330
2333
|
});
|
|
2331
2334
|
let stderr = "";
|
|
2332
2335
|
let timedOut = false;
|
|
2336
|
+
const hasTimedOut = () => timedOut;
|
|
2333
2337
|
const timeout = setTimeout(() => {
|
|
2334
2338
|
timedOut = true;
|
|
2335
2339
|
terminateChildProcess(child);
|
|
@@ -2347,7 +2351,7 @@ async function streamCommandToFile(command, args, destination, cwd, secrets = []
|
|
|
2347
2351
|
exit,
|
|
2348
2352
|
pipeline(child.stdout, createWriteStream(temporary, { flags: "wx", mode: 384 }))
|
|
2349
2353
|
]);
|
|
2350
|
-
if (
|
|
2354
|
+
if (hasTimedOut())
|
|
2351
2355
|
throw new Error(`${command} exceeded the ${STREAM_COMMAND_TIMEOUT_MS / 1000}-second archive deadline.`);
|
|
2352
2356
|
if (exitCode !== 0) {
|
|
2353
2357
|
throw new Error(`${command} ${args.join(" ")} exited with ${exitCode}. ${redact(stderr, secrets)}`.trim());
|
|
@@ -2375,6 +2379,7 @@ async function streamFileToCommand(command, args, source, cwd, secrets = []) {
|
|
|
2375
2379
|
});
|
|
2376
2380
|
let stderr = "";
|
|
2377
2381
|
let timedOut = false;
|
|
2382
|
+
const hasTimedOut = () => timedOut;
|
|
2378
2383
|
const timeout = setTimeout(() => {
|
|
2379
2384
|
timedOut = true;
|
|
2380
2385
|
terminateChildProcess(child);
|
|
@@ -2392,7 +2397,7 @@ async function streamFileToCommand(command, args, source, cwd, secrets = []) {
|
|
|
2392
2397
|
exit,
|
|
2393
2398
|
pipeline(createReadStream(source), child.stdin)
|
|
2394
2399
|
]);
|
|
2395
|
-
if (
|
|
2400
|
+
if (hasTimedOut())
|
|
2396
2401
|
throw new Error(`${command} exceeded the ${STREAM_COMMAND_TIMEOUT_MS / 1000}-second archive deadline.`);
|
|
2397
2402
|
if (exitCode !== 0) {
|
|
2398
2403
|
throw new Error(`${command} ${args.join(" ")} exited with ${exitCode}. ${redact(stderr, secrets)}`.trim());
|
|
@@ -3785,7 +3790,7 @@ async function assessUpdate(directory, targetVersion, options = {}) {
|
|
|
3785
3790
|
}
|
|
3786
3791
|
try {
|
|
3787
3792
|
assertKnownStateSchema(state?.schemaVersion);
|
|
3788
|
-
checks.push({ code: "state-schema", status: "passed", detail: `Managed state schema ${String(state
|
|
3793
|
+
checks.push({ code: "state-schema", status: "passed", detail: `Managed state schema ${String(state.schemaVersion)} is supported.` });
|
|
3789
3794
|
} catch (error) {
|
|
3790
3795
|
findings.push({ code: "state-schema-unsupported", severity: "blocker", message: error instanceof Error ? error.message : String(error) });
|
|
3791
3796
|
}
|
|
@@ -4504,7 +4509,7 @@ async function doctorCommand(directory) {
|
|
|
4504
4509
|
}
|
|
4505
4510
|
function validateVerificationHealth(value) {
|
|
4506
4511
|
const health = value;
|
|
4507
|
-
if (!health || health.status !== "ok" || health.providers?.auth?.provider !== "basic-auth" || health.providers
|
|
4512
|
+
if (!health || health.status !== "ok" || health.providers?.auth?.provider !== "basic-auth" || health.providers.sync?.provider !== "sqlite" || health.providers.storage?.provider !== "fs") {
|
|
4508
4513
|
throw new Error("Public deep health does not report the managed Basic Auth + SQLite + filesystem profile.");
|
|
4509
4514
|
}
|
|
4510
4515
|
return health;
|
|
@@ -4524,7 +4529,7 @@ async function verificationJson(baseUrl, path, options = {}) {
|
|
|
4524
4529
|
accept: "application/json",
|
|
4525
4530
|
...options.body === undefined ? {} : { "content-type": "application/json" },
|
|
4526
4531
|
...options.cookie ? { cookie: options.cookie } : {},
|
|
4527
|
-
...method === "GET" ? {} : { origin: baseUrl.origin }
|
|
4532
|
+
...method === "GET" ? {} : { origin: baseUrl.origin, "x-or3-cloud-intent": "mutation" }
|
|
4528
4533
|
},
|
|
4529
4534
|
...options.body === undefined ? {} : { body: JSON.stringify(options.body) }
|
|
4530
4535
|
});
|
|
@@ -4532,7 +4537,11 @@ async function verificationJson(baseUrl, path, options = {}) {
|
|
|
4532
4537
|
const detail = (await response.text().catch(() => "")).slice(0, 300);
|
|
4533
4538
|
throw new Error(`${response.url} returned HTTP ${response.status}${detail ? `: ${detail}` : ""}`);
|
|
4534
4539
|
}
|
|
4535
|
-
|
|
4540
|
+
const value = await response.json();
|
|
4541
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
4542
|
+
throw new Error(`${response.url} returned an invalid JSON object.`);
|
|
4543
|
+
}
|
|
4544
|
+
return value;
|
|
4536
4545
|
}
|
|
4537
4546
|
function sameOriginVerificationUrl(baseUrl, value, label) {
|
|
4538
4547
|
if (typeof value !== "string")
|
|
@@ -4599,7 +4608,7 @@ async function verifyPublicApplication(baseUrl, credentials) {
|
|
|
4599
4608
|
throw new Error("Public Basic Auth sign-in did not set a session cookie.");
|
|
4600
4609
|
try {
|
|
4601
4610
|
const session = await verificationJson(baseUrl, "/api/auth/session", { cookie });
|
|
4602
|
-
if (session.session?.user?.email !== email || !session.session
|
|
4611
|
+
if (session.session?.user?.email !== email || !session.session.workspace?.id) {
|
|
4603
4612
|
throw new Error("Public session hydration did not return the verification user and workspace.");
|
|
4604
4613
|
}
|
|
4605
4614
|
const workspaceId = String(session.session.workspace.id);
|
|
@@ -4767,7 +4776,7 @@ async function provisionManagedCredentialsOnce(baseUrl, email, password, adminUs
|
|
|
4767
4776
|
const appCookie = responseCookie(appSignIn, "Managed owner provisioning");
|
|
4768
4777
|
try {
|
|
4769
4778
|
const session = await verificationJson(baseUrl, "/api/auth/session", { cookie: appCookie });
|
|
4770
|
-
if (session.session?.user?.email !== email || !session.session
|
|
4779
|
+
if (session.session?.user?.email !== email || !session.session.workspace?.id) {
|
|
4771
4780
|
throw new Error("Managed owner provisioning did not create the expected account and workspace.");
|
|
4772
4781
|
}
|
|
4773
4782
|
} finally {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@or3/cloud",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.72",
|
|
4
4
|
"description": "Install and operate the OR3 Cloud container distribution",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "GPL-3.0",
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
"dashboardUpdateProtocol": 1,
|
|
20
20
|
"dashboardUpdateMinimumSourceVersion": "0.1.40",
|
|
21
21
|
"stateSchema": 1,
|
|
22
|
-
"imageDigest": "sha256:
|
|
23
|
-
"operatorImageDigest": "sha256:
|
|
24
|
-
"sourceRevision": "
|
|
22
|
+
"imageDigest": "sha256:c4b408ea3a5fbd647b26d6efe89ddad58f90be7528aa2b5b6ed20d6d41c928ac",
|
|
23
|
+
"operatorImageDigest": "sha256:05b03560594da28e436977b82a905aa9a7702668b5e4ac4daea8b54376a75813",
|
|
24
|
+
"sourceRevision": "90c5756fa313331df7be656fcbc1bce5a4164d6e"
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
|
27
27
|
"dist",
|