@omnitron-dev/omnitron 0.2.0 → 0.3.1
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 +4 -0
- package/dist/BUILD.json +5 -0
- package/dist/cli/omnitron.js +375 -29
- package/dist/cli/omnitron.js.map +1 -1
- package/dist/cluster/cluster.rpc-service.d.ts +40 -0
- package/dist/cluster/cluster.rpc-service.d.ts.map +1 -1
- package/dist/cluster/cluster.rpc-service.js +49 -3
- package/dist/cluster/cluster.rpc-service.js.map +1 -1
- package/dist/cluster/config-sync.d.ts.map +1 -1
- package/dist/cluster/config-sync.js.map +1 -1
- package/dist/cluster/leader-election.d.ts +90 -2
- package/dist/cluster/leader-election.d.ts.map +1 -1
- package/dist/cluster/leader-election.js +176 -22
- package/dist/cluster/leader-election.js.map +1 -1
- package/dist/cluster/mesh-link.d.ts +136 -0
- package/dist/cluster/mesh-link.d.ts.map +1 -0
- package/dist/cluster/mesh-link.js +212 -0
- package/dist/cluster/mesh-link.js.map +1 -0
- package/dist/cluster/mesh.d.ts +59 -0
- package/dist/cluster/mesh.d.ts.map +1 -0
- package/dist/cluster/mesh.js +117 -0
- package/dist/cluster/mesh.js.map +1 -0
- package/dist/cluster/slave-connector.d.ts +193 -9
- package/dist/cluster/slave-connector.d.ts.map +1 -1
- package/dist/cluster/slave-connector.js +409 -37
- package/dist/cluster/slave-connector.js.map +1 -1
- package/dist/commands/audit.d.ts +65 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +233 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/backup.d.ts +4 -0
- package/dist/commands/backup.d.ts.map +1 -1
- package/dist/commands/backup.js +255 -33
- package/dist/commands/backup.js.map +1 -1
- package/dist/commands/cluster.d.ts.map +1 -1
- package/dist/commands/cluster.js +78 -47
- package/dist/commands/cluster.js.map +1 -1
- package/dist/commands/daemon-cmd.d.ts +7 -1
- package/dist/commands/daemon-cmd.d.ts.map +1 -1
- package/dist/commands/daemon-cmd.js +87 -21
- package/dist/commands/daemon-cmd.js.map +1 -1
- package/dist/commands/daemon-required.d.ts +34 -0
- package/dist/commands/daemon-required.d.ts.map +1 -0
- package/dist/commands/daemon-required.js +92 -0
- package/dist/commands/daemon-required.js.map +1 -0
- package/dist/commands/deploy.d.ts +70 -8
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +99 -64
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/discover.d.ts +25 -4
- package/dist/commands/discover.d.ts.map +1 -1
- package/dist/commands/discover.js +155 -102
- package/dist/commands/discover.js.map +1 -1
- package/dist/commands/doctor.d.ts +293 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +1706 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/env.d.ts +8 -1
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/env.js +13 -8
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/exec.d.ts.map +1 -1
- package/dist/commands/exec.js +3 -2
- package/dist/commands/exec.js.map +1 -1
- package/dist/commands/fleet-asking.d.ts +87 -0
- package/dist/commands/fleet-asking.d.ts.map +1 -0
- package/dist/commands/fleet-asking.js +176 -0
- package/dist/commands/fleet-asking.js.map +1 -0
- package/dist/commands/fleet-recover.d.ts +2 -0
- package/dist/commands/fleet-recover.d.ts.map +1 -0
- package/dist/commands/fleet-recover.js +30 -0
- package/dist/commands/fleet-recover.js.map +1 -0
- package/dist/commands/fleet.d.ts +18 -0
- package/dist/commands/fleet.d.ts.map +1 -1
- package/dist/commands/fleet.js +314 -74
- package/dist/commands/fleet.js.map +1 -1
- package/dist/commands/health-check.d.ts +8 -6
- package/dist/commands/health-check.d.ts.map +1 -1
- package/dist/commands/health-check.js +26 -23
- package/dist/commands/health-check.js.map +1 -1
- package/dist/commands/health.d.ts.map +1 -1
- package/dist/commands/health.js +22 -8
- package/dist/commands/health.js.map +1 -1
- package/dist/commands/host-ingress.d.ts +3 -0
- package/dist/commands/host-ingress.d.ts.map +1 -0
- package/dist/commands/host-ingress.js +31 -0
- package/dist/commands/host-ingress.js.map +1 -0
- package/dist/commands/infra.d.ts +42 -1
- package/dist/commands/infra.d.ts.map +1 -1
- package/dist/commands/infra.js +418 -49
- package/dist/commands/infra.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +21 -36
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/inspect-graph.d.ts.map +1 -1
- package/dist/commands/inspect-graph.js +2 -6
- package/dist/commands/inspect-graph.js.map +1 -1
- package/dist/commands/inspect.d.ts.map +1 -1
- package/dist/commands/inspect.js +110 -14
- package/dist/commands/inspect.js.map +1 -1
- package/dist/commands/k8s.d.ts.map +1 -1
- package/dist/commands/k8s.js +23 -18
- package/dist/commands/k8s.js.map +1 -1
- package/dist/commands/kb.d.ts.map +1 -1
- package/dist/commands/kb.js +88 -29
- package/dist/commands/kb.js.map +1 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +21 -9
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/log-health.d.ts +120 -0
- package/dist/commands/log-health.d.ts.map +1 -0
- package/dist/commands/log-health.js +212 -0
- package/dist/commands/log-health.js.map +1 -0
- package/dist/commands/logs.d.ts +96 -2
- package/dist/commands/logs.d.ts.map +1 -1
- package/dist/commands/logs.js +522 -196
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/metrics.d.ts.map +1 -1
- package/dist/commands/metrics.js +35 -17
- package/dist/commands/metrics.js.map +1 -1
- package/dist/commands/monit.d.ts.map +1 -1
- package/dist/commands/monit.js +3 -2
- package/dist/commands/monit.js.map +1 -1
- package/dist/commands/node.d.ts +56 -0
- package/dist/commands/node.d.ts.map +1 -1
- package/dist/commands/node.js +297 -69
- package/dist/commands/node.js.map +1 -1
- package/dist/commands/output.d.ts +10 -0
- package/dist/commands/output.d.ts.map +1 -1
- package/dist/commands/output.js +41 -1
- package/dist/commands/output.js.map +1 -1
- package/dist/commands/pipeline.d.ts.map +1 -1
- package/dist/commands/pipeline.js +33 -19
- package/dist/commands/pipeline.js.map +1 -1
- package/dist/commands/project.d.ts +19 -0
- package/dist/commands/project.d.ts.map +1 -1
- package/dist/commands/project.js +125 -27
- package/dist/commands/project.js.map +1 -1
- package/dist/commands/release-store.d.ts +28 -0
- package/dist/commands/release-store.d.ts.map +1 -0
- package/dist/commands/release-store.js +158 -0
- package/dist/commands/release-store.js.map +1 -0
- package/dist/commands/release.d.ts +61 -0
- package/dist/commands/release.d.ts.map +1 -0
- package/dist/commands/release.js +555 -0
- package/dist/commands/release.js.map +1 -0
- package/dist/commands/reload.d.ts +16 -0
- package/dist/commands/reload.d.ts.map +1 -1
- package/dist/commands/reload.js +21 -5
- package/dist/commands/reload.js.map +1 -1
- package/dist/commands/remote.d.ts +40 -0
- package/dist/commands/remote.d.ts.map +1 -1
- package/dist/commands/remote.js +146 -35
- package/dist/commands/remote.js.map +1 -1
- package/dist/commands/restart.d.ts +16 -0
- package/dist/commands/restart.d.ts.map +1 -1
- package/dist/commands/restart.js +21 -5
- package/dist/commands/restart.js.map +1 -1
- package/dist/commands/scale.d.ts.map +1 -1
- package/dist/commands/scale.js +4 -3
- package/dist/commands/scale.js.map +1 -1
- package/dist/commands/secret.d.ts +54 -0
- package/dist/commands/secret.d.ts.map +1 -1
- package/dist/commands/secret.js +236 -34
- package/dist/commands/secret.js.map +1 -1
- package/dist/commands/service-units.d.ts +181 -0
- package/dist/commands/service-units.d.ts.map +1 -0
- package/dist/commands/service-units.js +291 -0
- package/dist/commands/service-units.js.map +1 -0
- package/dist/commands/service.d.ts +39 -0
- package/dist/commands/service.d.ts.map +1 -0
- package/dist/commands/service.js +370 -0
- package/dist/commands/service.js.map +1 -0
- package/dist/commands/spinner.d.ts +29 -0
- package/dist/commands/spinner.d.ts.map +1 -0
- package/dist/commands/spinner.js +44 -0
- package/dist/commands/spinner.js.map +1 -0
- package/dist/commands/stack.d.ts +49 -1
- package/dist/commands/stack.d.ts.map +1 -1
- package/dist/commands/stack.js +325 -12
- package/dist/commands/stack.js.map +1 -1
- package/dist/commands/start.d.ts +16 -0
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +20 -3
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/status.d.ts +9 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +45 -29
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/stop.d.ts +16 -0
- package/dist/commands/stop.d.ts.map +1 -1
- package/dist/commands/stop.js +34 -6
- package/dist/commands/stop.js.map +1 -1
- package/dist/commands/tor.d.ts +14 -7
- package/dist/commands/tor.d.ts.map +1 -1
- package/dist/commands/tor.js +113 -33
- package/dist/commands/tor.js.map +1 -1
- package/dist/commands/up.d.ts +85 -1
- package/dist/commands/up.d.ts.map +1 -1
- package/dist/commands/up.js +180 -32
- package/dist/commands/up.js.map +1 -1
- package/dist/commands/webapp.d.ts.map +1 -1
- package/dist/commands/webapp.js +2 -1
- package/dist/commands/webapp.js.map +1 -1
- package/dist/config/defaults.d.ts +16 -0
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +26 -3
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/define-ecosystem.d.ts.map +1 -1
- package/dist/config/define-ecosystem.js +2 -0
- package/dist/config/define-ecosystem.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/loader.d.ts +45 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +64 -6
- package/dist/config/loader.js.map +1 -1
- package/dist/config/omnitron-config.schema.d.ts.map +1 -1
- package/dist/config/omnitron-config.schema.js +16 -0
- package/dist/config/omnitron-config.schema.js.map +1 -1
- package/dist/config/types.d.ts +416 -44
- package/dist/config/types.d.ts.map +1 -1
- package/dist/daemon/config-reload.d.ts +27 -0
- package/dist/daemon/config-reload.d.ts.map +1 -0
- package/dist/daemon/config-reload.js +42 -0
- package/dist/daemon/config-reload.js.map +1 -0
- package/dist/daemon/daemon-client.d.ts +136 -2
- package/dist/daemon/daemon-client.d.ts.map +1 -1
- package/dist/daemon/daemon-client.js +307 -21
- package/dist/daemon/daemon-client.js.map +1 -1
- package/dist/daemon/daemon-entry.js +90 -30
- package/dist/daemon/daemon-entry.js.map +1 -1
- package/dist/daemon/daemon-scheduler.d.ts +4 -0
- package/dist/daemon/daemon-scheduler.d.ts.map +1 -1
- package/dist/daemon/daemon-scheduler.js +137 -7
- package/dist/daemon/daemon-scheduler.js.map +1 -1
- package/dist/daemon/daemon-state-store.service.d.ts +263 -0
- package/dist/daemon/daemon-state-store.service.d.ts.map +1 -0
- package/dist/daemon/daemon-state-store.service.js +446 -0
- package/dist/daemon/daemon-state-store.service.js.map +1 -0
- package/dist/daemon/daemon.d.ts +194 -4
- package/dist/daemon/daemon.d.ts.map +1 -1
- package/dist/daemon/daemon.js +1160 -157
- package/dist/daemon/daemon.js.map +1 -1
- package/dist/daemon/daemon.module.d.ts.map +1 -1
- package/dist/daemon/daemon.module.js +163 -85
- package/dist/daemon/daemon.module.js.map +1 -1
- package/dist/daemon/daemon.rpc-service.d.ts +90 -1
- package/dist/daemon/daemon.rpc-service.d.ts.map +1 -1
- package/dist/daemon/daemon.rpc-service.js +439 -97
- package/dist/daemon/daemon.rpc-service.js.map +1 -1
- package/dist/daemon/pid-manager.d.ts +16 -3
- package/dist/daemon/pid-manager.d.ts.map +1 -1
- package/dist/daemon/pid-manager.js +31 -4
- package/dist/daemon/pid-manager.js.map +1 -1
- package/dist/daemon/spawn-daemon.d.ts +73 -0
- package/dist/daemon/spawn-daemon.d.ts.map +1 -0
- package/dist/daemon/spawn-daemon.js +101 -0
- package/dist/daemon/spawn-daemon.js.map +1 -0
- package/dist/daemon/state-store.d.ts +65 -3
- package/dist/daemon/state-store.d.ts.map +1 -1
- package/dist/daemon/state-store.js +100 -58
- package/dist/daemon/state-store.js.map +1 -1
- package/dist/database/connection.d.ts +71 -0
- package/dist/database/connection.d.ts.map +1 -0
- package/dist/database/connection.js +129 -0
- package/dist/database/connection.js.map +1 -0
- package/dist/database/dialect.d.ts +60 -0
- package/dist/database/dialect.d.ts.map +1 -0
- package/dist/database/dialect.js +80 -0
- package/dist/database/dialect.js.map +1 -0
- package/dist/database/migrate.d.ts +5 -2
- package/dist/database/migrate.d.ts.map +1 -1
- package/dist/database/migrate.js +23 -33
- package/dist/database/migrate.js.map +1 -1
- package/dist/database/migration-runner.d.ts +50 -0
- package/dist/database/migration-runner.d.ts.map +1 -0
- package/dist/database/migration-runner.js +143 -0
- package/dist/database/migration-runner.js.map +1 -0
- package/dist/database/migrations/006_login_throttle.d.ts +17 -0
- package/dist/database/migrations/006_login_throttle.d.ts.map +1 -0
- package/dist/database/migrations/006_login_throttle.js +33 -0
- package/dist/database/migrations/006_login_throttle.js.map +1 -0
- package/dist/database/migrations/007_sync_ingested.d.ts +21 -0
- package/dist/database/migrations/007_sync_ingested.d.ts.map +1 -0
- package/dist/database/migrations/007_sync_ingested.js +39 -0
- package/dist/database/migrations/007_sync_ingested.js.map +1 -0
- package/dist/database/migrations/008_node_health_version_text.d.ts +24 -0
- package/dist/database/migrations/008_node_health_version_text.d.ts.map +1 -0
- package/dist/database/migrations/008_node_health_version_text.js +35 -0
- package/dist/database/migrations/008_node_health_version_text.js.map +1 -0
- package/dist/database/migrations/009_node_health_unmeasured.d.ts +40 -0
- package/dist/database/migrations/009_node_health_unmeasured.d.ts.map +1 -0
- package/dist/database/migrations/009_node_health_unmeasured.js +63 -0
- package/dist/database/migrations/009_node_health_unmeasured.js.map +1 -0
- package/dist/database/migrations/010_metrics_raw_had_no_reader.d.ts +22 -0
- package/dist/database/migrations/010_metrics_raw_had_no_reader.d.ts.map +1 -0
- package/dist/database/migrations/010_metrics_raw_had_no_reader.js +26 -0
- package/dist/database/migrations/010_metrics_raw_had_no_reader.js.map +1 -0
- package/dist/database/migrations/011_alerts_nobody_had_to_write.d.ts +56 -0
- package/dist/database/migrations/011_alerts_nobody_had_to_write.d.ts.map +1 -0
- package/dist/database/migrations/011_alerts_nobody_had_to_write.js +79 -0
- package/dist/database/migrations/011_alerts_nobody_had_to_write.js.map +1 -0
- package/dist/database/migrations/012_a_disk_nobody_watched.d.ts +26 -0
- package/dist/database/migrations/012_a_disk_nobody_watched.d.ts.map +1 -0
- package/dist/database/migrations/012_a_disk_nobody_watched.js +40 -0
- package/dist/database/migrations/012_a_disk_nobody_watched.js.map +1 -0
- package/dist/database/migrations/013_an_alarm_delivered.d.ts +14 -0
- package/dist/database/migrations/013_an_alarm_delivered.d.ts.map +1 -0
- package/dist/database/migrations/013_an_alarm_delivered.js +28 -0
- package/dist/database/migrations/013_an_alarm_delivered.js.map +1 -0
- package/dist/database/migrations/index.d.ts +21 -0
- package/dist/database/migrations/index.d.ts.map +1 -0
- package/dist/database/migrations/index.js +47 -0
- package/dist/database/migrations/index.js.map +1 -0
- package/dist/database/schema.d.ts +27 -11
- package/dist/database/schema.d.ts.map +1 -1
- package/dist/database/sqlite-date-binding.d.ts +71 -0
- package/dist/database/sqlite-date-binding.d.ts.map +1 -0
- package/dist/database/sqlite-date-binding.js +174 -0
- package/dist/database/sqlite-date-binding.js.map +1 -0
- package/dist/execution/data-channel.d.ts +48 -0
- package/dist/execution/data-channel.d.ts.map +1 -0
- package/dist/execution/data-channel.js +55 -0
- package/dist/execution/data-channel.js.map +1 -0
- package/dist/execution/execution.service.d.ts +146 -0
- package/dist/execution/execution.service.d.ts.map +1 -1
- package/dist/execution/execution.service.js +330 -10
- package/dist/execution/execution.service.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/infrastructure/bare-metal-plan.d.ts +208 -0
- package/dist/infrastructure/bare-metal-plan.d.ts.map +1 -0
- package/dist/infrastructure/bare-metal-plan.js +363 -0
- package/dist/infrastructure/bare-metal-plan.js.map +1 -0
- package/dist/infrastructure/bare-metal-runner.d.ts +65 -0
- package/dist/infrastructure/bare-metal-runner.d.ts.map +1 -0
- package/dist/infrastructure/bare-metal-runner.js +354 -0
- package/dist/infrastructure/bare-metal-runner.js.map +1 -0
- package/dist/infrastructure/config-payload.d.ts +149 -0
- package/dist/infrastructure/config-payload.d.ts.map +1 -0
- package/dist/infrastructure/config-payload.js +235 -0
- package/dist/infrastructure/config-payload.js.map +1 -0
- package/dist/infrastructure/container-runtime.d.ts +170 -10
- package/dist/infrastructure/container-runtime.d.ts.map +1 -1
- package/dist/infrastructure/container-runtime.js +565 -52
- package/dist/infrastructure/container-runtime.js.map +1 -1
- package/dist/infrastructure/gateway-reachability.d.ts +85 -0
- package/dist/infrastructure/gateway-reachability.d.ts.map +1 -0
- package/dist/infrastructure/gateway-reachability.js +116 -0
- package/dist/infrastructure/gateway-reachability.js.map +1 -0
- package/dist/infrastructure/gateway-redis-db.d.ts +29 -0
- package/dist/infrastructure/gateway-redis-db.d.ts.map +1 -0
- package/dist/infrastructure/gateway-redis-db.js +32 -0
- package/dist/infrastructure/gateway-redis-db.js.map +1 -0
- package/dist/infrastructure/host-ingress-config.d.ts +12 -0
- package/dist/infrastructure/host-ingress-config.d.ts.map +1 -0
- package/dist/infrastructure/host-ingress-config.js +197 -0
- package/dist/infrastructure/host-ingress-config.js.map +1 -0
- package/dist/infrastructure/host-ingress-lock.d.ts +4 -0
- package/dist/infrastructure/host-ingress-lock.d.ts.map +1 -0
- package/dist/infrastructure/host-ingress-lock.js +36 -0
- package/dist/infrastructure/host-ingress-lock.js.map +1 -0
- package/dist/infrastructure/host-ingress-runtime.d.ts +25 -0
- package/dist/infrastructure/host-ingress-runtime.d.ts.map +1 -0
- package/dist/infrastructure/host-ingress-runtime.js +114 -0
- package/dist/infrastructure/host-ingress-runtime.js.map +1 -0
- package/dist/infrastructure/host-ingress-takeover.d.ts +18 -0
- package/dist/infrastructure/host-ingress-takeover.d.ts.map +1 -0
- package/dist/infrastructure/host-ingress-takeover.js +142 -0
- package/dist/infrastructure/host-ingress-takeover.js.map +1 -0
- package/dist/infrastructure/host-ingress-types.d.ts +173 -0
- package/dist/infrastructure/host-ingress-types.d.ts.map +1 -0
- package/dist/infrastructure/host-ingress-types.js +2 -0
- package/dist/infrastructure/host-ingress-types.js.map +1 -0
- package/dist/infrastructure/host-ingress.service.d.ts +47 -0
- package/dist/infrastructure/host-ingress.service.d.ts.map +1 -0
- package/dist/infrastructure/host-ingress.service.js +514 -0
- package/dist/infrastructure/host-ingress.service.js.map +1 -0
- package/dist/infrastructure/host-inspection.d.ts +223 -0
- package/dist/infrastructure/host-inspection.d.ts.map +1 -0
- package/dist/infrastructure/host-inspection.js +501 -0
- package/dist/infrastructure/host-inspection.js.map +1 -0
- package/dist/infrastructure/infrastructure-gate.d.ts.map +1 -1
- package/dist/infrastructure/infrastructure.service.d.ts +223 -7
- package/dist/infrastructure/infrastructure.service.d.ts.map +1 -1
- package/dist/infrastructure/infrastructure.service.js +500 -93
- package/dist/infrastructure/infrastructure.service.js.map +1 -1
- package/dist/infrastructure/known-machines.d.ts +76 -0
- package/dist/infrastructure/known-machines.d.ts.map +1 -0
- package/dist/infrastructure/known-machines.js +94 -0
- package/dist/infrastructure/known-machines.js.map +1 -0
- package/dist/infrastructure/node-credentials.d.ts +45 -0
- package/dist/infrastructure/node-credentials.d.ts.map +1 -0
- package/dist/infrastructure/node-credentials.js +80 -0
- package/dist/infrastructure/node-credentials.js.map +1 -0
- package/dist/infrastructure/orphan-containers.d.ts +99 -0
- package/dist/infrastructure/orphan-containers.d.ts.map +1 -0
- package/dist/infrastructure/orphan-containers.js +106 -0
- package/dist/infrastructure/orphan-containers.js.map +1 -0
- package/dist/infrastructure/phantom-endpoint-janitor.d.ts +20 -0
- package/dist/infrastructure/phantom-endpoint-janitor.d.ts.map +1 -1
- package/dist/infrastructure/phantom-endpoint-janitor.js +56 -6
- package/dist/infrastructure/phantom-endpoint-janitor.js.map +1 -1
- package/dist/infrastructure/presets/gateway-openresty.d.ts.map +1 -1
- package/dist/infrastructure/presets/gateway-openresty.js +29 -3
- package/dist/infrastructure/presets/gateway-openresty.js.map +1 -1
- package/dist/infrastructure/presets/minio.d.ts.map +1 -1
- package/dist/infrastructure/presets/minio.js +36 -3
- package/dist/infrastructure/presets/minio.js.map +1 -1
- package/dist/infrastructure/presets/postgres.d.ts.map +1 -1
- package/dist/infrastructure/presets/postgres.js +69 -2
- package/dist/infrastructure/presets/postgres.js.map +1 -1
- package/dist/infrastructure/presets/redis.d.ts.map +1 -1
- package/dist/infrastructure/presets/redis.js +13 -0
- package/dist/infrastructure/presets/redis.js.map +1 -1
- package/dist/infrastructure/presets/registry.d.ts.map +1 -1
- package/dist/infrastructure/presets/registry.js +81 -12
- package/dist/infrastructure/presets/registry.js.map +1 -1
- package/dist/infrastructure/presets/tor.d.ts +38 -0
- package/dist/infrastructure/presets/tor.d.ts.map +1 -1
- package/dist/infrastructure/presets/tor.js +78 -69
- package/dist/infrastructure/presets/tor.js.map +1 -1
- package/dist/infrastructure/presets/torrc.d.ts +54 -0
- package/dist/infrastructure/presets/torrc.d.ts.map +1 -0
- package/dist/infrastructure/presets/torrc.js +153 -0
- package/dist/infrastructure/presets/torrc.js.map +1 -0
- package/dist/infrastructure/presets/types.d.ts +17 -0
- package/dist/infrastructure/presets/types.d.ts.map +1 -1
- package/dist/infrastructure/provisioning-outcome.d.ts +85 -0
- package/dist/infrastructure/provisioning-outcome.d.ts.map +1 -0
- package/dist/infrastructure/provisioning-outcome.js +122 -0
- package/dist/infrastructure/provisioning-outcome.js.map +1 -0
- package/dist/infrastructure/server-registry.d.ts +27 -0
- package/dist/infrastructure/server-registry.d.ts.map +1 -1
- package/dist/infrastructure/server-registry.js +60 -5
- package/dist/infrastructure/server-registry.js.map +1 -1
- package/dist/infrastructure/service-binding.d.ts +60 -0
- package/dist/infrastructure/service-binding.d.ts.map +1 -0
- package/dist/infrastructure/service-binding.js +90 -0
- package/dist/infrastructure/service-binding.js.map +1 -0
- package/dist/infrastructure/service-credentials.d.ts +105 -0
- package/dist/infrastructure/service-credentials.d.ts.map +1 -0
- package/dist/infrastructure/service-credentials.js +141 -0
- package/dist/infrastructure/service-credentials.js.map +1 -0
- package/dist/infrastructure/service-resolver.d.ts +166 -12
- package/dist/infrastructure/service-resolver.d.ts.map +1 -1
- package/dist/infrastructure/service-resolver.js +535 -82
- package/dist/infrastructure/service-resolver.js.map +1 -1
- package/dist/infrastructure/shipped-config.d.ts +43 -0
- package/dist/infrastructure/shipped-config.d.ts.map +1 -0
- package/dist/infrastructure/shipped-config.js +159 -0
- package/dist/infrastructure/shipped-config.js.map +1 -0
- package/dist/infrastructure/stack-infra-manager.d.ts +16 -1
- package/dist/infrastructure/stack-infra-manager.d.ts.map +1 -1
- package/dist/infrastructure/stack-infra-manager.js +81 -53
- package/dist/infrastructure/stack-infra-manager.js.map +1 -1
- package/dist/infrastructure/types.d.ts +263 -6
- package/dist/infrastructure/types.d.ts.map +1 -1
- package/dist/mcp/mcp-bridge.d.ts.map +1 -1
- package/dist/mcp/mcp-bridge.js.map +1 -1
- package/dist/mcp/tool-groups/apps.tools.d.ts +2 -1
- package/dist/mcp/tool-groups/apps.tools.d.ts.map +1 -1
- package/dist/mcp/tool-groups/apps.tools.js +2 -2
- package/dist/mcp/tool-groups/apps.tools.js.map +1 -1
- package/dist/mcp/tool-groups/infra.tools.d.ts +16 -2
- package/dist/mcp/tool-groups/infra.tools.d.ts.map +1 -1
- package/dist/mcp/tool-groups/infra.tools.js +51 -41
- package/dist/mcp/tool-groups/infra.tools.js.map +1 -1
- package/dist/mcp/tool-groups/kb.tools.d.ts.map +1 -1
- package/dist/mcp/tool-groups/kb.tools.js +4 -6
- package/dist/mcp/tool-groups/kb.tools.js.map +1 -1
- package/dist/mcp/tool-groups/management.tools.d.ts +20 -3
- package/dist/mcp/tool-groups/management.tools.d.ts.map +1 -1
- package/dist/mcp/tool-groups/management.tools.js +158 -125
- package/dist/mcp/tool-groups/management.tools.js.map +1 -1
- package/dist/mcp/tool-groups/monitoring.tools.d.ts +10 -1
- package/dist/mcp/tool-groups/monitoring.tools.d.ts.map +1 -1
- package/dist/mcp/tool-groups/monitoring.tools.js +65 -18
- package/dist/mcp/tool-groups/monitoring.tools.js.map +1 -1
- package/dist/mcp/unavailable-tools.d.ts +35 -0
- package/dist/mcp/unavailable-tools.d.ts.map +1 -0
- package/dist/mcp/unavailable-tools.js +59 -0
- package/dist/mcp/unavailable-tools.js.map +1 -0
- package/dist/monitoring/app-health.indicator.d.ts.map +1 -1
- package/dist/monitoring/app-health.indicator.js +12 -0
- package/dist/monitoring/app-health.indicator.js.map +1 -1
- package/dist/monitoring/desktop-notifier.d.ts +26 -0
- package/dist/monitoring/desktop-notifier.d.ts.map +1 -0
- package/dist/monitoring/desktop-notifier.js +49 -0
- package/dist/monitoring/desktop-notifier.js.map +1 -0
- package/dist/monitoring/docker-health.indicator.d.ts +17 -1
- package/dist/monitoring/docker-health.indicator.d.ts.map +1 -1
- package/dist/monitoring/docker-health.indicator.js +38 -8
- package/dist/monitoring/docker-health.indicator.js.map +1 -1
- package/dist/monitoring/event-loop-stall.indicator.d.ts +26 -0
- package/dist/monitoring/event-loop-stall.indicator.d.ts.map +1 -0
- package/dist/monitoring/event-loop-stall.indicator.js +47 -0
- package/dist/monitoring/event-loop-stall.indicator.js.map +1 -0
- package/dist/monitoring/event-loop-watch.d.ts +124 -0
- package/dist/monitoring/event-loop-watch.d.ts.map +1 -0
- package/dist/monitoring/event-loop-watch.js +179 -0
- package/dist/monitoring/event-loop-watch.js.map +1 -0
- package/dist/monitoring/host-disk.d.ts +6 -0
- package/dist/monitoring/host-disk.d.ts.map +1 -0
- package/dist/monitoring/host-disk.js +26 -0
- package/dist/monitoring/host-disk.js.map +1 -0
- package/dist/monitoring/log-line.d.ts +188 -0
- package/dist/monitoring/log-line.d.ts.map +1 -0
- package/dist/monitoring/log-line.js +458 -0
- package/dist/monitoring/log-line.js.map +1 -0
- package/dist/monitoring/log-manager.d.ts +89 -8
- package/dist/monitoring/log-manager.d.ts.map +1 -1
- package/dist/monitoring/log-manager.js +246 -77
- package/dist/monitoring/log-manager.js.map +1 -1
- package/dist/observability/metrics-bridge.d.ts.map +1 -1
- package/dist/observability/metrics-server.d.ts.map +1 -1
- package/dist/operations.d.ts +16 -0
- package/dist/operations.d.ts.map +1 -0
- package/dist/operations.js +13 -0
- package/dist/operations.js.map +1 -0
- package/dist/orchestrator/app-handle.d.ts +157 -2
- package/dist/orchestrator/app-handle.d.ts.map +1 -1
- package/dist/orchestrator/app-handle.js +165 -3
- package/dist/orchestrator/app-handle.js.map +1 -1
- package/dist/orchestrator/app-health.d.ts +33 -0
- package/dist/orchestrator/app-health.d.ts.map +1 -0
- package/dist/orchestrator/app-health.js +74 -0
- package/dist/orchestrator/app-health.js.map +1 -0
- package/dist/orchestrator/app-traffic.d.ts +14 -0
- package/dist/orchestrator/app-traffic.d.ts.map +1 -0
- package/dist/orchestrator/app-traffic.js +33 -0
- package/dist/orchestrator/app-traffic.js.map +1 -0
- package/dist/orchestrator/bootstrap-loader-child.d.ts +19 -0
- package/dist/orchestrator/bootstrap-loader-child.d.ts.map +1 -0
- package/dist/orchestrator/bootstrap-loader-child.js +43 -0
- package/dist/orchestrator/bootstrap-loader-child.js.map +1 -0
- package/dist/orchestrator/bootstrap-loader.d.ts +72 -0
- package/dist/orchestrator/bootstrap-loader.d.ts.map +1 -1
- package/dist/orchestrator/bootstrap-loader.js +350 -5
- package/dist/orchestrator/bootstrap-loader.js.map +1 -1
- package/dist/orchestrator/bootstrap-process.d.ts +99 -4
- package/dist/orchestrator/bootstrap-process.d.ts.map +1 -1
- package/dist/orchestrator/bootstrap-process.js +332 -20
- package/dist/orchestrator/bootstrap-process.js.map +1 -1
- package/dist/orchestrator/build-service.d.ts +6 -12
- package/dist/orchestrator/build-service.d.ts.map +1 -1
- package/dist/orchestrator/build-service.js +120 -83
- package/dist/orchestrator/build-service.js.map +1 -1
- package/dist/orchestrator/call-exposed-service.d.ts +7 -0
- package/dist/orchestrator/call-exposed-service.d.ts.map +1 -0
- package/dist/orchestrator/call-exposed-service.js +50 -0
- package/dist/orchestrator/call-exposed-service.js.map +1 -0
- package/dist/orchestrator/classic-launcher.d.ts +1 -0
- package/dist/orchestrator/classic-launcher.d.ts.map +1 -1
- package/dist/orchestrator/classic-launcher.js +40 -4
- package/dist/orchestrator/classic-launcher.js.map +1 -1
- package/dist/orchestrator/file-watcher.d.ts +79 -1
- package/dist/orchestrator/file-watcher.d.ts.map +1 -1
- package/dist/orchestrator/file-watcher.js +193 -7
- package/dist/orchestrator/file-watcher.js.map +1 -1
- package/dist/orchestrator/http-routes.d.ts +4 -0
- package/dist/orchestrator/http-routes.d.ts.map +1 -0
- package/dist/orchestrator/http-routes.js +19 -0
- package/dist/orchestrator/http-routes.js.map +1 -0
- package/dist/orchestrator/module-worker-process.d.ts.map +1 -1
- package/dist/orchestrator/module-worker-process.js +10 -0
- package/dist/orchestrator/module-worker-process.js.map +1 -1
- package/dist/orchestrator/orchestrator.service.d.ts +385 -11
- package/dist/orchestrator/orchestrator.service.d.ts.map +1 -1
- package/dist/orchestrator/orchestrator.service.js +1738 -364
- package/dist/orchestrator/orchestrator.service.js.map +1 -1
- package/dist/orchestrator/owned-pids.d.ts +83 -0
- package/dist/orchestrator/owned-pids.d.ts.map +1 -0
- package/dist/orchestrator/owned-pids.js +93 -0
- package/dist/orchestrator/owned-pids.js.map +1 -0
- package/dist/orchestrator/port-conflict.d.ts +102 -0
- package/dist/orchestrator/port-conflict.d.ts.map +1 -0
- package/dist/orchestrator/port-conflict.js +131 -0
- package/dist/orchestrator/port-conflict.js.map +1 -0
- package/dist/orchestrator/process-janitor.d.ts +78 -4
- package/dist/orchestrator/process-janitor.d.ts.map +1 -1
- package/dist/orchestrator/process-janitor.js +246 -30
- package/dist/orchestrator/process-janitor.js.map +1 -1
- package/dist/orchestrator/ps-metrics.d.ts +37 -0
- package/dist/orchestrator/ps-metrics.d.ts.map +1 -0
- package/dist/orchestrator/ps-metrics.js +60 -0
- package/dist/orchestrator/ps-metrics.js.map +1 -0
- package/dist/orchestrator/service-router.d.ts +58 -2
- package/dist/orchestrator/service-router.d.ts.map +1 -1
- package/dist/orchestrator/service-router.js +157 -25
- package/dist/orchestrator/service-router.js.map +1 -1
- package/dist/orchestrator/topology-query.d.ts +49 -0
- package/dist/orchestrator/topology-query.d.ts.map +1 -0
- package/dist/orchestrator/topology-query.js +54 -0
- package/dist/orchestrator/topology-query.js.map +1 -0
- package/dist/project/artifact-builder.d.ts +174 -3
- package/dist/project/artifact-builder.d.ts.map +1 -1
- package/dist/project/artifact-builder.js +454 -42
- package/dist/project/artifact-builder.js.map +1 -1
- package/dist/project/build-decision.d.ts +58 -0
- package/dist/project/build-decision.d.ts.map +1 -0
- package/dist/project/build-decision.js +59 -0
- package/dist/project/build-decision.js.map +1 -0
- package/dist/project/config-resolver.d.ts +6 -4
- package/dist/project/config-resolver.d.ts.map +1 -1
- package/dist/project/config-resolver.js +128 -74
- package/dist/project/config-resolver.js.map +1 -1
- package/dist/project/declared-config.d.ts +42 -0
- package/dist/project/declared-config.d.ts.map +1 -0
- package/dist/project/declared-config.js +60 -0
- package/dist/project/declared-config.js.map +1 -0
- package/dist/project/dependency-analyzer.d.ts.map +1 -1
- package/dist/project/dependency-analyzer.js.map +1 -1
- package/dist/project/deploy-phases.d.ts +35 -0
- package/dist/project/deploy-phases.d.ts.map +1 -0
- package/dist/project/deploy-phases.js +75 -0
- package/dist/project/deploy-phases.js.map +1 -0
- package/dist/project/exec-in-group.d.ts +49 -0
- package/dist/project/exec-in-group.d.ts.map +1 -0
- package/dist/project/exec-in-group.js +100 -0
- package/dist/project/exec-in-group.js.map +1 -0
- package/dist/project/node-app-config.d.ts +101 -0
- package/dist/project/node-app-config.d.ts.map +1 -0
- package/dist/project/node-app-config.js +134 -0
- package/dist/project/node-app-config.js.map +1 -0
- package/dist/project/node-app-health.d.ts +76 -0
- package/dist/project/node-app-health.d.ts.map +1 -0
- package/dist/project/node-app-health.js +119 -0
- package/dist/project/node-app-health.js.map +1 -0
- package/dist/project/operator-account.d.ts +293 -0
- package/dist/project/operator-account.d.ts.map +1 -0
- package/dist/project/operator-account.js +373 -0
- package/dist/project/operator-account.js.map +1 -0
- package/dist/project/registry.d.ts +45 -8
- package/dist/project/registry.d.ts.map +1 -1
- package/dist/project/registry.js +214 -64
- package/dist/project/registry.js.map +1 -1
- package/dist/project/requirements-scanner.d.ts +1 -0
- package/dist/project/requirements-scanner.d.ts.map +1 -1
- package/dist/project/requirements-scanner.js +28 -3
- package/dist/project/requirements-scanner.js.map +1 -1
- package/dist/project/stack-env.d.ts +37 -0
- package/dist/project/stack-env.d.ts.map +1 -0
- package/dist/project/stack-env.js +85 -0
- package/dist/project/stack-env.js.map +1 -0
- package/dist/project/stand-containers.d.ts +11 -0
- package/dist/project/stand-containers.d.ts.map +1 -0
- package/dist/project/stand-containers.js +27 -0
- package/dist/project/stand-containers.js.map +1 -0
- package/dist/project/working-tree.d.ts +62 -0
- package/dist/project/working-tree.d.ts.map +1 -0
- package/dist/project/working-tree.js +101 -0
- package/dist/project/working-tree.js.map +1 -0
- package/dist/release/artifact-store.d.ts +360 -0
- package/dist/release/artifact-store.d.ts.map +1 -0
- package/dist/release/artifact-store.js +1040 -0
- package/dist/release/artifact-store.js.map +1 -0
- package/dist/release/attest-on-node.d.ts +93 -0
- package/dist/release/attest-on-node.d.ts.map +1 -0
- package/dist/release/attest-on-node.js +207 -0
- package/dist/release/attest-on-node.js.map +1 -0
- package/dist/release/attest.d.ts +135 -0
- package/dist/release/attest.d.ts.map +1 -0
- package/dist/release/attest.js +199 -0
- package/dist/release/attest.js.map +1 -0
- package/dist/release/build-run.d.ts +151 -0
- package/dist/release/build-run.d.ts.map +1 -0
- package/dist/release/build-run.js +609 -0
- package/dist/release/build-run.js.map +1 -0
- package/dist/release/builder.d.ts +57 -0
- package/dist/release/builder.d.ts.map +1 -0
- package/dist/release/builder.js +120 -0
- package/dist/release/builder.js.map +1 -0
- package/dist/release/daemon-omni.d.ts +41 -0
- package/dist/release/daemon-omni.d.ts.map +1 -0
- package/dist/release/daemon-omni.js +59 -0
- package/dist/release/daemon-omni.js.map +1 -0
- package/dist/release/definition-inputs.d.ts +34 -0
- package/dist/release/definition-inputs.d.ts.map +1 -0
- package/dist/release/definition-inputs.js +90 -0
- package/dist/release/definition-inputs.js.map +1 -0
- package/dist/release/delivered.d.ts +53 -0
- package/dist/release/delivered.d.ts.map +1 -0
- package/dist/release/delivered.js +81 -0
- package/dist/release/delivered.js.map +1 -0
- package/dist/release/layout.d.ts +61 -0
- package/dist/release/layout.d.ts.map +1 -0
- package/dist/release/layout.js +114 -0
- package/dist/release/layout.js.map +1 -0
- package/dist/release/load.d.ts +44 -0
- package/dist/release/load.d.ts.map +1 -0
- package/dist/release/load.js +84 -0
- package/dist/release/load.js.map +1 -0
- package/dist/release/manifest.d.ts +299 -0
- package/dist/release/manifest.d.ts.map +1 -0
- package/dist/release/manifest.js +176 -0
- package/dist/release/manifest.js.map +1 -0
- package/dist/release/migrations.d.ts +32 -0
- package/dist/release/migrations.d.ts.map +1 -0
- package/dist/release/migrations.js +51 -0
- package/dist/release/migrations.js.map +1 -0
- package/dist/release/publish.d.ts +71 -0
- package/dist/release/publish.d.ts.map +1 -0
- package/dist/release/publish.js +102 -0
- package/dist/release/publish.js.map +1 -0
- package/dist/release/store.d.ts +174 -0
- package/dist/release/store.d.ts.map +1 -0
- package/dist/release/store.js +257 -0
- package/dist/release/store.js.map +1 -0
- package/dist/services/alert.rpc-service.d.ts +11 -15
- package/dist/services/alert.rpc-service.d.ts.map +1 -1
- package/dist/services/alert.rpc-service.js +29 -14
- package/dist/services/alert.rpc-service.js.map +1 -1
- package/dist/services/alert.service.d.ts +96 -59
- package/dist/services/alert.service.d.ts.map +1 -1
- package/dist/services/alert.service.js +455 -70
- package/dist/services/alert.service.js.map +1 -1
- package/dist/services/anonymous-input.d.ts +26 -0
- package/dist/services/anonymous-input.d.ts.map +1 -0
- package/dist/services/anonymous-input.js +44 -0
- package/dist/services/anonymous-input.js.map +1 -0
- package/dist/services/audit.rpc-service.d.ts +27 -0
- package/dist/services/audit.rpc-service.d.ts.map +1 -0
- package/dist/services/audit.rpc-service.js +57 -0
- package/dist/services/audit.rpc-service.js.map +1 -0
- package/dist/services/audit.service.d.ts +165 -0
- package/dist/services/audit.service.d.ts.map +1 -0
- package/dist/services/audit.service.js +242 -0
- package/dist/services/audit.service.js.map +1 -0
- package/dist/services/auth-context.d.ts +21 -1
- package/dist/services/auth-context.d.ts.map +1 -1
- package/dist/services/auth-context.js +51 -5
- package/dist/services/auth-context.js.map +1 -1
- package/dist/services/auth.rpc-service.d.ts +0 -1
- package/dist/services/auth.rpc-service.d.ts.map +1 -1
- package/dist/services/auth.rpc-service.js +23 -9
- package/dist/services/auth.rpc-service.js.map +1 -1
- package/dist/services/auth.service.d.ts +47 -33
- package/dist/services/auth.service.d.ts.map +1 -1
- package/dist/services/auth.service.js +155 -23
- package/dist/services/auth.service.js.map +1 -1
- package/dist/services/backup-pipeline.d.ts +97 -0
- package/dist/services/backup-pipeline.d.ts.map +1 -0
- package/dist/services/backup-pipeline.js +286 -0
- package/dist/services/backup-pipeline.js.map +1 -0
- package/dist/services/backup-schedule.d.ts +69 -0
- package/dist/services/backup-schedule.d.ts.map +1 -0
- package/dist/services/backup-schedule.js +132 -0
- package/dist/services/backup-schedule.js.map +1 -0
- package/dist/services/backup.rpc-service.d.ts +31 -2
- package/dist/services/backup.rpc-service.d.ts.map +1 -1
- package/dist/services/backup.rpc-service.js +53 -0
- package/dist/services/backup.rpc-service.js.map +1 -1
- package/dist/services/backup.service.d.ts +458 -14
- package/dist/services/backup.service.d.ts.map +1 -1
- package/dist/services/backup.service.js +1368 -170
- package/dist/services/backup.service.js.map +1 -1
- package/dist/services/bundle-build-worker.d.ts +19 -0
- package/dist/services/bundle-build-worker.d.ts.map +1 -0
- package/dist/services/bundle-build-worker.js +40 -0
- package/dist/services/bundle-build-worker.js.map +1 -0
- package/dist/services/bundle-builder.d.ts +490 -0
- package/dist/services/bundle-builder.d.ts.map +1 -0
- package/dist/services/bundle-builder.js +1159 -0
- package/dist/services/bundle-builder.js.map +1 -0
- package/dist/services/bundle-worker-protocol.d.ts +19 -0
- package/dist/services/bundle-worker-protocol.d.ts.map +1 -0
- package/dist/services/bundle-worker-protocol.js +32 -0
- package/dist/services/bundle-worker-protocol.js.map +1 -0
- package/dist/services/deploy.rpc-service.d.ts +4 -1
- package/dist/services/deploy.rpc-service.d.ts.map +1 -1
- package/dist/services/deploy.rpc-service.js +10 -0
- package/dist/services/deploy.rpc-service.js.map +1 -1
- package/dist/services/deploy.service.d.ts +14 -24
- package/dist/services/deploy.service.d.ts.map +1 -1
- package/dist/services/deploy.service.js +46 -5
- package/dist/services/deploy.service.js.map +1 -1
- package/dist/services/discovery.rpc-service.d.ts +2 -1
- package/dist/services/discovery.rpc-service.d.ts.map +1 -1
- package/dist/services/discovery.rpc-service.js.map +1 -1
- package/dist/services/discovery.service.d.ts +32 -28
- package/dist/services/discovery.service.d.ts.map +1 -1
- package/dist/services/discovery.service.js +108 -133
- package/dist/services/discovery.service.js.map +1 -1
- package/dist/services/event-broadcaster.rpc-service.d.ts +36 -23
- package/dist/services/event-broadcaster.rpc-service.d.ts.map +1 -1
- package/dist/services/event-broadcaster.rpc-service.js +70 -32
- package/dist/services/event-broadcaster.rpc-service.js.map +1 -1
- package/dist/services/event-broadcaster.service.d.ts.map +1 -1
- package/dist/services/event-broadcaster.service.js.map +1 -1
- package/dist/services/fleet.rpc-service.d.ts +2 -1
- package/dist/services/fleet.rpc-service.d.ts.map +1 -1
- package/dist/services/fleet.rpc-service.js +3 -1
- package/dist/services/fleet.rpc-service.js.map +1 -1
- package/dist/services/fleet.service.d.ts +32 -34
- package/dist/services/fleet.service.d.ts.map +1 -1
- package/dist/services/fleet.service.js +66 -10
- package/dist/services/fleet.service.js.map +1 -1
- package/dist/services/health-check.rpc-service.d.ts +2 -1
- package/dist/services/health-check.rpc-service.d.ts.map +1 -1
- package/dist/services/health-check.rpc-service.js.map +1 -1
- package/dist/services/health-check.service.d.ts +50 -36
- package/dist/services/health-check.service.d.ts.map +1 -1
- package/dist/services/health-check.service.js +179 -182
- package/dist/services/health-check.service.js.map +1 -1
- package/dist/services/host-operation-barrier.d.ts +8 -0
- package/dist/services/host-operation-barrier.d.ts.map +1 -0
- package/dist/services/host-operation-barrier.js +44 -0
- package/dist/services/host-operation-barrier.js.map +1 -0
- package/dist/services/host-upgrade.d.ts +129 -0
- package/dist/services/host-upgrade.d.ts.map +1 -0
- package/dist/services/host-upgrade.js +352 -0
- package/dist/services/host-upgrade.js.map +1 -0
- package/dist/services/infrastructure.rpc-service.d.ts +312 -2
- package/dist/services/infrastructure.rpc-service.d.ts.map +1 -1
- package/dist/services/infrastructure.rpc-service.js +584 -11
- package/dist/services/infrastructure.rpc-service.js.map +1 -1
- package/dist/services/kubernetes.rpc-service.d.ts +2 -1
- package/dist/services/kubernetes.rpc-service.d.ts.map +1 -1
- package/dist/services/kubernetes.rpc-service.js.map +1 -1
- package/dist/services/kubernetes.service.d.ts +5 -39
- package/dist/services/kubernetes.service.d.ts.map +1 -1
- package/dist/services/kubernetes.service.js +29 -5
- package/dist/services/kubernetes.service.js.map +1 -1
- package/dist/services/local-bundle.d.ts +160 -0
- package/dist/services/local-bundle.d.ts.map +1 -0
- package/dist/services/local-bundle.js +242 -0
- package/dist/services/local-bundle.js.map +1 -0
- package/dist/services/lockout.d.ts +28 -0
- package/dist/services/lockout.d.ts.map +1 -0
- package/dist/services/lockout.js +41 -0
- package/dist/services/lockout.js.map +1 -0
- package/dist/services/log-collector.rpc-service.d.ts +16 -0
- package/dist/services/log-collector.rpc-service.d.ts.map +1 -1
- package/dist/services/log-collector.rpc-service.js +16 -0
- package/dist/services/log-collector.rpc-service.js.map +1 -1
- package/dist/services/log-collector.service.d.ts +172 -54
- package/dist/services/log-collector.service.d.ts.map +1 -1
- package/dist/services/log-collector.service.js +492 -102
- package/dist/services/log-collector.service.js.map +1 -1
- package/dist/services/log-retention.d.ts +50 -0
- package/dist/services/log-retention.d.ts.map +1 -0
- package/dist/services/log-retention.js +52 -0
- package/dist/services/log-retention.js.map +1 -0
- package/dist/services/maintenance-lock.d.ts +162 -0
- package/dist/services/maintenance-lock.d.ts.map +1 -0
- package/dist/services/maintenance-lock.js +316 -0
- package/dist/services/maintenance-lock.js.map +1 -0
- package/dist/services/master-address.d.ts +107 -0
- package/dist/services/master-address.d.ts.map +1 -0
- package/dist/services/master-address.js +154 -0
- package/dist/services/master-address.js.map +1 -0
- package/dist/services/migration-output.d.ts +16 -0
- package/dist/services/migration-output.d.ts.map +1 -0
- package/dist/services/migration-output.js +22 -0
- package/dist/services/migration-output.js.map +1 -0
- package/dist/services/netron-telemetry-transport.d.ts.map +1 -1
- package/dist/services/netron-telemetry-transport.js.map +1 -1
- package/dist/services/node-deploy-lease.d.ts +171 -0
- package/dist/services/node-deploy-lease.d.ts.map +1 -0
- package/dist/services/node-deploy-lease.js +460 -0
- package/dist/services/node-deploy-lease.js.map +1 -0
- package/dist/services/node-health.repository.d.ts +63 -4
- package/dist/services/node-health.repository.d.ts.map +1 -1
- package/dist/services/node-health.repository.js +108 -67
- package/dist/services/node-health.repository.js.map +1 -1
- package/dist/services/node-manager.rpc-service.d.ts +360 -10
- package/dist/services/node-manager.rpc-service.d.ts.map +1 -1
- package/dist/services/node-manager.rpc-service.js +754 -34
- package/dist/services/node-manager.rpc-service.js.map +1 -1
- package/dist/services/node-manager.service.d.ts +267 -95
- package/dist/services/node-manager.service.d.ts.map +1 -1
- package/dist/services/node-manager.service.js +805 -103
- package/dist/services/node-manager.service.js.map +1 -1
- package/dist/services/node-upgrade.d.ts +129 -0
- package/dist/services/node-upgrade.d.ts.map +1 -0
- package/dist/services/node-upgrade.js +161 -0
- package/dist/services/node-upgrade.js.map +1 -0
- package/dist/services/node-upgrade.service.d.ts +232 -0
- package/dist/services/node-upgrade.service.d.ts.map +1 -0
- package/dist/services/node-upgrade.service.js +468 -0
- package/dist/services/node-upgrade.service.js.map +1 -0
- package/dist/services/pipeline.rpc-service.d.ts +6 -1
- package/dist/services/pipeline.rpc-service.d.ts.map +1 -1
- package/dist/services/pipeline.rpc-service.js +9 -0
- package/dist/services/pipeline.rpc-service.js.map +1 -1
- package/dist/services/pipeline.service.d.ts +17 -46
- package/dist/services/pipeline.service.d.ts.map +1 -1
- package/dist/services/pipeline.service.js +84 -9
- package/dist/services/pipeline.service.js.map +1 -1
- package/dist/services/project.rpc-service.d.ts +140 -5
- package/dist/services/project.rpc-service.d.ts.map +1 -1
- package/dist/services/project.rpc-service.js +260 -22
- package/dist/services/project.rpc-service.js.map +1 -1
- package/dist/services/project.service.d.ts +687 -15
- package/dist/services/project.service.d.ts.map +1 -1
- package/dist/services/project.service.js +2846 -337
- package/dist/services/project.service.js.map +1 -1
- package/dist/services/redeploy-decision.d.ts +176 -0
- package/dist/services/redeploy-decision.d.ts.map +1 -0
- package/dist/services/redeploy-decision.js +142 -0
- package/dist/services/redeploy-decision.js.map +1 -0
- package/dist/services/release.rpc-service.d.ts +159 -0
- package/dist/services/release.rpc-service.d.ts.map +1 -0
- package/dist/services/release.rpc-service.js +395 -0
- package/dist/services/release.rpc-service.js.map +1 -0
- package/dist/services/release.service.d.ts +114 -0
- package/dist/services/release.service.d.ts.map +1 -0
- package/dist/services/release.service.js +208 -0
- package/dist/services/release.service.js.map +1 -0
- package/dist/services/remote-deployer.service.d.ts +580 -8
- package/dist/services/remote-deployer.service.d.ts.map +1 -1
- package/dist/services/remote-deployer.service.js +1786 -169
- package/dist/services/remote-deployer.service.js.map +1 -1
- package/dist/services/remote-ops.service.d.ts +51 -9
- package/dist/services/remote-ops.service.d.ts.map +1 -1
- package/dist/services/remote-ops.service.js +235 -39
- package/dist/services/remote-ops.service.js.map +1 -1
- package/dist/services/remote-provisioner.d.ts +124 -0
- package/dist/services/remote-provisioner.d.ts.map +1 -0
- package/dist/services/remote-provisioner.js +258 -0
- package/dist/services/remote-provisioner.js.map +1 -0
- package/dist/services/secrets.rpc-service.d.ts +51 -2
- package/dist/services/secrets.rpc-service.d.ts.map +1 -1
- package/dist/services/secrets.rpc-service.js +81 -2
- package/dist/services/secrets.rpc-service.js.map +1 -1
- package/dist/services/secrets.service.d.ts +108 -9
- package/dist/services/secrets.service.d.ts.map +1 -1
- package/dist/services/secrets.service.js +313 -48
- package/dist/services/secrets.service.js.map +1 -1
- package/dist/services/slave-storage.service.d.ts +107 -0
- package/dist/services/slave-storage.service.d.ts.map +1 -1
- package/dist/services/slave-storage.service.js +171 -2
- package/dist/services/slave-storage.service.js.map +1 -1
- package/dist/services/static-carry-forward.d.ts +110 -0
- package/dist/services/static-carry-forward.d.ts.map +1 -0
- package/dist/services/static-carry-forward.js +433 -0
- package/dist/services/static-carry-forward.js.map +1 -0
- package/dist/services/sync-policy.d.ts +167 -0
- package/dist/services/sync-policy.d.ts.map +1 -0
- package/dist/services/sync-policy.js +161 -0
- package/dist/services/sync-policy.js.map +1 -0
- package/dist/services/sync-summary.d.ts +39 -0
- package/dist/services/sync-summary.d.ts.map +1 -0
- package/dist/services/sync-summary.js +62 -0
- package/dist/services/sync-summary.js.map +1 -0
- package/dist/services/sync.rpc-service.d.ts +19 -7
- package/dist/services/sync.rpc-service.d.ts.map +1 -1
- package/dist/services/sync.rpc-service.js +36 -5
- package/dist/services/sync.rpc-service.js.map +1 -1
- package/dist/services/sync.service.d.ts +350 -18
- package/dist/services/sync.service.d.ts.map +1 -1
- package/dist/services/sync.service.js +864 -116
- package/dist/services/sync.service.js.map +1 -1
- package/dist/services/system-info.rpc-service.d.ts +2 -1
- package/dist/services/system-info.rpc-service.d.ts.map +1 -1
- package/dist/services/system-info.rpc-service.js.map +1 -1
- package/dist/services/system-info.service.d.ts +56 -68
- package/dist/services/system-info.service.d.ts.map +1 -1
- package/dist/services/system-info.service.js +240 -127
- package/dist/services/system-info.service.js.map +1 -1
- package/dist/services/telemetry.rpc-service.d.ts.map +1 -1
- package/dist/services/telemetry.rpc-service.js +9 -3
- package/dist/services/telemetry.rpc-service.js.map +1 -1
- package/dist/services/telemetry.service.d.ts +4 -2
- package/dist/services/telemetry.service.d.ts.map +1 -1
- package/dist/services/telemetry.service.js +4 -2
- package/dist/services/telemetry.service.js.map +1 -1
- package/dist/services/trace-collector.rpc-service.d.ts +2 -1
- package/dist/services/trace-collector.rpc-service.d.ts.map +1 -1
- package/dist/services/trace-collector.rpc-service.js.map +1 -1
- package/dist/services/trace-collector.service.d.ts +2 -41
- package/dist/services/trace-collector.service.d.ts.map +1 -1
- package/dist/services/trace-collector.service.js +27 -7
- package/dist/services/trace-collector.service.js.map +1 -1
- package/dist/services/wait-for-postgres.d.ts +28 -0
- package/dist/services/wait-for-postgres.d.ts.map +1 -0
- package/dist/services/wait-for-postgres.js +77 -0
- package/dist/services/wait-for-postgres.js.map +1 -0
- package/dist/shared/alert-expression.d.ts +60 -0
- package/dist/shared/alert-expression.d.ts.map +1 -0
- package/dist/shared/alert-expression.js +124 -0
- package/dist/shared/alert-expression.js.map +1 -0
- package/dist/shared/audit-outcome.d.ts +39 -0
- package/dist/shared/audit-outcome.d.ts.map +1 -0
- package/dist/shared/audit-outcome.js +45 -0
- package/dist/shared/audit-outcome.js.map +1 -0
- package/dist/shared/build-freshness.d.ts +59 -0
- package/dist/shared/build-freshness.d.ts.map +1 -0
- package/dist/shared/build-freshness.js +113 -0
- package/dist/shared/build-freshness.js.map +1 -0
- package/dist/shared/build-stamp.d.ts +26 -0
- package/dist/shared/build-stamp.d.ts.map +1 -0
- package/dist/shared/build-stamp.js +36 -0
- package/dist/shared/build-stamp.js.map +1 -0
- package/dist/shared/describe-error.d.ts +22 -0
- package/dist/shared/describe-error.d.ts.map +1 -0
- package/dist/shared/describe-error.js +39 -0
- package/dist/shared/describe-error.js.map +1 -0
- package/dist/shared/dto/alerts.d.ts +101 -0
- package/dist/shared/dto/alerts.d.ts.map +1 -0
- package/dist/shared/dto/alerts.js +9 -0
- package/dist/shared/dto/alerts.js.map +1 -0
- package/dist/shared/dto/auth.d.ts +49 -0
- package/dist/shared/dto/auth.d.ts.map +1 -0
- package/dist/shared/dto/auth.js +14 -0
- package/dist/shared/dto/auth.js.map +1 -0
- package/dist/shared/dto/backups.d.ts +16 -0
- package/dist/shared/dto/backups.d.ts.map +1 -0
- package/dist/shared/dto/backups.js +9 -0
- package/dist/shared/dto/backups.js.map +1 -0
- package/dist/shared/dto/deploy.d.ts +28 -0
- package/dist/shared/dto/deploy.d.ts.map +1 -0
- package/dist/shared/dto/deploy.js +8 -0
- package/dist/shared/dto/deploy.js.map +1 -0
- package/dist/shared/dto/discovery.d.ts +24 -0
- package/dist/shared/dto/discovery.d.ts.map +1 -0
- package/dist/shared/dto/discovery.js +9 -0
- package/dist/shared/dto/discovery.js.map +1 -0
- package/dist/shared/dto/fleet.d.ts +35 -0
- package/dist/shared/dto/fleet.d.ts.map +1 -0
- package/dist/shared/dto/fleet.js +8 -0
- package/dist/shared/dto/fleet.js.map +1 -0
- package/dist/shared/dto/health.d.ts +26 -0
- package/dist/shared/dto/health.d.ts.map +1 -0
- package/dist/shared/dto/health.js +9 -0
- package/dist/shared/dto/health.js.map +1 -0
- package/dist/shared/dto/kubernetes.d.ts +44 -0
- package/dist/shared/dto/kubernetes.d.ts.map +1 -0
- package/dist/shared/dto/kubernetes.js +9 -0
- package/dist/shared/dto/kubernetes.js.map +1 -0
- package/dist/shared/dto/logs.d.ts +77 -0
- package/dist/shared/dto/logs.d.ts.map +1 -0
- package/dist/shared/dto/logs.js +10 -0
- package/dist/shared/dto/logs.js.map +1 -0
- package/dist/shared/dto/metrics.d.ts +65 -0
- package/dist/shared/dto/metrics.d.ts.map +1 -0
- package/dist/shared/dto/metrics.js +17 -0
- package/dist/shared/dto/metrics.js.map +1 -0
- package/dist/shared/dto/nodes.d.ts +347 -0
- package/dist/shared/dto/nodes.d.ts.map +1 -0
- package/dist/shared/dto/nodes.js +8 -0
- package/dist/shared/dto/nodes.js.map +1 -0
- package/dist/shared/dto/pipelines.d.ts +53 -0
- package/dist/shared/dto/pipelines.d.ts.map +1 -0
- package/dist/shared/dto/pipelines.js +9 -0
- package/dist/shared/dto/pipelines.js.map +1 -0
- package/dist/shared/dto/project.d.ts +142 -8
- package/dist/shared/dto/project.d.ts.map +1 -1
- package/dist/shared/dto/services.d.ts +858 -7
- package/dist/shared/dto/services.d.ts.map +1 -1
- package/dist/shared/dto/system-info.d.ts +93 -0
- package/dist/shared/dto/system-info.d.ts.map +1 -0
- package/dist/shared/dto/system-info.js +9 -0
- package/dist/shared/dto/system-info.js.map +1 -0
- package/dist/shared/dto/traces.d.ts +49 -0
- package/dist/shared/dto/traces.d.ts.map +1 -0
- package/dist/shared/dto/traces.js +9 -0
- package/dist/shared/dto/traces.js.map +1 -0
- package/dist/shared/env-config.d.ts +74 -0
- package/dist/shared/env-config.d.ts.map +1 -0
- package/dist/shared/env-config.js +99 -0
- package/dist/shared/env-config.js.map +1 -0
- package/dist/shared/events.d.ts +45 -39
- package/dist/shared/events.d.ts.map +1 -1
- package/dist/shared/events.js +6 -0
- package/dist/shared/events.js.map +1 -1
- package/dist/shared/format.d.ts +1 -1
- package/dist/shared/format.d.ts.map +1 -1
- package/dist/shared/format.js +4 -0
- package/dist/shared/format.js.map +1 -1
- package/dist/shared/local-infra-host.d.ts +28 -0
- package/dist/shared/local-infra-host.d.ts.map +1 -0
- package/dist/shared/local-infra-host.js +28 -0
- package/dist/shared/local-infra-host.js.map +1 -0
- package/dist/shared/node-check.d.ts +37 -0
- package/dist/shared/node-check.d.ts.map +1 -0
- package/dist/shared/node-check.js +41 -0
- package/dist/shared/node-check.js.map +1 -0
- package/dist/shared/paths.d.ts +29 -0
- package/dist/shared/paths.d.ts.map +1 -0
- package/dist/shared/paths.js +54 -0
- package/dist/shared/paths.js.map +1 -0
- package/dist/shared/pnpm.d.ts +29 -0
- package/dist/shared/pnpm.d.ts.map +1 -0
- package/dist/shared/pnpm.js +57 -0
- package/dist/shared/pnpm.js.map +1 -0
- package/dist/shared/private-files.d.ts +29 -0
- package/dist/shared/private-files.d.ts.map +1 -0
- package/dist/shared/private-files.js +109 -0
- package/dist/shared/private-files.js.map +1 -0
- package/dist/shared/redact-env.d.ts +24 -0
- package/dist/shared/redact-env.d.ts.map +1 -0
- package/dist/shared/redact-env.js +36 -0
- package/dist/shared/redact-env.js.map +1 -0
- package/dist/shared/release-reading.d.ts +85 -0
- package/dist/shared/release-reading.d.ts.map +1 -0
- package/dist/shared/release-reading.js +81 -0
- package/dist/shared/release-reading.js.map +1 -0
- package/dist/shared/roles.d.ts +58 -3
- package/dist/shared/roles.d.ts.map +1 -1
- package/dist/shared/roles.js +55 -0
- package/dist/shared/roles.js.map +1 -1
- package/dist/shared/rpcauth.d.ts +13 -0
- package/dist/shared/rpcauth.d.ts.map +1 -0
- package/dist/shared/rpcauth.js +23 -0
- package/dist/shared/rpcauth.js.map +1 -0
- package/dist/shared/shell-escape.d.ts +9 -0
- package/dist/shared/shell-escape.d.ts.map +1 -0
- package/dist/shared/shell-escape.js +11 -0
- package/dist/shared/shell-escape.js.map +1 -0
- package/dist/shared/sync-reading.d.ts +45 -0
- package/dist/shared/sync-reading.d.ts.map +1 -0
- package/dist/shared/sync-reading.js +42 -0
- package/dist/shared/sync-reading.js.map +1 -0
- package/dist/shared/tokens.d.ts +19 -0
- package/dist/shared/tokens.d.ts.map +1 -1
- package/dist/shared/tokens.js +28 -0
- package/dist/shared/tokens.js.map +1 -1
- package/dist/webapp/webapp.service.d.ts +33 -2
- package/dist/webapp/webapp.service.d.ts.map +1 -1
- package/dist/webapp/webapp.service.js +143 -31
- package/dist/webapp/webapp.service.js.map +1 -1
- package/dist/workers/health-monitor-process.d.ts.map +1 -1
- package/dist/workers/health-monitor-process.js +10 -0
- package/dist/workers/health-monitor-process.js.map +1 -1
- package/dist/workers/health-monitor.service.d.ts +45 -3
- package/dist/workers/health-monitor.service.d.ts.map +1 -1
- package/dist/workers/health-monitor.service.js +152 -25
- package/dist/workers/health-monitor.service.js.map +1 -1
- package/dist/workers/system-worker-manager.d.ts +43 -0
- package/dist/workers/system-worker-manager.d.ts.map +1 -1
- package/dist/workers/system-worker-manager.js +150 -3
- package/dist/workers/system-worker-manager.js.map +1 -1
- package/dist/workers/types.d.ts +8 -2
- package/dist/workers/types.d.ts.map +1 -1
- package/package.json +68 -30
- package/webapp/dist/BUILD.json +5 -0
- package/webapp/dist/assets/FormControlLabel-BbSxpQwN.js +1 -0
- package/webapp/dist/assets/Grid-DizFZYue.js +1 -0
- package/webapp/dist/assets/Switch-Bfiqzx8l.js +1 -0
- package/webapp/dist/assets/alerts-DH_RVRS3.js +1 -0
- package/webapp/dist/assets/apps-B96355sz.js +1 -0
- package/webapp/dist/assets/audit-CYGtbi4k.js +1 -0
- package/webapp/dist/assets/client-BmqFExWT.js +1 -0
- package/webapp/dist/assets/constants-veKGFkC6.js +1 -0
- package/webapp/dist/assets/containers-B_TpThln.js +2 -0
- package/webapp/dist/assets/daemon-memory-CCPZ4cV_.js +1 -0
- package/webapp/dist/assets/dashboard-DHf2_65N.js +1 -0
- package/webapp/dist/assets/dashboard-builder-CWY2pjeG.js +1 -0
- package/webapp/dist/assets/deploy-release-dialog-Dp-zpSAd.js +1 -0
- package/webapp/dist/assets/deployments-tJI6O3fK.js +1 -0
- package/webapp/dist/assets/detail-B2zP1Hto.js +8 -0
- package/webapp/dist/assets/detail-CoIrwmsy.js +1 -0
- package/webapp/dist/assets/detail-DWaGaOtL.js +2 -0
- package/webapp/dist/assets/formatters-BqjL73N3.js +1 -0
- package/webapp/dist/assets/index-Dvo0iprx.css +1 -0
- package/webapp/dist/assets/index-vMnY_4jR.js +412 -0
- package/webapp/dist/assets/logs-DTRjOfX8.js +12 -0
- package/webapp/dist/assets/maplibre-gl-DowHoZAx.js +814 -0
- package/webapp/dist/assets/metrics-UCajtdox.js +2 -0
- package/webapp/dist/assets/nodes-DuTVU0f6.js +7 -0
- package/webapp/dist/assets/pipelines-C8BeDcAl.js +4 -0
- package/webapp/dist/assets/projects-Dp_zFfLY.js +1 -0
- package/webapp/dist/assets/react-DlmbjZJV.js +1 -0
- package/webapp/dist/assets/react-apexcharts.esm-C8pn45ml.js +97 -0
- package/webapp/dist/assets/release-bits-BzTKz5fM.js +1 -0
- package/webapp/dist/assets/release-build-panel-DcW9YcXQ.js +1 -0
- package/webapp/dist/assets/releases-B4hcr1bE.js +2 -0
- package/webapp/dist/assets/rolldown-runtime-XKyaHtl9.js +1 -0
- package/webapp/dist/assets/settings-DIteZTbe.js +1 -0
- package/webapp/dist/assets/settled-pair-C7SjZuns.js +1 -0
- package/webapp/dist/assets/sign-in-D4kMBOHp.js +1 -0
- package/webapp/dist/assets/stacks-Brnf-EB7.js +1 -0
- package/webapp/dist/assets/sync-reading-C3PnJ7AX.js +1 -0
- package/webapp/dist/assets/system-info-CFDNVKkU.js +1 -0
- package/webapp/dist/assets/topology-7WeTUsDN.js +12 -0
- package/webapp/dist/assets/topology-DLioOiRN.css +1 -0
- package/webapp/dist/assets/traces-9c3gwCN-.js +1 -0
- package/webapp/dist/assets/use-stack-context-CnA5FTHu.js +1 -0
- package/webapp/dist/index.html +6 -6
- package/dist/commands/dev.d.ts +0 -23
- package/dist/commands/dev.d.ts.map +0 -1
- package/dist/commands/dev.js +0 -76
- package/dist/commands/dev.js.map +0 -1
- package/dist/config/define-app.d.ts +0 -6
- package/dist/config/define-app.d.ts.map +0 -1
- package/dist/config/define-app.js +0 -38
- package/dist/config/define-app.js.map +0 -1
- package/dist/infrastructure/gateway-generator.d.ts +0 -63
- package/dist/infrastructure/gateway-generator.d.ts.map +0 -1
- package/dist/infrastructure/gateway-generator.js +0 -253
- package/dist/infrastructure/gateway-generator.js.map +0 -1
- package/dist/monitoring/health.service.d.ts +0 -14
- package/dist/monitoring/health.service.d.ts.map +0 -1
- package/dist/monitoring/health.service.js +0 -50
- package/dist/monitoring/health.service.js.map +0 -1
- package/dist/monitoring/metrics.service.d.ts +0 -14
- package/dist/monitoring/metrics.service.d.ts.map +0 -1
- package/dist/monitoring/metrics.service.js +0 -40
- package/dist/monitoring/metrics.service.js.map +0 -1
- package/dist/orchestrator/bootstrap-runner.d.ts +0 -15
- package/dist/orchestrator/bootstrap-runner.d.ts.map +0 -1
- package/dist/orchestrator/bootstrap-runner.js +0 -152
- package/dist/orchestrator/bootstrap-runner.js.map +0 -1
- package/dist/orchestrator/topology-proxy.d.ts +0 -65
- package/dist/orchestrator/topology-proxy.d.ts.map +0 -1
- package/dist/orchestrator/topology-proxy.js +0 -209
- package/dist/orchestrator/topology-proxy.js.map +0 -1
- package/dist/orchestrator/topology-relay.d.ts +0 -111
- package/dist/orchestrator/topology-relay.d.ts.map +0 -1
- package/dist/orchestrator/topology-relay.js +0 -255
- package/dist/orchestrator/topology-relay.js.map +0 -1
- package/dist/services/auth-middleware.d.ts +0 -47
- package/dist/services/auth-middleware.d.ts.map +0 -1
- package/dist/services/auth-middleware.js +0 -158
- package/dist/services/auth-middleware.js.map +0 -1
- package/dist/services/environment.rpc-service.d.ts +0 -22
- package/dist/services/environment.rpc-service.d.ts.map +0 -1
- package/dist/services/environment.rpc-service.js +0 -65
- package/dist/services/environment.rpc-service.js.map +0 -1
- package/dist/services/environment.service.d.ts +0 -87
- package/dist/services/environment.service.d.ts.map +0 -1
- package/dist/services/environment.service.js +0 -220
- package/dist/services/environment.service.js.map +0 -1
- package/dist/services/metrics-collector.service.d.ts +0 -103
- package/dist/services/metrics-collector.service.d.ts.map +0 -1
- package/dist/services/metrics-collector.service.js +0 -235
- package/dist/services/metrics-collector.service.js.map +0 -1
- package/dist/services/metrics.rpc-service.d.ts +0 -41
- package/dist/services/metrics.rpc-service.d.ts.map +0 -1
- package/dist/services/metrics.rpc-service.js +0 -90
- package/dist/services/metrics.rpc-service.js.map +0 -1
- package/dist/services/metrics.service.d.ts +0 -72
- package/dist/services/metrics.service.d.ts.map +0 -1
- package/dist/services/metrics.service.js +0 -185
- package/dist/services/metrics.service.js.map +0 -1
- package/dist/supervisor/omnitron-supervisor.d.ts +0 -21
- package/dist/supervisor/omnitron-supervisor.d.ts.map +0 -1
- package/dist/supervisor/omnitron-supervisor.js +0 -43
- package/dist/supervisor/omnitron-supervisor.js.map +0 -1
- package/dist/webapp/static-server.d.ts +0 -24
- package/dist/webapp/static-server.d.ts.map +0 -1
- package/dist/webapp/static-server.js +0 -152
- package/dist/webapp/static-server.js.map +0 -1
- package/webapp/dist/assets/Badge-D2ZBP5iK.js +0 -1
- package/webapp/dist/assets/Card-vO88g06B.js +0 -1
- package/webapp/dist/assets/CardActions-C9h7Q2wW.js +0 -1
- package/webapp/dist/assets/CardContent-BA_Xmmhk.js +0 -1
- package/webapp/dist/assets/CardHeader-ceIs__6x.js +0 -1
- package/webapp/dist/assets/Chip-Ckk0xUhK.js +0 -1
- package/webapp/dist/assets/DialogActions-BhHM7hov.js +0 -1
- package/webapp/dist/assets/DialogContentText-BT2JQRmK.js +0 -1
- package/webapp/dist/assets/FormControlLabel-CcQByVS8.js +0 -1
- package/webapp/dist/assets/Grid-14PETRQW.js +0 -1
- package/webapp/dist/assets/InputAdornment-B8aHIsQ7.js +0 -1
- package/webapp/dist/assets/Skeleton-B74-Ds6O.js +0 -37
- package/webapp/dist/assets/Switch-DvWD2wh4.js +0 -1
- package/webapp/dist/assets/SwitchBase-CDU4nY8O.js +0 -1
- package/webapp/dist/assets/Tab-DcCOYYp5.js +0 -1
- package/webapp/dist/assets/TableContainer-CzTh4mu-.js +0 -1
- package/webapp/dist/assets/TableRow-BySEreZR.js +0 -2
- package/webapp/dist/assets/TextField-BLf-BHz2.js +0 -1
- package/webapp/dist/assets/alerts-DnRbT41C.js +0 -1
- package/webapp/dist/assets/apps-CdR0VH2d.js +0 -1
- package/webapp/dist/assets/chunk-DtcAfS_W.js +0 -1
- package/webapp/dist/assets/client-DU8I_lDc.js +0 -2
- package/webapp/dist/assets/constants-BgnT-Xdy.js +0 -1
- package/webapp/dist/assets/containers-Dw-rRXV1.js +0 -1
- package/webapp/dist/assets/dashboard-CzgB0uZz.js +0 -1
- package/webapp/dist/assets/dashboard-builder-DsA0yg33.js +0 -1
- package/webapp/dist/assets/deployments-DtQAoIcQ.js +0 -1
- package/webapp/dist/assets/detail-BJR-G7JG.js +0 -1
- package/webapp/dist/assets/detail-nlCeSltl.js +0 -8
- package/webapp/dist/assets/formatters-Do41SRmE.js +0 -1
- package/webapp/dist/assets/index-ByQDwp2r.js +0 -566
- package/webapp/dist/assets/index-CHVXOsTS.css +0 -1
- package/webapp/dist/assets/isMuiElement-DwF2naaF.js +0 -1
- package/webapp/dist/assets/logs-Kn8o4H7k.js +0 -11
- package/webapp/dist/assets/metrics-DN8Zu5wT.js +0 -2
- package/webapp/dist/assets/nodes-Bgch7AtN.js +0 -7
- package/webapp/dist/assets/pipelines-Cry3qm-S.js +0 -4
- package/webapp/dist/assets/popper-BJFSj6rc.js +0 -1
- package/webapp/dist/assets/preload-helper-DSXbuxSR.js +0 -1
- package/webapp/dist/assets/projects-Dym2GI1U.js +0 -1
- package/webapp/dist/assets/react-apexcharts.esm-CSGK5Cxn.js +0 -958
- package/webapp/dist/assets/react-apexcharts.esm-DEAWOwx5.js +0 -1003
- package/webapp/dist/assets/settings-va3zTcow.js +0 -1
- package/webapp/dist/assets/sign-in-ik35umbp.js +0 -1
- package/webapp/dist/assets/stacks-CVFOnxbF.js +0 -1
- package/webapp/dist/assets/system-info-npIXAjX2.js +0 -1
- package/webapp/dist/assets/topology-CHpVij2M.css +0 -1
- package/webapp/dist/assets/topology-bDe70vLs.js +0 -12
- package/webapp/dist/assets/traces-DIIcT8DF.js +0 -1
- package/webapp/dist/assets/use-stack-context-DHLwZv1r.js +0 -1
- /package/webapp/dist/assets/{fs-CgZLtHiQ.js → fs-Ccl3sAcp.js} +0 -0
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NodeManagerService — Manages infrastructure nodes (machines)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Registry lives in the SQLite-backed `nodes` table of DaemonStateStore.
|
|
5
|
+
* `~/.omnitron/nodes.json` is read once, on a boot that finds the table
|
|
6
|
+
* empty, and then unlinked — the header claimed the JSON file was still the
|
|
7
|
+
* storage long after T-7 moved it, which is the kind of thing a reader
|
|
8
|
+
* believes because there is nothing to contradict it.
|
|
5
9
|
* Always includes a "local" node for the local machine.
|
|
6
10
|
* Remote nodes are accessed via SSH for provisioning and management.
|
|
7
11
|
*/
|
|
@@ -10,53 +14,213 @@ import path from 'node:path';
|
|
|
10
14
|
import os from 'node:os';
|
|
11
15
|
import { EventEmitter } from 'node:events';
|
|
12
16
|
import { randomUUID } from 'node:crypto';
|
|
13
|
-
import { RemoteOpsService, DEFAULT_CHECK_CONFIG } from './remote-ops.service.js';
|
|
17
|
+
import { RemoteOpsService, DEFAULT_CHECK_CONFIG, normalizeCheckConfig, assertNodeHost, } from './remote-ops.service.js';
|
|
18
|
+
import { CLI_VERSION } from '../config/defaults.js';
|
|
14
19
|
// =============================================================================
|
|
15
20
|
// Constants
|
|
16
21
|
// =============================================================================
|
|
17
22
|
const OMNITRON_HOME = path.join(os.homedir(), '.omnitron');
|
|
18
23
|
const NODES_FILE = path.join(OMNITRON_HOME, 'nodes.json');
|
|
19
24
|
const LOCAL_NODE_ID = 'local';
|
|
25
|
+
/** DaemonStateStore key holding the operator-set check configuration. */
|
|
26
|
+
const CHECK_CONFIG_KEY = 'nodes:check-config';
|
|
20
27
|
// =============================================================================
|
|
21
28
|
// Service
|
|
22
29
|
// =============================================================================
|
|
23
30
|
export class NodeManagerService extends EventEmitter {
|
|
24
31
|
logger;
|
|
32
|
+
store;
|
|
25
33
|
secrets;
|
|
26
34
|
nodes = new Map();
|
|
27
35
|
statusCache = new Map();
|
|
36
|
+
/**
|
|
37
|
+
* Aggregated health per node — the shape the worker reports and the console
|
|
38
|
+
* reads. Kept here so a daemon whose worker is down can still answer
|
|
39
|
+
* `triggerNodeCheck`, and so status TRANSITIONS have something to compare
|
|
40
|
+
* against: `node.went_offline` and its siblings are declared event channels
|
|
41
|
+
* that nothing ever emitted, because no one held the previous value.
|
|
42
|
+
*/
|
|
43
|
+
summaryCache = new Map();
|
|
28
44
|
remoteOps;
|
|
29
45
|
checkConfig = DEFAULT_CHECK_CONFIG;
|
|
30
|
-
|
|
46
|
+
/** Set by the daemon from its own config; see `setHistoryConfig`. */
|
|
47
|
+
historyConfig = { uptimeIntervalMs: 86_400_000, retentionDays: 90 };
|
|
48
|
+
/**
|
|
49
|
+
* Secrets read out of a node row and not yet written to the vault.
|
|
50
|
+
*
|
|
51
|
+
* The migration in `healLeakedSecrets` is async and starts at construction;
|
|
52
|
+
* without this, a check running in that window would find no passphrase and
|
|
53
|
+
* report a perfectly reachable node as unreachable.
|
|
54
|
+
*/
|
|
55
|
+
pendingSecrets = new Map();
|
|
56
|
+
/** The master's mesh — see `setSlaveConnector`. */
|
|
57
|
+
mesh = null;
|
|
58
|
+
constructor(logger,
|
|
59
|
+
/**
|
|
60
|
+
* T-7 — fleet node registry persistence moved off
|
|
61
|
+
* ~/.omnitron/nodes.json onto the SQLite-backed `nodes` table
|
|
62
|
+
* in DaemonStateStore.
|
|
63
|
+
* Canonical name/host/port are denormalised into typed columns
|
|
64
|
+
* for queries; the full INode payload (SSH config, tags, etc.)
|
|
65
|
+
* lives in the `metadata` column as JSON.
|
|
66
|
+
*/
|
|
67
|
+
store, secrets) {
|
|
31
68
|
super();
|
|
32
69
|
this.logger = logger;
|
|
70
|
+
this.store = store;
|
|
33
71
|
this.secrets = secrets;
|
|
34
72
|
this.remoteOps = new RemoteOpsService(logger);
|
|
35
73
|
this.load();
|
|
36
74
|
this.ensureLocalNode();
|
|
37
|
-
this.initLocalStatus();
|
|
38
75
|
}
|
|
39
|
-
/**
|
|
76
|
+
/**
|
|
77
|
+
* Update check configuration (ping/SSH timeouts, ping enabled/disabled).
|
|
78
|
+
*
|
|
79
|
+
* Persisted and announced. Both were missing: the setting lived in this
|
|
80
|
+
* field alone, so it was lost on restart, and the health-monitor worker —
|
|
81
|
+
* which performs every check the console displays — kept running with the
|
|
82
|
+
* values it was handed at boot. An operator turning ping off in the console
|
|
83
|
+
* changed a value that only the daemon's own fallback path ever read.
|
|
84
|
+
*/
|
|
40
85
|
setCheckConfig(config) {
|
|
41
|
-
|
|
86
|
+
const next = normalizeCheckConfig({ ...this.checkConfig, ...config });
|
|
87
|
+
const changed = Object.keys(next)
|
|
88
|
+
.some((k) => next[k] !== this.checkConfig[k]);
|
|
89
|
+
this.checkConfig = next;
|
|
90
|
+
if (!changed)
|
|
91
|
+
return;
|
|
92
|
+
try {
|
|
93
|
+
this.store.kvSetSync(CHECK_CONFIG_KEY, next);
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
this.logger.warn({ error: err.message }, 'Failed to persist node check config');
|
|
97
|
+
}
|
|
98
|
+
this.logger.info({ config: next }, 'Node check config updated');
|
|
99
|
+
this.emit('checkConfig:changed', next);
|
|
42
100
|
}
|
|
43
101
|
getCheckConfig() {
|
|
44
102
|
return { ...this.checkConfig };
|
|
45
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Tell the service how history is kept, so the console can be told too.
|
|
106
|
+
*
|
|
107
|
+
* `uptimeIntervalMs` was declared in the daemon config, documented, given a
|
|
108
|
+
* default — and read by nothing. The console used a constant of its own,
|
|
109
|
+
* and no caller anywhere could have discovered the retention window that
|
|
110
|
+
* bounds what the bars can show.
|
|
111
|
+
*/
|
|
112
|
+
setHistoryConfig(config) {
|
|
113
|
+
if (Number.isFinite(config.uptimeIntervalMs)) {
|
|
114
|
+
this.historyConfig.uptimeIntervalMs = config.uptimeIntervalMs;
|
|
115
|
+
}
|
|
116
|
+
if (Number.isFinite(config.retentionDays)) {
|
|
117
|
+
this.historyConfig.retentionDays = config.retentionDays;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
getHistoryConfig() {
|
|
121
|
+
return { ...this.historyConfig };
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* The master's mesh, so a check asks a node's daemon over the connection
|
|
125
|
+
* the master already holds to it.
|
|
126
|
+
*
|
|
127
|
+
* Without it this service could only dial `tcp://<host>:<daemonPort>`, and
|
|
128
|
+
* a hardened node's daemon port is closed to the master — that is why the
|
|
129
|
+
* mesh tunnels over SSH. Measured 2026-09-23 with the health worker
|
|
130
|
+
* detached: `omnitron node check` on sample-test printed `Omnitron: ○
|
|
131
|
+
* offline` / `Connection timeout to tcp://37.27.130.185:9700` while the
|
|
132
|
+
* mesh held that node `connected via ssh-tunnel, authenticated` and
|
|
133
|
+
* `fleet status` read six apps from it through that connection. The
|
|
134
|
+
* comment above the probe said the SlaveConnector was asked first; the
|
|
135
|
+
* code never asked it.
|
|
136
|
+
*/
|
|
137
|
+
setSlaveConnector(connector) {
|
|
138
|
+
this.mesh = connector;
|
|
139
|
+
}
|
|
46
140
|
// ===========================================================================
|
|
47
141
|
// CRUD
|
|
48
142
|
// ===========================================================================
|
|
49
143
|
listNodes() {
|
|
50
144
|
return Array.from(this.nodes.values()).map((node) => ({
|
|
51
|
-
...node,
|
|
52
|
-
status: this.
|
|
145
|
+
...toWireNode(node),
|
|
146
|
+
status: this.statusFor(node.id),
|
|
53
147
|
}));
|
|
54
148
|
}
|
|
55
149
|
getNode(id) {
|
|
56
150
|
const node = this.nodes.get(id);
|
|
57
151
|
if (!node)
|
|
58
152
|
return null;
|
|
59
|
-
return { ...node, status: this.
|
|
153
|
+
return { ...toWireNode(node), status: this.statusFor(id) };
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Status for one node.
|
|
157
|
+
*
|
|
158
|
+
* For the local node the facts about this daemon — version, pid, uptime,
|
|
159
|
+
* role — are read from `process` on every call. They used to be written
|
|
160
|
+
* once into the cache in the constructor, so `omnitronUptime` was whatever
|
|
161
|
+
* `process.uptime()` returned a few milliseconds into boot, and the
|
|
162
|
+
* console renders that as "Uptime": a handful of seconds, however long the
|
|
163
|
+
* daemon had been up.
|
|
164
|
+
*
|
|
165
|
+
* The health-monitor worker also checks the local node, and what it
|
|
166
|
+
* reports is not worthless — whether sshd answers on loopback is a real
|
|
167
|
+
* check, and it is the only source for `checkedAt`, which dates the
|
|
168
|
+
* reachability reading rather than this call. So the worker's status is
|
|
169
|
+
* kept and only the fields the daemon knows first-hand are overwritten.
|
|
170
|
+
* Neither source is discarded, because neither one is redundant.
|
|
171
|
+
*/
|
|
172
|
+
statusFor(id) {
|
|
173
|
+
if (id !== LOCAL_NODE_ID)
|
|
174
|
+
return this.statusCache.get(id) ?? null;
|
|
175
|
+
const live = this.localStatus();
|
|
176
|
+
const checked = this.statusCache.get(LOCAL_NODE_ID);
|
|
177
|
+
if (!checked)
|
|
178
|
+
return live;
|
|
179
|
+
const merged = { ...checked, omnitronConnected: true };
|
|
180
|
+
// Assigned rather than spread: the fields are optional under
|
|
181
|
+
// `exactOptionalPropertyTypes`, so writing `undefined` into them is a
|
|
182
|
+
// different thing from leaving them out.
|
|
183
|
+
if (live.omnitronVersion !== undefined)
|
|
184
|
+
merged.omnitronVersion = live.omnitronVersion;
|
|
185
|
+
if (live.omnitronPid !== undefined)
|
|
186
|
+
merged.omnitronPid = live.omnitronPid;
|
|
187
|
+
if (live.omnitronUptime !== undefined)
|
|
188
|
+
merged.omnitronUptime = live.omnitronUptime;
|
|
189
|
+
if (live.omnitronRole !== undefined)
|
|
190
|
+
merged.omnitronRole = live.omnitronRole;
|
|
191
|
+
return merged;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* One row per daemon.
|
|
195
|
+
*
|
|
196
|
+
* `host` plus `daemonPort` names a DAEMON, and two registry rows naming
|
|
197
|
+
* the same one are always a mistake — there is no second thing there to
|
|
198
|
+
* manage. Two daemons on one machine are two ports, and those are still
|
|
199
|
+
* allowed.
|
|
200
|
+
*
|
|
201
|
+
* It was worth every cost it caused, all measured on one machine that had
|
|
202
|
+
* been registered twice:
|
|
203
|
+
*
|
|
204
|
+
* - the health monitor checked it on both rows, 120 connections an hour
|
|
205
|
+
* to one socket;
|
|
206
|
+
* - `fleet upgrade` transferred and installed the bundle to it twice;
|
|
207
|
+
* - the mesh holds one connection per ADDRESS, so exactly one of the two
|
|
208
|
+
* rows receives the node's data and the other reads "not joined"
|
|
209
|
+
* forever — and which one is arbitrary.
|
|
210
|
+
*
|
|
211
|
+
* Refused rather than merged: the existing row may carry credentials,
|
|
212
|
+
* tags and history, and picking which of two to keep is the operator's
|
|
213
|
+
* call, not this function's.
|
|
214
|
+
*/
|
|
215
|
+
assertAddressIsFree(host, daemonPort, exceptId) {
|
|
216
|
+
for (const existing of this.nodes.values()) {
|
|
217
|
+
if (existing.id === exceptId)
|
|
218
|
+
continue;
|
|
219
|
+
if (existing.host !== host || existing.daemonPort !== daemonPort)
|
|
220
|
+
continue;
|
|
221
|
+
throw new Error(`${host}:${daemonPort} is already registered as "${existing.name}". ` +
|
|
222
|
+
'One row per daemon — edit that node, or give this one a different daemon port.');
|
|
223
|
+
}
|
|
60
224
|
}
|
|
61
225
|
async addNode(input) {
|
|
62
226
|
const id = randomUUID();
|
|
@@ -64,19 +228,25 @@ export class NodeManagerService extends EventEmitter {
|
|
|
64
228
|
const node = {
|
|
65
229
|
id,
|
|
66
230
|
name: input.name,
|
|
67
|
-
host:
|
|
68
|
-
|
|
231
|
+
// A host is not free text: it is spelled into an SSH target and into
|
|
232
|
+
// the argument list of `ping`. Rejected at the WRITE so a stored value
|
|
233
|
+
// cannot surprise a reader downstream.
|
|
234
|
+
host: assertNodeHost(input.host),
|
|
235
|
+
sshPort: assertPort('SSH port', input.sshPort ?? 22),
|
|
69
236
|
sshUser: input.sshUser ?? 'root',
|
|
70
237
|
sshAuthMethod: input.sshAuthMethod ?? 'key',
|
|
71
238
|
...(input.sshPrivateKey && { sshPrivateKey: input.sshPrivateKey }),
|
|
72
239
|
runtime: input.runtime ?? 'node',
|
|
73
|
-
daemonPort: input.daemonPort ?? 9700,
|
|
240
|
+
daemonPort: assertPort('daemon port', input.daemonPort ?? 9700),
|
|
74
241
|
tags: input.tags ?? [],
|
|
75
242
|
isLocal: false,
|
|
76
243
|
createdAt: now,
|
|
77
244
|
updatedAt: now,
|
|
78
245
|
...(input.offlineTimeout != null && { offlineTimeout: input.offlineTimeout }),
|
|
79
246
|
};
|
|
247
|
+
if (!node.name.trim())
|
|
248
|
+
throw new Error('Node name is required');
|
|
249
|
+
this.assertAddressIsFree(node.host, node.daemonPort);
|
|
80
250
|
// Store secrets encrypted (passphrase, password) — only boolean markers in nodes.json.
|
|
81
251
|
// Must await before connectivity check, otherwise getSecret() reads stale file.
|
|
82
252
|
if (input.sshPassphrase) {
|
|
@@ -91,8 +261,14 @@ export class NodeManagerService extends EventEmitter {
|
|
|
91
261
|
this.save();
|
|
92
262
|
this.emit('node:added', node);
|
|
93
263
|
this.logger.info({ nodeId: id, name: node.name, host: node.host }, 'Node added');
|
|
94
|
-
// Check connectivity in background — secrets are already persisted
|
|
95
|
-
|
|
264
|
+
// Check connectivity in background — secrets are already persisted.
|
|
265
|
+
// `checkNodeStatus` records an unreachable host in the status it returns
|
|
266
|
+
// rather than throwing, so anything arriving here is a fault in the probe
|
|
267
|
+
// itself, and swallowing it leaves the node "unchecked" for ever with
|
|
268
|
+
// nothing to explain why.
|
|
269
|
+
void this.checkNodeStatus(id).catch((err) => {
|
|
270
|
+
this.logger.warn({ nodeId: id, err }, 'Connectivity check failed to run');
|
|
271
|
+
});
|
|
96
272
|
return node;
|
|
97
273
|
}
|
|
98
274
|
async updateNode(id, input) {
|
|
@@ -103,6 +279,12 @@ export class NodeManagerService extends EventEmitter {
|
|
|
103
279
|
throw new Error('Cannot change host of local node');
|
|
104
280
|
// Extract secrets before spreading into node (they must not be saved to nodes.json)
|
|
105
281
|
const { sshPassphrase, sshPassword, ...safeInput } = input;
|
|
282
|
+
if (safeInput.host !== undefined)
|
|
283
|
+
safeInput.host = assertNodeHost(safeInput.host);
|
|
284
|
+
if (safeInput.sshPort !== undefined)
|
|
285
|
+
safeInput.sshPort = assertPort('SSH port', safeInput.sshPort);
|
|
286
|
+
if (safeInput.daemonPort !== undefined)
|
|
287
|
+
safeInput.daemonPort = assertPort('daemon port', safeInput.daemonPort);
|
|
106
288
|
const updated = {
|
|
107
289
|
...node,
|
|
108
290
|
...safeInput,
|
|
@@ -111,6 +293,25 @@ export class NodeManagerService extends EventEmitter {
|
|
|
111
293
|
createdAt: node.createdAt,
|
|
112
294
|
updatedAt: new Date().toISOString(),
|
|
113
295
|
};
|
|
296
|
+
// An edit can collide as readily as an add — correcting one node's host
|
|
297
|
+
// to the address another already holds is exactly how a duplicate gets
|
|
298
|
+
// made. Checked before any secret is written, so a refused edit leaves
|
|
299
|
+
// nothing behind.
|
|
300
|
+
//
|
|
301
|
+
// Only when the edit MOVES the row. A registry that already holds two
|
|
302
|
+
// rows for one daemon — made before this rule existed — refused every
|
|
303
|
+
// edit to either of them, including the one that would have repaired it:
|
|
304
|
+
//
|
|
305
|
+
// omnitron node update <id> --ssh-auth password
|
|
306
|
+
// 37.27.130.185:9700 is already registered as "acme-deploy-test"
|
|
307
|
+
//
|
|
308
|
+
// The guard exists to stop a duplicate being CREATED. Refusing an edit
|
|
309
|
+
// that changes neither the host nor the port cannot prevent one, and it
|
|
310
|
+
// leaves an operator with a registry they can neither use nor mend.
|
|
311
|
+
const addressChanged = updated.host !== node.host || updated.daemonPort !== node.daemonPort;
|
|
312
|
+
if (addressChanged) {
|
|
313
|
+
this.assertAddressIsFree(updated.host, updated.daemonPort, id);
|
|
314
|
+
}
|
|
114
315
|
// Update encrypted secrets — await to ensure they're persisted before connectivity check
|
|
115
316
|
if (sshPassphrase !== undefined) {
|
|
116
317
|
if (sshPassphrase) {
|
|
@@ -132,26 +333,66 @@ export class NodeManagerService extends EventEmitter {
|
|
|
132
333
|
await this.deleteSecret(id, 'password');
|
|
133
334
|
}
|
|
134
335
|
}
|
|
336
|
+
// A credential that belongs to the other auth method is dead weight that
|
|
337
|
+
// still authenticates: leaving a stored password on a node switched to
|
|
338
|
+
// key auth means the console shows "SSH Key" while the daemon may log in
|
|
339
|
+
// with a password the operator believes they stopped using.
|
|
340
|
+
if (updated.sshAuthMethod !== node.sshAuthMethod) {
|
|
341
|
+
if (updated.sshAuthMethod === 'key' && updated.hasPassword) {
|
|
342
|
+
updated.hasPassword = false;
|
|
343
|
+
await this.deleteSecret(id, 'password');
|
|
344
|
+
}
|
|
345
|
+
if (updated.sshAuthMethod === 'password') {
|
|
346
|
+
delete updated.sshPrivateKey;
|
|
347
|
+
if (updated.hasPassphrase) {
|
|
348
|
+
updated.hasPassphrase = false;
|
|
349
|
+
await this.deleteSecret(id, 'passphrase');
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
135
353
|
this.nodes.set(id, updated);
|
|
136
354
|
this.save();
|
|
137
355
|
this.emit('node:updated', updated);
|
|
138
356
|
// Re-check connectivity after update
|
|
139
357
|
if (!updated.isLocal) {
|
|
140
|
-
void this.checkNodeStatus(id).catch(() => {
|
|
358
|
+
void this.checkNodeStatus(id).catch((err) => {
|
|
359
|
+
this.logger.warn({ nodeId: id, err }, 'Connectivity check failed to run');
|
|
360
|
+
});
|
|
141
361
|
}
|
|
142
362
|
return updated;
|
|
143
363
|
}
|
|
144
|
-
|
|
364
|
+
/**
|
|
365
|
+
* Remove a node from the registry.
|
|
366
|
+
*
|
|
367
|
+
* Deletes the ROW, not just the map entry. `save()` rewrites every node
|
|
368
|
+
* still held in memory, which is how the file-backed registry used to
|
|
369
|
+
* express a deletion — but an UPSERT-per-row store expresses it by
|
|
370
|
+
* deleting, and the row for a removed node stayed behind. The console
|
|
371
|
+
* reported the node gone, and the next daemon start read it back in.
|
|
372
|
+
*
|
|
373
|
+
* Secret deletion is awaited for the same reason: fired and forgotten, a
|
|
374
|
+
* failure left an SSH password in the vault under the id of a node nobody
|
|
375
|
+
* can see any more.
|
|
376
|
+
*/
|
|
377
|
+
async removeNode(id) {
|
|
145
378
|
const node = this.nodes.get(id);
|
|
146
379
|
if (!node)
|
|
147
380
|
throw new Error(`Node not found: ${id}`);
|
|
148
381
|
if (node.isLocal)
|
|
149
382
|
throw new Error('Cannot remove local node');
|
|
150
383
|
// Clean up encrypted secrets
|
|
151
|
-
|
|
152
|
-
|
|
384
|
+
await this.deleteSecret(id, 'passphrase');
|
|
385
|
+
await this.deleteSecret(id, 'password');
|
|
153
386
|
this.nodes.delete(id);
|
|
154
387
|
this.statusCache.delete(id);
|
|
388
|
+
this.summaryCache.delete(id);
|
|
389
|
+
try {
|
|
390
|
+
this.store.deleteNodeSync(id);
|
|
391
|
+
}
|
|
392
|
+
catch (err) {
|
|
393
|
+
this.logger.warn({ nodeId: id, error: err.message }, 'Failed to delete node row');
|
|
394
|
+
throw err;
|
|
395
|
+
}
|
|
155
396
|
this.save();
|
|
156
397
|
this.emit('node:removed', id);
|
|
157
398
|
this.logger.info({ nodeId: id, name: node.name }, 'Node removed');
|
|
@@ -185,25 +426,29 @@ export class NodeManagerService extends EventEmitter {
|
|
|
185
426
|
entry === 'authorized_keys') {
|
|
186
427
|
continue;
|
|
187
428
|
}
|
|
188
|
-
// Check if it looks like a private key (starts with -----BEGIN)
|
|
429
|
+
// Check if it looks like a private key (starts with -----BEGIN).
|
|
430
|
+
// Read the HEADER, not the file: this walks a directory of private
|
|
431
|
+
// keys, and `readFileSync(...).slice(0, 100)` pulled every byte of
|
|
432
|
+
// every one of them into the daemon's heap to look at the first line.
|
|
433
|
+
let head;
|
|
189
434
|
try {
|
|
190
|
-
|
|
191
|
-
if (head.includes('-----BEGIN') && head.includes('KEY')) {
|
|
192
|
-
// Detect key type from header
|
|
193
|
-
let type = 'unknown';
|
|
194
|
-
if (head.includes('RSA'))
|
|
195
|
-
type = 'rsa';
|
|
196
|
-
else if (head.includes('EC'))
|
|
197
|
-
type = 'ecdsa';
|
|
198
|
-
else if (head.includes('OPENSSH'))
|
|
199
|
-
type = 'ed25519';
|
|
200
|
-
else if (head.includes('DSA'))
|
|
201
|
-
type = 'dsa';
|
|
202
|
-
keys.push({ name: entry, path: fullPath, type });
|
|
203
|
-
}
|
|
435
|
+
head = readFileHead(fullPath, 100);
|
|
204
436
|
}
|
|
205
437
|
catch {
|
|
206
|
-
// Can't read — skip
|
|
438
|
+
continue; // Can't read — skip
|
|
439
|
+
}
|
|
440
|
+
if (head.includes('-----BEGIN') && head.includes('KEY')) {
|
|
441
|
+
// Detect key type from header
|
|
442
|
+
let type = 'unknown';
|
|
443
|
+
if (head.includes('RSA'))
|
|
444
|
+
type = 'rsa';
|
|
445
|
+
else if (head.includes('EC'))
|
|
446
|
+
type = 'ecdsa';
|
|
447
|
+
else if (head.includes('OPENSSH'))
|
|
448
|
+
type = 'ed25519';
|
|
449
|
+
else if (head.includes('DSA'))
|
|
450
|
+
type = 'dsa';
|
|
451
|
+
keys.push({ name: entry, path: fullPath, type });
|
|
207
452
|
}
|
|
208
453
|
}
|
|
209
454
|
return keys;
|
|
@@ -219,7 +464,9 @@ export class NodeManagerService extends EventEmitter {
|
|
|
219
464
|
nodeId: id,
|
|
220
465
|
pingReachable: false,
|
|
221
466
|
pingLatencyMs: null,
|
|
222
|
-
|
|
467
|
+
// Not `false`: this check does not open an SSH session at all, and
|
|
468
|
+
// `false` reads as "SSH was refused" everywhere it is consumed.
|
|
469
|
+
sshConnected: null,
|
|
223
470
|
sshLatencyMs: null,
|
|
224
471
|
omnitronConnected: false,
|
|
225
472
|
checkedAt: new Date().toISOString(),
|
|
@@ -234,22 +481,18 @@ export class NodeManagerService extends EventEmitter {
|
|
|
234
481
|
status.omnitronPid = process.pid;
|
|
235
482
|
status.omnitronUptime = process.uptime() * 1000;
|
|
236
483
|
status.omnitronRole = 'master';
|
|
484
|
+
status.omnitronVersion = CLI_VERSION;
|
|
237
485
|
status.os = {
|
|
238
486
|
platform: os.platform(),
|
|
239
487
|
arch: os.arch(),
|
|
240
488
|
hostname: os.hostname(),
|
|
241
489
|
release: os.release(),
|
|
242
490
|
};
|
|
243
|
-
try {
|
|
244
|
-
const { CLI_VERSION } = await import('../config/defaults.js');
|
|
245
|
-
status.omnitronVersion = CLI_VERSION;
|
|
246
|
-
}
|
|
247
|
-
catch {
|
|
248
|
-
status.omnitronVersion = '0.1.0';
|
|
249
|
-
}
|
|
250
491
|
}
|
|
251
492
|
else {
|
|
252
|
-
// Remote node — ping
|
|
493
|
+
// Remote node — ping, then the daemon itself (no SSH — SSH is
|
|
494
|
+
// manual-only via UI, and the health worker's round is the one that
|
|
495
|
+
// opens a session).
|
|
253
496
|
// 1. Ping (ICMP) — lightweight reachability check
|
|
254
497
|
if (this.checkConfig.pingEnabled) {
|
|
255
498
|
const ping = await this.remoteOps.ping(node.host, this.checkConfig.pingTimeout);
|
|
@@ -262,47 +505,92 @@ export class NodeManagerService extends EventEmitter {
|
|
|
262
505
|
status.pingReachable = true;
|
|
263
506
|
status.pingLatencyMs = null;
|
|
264
507
|
}
|
|
265
|
-
// 2.
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
const port = node.daemonPort ?? 9700;
|
|
269
|
-
try {
|
|
270
|
-
const { Netron } = await import('@omnitron-dev/titan/netron');
|
|
271
|
-
const { TcpTransport } = await import('@omnitron-dev/titan/netron/transport/tcp');
|
|
272
|
-
const { createNullLogger } = await import('@omnitron-dev/titan/module/logger');
|
|
273
|
-
const probeNetron = new Netron(createNullLogger(), { id: `probe-${node.host}` });
|
|
274
|
-
probeNetron.registerTransport('tcp', () => new TcpTransport());
|
|
275
|
-
const connectStart = Date.now();
|
|
276
|
-
const peer = await Promise.race([
|
|
277
|
-
probeNetron.connect(`tcp://${node.host}:${port}`, false),
|
|
278
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), this.checkConfig.omnitronCheckTimeout)),
|
|
279
|
-
]);
|
|
280
|
-
// Ping via OmnitronDaemon service
|
|
281
|
-
const daemon = await peer.queryInterface('OmnitronDaemon');
|
|
282
|
-
const info = await daemon.ping();
|
|
283
|
-
const latency = Date.now() - connectStart;
|
|
508
|
+
// 2. The daemon: asked over the mesh first, dialled directly second.
|
|
509
|
+
const answer = await this.askDaemon(node);
|
|
510
|
+
if (answer.ok) {
|
|
284
511
|
status.omnitronConnected = true;
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
if (info?.
|
|
288
|
-
status.
|
|
289
|
-
if (info?.
|
|
290
|
-
status.
|
|
291
|
-
if (info?.uptime)
|
|
292
|
-
status.omnitronUptime = info.uptime;
|
|
293
|
-
this.logger.debug({ node: node.name, host: node.host, latencyMs: latency, version: info?.version }, 'Node check: Netron TCP ping OK');
|
|
294
|
-
// Disconnect probe — SlaveConnector manages persistent connections
|
|
295
|
-
await probeNetron.stop();
|
|
512
|
+
if (answer.info?.version)
|
|
513
|
+
status.omnitronVersion = answer.info.version;
|
|
514
|
+
if (answer.info?.pid)
|
|
515
|
+
status.omnitronPid = answer.info.pid;
|
|
516
|
+
if (answer.info?.uptime)
|
|
517
|
+
status.omnitronUptime = answer.info.uptime;
|
|
296
518
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
519
|
+
else {
|
|
520
|
+
// `null`, not `false`. Neither path reached the daemon, and that says
|
|
521
|
+
// nothing about whether it runs: a closed daemon port is the normal
|
|
522
|
+
// state of a hardened node, and a mesh link can be down while every
|
|
523
|
+
// app on the node serves. `false` reads as "the daemon is down" to
|
|
524
|
+
// every consumer — `node list`, `node check`, the console's dot —
|
|
525
|
+
// and that is the claim this check had no evidence for. The reasons
|
|
526
|
+
// travel in `omnitronError`, each naming its path.
|
|
527
|
+
status.omnitronConnected = null;
|
|
528
|
+
status.omnitronError = `Neither path reached the daemon — ${answer.reasons.join('; ')}`;
|
|
300
529
|
}
|
|
301
530
|
}
|
|
302
|
-
this.
|
|
303
|
-
this.emit('node:status', id, status);
|
|
531
|
+
this.recordStatus(node, status);
|
|
304
532
|
return status;
|
|
305
533
|
}
|
|
534
|
+
/**
|
|
535
|
+
* Ask a node's daemon to answer `ping`, the way the master can reach it.
|
|
536
|
+
*
|
|
537
|
+
* The mesh first: it is the connection the master already holds, and for
|
|
538
|
+
* a node whose daemon port is firewalled it is the only one that works —
|
|
539
|
+
* over an SSH tunnel. The direct dial second, for a node outside the mesh
|
|
540
|
+
* (just added, or on a master whose mesh did not start) whose port IS open.
|
|
541
|
+
* Each failure is kept with the name of its path, because «connection
|
|
542
|
+
* timeout» alone does not say which door was shut.
|
|
543
|
+
*/
|
|
544
|
+
async askDaemon(node) {
|
|
545
|
+
const port = node.daemonPort ?? 9700;
|
|
546
|
+
const reasons = [];
|
|
547
|
+
if (this.mesh) {
|
|
548
|
+
try {
|
|
549
|
+
const info = (await withTimeout(this.mesh.invokeOnSlave(node.host, port, 'OmnitronDaemon', 'ping', []), this.checkConfig.omnitronCheckTimeout));
|
|
550
|
+
this.logger.debug({ node: node.name, host: node.host, version: info?.version }, 'Node check: daemon answered over the mesh');
|
|
551
|
+
return { ok: true, via: 'mesh', info };
|
|
552
|
+
}
|
|
553
|
+
catch (err) {
|
|
554
|
+
reasons.push(`mesh: ${err.message}`);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
reasons.push('mesh: this daemon has no mesh connector');
|
|
559
|
+
}
|
|
560
|
+
let probeNetron = null;
|
|
561
|
+
try {
|
|
562
|
+
const { Netron } = await import('@omnitron-dev/titan/netron');
|
|
563
|
+
const { TcpTransport } = await import('@omnitron-dev/titan/netron/transport/tcp');
|
|
564
|
+
const { createNullLogger } = await import('@omnitron-dev/titan/module/logger');
|
|
565
|
+
const probe = new Netron(createNullLogger(), { id: `probe-${node.host}` });
|
|
566
|
+
probeNetron = probe;
|
|
567
|
+
probe.registerTransport('tcp', () => new TcpTransport());
|
|
568
|
+
const connectStart = Date.now();
|
|
569
|
+
const peer = await withTimeout(probe.connect(`tcp://${node.host}:${port}`, false), this.checkConfig.omnitronCheckTimeout);
|
|
570
|
+
// Ping via OmnitronDaemon service
|
|
571
|
+
const daemon = await peer.queryInterface('OmnitronDaemon');
|
|
572
|
+
const info = await daemon.ping();
|
|
573
|
+
this.logger.debug({ node: node.name, host: node.host, latencyMs: Date.now() - connectStart, version: info?.version }, 'Node check: daemon answered a direct dial');
|
|
574
|
+
return { ok: true, via: 'direct', info };
|
|
575
|
+
}
|
|
576
|
+
catch (err) {
|
|
577
|
+
reasons.push(`direct dial to ${node.host}:${port}: ${err.message}`);
|
|
578
|
+
this.logger.debug({ node: node.name, host: node.host, port, reasons }, 'Node check: no path reached the daemon');
|
|
579
|
+
return { ok: false, reasons };
|
|
580
|
+
}
|
|
581
|
+
finally {
|
|
582
|
+
// Stop the probe on EVERY path. It only ran on success, so each
|
|
583
|
+
// failed check — the common case for an offline node, once a minute,
|
|
584
|
+
// for ever — left a Netron instance with a registered TCP transport
|
|
585
|
+
// behind in the daemon.
|
|
586
|
+
if (probeNetron) {
|
|
587
|
+
try {
|
|
588
|
+
await probeNetron.stop();
|
|
589
|
+
}
|
|
590
|
+
catch { /* the probe is being discarded either way */ }
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
}
|
|
306
594
|
/** Convert node to SSH target — used for manual SSH checks from UI */
|
|
307
595
|
async nodeToSshTarget(node) {
|
|
308
596
|
const target = {
|
|
@@ -325,16 +613,73 @@ export class NodeManagerService extends EventEmitter {
|
|
|
325
613
|
}
|
|
326
614
|
return target;
|
|
327
615
|
}
|
|
616
|
+
/**
|
|
617
|
+
* Convert a registered node into something the deployer can reach.
|
|
618
|
+
*
|
|
619
|
+
* The bridge between the two registries. An operator registers machines
|
|
620
|
+
* here, in the console; deployment reads `stacks.nodes` out of a project
|
|
621
|
+
* config. Nothing joined them, which is half of why a machine added in the
|
|
622
|
+
* console could not be deployed to — the other half being that the deployer
|
|
623
|
+
* could not have used this node's credentials even if it had been handed
|
|
624
|
+
* one: it shelled out to `ssh -o BatchMode=yes`, and what this method
|
|
625
|
+
* returns is a password.
|
|
626
|
+
*
|
|
627
|
+
* The credentials come from `nodeToSshTarget`, which the manual SSH check
|
|
628
|
+
* already uses, so there is one place that knows how to unlock a node and
|
|
629
|
+
* both callers use it.
|
|
630
|
+
*/
|
|
631
|
+
async nodeToDeployTarget(id) {
|
|
632
|
+
const node = this.nodes.get(id);
|
|
633
|
+
if (!node)
|
|
634
|
+
throw new Error(`Node not found: ${id}`);
|
|
635
|
+
if (node.isLocal) {
|
|
636
|
+
// Not a refusal on principle — a local daemon is deployed to by running
|
|
637
|
+
// omnitron, not by SSHing to yourself — but a refusal that says so,
|
|
638
|
+
// rather than a loopback SSH that fails for a reason the operator then
|
|
639
|
+
// has to work out.
|
|
640
|
+
throw new Error('The local node is this daemon; it is not deployed to over SSH.');
|
|
641
|
+
}
|
|
642
|
+
const ssh = await this.nodeToSshTarget(node);
|
|
643
|
+
const target = {
|
|
644
|
+
host: ssh.host,
|
|
645
|
+
label: node.name,
|
|
646
|
+
daemonPort: node.daemonPort ?? 9700,
|
|
647
|
+
};
|
|
648
|
+
if (ssh.port != null)
|
|
649
|
+
target.sshPort = ssh.port;
|
|
650
|
+
if (ssh.username)
|
|
651
|
+
target.username = ssh.username;
|
|
652
|
+
if (ssh.privateKey)
|
|
653
|
+
target.privateKey = ssh.privateKey;
|
|
654
|
+
if (ssh.passphrase)
|
|
655
|
+
target.passphrase = ssh.passphrase;
|
|
656
|
+
if (ssh.password)
|
|
657
|
+
target.password = ssh.password;
|
|
658
|
+
return target;
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Check every node.
|
|
662
|
+
*
|
|
663
|
+
* Concurrent, bounded by the same `concurrency` the worker uses. It was a
|
|
664
|
+
* `for` loop with an `await` in it, so a fleet of twenty nodes with one
|
|
665
|
+
* unreachable host took the ping timeout plus the TCP timeout SERIALLY —
|
|
666
|
+
* twenty seconds of a thirty-second check interval spent on one node.
|
|
667
|
+
*/
|
|
328
668
|
async checkAllNodes() {
|
|
669
|
+
const ids = Array.from(this.nodes.keys());
|
|
329
670
|
const results = [];
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
671
|
+
const width = Math.max(1, this.checkConfig.concurrency);
|
|
672
|
+
for (let i = 0; i < ids.length; i += width) {
|
|
673
|
+
const batch = ids.slice(i, i + width);
|
|
674
|
+
const settled = await Promise.allSettled(batch.map((id) => this.checkNodeStatus(id)));
|
|
675
|
+
settled.forEach((r, idx) => {
|
|
676
|
+
if (r.status === 'fulfilled') {
|
|
677
|
+
results.push(r.value);
|
|
678
|
+
}
|
|
679
|
+
else {
|
|
680
|
+
this.logger.warn({ nodeId: batch[idx], error: r.reason?.message }, 'Failed to check node');
|
|
681
|
+
}
|
|
682
|
+
});
|
|
338
683
|
}
|
|
339
684
|
return results;
|
|
340
685
|
}
|
|
@@ -344,11 +689,19 @@ export class NodeManagerService extends EventEmitter {
|
|
|
344
689
|
/**
|
|
345
690
|
* Update the in-memory status cache from health-monitor worker summaries.
|
|
346
691
|
* Called by daemon when worker sends IPC status batch.
|
|
692
|
+
*
|
|
693
|
+
* Only for nodes the registry holds. The worker's batch is its own memory,
|
|
694
|
+
* and it can name a node this registry removed — it did, every minute, for
|
|
695
|
+
* a node removed 82 minutes earlier — and writing that back put a status
|
|
696
|
+
* with no node behind it into `statusCache`, `summaryCache` and the
|
|
697
|
+
* heartbeat column of a row that no longer exists.
|
|
347
698
|
*/
|
|
348
699
|
updateStatusCacheFromWorker(summaries) {
|
|
349
700
|
for (const summary of summaries) {
|
|
350
701
|
if (!summary.lastCheck)
|
|
351
702
|
continue;
|
|
703
|
+
if (!this.nodes.has(summary.nodeId))
|
|
704
|
+
continue;
|
|
352
705
|
const check = summary.lastCheck;
|
|
353
706
|
const status = {
|
|
354
707
|
nodeId: summary.nodeId,
|
|
@@ -377,7 +730,38 @@ export class NodeManagerService extends EventEmitter {
|
|
|
377
730
|
status.omnitronError = check.omnitronError;
|
|
378
731
|
this.statusCache.set(summary.nodeId, status);
|
|
379
732
|
this.emit('node:status', summary.nodeId, status);
|
|
733
|
+
this.setSummary(summary);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
/**
|
|
737
|
+
* Aggregated health, for a daemon serving checks without the worker.
|
|
738
|
+
*
|
|
739
|
+
* `triggerNodeCheck` used to return `[]` when the worker was absent, and an
|
|
740
|
+
* empty array on a page whose subject is the fleet reads as "no nodes".
|
|
741
|
+
*/
|
|
742
|
+
getHealthSummaries(nodeId) {
|
|
743
|
+
if (nodeId) {
|
|
744
|
+
const one = this.summaryCache.get(nodeId);
|
|
745
|
+
return one ? [one] : [];
|
|
380
746
|
}
|
|
747
|
+
return Array.from(this.summaryCache.values());
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* Note that one call to the health worker failed.
|
|
751
|
+
*
|
|
752
|
+
* Called by the RPC layer when a worker call throws. The call is served
|
|
753
|
+
* from the daemon instead; the worker keeps its proxy — a process that has
|
|
754
|
+
* gone is noticed by its exit handler, not guessed from one error. This
|
|
755
|
+
* exists so the reason appears in the daemon's log rather than only in the
|
|
756
|
+
* error text of whichever console button was pressed.
|
|
757
|
+
*/
|
|
758
|
+
reportWorkerUnavailable(method, err) {
|
|
759
|
+
this.logger.warn({ method, error: err.message }, 'Health monitor worker did not answer this call — serving it from the daemon');
|
|
760
|
+
this.emit('worker:unavailable', method, err);
|
|
761
|
+
}
|
|
762
|
+
/** Report a non-fatal failure in node bookkeeping, with the reason. */
|
|
763
|
+
reportProblem(operation, err) {
|
|
764
|
+
this.logger.warn({ operation, error: err.message }, 'Node maintenance step failed');
|
|
381
765
|
}
|
|
382
766
|
/**
|
|
383
767
|
* Convert current node list to serializable check targets for the worker.
|
|
@@ -423,7 +807,8 @@ export class NodeManagerService extends EventEmitter {
|
|
|
423
807
|
secretKey(nodeId, field) {
|
|
424
808
|
return `node:${nodeId}:${field}`;
|
|
425
809
|
}
|
|
426
|
-
|
|
810
|
+
/** The vault's own answer, with no in-memory fallback. */
|
|
811
|
+
async readVault(nodeId, field) {
|
|
427
812
|
if (!this.secrets)
|
|
428
813
|
return null;
|
|
429
814
|
try {
|
|
@@ -433,6 +818,18 @@ export class NodeManagerService extends EventEmitter {
|
|
|
433
818
|
return null;
|
|
434
819
|
}
|
|
435
820
|
}
|
|
821
|
+
async getSecret(nodeId, field) {
|
|
822
|
+
const key = this.secretKey(nodeId, field);
|
|
823
|
+
if (this.secrets) {
|
|
824
|
+
try {
|
|
825
|
+
const stored = await this.secrets.get(key);
|
|
826
|
+
if (stored)
|
|
827
|
+
return stored;
|
|
828
|
+
}
|
|
829
|
+
catch { /* fall through to the pending value, if any */ }
|
|
830
|
+
}
|
|
831
|
+
return this.pendingSecrets.get(key) ?? null;
|
|
832
|
+
}
|
|
436
833
|
async setSecret(nodeId, field, value) {
|
|
437
834
|
if (!this.secrets) {
|
|
438
835
|
this.logger.warn({ nodeId, field }, 'SecretsService not available — secret not stored');
|
|
@@ -449,18 +846,26 @@ export class NodeManagerService extends EventEmitter {
|
|
|
449
846
|
catch { /* non-critical */ }
|
|
450
847
|
}
|
|
451
848
|
/**
|
|
452
|
-
*
|
|
453
|
-
*
|
|
849
|
+
* Status of the machine this daemon runs on.
|
|
850
|
+
*
|
|
851
|
+
* We ARE the daemon — no RPC or socket needed, just read process info, and
|
|
852
|
+
* read it now rather than at construction. The version came from a string
|
|
853
|
+
* literal `'0.1.0'` while the package was at 0.2.0, so the fleet view
|
|
854
|
+
* reported a version the daemon has never been; it is `CLI_VERSION` now,
|
|
855
|
+
* the same source `omnitron status` uses.
|
|
856
|
+
*
|
|
857
|
+
* The role is `master` unconditionally, and that is correct rather than
|
|
858
|
+
* lazy: this service is only constructed on a non-slave daemon.
|
|
454
859
|
*/
|
|
455
|
-
|
|
456
|
-
|
|
860
|
+
localStatus() {
|
|
861
|
+
return {
|
|
457
862
|
nodeId: LOCAL_NODE_ID,
|
|
458
863
|
pingReachable: true,
|
|
459
864
|
pingLatencyMs: 0,
|
|
460
865
|
sshConnected: true,
|
|
461
866
|
sshLatencyMs: 0,
|
|
462
867
|
omnitronConnected: true,
|
|
463
|
-
omnitronVersion:
|
|
868
|
+
omnitronVersion: CLI_VERSION,
|
|
464
869
|
omnitronPid: process.pid,
|
|
465
870
|
omnitronUptime: process.uptime() * 1000,
|
|
466
871
|
omnitronRole: 'master',
|
|
@@ -471,34 +876,243 @@ export class NodeManagerService extends EventEmitter {
|
|
|
471
876
|
release: os.release(),
|
|
472
877
|
},
|
|
473
878
|
checkedAt: new Date().toISOString(),
|
|
879
|
+
};
|
|
880
|
+
}
|
|
881
|
+
// ===========================================================================
|
|
882
|
+
// Status bookkeeping
|
|
883
|
+
// ===========================================================================
|
|
884
|
+
/** Record a check this service performed, and derive its health summary. */
|
|
885
|
+
recordStatus(node, status) {
|
|
886
|
+
this.statusCache.set(node.id, status);
|
|
887
|
+
this.emit('node:status', node.id, status);
|
|
888
|
+
const previous = this.summaryCache.get(node.id);
|
|
889
|
+
const reachable = status.sshConnected || status.pingReachable || status.omnitronConnected;
|
|
890
|
+
const offlineTimeout = node.offlineTimeout ?? DEFAULT_OFFLINE_TIMEOUT_MS;
|
|
891
|
+
let health;
|
|
892
|
+
if (status.omnitronConnected) {
|
|
893
|
+
health = 'online';
|
|
894
|
+
}
|
|
895
|
+
else if (reachable) {
|
|
896
|
+
health = 'degraded';
|
|
897
|
+
}
|
|
898
|
+
else {
|
|
899
|
+
const lastSeen = previous?.lastSeenOnline;
|
|
900
|
+
health = lastSeen && Date.now() - Date.parse(lastSeen) < offlineTimeout ? 'degraded' : 'offline';
|
|
901
|
+
}
|
|
902
|
+
this.setSummary({
|
|
903
|
+
nodeId: node.id,
|
|
904
|
+
status: health,
|
|
905
|
+
lastCheck: {
|
|
906
|
+
nodeId: node.id,
|
|
907
|
+
checkedAt: status.checkedAt,
|
|
908
|
+
checkDurationMs: 0,
|
|
909
|
+
pingReachable: status.pingReachable,
|
|
910
|
+
pingLatencyMs: status.pingLatencyMs,
|
|
911
|
+
pingError: status.pingError ?? null,
|
|
912
|
+
sshConnected: status.sshConnected,
|
|
913
|
+
sshLatencyMs: status.sshLatencyMs,
|
|
914
|
+
sshError: status.sshError ?? null,
|
|
915
|
+
omnitronConnected: status.omnitronConnected,
|
|
916
|
+
omnitronVersion: status.omnitronVersion ?? null,
|
|
917
|
+
omnitronPid: status.omnitronPid ?? null,
|
|
918
|
+
omnitronUptime: status.omnitronUptime ?? null,
|
|
919
|
+
omnitronRole: status.omnitronRole ?? null,
|
|
920
|
+
omnitronError: status.omnitronError ?? null,
|
|
921
|
+
os: status.os ?? null,
|
|
922
|
+
},
|
|
923
|
+
lastSeenOnline: reachable ? status.checkedAt : (previous?.lastSeenOnline ?? null),
|
|
924
|
+
consecutiveFailures: reachable ? 0 : (previous?.consecutiveFailures ?? 0) + 1,
|
|
474
925
|
});
|
|
475
926
|
}
|
|
927
|
+
/**
|
|
928
|
+
* Store a summary, write it to the row, and announce a change of state.
|
|
929
|
+
*
|
|
930
|
+
* `nodes.status` and `nodes.last_heartbeat` are columns the schema declares,
|
|
931
|
+
* `selectNodesSync` reads back, and nothing ever wrote: every row on a live
|
|
932
|
+
* daemon said `status = 'unknown'` with a null heartbeat, because the only
|
|
933
|
+
* writer — `touchNodeHeartbeatSync` — had no callers. The upsert filled
|
|
934
|
+
* them with its own `'unknown'` default on every save.
|
|
935
|
+
*
|
|
936
|
+
* What this buys beyond tidiness: `lastSeenOnline` survives a daemon
|
|
937
|
+
* restart, so the offline grace period is measured from when the node was
|
|
938
|
+
* actually last seen rather than from boot.
|
|
939
|
+
*/
|
|
940
|
+
setSummary(summary) {
|
|
941
|
+
const previous = this.summaryCache.get(summary.nodeId) ?? null;
|
|
942
|
+
this.summaryCache.set(summary.nodeId, summary);
|
|
943
|
+
try {
|
|
944
|
+
this.store.touchNodeHeartbeatSync(summary.nodeId, summary.status, summary.lastCheck?.checkedAt ?? new Date().toISOString());
|
|
945
|
+
}
|
|
946
|
+
catch { /* the in-memory answer is still correct */ }
|
|
947
|
+
if (previous?.status === summary.status)
|
|
948
|
+
return;
|
|
949
|
+
const transition = {
|
|
950
|
+
nodeId: summary.nodeId,
|
|
951
|
+
status: summary.status,
|
|
952
|
+
previousStatus: previous?.status ?? null,
|
|
953
|
+
};
|
|
954
|
+
this.emit('node:health', transition);
|
|
955
|
+
}
|
|
476
956
|
// ===========================================================================
|
|
477
957
|
// Persistence
|
|
478
958
|
// ===========================================================================
|
|
479
959
|
load() {
|
|
960
|
+
/** Rows found carrying a plaintext secret; healed after the loop. */
|
|
961
|
+
const leaked = [];
|
|
480
962
|
try {
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
963
|
+
// First-pass: read from SQLite. Each row's `metadata` column
|
|
964
|
+
// holds the full INode JSON; the denormalised columns are for
|
|
965
|
+
// future queries (status filters, by-host lookups, etc.).
|
|
966
|
+
const rows = this.store.selectNodesSync();
|
|
967
|
+
for (const row of rows) {
|
|
968
|
+
if (!row.metadata)
|
|
969
|
+
continue;
|
|
970
|
+
try {
|
|
971
|
+
const raw = JSON.parse(row.metadata);
|
|
972
|
+
const { node, strays } = splitStoredSecrets(raw);
|
|
973
|
+
this.nodes.set(node.id, node);
|
|
974
|
+
if (strays.length > 0) {
|
|
975
|
+
for (const stray of strays)
|
|
976
|
+
this.pendingSecrets.set(this.secretKey(node.id, stray.field), stray.value);
|
|
977
|
+
leaked.push({ node, strays });
|
|
978
|
+
}
|
|
979
|
+
// Restore the last known health, but NOT a status reading: a
|
|
980
|
+
// reachability answer from a previous daemon is not a current one,
|
|
981
|
+
// and the console has no way to tell them apart on the dots. What
|
|
982
|
+
// is worth keeping is when the node was last up, which is what the
|
|
983
|
+
// offline grace period is measured against.
|
|
984
|
+
if (row.status && row.status !== 'unknown') {
|
|
985
|
+
this.summaryCache.set(node.id, {
|
|
986
|
+
nodeId: node.id,
|
|
987
|
+
status: row.status,
|
|
988
|
+
lastCheck: null,
|
|
989
|
+
lastSeenOnline: row.status === 'offline' ? null : row.last_heartbeat ?? null,
|
|
990
|
+
consecutiveFailures: 0,
|
|
991
|
+
});
|
|
486
992
|
}
|
|
487
993
|
}
|
|
994
|
+
catch {
|
|
995
|
+
// Corrupt row — skip and let the next mutation overwrite.
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
// One-shot legacy import. If the SQLite table is empty but the
|
|
999
|
+
// pre-T-7 nodes.json file exists, migrate it in-place. The
|
|
1000
|
+
// existing file is then unlinked so subsequent boots skip the
|
|
1001
|
+
// branch.
|
|
1002
|
+
if (this.nodes.size === 0 && fs.existsSync(NODES_FILE)) {
|
|
1003
|
+
try {
|
|
1004
|
+
const data = JSON.parse(fs.readFileSync(NODES_FILE, 'utf-8'));
|
|
1005
|
+
if (Array.isArray(data.nodes)) {
|
|
1006
|
+
for (const node of data.nodes) {
|
|
1007
|
+
this.nodes.set(node.id, node);
|
|
1008
|
+
this.persistNode(node);
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
try {
|
|
1012
|
+
fs.unlinkSync(NODES_FILE);
|
|
1013
|
+
}
|
|
1014
|
+
catch { /* best-effort */ }
|
|
1015
|
+
}
|
|
1016
|
+
catch (err) {
|
|
1017
|
+
this.logger.warn({ error: err.message }, 'Legacy nodes.json migration failed — leaving file in place');
|
|
1018
|
+
}
|
|
488
1019
|
}
|
|
489
1020
|
}
|
|
490
1021
|
catch (err) {
|
|
491
|
-
this.logger.warn({ error: err.message }, 'Failed to load nodes
|
|
1022
|
+
this.logger.warn({ error: err.message }, 'Failed to load nodes from store');
|
|
492
1023
|
}
|
|
1024
|
+
if (leaked.length > 0)
|
|
1025
|
+
void this.healLeakedSecrets(leaked);
|
|
1026
|
+
this.loadCheckConfig();
|
|
493
1027
|
}
|
|
494
|
-
|
|
1028
|
+
/**
|
|
1029
|
+
* Move a plaintext secret out of a node row and into the vault.
|
|
1030
|
+
*
|
|
1031
|
+
* Observed on a live daemon: a node row whose `metadata` JSON contained
|
|
1032
|
+
* `"sshPassphrase": "<the operator's actual passphrase>"` next to
|
|
1033
|
+
* `"hasPassphrase": true`. An older `updateNode` spread its whole input
|
|
1034
|
+
* into the node — the destructure that stops that was added afterwards, and
|
|
1035
|
+
* it fixed new writes without touching rows already written. `listNodes`
|
|
1036
|
+
* then spread the parsed row onto the wire, so the passphrase went to every
|
|
1037
|
+
* caller with the VIEWER role, and to `omnitron node list`.
|
|
1038
|
+
*
|
|
1039
|
+
* Two things are needed and they are not the same: the wire shape is now
|
|
1040
|
+
* built field by field (`toWireNode`), which stops the leak for any
|
|
1041
|
+
* residue, present or future; and this moves the value to where it should
|
|
1042
|
+
* have been, so the row itself stops holding it.
|
|
1043
|
+
*/
|
|
1044
|
+
async healLeakedSecrets(leaked) {
|
|
1045
|
+
for (const { node, strays } of leaked) {
|
|
1046
|
+
for (const { field, value } of strays) {
|
|
1047
|
+
this.logger.warn({ nodeId: node.id, field }, 'Node row held a plaintext SSH secret — moving it to the secret store');
|
|
1048
|
+
// Read the VAULT, not `getSecret`: that one falls back to
|
|
1049
|
+
// `pendingSecrets`, which is where this value already is — so asking
|
|
1050
|
+
// it whether the secret is stored answers "yes" about the copy we are
|
|
1051
|
+
// trying to store, and the write never happens.
|
|
1052
|
+
const existing = await this.readVault(node.id, field);
|
|
1053
|
+
if (!existing) {
|
|
1054
|
+
if (!this.secrets) {
|
|
1055
|
+
// Nothing to migrate into. The row keeps the value for now — the
|
|
1056
|
+
// node would otherwise stop authenticating — but it no longer
|
|
1057
|
+
// reaches the wire, which is the part that matters.
|
|
1058
|
+
this.logger.error({ nodeId: node.id, field }, 'No secret store available — plaintext secret left in the node row');
|
|
1059
|
+
continue;
|
|
1060
|
+
}
|
|
1061
|
+
await this.setSecret(node.id, field, value);
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
// Rewrite the row from the sanitised node.
|
|
1065
|
+
this.persistNode(node);
|
|
1066
|
+
for (const { field } of strays)
|
|
1067
|
+
this.pendingSecrets.delete(this.secretKey(node.id, field));
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
/** Restore the operator's check configuration, if one was ever set. */
|
|
1071
|
+
loadCheckConfig() {
|
|
495
1072
|
try {
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
1073
|
+
const stored = this.store.kvGetSync(CHECK_CONFIG_KEY);
|
|
1074
|
+
if (!stored)
|
|
1075
|
+
return;
|
|
1076
|
+
this.checkConfig = normalizeCheckConfig({ ...DEFAULT_CHECK_CONFIG, ...stored });
|
|
499
1077
|
}
|
|
500
1078
|
catch (err) {
|
|
501
|
-
this.logger.warn({ error: err.message }, 'Failed to
|
|
1079
|
+
this.logger.warn({ error: err.message }, 'Failed to load node check config — using defaults');
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
/**
|
|
1083
|
+
* Persist a single node to SQLite. Called on add / update /
|
|
1084
|
+
* status-touch. Pre-T-7 every mutation rewrote the entire
|
|
1085
|
+
* registry JSON file; now it's a single atomic UPSERT.
|
|
1086
|
+
*/
|
|
1087
|
+
persistNode(node) {
|
|
1088
|
+
try {
|
|
1089
|
+
// Carry the status forward. `upsertNodeSync` defaults it to `'unknown'`,
|
|
1090
|
+
// so a `save()` triggered by an unrelated edit used to erase what the
|
|
1091
|
+
// last check had established.
|
|
1092
|
+
const known = this.summaryCache.get(node.id);
|
|
1093
|
+
this.store.upsertNodeSync({
|
|
1094
|
+
id: node.id,
|
|
1095
|
+
name: node.name,
|
|
1096
|
+
host: node.host,
|
|
1097
|
+
port: node.daemonPort,
|
|
1098
|
+
role: node.isLocal ? 'master' : 'slave',
|
|
1099
|
+
status: known?.status ?? 'unknown',
|
|
1100
|
+
last_heartbeat: known?.lastCheck?.checkedAt ?? null,
|
|
1101
|
+
metadata: node,
|
|
1102
|
+
});
|
|
1103
|
+
}
|
|
1104
|
+
catch (err) {
|
|
1105
|
+
this.logger.warn({ id: node.id, error: err.message }, 'Failed to persist node');
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
/**
|
|
1109
|
+
* Persist every node currently held in memory. Used after a
|
|
1110
|
+
* batch mutation that affected multiple rows (the previous
|
|
1111
|
+
* fs.writeFileSync semantics).
|
|
1112
|
+
*/
|
|
1113
|
+
save() {
|
|
1114
|
+
for (const node of this.nodes.values()) {
|
|
1115
|
+
this.persistNode(node);
|
|
502
1116
|
}
|
|
503
1117
|
}
|
|
504
1118
|
ensureLocalNode() {
|
|
@@ -528,6 +1142,94 @@ export class NodeManagerService extends EventEmitter {
|
|
|
528
1142
|
// =============================================================================
|
|
529
1143
|
// Helpers
|
|
530
1144
|
// =============================================================================
|
|
1145
|
+
/**
|
|
1146
|
+
* The node as it may be sent to a caller.
|
|
1147
|
+
*
|
|
1148
|
+
* Built field by field on purpose. `listNodes` used to spread the object
|
|
1149
|
+
* parsed out of the `metadata` column, which means the payload was whatever
|
|
1150
|
+
* happened to have been written there — and on a live daemon that included
|
|
1151
|
+
* an SSH passphrase in plaintext. A DTO is a promise about what is returned;
|
|
1152
|
+
* spreading a JSON blob delegates that promise to whoever last wrote the row.
|
|
1153
|
+
*/
|
|
1154
|
+
function toWireNode(node) {
|
|
1155
|
+
const wire = {
|
|
1156
|
+
id: node.id,
|
|
1157
|
+
name: node.name,
|
|
1158
|
+
host: node.host,
|
|
1159
|
+
sshPort: node.sshPort,
|
|
1160
|
+
sshUser: node.sshUser,
|
|
1161
|
+
sshAuthMethod: node.sshAuthMethod,
|
|
1162
|
+
runtime: node.runtime,
|
|
1163
|
+
daemonPort: node.daemonPort,
|
|
1164
|
+
tags: node.tags ?? [],
|
|
1165
|
+
isLocal: node.isLocal,
|
|
1166
|
+
createdAt: node.createdAt,
|
|
1167
|
+
updatedAt: node.updatedAt,
|
|
1168
|
+
};
|
|
1169
|
+
// The key is a PATH or key content chosen by the operator; the booleans say
|
|
1170
|
+
// only whether a secret exists. Neither is a secret itself.
|
|
1171
|
+
if (node.sshPrivateKey !== undefined)
|
|
1172
|
+
wire.sshPrivateKey = node.sshPrivateKey;
|
|
1173
|
+
if (node.hasPassphrase !== undefined)
|
|
1174
|
+
wire.hasPassphrase = node.hasPassphrase;
|
|
1175
|
+
if (node.hasPassword !== undefined)
|
|
1176
|
+
wire.hasPassword = node.hasPassword;
|
|
1177
|
+
if (node.offlineTimeout !== undefined)
|
|
1178
|
+
wire.offlineTimeout = node.offlineTimeout;
|
|
1179
|
+
return wire;
|
|
1180
|
+
}
|
|
1181
|
+
/** Separate a stored node from any plaintext secret its row still carries. */
|
|
1182
|
+
function splitStoredSecrets(raw) {
|
|
1183
|
+
const { sshPassphrase, sshPassword, ...rest } = raw;
|
|
1184
|
+
const node = rest;
|
|
1185
|
+
const strays = [];
|
|
1186
|
+
if (typeof sshPassphrase === 'string' && sshPassphrase) {
|
|
1187
|
+
node.hasPassphrase = true;
|
|
1188
|
+
strays.push({ field: 'passphrase', value: sshPassphrase });
|
|
1189
|
+
}
|
|
1190
|
+
if (typeof sshPassword === 'string' && sshPassword) {
|
|
1191
|
+
node.hasPassword = true;
|
|
1192
|
+
strays.push({ field: 'password', value: sshPassword });
|
|
1193
|
+
}
|
|
1194
|
+
return { node, strays };
|
|
1195
|
+
}
|
|
1196
|
+
/** Fallback offline timeout, matching the health monitor's own default. */
|
|
1197
|
+
const DEFAULT_OFFLINE_TIMEOUT_MS = 90_000;
|
|
1198
|
+
/** A TCP port the daemon will actually try to connect to. */
|
|
1199
|
+
function assertPort(kind, value) {
|
|
1200
|
+
if (!Number.isInteger(value) || value < 1 || value > 65_535) {
|
|
1201
|
+
throw new Error(`Invalid ${kind}: ${JSON.stringify(value)}. Expected an integer between 1 and 65535.`);
|
|
1202
|
+
}
|
|
1203
|
+
return value;
|
|
1204
|
+
}
|
|
1205
|
+
/** Reject a promise that has not settled within `ms`. */
|
|
1206
|
+
async function withTimeout(promise, ms) {
|
|
1207
|
+
let timer;
|
|
1208
|
+
try {
|
|
1209
|
+
return await Promise.race([
|
|
1210
|
+
promise,
|
|
1211
|
+
new Promise((_, reject) => {
|
|
1212
|
+
timer = setTimeout(() => reject(new Error(`Timed out after ${ms}ms`)), ms);
|
|
1213
|
+
}),
|
|
1214
|
+
]);
|
|
1215
|
+
}
|
|
1216
|
+
finally {
|
|
1217
|
+
if (timer)
|
|
1218
|
+
clearTimeout(timer);
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
/** Read the first `bytes` of a file without loading the whole thing. */
|
|
1222
|
+
function readFileHead(filePath, bytes) {
|
|
1223
|
+
const fd = fs.openSync(filePath, 'r');
|
|
1224
|
+
try {
|
|
1225
|
+
const buf = Buffer.alloc(bytes);
|
|
1226
|
+
const read = fs.readSync(fd, buf, 0, bytes, 0);
|
|
1227
|
+
return buf.subarray(0, read).toString('utf-8');
|
|
1228
|
+
}
|
|
1229
|
+
finally {
|
|
1230
|
+
fs.closeSync(fd);
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
531
1233
|
/**
|
|
532
1234
|
* Read SSH private key file contents.
|
|
533
1235
|
* If the value is already key content (starts with -----BEGIN), return as-is.
|