@uns-kit/core 3.0.30 → 3.0.32
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/MIGRATIONS.md +45 -0
- package/dist/config/app-config.d.ts +1 -0
- package/dist/config/app-config.d.ts.map +1 -1
- package/dist/config/app-config.js.map +1 -1
- package/dist/runtime/mqtt-output-state-contract.d.ts +27 -0
- package/dist/runtime/mqtt-output-state-contract.d.ts.map +1 -0
- package/dist/runtime/mqtt-output-state-contract.js +32 -0
- package/dist/runtime/mqtt-output-state-contract.js.map +1 -0
- package/dist/runtime/mqtt-output-state-contract.json +8 -0
- package/dist/runtime/mqtt-output-state-program.d.mts +32 -0
- package/dist/runtime/mqtt-output-state-program.mjs +562 -0
- package/dist/runtime/process-group-configured-upgrade.d.ts +1 -0
- package/dist/runtime/process-group-configured-upgrade.d.ts.map +1 -1
- package/dist/runtime/process-group-configured-upgrade.js +21 -4
- package/dist/runtime/process-group-configured-upgrade.js.map +1 -1
- package/dist/runtime/process-group-mqtt-output.d.ts +63 -0
- package/dist/runtime/process-group-mqtt-output.d.ts.map +1 -0
- package/dist/runtime/process-group-mqtt-output.js +89 -0
- package/dist/runtime/process-group-mqtt-output.js.map +1 -0
- package/dist/runtime/process-group-upgrade.d.ts +85 -2
- package/dist/runtime/process-group-upgrade.d.ts.map +1 -1
- package/dist/runtime/process-group-upgrade.js +74 -9
- package/dist/runtime/process-group-upgrade.js.map +1 -1
- package/dist/uns-config/config-schema.d.ts +4 -0
- package/dist/uns-config/config-schema.d.ts.map +1 -1
- package/dist/uns-config/uns-core-schema.d.ts +8 -0
- package/dist/uns-config/uns-core-schema.d.ts.map +1 -1
- package/dist/uns-mqtt/publish-queue-contract.d.ts +13 -0
- package/dist/uns-mqtt/publish-queue-contract.d.ts.map +1 -1
- package/dist/uns-mqtt/publish-queue-contract.js +13 -0
- package/dist/uns-mqtt/publish-queue-contract.js.map +1 -1
- package/dist/uns-mqtt/publish-queue-store.d.ts +1 -0
- package/dist/uns-mqtt/publish-queue-store.d.ts.map +1 -1
- package/dist/uns-mqtt/publish-queue-store.js +38 -39
- package/dist/uns-mqtt/publish-queue-store.js.map +1 -1
- package/dist/uns-mqtt/uns-mqtt-proxy.d.ts.map +1 -1
- package/dist/uns-mqtt/uns-mqtt-proxy.js +2 -7
- package/dist/uns-mqtt/uns-mqtt-proxy.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-group-configured-upgrade.js","sourceRoot":"","sources":["../../src/runtime/process-group-configured-upgrade.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\n\nimport { configurationGroupAuthorizationSchema } from \"./configuration-group-authorization.js\";\nimport { configurationResourceHash } from \"./configuration-group-contract.js\";\nimport { authorizeProcessGroupRuntime, processGroupAuthorizationFile, validateProcessGroupPolicyCandidate } from \"./process-group-authorization.js\";\nimport { resolvedProcessGroupChannels } from \"./process-group-contract.js\";\nimport { describeInstalledProcessGroupGeneration, inspectGenerationJournal } from \"./process-group-generation.js\";\nimport {\n groupArtifactHash,\n groupChannelsHash,\n configurationAuthorizationHash as hash,\n readProcessGroupResource as read,\n sha256,\n} from \"./process-group-resources.js\";\nimport type { GroupVersionUpgradeReview, PreparedGroupUpgrade, UpgradeConfiguration, UpgradeConfigurations } from \"./process-group-upgrade.js\";\n\n/** Same generation, different paired artifacts. Never initializes or rewrites the journal. */\nexport function reviewInstalledConfigurationGroupUpgrade(\n configs: UpgradeConfigurations,\n controllerName: string,\n stateRoot: string,\n excludedUnsFields: readonly string[] = [],\n): PreparedGroupUpgrade {\n const context = (c: UpgradeConfiguration) => ({\n packageRoot: c.packageRoot,\n instanceDirectory: c.instanceDirectory,\n rawConfiguration: c.raw,\n channels: resolvedProcessGroupChannels(c.resolved),\n controllerName,\n stateRoot,\n });\n const source = configs.source.publisher,\n target = configs.target.publisher,\n a = describeInstalledProcessGroupGeneration(source),\n b = describeInstalledProcessGroupGeneration(target);\n if (a.d.protocolVersion !== 2 || b.d.protocolVersion !== 2 || a.d.namespace !== b.d.namespace || hash(a.reference) !== hash(b.reference))\n throw Error(\"Unchanged configuration generation required; review resource changes as a separate generation\");\n const pkg = (c: UpgradeConfiguration) => JSON.parse(read(path.join(c.packageRoot, \"package.json\")).toString()),\n sourcePackage = pkg(source),\n targetPackage = pkg(target);\n if (!sourcePackage.version || !targetPackage.version || sourcePackage.version === targetPackage.version)\n throw Error(\"Two different installed paired versions required\");\n const old = authorizeProcessGroupRuntime(context(source));\n const sourcePolicy = read(old.file, true),\n previous = configurationGroupAuthorizationSchema.parse(JSON.parse(sourcePolicy.toString()));\n const portable = (raw: Record<string, unknown>) => {\n const copy = structuredClone(raw),\n uns = { ...(copy[\"uns\"] as Record<string, unknown>) };\n for (const key of excludedUnsFields) delete uns[key];\n copy[\"uns\"] = uns;\n return hash(copy);\n };\n const members: GroupVersionUpgradeReview[\"members\"] = [];\n const directories = new Set<string>();\n for (const side of [\"source\", \"target\"] as const)\n for (const role of [\"publisher\", \"receiver\"] as const) {\n const c = configs[side][role],\n g = describeInstalledProcessGroupGeneration(c),\n installed = pkg(c);\n if (\n g.d.protocolVersion !== 2 ||\n g.d.namespace !== a.d.namespace ||\n installed.name !== sourcePackage.name ||\n installed.version !== (side === \"source\" ? sourcePackage.version : targetPackage.version) ||\n c.packageRoot !== configs[side].publisher.packageRoot ||\n directories.has(c.instanceDirectory) ||\n hash(g.reference) !== hash(a.reference) ||\n g.normalized.uns[\"processName\"] !== (role === \"publisher\" ? a.processName : a.receiverProcessName) ||\n (role === \"receiver\"\n ? g.normalized.runtimeRole !== \"admission\"\n : g.normalized.runtimeRole !== undefined && g.normalized.runtimeRole !== \"publisher\") ||\n portable(c.raw) !== portable(configs.source[role].raw) ||\n groupChannelsHash(g.channels) !== groupChannelsHash(a.channels) ||\n processGroupAuthorizationFile(context(c)) !== old.file\n )\n throw Error(\"Exact paired configuration, resources, broker identity and retained journal required\");\n directories.add(c.instanceDirectory);\n if (side === \"source\") {\n const proof = authorizeProcessGroupRuntime(context(c));\n if (proof.role !== (role === \"publisher\" ? \"target\" : \"receiver\") || proof.sha256 !== sha256(sourcePolicy))\n throw Error(\"Exact authorized source pair required\");\n }\n members.push({\n side,\n role,\n processName: String(g.normalized.uns[\"processName\"]),\n configurationSha256: hash(c.raw),\n artifactSha256: groupArtifactHash(c.packageRoot),\n });\n }\n const policy = configurationGroupAuthorizationSchema.parse({\n ...previous,\n packageRoot: target.packageRoot,\n descriptorSha256: configurationResourceHash(targetPackage.unsDatahub.processGroupConfigurationRuntime),\n artifactSha256: groupArtifactHash(target.packageRoot),\n placements: [\n ...previous.placements.filter((p) => p.role === \"source\"),\n ...([\"publisher\", \"receiver\"] as const).map((role) => ({\n instanceId: path.basename(configs.target[role].instanceDirectory),\n processName: members.find((m) => m.side === \"target\" && m.role === role)!.processName,\n role: role === \"publisher\" ? \"target\" : \"receiver\",\n configurationSha256: configurationResourceHash(configs.target[role].raw),\n })),\n ],\n });\n const targetPolicy = Buffer.from(JSON.stringify(policy));\n for (const role of [\"publisher\", \"receiver\"] as const) validateProcessGroupPolicyCandidate(context(configs.target[role]), targetPolicy);\n inspectGenerationJournal(a.reference); // Pending, previously completed work is valid and must remain bound.\n if (sha256(read(old.file, true)) !== sha256(sourcePolicy)) throw Error(\"Source policy changed during review\");\n return {\n review: {\n protocolVersion: 1,\n namespace: a.d.namespace,\n groupId: a.id,\n policyFile: old.file,\n sourcePolicySha256: sha256(sourcePolicy),\n targetPolicySha256: sha256(targetPolicy),\n journalId: a.reference.journalId,\n directory: a.reference.directory,\n journalContractSha256: a.reference.journalContractSha256,\n profiles: a.reference.profiles,\n retainedJournal: a.reference,\n members,\n },\n sourcePolicy,\n targetPolicy,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"process-group-configured-upgrade.js","sourceRoot":"","sources":["../../src/runtime/process-group-configured-upgrade.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\n\nimport { configurationGroupAuthorizationSchema } from \"./configuration-group-authorization.js\";\nimport { configurationResourceHash } from \"./configuration-group-contract.js\";\nimport { authorizeProcessGroupRuntime, processGroupAuthorizationFile, validateProcessGroupPolicyCandidate } from \"./process-group-authorization.js\";\nimport { resolvedProcessGroupChannels } from \"./process-group-contract.js\";\nimport { describeInstalledProcessGroupGeneration, inspectGenerationJournal } from \"./process-group-generation.js\";\nimport { mqttOutputPortableConfiguration, reviewProcessGroupMqttOutput } from \"./process-group-mqtt-output.js\";\nimport {\n groupArtifactHash,\n groupChannelsHash,\n configurationAuthorizationHash as hash,\n readProcessGroupResource as read,\n sha256,\n} from \"./process-group-resources.js\";\nimport type {\n GroupMqttOutputReview,\n GroupVersionUpgradeReview,\n PreparedGroupUpgrade,\n UpgradeConfiguration,\n UpgradeConfigurations,\n} from \"./process-group-upgrade.js\";\n\n/** Same generation, different paired artifacts. Never initializes or rewrites the journal. */\nexport function reviewInstalledConfigurationGroupUpgrade(\n configs: UpgradeConfigurations,\n controllerName: string,\n stateRoot: string,\n excludedUnsFields: readonly string[] = [],\n): PreparedGroupUpgrade {\n return reviewConfigurationGroup(configs, controllerName, stateRoot, excludedUnsFields, false);\n}\nexport function reviewInstalledConfigurationGroupMqttOutput(\n configs: UpgradeConfigurations,\n controllerName: string,\n stateRoot: string,\n excludedUnsFields: readonly string[] = [],\n): PreparedGroupUpgrade {\n const mqttOutput = reviewProcessGroupMqttOutput(configs, process.env[\"UNS_MQTT_OUTPUT_STATE_ROOT\"], stateRoot);\n const result = reviewConfigurationGroup(configs, controllerName, stateRoot, excludedUnsFields, true);\n return {\n ...result,\n review: {\n ...result.review,\n protocolVersion: 3,\n mqttOutput,\n delivery: { inputPausePossible: true, exactlyOnceOutput: false, pendingOutputBlocksRollback: true },\n } as GroupMqttOutputReview,\n };\n}\nfunction reviewConfigurationGroup(\n configs: UpgradeConfigurations,\n controllerName: string,\n stateRoot: string,\n excludedUnsFields: readonly string[],\n mqttOutput: boolean,\n): PreparedGroupUpgrade {\n const context = (c: UpgradeConfiguration) => ({\n packageRoot: c.packageRoot,\n instanceDirectory: c.instanceDirectory,\n rawConfiguration: c.raw,\n channels: resolvedProcessGroupChannels(c.resolved),\n controllerName,\n stateRoot,\n });\n const source = configs.source.publisher,\n target = configs.target.publisher,\n a = describeInstalledProcessGroupGeneration(source),\n b = describeInstalledProcessGroupGeneration(target);\n if (a.d.protocolVersion !== 2 || b.d.protocolVersion !== 2 || a.d.namespace !== b.d.namespace || hash(a.reference) !== hash(b.reference))\n throw Error(\"Unchanged configuration generation required; review resource changes as a separate generation\");\n const pkg = (c: UpgradeConfiguration) => JSON.parse(read(path.join(c.packageRoot, \"package.json\")).toString()),\n sourcePackage = pkg(source),\n targetPackage = pkg(target);\n if (!sourcePackage.version || !targetPackage.version || (!mqttOutput && sourcePackage.version === targetPackage.version))\n throw Error(\"Two different installed paired versions required\");\n const old = authorizeProcessGroupRuntime(context(source));\n const sourcePolicy = read(old.file, true),\n previous = configurationGroupAuthorizationSchema.parse(JSON.parse(sourcePolicy.toString()));\n const portable = (raw: Record<string, unknown>, role: \"publisher\" | \"receiver\") => {\n const copy = mqttOutput ? mqttOutputPortableConfiguration(raw, role) : structuredClone(raw),\n uns = { ...(copy[\"uns\"] as Record<string, unknown>) };\n for (const key of excludedUnsFields) delete uns[key];\n copy[\"uns\"] = uns;\n return hash(copy);\n };\n const members: GroupVersionUpgradeReview[\"members\"] = [];\n const directories = new Set<string>();\n for (const side of [\"source\", \"target\"] as const)\n for (const role of [\"publisher\", \"receiver\"] as const) {\n const c = configs[side][role],\n g = describeInstalledProcessGroupGeneration(c),\n installed = pkg(c);\n if (\n g.d.protocolVersion !== 2 ||\n g.d.namespace !== a.d.namespace ||\n installed.name !== sourcePackage.name ||\n installed.version !== (side === \"source\" ? sourcePackage.version : targetPackage.version) ||\n c.packageRoot !== configs[side].publisher.packageRoot ||\n directories.has(c.instanceDirectory) ||\n hash(g.reference) !== hash(a.reference) ||\n g.normalized.uns[\"processName\"] !== (role === \"publisher\" ? a.processName : a.receiverProcessName) ||\n (role === \"receiver\"\n ? g.normalized.runtimeRole !== \"admission\"\n : g.normalized.runtimeRole !== undefined && g.normalized.runtimeRole !== \"publisher\") ||\n portable(c.raw, role) !== portable(configs.source[role].raw, role) ||\n groupChannelsHash(g.channels) !== groupChannelsHash(a.channels) ||\n processGroupAuthorizationFile(context(c)) !== old.file\n )\n throw Error(\"Exact paired configuration, resources, broker identity and retained journal required\");\n directories.add(c.instanceDirectory);\n if (side === \"source\") {\n const proof = authorizeProcessGroupRuntime(context(c));\n if (proof.role !== (role === \"publisher\" ? \"target\" : \"receiver\") || proof.sha256 !== sha256(sourcePolicy))\n throw Error(\"Exact authorized source pair required\");\n }\n members.push({\n side,\n role,\n processName: String(g.normalized.uns[\"processName\"]),\n configurationSha256: hash(c.raw),\n artifactSha256: groupArtifactHash(c.packageRoot),\n });\n }\n const policy = configurationGroupAuthorizationSchema.parse({\n ...previous,\n packageRoot: target.packageRoot,\n descriptorSha256: configurationResourceHash(targetPackage.unsDatahub.processGroupConfigurationRuntime),\n artifactSha256: groupArtifactHash(target.packageRoot),\n placements: [\n ...previous.placements.filter((p) => p.role === \"source\"),\n ...([\"publisher\", \"receiver\"] as const).map((role) => ({\n instanceId: path.basename(configs.target[role].instanceDirectory),\n processName: members.find((m) => m.side === \"target\" && m.role === role)!.processName,\n role: role === \"publisher\" ? \"target\" : \"receiver\",\n configurationSha256: configurationResourceHash(configs.target[role].raw),\n })),\n ],\n });\n const targetPolicy = Buffer.from(JSON.stringify(policy));\n for (const role of [\"publisher\", \"receiver\"] as const) validateProcessGroupPolicyCandidate(context(configs.target[role]), targetPolicy);\n inspectGenerationJournal(a.reference); // Pending, previously completed work is valid and must remain bound.\n if (sha256(read(old.file, true)) !== sha256(sourcePolicy)) throw Error(\"Source policy changed during review\");\n return {\n review: {\n protocolVersion: 1,\n namespace: a.d.namespace,\n groupId: a.id,\n policyFile: old.file,\n sourcePolicySha256: sha256(sourcePolicy),\n targetPolicySha256: sha256(targetPolicy),\n journalId: a.reference.journalId,\n directory: a.reference.directory,\n journalContractSha256: a.reference.journalContractSha256,\n profiles: a.reference.profiles,\n retainedJournal: a.reference,\n members,\n },\n sourcePolicy,\n targetPolicy,\n };\n}\n"]}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { UpgradeConfigurations } from "./process-group-upgrade.js";
|
|
3
|
+
export declare const processGroupMqttOutputRuntimeSchema: z.ZodObject<{
|
|
4
|
+
protocolVersion: z.ZodLiteral<1>;
|
|
5
|
+
instanceName: z.ZodString;
|
|
6
|
+
}, z.core.$strict>;
|
|
7
|
+
/** An explicit output enablement, never an incidental version/configuration change. */
|
|
8
|
+
export declare const processGroupMqttOutputInputSchema: z.ZodObject<{
|
|
9
|
+
protocolVersion: z.ZodLiteral<3>;
|
|
10
|
+
source: z.ZodObject<{
|
|
11
|
+
publisher: z.ZodObject<{
|
|
12
|
+
controller: z.ZodString;
|
|
13
|
+
rttNode: z.ZodString;
|
|
14
|
+
version: z.ZodString;
|
|
15
|
+
instanceId: z.ZodString;
|
|
16
|
+
}, z.core.$strict>;
|
|
17
|
+
receiver: z.ZodObject<{
|
|
18
|
+
controller: z.ZodString;
|
|
19
|
+
rttNode: z.ZodString;
|
|
20
|
+
version: z.ZodString;
|
|
21
|
+
instanceId: z.ZodString;
|
|
22
|
+
}, z.core.$strict>;
|
|
23
|
+
}, z.core.$strict>;
|
|
24
|
+
target: z.ZodObject<{
|
|
25
|
+
publisher: z.ZodObject<{
|
|
26
|
+
controller: z.ZodString;
|
|
27
|
+
rttNode: z.ZodString;
|
|
28
|
+
version: z.ZodString;
|
|
29
|
+
instanceId: z.ZodString;
|
|
30
|
+
}, z.core.$strict>;
|
|
31
|
+
receiver: z.ZodObject<{
|
|
32
|
+
controller: z.ZodString;
|
|
33
|
+
rttNode: z.ZodString;
|
|
34
|
+
version: z.ZodString;
|
|
35
|
+
instanceId: z.ZodString;
|
|
36
|
+
}, z.core.$strict>;
|
|
37
|
+
}, z.core.$strict>;
|
|
38
|
+
acknowledgeInputPause: z.ZodLiteral<true>;
|
|
39
|
+
acknowledgePossibleReplay: z.ZodLiteral<true>;
|
|
40
|
+
acknowledgePendingOutputBlocksRollback: z.ZodLiteral<true>;
|
|
41
|
+
}, z.core.$strict>;
|
|
42
|
+
export type GroupMqttOutputReference = {
|
|
43
|
+
root: string;
|
|
44
|
+
directory: string;
|
|
45
|
+
rootId: string;
|
|
46
|
+
relative: string;
|
|
47
|
+
identity: string;
|
|
48
|
+
optionsSha256: string;
|
|
49
|
+
};
|
|
50
|
+
/** Only these explicitly reviewed output fields can differ; all other portable data remains exact. */
|
|
51
|
+
export declare function mqttOutputPortableConfiguration(raw: Record<string, unknown>, role: "publisher" | "receiver"): Record<string, unknown>;
|
|
52
|
+
export declare function reviewProcessGroupMqttOutput(configs: UpgradeConfigurations, root: string | undefined, stateRoot: string): GroupMqttOutputReference;
|
|
53
|
+
/** Recheck after proven exit and immediately before policy/start. Unknown state is never empty. */
|
|
54
|
+
export declare function inspectReviewedProcessGroupMqttOutput(reference: GroupMqttOutputReference, requireStopped?: boolean): {
|
|
55
|
+
rootId: string;
|
|
56
|
+
relative: string;
|
|
57
|
+
identity: string;
|
|
58
|
+
records: number;
|
|
59
|
+
bytes: number;
|
|
60
|
+
exists: boolean;
|
|
61
|
+
ownerActive: boolean;
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=process-group-mqtt-output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-group-mqtt-output.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-mqtt-output.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAExE,eAAO,MAAM,mCAAmC;;;kBAG9C,CAAC;AAEH,uFAAuF;AACvF,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAkB1C,CAAC;AACL,MAAM,MAAM,wBAAwB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AACtJ,sGAAsG;AACtG,wBAAgB,+BAA+B,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,2BAe3G;AACD,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,qBAAqB,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,wBAAwB,CA6BlJ;AACD,mGAAmG;AACnG,wBAAgB,qCAAqC,CAAC,SAAS,EAAE,wBAAwB,EAAE,cAAc,UAAO;;;;;;;;EAI/G"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { mqttPublishQueueIdentity, mqttPublishQueueSchema } from "../uns-mqtt/publish-queue-contract.js";
|
|
4
|
+
import { managedMqttOutputBinding, mqttOutputStateLimits } from "./mqtt-output-state-contract.js";
|
|
5
|
+
import { inspectManagedOutputQueue } from "./mqtt-output-state-program.mjs";
|
|
6
|
+
import { resolvedProcessGroupChannels } from "./process-group-contract.js";
|
|
7
|
+
import { groupPlacementSchema, placementKey } from "./process-group-control-contract.js";
|
|
8
|
+
import { configurationAuthorizationHash as hash, readProcessGroupResource as read, sha256 } from "./process-group-resources.js";
|
|
9
|
+
export const processGroupMqttOutputRuntimeSchema = z.strictObject({
|
|
10
|
+
protocolVersion: z.literal(1),
|
|
11
|
+
instanceName: z.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,99}$/),
|
|
12
|
+
});
|
|
13
|
+
const pair = z.strictObject({ publisher: groupPlacementSchema, receiver: groupPlacementSchema });
|
|
14
|
+
/** An explicit output enablement, never an incidental version/configuration change. */
|
|
15
|
+
export const processGroupMqttOutputInputSchema = z
|
|
16
|
+
.strictObject({
|
|
17
|
+
protocolVersion: z.literal(3),
|
|
18
|
+
source: pair,
|
|
19
|
+
target: pair,
|
|
20
|
+
acknowledgeInputPause: z.literal(true),
|
|
21
|
+
acknowledgePossibleReplay: z.literal(true),
|
|
22
|
+
acknowledgePendingOutputBlocksRollback: z.literal(true),
|
|
23
|
+
})
|
|
24
|
+
.superRefine((v, c) => {
|
|
25
|
+
const all = [v.source.publisher, v.source.receiver, v.target.publisher, v.target.receiver];
|
|
26
|
+
if (new Set(all.map(placementKey)).size !== 4 ||
|
|
27
|
+
all.some((p) => p.controller !== all[0].controller || p.rttNode !== all[0].rttNode) ||
|
|
28
|
+
v.source.publisher.version !== v.source.receiver.version ||
|
|
29
|
+
v.target.publisher.version !== v.target.receiver.version)
|
|
30
|
+
c.addIssue({ code: "custom", message: "Four distinct same-host paired placements required" });
|
|
31
|
+
});
|
|
32
|
+
/** Only these explicitly reviewed output fields can differ; all other portable data remains exact. */
|
|
33
|
+
export function mqttOutputPortableConfiguration(raw, role) {
|
|
34
|
+
const copy = structuredClone(raw);
|
|
35
|
+
if (role === "publisher") {
|
|
36
|
+
const output = copy["output"];
|
|
37
|
+
if (output) {
|
|
38
|
+
delete output["publishQueue"];
|
|
39
|
+
if (!Object.keys(output).length)
|
|
40
|
+
delete copy["output"];
|
|
41
|
+
}
|
|
42
|
+
const uns = copy["uns"];
|
|
43
|
+
if (uns) {
|
|
44
|
+
delete uns["handover"];
|
|
45
|
+
delete uns["instanceMode"];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return copy;
|
|
49
|
+
}
|
|
50
|
+
export function reviewProcessGroupMqttOutput(configs, root, stateRoot) {
|
|
51
|
+
const source = configs.source.publisher, target = configs.target.publisher;
|
|
52
|
+
for (const role of ["publisher", "receiver"]) {
|
|
53
|
+
const raw = configs.source[role].raw;
|
|
54
|
+
if (raw.output?.publishQueue !== undefined)
|
|
55
|
+
throw Error("Output enablement requires a source without an MQTT queue");
|
|
56
|
+
}
|
|
57
|
+
if (configs.target.receiver.raw["output"]?.publishQueue !== undefined)
|
|
58
|
+
throw Error("Admission receiver cannot own the publisher output queue");
|
|
59
|
+
const queue = mqttPublishQueueSchema.parse(target.raw["output"]?.publishQueue);
|
|
60
|
+
if (queue.mode !== "durable" || queue.storage !== "runtime")
|
|
61
|
+
throw Error("Reviewed output enablement requires durable Runtime storage");
|
|
62
|
+
const uns = target.raw["uns"];
|
|
63
|
+
if (uns["handover"] !== false || !["force", "wait"].includes(String(uns["instanceMode"])))
|
|
64
|
+
throw Error("MQTT output enablement requires explicit stop-before-start configuration");
|
|
65
|
+
if (!root || path.resolve(root) === path.resolve(stateRoot) || queue.directory.startsWith(path.resolve(stateRoot) + path.sep))
|
|
66
|
+
throw Error("A separate permanent MQTT output mount is required");
|
|
67
|
+
const binding = managedMqttOutputBinding(target.raw, root);
|
|
68
|
+
const pkg = JSON.parse(read(path.join(target.packageRoot, "package.json")).toString());
|
|
69
|
+
const sourcePackage = JSON.parse(read(path.join(source.packageRoot, "package.json")).toString());
|
|
70
|
+
if (pkg.name !== sourcePackage.name)
|
|
71
|
+
throw Error("Publisher package identity changed");
|
|
72
|
+
const declaration = processGroupMqttOutputRuntimeSchema.parse(pkg.unsDatahub?.processGroupMqttOutputRuntime);
|
|
73
|
+
const processName = String(target.raw["uns"]["processName"]);
|
|
74
|
+
if (processName !== String(source.raw["uns"]["processName"]))
|
|
75
|
+
throw Error("Publisher identity changed");
|
|
76
|
+
const identity = sha256(mqttPublishQueueIdentity(pkg.name, processName + "-" + declaration.instanceName, resolvedProcessGroupChannels(target.resolved)[2]));
|
|
77
|
+
const status = inspectManagedOutputQueue(root, binding.directory, identity, mqttOutputStateLimits);
|
|
78
|
+
if (status.records || status.bytes)
|
|
79
|
+
throw Error("Output enablement requires an empty original-destination queue; preserve pending work");
|
|
80
|
+
return { root, directory: binding.directory, rootId: status.rootId, relative: binding.relative, identity, optionsSha256: hash(queue) };
|
|
81
|
+
}
|
|
82
|
+
/** Recheck after proven exit and immediately before policy/start. Unknown state is never empty. */
|
|
83
|
+
export function inspectReviewedProcessGroupMqttOutput(reference, requireStopped = true) {
|
|
84
|
+
const status = inspectManagedOutputQueue(reference.root, reference.directory, reference.identity, mqttOutputStateLimits, requireStopped);
|
|
85
|
+
if (status.rootId !== reference.rootId || status.relative !== reference.relative)
|
|
86
|
+
throw Error("Reviewed MQTT output storage identity changed");
|
|
87
|
+
return status;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=process-group-mqtt-output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-group-mqtt-output.js","sourceRoot":"","sources":["../../src/runtime/process-group-mqtt-output.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\nimport { z } from \"zod\";\n\nimport { mqttPublishQueueIdentity, mqttPublishQueueSchema } from \"../uns-mqtt/publish-queue-contract.js\";\nimport { managedMqttOutputBinding, mqttOutputStateLimits } from \"./mqtt-output-state-contract.js\";\nimport { inspectManagedOutputQueue } from \"./mqtt-output-state-program.mjs\";\nimport { resolvedProcessGroupChannels } from \"./process-group-contract.js\";\nimport { groupPlacementSchema, placementKey } from \"./process-group-control-contract.js\";\nimport { configurationAuthorizationHash as hash, readProcessGroupResource as read, sha256 } from \"./process-group-resources.js\";\nimport type { UpgradeConfigurations } from \"./process-group-upgrade.js\";\n\nexport const processGroupMqttOutputRuntimeSchema = z.strictObject({\n protocolVersion: z.literal(1),\n instanceName: z.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,99}$/),\n});\nconst pair = z.strictObject({ publisher: groupPlacementSchema, receiver: groupPlacementSchema });\n/** An explicit output enablement, never an incidental version/configuration change. */\nexport const processGroupMqttOutputInputSchema = z\n .strictObject({\n protocolVersion: z.literal(3),\n source: pair,\n target: pair,\n acknowledgeInputPause: z.literal(true),\n acknowledgePossibleReplay: z.literal(true),\n acknowledgePendingOutputBlocksRollback: z.literal(true),\n })\n .superRefine((v, c) => {\n const all = [v.source.publisher, v.source.receiver, v.target.publisher, v.target.receiver];\n if (\n new Set(all.map(placementKey)).size !== 4 ||\n all.some((p) => p.controller !== all[0]!.controller || p.rttNode !== all[0]!.rttNode) ||\n v.source.publisher.version !== v.source.receiver.version ||\n v.target.publisher.version !== v.target.receiver.version\n )\n c.addIssue({ code: \"custom\", message: \"Four distinct same-host paired placements required\" });\n });\nexport type GroupMqttOutputReference = { root: string; directory: string; rootId: string; relative: string; identity: string; optionsSha256: string };\n/** Only these explicitly reviewed output fields can differ; all other portable data remains exact. */\nexport function mqttOutputPortableConfiguration(raw: Record<string, unknown>, role: \"publisher\" | \"receiver\") {\n const copy = structuredClone(raw);\n if (role === \"publisher\") {\n const output = copy[\"output\"] as Record<string, unknown> | undefined;\n if (output) {\n delete output[\"publishQueue\"];\n if (!Object.keys(output).length) delete copy[\"output\"];\n }\n const uns = copy[\"uns\"] as Record<string, unknown> | undefined;\n if (uns) {\n delete uns[\"handover\"];\n delete uns[\"instanceMode\"];\n }\n }\n return copy;\n}\nexport function reviewProcessGroupMqttOutput(configs: UpgradeConfigurations, root: string | undefined, stateRoot: string): GroupMqttOutputReference {\n const source = configs.source.publisher,\n target = configs.target.publisher;\n for (const role of [\"publisher\", \"receiver\"] as const) {\n const raw = configs.source[role].raw as { output?: { publishQueue?: unknown } };\n if (raw.output?.publishQueue !== undefined) throw Error(\"Output enablement requires a source without an MQTT queue\");\n }\n if ((configs.target.receiver.raw[\"output\"] as { publishQueue?: unknown } | undefined)?.publishQueue !== undefined)\n throw Error(\"Admission receiver cannot own the publisher output queue\");\n const queue = mqttPublishQueueSchema.parse((target.raw[\"output\"] as { publishQueue?: unknown } | undefined)?.publishQueue);\n if (queue.mode !== \"durable\" || queue.storage !== \"runtime\") throw Error(\"Reviewed output enablement requires durable Runtime storage\");\n const uns = target.raw[\"uns\"] as Record<string, unknown>;\n if (uns[\"handover\"] !== false || ![\"force\", \"wait\"].includes(String(uns[\"instanceMode\"])))\n throw Error(\"MQTT output enablement requires explicit stop-before-start configuration\");\n if (!root || path.resolve(root) === path.resolve(stateRoot) || queue.directory.startsWith(path.resolve(stateRoot) + path.sep))\n throw Error(\"A separate permanent MQTT output mount is required\");\n const binding = managedMqttOutputBinding(target.raw, root)!;\n const pkg = JSON.parse(read(path.join(target.packageRoot, \"package.json\")).toString());\n const sourcePackage = JSON.parse(read(path.join(source.packageRoot, \"package.json\")).toString());\n if (pkg.name !== sourcePackage.name) throw Error(\"Publisher package identity changed\");\n const declaration = processGroupMqttOutputRuntimeSchema.parse(pkg.unsDatahub?.processGroupMqttOutputRuntime);\n const processName = String((target.raw[\"uns\"] as Record<string, unknown>)[\"processName\"]);\n if (processName !== String((source.raw[\"uns\"] as Record<string, unknown>)[\"processName\"])) throw Error(\"Publisher identity changed\");\n const identity = sha256(\n mqttPublishQueueIdentity(pkg.name, processName + \"-\" + declaration.instanceName, resolvedProcessGroupChannels(target.resolved)[2]!),\n );\n const status = inspectManagedOutputQueue(root, binding.directory, identity, mqttOutputStateLimits);\n if (status.records || status.bytes) throw Error(\"Output enablement requires an empty original-destination queue; preserve pending work\");\n return { root, directory: binding.directory, rootId: status.rootId, relative: binding.relative, identity, optionsSha256: hash(queue) };\n}\n/** Recheck after proven exit and immediately before policy/start. Unknown state is never empty. */\nexport function inspectReviewedProcessGroupMqttOutput(reference: GroupMqttOutputReference, requireStopped = true) {\n const status = inspectManagedOutputQueue(reference.root, reference.directory, reference.identity, mqttOutputStateLimits, requireStopped);\n if (status.rootId !== reference.rootId || status.relative !== reference.relative) throw Error(\"Reviewed MQTT output storage identity changed\");\n return status;\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type GroupGenerationReview, type GenerationJournalReference } from "./process-group-generation.js";
|
|
2
1
|
import { z } from "zod";
|
|
2
|
+
import { type GenerationJournalReference, type GroupGenerationReview } from "./process-group-generation.js";
|
|
3
|
+
import { type GroupMqttOutputReference } from "./process-group-mqtt-output.js";
|
|
3
4
|
export declare const processGroupUpgradeInputSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
4
5
|
protocolVersion: z.ZodLiteral<1>;
|
|
5
6
|
source: z.ZodObject<{
|
|
@@ -63,6 +64,39 @@ export declare const processGroupUpgradeInputSchema: z.ZodUnion<readonly [z.ZodO
|
|
|
63
64
|
acknowledgeInputPause: z.ZodLiteral<true>;
|
|
64
65
|
acknowledgeResourceReview: z.ZodLiteral<true>;
|
|
65
66
|
acknowledgePossibleReplay: z.ZodLiteral<true>;
|
|
67
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
68
|
+
protocolVersion: z.ZodLiteral<3>;
|
|
69
|
+
source: z.ZodObject<{
|
|
70
|
+
publisher: z.ZodObject<{
|
|
71
|
+
controller: z.ZodString;
|
|
72
|
+
rttNode: z.ZodString;
|
|
73
|
+
version: z.ZodString;
|
|
74
|
+
instanceId: z.ZodString;
|
|
75
|
+
}, z.core.$strict>;
|
|
76
|
+
receiver: z.ZodObject<{
|
|
77
|
+
controller: z.ZodString;
|
|
78
|
+
rttNode: z.ZodString;
|
|
79
|
+
version: z.ZodString;
|
|
80
|
+
instanceId: z.ZodString;
|
|
81
|
+
}, z.core.$strict>;
|
|
82
|
+
}, z.core.$strict>;
|
|
83
|
+
target: z.ZodObject<{
|
|
84
|
+
publisher: z.ZodObject<{
|
|
85
|
+
controller: z.ZodString;
|
|
86
|
+
rttNode: z.ZodString;
|
|
87
|
+
version: z.ZodString;
|
|
88
|
+
instanceId: z.ZodString;
|
|
89
|
+
}, z.core.$strict>;
|
|
90
|
+
receiver: z.ZodObject<{
|
|
91
|
+
controller: z.ZodString;
|
|
92
|
+
rttNode: z.ZodString;
|
|
93
|
+
version: z.ZodString;
|
|
94
|
+
instanceId: z.ZodString;
|
|
95
|
+
}, z.core.$strict>;
|
|
96
|
+
}, z.core.$strict>;
|
|
97
|
+
acknowledgeInputPause: z.ZodLiteral<true>;
|
|
98
|
+
acknowledgePossibleReplay: z.ZodLiteral<true>;
|
|
99
|
+
acknowledgePendingOutputBlocksRollback: z.ZodLiteral<true>;
|
|
66
100
|
}, z.core.$strict>]>;
|
|
67
101
|
export type ProcessGroupUpgradeInput = z.infer<typeof processGroupUpgradeInputSchema>;
|
|
68
102
|
export type UpgradeRole = "publisher" | "receiver";
|
|
@@ -98,7 +132,16 @@ export type GroupVersionUpgradeReview = {
|
|
|
98
132
|
artifactSha256: string;
|
|
99
133
|
}>;
|
|
100
134
|
};
|
|
101
|
-
export type
|
|
135
|
+
export type GroupMqttOutputReview = Omit<GroupVersionUpgradeReview, "protocolVersion"> & {
|
|
136
|
+
protocolVersion: 3;
|
|
137
|
+
mqttOutput: GroupMqttOutputReference;
|
|
138
|
+
delivery: {
|
|
139
|
+
inputPausePossible: true;
|
|
140
|
+
exactlyOnceOutput: false;
|
|
141
|
+
pendingOutputBlocksRollback: true;
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
export type GroupUpgradeReview = GroupVersionUpgradeReview | GroupGenerationReview | GroupMqttOutputReview;
|
|
102
145
|
export type PreparedGroupUpgrade = {
|
|
103
146
|
review: GroupUpgradeReview;
|
|
104
147
|
sourcePolicy: Buffer;
|
|
@@ -106,6 +149,8 @@ export type PreparedGroupUpgrade = {
|
|
|
106
149
|
};
|
|
107
150
|
/** Data-only same-host version review. No application JS, journal writes or launch authority. */
|
|
108
151
|
export declare function reviewInstalledProcessGroupUpgrade(configs: UpgradeConfigurations, controllerName: string, stateRoot: string, excludedUnsFields?: readonly string[]): PreparedGroupUpgrade;
|
|
152
|
+
/** Explicit shared output capability. Ordinary upgrades keep their strict comparison. */
|
|
153
|
+
export declare function reviewInstalledProcessGroupMqttOutput(configs: UpgradeConfigurations, controllerName: string, stateRoot: string, excludedUnsFields?: readonly string[], outputRoot?: string): PreparedGroupUpgrade;
|
|
109
154
|
/** Atomic compare-and-swap. The authenticated host must first prove both old owners exited. */
|
|
110
155
|
export declare function replaceReviewedProcessGroupPolicy(file: string, expected: string, bytes: Buffer): void;
|
|
111
156
|
export declare const processGroupUpgradeRequestSchema: z.ZodObject<{
|
|
@@ -181,6 +226,39 @@ export declare const processGroupUpgradeRequestSchema: z.ZodObject<{
|
|
|
181
226
|
acknowledgeInputPause: z.ZodLiteral<true>;
|
|
182
227
|
acknowledgeResourceReview: z.ZodLiteral<true>;
|
|
183
228
|
acknowledgePossibleReplay: z.ZodLiteral<true>;
|
|
229
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
230
|
+
protocolVersion: z.ZodLiteral<3>;
|
|
231
|
+
source: z.ZodObject<{
|
|
232
|
+
publisher: z.ZodObject<{
|
|
233
|
+
controller: z.ZodString;
|
|
234
|
+
rttNode: z.ZodString;
|
|
235
|
+
version: z.ZodString;
|
|
236
|
+
instanceId: z.ZodString;
|
|
237
|
+
}, z.core.$strict>;
|
|
238
|
+
receiver: z.ZodObject<{
|
|
239
|
+
controller: z.ZodString;
|
|
240
|
+
rttNode: z.ZodString;
|
|
241
|
+
version: z.ZodString;
|
|
242
|
+
instanceId: z.ZodString;
|
|
243
|
+
}, z.core.$strict>;
|
|
244
|
+
}, z.core.$strict>;
|
|
245
|
+
target: z.ZodObject<{
|
|
246
|
+
publisher: z.ZodObject<{
|
|
247
|
+
controller: z.ZodString;
|
|
248
|
+
rttNode: z.ZodString;
|
|
249
|
+
version: z.ZodString;
|
|
250
|
+
instanceId: z.ZodString;
|
|
251
|
+
}, z.core.$strict>;
|
|
252
|
+
receiver: z.ZodObject<{
|
|
253
|
+
controller: z.ZodString;
|
|
254
|
+
rttNode: z.ZodString;
|
|
255
|
+
version: z.ZodString;
|
|
256
|
+
instanceId: z.ZodString;
|
|
257
|
+
}, z.core.$strict>;
|
|
258
|
+
}, z.core.$strict>;
|
|
259
|
+
acknowledgeInputPause: z.ZodLiteral<true>;
|
|
260
|
+
acknowledgePossibleReplay: z.ZodLiteral<true>;
|
|
261
|
+
acknowledgePendingOutputBlocksRollback: z.ZodLiteral<true>;
|
|
184
262
|
}, z.core.$strict>]>>;
|
|
185
263
|
id: z.ZodOptional<z.ZodString>;
|
|
186
264
|
expectedFingerprint: z.ZodOptional<z.ZodString>;
|
|
@@ -192,4 +270,9 @@ export declare function inspectProcessGroupUpgradeJournal(review: Pick<GroupVers
|
|
|
192
270
|
receiverReady: boolean;
|
|
193
271
|
publisherReady: boolean;
|
|
194
272
|
};
|
|
273
|
+
/** Bounded, read-only usage for a retained file/configuration input journal. */
|
|
274
|
+
export declare function inspectProcessGroupUpgradeUsage(review: Pick<GroupVersionUpgradeReview, "directory" | "journalId" | "journalContractSha256">): {
|
|
275
|
+
records: number;
|
|
276
|
+
bytes: number;
|
|
277
|
+
};
|
|
195
278
|
//# sourceMappingURL=process-group-upgrade.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-group-upgrade.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-upgrade.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"process-group-upgrade.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-upgrade.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { reviewInstalledConfigurationGroupUpgrade } from "./process-group-configured-upgrade.js";
|
|
2
|
-
import { selectedProcessGroupDescriptor } from "./process-group-runtime-selection.js";
|
|
3
|
-
import { processGroupGenerationInputSchema } from "./process-group-generation.js";
|
|
4
1
|
import fs from "node:fs";
|
|
5
2
|
import { createRequire } from "node:module";
|
|
6
3
|
import path from "node:path";
|
|
7
4
|
import { z } from "zod";
|
|
8
5
|
import { authorizeProcessGroupRuntime, processGroupAuthorizationFile, processGroupAuthorizationSchema, processGroupManifestSchema, validateProcessGroupPolicyCandidate, } from "./process-group-authorization.js";
|
|
6
|
+
import { reviewInstalledConfigurationGroupMqttOutput, reviewInstalledConfigurationGroupUpgrade } from "./process-group-configured-upgrade.js";
|
|
9
7
|
import { normalizeProcessGroupConfiguration, processGroupDescriptor, processGroupJournalContract, processGroupJournalSchema, processGroupSourceIdentity, resolvedProcessGroupChannels, } from "./process-group-contract.js";
|
|
10
8
|
import { groupPlacementSchema, placementKey } from "./process-group-control-contract.js";
|
|
9
|
+
import { processGroupGenerationInputSchema } from "./process-group-generation.js";
|
|
10
|
+
import { mqttOutputPortableConfiguration, processGroupMqttOutputInputSchema, reviewProcessGroupMqttOutput, } from "./process-group-mqtt-output.js";
|
|
11
11
|
import { groupArtifactHash, groupChannelsHash, configurationAuthorizationHash as hash, readProcessGroupResource as read, sha256, } from "./process-group-resources.js";
|
|
12
|
+
import { selectedProcessGroupDescriptor } from "./process-group-runtime-selection.js";
|
|
12
13
|
const pair = z.strictObject({ publisher: groupPlacementSchema, receiver: groupPlacementSchema });
|
|
13
14
|
const processGroupVersionUpgradeInputSchema = z.strictObject({ protocolVersion: z.literal(1), source: pair, target: pair }).superRefine((v, c) => {
|
|
14
15
|
const all = [v.source.publisher, v.source.receiver, v.target.publisher, v.target.receiver];
|
|
@@ -19,11 +20,34 @@ const processGroupVersionUpgradeInputSchema = z.strictObject({ protocolVersion:
|
|
|
19
20
|
v.source.publisher.version === v.target.publisher.version)
|
|
20
21
|
c.addIssue({ code: "custom", message: "Four distinct placements, one package/controller and two paired versions required" });
|
|
21
22
|
});
|
|
22
|
-
export const processGroupUpgradeInputSchema = z.union([
|
|
23
|
+
export const processGroupUpgradeInputSchema = z.union([
|
|
24
|
+
processGroupVersionUpgradeInputSchema,
|
|
25
|
+
processGroupGenerationInputSchema,
|
|
26
|
+
processGroupMqttOutputInputSchema,
|
|
27
|
+
]);
|
|
23
28
|
/** Data-only same-host version review. No application JS, journal writes or launch authority. */
|
|
24
29
|
export function reviewInstalledProcessGroupUpgrade(configs, controllerName, stateRoot, excludedUnsFields = []) {
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
return reviewRetainedProcessGroup(configs, controllerName, stateRoot, excludedUnsFields);
|
|
31
|
+
}
|
|
32
|
+
/** Explicit shared output capability. Ordinary upgrades keep their strict comparison. */
|
|
33
|
+
export function reviewInstalledProcessGroupMqttOutput(configs, controllerName, stateRoot, excludedUnsFields = [], outputRoot = process.env["UNS_MQTT_OUTPUT_STATE_ROOT"]) {
|
|
34
|
+
const mqttOutput = reviewProcessGroupMqttOutput(configs, outputRoot, stateRoot);
|
|
35
|
+
const result = reviewRetainedProcessGroup(configs, controllerName, stateRoot, excludedUnsFields, true);
|
|
36
|
+
return {
|
|
37
|
+
...result,
|
|
38
|
+
review: {
|
|
39
|
+
...result.review,
|
|
40
|
+
protocolVersion: 3,
|
|
41
|
+
mqttOutput,
|
|
42
|
+
delivery: { inputPausePossible: true, exactlyOnceOutput: false, pendingOutputBlocksRollback: true },
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function reviewRetainedProcessGroup(configs, controllerName, stateRoot, excludedUnsFields, mqttOutput = false) {
|
|
47
|
+
if (Object.values(configs)
|
|
48
|
+
.flatMap(Object.values)
|
|
49
|
+
.some((c) => selectedProcessGroupDescriptor(c.packageRoot, c.raw)?.protocolVersion === 2))
|
|
50
|
+
return (mqttOutput ? reviewInstalledConfigurationGroupMqttOutput : reviewInstalledConfigurationGroupUpgrade)(configs, controllerName, stateRoot, excludedUnsFields);
|
|
27
51
|
const first = configs.source.publisher;
|
|
28
52
|
const context = (c) => ({
|
|
29
53
|
packageRoot: c.packageRoot,
|
|
@@ -55,8 +79,8 @@ export function reviewInstalledProcessGroupUpgrade(configs, controllerName, stat
|
|
|
55
79
|
if (manifest.id !== resource.id || journal.directory !== old.directory || journal.journalId !== old.journalId)
|
|
56
80
|
throw Error("Journal or manifest identity changed");
|
|
57
81
|
const members = [];
|
|
58
|
-
const portable = (raw) => {
|
|
59
|
-
const copy = structuredClone(raw), uns = { ...copy["uns"] };
|
|
82
|
+
const portable = (raw, role) => {
|
|
83
|
+
const copy = mqttOutput ? mqttOutputPortableConfiguration(raw, role) : structuredClone(raw), uns = { ...copy["uns"] };
|
|
60
84
|
for (const k of excludedUnsFields)
|
|
61
85
|
delete uns[k];
|
|
62
86
|
copy["uns"] = uns;
|
|
@@ -64,7 +88,7 @@ export function reviewInstalledProcessGroupUpgrade(configs, controllerName, stat
|
|
|
64
88
|
};
|
|
65
89
|
for (const role of ["publisher", "receiver"]) {
|
|
66
90
|
const a = configs.source[role], b = configs.target[role];
|
|
67
|
-
if (portable(a.raw) !== portable(b.raw) ||
|
|
91
|
+
if (portable(a.raw, role) !== portable(b.raw, role) ||
|
|
68
92
|
groupChannelsHash(resolvedProcessGroupChannels(a.resolved)) !== groupChannelsHash(resolvedProcessGroupChannels(b.resolved)))
|
|
69
93
|
throw Error("Configuration, broker identity, paths or units changed");
|
|
70
94
|
for (const side of ["source", "target"]) {
|
|
@@ -259,4 +283,45 @@ export function inspectProcessGroupUpgradeJournal(review, publisherPid, receiver
|
|
|
259
283
|
db.close();
|
|
260
284
|
}
|
|
261
285
|
}
|
|
286
|
+
/** Bounded, read-only usage for a retained file/configuration input journal. */
|
|
287
|
+
export function inspectProcessGroupUpgradeUsage(review) {
|
|
288
|
+
const file = path.join(review.directory, "admission.sqlite"), s = fs.lstatSync(file);
|
|
289
|
+
if (fs.realpathSync(file) !== file ||
|
|
290
|
+
!s.isFile() ||
|
|
291
|
+
s.nlink !== 1 ||
|
|
292
|
+
s.uid !== process.getuid?.() ||
|
|
293
|
+
(s.mode & 0o077) !== 0 ||
|
|
294
|
+
s.size > 512 * 1024 * 1024)
|
|
295
|
+
throw Error("Private retained journal required");
|
|
296
|
+
const { DatabaseSync } = createRequire(import.meta.url)("node:sqlite");
|
|
297
|
+
const db = new DatabaseSync(file, { readOnly: true });
|
|
298
|
+
try {
|
|
299
|
+
db.exec("PRAGMA query_only=ON; PRAGMA busy_timeout=1000; BEGIN");
|
|
300
|
+
if (db.prepare("PRAGMA quick_check").get()["quick_check"] !== "ok")
|
|
301
|
+
throw Error("Journal integrity unconfirmed");
|
|
302
|
+
const meta = Object.fromEntries(db
|
|
303
|
+
.prepare("SELECT key,value FROM metadata WHERE key IN ('id','contract')")
|
|
304
|
+
.all()
|
|
305
|
+
.map((r) => [r["key"], r["value"]]));
|
|
306
|
+
if (meta["id"] !== review.journalId || sha256(String(meta["contract"])) !== review.journalContractSha256)
|
|
307
|
+
throw Error("Retained journal identity changed");
|
|
308
|
+
const usage = db.prepare("SELECT records,bytes FROM usage WHERE id=1").get();
|
|
309
|
+
const pending = db.prepare("SELECT COUNT(*) records,COALESCE(SUM(bytes),0) bytes FROM tasks").get();
|
|
310
|
+
const records = Number(pending["records"]), bytes = Number(pending["bytes"]);
|
|
311
|
+
if (!usage ||
|
|
312
|
+
usage["records"] !== records ||
|
|
313
|
+
usage["bytes"] !== bytes ||
|
|
314
|
+
!Number.isSafeInteger(records) ||
|
|
315
|
+
records < 0 ||
|
|
316
|
+
records > 100000 ||
|
|
317
|
+
!Number.isSafeInteger(bytes) ||
|
|
318
|
+
bytes < 0 ||
|
|
319
|
+
bytes > 256 * 1024 * 1024)
|
|
320
|
+
throw Error("Retained journal usage unconfirmed");
|
|
321
|
+
return { records, bytes };
|
|
322
|
+
}
|
|
323
|
+
finally {
|
|
324
|
+
db.close();
|
|
325
|
+
}
|
|
326
|
+
}
|
|
262
327
|
//# sourceMappingURL=process-group-upgrade.js.map
|