@omnitron-dev/omnitron 0.3.5 → 0.4.6
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/README.md +296 -6
- package/bin/{pnpmfile-sdk.mjs → pnpmfile-sdk.js} +13 -0
- package/bin/sdk.d.ts +19 -0
- package/bin/sdk.js +932 -0
- package/dist/BUILD.json +2 -2
- package/dist/cli/omnitron.js +14 -6
- package/dist/cli/omnitron.js.map +1 -1
- package/dist/commands/stack.d.ts +2 -5
- package/dist/commands/stack.d.ts.map +1 -1
- package/dist/commands/stack.js +32 -0
- package/dist/commands/stack.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +1 -0
- package/dist/commands/status.js.map +1 -1
- package/dist/daemon/daemon-client.d.ts +3 -15
- package/dist/daemon/daemon-client.d.ts.map +1 -1
- package/dist/daemon/daemon-client.js +4 -0
- package/dist/daemon/daemon-client.js.map +1 -1
- package/dist/daemon/daemon.d.ts +5 -11
- package/dist/daemon/daemon.d.ts.map +1 -1
- package/dist/daemon/daemon.js +28 -42
- package/dist/daemon/daemon.js.map +1 -1
- package/dist/daemon/daemon.rpc-service.d.ts +3 -15
- package/dist/daemon/daemon.rpc-service.d.ts.map +1 -1
- package/dist/daemon/daemon.rpc-service.js +27 -3
- package/dist/daemon/daemon.rpc-service.js.map +1 -1
- package/dist/daemon/darwin-owner-evidence.js +1 -1
- package/dist/daemon/darwin-owner-evidence.js.map +1 -1
- package/dist/daemon/execution-capabilities.d.ts +1 -1
- package/dist/daemon/execution-capabilities.d.ts.map +1 -1
- package/dist/daemon/execution-capabilities.js +3 -3
- package/dist/daemon/execution-capabilities.js.map +1 -1
- package/dist/daemon/execution-client.d.ts +4 -0
- package/dist/daemon/execution-client.d.ts.map +1 -1
- package/dist/daemon/execution-client.js +28 -6
- package/dist/daemon/execution-client.js.map +1 -1
- package/dist/daemon/execution-host.d.ts +4 -11
- package/dist/daemon/execution-host.d.ts.map +1 -1
- package/dist/daemon/execution-host.js +3 -9
- package/dist/daemon/execution-host.js.map +1 -1
- package/dist/daemon/execution-owner.d.ts.map +1 -1
- package/dist/daemon/execution-owner.js +2 -16
- package/dist/daemon/execution-owner.js.map +1 -1
- package/dist/daemon/execution-shutdown.d.ts +1 -1
- package/dist/daemon/execution-shutdown.d.ts.map +1 -1
- package/dist/daemon/managed-owner-build.d.ts +4 -0
- package/dist/daemon/managed-owner-build.d.ts.map +1 -1
- package/dist/daemon/managed-owner-build.js +14 -2
- package/dist/daemon/managed-owner-build.js.map +1 -1
- package/dist/daemon/managed-runtime.js +1 -1
- package/dist/daemon/managed-runtime.js.map +1 -1
- package/dist/daemon/owner-reconciliation.d.ts.map +1 -1
- package/dist/daemon/owner-reconciliation.js +1 -2
- package/dist/daemon/owner-reconciliation.js.map +1 -1
- package/dist/daemon/system-guardian-cgroup.js +1 -1
- package/dist/daemon/system-guardian-cgroup.js.map +1 -1
- package/dist/infrastructure/existing-containers.d.ts +25 -0
- package/dist/infrastructure/existing-containers.d.ts.map +1 -0
- package/dist/infrastructure/existing-containers.js +183 -0
- package/dist/infrastructure/existing-containers.js.map +1 -0
- package/dist/infrastructure/infrastructure.service.d.ts +14 -1
- package/dist/infrastructure/infrastructure.service.d.ts.map +1 -1
- package/dist/infrastructure/infrastructure.service.js +118 -9
- package/dist/infrastructure/infrastructure.service.js.map +1 -1
- package/dist/infrastructure/stack-infra-manager.d.ts +8 -2
- package/dist/infrastructure/stack-infra-manager.d.ts.map +1 -1
- package/dist/infrastructure/stack-infra-manager.js +46 -9
- package/dist/infrastructure/stack-infra-manager.js.map +1 -1
- package/dist/monitoring/log-journal.d.ts.map +1 -1
- package/dist/monitoring/log-journal.js +1 -2
- package/dist/monitoring/log-journal.js.map +1 -1
- package/dist/operations.d.ts +1 -0
- package/dist/operations.d.ts.map +1 -1
- package/dist/operations.js +1 -0
- package/dist/operations.js.map +1 -1
- package/dist/orchestrator/bootstrap-loader.d.ts +2 -0
- package/dist/orchestrator/bootstrap-loader.d.ts.map +1 -1
- package/dist/orchestrator/bootstrap-loader.js +2 -1
- package/dist/orchestrator/bootstrap-loader.js.map +1 -1
- package/dist/orchestrator/classic-launcher.d.ts.map +1 -1
- package/dist/orchestrator/classic-launcher.js +2 -1
- package/dist/orchestrator/classic-launcher.js.map +1 -1
- package/dist/orchestrator/execution-contract.d.ts +2 -3
- package/dist/orchestrator/execution-contract.d.ts.map +1 -1
- package/dist/orchestrator/file-watcher.d.ts +11 -23
- package/dist/orchestrator/file-watcher.d.ts.map +1 -1
- package/dist/orchestrator/file-watcher.js +57 -42
- package/dist/orchestrator/file-watcher.js.map +1 -1
- package/dist/orchestrator/orchestrator.service.d.ts +10 -5
- package/dist/orchestrator/orchestrator.service.d.ts.map +1 -1
- package/dist/orchestrator/orchestrator.service.js +117 -20
- package/dist/orchestrator/orchestrator.service.js.map +1 -1
- package/dist/project/bootstrap-metadata.d.ts +1 -1
- package/dist/project/bootstrap-metadata.d.ts.map +1 -1
- package/dist/project/bootstrap-metadata.js +3 -2
- package/dist/project/bootstrap-metadata.js.map +1 -1
- package/dist/project/node-stack-stop.d.ts +2 -1
- package/dist/project/node-stack-stop.d.ts.map +1 -1
- package/dist/project/node-stack-stop.js +5 -1
- package/dist/project/node-stack-stop.js.map +1 -1
- package/dist/release/closure-library-path.d.ts +8 -2
- package/dist/release/closure-library-path.d.ts.map +1 -1
- package/dist/release/closure-library-path.js +72 -28
- package/dist/release/closure-library-path.js.map +1 -1
- package/dist/release/local-installation.d.ts +2 -0
- package/dist/release/local-installation.d.ts.map +1 -1
- package/dist/release/local-installation.js +1 -1
- package/dist/release/local-installation.js.map +1 -1
- package/dist/release/portable-archive.d.ts +3 -0
- package/dist/release/portable-archive.d.ts.map +1 -1
- package/dist/release/portable-archive.js +13 -7
- package/dist/release/portable-archive.js.map +1 -1
- package/dist/release/registry-framework.d.ts +25 -0
- package/dist/release/registry-framework.d.ts.map +1 -1
- package/dist/release/registry-framework.js +51 -3
- package/dist/release/registry-framework.js.map +1 -1
- package/dist/release/target-runtime.d.ts +4 -0
- package/dist/release/target-runtime.d.ts.map +1 -1
- package/dist/release/target-runtime.js +9 -0
- package/dist/release/target-runtime.js.map +1 -1
- package/dist/services/host-upgrade.d.ts +2 -0
- package/dist/services/host-upgrade.d.ts.map +1 -1
- package/dist/services/host-upgrade.js +6 -2
- package/dist/services/host-upgrade.js.map +1 -1
- package/dist/services/infrastructure.rpc-service.d.ts +8 -0
- package/dist/services/infrastructure.rpc-service.d.ts.map +1 -1
- package/dist/services/infrastructure.rpc-service.js +90 -10
- package/dist/services/infrastructure.rpc-service.js.map +1 -1
- package/dist/services/kernel-rollout.service.d.ts.map +1 -1
- package/dist/services/kernel-rollout.service.js +1 -2
- package/dist/services/kernel-rollout.service.js.map +1 -1
- package/dist/services/migration-process.d.ts +1 -0
- package/dist/services/migration-process.d.ts.map +1 -1
- package/dist/services/migration-process.js +4 -2
- package/dist/services/migration-process.js.map +1 -1
- package/dist/services/pipeline-definition.d.ts.map +1 -1
- package/dist/services/pipeline-definition.js +32 -6
- package/dist/services/pipeline-definition.js.map +1 -1
- package/dist/services/pipeline.service.d.ts +7 -1
- package/dist/services/pipeline.service.d.ts.map +1 -1
- package/dist/services/pipeline.service.js +106 -13
- package/dist/services/pipeline.service.js.map +1 -1
- package/dist/services/project.rpc-service.d.ts +6 -5
- package/dist/services/project.rpc-service.d.ts.map +1 -1
- package/dist/services/project.rpc-service.js +13 -0
- package/dist/services/project.rpc-service.js.map +1 -1
- package/dist/services/project.service.d.ts +24 -6
- package/dist/services/project.service.d.ts.map +1 -1
- package/dist/services/project.service.js +327 -59
- package/dist/services/project.service.js.map +1 -1
- package/dist/services/remote-deployer.service.d.ts.map +1 -1
- package/dist/services/remote-deployer.service.js +3 -0
- package/dist/services/remote-deployer.service.js.map +1 -1
- package/dist/shared/dto/backend.d.ts +3 -0
- package/dist/shared/dto/backend.d.ts.map +1 -1
- package/dist/shared/dto/backend.js.map +1 -1
- package/dist/shared/dto/pipelines.d.ts +54 -5
- package/dist/shared/dto/pipelines.d.ts.map +1 -1
- package/dist/shared/dto/pipelines.js +0 -7
- package/dist/shared/dto/pipelines.js.map +1 -1
- package/dist/shared/dto/project.d.ts +60 -0
- package/dist/shared/dto/project.d.ts.map +1 -1
- package/dist/shared/dto/services.d.ts +26 -17
- package/dist/shared/dto/services.d.ts.map +1 -1
- package/dist/shared/dto/services.js.map +1 -1
- package/dist/workers/system-worker-manager.d.ts +1 -2
- package/dist/workers/system-worker-manager.d.ts.map +1 -1
- package/dist/workers/system-worker-manager.js +5 -3
- package/dist/workers/system-worker-manager.js.map +1 -1
- package/package.json +17 -16
- package/webapp/dist/BUILD.json +2 -2
- package/webapp/dist/assets/{access-DUjabwNX.js → access-B2gXuoMG.js} +1 -1
- package/webapp/dist/assets/{access-BvKK9dEv.js → access-I0f72P9m.js} +1 -1
- package/webapp/dist/assets/{admin-data-table-BKSDI8sU.js → admin-data-table-CAEL2f-m.js} +1 -1
- package/webapp/dist/assets/{alert-uBG6r9NW.js → alert-BdJ2uaY0.js} +1 -1
- package/webapp/dist/assets/{alerts-CzN6OqX5.js → alerts-DeVkMXWo.js} +1 -1
- package/webapp/dist/assets/{apps-G_Lm6m4F.js → apps-9SuDvyGQ.js} +1 -1
- package/webapp/dist/assets/{audit-CLMpdBzG.js → audit-DT8cY7Ys.js} +1 -1
- package/webapp/dist/assets/backend-status.store-BbBE9cn8.js +4 -0
- package/webapp/dist/assets/{card-DkH32gMY.js → card-DaUEmUI5.js} +1 -1
- package/webapp/dist/assets/{chart-BpGXlCJc.js → chart-BKXP2ter.js} +1 -1
- package/webapp/dist/assets/{client-DFnuv2z3.js → client-CgyTwq9g.js} +1 -1
- package/webapp/dist/assets/{code-editor-DK6Tmmxv.js → code-editor-JVuQ4m-z.js} +1 -1
- package/webapp/dist/assets/{comparison-bars-BtC0dHjF.js → comparison-bars-Ds5Dt1oj.js} +1 -1
- package/webapp/dist/assets/{confirm-dialog-BbGsAz7_.js → confirm-dialog-BayExVbF.js} +1 -1
- package/webapp/dist/assets/{console-keyboard-D3YCA0yU.js → console-keyboard-uSLt92dB.js} +1 -1
- package/webapp/dist/assets/{containers-BsFwprq4.js → containers-DkXTgcrY.js} +1 -1
- package/webapp/dist/assets/{controls-C5W8gHU4.js → controls-CqeGPnaF.js} +1 -1
- package/webapp/dist/assets/{dashboard-BN7rKE5n.js → dashboard-By5yPuOf.js} +1 -1
- package/webapp/dist/assets/{dashboard-builder-BXFxWjXP.js → dashboard-builder-C0hvBwkd.js} +1 -1
- package/webapp/dist/assets/{deploy-progress-CUUwlYtQ.js → deploy-progress-B39cvvCE.js} +1 -1
- package/webapp/dist/assets/{deploy-release-dialog-58lGZDNk.js → deploy-release-dialog-CnzaO_xL.js} +1 -1
- package/webapp/dist/assets/{deployments-DEzjHerg.js → deployments-BXP943hA.js} +1 -1
- package/webapp/dist/assets/{detail-pXPk4O0E.js → detail-B84RgiOb.js} +1 -1
- package/webapp/dist/assets/{detail-Dj3gxaH0.js → detail-CVXDks9-.js} +1 -1
- package/webapp/dist/assets/{detail-CBn9pjJU.js → detail-D9DixtaK.js} +1 -1
- package/webapp/dist/assets/{empty-content-7jOFhG4C.js → empty-content-eyDOuOVp.js} +1 -1
- package/webapp/dist/assets/{error-boundary-CLLI8PWw.js → error-boundary-CQmDr_HS.js} +1 -1
- package/webapp/dist/assets/{event-fields-CiyqrRO8.js → event-fields-C7p2a2HY.js} +1 -1
- package/webapp/dist/assets/{files-DigwXndm.js → files-BsfGT3t6.js} +2 -2
- package/webapp/dist/assets/{icons-OboZgWSt.js → icons-B9Ct8PJ9.js} +1 -1
- package/webapp/dist/assets/index-BEfv96EF.js +1 -0
- package/webapp/dist/assets/{label-B1SF0RTL.js → label-avMhe08g.js} +1 -1
- package/webapp/dist/assets/{log-level-filter-Bcn31D1F.js → log-level-filter-oaUGdbpk.js} +1 -1
- package/webapp/dist/assets/{logs-DrsBbLfb.js → logs-iC1OEDv3.js} +1 -1
- package/webapp/dist/assets/{metric-chart-M-kI-XOt.js → metric-chart-CSa_qv4F.js} +1 -1
- package/webapp/dist/assets/{metrics-D5cDZTEo.js → metrics-CKCmcGKw.js} +1 -1
- package/webapp/dist/assets/{mui-Cd711nOk.js → mui-B3fJdIMc.js} +1 -1
- package/webapp/dist/assets/{mui-CdB_p2lt.js → mui-Bdr6Ks5j.js} +1 -1
- package/webapp/dist/assets/{mui-Db5J-QUd.js → mui-CADnFGCx.js} +1 -1
- package/webapp/dist/assets/{mui-AnEgAVjz.js → mui-CMWGTMXv.js} +1 -1
- package/webapp/dist/assets/{mui-DyT2n1lx.js → mui-CN3dT7bb.js} +1 -1
- package/webapp/dist/assets/{mui-BwsIrivo.js → mui-CPEkFAPo.js} +1 -1
- package/webapp/dist/assets/{mui-dLCwWoMw.js → mui-D3qAWvfZ.js} +1 -1
- package/webapp/dist/assets/{mui-D5m7fDCh.js → mui-D7tBU80e.js} +1 -1
- package/webapp/dist/assets/{mui-59N0OVRa.js → mui-DaJavAoc.js} +1 -1
- package/webapp/dist/assets/{mui-BXSXx9c9.js → mui-SNRRJ_vi.js} +1 -1
- package/webapp/dist/assets/{nodes-CwwZZuu4.js → nodes-DtLyXH0V.js} +1 -1
- package/webapp/dist/assets/{operation-status-Bm1x1wTz.js → operation-status-DHyYOT7G.js} +1 -1
- package/webapp/dist/assets/{page-breadcrumbs-fR7Jmpp4.js → page-breadcrumbs-3R8RZ3nA.js} +1 -1
- package/webapp/dist/assets/pipelines-Do2NAAqK.js +3 -0
- package/webapp/dist/assets/{project.store-DuCgv6Eq.js → project.store-D5IR3fo9.js} +1 -1
- package/webapp/dist/assets/{projects-TBAdpCeX.js → projects-BqlGbzeG.js} +1 -1
- package/webapp/dist/assets/{realtime.store-hfxZD2DU.js → realtime.store-C8D235-B.js} +1 -1
- package/webapp/dist/assets/{release-bits-BJ6i23y0.js → release-bits-IehuBssK.js} +1 -1
- package/webapp/dist/assets/{release-build-panel-BNXkwNE1.js → release-build-panel-C48hP_9w.js} +1 -1
- package/webapp/dist/assets/{release-deployment-state-gN8ZT3aq.js → release-deployment-state-BfmxZP4Y.js} +1 -1
- package/webapp/dist/assets/{releases-CXXKUh-v.js → releases-Cm0RV5Xu.js} +1 -1
- package/webapp/dist/assets/{search-input-C0MHI8vO.js → search-input-SWD1dXxD.js} +1 -1
- package/webapp/dist/assets/settings-DwuEPQGg.js +1 -0
- package/webapp/dist/assets/sign-in-CQ-WeS5A.js +1 -0
- package/webapp/dist/assets/{skeleton-BmWDJWF9.js → skeleton-BnVxAoeX.js} +1 -1
- package/webapp/dist/assets/{snackbar-DSPmjMyi.js → snackbar-CRX6eqRT.js} +1 -1
- package/webapp/dist/assets/{stack-health-status-BIv2C10x.js → stack-health-status-DfErRNb1.js} +1 -1
- package/webapp/dist/assets/{stack-start-notice-D-AH_bzn.js → stack-start-notice-NkYDjR-f.js} +1 -1
- package/webapp/dist/assets/{stacks-WY_ynkON.js → stacks-BOGCfW90.js} +1 -1
- package/webapp/dist/assets/{store-bqUBn2A4.js → store-DtTtbc9H.js} +1 -1
- package/webapp/dist/assets/{system-info-DXMwo6gl.js → system-info-Cw-xywgI.js} +1 -1
- package/webapp/dist/assets/{table-BOWT6Y9d.js → table-D-so_B1p.js} +1 -1
- package/webapp/dist/assets/{table-viewport-Bp4pq-c_.js → table-viewport-DdZ1yAKm.js} +1 -1
- package/webapp/dist/assets/{tabs-k5NPGLnJ.js → tabs-DGqBkXh_.js} +1 -1
- package/webapp/dist/assets/{terminal-QWBau-Us.js → terminal-Bbl0XNeB.js} +1 -1
- package/webapp/dist/assets/{topology-C_Qp1RqW.js → topology-DmrRy7nN.js} +1 -1
- package/webapp/dist/assets/{topology-metadata-dialog-BivuU2y6.js → topology-metadata-dialog-Dpfp4YF1.js} +1 -1
- package/webapp/dist/assets/{traces-By0rdfDC.js → traces-CKHsOabJ.js} +1 -1
- package/webapp/dist/assets/{use-stack-context-8yaHaN8L.js → use-stack-context-BuraYaeY.js} +1 -1
- package/webapp/dist/assets/webapp-D8h_eabt.js +35 -0
- package/webapp/dist/console-version.json +1 -1
- package/webapp/dist/index.html +34 -34
- package/webapp/dist/logo.svg +1 -80
- package/bin/sdk.d.mts +0 -8
- package/bin/sdk.mjs +0 -580
- package/dist/monitoring/process-lifetime.d.ts +0 -11
- package/dist/monitoring/process-lifetime.d.ts.map +0 -1
- package/dist/monitoring/process-lifetime.js +0 -45
- package/dist/monitoring/process-lifetime.js.map +0 -1
- package/dist/shared/host-boot-identity.d.ts +0 -12
- package/dist/shared/host-boot-identity.d.ts.map +0 -1
- package/dist/shared/host-boot-identity.js +0 -89
- package/dist/shared/host-boot-identity.js.map +0 -1
- package/webapp/dist/assets/index-Bo9An3pJ.js +0 -1
- package/webapp/dist/assets/omnitron-logo-koMCbsCv.js +0 -1
- package/webapp/dist/assets/pipelines-BrfTjf6Y.js +0 -3
- package/webapp/dist/assets/settings-B3egRvbI.js +0 -1
- package/webapp/dist/assets/sign-in-9q-Nfy83.js +0 -1
- package/webapp/dist/assets/webapp-BO_WoB_z.js +0 -35
- package/webapp/dist/favicon.png +0 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { promisify } from 'node:util';
|
|
3
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { containerResources, containerSpecHash, inspectStackContainers } from './container-runtime.js';
|
|
6
|
+
import { stackDefinitionFingerprint } from '../project/node-stack-stop.js';
|
|
7
|
+
const execute = promisify(execFile);
|
|
8
|
+
async function inspect(args) {
|
|
9
|
+
try {
|
|
10
|
+
const { stdout } = await execute('docker', args, { timeout: 15_000, maxBuffer: 32 * 1024 * 1024 });
|
|
11
|
+
const answer = JSON.parse(stdout);
|
|
12
|
+
if (!Array.isArray(answer))
|
|
13
|
+
throw Error();
|
|
14
|
+
return answer;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
throw new Error('Native Docker inspection is unavailable');
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export const existingContainerProbes = {
|
|
21
|
+
inventory: inspectStackContainers,
|
|
22
|
+
inspect: names => inspect(['container', 'inspect', ...names]),
|
|
23
|
+
image: async (id) => {
|
|
24
|
+
const images = await inspect(['image', 'inspect', id]);
|
|
25
|
+
if (images.length !== 1 || typeof images[0]?.['Id'] !== 'string')
|
|
26
|
+
throw Error('Native image identity is unavailable');
|
|
27
|
+
return images[0];
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
const sorted = (values) => values.map(value => JSON.stringify(value)).sort();
|
|
31
|
+
const environment = (values) => {
|
|
32
|
+
if (!Array.isArray(values) || values.some(value => typeof value !== 'string' || !value.includes('=')))
|
|
33
|
+
throw Error('Native environment is unavailable');
|
|
34
|
+
const entries = values.map(value => [value.slice(0, value.indexOf('=')), value.slice(value.indexOf('=') + 1)]);
|
|
35
|
+
if (new Set(entries.map(([key]) => key)).size !== entries.length)
|
|
36
|
+
throw Error('Duplicate native environment');
|
|
37
|
+
return Object.fromEntries(entries);
|
|
38
|
+
};
|
|
39
|
+
const duration = (value) => {
|
|
40
|
+
if (value === undefined)
|
|
41
|
+
return undefined;
|
|
42
|
+
const units = { ns: 1, us: 1e3, ms: 1e6, s: 1e9, m: 60e9, h: 3600e9 };
|
|
43
|
+
const parts = [...value.matchAll(/(\d+(?:\.\d+)?)(ns|us|ms|s|m|h)/g)];
|
|
44
|
+
const n = parts.reduce((sum, part) => sum + Number(part[1]) * units[part[2]], 0);
|
|
45
|
+
if (!parts.length || parts.map(part => part[0]).join('') !== value || !Number.isSafeInteger(n))
|
|
46
|
+
throw Error('Health-check duration is not representable');
|
|
47
|
+
return n;
|
|
48
|
+
};
|
|
49
|
+
const host = (value) => value === '' || value === undefined || value === '0.0.0.0' ? '*' : value;
|
|
50
|
+
/** Compare enforced settings, including image defaults. A historical label is not evidence of drift. */
|
|
51
|
+
export function existingContainerMismatch(desired, native, image) {
|
|
52
|
+
const config = native['Config'], runtime = native['HostConfig'];
|
|
53
|
+
if (!config || !runtime || !image['Config'] || image['Id'] !== native['Image'])
|
|
54
|
+
return 'native configuration is incomplete';
|
|
55
|
+
if (!/^sha256:[a-f0-9]{64}$/.test(image['Id'] ?? ''))
|
|
56
|
+
return 'native image identity is unavailable';
|
|
57
|
+
if (!/^[a-f0-9]{64}$/.test(native['Id'] ?? '') || native['Name'] !== '/' + desired.name)
|
|
58
|
+
return 'native container identity differs';
|
|
59
|
+
if (typeof native['State']?.StartedAt !== 'string' || !Number.isFinite(Date.parse(native['State'].StartedAt)))
|
|
60
|
+
return 'native restart generation is unavailable';
|
|
61
|
+
if (native['State']?.Status !== 'running' || native['State']?.Running !== true)
|
|
62
|
+
return 'container is not running';
|
|
63
|
+
if (native['State']?.Health && native['State'].Health.Status !== 'healthy')
|
|
64
|
+
return 'native health is not ready';
|
|
65
|
+
if ((desired.healthCheck || (image['Config'].Healthcheck && image['Config'].Healthcheck.Test?.[0] !== 'NONE')) && native['State']?.Health?.Status !== 'healthy')
|
|
66
|
+
return 'native health is not ready';
|
|
67
|
+
if (config['Image'] !== desired.image)
|
|
68
|
+
return 'image reference differs';
|
|
69
|
+
if ((config.User ?? '') !== (image['Config'].User ?? '') || (config.WorkingDir ?? '') !== (image['Config'].WorkingDir ?? '') ||
|
|
70
|
+
(config.StopSignal ?? '') !== (image['Config'].StopSignal ?? '') || config.Tty === true || config.OpenStdin === true ||
|
|
71
|
+
runtime.Privileged === true || runtime.ReadonlyRootfs === true || runtime.PublishAllPorts === true || runtime.AutoRemove === true ||
|
|
72
|
+
[runtime.CapAdd, runtime.CapDrop, runtime.Devices, runtime.DeviceRequests].some(value => value?.length) ||
|
|
73
|
+
[runtime.PidMode, runtime.UTSMode, runtime.UsernsMode].some(value => value && value !== 'private'))
|
|
74
|
+
return 'native runtime options differ';
|
|
75
|
+
if (Object.entries(desired.labels).some(([key, value]) => config.Labels?.[key] !== value))
|
|
76
|
+
return 'stack ownership differs';
|
|
77
|
+
// Native mount paths cannot prove which bytes a daemon loaded at creation.
|
|
78
|
+
// Existing intent is usable only when its complete current spec reproduces the receipt.
|
|
79
|
+
if (desired.configDigest && config.Labels?.['omnitron.spec-hash'] !== containerSpecHash(desired))
|
|
80
|
+
return 'mounted configuration content cannot be proved from this spec receipt';
|
|
81
|
+
if (!isDeepStrictEqual(environment(config.Env), { ...environment(image['Config'].Env ?? []), ...desired.environment }))
|
|
82
|
+
return 'environment differs';
|
|
83
|
+
const entrypoint = desired.entrypoint ? [desired.entrypoint[0]] : image['Config'].Entrypoint ?? null;
|
|
84
|
+
const command = desired.entrypoint && desired.entrypoint.length > 1
|
|
85
|
+
? [...desired.entrypoint.slice(1), ...(desired.command ?? [])] : desired.command ?? image['Config'].Cmd ?? null;
|
|
86
|
+
if (!isDeepStrictEqual(config.Entrypoint ?? null, entrypoint) || !isDeepStrictEqual(config.Cmd ?? null, command))
|
|
87
|
+
return 'command or entrypoint differs';
|
|
88
|
+
const wantedPorts = sorted(desired.ports.map(p => [p.container + '/tcp', host(p.bindHost), String(p.host)]));
|
|
89
|
+
const actualPorts = (bindings) => sorted(Object.entries(bindings ?? {}).flatMap(([port, portBindings]) => portBindings?.map(binding => [port, host(binding['HostIp']), binding['HostPort']]) ?? []));
|
|
90
|
+
if (!isDeepStrictEqual(wantedPorts, actualPorts(runtime.PortBindings)) ||
|
|
91
|
+
!isDeepStrictEqual(wantedPorts, actualPorts(native['NetworkSettings']?.Ports)))
|
|
92
|
+
return 'published ports differ';
|
|
93
|
+
if (!Array.isArray(native['Mounts']))
|
|
94
|
+
return 'native mounts are unavailable';
|
|
95
|
+
const mounts = native['Mounts'];
|
|
96
|
+
if (mounts.length !== desired.volumes.length || desired.volumes.some(wanted => {
|
|
97
|
+
const actual = mounts.find(mount => mount['Destination'] === wanted.target);
|
|
98
|
+
const bind = path.isAbsolute(wanted.source) || wanted.source.startsWith('.');
|
|
99
|
+
return !actual || actual['RW'] !== !wanted.readonly || (bind
|
|
100
|
+
? actual['Type'] !== 'bind' || actual['Source'] !== path.resolve(wanted.source)
|
|
101
|
+
: actual['Type'] !== 'volume' || actual['Name'] !== wanted.source);
|
|
102
|
+
}))
|
|
103
|
+
return 'volume identity or mount permissions differ';
|
|
104
|
+
const network = desired.network ?? 'bridge';
|
|
105
|
+
if (runtime.NetworkMode !== network || !/^[a-f0-9]{64}$/.test(native['NetworkSettings']?.Networks?.[network]?.NetworkID ?? '') ||
|
|
106
|
+
Object.keys(native['NetworkSettings'].Networks).length !== 1)
|
|
107
|
+
return 'network attachment differs';
|
|
108
|
+
const [restart, attempts] = (desired.restart || 'no').split(':');
|
|
109
|
+
if ((runtime.RestartPolicy?.['Name'] || 'no') !== restart || runtime.RestartPolicy?.MaximumRetryCount !== Number(attempts ?? 0))
|
|
110
|
+
return 'restart policy differs';
|
|
111
|
+
if (!isDeepStrictEqual([...(runtime.ExtraHosts ?? [])].sort(), [...(desired.extraHosts ?? [])].sort()))
|
|
112
|
+
return 'extra host bindings differ';
|
|
113
|
+
const resources = containerResources(desired);
|
|
114
|
+
const fields = { memoryBytes: 'Memory', memoryReservationBytes: 'MemoryReservation', nanoCpus: 'NanoCpus', shmBytes: 'ShmSize' };
|
|
115
|
+
for (const [key, value] of Object.entries({ memoryBytes: 0, memoryReservationBytes: 0, nanoCpus: 0, ...resources })) {
|
|
116
|
+
if (key === 'shmBytes' && value === 0) {
|
|
117
|
+
if (!Number.isSafeInteger(runtime.ShmSize) || runtime.ShmSize <= 0)
|
|
118
|
+
return 'shared memory limit is unavailable';
|
|
119
|
+
}
|
|
120
|
+
else if (runtime[fields[key]] !== value)
|
|
121
|
+
return 'resource limits differ';
|
|
122
|
+
}
|
|
123
|
+
if (runtime.CpuQuota > 0 || runtime.CpuPeriod > 0)
|
|
124
|
+
return 'CPU quota differs';
|
|
125
|
+
const health = config.Healthcheck ?? null;
|
|
126
|
+
if (desired.healthCheck) {
|
|
127
|
+
const declared = desired.healthCheck;
|
|
128
|
+
const cmd = declared.test.length === 2 && declared.test[0] === 'CMD-SHELL' ? declared.test[1]
|
|
129
|
+
: declared.test.filter(part => part !== 'CMD-SHELL' && part !== 'CMD').join(' ');
|
|
130
|
+
if (!health || !isDeepStrictEqual(health.Test, ['CMD-SHELL', cmd]) ||
|
|
131
|
+
Object.entries({ Interval: duration(declared.interval), Timeout: duration(declared.timeout),
|
|
132
|
+
StartPeriod: duration(declared.startPeriod), Retries: declared.retries }).some(([key, value]) => (health[key] ?? 0) !== (value ?? image['Config'].Healthcheck?.[key] ?? 0)))
|
|
133
|
+
return 'health-check specification differs';
|
|
134
|
+
}
|
|
135
|
+
else if (!isDeepStrictEqual(health, image['Config'].Healthcheck ?? null))
|
|
136
|
+
return 'health-check specification differs';
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
function nativeFingerprint(native) {
|
|
140
|
+
// Health probe timestamps and counters are observations, not resource identity.
|
|
141
|
+
const { Labels: labels, ...config } = native['Config'];
|
|
142
|
+
const { ["omnitron.spec-hash"]: _hash, ...ownership } = labels ?? {};
|
|
143
|
+
return stackDefinitionFingerprint([native['Id'], native['Image'], native['State'].StartedAt,
|
|
144
|
+
{ ...config, Labels: ownership }, native['HostConfig'], native['Mounts'], native['NetworkSettings']]);
|
|
145
|
+
}
|
|
146
|
+
/** Pure observation plus native readers. No container, file, credential or setup writes. */
|
|
147
|
+
export async function reviewExistingContainers(desired, probes = existingContainerProbes, scope) {
|
|
148
|
+
const review = { protocol: 1, mode: 'preserve', digest: null, checks: [], containers: [] };
|
|
149
|
+
try {
|
|
150
|
+
if (new Set(desired.map(c => c.name)).size !== desired.length)
|
|
151
|
+
throw Error('Duplicate infrastructure declaration');
|
|
152
|
+
const project = scope?.project ?? desired[0]?.labels['omnitron.project'], stack = scope?.stack ?? desired[0]?.labels['omnitron.stack'];
|
|
153
|
+
if (desired.length && (!project || !stack || desired.some(container => container.labels['omnitron.project'] !== project || container.labels['omnitron.stack'] !== stack)))
|
|
154
|
+
throw Error('Ambiguous infrastructure ownership');
|
|
155
|
+
const inventory = project && stack ? await probes.inventory({ project, stack }) : [];
|
|
156
|
+
if (project && stack)
|
|
157
|
+
review.scope = { project, stack };
|
|
158
|
+
if (!isDeepStrictEqual(inventory.map(item => item.name).sort(), desired.map(item => item.name).sort())) {
|
|
159
|
+
review.checks.push({ code: 'infrastructure.preservation-footprint', resource: 'Infrastructure', state: 'blocked', message: 'Native ownership footprint differs from the desired services; reconcile separately.' });
|
|
160
|
+
return review;
|
|
161
|
+
}
|
|
162
|
+
const observed = desired.length ? await probes.inspect(desired.map(c => c.name)) : [];
|
|
163
|
+
for (const declaration of [...desired].sort((a, b) => a.name.localeCompare(b.name))) {
|
|
164
|
+
const candidates = observed.filter(item => item['Name'] === '/' + declaration.name);
|
|
165
|
+
const native = candidates.length === 1 ? candidates[0] : undefined;
|
|
166
|
+
const mismatch = !native || !inventory.some(item => item.name === declaration.name && item.id === native['Id']) ? 'native container is missing, replaced or ambiguous' :
|
|
167
|
+
existingContainerMismatch(declaration, native, await probes.image(declaration.image));
|
|
168
|
+
review.checks.push({ code: mismatch ? 'infrastructure.preservation-blocked' : 'infrastructure.preserved', resource: declaration.name,
|
|
169
|
+
state: mismatch?.includes('cannot be proved') ? 'unknown' : mismatch ? 'blocked' : 'pass', message: mismatch ? `Cannot preserve: ${mismatch}.` : 'Existing native identity and specification verified; no infrastructure changes permitted.' });
|
|
170
|
+
if (!mismatch)
|
|
171
|
+
review.containers.push({ name: declaration.name, id: native['Id'], fingerprint: nativeFingerprint(native) });
|
|
172
|
+
}
|
|
173
|
+
if (review.checks.every(check => check.state === 'pass'))
|
|
174
|
+
review.digest = stackDefinitionFingerprint([
|
|
175
|
+
'omnitron/infrastructure.preserve/v1', review.scope ?? null, [...desired].sort((a, b) => a.name.localeCompare(b.name)), review.containers,
|
|
176
|
+
]);
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
review.checks.push({ code: 'infrastructure.preservation-unknown', resource: 'Infrastructure', state: 'unknown', message: 'Complete native infrastructure identity and specification could not be verified.' });
|
|
180
|
+
}
|
|
181
|
+
return review;
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=existing-containers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"existing-containers.js","sourceRoot":"","sources":["../../src/infrastructure/existing-containers.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
import type { ILogger } from '@omnitron-dev/titan/module/logger';
|
|
19
19
|
import type { InfrastructureConfig, InfrastructureState, ResolvedContainer } from './types.js';
|
|
20
20
|
import { type UnhealthyEvidence } from './health-recovery.js';
|
|
21
|
+
import type { ExistingInfrastructureReview } from '../shared/dto/project.js';
|
|
21
22
|
/**
|
|
22
23
|
* Restart-circuit-breaker backoff schedule: the delay (ms) to wait before the
|
|
23
24
|
* next restart attempt after `failures` consecutive failed (re)creates.
|
|
@@ -77,6 +78,8 @@ export declare function decideControlPlaneDatabase(input: {
|
|
|
77
78
|
reconcileName: string;
|
|
78
79
|
};
|
|
79
80
|
export interface InfrastructureHandoffState {
|
|
81
|
+
preservation?: ExistingInfrastructureReview;
|
|
82
|
+
preservationPending?: true;
|
|
80
83
|
/** Native evidence is separate from desired services and their failure history. */
|
|
81
84
|
nativeState?: {
|
|
82
85
|
protocol: 1;
|
|
@@ -123,6 +126,8 @@ export declare class InfrastructureService {
|
|
|
123
126
|
* Postgres never.
|
|
124
127
|
*/
|
|
125
128
|
private readonly needsControlPlaneDatabase;
|
|
129
|
+
private preservation;
|
|
130
|
+
private preservationPending;
|
|
126
131
|
private readonly retiredStacks;
|
|
127
132
|
private desiredContainers;
|
|
128
133
|
/** What the most recent reconcile did to each service. */
|
|
@@ -192,7 +197,7 @@ export declare class InfrastructureService {
|
|
|
192
197
|
* Ensures Docker is available, pulls images, creates/starts containers,
|
|
193
198
|
* runs post-provisioning setup, and starts the health monitor.
|
|
194
199
|
*/
|
|
195
|
-
provision(definition?: InfrastructureService): Promise<InfrastructureState>;
|
|
200
|
+
provision(definition?: InfrastructureService, reconcile?: boolean): Promise<InfrastructureState>;
|
|
196
201
|
/** Resolve a plan without installing another monitor or changing the current definition. */
|
|
197
202
|
resolveDefinition(config: InfrastructureConfig, services: Record<string, import('./types.js').IServiceRequirement>, overrides?: Record<string, import('./types.js').IServiceOverride>): InfrastructureService;
|
|
198
203
|
private provisionDefinition;
|
|
@@ -206,10 +211,18 @@ export declare class InfrastructureService {
|
|
|
206
211
|
*/
|
|
207
212
|
/** Internal immutable plan. Never expose environment or command values through RPC. */
|
|
208
213
|
getDesiredContainers(): import('./types.js').ResolvedContainer[];
|
|
214
|
+
/** Adopt a reviewed native generation with no provisioning, setup or mutation monitor. */
|
|
215
|
+
holdForPreservation(): Promise<void>;
|
|
216
|
+
/** Adopt a reviewed native generation with no provisioning, setup or mutation monitor. */
|
|
217
|
+
preserveExisting(review: string, candidate?: InfrastructureService, scope?: {
|
|
218
|
+
project: string;
|
|
219
|
+
stack: string;
|
|
220
|
+
}): Promise<ExistingInfrastructureReview>;
|
|
209
221
|
getDesiredServices(): ReadonlyArray<{
|
|
210
222
|
name: string;
|
|
211
223
|
image?: string | undefined;
|
|
212
224
|
}>;
|
|
225
|
+
verifyPreservation(): Promise<ExistingInfrastructureReview>;
|
|
213
226
|
/** Identify a single stack handed off by a controller predating the scoped registry. */
|
|
214
227
|
representsStack(scope: {
|
|
215
228
|
project: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"infrastructure.service.d.ts","sourceRoot":"","sources":["../../src/infrastructure/infrastructure.service.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mCAAmC,CAAC;AAIjE,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EAEnB,iBAAiB,EAElB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"infrastructure.service.d.ts","sourceRoot":"","sources":["../../src/infrastructure/infrastructure.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,6 +17,7 @@ import { observeUnhealthy } from './health-recovery.js';
|
|
|
17
17
|
import { normalizeInfraConfig } from './config-normalizer.js';
|
|
18
18
|
import { createDefaultRegistry } from './presets/index.js';
|
|
19
19
|
import { PhantomEndpointJanitor } from './phantom-endpoint-janitor.js';
|
|
20
|
+
import { reviewExistingContainers } from './existing-containers.js';
|
|
20
21
|
import { LOCAL_INFRA_HOST } from '../shared/local-infra-host.js';
|
|
21
22
|
import { isDockerAvailable, getContainerState, createContainer, startContainer, removeContainer, ensureImage, waitForHealthy, createVolume, containerSpecHash, containerResources, containerResourcesMatch, } from './container-runtime.js';
|
|
22
23
|
import { summariseProvisioning, describeProvisioning, retainProvisioningObservation } from './provisioning-outcome.js';
|
|
@@ -91,6 +92,8 @@ export class InfrastructureService {
|
|
|
91
92
|
presetRegistry;
|
|
92
93
|
serviceOverrides;
|
|
93
94
|
needsControlPlaneDatabase;
|
|
95
|
+
preservation;
|
|
96
|
+
preservationPending = false;
|
|
94
97
|
retiredStacks = new Set();
|
|
95
98
|
desiredContainers = [];
|
|
96
99
|
/** What the most recent reconcile did to each service. */
|
|
@@ -193,16 +196,22 @@ export class InfrastructureService {
|
|
|
193
196
|
* Ensures Docker is available, pulls images, creates/starts containers,
|
|
194
197
|
* runs post-provisioning setup, and starts the health monitor.
|
|
195
198
|
*/
|
|
196
|
-
async provision(definition) {
|
|
199
|
+
async provision(definition, reconcile = false) {
|
|
197
200
|
if (this.monitoringRelinquished)
|
|
198
201
|
throw new Error('Infrastructure monitoring ownership has been relinquished');
|
|
199
202
|
if (this.ownershipFrozen)
|
|
200
203
|
throw new Error('Infrastructure ownership is frozen');
|
|
204
|
+
if ((this.preservation || this.preservationPending) && !reconcile)
|
|
205
|
+
throw new Error('Infrastructure is preserved; an explicit reconcile start is required');
|
|
201
206
|
if (this.provisioning) {
|
|
202
207
|
if (definition)
|
|
203
208
|
throw new Error('Infrastructure provisioning is already in progress; retry the new declaration after it finishes');
|
|
204
209
|
return this.provisioning;
|
|
205
210
|
}
|
|
211
|
+
if (reconcile) {
|
|
212
|
+
this.preservation = undefined;
|
|
213
|
+
this.preservationPending = false;
|
|
214
|
+
}
|
|
206
215
|
const task = this.provisionDefinition(definition);
|
|
207
216
|
this.provisioning = task;
|
|
208
217
|
try {
|
|
@@ -400,9 +409,64 @@ export class InfrastructureService {
|
|
|
400
409
|
getDesiredContainers() {
|
|
401
410
|
return structuredClone(this.desiredContainers);
|
|
402
411
|
}
|
|
412
|
+
/** Adopt a reviewed native generation with no provisioning, setup or mutation monitor. */
|
|
413
|
+
async holdForPreservation() {
|
|
414
|
+
if (this.ownershipFrozen)
|
|
415
|
+
throw new Error('Infrastructure ownership is frozen');
|
|
416
|
+
this.preservationPending = true;
|
|
417
|
+
this.stopHealthMonitor();
|
|
418
|
+
await Promise.allSettled([...this.activeSweeps, ...this.reconcileTasks.values(), ...(this.provisioning ? [this.provisioning] : [])]);
|
|
419
|
+
await this.phantomJanitor?.drain();
|
|
420
|
+
this.phantomJanitor = null;
|
|
421
|
+
this.janitorNetworks = [];
|
|
422
|
+
}
|
|
423
|
+
/** Adopt a reviewed native generation with no provisioning, setup or mutation monitor. */
|
|
424
|
+
async preserveExisting(review, candidate = this, scope) {
|
|
425
|
+
if (!/^[a-f0-9]{64}$/.test(review) || this.ownershipFrozen || this.provisioning)
|
|
426
|
+
throw new Error('Infrastructure preservation requires a current review and idle ownership');
|
|
427
|
+
this.preservationPending = true;
|
|
428
|
+
this.definitionChanging = true;
|
|
429
|
+
try {
|
|
430
|
+
this.stopHealthMonitor();
|
|
431
|
+
await Promise.allSettled([...this.activeSweeps, ...this.reconcileTasks.values()]);
|
|
432
|
+
await this.phantomJanitor?.drain();
|
|
433
|
+
this.phantomJanitor = null;
|
|
434
|
+
this.janitorNetworks = [];
|
|
435
|
+
const observed = await reviewExistingContainers(candidate.desiredContainers, undefined, scope ?? this.preservation?.scope);
|
|
436
|
+
if (!observed.digest || observed.digest !== review)
|
|
437
|
+
throw new Error('Native infrastructure changed after review; nothing was provisioned');
|
|
438
|
+
const states = await Promise.all(observed.containers.map(async (expected) => {
|
|
439
|
+
const state = await getContainerState(expected.name, { orThrow: true, fullId: true });
|
|
440
|
+
if (!state || state.containerId !== expected.id || state.status !== 'running')
|
|
441
|
+
throw new Error('Native infrastructure identity changed during preservation');
|
|
442
|
+
return state;
|
|
443
|
+
}));
|
|
444
|
+
this.replaceDefinitionFrom(candidate);
|
|
445
|
+
this.preservation = observed;
|
|
446
|
+
this.preservationPending = false;
|
|
447
|
+
for (const key of Object.keys(this.state.services))
|
|
448
|
+
delete this.state.services[key];
|
|
449
|
+
for (const state of states)
|
|
450
|
+
this.state.services[state.name] = state;
|
|
451
|
+
this.state.ready = observed.containers.length === 0 || summariseProvisioning(this.desiredContainers, this.state.services).ready;
|
|
452
|
+
this.startHealthMonitor();
|
|
453
|
+
return structuredClone(observed);
|
|
454
|
+
}
|
|
455
|
+
finally {
|
|
456
|
+
this.definitionChanging = false;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
403
459
|
getDesiredServices() {
|
|
404
460
|
return this.desiredContainers.map((c) => ({ name: c.name, image: c.image }));
|
|
405
461
|
}
|
|
462
|
+
async verifyPreservation() {
|
|
463
|
+
if (!this.preservation?.digest)
|
|
464
|
+
throw new Error('Infrastructure has no preserved native binding');
|
|
465
|
+
const observed = await reviewExistingContainers(this.desiredContainers, undefined, this.preservation.scope);
|
|
466
|
+
if (observed.digest !== this.preservation.digest)
|
|
467
|
+
throw new Error('Preserved native infrastructure changed');
|
|
468
|
+
return observed;
|
|
469
|
+
}
|
|
406
470
|
/** Identify a single stack handed off by a controller predating the scoped registry. */
|
|
407
471
|
representsStack(scope) {
|
|
408
472
|
const key = `${scope.project}/${scope.stack}`;
|
|
@@ -463,7 +527,7 @@ export class InfrastructureService {
|
|
|
463
527
|
if (settled.some(result => result.status === 'rejected'))
|
|
464
528
|
throw new Error('Infrastructure reconciliation failed while draining');
|
|
465
529
|
await this.phantomJanitor?.drain();
|
|
466
|
-
const observations = await InfrastructureService.validateHandoffContainers(this.desiredContainers, this.needsControlPlaneDatabase && !this.usingGlobalOmnitronPg ? this.omnitronPgContainer : undefined, this.state, { protocol: 1 });
|
|
530
|
+
const observations = this.preservation ? (await this.verifyPreservation()).containers.map(c => ({ name: c.name, containerId: c.id })) : await InfrastructureService.validateHandoffContainers(this.desiredContainers, this.needsControlPlaneDatabase && !this.usingGlobalOmnitronPg ? this.omnitronPgContainer : undefined, this.state, { protocol: 1 });
|
|
467
531
|
this.dispose();
|
|
468
532
|
const snapshot = this.ownershipSnapshot(this.handoffMonitoring);
|
|
469
533
|
snapshot.nativeState = { protocol: 1, observations };
|
|
@@ -483,6 +547,8 @@ export class InfrastructureService {
|
|
|
483
547
|
ownershipSnapshot(monitoring) {
|
|
484
548
|
return structuredClone({
|
|
485
549
|
nativeState: { protocol: 1 },
|
|
550
|
+
...(this.preservation && { preservation: this.preservation }),
|
|
551
|
+
...(this.preservationPending && { preservationPending: true }),
|
|
486
552
|
retiredStacks: [...this.retiredStacks],
|
|
487
553
|
config: this.config, containers: this.desiredContainers, normalizedServices: this.normalizedServices,
|
|
488
554
|
...(this.serviceOverrides && { serviceOverrides: this.serviceOverrides }),
|
|
@@ -498,9 +564,9 @@ export class InfrastructureService {
|
|
|
498
564
|
if (this.monitoringRelinquished)
|
|
499
565
|
return;
|
|
500
566
|
this.ownershipFrozen = false;
|
|
501
|
-
if (this.handoffMonitoring)
|
|
567
|
+
if (this.handoffMonitoring && !this.preservationPending)
|
|
502
568
|
this.startHealthMonitor();
|
|
503
|
-
if (!this.phantomJanitor && this.janitorNetworks.length) {
|
|
569
|
+
if (!this.preservation && !this.preservationPending && !this.phantomJanitor && this.janitorNetworks.length) {
|
|
504
570
|
this.phantomJanitor = new PhantomEndpointJanitor({ networks: this.janitorNetworks, intervalMs: 60_000, logger: this.logger });
|
|
505
571
|
this.phantomJanitor.start();
|
|
506
572
|
}
|
|
@@ -508,7 +574,13 @@ export class InfrastructureService {
|
|
|
508
574
|
}
|
|
509
575
|
/** Read and validate existing containers. Never provision, start or recreate during adoption. */
|
|
510
576
|
static async adoptHandoff(logger, snapshot) {
|
|
511
|
-
|
|
577
|
+
if (snapshot.preservation) {
|
|
578
|
+
const observed = await reviewExistingContainers(snapshot.containers, undefined, snapshot.preservation.scope);
|
|
579
|
+
if (!observed.digest || observed.digest !== snapshot.preservation.digest)
|
|
580
|
+
throw new Error('Preserved infrastructure changed during handoff');
|
|
581
|
+
}
|
|
582
|
+
else
|
|
583
|
+
await InfrastructureService.validateHandoffContainers(snapshot.containers, snapshot.needsControlPlaneDatabase && !snapshot.usingGlobalOmnitronPg ? snapshot.controlPlaneContainer : undefined, snapshot.state, snapshot.nativeState);
|
|
512
584
|
const service = new InfrastructureService(logger, snapshot.config, snapshot.normalizedServices, undefined, snapshot.serviceOverrides, snapshot.needsControlPlaneDatabase);
|
|
513
585
|
service.desiredContainers = structuredClone(snapshot.containers);
|
|
514
586
|
for (const key of snapshot.retiredStacks ?? [])
|
|
@@ -520,6 +592,8 @@ export class InfrastructureService {
|
|
|
520
592
|
Object.assign(service.state, structuredClone(snapshot.state));
|
|
521
593
|
service.usingGlobalOmnitronPg = snapshot.usingGlobalOmnitronPg;
|
|
522
594
|
service.handoffMonitoring = snapshot.monitoring;
|
|
595
|
+
service.preservation = snapshot.preservation;
|
|
596
|
+
service.preservationPending = snapshot.preservationPending === true;
|
|
523
597
|
service.ownershipFrozen = true;
|
|
524
598
|
return service;
|
|
525
599
|
}
|
|
@@ -875,6 +949,8 @@ export class InfrastructureService {
|
|
|
875
949
|
}
|
|
876
950
|
}
|
|
877
951
|
async reconcileServiceLocked(desired) {
|
|
952
|
+
if (this.preservation || this.preservationPending)
|
|
953
|
+
throw new Error('Preserved infrastructure cannot be reconciled');
|
|
878
954
|
const actual = await getContainerState(desired.name, { orThrow: true, fullId: true });
|
|
879
955
|
if (this.ownershipFrozen || this.definitionChanging || this.retiredStacks.has(this.containerScope(desired)))
|
|
880
956
|
return;
|
|
@@ -918,6 +994,8 @@ export class InfrastructureService {
|
|
|
918
994
|
}
|
|
919
995
|
}
|
|
920
996
|
async recoverUnhealthyLocked(desired, actual, previous) {
|
|
997
|
+
if (this.preservation || this.preservationPending)
|
|
998
|
+
throw new Error('Preserved infrastructure cannot be restarted');
|
|
921
999
|
// Recheck immediately before destruction: queued polls, recovery and
|
|
922
1000
|
// replacement while inspecting must not authorize a stale decision.
|
|
923
1001
|
const confirmed = await getContainerState(desired.name, { orThrow: true, fullId: true });
|
|
@@ -1212,7 +1290,7 @@ export class InfrastructureService {
|
|
|
1212
1290
|
// Private — Health Monitor (Self-Healing)
|
|
1213
1291
|
// ===========================================================================
|
|
1214
1292
|
startHealthMonitor() {
|
|
1215
|
-
if (this.monitoringRelinquished || this.ownershipFrozen || this.healthTimer)
|
|
1293
|
+
if (this.preservationPending || this.monitoringRelinquished || this.ownershipFrozen || this.healthTimer)
|
|
1216
1294
|
return;
|
|
1217
1295
|
this.healthTimer = setInterval(() => {
|
|
1218
1296
|
this.healthSweep().catch((err) => {
|
|
@@ -1242,7 +1320,7 @@ export class InfrastructureService {
|
|
|
1242
1320
|
return this.needsControlPlaneDatabase && !this.usingGlobalOmnitronPg ? [this.omnitronPgContainer] : [];
|
|
1243
1321
|
}
|
|
1244
1322
|
async healthSweep() {
|
|
1245
|
-
if (this.ownershipFrozen || this.provisioning || this.activeSweeps.size)
|
|
1323
|
+
if (this.preservationPending || this.ownershipFrozen || this.provisioning || this.activeSweeps.size)
|
|
1246
1324
|
return;
|
|
1247
1325
|
const task = this.healthSweepOwned();
|
|
1248
1326
|
this.activeSweeps.add(task);
|
|
@@ -1254,12 +1332,31 @@ export class InfrastructureService {
|
|
|
1254
1332
|
}
|
|
1255
1333
|
}
|
|
1256
1334
|
async healthSweepOwned() {
|
|
1335
|
+
if (this.preservation) {
|
|
1336
|
+
try {
|
|
1337
|
+
const review = await reviewExistingContainers(this.desiredContainers, undefined, this.preservation.scope);
|
|
1338
|
+
const states = await Promise.all(this.desiredContainers.map(container => getContainerState(container.name, { orThrow: true, fullId: true })));
|
|
1339
|
+
if (this.ownershipFrozen || this.definitionChanging)
|
|
1340
|
+
return;
|
|
1341
|
+
for (const key of Object.keys(this.state.services))
|
|
1342
|
+
delete this.state.services[key];
|
|
1343
|
+
for (const state of states)
|
|
1344
|
+
if (state)
|
|
1345
|
+
this.state.services[state.name] = state;
|
|
1346
|
+
this.state.ready = review.digest !== null && review.digest === this.preservation.digest;
|
|
1347
|
+
}
|
|
1348
|
+
catch {
|
|
1349
|
+
this.state.ready = false;
|
|
1350
|
+
this.logger.warn('Preserved native infrastructure observation is unavailable; repair authority remains disabled');
|
|
1351
|
+
}
|
|
1352
|
+
return; // Observation never promotes itself to repair authority.
|
|
1353
|
+
}
|
|
1257
1354
|
// The control-plane database alongside the app containers, where this
|
|
1258
1355
|
// service keeps one.
|
|
1259
1356
|
const allContainers = [...this.controlPlaneContainers(), ...this.desiredContainers];
|
|
1260
1357
|
for (const desired of allContainers) {
|
|
1261
1358
|
const actual = await getContainerState(desired.name, { orThrow: true, fullId: true });
|
|
1262
|
-
if (this.ownershipFrozen || this.definitionChanging)
|
|
1359
|
+
if (this.ownershipFrozen || this.definitionChanging || this.preservationPending || this.preservation)
|
|
1263
1360
|
return;
|
|
1264
1361
|
if (this.retiredStacks.has(this.containerScope(desired)))
|
|
1265
1362
|
continue;
|
|
@@ -1354,9 +1451,21 @@ __decorate([
|
|
|
1354
1451
|
__decorate([
|
|
1355
1452
|
RecoveryMutation(),
|
|
1356
1453
|
__metadata("design:type", Function),
|
|
1357
|
-
__metadata("design:paramtypes", [InfrastructureService]),
|
|
1454
|
+
__metadata("design:paramtypes", [InfrastructureService, Object]),
|
|
1358
1455
|
__metadata("design:returntype", Promise)
|
|
1359
1456
|
], InfrastructureService.prototype, "provision", null);
|
|
1457
|
+
__decorate([
|
|
1458
|
+
RecoveryMutation(),
|
|
1459
|
+
__metadata("design:type", Function),
|
|
1460
|
+
__metadata("design:paramtypes", []),
|
|
1461
|
+
__metadata("design:returntype", Promise)
|
|
1462
|
+
], InfrastructureService.prototype, "holdForPreservation", null);
|
|
1463
|
+
__decorate([
|
|
1464
|
+
RecoveryMutation(),
|
|
1465
|
+
__metadata("design:type", Function),
|
|
1466
|
+
__metadata("design:paramtypes", [String, InfrastructureService, Object]),
|
|
1467
|
+
__metadata("design:returntype", Promise)
|
|
1468
|
+
], InfrastructureService.prototype, "preserveExisting", null);
|
|
1360
1469
|
__decorate([
|
|
1361
1470
|
RecoveryMutation(),
|
|
1362
1471
|
__metadata("design:type", Function),
|