@uns-kit/core 3.0.31 → 3.0.33
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 +43 -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-drain.d.ts +29 -0
- package/dist/runtime/mqtt-drain.d.ts.map +1 -0
- package/dist/runtime/mqtt-drain.js +70 -0
- package/dist/runtime/mqtt-drain.js.map +1 -0
- package/dist/runtime/mqtt-output-state-contract.d.ts.map +1 -1
- package/dist/runtime/mqtt-output-state-contract.js +2 -0
- package/dist/runtime/mqtt-output-state-contract.js.map +1 -1
- package/dist/runtime/mqtt-output-state-program.d.mts +4 -0
- package/dist/runtime/mqtt-output-state-program.mjs +51 -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/uns-proxy-process.d.ts +8 -4
- package/dist/uns/uns-proxy-process.d.ts.map +1 -1
- package/dist/uns/uns-proxy-process.js +41 -5
- package/dist/uns/uns-proxy-process.js.map +1 -1
- package/dist/uns-config/config-schema.d.ts +1 -0
- package/dist/uns-config/config-schema.d.ts.map +1 -1
- package/dist/uns-config/uns-core-schema.d.ts +2 -0
- package/dist/uns-config/uns-core-schema.d.ts.map +1 -1
- package/dist/uns-mqtt/disabled-publish-queue.d.ts +6 -0
- package/dist/uns-mqtt/disabled-publish-queue.d.ts.map +1 -0
- package/dist/uns-mqtt/disabled-publish-queue.js +64 -0
- package/dist/uns-mqtt/disabled-publish-queue.js.map +1 -0
- package/dist/uns-mqtt/publish-queue-contract.d.ts +11 -0
- package/dist/uns-mqtt/publish-queue-contract.d.ts.map +1 -1
- package/dist/uns-mqtt/publish-queue-contract.js +16 -0
- package/dist/uns-mqtt/publish-queue-contract.js.map +1 -1
- package/dist/uns-mqtt/publish-queue.d.ts.map +1 -1
- package/dist/uns-mqtt/publish-queue.js +2 -0
- package/dist/uns-mqtt/publish-queue.js.map +1 -1
- package/dist/uns-mqtt/uns-mqtt-proxy.d.ts +3 -0
- package/dist/uns-mqtt/uns-mqtt-proxy.d.ts.map +1 -1
- package/dist/uns-mqtt/uns-mqtt-proxy.js +19 -8
- package/dist/uns-mqtt/uns-mqtt-proxy.js.map +1 -1
- package/package.json +1 -1
|
@@ -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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-group-upgrade.js","sourceRoot":"","sources":["../../src/runtime/process-group-upgrade.ts"],"names":[],"mappings":"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","sourcesContent":["import { reviewInstalledConfigurationGroupUpgrade } from \"./process-group-configured-upgrade.js\";\nimport { selectedProcessGroupDescriptor } from \"./process-group-runtime-selection.js\";\nimport {processGroupGenerationInputSchema,type GroupGenerationReview,type GenerationJournalReference} from \"./process-group-generation.js\";\nimport fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\n\nimport {\n authorizeProcessGroupRuntime,\n processGroupAuthorizationFile,\n processGroupAuthorizationSchema,\n processGroupManifestSchema,\n validateProcessGroupPolicyCandidate,\n} from \"./process-group-authorization.js\";\nimport {\n normalizeProcessGroupConfiguration,\n processGroupDescriptor,\n processGroupJournalContract,\n processGroupJournalSchema,\n processGroupSourceIdentity,\n resolvedProcessGroupChannels,\n} from \"./process-group-contract.js\";\nimport { groupPlacementSchema, placementKey } from \"./process-group-control-contract.js\";\nimport {\n groupArtifactHash,\n groupChannelsHash,\n configurationAuthorizationHash as hash,\n readProcessGroupResource as read,\n sha256,\n} from \"./process-group-resources.js\";\n\nconst pair = z.strictObject({ publisher: groupPlacementSchema, receiver: groupPlacementSchema });\nconst processGroupVersionUpgradeInputSchema = z.strictObject({ protocolVersion: z.literal(1), source: pair, target: pair }).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 v.source.publisher.version === v.target.publisher.version\n )\n c.addIssue({ code: \"custom\", message: \"Four distinct placements, one package/controller and two paired versions required\" });\n});\nexport const processGroupUpgradeInputSchema=z.union([processGroupVersionUpgradeInputSchema,processGroupGenerationInputSchema]);\nexport type ProcessGroupUpgradeInput = z.infer<typeof processGroupUpgradeInputSchema>;\nexport type UpgradeRole = \"publisher\" | \"receiver\";\nexport type UpgradeConfiguration = {\n packageRoot: string;\n instanceDirectory: string;\n raw: Record<string, unknown>;\n resolved: Record<string, unknown>;\n};\nexport type UpgradeConfigurations = Record<\"source\" | \"target\", Record<UpgradeRole, UpgradeConfiguration>>;\nexport type GroupVersionUpgradeReview = {\n protocolVersion: 1;\n /** Present only for configuration-owned protocol-2 resources retained across a version change. */\n retainedJournal?: GenerationJournalReference;\n namespace: string;\n groupId: string;\n policyFile: string;\n sourcePolicySha256: string;\n targetPolicySha256: string;\n journalId: string;\n directory: string;\n journalContractSha256: string;\n profiles: Array<{ processName: string; mappingSha256: string; dataGroup: string }>;\n members: Array<{ side: \"source\" | \"target\"; role: UpgradeRole; processName: string; configurationSha256: string; artifactSha256: string }>;\n};\nexport type GroupUpgradeReview = GroupVersionUpgradeReview | GroupGenerationReview;\nexport type PreparedGroupUpgrade = { review: GroupUpgradeReview; sourcePolicy: Buffer; targetPolicy: Buffer };\n\n/** Data-only same-host version review. No application JS, journal writes or launch authority. */\nexport function reviewInstalledProcessGroupUpgrade(\n configs: UpgradeConfigurations,\n controllerName: string,\n stateRoot: string,\n excludedUnsFields: readonly string[] = [],\n): PreparedGroupUpgrade {\n if (Object.values(configs).flatMap(Object.values).some(c => selectedProcessGroupDescriptor(c.packageRoot, c.raw)?.protocolVersion === 2))\n return reviewInstalledConfigurationGroupUpgrade(configs, controllerName, stateRoot, excludedUnsFields);\n const first = configs.source.publisher;\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 old = authorizeProcessGroupRuntime(context(first));\n const receiver = authorizeProcessGroupRuntime(context(configs.source.receiver));\n if (\n old.role !== \"target\" ||\n receiver.role !== \"receiver\" ||\n old.file !== receiver.file ||\n old.directory !== receiver.directory ||\n !old.journalId ||\n old.journalId !== receiver.journalId\n )\n throw Error(\"Exact authorized source publisher/receiver pair required\");\n const sourcePolicy = read(old.file, true),\n previous = JSON.parse(sourcePolicy.toString());\n const target = configs.target.publisher,\n descriptor = processGroupDescriptor(target.packageRoot);\n if (!descriptor || descriptor.legacy) throw Error(\"Target requires the shared process-group protocol declaration\");\n const targetConfig = normalizeProcessGroupConfiguration(target.raw, descriptor);\n const journal = processGroupJournalSchema.parse(targetConfig.journal);\n const resource = descriptor.manifests.find((m) => m.file === journal.groupManifest);\n if (!resource) throw Error(\"Unregistered target manifest\");\n const manifestBytes = read(path.join(target.packageRoot, resource.file)),\n manifest = processGroupManifestSchema.parse(JSON.parse(manifestBytes.toString()));\n if (manifest.id !== resource.id || journal.directory !== old.directory || journal.journalId !== old.journalId)\n throw Error(\"Journal or manifest identity changed\");\n const members: GroupUpgradeReview[\"members\"] = [];\n const portable = (raw: Record<string, unknown>) => {\n const copy = structuredClone(raw),\n uns = { ...(copy[\"uns\"] as Record<string, unknown>) };\n for (const k of excludedUnsFields) delete uns[k];\n copy[\"uns\"] = uns;\n return hash(copy);\n };\n for (const role of [\"publisher\", \"receiver\"] as const) {\n const a = configs.source[role],\n b = configs.target[role];\n if (\n portable(a.raw) !== portable(b.raw) ||\n groupChannelsHash(resolvedProcessGroupChannels(a.resolved)) !== groupChannelsHash(resolvedProcessGroupChannels(b.resolved))\n )\n throw Error(\"Configuration, broker identity, paths or units changed\");\n for (const side of [\"source\", \"target\"] as const) {\n const c = configs[side][role],\n d = processGroupDescriptor(c.packageRoot);\n if (!d) throw Error(\"Missing shared runtime contract\");\n const normalized = normalizeProcessGroupConfiguration(c.raw, d),\n j = processGroupJournalSchema.parse(normalized.journal);\n if (\n !normalized.matches ||\n (role === \"receiver\"\n ? normalized.runtimeRole !== \"admission\"\n : normalized.runtimeRole !== undefined && normalized.runtimeRole !== \"publisher\") ||\n j.directory !== old.directory ||\n j.journalId !== old.journalId ||\n sha256(read(path.join(c.packageRoot, j.groupManifest))) !== sha256(manifestBytes)\n )\n throw Error(\"Runtime role, manifest or journal differs\");\n members.push({\n side,\n role,\n processName: String(normalized.uns[\"processName\"]),\n configurationSha256: hash(c.raw),\n artifactSha256: groupArtifactHash(c.packageRoot),\n });\n }\n }\n if (\n members.find((m) => m.role === \"publisher\")?.processName !== manifest.processName ||\n members.find((m) => m.role === \"receiver\")?.processName !== manifest.processName + \"-admission\"\n )\n throw Error(\"Manifest process identities differ\");\n const pkg = JSON.parse(read(path.join(target.packageRoot, \"package.json\")).toString());\n const historical = previous.placements.filter((p: { role: string }) => p.role === \"source\");\n const policy = processGroupAuthorizationSchema.parse({\n schemaVersion: 3,\n kind: \"uns-process-group-runtime-authorization\",\n protocolVersion: 1,\n packageName: pkg.name,\n namespace: descriptor.namespace,\n groupId: manifest.id,\n descriptorSha256: hash(pkg.unsDatahub.processGroupRuntime),\n controllerName,\n packageRoot: target.packageRoot,\n artifactSha256: groupArtifactHash(target.packageRoot),\n groupManifestSha256: sha256(manifestBytes),\n channelsSha256: groupChannelsHash(resolvedProcessGroupChannels(target.resolved)),\n stateRoot,\n directory: old.directory,\n journalId: old.journalId,\n placements: [\n ...historical,\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: hash(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 const expected = processGroupJournalContract(\n processGroupSourceIdentity(resolvedProcessGroupChannels(target.resolved)[1]!),\n journal,\n manifest.profiles,\n );\n const file = path.join(old.directory, \"admission.sqlite\");\n if (fs.realpathSync(file) !== file || !fs.lstatSync(file).isFile()) throw Error(\"Unsafe journal resource\");\n const { DatabaseSync } = createRequire(import.meta.url)(\"node:sqlite\") as typeof import(\"node:sqlite\");\n const db = new DatabaseSync(file, { readOnly: true });\n try {\n db.exec(\"PRAGMA query_only=ON; PRAGMA busy_timeout=1000;\");\n const metadata = Object.fromEntries(\n db\n .prepare(\"SELECT key,value FROM metadata WHERE key IN ('id','contract')\")\n .all()\n .map((r) => [r[\"key\"], r[\"value\"]]),\n );\n if (metadata[\"id\"] !== old.journalId || metadata[\"contract\"] !== expected)\n throw Error(\"Installed target cannot reopen the retained journal contract\");\n } finally {\n db.close();\n }\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: descriptor.namespace,\n groupId: manifest.id,\n policyFile: processGroupAuthorizationFile(context(target)),\n sourcePolicySha256: sha256(sourcePolicy),\n targetPolicySha256: sha256(targetPolicy),\n journalId: old.journalId,\n directory: old.directory,\n journalContractSha256: sha256(expected),\n profiles: manifest.profiles.map(({ processName, mappingSha256, dataGroup }) => ({ processName, mappingSha256, dataGroup })),\n members,\n },\n sourcePolicy,\n targetPolicy,\n };\n}\n\n/** Atomic compare-and-swap. The authenticated host must first prove both old owners exited. */\nexport function replaceReviewedProcessGroupPolicy(file: string, expected: string, bytes: Buffer): void {\n const actual = sha256(read(file, true)),\n next = sha256(bytes);\n if (actual === next) return; // Reconcile an already completed write after a lost reply.\n if (actual !== expected) throw Error(\"Runtime policy changed; review required\");\n const temporary = file + \".upgrade-tmp\";\n const fd = fs.openSync(temporary, \"wx\", 0o600);\n try {\n fs.writeFileSync(fd, bytes);\n fs.fsyncSync(fd);\n } finally {\n fs.closeSync(fd);\n }\n try {\n if (sha256(read(file, true)) !== expected) throw Error(\"Runtime policy changed before replacement\");\n fs.renameSync(temporary, file);\n const directory = fs.openSync(path.dirname(file), \"r\");\n try {\n fs.fsyncSync(directory);\n } finally {\n fs.closeSync(directory);\n }\n } finally {\n if (fs.existsSync(temporary)) fs.unlinkSync(temporary);\n }\n}\n\nexport const processGroupUpgradeRequestSchema = z\n .strictObject({\n protocolVersion: z.literal(1),\n controllerName: groupPlacementSchema.shape.controller,\n action: z.enum([\"preview\", \"prepare\", \"get\", \"execute\", \"rollback\"]),\n input: processGroupUpgradeInputSchema.optional(),\n id: z.string().uuid().optional(),\n expectedFingerprint: z\n .string()\n .regex(/^[a-f0-9]{64}$/)\n .optional(),\n expectedRevision: z.number().int().positive().optional(),\n })\n .superRefine((v, c) => {\n if (\n ([\"preview\", \"prepare\"].includes(v.action) && !v.input) ||\n (v.action !== \"preview\" && !v.id) ||\n ([\"prepare\", \"execute\", \"rollback\"].includes(v.action) && !v.expectedFingerprint) ||\n ([\"execute\", \"rollback\"].includes(v.action) && !v.expectedRevision) ||\n (v.input && v.input.source.publisher.controller !== v.controllerName)\n )\n c.addIssue({ code: \"custom\", message: \"Exact upgrade selector and reviewed revision required\" });\n });\nexport type ProcessGroupUpgradeRequest = z.infer<typeof processGroupUpgradeRequestSchema>;\n/** Shared journal observations; only PID/start identity and fresh capture prove readiness. */\nexport function inspectProcessGroupUpgradeJournal(review: Pick<GroupVersionUpgradeReview,\"directory\"|\"journalId\"|\"journalContractSha256\"|\"profiles\">, publisherPid?: number, receiverPid?: number) {\n const file = path.join(review.directory, \"admission.sqlite\");\n if (fs.realpathSync(file) !== file) throw Error(\"Unsafe retained journal path\");\n const { DatabaseSync } = createRequire(import.meta.url)(\"node:sqlite\") as typeof import(\"node:sqlite\");\n const db = new DatabaseSync(file, { readOnly: true });\n try {\n db.exec(\"PRAGMA query_only=ON; PRAGMA busy_timeout=1000;\");\n const meta = Object.fromEntries(\n db\n .prepare(\"SELECT key,value FROM metadata WHERE key IN ('id','contract','capture','runtime_namespace')\")\n .all()\n .map((r) => [r[\"key\"], r[\"value\"]]),\n );\n if (meta[\"id\"] !== review.journalId || sha256(String(meta[\"contract\"])) !== review.journalContractSha256)\n throw Error(\"Retained journal contract changed\");\n const capture = JSON.parse(String(meta[\"capture\"] ?? \"null\"));\n const identity = (pid: number | undefined, digest: unknown) => {\n if (!pid || !Number.isSafeInteger(pid) || pid <= 0 || typeof digest !== \"string\" || process.platform !== \"linux\") return false;\n try {\n const namespace = sha256(fs.readFileSync(\"/proc/sys/kernel/random/boot_id\", \"utf8\").trim() + \":\" + fs.readlinkSync(\"/proc/self/ns/pid\"));\n const stat = fs.readFileSync(`/proc/${pid}/stat`, \"utf8\"),\n start = stat.slice(stat.lastIndexOf(\")\") + 2).split(\" \")[19];\n return meta[\"runtime_namespace\"] === namespace && !!start && digest === sha256(namespace + \":\" + pid + \":\" + start);\n } catch {\n return false;\n }\n };\n const rows = db.prepare(\"SELECT name,pid,owner,runtime_identity FROM profiles\").all();\n return {\n receiverReady:\n capture?.pid === receiverPid &&\n [\"ready\", \"capacity-blocked\"].includes(capture?.state) &&\n Number.isSafeInteger(capture?.heartbeat) &&\n capture.heartbeat <= Date.now() + 1000 &&\n Date.now() - capture.heartbeat <= 5000 &&\n identity(receiverPid, capture.runtimeIdentity),\n publisherReady:\n rows.length === review.profiles.length &&\n review.profiles.every((p) =>\n rows.some((r) => r[\"name\"] === p.processName && r[\"pid\"] === publisherPid && !!r[\"owner\"] && identity(publisherPid, r[\"runtime_identity\"])),\n ),\n };\n } finally {\n db.close();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"process-group-upgrade.js","sourceRoot":"","sources":["../../src/runtime/process-group-upgrade.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\n\nimport {\n authorizeProcessGroupRuntime,\n processGroupAuthorizationFile,\n processGroupAuthorizationSchema,\n processGroupManifestSchema,\n validateProcessGroupPolicyCandidate,\n} from \"./process-group-authorization.js\";\nimport { reviewInstalledConfigurationGroupMqttOutput, reviewInstalledConfigurationGroupUpgrade } from \"./process-group-configured-upgrade.js\";\nimport {\n normalizeProcessGroupConfiguration,\n processGroupDescriptor,\n processGroupJournalContract,\n processGroupJournalSchema,\n processGroupSourceIdentity,\n resolvedProcessGroupChannels,\n} from \"./process-group-contract.js\";\nimport { groupPlacementSchema, placementKey } from \"./process-group-control-contract.js\";\nimport { type GenerationJournalReference, type GroupGenerationReview, processGroupGenerationInputSchema } from \"./process-group-generation.js\";\nimport {\n type GroupMqttOutputReference,\n mqttOutputPortableConfiguration,\n processGroupMqttOutputInputSchema,\n reviewProcessGroupMqttOutput,\n} 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 { selectedProcessGroupDescriptor } from \"./process-group-runtime-selection.js\";\n\nconst pair = z.strictObject({ publisher: groupPlacementSchema, receiver: groupPlacementSchema });\nconst processGroupVersionUpgradeInputSchema = z.strictObject({ protocolVersion: z.literal(1), source: pair, target: pair }).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 v.source.publisher.version === v.target.publisher.version\n )\n c.addIssue({ code: \"custom\", message: \"Four distinct placements, one package/controller and two paired versions required\" });\n});\nexport const processGroupUpgradeInputSchema = z.union([\n processGroupVersionUpgradeInputSchema,\n processGroupGenerationInputSchema,\n processGroupMqttOutputInputSchema,\n]);\nexport type ProcessGroupUpgradeInput = z.infer<typeof processGroupUpgradeInputSchema>;\nexport type UpgradeRole = \"publisher\" | \"receiver\";\nexport type UpgradeConfiguration = {\n packageRoot: string;\n instanceDirectory: string;\n raw: Record<string, unknown>;\n resolved: Record<string, unknown>;\n};\nexport type UpgradeConfigurations = Record<\"source\" | \"target\", Record<UpgradeRole, UpgradeConfiguration>>;\nexport type GroupVersionUpgradeReview = {\n protocolVersion: 1;\n /** Present only for configuration-owned protocol-2 resources retained across a version change. */\n retainedJournal?: GenerationJournalReference;\n namespace: string;\n groupId: string;\n policyFile: string;\n sourcePolicySha256: string;\n targetPolicySha256: string;\n journalId: string;\n directory: string;\n journalContractSha256: string;\n profiles: Array<{ processName: string; mappingSha256: string; dataGroup: string }>;\n members: Array<{ side: \"source\" | \"target\"; role: UpgradeRole; processName: string; configurationSha256: string; artifactSha256: string }>;\n};\nexport type GroupMqttOutputReview = Omit<GroupVersionUpgradeReview, \"protocolVersion\"> & {\n protocolVersion: 3;\n mqttOutput: GroupMqttOutputReference;\n delivery: { inputPausePossible: true; exactlyOnceOutput: false; pendingOutputBlocksRollback: true };\n};\nexport type GroupUpgradeReview = GroupVersionUpgradeReview | GroupGenerationReview | GroupMqttOutputReview;\nexport type PreparedGroupUpgrade = { review: GroupUpgradeReview; sourcePolicy: Buffer; targetPolicy: Buffer };\n\n/** Data-only same-host version review. No application JS, journal writes or launch authority. */\nexport function reviewInstalledProcessGroupUpgrade(\n configs: UpgradeConfigurations,\n controllerName: string,\n stateRoot: string,\n excludedUnsFields: readonly string[] = [],\n): PreparedGroupUpgrade {\n return reviewRetainedProcessGroup(configs, controllerName, stateRoot, excludedUnsFields);\n}\n/** Explicit shared output capability. Ordinary upgrades keep their strict comparison. */\nexport function reviewInstalledProcessGroupMqttOutput(\n configs: UpgradeConfigurations,\n controllerName: string,\n stateRoot: string,\n excludedUnsFields: readonly string[] = [],\n outputRoot = process.env[\"UNS_MQTT_OUTPUT_STATE_ROOT\"],\n): PreparedGroupUpgrade {\n const mqttOutput = reviewProcessGroupMqttOutput(configs, outputRoot, stateRoot);\n const result = reviewRetainedProcessGroup(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 reviewRetainedProcessGroup(\n configs: UpgradeConfigurations,\n controllerName: string,\n stateRoot: string,\n excludedUnsFields: readonly string[],\n mqttOutput = false,\n): PreparedGroupUpgrade {\n if (\n Object.values(configs)\n .flatMap(Object.values)\n .some((c) => selectedProcessGroupDescriptor(c.packageRoot, c.raw)?.protocolVersion === 2)\n )\n return (mqttOutput ? reviewInstalledConfigurationGroupMqttOutput : reviewInstalledConfigurationGroupUpgrade)(\n configs,\n controllerName,\n stateRoot,\n excludedUnsFields,\n );\n const first = configs.source.publisher;\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 old = authorizeProcessGroupRuntime(context(first));\n const receiver = authorizeProcessGroupRuntime(context(configs.source.receiver));\n if (\n old.role !== \"target\" ||\n receiver.role !== \"receiver\" ||\n old.file !== receiver.file ||\n old.directory !== receiver.directory ||\n !old.journalId ||\n old.journalId !== receiver.journalId\n )\n throw Error(\"Exact authorized source publisher/receiver pair required\");\n const sourcePolicy = read(old.file, true),\n previous = JSON.parse(sourcePolicy.toString());\n const target = configs.target.publisher,\n descriptor = processGroupDescriptor(target.packageRoot);\n if (!descriptor || descriptor.legacy) throw Error(\"Target requires the shared process-group protocol declaration\");\n const targetConfig = normalizeProcessGroupConfiguration(target.raw, descriptor);\n const journal = processGroupJournalSchema.parse(targetConfig.journal);\n const resource = descriptor.manifests.find((m) => m.file === journal.groupManifest);\n if (!resource) throw Error(\"Unregistered target manifest\");\n const manifestBytes = read(path.join(target.packageRoot, resource.file)),\n manifest = processGroupManifestSchema.parse(JSON.parse(manifestBytes.toString()));\n if (manifest.id !== resource.id || journal.directory !== old.directory || journal.journalId !== old.journalId)\n throw Error(\"Journal or manifest identity changed\");\n const members: GroupUpgradeReview[\"members\"] = [];\n const portable = (raw: Record<string, unknown>, role: UpgradeRole) => {\n const copy = mqttOutput ? mqttOutputPortableConfiguration(raw, role) : structuredClone(raw),\n uns = { ...(copy[\"uns\"] as Record<string, unknown>) };\n for (const k of excludedUnsFields) delete uns[k];\n copy[\"uns\"] = uns;\n return hash(copy);\n };\n for (const role of [\"publisher\", \"receiver\"] as const) {\n const a = configs.source[role],\n b = configs.target[role];\n if (\n portable(a.raw, role) !== portable(b.raw, role) ||\n groupChannelsHash(resolvedProcessGroupChannels(a.resolved)) !== groupChannelsHash(resolvedProcessGroupChannels(b.resolved))\n )\n throw Error(\"Configuration, broker identity, paths or units changed\");\n for (const side of [\"source\", \"target\"] as const) {\n const c = configs[side][role],\n d = processGroupDescriptor(c.packageRoot);\n if (!d) throw Error(\"Missing shared runtime contract\");\n const normalized = normalizeProcessGroupConfiguration(c.raw, d),\n j = processGroupJournalSchema.parse(normalized.journal);\n if (\n !normalized.matches ||\n (role === \"receiver\"\n ? normalized.runtimeRole !== \"admission\"\n : normalized.runtimeRole !== undefined && normalized.runtimeRole !== \"publisher\") ||\n j.directory !== old.directory ||\n j.journalId !== old.journalId ||\n sha256(read(path.join(c.packageRoot, j.groupManifest))) !== sha256(manifestBytes)\n )\n throw Error(\"Runtime role, manifest or journal differs\");\n members.push({\n side,\n role,\n processName: String(normalized.uns[\"processName\"]),\n configurationSha256: hash(c.raw),\n artifactSha256: groupArtifactHash(c.packageRoot),\n });\n }\n }\n if (\n members.find((m) => m.role === \"publisher\")?.processName !== manifest.processName ||\n members.find((m) => m.role === \"receiver\")?.processName !== manifest.processName + \"-admission\"\n )\n throw Error(\"Manifest process identities differ\");\n const pkg = JSON.parse(read(path.join(target.packageRoot, \"package.json\")).toString());\n const historical = previous.placements.filter((p: { role: string }) => p.role === \"source\");\n const policy = processGroupAuthorizationSchema.parse({\n schemaVersion: 3,\n kind: \"uns-process-group-runtime-authorization\",\n protocolVersion: 1,\n packageName: pkg.name,\n namespace: descriptor.namespace,\n groupId: manifest.id,\n descriptorSha256: hash(pkg.unsDatahub.processGroupRuntime),\n controllerName,\n packageRoot: target.packageRoot,\n artifactSha256: groupArtifactHash(target.packageRoot),\n groupManifestSha256: sha256(manifestBytes),\n channelsSha256: groupChannelsHash(resolvedProcessGroupChannels(target.resolved)),\n stateRoot,\n directory: old.directory,\n journalId: old.journalId,\n placements: [\n ...historical,\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: hash(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 const expected = processGroupJournalContract(\n processGroupSourceIdentity(resolvedProcessGroupChannels(target.resolved)[1]!),\n journal,\n manifest.profiles,\n );\n const file = path.join(old.directory, \"admission.sqlite\");\n if (fs.realpathSync(file) !== file || !fs.lstatSync(file).isFile()) throw Error(\"Unsafe journal resource\");\n const { DatabaseSync } = createRequire(import.meta.url)(\"node:sqlite\") as typeof import(\"node:sqlite\");\n const db = new DatabaseSync(file, { readOnly: true });\n try {\n db.exec(\"PRAGMA query_only=ON; PRAGMA busy_timeout=1000;\");\n const metadata = Object.fromEntries(\n db\n .prepare(\"SELECT key,value FROM metadata WHERE key IN ('id','contract')\")\n .all()\n .map((r) => [r[\"key\"], r[\"value\"]]),\n );\n if (metadata[\"id\"] !== old.journalId || metadata[\"contract\"] !== expected)\n throw Error(\"Installed target cannot reopen the retained journal contract\");\n } finally {\n db.close();\n }\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: descriptor.namespace,\n groupId: manifest.id,\n policyFile: processGroupAuthorizationFile(context(target)),\n sourcePolicySha256: sha256(sourcePolicy),\n targetPolicySha256: sha256(targetPolicy),\n journalId: old.journalId,\n directory: old.directory,\n journalContractSha256: sha256(expected),\n profiles: manifest.profiles.map(({ processName, mappingSha256, dataGroup }) => ({ processName, mappingSha256, dataGroup })),\n members,\n },\n sourcePolicy,\n targetPolicy,\n };\n}\n\n/** Atomic compare-and-swap. The authenticated host must first prove both old owners exited. */\nexport function replaceReviewedProcessGroupPolicy(file: string, expected: string, bytes: Buffer): void {\n const actual = sha256(read(file, true)),\n next = sha256(bytes);\n if (actual === next) return; // Reconcile an already completed write after a lost reply.\n if (actual !== expected) throw Error(\"Runtime policy changed; review required\");\n const temporary = file + \".upgrade-tmp\";\n const fd = fs.openSync(temporary, \"wx\", 0o600);\n try {\n fs.writeFileSync(fd, bytes);\n fs.fsyncSync(fd);\n } finally {\n fs.closeSync(fd);\n }\n try {\n if (sha256(read(file, true)) !== expected) throw Error(\"Runtime policy changed before replacement\");\n fs.renameSync(temporary, file);\n const directory = fs.openSync(path.dirname(file), \"r\");\n try {\n fs.fsyncSync(directory);\n } finally {\n fs.closeSync(directory);\n }\n } finally {\n if (fs.existsSync(temporary)) fs.unlinkSync(temporary);\n }\n}\n\nexport const processGroupUpgradeRequestSchema = z\n .strictObject({\n protocolVersion: z.literal(1),\n controllerName: groupPlacementSchema.shape.controller,\n action: z.enum([\"preview\", \"prepare\", \"get\", \"execute\", \"rollback\"]),\n input: processGroupUpgradeInputSchema.optional(),\n id: z.string().uuid().optional(),\n expectedFingerprint: z\n .string()\n .regex(/^[a-f0-9]{64}$/)\n .optional(),\n expectedRevision: z.number().int().positive().optional(),\n })\n .superRefine((v, c) => {\n if (\n ([\"preview\", \"prepare\"].includes(v.action) && !v.input) ||\n (v.action !== \"preview\" && !v.id) ||\n ([\"prepare\", \"execute\", \"rollback\"].includes(v.action) && !v.expectedFingerprint) ||\n ([\"execute\", \"rollback\"].includes(v.action) && !v.expectedRevision) ||\n (v.input && v.input.source.publisher.controller !== v.controllerName)\n )\n c.addIssue({ code: \"custom\", message: \"Exact upgrade selector and reviewed revision required\" });\n });\nexport type ProcessGroupUpgradeRequest = z.infer<typeof processGroupUpgradeRequestSchema>;\n/** Shared journal observations; only PID/start identity and fresh capture prove readiness. */\nexport function inspectProcessGroupUpgradeJournal(\n review: Pick<GroupVersionUpgradeReview, \"directory\" | \"journalId\" | \"journalContractSha256\" | \"profiles\">,\n publisherPid?: number,\n receiverPid?: number,\n) {\n const file = path.join(review.directory, \"admission.sqlite\");\n if (fs.realpathSync(file) !== file) throw Error(\"Unsafe retained journal path\");\n const { DatabaseSync } = createRequire(import.meta.url)(\"node:sqlite\") as typeof import(\"node:sqlite\");\n const db = new DatabaseSync(file, { readOnly: true });\n try {\n db.exec(\"PRAGMA query_only=ON; PRAGMA busy_timeout=1000;\");\n const meta = Object.fromEntries(\n db\n .prepare(\"SELECT key,value FROM metadata WHERE key IN ('id','contract','capture','runtime_namespace')\")\n .all()\n .map((r) => [r[\"key\"], r[\"value\"]]),\n );\n if (meta[\"id\"] !== review.journalId || sha256(String(meta[\"contract\"])) !== review.journalContractSha256)\n throw Error(\"Retained journal contract changed\");\n const capture = JSON.parse(String(meta[\"capture\"] ?? \"null\"));\n const identity = (pid: number | undefined, digest: unknown) => {\n if (!pid || !Number.isSafeInteger(pid) || pid <= 0 || typeof digest !== \"string\" || process.platform !== \"linux\") return false;\n try {\n const namespace = sha256(fs.readFileSync(\"/proc/sys/kernel/random/boot_id\", \"utf8\").trim() + \":\" + fs.readlinkSync(\"/proc/self/ns/pid\"));\n const stat = fs.readFileSync(`/proc/${pid}/stat`, \"utf8\"),\n start = stat.slice(stat.lastIndexOf(\")\") + 2).split(\" \")[19];\n return meta[\"runtime_namespace\"] === namespace && !!start && digest === sha256(namespace + \":\" + pid + \":\" + start);\n } catch {\n return false;\n }\n };\n const rows = db.prepare(\"SELECT name,pid,owner,runtime_identity FROM profiles\").all();\n return {\n receiverReady:\n capture?.pid === receiverPid &&\n [\"ready\", \"capacity-blocked\"].includes(capture?.state) &&\n Number.isSafeInteger(capture?.heartbeat) &&\n capture.heartbeat <= Date.now() + 1000 &&\n Date.now() - capture.heartbeat <= 5000 &&\n identity(receiverPid, capture.runtimeIdentity),\n publisherReady:\n rows.length === review.profiles.length &&\n review.profiles.every((p) =>\n rows.some((r) => r[\"name\"] === p.processName && r[\"pid\"] === publisherPid && !!r[\"owner\"] && identity(publisherPid, r[\"runtime_identity\"])),\n ),\n };\n } finally {\n db.close();\n }\n}\n\n/** Bounded, read-only usage for a retained file/configuration input journal. */\nexport function inspectProcessGroupUpgradeUsage(review: Pick<GroupVersionUpgradeReview, \"directory\" | \"journalId\" | \"journalContractSha256\">) {\n const file = path.join(review.directory, \"admission.sqlite\"),\n s = fs.lstatSync(file);\n if (\n fs.realpathSync(file) !== file ||\n !s.isFile() ||\n s.nlink !== 1 ||\n s.uid !== process.getuid?.() ||\n (s.mode & 0o077) !== 0 ||\n s.size > 512 * 1024 * 1024\n )\n throw Error(\"Private retained journal required\");\n const { DatabaseSync } = createRequire(import.meta.url)(\"node:sqlite\") as typeof import(\"node:sqlite\");\n const db = new DatabaseSync(file, { readOnly: true });\n try {\n db.exec(\"PRAGMA query_only=ON; PRAGMA busy_timeout=1000; BEGIN\");\n if (db.prepare(\"PRAGMA quick_check\").get()![\"quick_check\"] !== \"ok\") throw Error(\"Journal integrity unconfirmed\");\n const meta = Object.fromEntries(\n db\n .prepare(\"SELECT key,value FROM metadata WHERE key IN ('id','contract')\")\n .all()\n .map((r) => [r[\"key\"], r[\"value\"]]),\n );\n if (meta[\"id\"] !== review.journalId || sha256(String(meta[\"contract\"])) !== review.journalContractSha256)\n throw Error(\"Retained journal identity changed\");\n const usage = db.prepare(\"SELECT records,bytes FROM usage WHERE id=1\").get();\n const pending = db.prepare(\"SELECT COUNT(*) records,COALESCE(SUM(bytes),0) bytes FROM tasks\").get()!;\n const records = Number(pending[\"records\"]),\n bytes = Number(pending[\"bytes\"]);\n if (\n !usage ||\n usage[\"records\"] !== records ||\n usage[\"bytes\"] !== bytes ||\n !Number.isSafeInteger(records) ||\n records < 0 ||\n records > 100000 ||\n !Number.isSafeInteger(bytes) ||\n bytes < 0 ||\n bytes > 256 * 1024 * 1024\n )\n throw Error(\"Retained journal usage unconfirmed\");\n return { records, bytes };\n } finally {\n db.close();\n }\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type MqttDrainReceipt } from "../runtime/mqtt-drain.js";
|
|
1
2
|
import UnsMqttProxy from "../uns-mqtt/uns-mqtt-proxy.js";
|
|
2
3
|
import type { UnsMqttProxyStopOptions } from "../uns-mqtt/uns-mqtt-proxy.js";
|
|
3
4
|
import { type UnsServiceMetadata, type UnsServiceMetadataInput } from "./service-metadata.js";
|
|
@@ -31,6 +32,8 @@ declare class UnsProxyProcess {
|
|
|
31
32
|
private statusMonitor;
|
|
32
33
|
private serviceMetadataTopic;
|
|
33
34
|
private shutdownPromise;
|
|
35
|
+
private migrationDrainPromise;
|
|
36
|
+
private migrationDrainHandler?;
|
|
34
37
|
static pluginApiVersion: number;
|
|
35
38
|
private static registered;
|
|
36
39
|
private static registeredMethodNames;
|
|
@@ -58,10 +61,11 @@ declare class UnsProxyProcess {
|
|
|
58
61
|
* with live process status to decide whether a service is currently healthy.
|
|
59
62
|
*/
|
|
60
63
|
publishServiceMetadata(metadata: UnsServiceMetadataInput): Promise<UnsServiceMetadata>;
|
|
61
|
-
/**
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
/** Call after application input handlers and shutdown hooks are prepared. */
|
|
65
|
+
enableMigrationDrain(): void;
|
|
66
|
+
/** Works without a Controller too; success means confirmed empty output and closed owners. */
|
|
67
|
+
drainForMigration(timeoutMs?: number): Promise<MqttDrainReceipt>;
|
|
68
|
+
/** Stop process timers, status publication and all owned MQTT proxies. */
|
|
65
69
|
shutdown(options?: UnsMqttProxyStopOptions): Promise<void>;
|
|
66
70
|
private performShutdown;
|
|
67
71
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uns-proxy-process.d.ts","sourceRoot":"","sources":["../../src/uns/uns-proxy-process.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"uns-proxy-process.d.ts","sourceRoot":"","sources":["../../src/uns/uns-proxy-process.ts"],"names":[],"mappings":"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"}
|