@omnitron-dev/omnitron 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/BUILD.json +5 -0
- package/dist/cli/omnitron.js +351 -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.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/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 +68 -0
- package/dist/commands/node.d.ts.map +1 -1
- package/dist/commands/node.js +285 -68
- 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 +26 -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 +411 -42
- 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 +205 -1
- package/dist/daemon/daemon.d.ts.map +1 -1
- package/dist/daemon/daemon.js +1139 -139
- 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 -83
- 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 +438 -96
- 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 +139 -0
- package/dist/execution/execution.service.d.ts.map +1 -1
- package/dist/execution/execution.service.js +273 -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 +169 -1
- package/dist/infrastructure/container-runtime.d.ts.map +1 -1
- package/dist/infrastructure/container-runtime.js +525 -33
- 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-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 +206 -6
- package/dist/infrastructure/infrastructure.service.d.ts.map +1 -1
- package/dist/infrastructure/infrastructure.service.js +415 -89
- 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 +160 -12
- package/dist/infrastructure/service-resolver.d.ts.map +1 -1
- package/dist/infrastructure/service-resolver.js +463 -53
- 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 +6 -0
- package/dist/infrastructure/stack-infra-manager.d.ts.map +1 -1
- package/dist/infrastructure/stack-infra-manager.js +31 -13
- package/dist/infrastructure/stack-infra-manager.js.map +1 -1
- package/dist/infrastructure/types.d.ts +261 -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/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 +330 -19
- package/dist/orchestrator/bootstrap-process.js.map +1 -1
- package/dist/orchestrator/build-service.d.ts.map +1 -1
- 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 +34 -3
- package/dist/orchestrator/classic-launcher.js.map +1 -1
- package/dist/orchestrator/file-watcher.d.ts +78 -1
- package/dist/orchestrator/file-watcher.d.ts.map +1 -1
- package/dist/orchestrator/file-watcher.js +181 -6
- package/dist/orchestrator/file-watcher.js.map +1 -1
- 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 +371 -11
- package/dist/orchestrator/orchestrator.service.d.ts.map +1 -1
- package/dist/orchestrator/orchestrator.service.js +1602 -269
- 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 +287 -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 +217 -49
- 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 +4 -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 +92 -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 +487 -0
- package/dist/services/bundle-builder.d.ts.map +1 -0
- package/dist/services/bundle-builder.js +1083 -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/infrastructure.rpc-service.d.ts +297 -2
- package/dist/services/infrastructure.rpc-service.d.ts.map +1 -1
- package/dist/services/infrastructure.rpc-service.js +523 -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 +151 -0
- package/dist/services/local-bundle.d.ts.map +1 -0
- package/dist/services/local-bundle.js +233 -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 +154 -0
- package/dist/services/node-deploy-lease.d.ts.map +1 -0
- package/dist/services/node-deploy-lease.js +386 -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 +355 -10
- package/dist/services/node-manager.rpc-service.d.ts.map +1 -1
- package/dist/services/node-manager.rpc-service.js +730 -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 +2 -1
- package/dist/services/pipeline.rpc-service.d.ts.map +1 -1
- package/dist/services/pipeline.rpc-service.js.map +1 -1
- package/dist/services/pipeline.service.d.ts +15 -46
- package/dist/services/pipeline.service.d.ts.map +1 -1
- package/dist/services/pipeline.service.js +72 -9
- package/dist/services/pipeline.service.js.map +1 -1
- package/dist/services/project.rpc-service.d.ts +133 -5
- package/dist/services/project.rpc-service.d.ts.map +1 -1
- package/dist/services/project.rpc-service.js +249 -22
- package/dist/services/project.rpc-service.js.map +1 -1
- package/dist/services/project.service.d.ts +677 -15
- package/dist/services/project.service.d.ts.map +1 -1
- package/dist/services/project.service.js +2798 -304
- 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 +569 -8
- package/dist/services/remote-deployer.service.d.ts.map +1 -1
- package/dist/services/remote-deployer.service.js +1618 -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 +122 -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 +85 -0
- package/dist/services/static-carry-forward.d.ts.map +1 -0
- package/dist/services/static-carry-forward.js +159 -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 +831 -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 +64 -30
- package/webapp/dist/BUILD.json +5 -0
- package/webapp/dist/assets/FormControlLabel-BrH2diyl.js +1 -0
- package/webapp/dist/assets/Grid-BZ7xhoHQ.js +1 -0
- package/webapp/dist/assets/Switch-DGSAxQPM.js +1 -0
- package/webapp/dist/assets/alerts-sXqHJbsa.js +1 -0
- package/webapp/dist/assets/apps-B_Ah8Flh.js +1 -0
- package/webapp/dist/assets/audit-YXihwyui.js +1 -0
- package/webapp/dist/assets/client-CGbBvy9k.js +1 -0
- package/webapp/dist/assets/constants-veKGFkC6.js +1 -0
- package/webapp/dist/assets/containers-Di4NOTLf.js +2 -0
- package/webapp/dist/assets/daemon-memory-CCPZ4cV_.js +1 -0
- package/webapp/dist/assets/dashboard-Cfuf95N3.js +1 -0
- package/webapp/dist/assets/dashboard-builder-CowaYb-M.js +1 -0
- package/webapp/dist/assets/deploy-release-dialog-D6C-XcKY.js +1 -0
- package/webapp/dist/assets/deployments-ChTq5kCw.js +1 -0
- package/webapp/dist/assets/detail-BsGWv7Dj.js +1 -0
- package/webapp/dist/assets/detail-CyVf_cw5.js +2 -0
- package/webapp/dist/assets/detail-D027j6aO.js +8 -0
- package/webapp/dist/assets/formatters-BqjL73N3.js +1 -0
- package/webapp/dist/assets/index-B8AHIPc-.css +1 -0
- package/webapp/dist/assets/index-DiZbrwxT.js +414 -0
- package/webapp/dist/assets/logs-L2b8Oqmo.js +12 -0
- package/webapp/dist/assets/maplibre-gl-MlmG2kbn.js +801 -0
- package/webapp/dist/assets/metrics-CQgjz2Lz.js +2 -0
- package/webapp/dist/assets/nodes-Nwia2Ty6.js +7 -0
- package/webapp/dist/assets/pipelines-DCu_rXOr.js +4 -0
- package/webapp/dist/assets/projects-Bb4aV76h.js +1 -0
- package/webapp/dist/assets/react-CwJFpaho.js +1 -0
- package/webapp/dist/assets/react-apexcharts.esm-Dy0Fez42.js +1956 -0
- package/webapp/dist/assets/release-bits-Dj4EOhhb.js +1 -0
- package/webapp/dist/assets/release-build-panel-D6OCVlhT.js +1 -0
- package/webapp/dist/assets/releases-CnAt3yO6.js +2 -0
- package/webapp/dist/assets/rolldown-runtime-hePW80VL.js +1 -0
- package/webapp/dist/assets/settings-DU-mjiwb.js +1 -0
- package/webapp/dist/assets/settled-pair-C7SjZuns.js +1 -0
- package/webapp/dist/assets/sign-in-Bcvjrr4C.js +1 -0
- package/webapp/dist/assets/stacks-B-e8p50I.js +1 -0
- package/webapp/dist/assets/sync-reading-C3PnJ7AX.js +1 -0
- package/webapp/dist/assets/system-info-BtE3dgfw.js +1 -0
- package/webapp/dist/assets/topology-Cwch-uF1.js +12 -0
- package/webapp/dist/assets/topology-DLioOiRN.css +1 -0
- package/webapp/dist/assets/traces-BbShR-4P.js +1 -0
- package/webapp/dist/assets/use-stack-context-CZUgPq88.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
|
@@ -0,0 +1,1040 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a release goes so that a master which did not build it can deploy it.
|
|
3
|
+
*
|
|
4
|
+
* A release exists in one place: `~/.omnitron/releases/<id>` on the master
|
|
5
|
+
* that built it. `release list`, `stack start --release` and the console all
|
|
6
|
+
* read that directory, so a second master — the one production will be run
|
|
7
|
+
* from, or a laptop standing in for a master that died — has none, and the
|
|
8
|
+
* only way across was a directory copied by hand with nothing checking what
|
|
9
|
+
* arrived. `omnitron release push <id>` puts the release in an S3-compatible
|
|
10
|
+
* bucket; `omnitron release pull <id>` takes it out onto any master and holds
|
|
11
|
+
* it to the checks a deployment makes before it becomes visible there.
|
|
12
|
+
*
|
|
13
|
+
* WHAT TRAVELS is the five parts a release is made of — `manifest.json`,
|
|
14
|
+
* `artifacts/`, `statics/`, `scripts/`, `attestations/` — laid out in the
|
|
15
|
+
* bucket as on disk, under `<prefix>/<id>/`. Not `logs/`, `gate-logs/` or a
|
|
16
|
+
* kept `src/`: those are the building master's evidence about its own build,
|
|
17
|
+
* and a pulled release says it has no logs rather than carrying somebody
|
|
18
|
+
* else's.
|
|
19
|
+
*
|
|
20
|
+
* THE INDEX. The manifest names each artifact by sha256 and the static
|
|
21
|
+
* bundle by count and size; it says nothing about `scripts/` or
|
|
22
|
+
* `attestations/`, which are written beside it. So the store keeps its own
|
|
23
|
+
* record, `<id>/index.json`: every object of the release with its sha256 and
|
|
24
|
+
* size. A pull hashes each object as it arrives and holds it to that record,
|
|
25
|
+
* and a refusal names both sums in full. The index is written LAST — a push
|
|
26
|
+
* that dies halfway leaves objects and no index, and a pull refuses that as a
|
|
27
|
+
* push that did not finish instead of taking half a release.
|
|
28
|
+
*
|
|
29
|
+
* WHAT A PULL CHECKS, in the order it can fail:
|
|
30
|
+
*
|
|
31
|
+
* 1. every object against the index — sha256 and size;
|
|
32
|
+
* 2. the index against the manifest — each artifact's sum, and the static
|
|
33
|
+
* bundle's file count and bytes (`loadRelease` only asks whether the
|
|
34
|
+
* directory exists);
|
|
35
|
+
* 3. `loadRelease` itself, on the copy — the check `stack start --release`
|
|
36
|
+
* runs, so a pulled release has passed what a deployment will ask.
|
|
37
|
+
*
|
|
38
|
+
* Only then is the copy renamed into the releases directory. It is fetched
|
|
39
|
+
* into a sibling of that directory rather than into it, because `release
|
|
40
|
+
* list` and `release prune` read every directory there: the console would
|
|
41
|
+
* show a half-fetched release as a failed build, and a prune could delete it
|
|
42
|
+
* mid-pull — what 4ca4527c found a prune doing to a build.
|
|
43
|
+
*
|
|
44
|
+
* A RELEASE IS IMMUTABLE; WHAT WAS MEASURED ABOUT IT IS NOT. An attestation
|
|
45
|
+
* arrives after the first push — test is attested once it carries the
|
|
46
|
+
* release — and production, deployed from another master, asks for it by
|
|
47
|
+
* name (`verifiedOn`). So a push or a pull of a release that is already
|
|
48
|
+
* there compares everything else file by file and refuses any difference,
|
|
49
|
+
* and moves only attestations. A difference means a different build under
|
|
50
|
+
* the same id, which is not hypothetical: the id has minute resolution, so
|
|
51
|
+
* two masters building one pair of commits in one minute produce exactly
|
|
52
|
+
* that. Between two copies of one stack's attestation, the one that measured
|
|
53
|
+
* later wins — `storeAttestation` keeps the newer run the same way — and the
|
|
54
|
+
* side that keeps its own says so. Two masters pushing attestations for one
|
|
55
|
+
* release in the same second: the later index wins, the other's object is in
|
|
56
|
+
* the bucket, and its next push adds it back. An attestation that travels
|
|
57
|
+
* was admitted at the door of the master that stored it (`attest.ts`); this
|
|
58
|
+
* proves it is the same file and nothing more.
|
|
59
|
+
*
|
|
60
|
+
* NO SDK. There is no S3 client in this monorepo. The obvious one,
|
|
61
|
+
* `@aws-sdk/client-s3@3.1137.0`, installs 26 packages — 3 338 files, 8.4 MB,
|
|
62
|
+
* 18 MB on disk (measured 2026-09-22 into an empty directory) — and it would
|
|
63
|
+
* install on every node, because a node installs omnitron's dependencies when
|
|
64
|
+
* the bundle arrives. The size is the lesser half. Its default credential
|
|
65
|
+
* chain reads `AWS_*` from the environment, `~/.aws/credentials`, the SSO
|
|
66
|
+
* cache and a credential process, and asks the instance-metadata address:
|
|
67
|
+
* `credential-provider-{env,ini,sso,process,web-identity,http,login}` and
|
|
68
|
+
* `credential-provider-imds`, all in that install. The key to this store
|
|
69
|
+
* comes from the daemon's vault and from nowhere else, and a client that
|
|
70
|
+
* looks in eight other places when it is handed an empty key has eight other
|
|
71
|
+
* doors. What this module needs is two verbs, PUT and GET, signed with
|
|
72
|
+
* Signature Version 4: `node:crypto`, pinned in the court by AWS's own worked
|
|
73
|
+
* examples and in practice by MinIO, which verifies every signature.
|
|
74
|
+
*
|
|
75
|
+
* THE KEY. `~/.omnitron/config.json` names the store and NAMES its key:
|
|
76
|
+
*
|
|
77
|
+
* "releaseStore": { "endpoint", "bucket", "region", "forcePathStyle", "prefix",
|
|
78
|
+
* "accessKey": { "secret": "<vault key>" },
|
|
79
|
+
* "secretKey": { "secret": "<vault key>" } }
|
|
80
|
+
*
|
|
81
|
+
* — the `{ secret }` reference `resolveSecretRefs` resolves everywhere else.
|
|
82
|
+
* The values are read from the daemon's vault through `OmnitronSecrets.get`,
|
|
83
|
+
* which records each read in the audit trail. A literal credential in the
|
|
84
|
+
* config is refused, a reference the vault cannot answer is refused by name,
|
|
85
|
+
* and the pair is never logged and never sent: a signed request carries the
|
|
86
|
+
* key's id and a signature, not the secret. Plain http is refused anywhere
|
|
87
|
+
* but loopback — the signature protects the key and not the bytes, and a
|
|
88
|
+
* release fetched over a network anyone can write to is code from anyone.
|
|
89
|
+
*
|
|
90
|
+
* WHAT THIS DOES NOT PROVE. The index lives in the bucket it describes. It
|
|
91
|
+
* catches a changed byte, a lost object, a truncated upload and a push that
|
|
92
|
+
* did not finish; it cannot catch someone who can write the bucket and
|
|
93
|
+
* rewrites an object together with its index entry — the manifest then
|
|
94
|
+
* catches an artifact or the static bundle's size, and nothing catches a
|
|
95
|
+
* script or an attestation. Both commands print the index's sha256 so two
|
|
96
|
+
* masters can compare it out of band; a signature over the index is the step
|
|
97
|
+
* after that, and it needs a key decision nobody has made. Each object goes
|
|
98
|
+
* up in one PUT, so a single file may be up to 5 GiB; the largest artifact
|
|
99
|
+
* today is 8.3 MB.
|
|
100
|
+
*/
|
|
101
|
+
import crypto from 'node:crypto';
|
|
102
|
+
import fs from 'node:fs';
|
|
103
|
+
import http from 'node:http';
|
|
104
|
+
import https from 'node:https';
|
|
105
|
+
import os from 'node:os';
|
|
106
|
+
import path from 'node:path';
|
|
107
|
+
import { Transform } from 'node:stream';
|
|
108
|
+
import { pipeline } from 'node:stream/promises';
|
|
109
|
+
import { resolveSecretRefs } from '../project/config-resolver.js';
|
|
110
|
+
import { loadRelease, releasesRoot } from './load.js';
|
|
111
|
+
const CONFIG_FIELDS = new Set(['endpoint', 'bucket', 'region', 'forcePathStyle', 'prefix', 'accessKey', 'secretKey']);
|
|
112
|
+
/** What a store looks like in the config, for a refusal to show — references, never values. */
|
|
113
|
+
export const STORE_CONFIG_EXAMPLE = [
|
|
114
|
+
'"releaseStore": {',
|
|
115
|
+
' "endpoint": "https://s3.example.com",',
|
|
116
|
+
' "bucket": "omnitron-releases",',
|
|
117
|
+
' "region": "us-east-1",',
|
|
118
|
+
' "forcePathStyle": true,',
|
|
119
|
+
' "accessKey": { "secret": "release-store.access_key" },',
|
|
120
|
+
' "secretKey": { "secret": "release-store.secret_key" }',
|
|
121
|
+
'}',
|
|
122
|
+
].join('\n');
|
|
123
|
+
function isLoopback(hostname) {
|
|
124
|
+
const h = hostname.replace(/^\[(.*)\]$/, '$1').toLowerCase();
|
|
125
|
+
return h === 'localhost' || h === '::1' || /^127\.\d+\.\d+\.\d+$/.test(h);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Read `releaseStore` as the config holds it, or say what is wrong with it.
|
|
129
|
+
*
|
|
130
|
+
* Every refusal names the field and what it should be. Unknown fields are
|
|
131
|
+
* refused as well: `forcePathStlye: false`, silently ignored, is a store that
|
|
132
|
+
* answers «NoSuchBucket» for a reason nobody would look for in a spelling.
|
|
133
|
+
*/
|
|
134
|
+
export function parseStoreConfig(raw, source) {
|
|
135
|
+
if (raw === undefined || raw === null) {
|
|
136
|
+
throw new Error(`No artifact store is configured on this master. ${source} takes one:\n\n${STORE_CONFIG_EXAMPLE}\n\n` +
|
|
137
|
+
"and the daemon's vault holds the two keys it names (`omnitron secret set <key> …`).");
|
|
138
|
+
}
|
|
139
|
+
if (typeof raw !== 'object' || Array.isArray(raw)) {
|
|
140
|
+
throw new Error(`'releaseStore' in ${source} is ${Array.isArray(raw) ? 'a list' : typeof raw}, not an object:\n\n${STORE_CONFIG_EXAMPLE}`);
|
|
141
|
+
}
|
|
142
|
+
const o = raw;
|
|
143
|
+
const unknown = Object.keys(o).filter((k) => !CONFIG_FIELDS.has(k));
|
|
144
|
+
if (unknown.length > 0) {
|
|
145
|
+
throw new Error(`'releaseStore' in ${source} has ${unknown.map((k) => `'${k}'`).join(', ')}, which it does not read — it reads ${[...CONFIG_FIELDS].join(', ')}`);
|
|
146
|
+
}
|
|
147
|
+
const reference = (field) => {
|
|
148
|
+
const value = o[field];
|
|
149
|
+
if (typeof value === 'string') {
|
|
150
|
+
throw new Error(`'releaseStore.${field}' in ${source} is a literal credential. The key lives in the daemon's vault and the config names it: ` +
|
|
151
|
+
`"${field}": { "secret": "<vault key>" }`);
|
|
152
|
+
}
|
|
153
|
+
const ref = value;
|
|
154
|
+
if (!ref || typeof ref !== 'object' || typeof ref['secret'] !== 'string' || ref['secret'] === '') {
|
|
155
|
+
throw new Error(`'releaseStore.${field}' in ${source} must name a vault key: "${field}": { "secret": "<vault key>" }`);
|
|
156
|
+
}
|
|
157
|
+
if ('default' in ref) {
|
|
158
|
+
// `resolveSecretRefs` falls back to it when the vault has nothing —
|
|
159
|
+
// which is a literal credential in the config by another name.
|
|
160
|
+
throw new Error(`'releaseStore.${field}' in ${source} carries a 'default' — a credential the vault does not hold is refused, not replaced`);
|
|
161
|
+
}
|
|
162
|
+
return { secret: ref['secret'] };
|
|
163
|
+
};
|
|
164
|
+
const accessKey = reference('accessKey');
|
|
165
|
+
const secretKey = reference('secretKey');
|
|
166
|
+
const endpoint = o['endpoint'];
|
|
167
|
+
if (typeof endpoint !== 'string' || endpoint === '') {
|
|
168
|
+
throw new Error(`'releaseStore.endpoint' in ${source} must be the store's address, e.g. "https://s3.example.com"`);
|
|
169
|
+
}
|
|
170
|
+
let url;
|
|
171
|
+
try {
|
|
172
|
+
url = new URL(endpoint);
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
throw new Error(`'releaseStore.endpoint' in ${source} is '${endpoint}', which is not an address`);
|
|
176
|
+
}
|
|
177
|
+
if (url.protocol !== 'https:' && url.protocol !== 'http:') {
|
|
178
|
+
throw new Error(`'releaseStore.endpoint' in ${source} is ${url.protocol} — the store speaks http(s)`);
|
|
179
|
+
}
|
|
180
|
+
if (url.username || url.password) {
|
|
181
|
+
throw new Error(`'releaseStore.endpoint' in ${source} carries credentials in the address — they belong in the vault, named by accessKey and secretKey`);
|
|
182
|
+
}
|
|
183
|
+
if (url.search || url.hash) {
|
|
184
|
+
throw new Error(`'releaseStore.endpoint' in ${source} has a query or a fragment; it is a base address`);
|
|
185
|
+
}
|
|
186
|
+
if (url.protocol === 'http:' && !isLoopback(url.hostname)) {
|
|
187
|
+
throw new Error(`'releaseStore.endpoint' in ${source} is plain http to ${url.hostname}. The signature protects the key and not the bytes: ` +
|
|
188
|
+
`anyone on the path could hand this master a release. Use https, or reach the store through a tunnel on loopback.`);
|
|
189
|
+
}
|
|
190
|
+
const bucket = o['bucket'];
|
|
191
|
+
if (typeof bucket !== 'string' || !/^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/.test(bucket)) {
|
|
192
|
+
throw new Error(`'releaseStore.bucket' in ${source} must be a bucket name — 3 to 63 of a-z, 0-9, '.' and '-'`);
|
|
193
|
+
}
|
|
194
|
+
const region = o['region'];
|
|
195
|
+
if (region !== undefined && (typeof region !== 'string' || !/^[a-z0-9][a-z0-9-]*$/.test(region))) {
|
|
196
|
+
throw new Error(`'releaseStore.region' in ${source} must be a region name such as "us-east-1"`);
|
|
197
|
+
}
|
|
198
|
+
const forcePathStyle = o['forcePathStyle'];
|
|
199
|
+
if (forcePathStyle !== undefined && typeof forcePathStyle !== 'boolean') {
|
|
200
|
+
throw new Error(`'releaseStore.forcePathStyle' in ${source} is true or false`);
|
|
201
|
+
}
|
|
202
|
+
const prefix = o['prefix'];
|
|
203
|
+
if (prefix !== undefined) {
|
|
204
|
+
const trimmed = typeof prefix === 'string' ? prefix.replace(/^\/+|\/+$/g, '') : null;
|
|
205
|
+
const fits = trimmed !== null &&
|
|
206
|
+
(trimmed === '' || trimmed.split('/').every((s) => /^[A-Za-z0-9._-]+$/.test(s) && s !== '.' && s !== '..'));
|
|
207
|
+
if (!fits) {
|
|
208
|
+
throw new Error(`'releaseStore.prefix' in ${source} must be a path inside the bucket, of A-Z, a-z, 0-9, '.', '_' and '-'`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
endpoint,
|
|
213
|
+
bucket,
|
|
214
|
+
...(typeof region === 'string' ? { region } : {}),
|
|
215
|
+
...(typeof forcePathStyle === 'boolean' ? { forcePathStyle } : {}),
|
|
216
|
+
...(typeof prefix === 'string' ? { prefix } : {}),
|
|
217
|
+
accessKey,
|
|
218
|
+
secretKey,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* The store with its key, read through `getSecret` — the daemon's
|
|
223
|
+
* `OmnitronSecrets.get` in the command, a fake vault in the court.
|
|
224
|
+
*
|
|
225
|
+
* `resolveSecretRefs` turns a reference the vault cannot answer into an empty
|
|
226
|
+
* string, which a store reports as a bad signature against a key it was never
|
|
227
|
+
* given. The misses are counted here instead and refused by name, before a
|
|
228
|
+
* single request is made.
|
|
229
|
+
*/
|
|
230
|
+
export async function resolveStore(config, getSecret) {
|
|
231
|
+
const missing = [];
|
|
232
|
+
const resolved = await resolveSecretRefs({ accessKey: config.accessKey, secretKey: config.secretKey }, async (key) => {
|
|
233
|
+
const value = await getSecret(key);
|
|
234
|
+
if (value === null || value === '')
|
|
235
|
+
missing.push(key);
|
|
236
|
+
return value;
|
|
237
|
+
});
|
|
238
|
+
if (missing.length > 0) {
|
|
239
|
+
throw new Error(`The artifact store's key is not in the daemon's vault: it holds no ${missing.map((k) => `'${k}'`).join(' and ')}. ` +
|
|
240
|
+
'`omnitron secret list` shows what it holds; `omnitron secret set <key> …` adds one.');
|
|
241
|
+
}
|
|
242
|
+
const accessKeyId = resolved['accessKey'];
|
|
243
|
+
const secretAccessKey = resolved['secretKey'];
|
|
244
|
+
if (typeof accessKeyId !== 'string' || typeof secretAccessKey !== 'string') {
|
|
245
|
+
throw new Error("The vault's answer for the artifact store's key is not a string");
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
endpoint: new URL(config.endpoint),
|
|
249
|
+
bucket: config.bucket,
|
|
250
|
+
region: config.region ?? 'us-east-1',
|
|
251
|
+
forcePathStyle: config.forcePathStyle ?? true,
|
|
252
|
+
prefix: (config.prefix ?? '').replace(/^\/+|\/+$/g, ''),
|
|
253
|
+
credentials: { accessKeyId, secretAccessKey },
|
|
254
|
+
credentialKeys: { accessKey: config.accessKey.secret, secretKey: config.secretKey.secret },
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
// ============================================================================
|
|
258
|
+
// Signature Version 4 — the part of it two verbs need
|
|
259
|
+
// ============================================================================
|
|
260
|
+
const EMPTY_SHA256 = crypto.createHash('sha256').digest('hex');
|
|
261
|
+
function sha256Hex(data) {
|
|
262
|
+
return crypto.createHash('sha256').update(data).digest('hex');
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Percent-encoding as SigV4 defines it: everything but `A-Z a-z 0-9 - _ . ~`.
|
|
266
|
+
* `encodeURIComponent` leaves `! ' ( ) *` alone, and a statics file named
|
|
267
|
+
* with one of them would be signed as one path and sent as another.
|
|
268
|
+
*/
|
|
269
|
+
export function encodeRfc3986(value) {
|
|
270
|
+
return encodeURIComponent(value).replace(/[!'()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Sign one request; returns the headers to add — `x-amz-date`,
|
|
274
|
+
* `x-amz-content-sha256` and `authorization`.
|
|
275
|
+
*
|
|
276
|
+
* The payload is signed by its real sum rather than as `UNSIGNED-PAYLOAD`:
|
|
277
|
+
* then the store itself refuses an upload whose bytes changed on the way,
|
|
278
|
+
* before this side ever reads them back.
|
|
279
|
+
*/
|
|
280
|
+
export function signV4(input) {
|
|
281
|
+
const amzDate = input.now.toISOString().replace(/[-:]/g, '').replace(/\.\d{3}/, '');
|
|
282
|
+
const day = amzDate.slice(0, 8);
|
|
283
|
+
const scope = `${day}/${input.region}/s3/aws4_request`;
|
|
284
|
+
const headers = new Map();
|
|
285
|
+
for (const [name, value] of Object.entries(input.headers))
|
|
286
|
+
headers.set(name.toLowerCase(), value);
|
|
287
|
+
headers.set('x-amz-date', amzDate);
|
|
288
|
+
headers.set('x-amz-content-sha256', input.payloadSha256);
|
|
289
|
+
const names = [...headers.keys()].sort();
|
|
290
|
+
const canonicalHeaders = names.map((n) => `${n}:${(headers.get(n) ?? '').trim().replace(/\s+/g, ' ')}\n`).join('');
|
|
291
|
+
const signedHeaders = names.join(';');
|
|
292
|
+
// By key, then by value — not by the joined `k=v`, which puts `a-b=` before
|
|
293
|
+
// `a=` because '-' sorts below '='.
|
|
294
|
+
const canonicalQuery = Object.entries(input.query ?? {})
|
|
295
|
+
.map(([k, v]) => [encodeRfc3986(k), encodeRfc3986(v)])
|
|
296
|
+
.sort(([ka, va], [kb, vb]) => (ka < kb ? -1 : ka > kb ? 1 : va < vb ? -1 : va > vb ? 1 : 0))
|
|
297
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
298
|
+
.join('&');
|
|
299
|
+
const canonicalRequest = [
|
|
300
|
+
input.method,
|
|
301
|
+
input.canonicalUri,
|
|
302
|
+
canonicalQuery,
|
|
303
|
+
canonicalHeaders,
|
|
304
|
+
signedHeaders,
|
|
305
|
+
input.payloadSha256,
|
|
306
|
+
].join('\n');
|
|
307
|
+
const stringToSign = ['AWS4-HMAC-SHA256', amzDate, scope, sha256Hex(canonicalRequest)].join('\n');
|
|
308
|
+
const hmac = (key, data) => crypto.createHmac('sha256', key).update(data).digest();
|
|
309
|
+
const signingKey = hmac(hmac(hmac(hmac(`AWS4${input.credentials.secretAccessKey}`, day), input.region), 's3'), 'aws4_request');
|
|
310
|
+
const signature = crypto.createHmac('sha256', signingKey).update(stringToSign).digest('hex');
|
|
311
|
+
return {
|
|
312
|
+
signature,
|
|
313
|
+
headers: {
|
|
314
|
+
'x-amz-date': amzDate,
|
|
315
|
+
'x-amz-content-sha256': input.payloadSha256,
|
|
316
|
+
authorization: `AWS4-HMAC-SHA256 Credential=${input.credentials.accessKeyId}/${scope}, SignedHeaders=${signedHeaders}, Signature=${signature}`,
|
|
317
|
+
},
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
/** Where an object is, in either addressing style. */
|
|
321
|
+
export function objectAddress(store, key) {
|
|
322
|
+
const base = store.endpoint;
|
|
323
|
+
const basePath = base.pathname.replace(/\/+$/, '');
|
|
324
|
+
const full = store.prefix ? `${store.prefix}/${key}` : key;
|
|
325
|
+
const encoded = full.split('/').map(encodeRfc3986).join('/');
|
|
326
|
+
const hostname = base.hostname.replace(/^\[(.*)\]$/, '$1');
|
|
327
|
+
const secure = base.protocol === 'https:';
|
|
328
|
+
if (store.forcePathStyle) {
|
|
329
|
+
return { https: secure, hostname, port: base.port, host: base.host, path: `${basePath}/${store.bucket}/${encoded}` };
|
|
330
|
+
}
|
|
331
|
+
return {
|
|
332
|
+
https: secure,
|
|
333
|
+
hostname: `${store.bucket}.${hostname}`,
|
|
334
|
+
port: base.port,
|
|
335
|
+
host: `${store.bucket}.${base.host}`,
|
|
336
|
+
path: `${basePath}/${encoded}`,
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
/** S3 refuses a single PUT above this; a multipart upload is the way past it. */
|
|
340
|
+
const SINGLE_PUT_LIMIT = 5 * 1024 ** 3;
|
|
341
|
+
/** An S3 error document is a few hundred bytes; this is how much of one is read. */
|
|
342
|
+
const ERROR_BODY_LIMIT = 64 * 1024;
|
|
343
|
+
function xmlField(body, field) {
|
|
344
|
+
const match = new RegExp(`<${field}>([^<]*)</${field}>`).exec(body);
|
|
345
|
+
if (!match)
|
|
346
|
+
return null;
|
|
347
|
+
return match[1]
|
|
348
|
+
.replace(/</g, '<')
|
|
349
|
+
.replace(/>/g, '>')
|
|
350
|
+
.replace(/"/g, '"')
|
|
351
|
+
.replace(/'/g, "'")
|
|
352
|
+
.replace(/&/g, '&');
|
|
353
|
+
}
|
|
354
|
+
function readCapped(res, cap) {
|
|
355
|
+
return new Promise((resolve, reject) => {
|
|
356
|
+
const chunks = [];
|
|
357
|
+
let size = 0;
|
|
358
|
+
res.on('data', (chunk) => {
|
|
359
|
+
if (size < cap)
|
|
360
|
+
chunks.push(chunk.subarray(0, cap - size));
|
|
361
|
+
size += chunk.length;
|
|
362
|
+
});
|
|
363
|
+
res.on('end', () => resolve(Buffer.concat(chunks)));
|
|
364
|
+
res.on('error', reject);
|
|
365
|
+
// A connection closed mid-answer ends with neither of the two above on
|
|
366
|
+
// every path through `http`; unanswered, this promise would wait for ever.
|
|
367
|
+
res.on('close', () => {
|
|
368
|
+
if (!res.complete)
|
|
369
|
+
reject(new Error('the connection closed before the store finished answering'));
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* An S3-compatible bucket, reached with `node:http(s)` and SigV4.
|
|
375
|
+
*
|
|
376
|
+
* The key pair is a private field: nothing that prints this object — a log
|
|
377
|
+
* line, an `inspect`, a `JSON.stringify` of an error that holds it — can
|
|
378
|
+
* reach it.
|
|
379
|
+
*/
|
|
380
|
+
export class S3ObjectStore {
|
|
381
|
+
location;
|
|
382
|
+
#credentials;
|
|
383
|
+
#store;
|
|
384
|
+
#agent;
|
|
385
|
+
#idleMs;
|
|
386
|
+
constructor(store, options = {}) {
|
|
387
|
+
this.#store = store;
|
|
388
|
+
this.#credentials = store.credentials;
|
|
389
|
+
this.#idleMs = options.idleTimeoutMs ?? 60_000;
|
|
390
|
+
const agentOptions = { keepAlive: true, maxSockets: options.sockets ?? 8 };
|
|
391
|
+
this.#agent = store.endpoint.protocol === 'https:' ? new https.Agent(agentOptions) : new http.Agent(agentOptions);
|
|
392
|
+
const base = `${store.endpoint.origin}${store.endpoint.pathname.replace(/\/+$/, '')}`;
|
|
393
|
+
this.location = `s3://${store.bucket}${store.prefix ? `/${store.prefix}` : ''} at ${base}`;
|
|
394
|
+
}
|
|
395
|
+
/** Keep-alive sockets hold the process open; a command closes the store when it is done. */
|
|
396
|
+
close() {
|
|
397
|
+
this.#agent.destroy();
|
|
398
|
+
}
|
|
399
|
+
async put(key, source, sum) {
|
|
400
|
+
if (sum.bytes > SINGLE_PUT_LIMIT) {
|
|
401
|
+
throw new Error(`${key} is ${sum.bytes} bytes; one PUT carries at most ${SINGLE_PUT_LIMIT}, and this store does not split uploads`);
|
|
402
|
+
}
|
|
403
|
+
const res = await this.send('PUT', key, { source, sum });
|
|
404
|
+
const body = await readCapped(res, ERROR_BODY_LIMIT);
|
|
405
|
+
if (res.statusCode !== 200)
|
|
406
|
+
throw this.failure('PUT', key, res.statusCode ?? 0, body.toString('utf8'));
|
|
407
|
+
}
|
|
408
|
+
async get(key, into, recordedBytes) {
|
|
409
|
+
const res = await this.send('GET', key, null);
|
|
410
|
+
if (res.statusCode !== 200) {
|
|
411
|
+
const body = (await readCapped(res, ERROR_BODY_LIMIT)).toString('utf8');
|
|
412
|
+
if (res.statusCode === 404 && xmlField(body, 'Code') === 'NoSuchKey')
|
|
413
|
+
return null;
|
|
414
|
+
throw this.failure('GET', key, res.statusCode ?? 0, body);
|
|
415
|
+
}
|
|
416
|
+
const declared = Number(res.headers['content-length']);
|
|
417
|
+
if (Number.isFinite(declared) && declared > recordedBytes) {
|
|
418
|
+
res.destroy();
|
|
419
|
+
throw new Error(`${key} in ${this.location} is ${declared} bytes, and the index recorded ${recordedBytes} — it is not the object that was pushed`);
|
|
420
|
+
}
|
|
421
|
+
const hash = crypto.createHash('sha256');
|
|
422
|
+
let bytes = 0;
|
|
423
|
+
const location = this.location;
|
|
424
|
+
const meter = new Transform({
|
|
425
|
+
transform(chunk, _encoding, done) {
|
|
426
|
+
bytes += chunk.length;
|
|
427
|
+
if (bytes > recordedBytes) {
|
|
428
|
+
done(new Error(`${key} in ${location} runs past the ${recordedBytes} bytes the index recorded — it is not the object that was pushed`));
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
hash.update(chunk);
|
|
432
|
+
done(null, chunk);
|
|
433
|
+
},
|
|
434
|
+
});
|
|
435
|
+
await pipeline(res, meter, fs.createWriteStream(into));
|
|
436
|
+
return { sha256: hash.digest('hex'), bytes };
|
|
437
|
+
}
|
|
438
|
+
async read(key, limitBytes) {
|
|
439
|
+
const res = await this.send('GET', key, null);
|
|
440
|
+
if (res.statusCode !== 200) {
|
|
441
|
+
const body = (await readCapped(res, ERROR_BODY_LIMIT)).toString('utf8');
|
|
442
|
+
if (res.statusCode === 404 && xmlField(body, 'Code') === 'NoSuchKey')
|
|
443
|
+
return null;
|
|
444
|
+
throw this.failure('GET', key, res.statusCode ?? 0, body);
|
|
445
|
+
}
|
|
446
|
+
const chunks = [];
|
|
447
|
+
let size = 0;
|
|
448
|
+
for await (const chunk of res) {
|
|
449
|
+
size += chunk.length;
|
|
450
|
+
if (size > limitBytes) {
|
|
451
|
+
res.destroy();
|
|
452
|
+
throw new Error(`${key} in ${this.location} is larger than ${limitBytes} bytes — more than this reads whole`);
|
|
453
|
+
}
|
|
454
|
+
chunks.push(chunk);
|
|
455
|
+
}
|
|
456
|
+
return Buffer.concat(chunks);
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* One signed request; resolves with the response once its headers arrive.
|
|
460
|
+
*
|
|
461
|
+
* `setTimeout` is an IDLE timeout on the socket: a transfer that is moving
|
|
462
|
+
* is never cut, one that has said nothing for a minute is — and the error
|
|
463
|
+
* reaches the response too, so a stream being read does not wait forever.
|
|
464
|
+
*/
|
|
465
|
+
send(method, key, body) {
|
|
466
|
+
const address = objectAddress(this.#store, key);
|
|
467
|
+
const signed = signV4({
|
|
468
|
+
method,
|
|
469
|
+
canonicalUri: address.path,
|
|
470
|
+
headers: { host: address.host },
|
|
471
|
+
payloadSha256: body ? body.sum.sha256 : EMPTY_SHA256,
|
|
472
|
+
region: this.#store.region,
|
|
473
|
+
credentials: this.#credentials,
|
|
474
|
+
now: new Date(),
|
|
475
|
+
});
|
|
476
|
+
const headers = { host: address.host, ...signed.headers };
|
|
477
|
+
if (body)
|
|
478
|
+
headers['content-length'] = String(body.sum.bytes);
|
|
479
|
+
return new Promise((resolve, reject) => {
|
|
480
|
+
let response = null;
|
|
481
|
+
const req = (address.https ? https : http).request({
|
|
482
|
+
hostname: address.hostname,
|
|
483
|
+
...(address.port ? { port: Number(address.port) } : {}),
|
|
484
|
+
path: address.path,
|
|
485
|
+
method,
|
|
486
|
+
headers,
|
|
487
|
+
agent: this.#agent,
|
|
488
|
+
}, (res) => {
|
|
489
|
+
response = res;
|
|
490
|
+
resolve(res);
|
|
491
|
+
});
|
|
492
|
+
req.setTimeout(this.#idleMs, () => {
|
|
493
|
+
const err = new Error(`${this.location}: ${method} ${key} — nothing for ${Math.round(this.#idleMs / 1000)}s, abandoned`);
|
|
494
|
+
req.destroy(err);
|
|
495
|
+
response?.destroy(err);
|
|
496
|
+
});
|
|
497
|
+
req.on('error', reject);
|
|
498
|
+
if (!body) {
|
|
499
|
+
req.end();
|
|
500
|
+
}
|
|
501
|
+
else if (Buffer.isBuffer(body.source)) {
|
|
502
|
+
req.end(body.source);
|
|
503
|
+
}
|
|
504
|
+
else {
|
|
505
|
+
// A store that answers early — a 403 before the body is through —
|
|
506
|
+
// ends this pipe with an error; the response carries the verdict.
|
|
507
|
+
pipeline(fs.createReadStream(body.source), req).catch(() => undefined);
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
/** A refusal in the store's own words, and what it usually means here. */
|
|
512
|
+
failure(method, key, status, body) {
|
|
513
|
+
const code = xmlField(body, 'Code');
|
|
514
|
+
const message = xmlField(body, 'Message')?.replace(/\.\s*$/, '');
|
|
515
|
+
const keys = this.#store.credentialKeys;
|
|
516
|
+
const hints = {
|
|
517
|
+
NoSuchBucket: `create the bucket '${this.#store.bucket}' there, or name the right one in releaseStore.bucket`,
|
|
518
|
+
InvalidAccessKeyId: `the key pair is the vault's '${keys.accessKey}' and '${keys.secretKey}', and the store does not know it`,
|
|
519
|
+
SignatureDoesNotMatch: `the key pair is the vault's '${keys.accessKey}' and '${keys.secretKey}', and the store does not accept it`,
|
|
520
|
+
AccessDenied: method === 'GET'
|
|
521
|
+
? 'S3 answers 403 rather than 404 for a missing object when the key may not list the bucket — grant s3:ListBucket on it'
|
|
522
|
+
: `the vault's '${keys.accessKey}' may not write here`,
|
|
523
|
+
RequestTimeTooSkewed: "this machine's clock is too far from the store's",
|
|
524
|
+
PermanentRedirect: 'the bucket is in another region — releaseStore.region, or path style off',
|
|
525
|
+
};
|
|
526
|
+
const hint = code ? hints[code] : undefined;
|
|
527
|
+
return new Error(`${this.location}: ${method} ${key} answered ${status}${code ? ` ${code}` : ''}` +
|
|
528
|
+
`${message ? ` — ${message}` : ''}${hint ? `. ${hint[0].toUpperCase()}${hint.slice(1)}.` : ''}`);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
// ============================================================================
|
|
532
|
+
// The index: every object of a release, by sha256
|
|
533
|
+
// ============================================================================
|
|
534
|
+
const INDEX_NAME = 'index.json';
|
|
535
|
+
/** The 555 objects of daos-202609221654-8d2f51e0-225cde48 make a 95 536-byte index; this is a bound, not an estimate. */
|
|
536
|
+
const INDEX_LIMIT = 16 * 1024 * 1024;
|
|
537
|
+
const DIRECTORY_PARTS = ['artifacts', 'statics', 'scripts', 'attestations'];
|
|
538
|
+
/** The same rule `loadRelease` applies — the court holds the two to one answer. */
|
|
539
|
+
const RELEASE_ID = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
540
|
+
export function isReleaseId(id) {
|
|
541
|
+
return RELEASE_ID.test(id) && !id.includes('..');
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Why a path may not be a file of a release — or null.
|
|
545
|
+
*
|
|
546
|
+
* Applied on both sides: a pull reads paths from the store, which is input
|
|
547
|
+
* from outside, and a path that climbs would write wherever it points; a
|
|
548
|
+
* push applies the same rule so it never writes an index a pull would
|
|
549
|
+
* refuse.
|
|
550
|
+
*/
|
|
551
|
+
export function entryPathProblem(p) {
|
|
552
|
+
if (typeof p !== 'string' || p === '')
|
|
553
|
+
return 'it is not a path';
|
|
554
|
+
if (p.length > 1024)
|
|
555
|
+
return 'it is longer than 1024 characters';
|
|
556
|
+
if (p.includes('\\') || p.includes('\0'))
|
|
557
|
+
return 'it holds a backslash or a NUL';
|
|
558
|
+
const segments = p.split('/');
|
|
559
|
+
if (segments.some((s) => s === '' || s === '.' || s === '..'))
|
|
560
|
+
return 'it is absolute, climbs, or has an empty segment';
|
|
561
|
+
const top = segments[0];
|
|
562
|
+
if (top === 'manifest.json')
|
|
563
|
+
return segments.length === 1 ? null : 'manifest.json is a file';
|
|
564
|
+
if (top === 'artifacts')
|
|
565
|
+
return segments.length === 2 ? null : 'an artifact is a file directly in artifacts/';
|
|
566
|
+
if (top === 'attestations') {
|
|
567
|
+
return segments.length === 2 && segments[1].endsWith('.json') ? null : 'an attestation is attestations/<stack>.json';
|
|
568
|
+
}
|
|
569
|
+
if (top === 'statics' || top === 'scripts')
|
|
570
|
+
return segments.length >= 2 ? null : `${top} is a directory`;
|
|
571
|
+
return `'${top}' is not one of the five parts of a release`;
|
|
572
|
+
}
|
|
573
|
+
function partOf(p) {
|
|
574
|
+
const top = p.split('/')[0];
|
|
575
|
+
return top === 'manifest.json' ? 'manifest' : top;
|
|
576
|
+
}
|
|
577
|
+
const isAttestation = (e) => partOf(e.path) === 'attestations';
|
|
578
|
+
const byPath = (a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
579
|
+
async function hashFile(file) {
|
|
580
|
+
const hash = crypto.createHash('sha256');
|
|
581
|
+
let bytes = 0;
|
|
582
|
+
for await (const chunk of fs.createReadStream(file)) {
|
|
583
|
+
hash.update(chunk);
|
|
584
|
+
bytes += chunk.length;
|
|
585
|
+
}
|
|
586
|
+
return { sha256: hash.digest('hex'), bytes };
|
|
587
|
+
}
|
|
588
|
+
function attestationAt(file) {
|
|
589
|
+
try {
|
|
590
|
+
const at = JSON.parse(fs.readFileSync(file, 'utf8')).at;
|
|
591
|
+
return typeof at === 'string' ? at : undefined;
|
|
592
|
+
}
|
|
593
|
+
catch {
|
|
594
|
+
// Unreadable: carried, and read as the oldest when two copies differ.
|
|
595
|
+
return undefined;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* The five parts of the release in `dir`, as index entries, by path.
|
|
600
|
+
*
|
|
601
|
+
* Regular files only. A symlink is refused rather than followed or skipped:
|
|
602
|
+
* `fs.cpSync` — which is how the builder copies `scripts/` and `statics/` —
|
|
603
|
+
* keeps a link as a link, pointing into a clone that is deleted after the
|
|
604
|
+
* build, so it would arrive as nothing, or as whatever the path names on the
|
|
605
|
+
* next machine.
|
|
606
|
+
*/
|
|
607
|
+
async function walkRelease(dir) {
|
|
608
|
+
const entries = [];
|
|
609
|
+
const take = async (rel, full) => {
|
|
610
|
+
const problem = entryPathProblem(rel);
|
|
611
|
+
if (problem)
|
|
612
|
+
throw new Error(`${full} cannot travel: ${problem}`);
|
|
613
|
+
const sum = await hashFile(full);
|
|
614
|
+
const executable = (fs.statSync(full).mode & 0o100) !== 0;
|
|
615
|
+
const at = partOf(rel) === 'attestations' ? attestationAt(full) : undefined;
|
|
616
|
+
entries.push({ path: rel, ...sum, ...(executable ? { executable: true } : {}), ...(at ? { at } : {}) });
|
|
617
|
+
};
|
|
618
|
+
const visit = async (abs, rel) => {
|
|
619
|
+
const children = fs.readdirSync(abs, { withFileTypes: true }).sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
620
|
+
for (const child of children) {
|
|
621
|
+
const childAbs = path.join(abs, child.name);
|
|
622
|
+
const childRel = `${rel}/${child.name}`;
|
|
623
|
+
if (child.isDirectory())
|
|
624
|
+
await visit(childAbs, childRel);
|
|
625
|
+
else if (child.isFile())
|
|
626
|
+
await take(childRel, childAbs);
|
|
627
|
+
else {
|
|
628
|
+
throw new Error(`${childAbs} is ${child.isSymbolicLink() ? 'a symbolic link' : 'not a regular file'} — the store carries files, ` +
|
|
629
|
+
'and this would arrive as nothing, or as whatever the path names on the next machine');
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
const manifest = path.join(dir, 'manifest.json');
|
|
634
|
+
if (!fs.lstatSync(manifest).isFile())
|
|
635
|
+
throw new Error(`${manifest} is not a regular file`);
|
|
636
|
+
await take('manifest.json', manifest);
|
|
637
|
+
for (const part of DIRECTORY_PARTS) {
|
|
638
|
+
const top = path.join(dir, part);
|
|
639
|
+
let st;
|
|
640
|
+
try {
|
|
641
|
+
st = fs.lstatSync(top);
|
|
642
|
+
}
|
|
643
|
+
catch {
|
|
644
|
+
continue; // A release built before this part existed has none.
|
|
645
|
+
}
|
|
646
|
+
if (!st.isDirectory())
|
|
647
|
+
throw new Error(`${top} is not a directory`);
|
|
648
|
+
await visit(top, part);
|
|
649
|
+
}
|
|
650
|
+
return entries.sort(byPath);
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* The index as the store holds it — read as input from outside.
|
|
654
|
+
*
|
|
655
|
+
* Every path is checked before anything is written, every sum and size is
|
|
656
|
+
* checked for shape, and the index must describe the release it was asked
|
|
657
|
+
* for: an index copied from another release's prefix is refused here rather
|
|
658
|
+
* than by a sum three hundred objects later.
|
|
659
|
+
*/
|
|
660
|
+
export function parseIndex(bytes, id, location) {
|
|
661
|
+
const where = `${location}: ${id}/${INDEX_NAME}`;
|
|
662
|
+
let raw;
|
|
663
|
+
try {
|
|
664
|
+
raw = JSON.parse(bytes.toString('utf8'));
|
|
665
|
+
}
|
|
666
|
+
catch (err) {
|
|
667
|
+
throw new Error(`${where} does not parse (${err.message}) — the store's record of this release is damaged`, {
|
|
668
|
+
cause: err,
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
const o = raw;
|
|
672
|
+
if (!o || typeof o !== 'object')
|
|
673
|
+
throw new Error(`${where} is not an object`);
|
|
674
|
+
if (o.format !== 1)
|
|
675
|
+
throw new Error(`${where} is format ${String(o.format)}; this omnitron reads format 1`);
|
|
676
|
+
if (o.release !== id)
|
|
677
|
+
throw new Error(`${where} describes release '${String(o.release)}', not '${id}'`);
|
|
678
|
+
if (!Array.isArray(o.files))
|
|
679
|
+
throw new Error(`${where} lists no files`);
|
|
680
|
+
const seen = new Set();
|
|
681
|
+
const files = [];
|
|
682
|
+
for (const item of o.files) {
|
|
683
|
+
const e = (item ?? {});
|
|
684
|
+
const problem = entryPathProblem(e.path);
|
|
685
|
+
if (problem)
|
|
686
|
+
throw new Error(`${where} names '${String(e.path)}': ${problem}. Nothing was written.`);
|
|
687
|
+
const p = e.path;
|
|
688
|
+
if (seen.has(p))
|
|
689
|
+
throw new Error(`${where} names ${p} twice`);
|
|
690
|
+
seen.add(p);
|
|
691
|
+
if (typeof e.sha256 !== 'string' || !/^[0-9a-f]{64}$/.test(e.sha256))
|
|
692
|
+
throw new Error(`${where} gives ${p} no sha256`);
|
|
693
|
+
if (typeof e.bytes !== 'number' || !Number.isSafeInteger(e.bytes) || e.bytes < 0)
|
|
694
|
+
throw new Error(`${where} gives ${p} no size`);
|
|
695
|
+
files.push({
|
|
696
|
+
path: p,
|
|
697
|
+
sha256: e.sha256,
|
|
698
|
+
bytes: e.bytes,
|
|
699
|
+
...(e.executable === true ? { executable: true } : {}),
|
|
700
|
+
...(typeof e.at === 'string' ? { at: e.at } : {}),
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
if (!seen.has('manifest.json'))
|
|
704
|
+
throw new Error(`${where} has no manifest.json`);
|
|
705
|
+
return {
|
|
706
|
+
format: 1,
|
|
707
|
+
release: id,
|
|
708
|
+
pushedAt: typeof o.pushedAt === 'string' ? o.pushedAt : '',
|
|
709
|
+
pushedBy: typeof o.pushedBy === 'string' ? o.pushedBy : '',
|
|
710
|
+
files: files.sort(byPath),
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
function tally(entries) {
|
|
714
|
+
return { files: entries.length, bytes: entries.reduce((sum, e) => sum + e.bytes, 0) };
|
|
715
|
+
}
|
|
716
|
+
function tallyParts(entries) {
|
|
717
|
+
const parts = ['manifest', ...DIRECTORY_PARTS];
|
|
718
|
+
return Object.fromEntries(parts.map((part) => [part, tally(entries.filter((e) => partOf(e.path) === part))]));
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* The files — an index's, or a disk's — against the manifest they carry.
|
|
722
|
+
*
|
|
723
|
+
* Each artifact by sum and size, both in full; the static bundle by count and
|
|
724
|
+
* bytes, counted as the builder counts them (`countFiles`: regular files,
|
|
725
|
+
* recursively). `loadRelease` compares the artifacts too, on disk, and says
|
|
726
|
+
* twelve characters of each sum; this runs first so a refusal says all
|
|
727
|
+
* sixty-four.
|
|
728
|
+
*/
|
|
729
|
+
function checkAgainstManifest(id, manifest, entries, where) {
|
|
730
|
+
const byEntry = new Map(entries.map((e) => [e.path, e]));
|
|
731
|
+
for (const a of manifest.artifacts) {
|
|
732
|
+
const p = `artifacts/${a.app}-${a.version}.tar.gz`;
|
|
733
|
+
const e = byEntry.get(p);
|
|
734
|
+
if (!e)
|
|
735
|
+
throw new Error(`Release ${id}: the manifest names ${a.app}@${a.version}, and ${where} has no ${p}`);
|
|
736
|
+
if (e.sha256 !== a.sha256 || e.bytes !== a.bytes) {
|
|
737
|
+
throw new Error(`Release ${id}: ${p} ${where} is ${e.bytes} bytes hashing to ${e.sha256}, ` +
|
|
738
|
+
`and the manifest recorded ${a.bytes} bytes hashing to ${a.sha256 || '(nothing)'}`);
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
const statics = tally(entries.filter((e) => partOf(e.path) === 'statics'));
|
|
742
|
+
if (manifest.statics) {
|
|
743
|
+
if (statics.files !== manifest.statics.files || statics.bytes !== manifest.statics.bytes) {
|
|
744
|
+
throw new Error(`Release ${id}: the static bundle ${where} is ${statics.files} files, ${statics.bytes} bytes, ` +
|
|
745
|
+
`and the manifest recorded ${manifest.statics.files} files, ${manifest.statics.bytes} bytes`);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
else if (statics.files > 0) {
|
|
749
|
+
throw new Error(`Release ${id}: the manifest records no static bundle, and ${where} has ${statics.files} statics file(s)`);
|
|
750
|
+
}
|
|
751
|
+
return { artifacts: manifest.artifacts.length, statics: manifest.statics ? statics : null };
|
|
752
|
+
}
|
|
753
|
+
/** Everything but the attestations, file by file: what makes two copies one build. */
|
|
754
|
+
function compareBuilds(here, there) {
|
|
755
|
+
const ours = new Map(here.filter((e) => !isAttestation(e)).map((e) => [e.path, e]));
|
|
756
|
+
const theirs = new Map(there.filter((e) => !isAttestation(e)).map((e) => [e.path, e]));
|
|
757
|
+
const out = [];
|
|
758
|
+
for (const [p, e] of ours) {
|
|
759
|
+
const t = theirs.get(p);
|
|
760
|
+
if (!t)
|
|
761
|
+
out.push({ path: p, here: e, there: null });
|
|
762
|
+
else if (t.sha256 !== e.sha256 || t.bytes !== e.bytes)
|
|
763
|
+
out.push({ path: p, here: e, there: t });
|
|
764
|
+
}
|
|
765
|
+
for (const [p, t] of theirs)
|
|
766
|
+
if (!ours.has(p))
|
|
767
|
+
out.push({ path: p, here: null, there: t });
|
|
768
|
+
return out.sort(byPath);
|
|
769
|
+
}
|
|
770
|
+
function differentBuild(id, differences, hereName, thereName) {
|
|
771
|
+
const lines = differences.slice(0, 5).map((d) => !d.there
|
|
772
|
+
? `${d.path} is only in ${hereName}`
|
|
773
|
+
: !d.here
|
|
774
|
+
? `${d.path} is only in ${thereName}`
|
|
775
|
+
: `${d.path} hashes to ${d.here.sha256} in ${hereName} and to ${d.there.sha256} in ${thereName}`);
|
|
776
|
+
const more = differences.length > 5 ? `; and ${differences.length - 5} more` : '';
|
|
777
|
+
return (`Release ${id}: ${hereName} and ${thereName} are two different builds under one id — ` +
|
|
778
|
+
`${differences.length} file(s) differ: ${lines.join('; ')}${more}. A release is never replaced; nothing was changed.`);
|
|
779
|
+
}
|
|
780
|
+
/** Which of two copies of one stack's attestation measured later; an unreadable `at` is the older. */
|
|
781
|
+
function measuredLater(candidate, incumbent) {
|
|
782
|
+
const c = candidate ? Date.parse(candidate) : Number.NaN;
|
|
783
|
+
const i = incumbent ? Date.parse(incumbent) : Number.NaN;
|
|
784
|
+
if (Number.isNaN(c))
|
|
785
|
+
return false;
|
|
786
|
+
if (Number.isNaN(i))
|
|
787
|
+
return true;
|
|
788
|
+
return c > i;
|
|
789
|
+
}
|
|
790
|
+
/** Attestations `from` one side that the other should take: absent there, or measured later. */
|
|
791
|
+
function planAttestations(from, into) {
|
|
792
|
+
const existing = new Map(into.map((e) => [e.path, e]));
|
|
793
|
+
const copy = [];
|
|
794
|
+
const kept = [];
|
|
795
|
+
for (const e of from) {
|
|
796
|
+
const there = existing.get(e.path);
|
|
797
|
+
if (!there)
|
|
798
|
+
copy.push(e);
|
|
799
|
+
else if (there.sha256 === e.sha256)
|
|
800
|
+
continue;
|
|
801
|
+
else if (measuredLater(e.at, there.at))
|
|
802
|
+
copy.push(e);
|
|
803
|
+
else
|
|
804
|
+
kept.push({ path: e.path, kept: there.at ?? null, offered: e.at ?? null });
|
|
805
|
+
}
|
|
806
|
+
const replaced = new Set(copy.map((e) => e.path));
|
|
807
|
+
return { copy, kept, merged: [...into.filter((e) => !replaced.has(e.path)), ...copy] };
|
|
808
|
+
}
|
|
809
|
+
async function eachLimited(items, limit, work) {
|
|
810
|
+
let next = 0;
|
|
811
|
+
let failed = false;
|
|
812
|
+
let first;
|
|
813
|
+
const worker = async () => {
|
|
814
|
+
while (!failed && next < items.length) {
|
|
815
|
+
const item = items[next++];
|
|
816
|
+
try {
|
|
817
|
+
await work(item);
|
|
818
|
+
}
|
|
819
|
+
catch (err) {
|
|
820
|
+
if (!failed) {
|
|
821
|
+
failed = true;
|
|
822
|
+
first = err;
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
await Promise.all(Array.from({ length: Math.max(1, Math.min(limit, items.length)) }, worker));
|
|
828
|
+
if (failed)
|
|
829
|
+
throw first;
|
|
830
|
+
}
|
|
831
|
+
/** A path from the index, placed under `dir` — and proved to stay there. */
|
|
832
|
+
function placeOf(dir, rel) {
|
|
833
|
+
const full = path.join(dir, ...rel.split('/'));
|
|
834
|
+
if (!full.startsWith(dir + path.sep))
|
|
835
|
+
throw new Error(`${rel} would land outside ${dir}`);
|
|
836
|
+
return full;
|
|
837
|
+
}
|
|
838
|
+
/**
|
|
839
|
+
* One object, fetched and held to its index entry.
|
|
840
|
+
*
|
|
841
|
+
* Both numbers, both sums, in full: the size says «a link dropped partway»
|
|
842
|
+
* as against «a different file», and a twelve-character prefix is not what
|
|
843
|
+
* an operator can paste into `grep`.
|
|
844
|
+
*/
|
|
845
|
+
async function fetchVerified(store, id, entry, file, consequence) {
|
|
846
|
+
let got;
|
|
847
|
+
try {
|
|
848
|
+
got = await store.get(`${id}/${entry.path}`, file, entry.bytes);
|
|
849
|
+
}
|
|
850
|
+
catch (err) {
|
|
851
|
+
throw new Error(`Release ${id}: ${err.message}. ${consequence}`, { cause: err });
|
|
852
|
+
}
|
|
853
|
+
const repair = `\`omnitron release push ${id} --repair\` on a master that holds the release writes it again.`;
|
|
854
|
+
if (!got) {
|
|
855
|
+
throw new Error(`Release ${id}: the index names ${entry.path}, and ${store.location} does not hold it. ${consequence} ${repair}`);
|
|
856
|
+
}
|
|
857
|
+
if (got.bytes !== entry.bytes || got.sha256 !== entry.sha256) {
|
|
858
|
+
throw new Error(`Release ${id}: ${entry.path} in ${store.location} is ${got.bytes} bytes hashing to ${got.sha256}, ` +
|
|
859
|
+
`and the index recorded ${entry.bytes} bytes hashing to ${entry.sha256} — it is not the object that was pushed. ` +
|
|
860
|
+
`${consequence} ${repair}`);
|
|
861
|
+
}
|
|
862
|
+
if (entry.executable)
|
|
863
|
+
fs.chmodSync(file, 0o755);
|
|
864
|
+
}
|
|
865
|
+
/**
|
|
866
|
+
* Put a release in the store.
|
|
867
|
+
*
|
|
868
|
+
* `loadRelease` first — a release that no longer matches its own manifest on
|
|
869
|
+
* this disk is not put anywhere else — and the static bundle against the
|
|
870
|
+
* manifest's count, which `loadRelease` does not check. Then the objects,
|
|
871
|
+
* each signed with its sum so the store refuses one that changed on the way,
|
|
872
|
+
* and the index last.
|
|
873
|
+
*/
|
|
874
|
+
export async function pushRelease(id, store, options = {}) {
|
|
875
|
+
if (!isReleaseId(id))
|
|
876
|
+
throw new Error(`'${id}' is not a release id`);
|
|
877
|
+
const root = path.resolve(options.root ?? releasesRoot());
|
|
878
|
+
const loaded = await loadRelease(id, root);
|
|
879
|
+
const local = await walkRelease(loaded.root);
|
|
880
|
+
checkAgainstManifest(id, loaded.manifest, local, 'on this disk');
|
|
881
|
+
const indexKey = `${id}/${INDEX_NAME}`;
|
|
882
|
+
const existing = await store.read(indexKey, INDEX_LIMIT);
|
|
883
|
+
const remote = existing ? parseIndex(existing, id, store.location) : null;
|
|
884
|
+
let send = local;
|
|
885
|
+
let files = local;
|
|
886
|
+
let keptNewer = [];
|
|
887
|
+
if (remote) {
|
|
888
|
+
const differences = compareBuilds(local, remote.files);
|
|
889
|
+
if (differences.length > 0)
|
|
890
|
+
throw new Error(differentBuild(id, differences, 'this machine', store.location));
|
|
891
|
+
const plan = planAttestations(local.filter(isAttestation), remote.files.filter(isAttestation));
|
|
892
|
+
const kept = new Set(plan.kept.map((k) => k.path));
|
|
893
|
+
send = options.repair ? local.filter((e) => !kept.has(e.path)) : plan.copy;
|
|
894
|
+
keptNewer = plan.kept;
|
|
895
|
+
files = [...remote.files.filter((e) => !isAttestation(e)), ...plan.merged].sort(byPath);
|
|
896
|
+
if (send.length === 0) {
|
|
897
|
+
return { id, location: store.location, parts: tallyParts(remote.files), moved: tally([]), indexSha256: sha256Hex(existing), keptNewer };
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
const total = tally(send);
|
|
901
|
+
let done = { files: 0, bytes: 0 };
|
|
902
|
+
await eachLimited(send, options.concurrency ?? 8, async (entry) => {
|
|
903
|
+
await store.put(`${id}/${entry.path}`, placeOf(loaded.root, entry.path), entry);
|
|
904
|
+
done = { files: done.files + 1, bytes: done.bytes + entry.bytes };
|
|
905
|
+
options.onProgress?.(done, total);
|
|
906
|
+
});
|
|
907
|
+
// Last, and only now: the index is what makes the release exist in the store.
|
|
908
|
+
const index = {
|
|
909
|
+
format: 1,
|
|
910
|
+
release: id,
|
|
911
|
+
pushedAt: new Date().toISOString(),
|
|
912
|
+
pushedBy: `${os.userInfo().username}@${os.hostname()}`,
|
|
913
|
+
files,
|
|
914
|
+
};
|
|
915
|
+
const body = Buffer.from(`${JSON.stringify(index, null, 2)}\n`);
|
|
916
|
+
const indexSha256 = sha256Hex(body);
|
|
917
|
+
await store.put(indexKey, body, { sha256: indexSha256, bytes: body.length });
|
|
918
|
+
return { id, location: store.location, parts: tallyParts(files), moved: total, indexSha256, keptNewer };
|
|
919
|
+
}
|
|
920
|
+
/**
|
|
921
|
+
* Take a release out of the store onto this machine.
|
|
922
|
+
*
|
|
923
|
+
* Into a directory beside the releases root, checked three ways, then renamed
|
|
924
|
+
* into place: the release appears whole and checked, or not at all. When it
|
|
925
|
+
* is already here, everything but the attestations must be the same build,
|
|
926
|
+
* and only an attestation that measured later is taken.
|
|
927
|
+
*/
|
|
928
|
+
export async function pullRelease(id, store, options = {}) {
|
|
929
|
+
if (!isReleaseId(id))
|
|
930
|
+
throw new Error(`'${id}' is not a release id`);
|
|
931
|
+
const root = path.resolve(options.root ?? releasesRoot());
|
|
932
|
+
const bytes = await store.read(`${id}/${INDEX_NAME}`, INDEX_LIMIT);
|
|
933
|
+
if (!bytes) {
|
|
934
|
+
throw new Error(`${store.location} has no release '${id}': there is no ${id}/${INDEX_NAME}. A push writes it last, so objects ` +
|
|
935
|
+
`without it are a push that did not finish — \`omnitron release push ${id}\` on the master that built it completes one.`);
|
|
936
|
+
}
|
|
937
|
+
const indexSha256 = sha256Hex(bytes);
|
|
938
|
+
const index = parseIndex(bytes, id, store.location);
|
|
939
|
+
const target = path.join(root, id);
|
|
940
|
+
if (fs.existsSync(target)) {
|
|
941
|
+
if (!fs.existsSync(path.join(target, 'manifest.json'))) {
|
|
942
|
+
throw new Error(`${target} is on this machine and holds no manifest.json — a build that did not finish. ` +
|
|
943
|
+
'It was left as it is; remove it, and the pull can put the release there.');
|
|
944
|
+
}
|
|
945
|
+
const local = await walkRelease(target);
|
|
946
|
+
const differences = compareBuilds(local, index.files);
|
|
947
|
+
if (differences.length > 0)
|
|
948
|
+
throw new Error(differentBuild(id, differences, target, store.location));
|
|
949
|
+
const plan = planAttestations(index.files.filter(isAttestation), local.filter(isAttestation));
|
|
950
|
+
for (const entry of plan.copy) {
|
|
951
|
+
const file = placeOf(target, entry.path);
|
|
952
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
953
|
+
// Beside the file and renamed over it: `loadAttestations` reads only
|
|
954
|
+
// `*.json`, so a half-written one is never read as evidence.
|
|
955
|
+
const partial = `${file}.pull-${process.pid}`;
|
|
956
|
+
try {
|
|
957
|
+
await fetchVerified(store, id, entry, partial, `${file} was left as it was.`);
|
|
958
|
+
fs.renameSync(partial, file);
|
|
959
|
+
}
|
|
960
|
+
finally {
|
|
961
|
+
fs.rmSync(partial, { force: true });
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
const loaded = await loadRelease(id, root);
|
|
965
|
+
const checked = checkAgainstManifest(id, loaded.manifest, local, 'on this disk');
|
|
966
|
+
return {
|
|
967
|
+
id,
|
|
968
|
+
location: store.location,
|
|
969
|
+
parts: tallyParts(index.files),
|
|
970
|
+
moved: tally(plan.copy),
|
|
971
|
+
indexSha256,
|
|
972
|
+
keptNewer: plan.kept,
|
|
973
|
+
root: target,
|
|
974
|
+
alreadyHere: true,
|
|
975
|
+
checked,
|
|
976
|
+
};
|
|
977
|
+
}
|
|
978
|
+
fs.mkdirSync(path.dirname(root), { recursive: true });
|
|
979
|
+
const staging = fs.mkdtempSync(path.join(path.dirname(root), `.${path.basename(root)}.pull-`));
|
|
980
|
+
const staged = path.join(staging, id);
|
|
981
|
+
const consequence = `Nothing was written to ${root}.`;
|
|
982
|
+
try {
|
|
983
|
+
const total = tally(index.files);
|
|
984
|
+
let done = { files: 0, bytes: 0 };
|
|
985
|
+
await eachLimited(index.files, options.concurrency ?? 8, async (entry) => {
|
|
986
|
+
const file = placeOf(staged, entry.path);
|
|
987
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
988
|
+
await fetchVerified(store, id, entry, file, consequence);
|
|
989
|
+
done = { files: done.files + 1, bytes: done.bytes + entry.bytes };
|
|
990
|
+
options.onProgress?.(done, total);
|
|
991
|
+
});
|
|
992
|
+
let manifest;
|
|
993
|
+
try {
|
|
994
|
+
manifest = JSON.parse(fs.readFileSync(path.join(staged, 'manifest.json'), 'utf8'));
|
|
995
|
+
}
|
|
996
|
+
catch (err) {
|
|
997
|
+
throw new Error(`Release ${id}: the manifest in the store does not parse (${err.message}). ${consequence}`, {
|
|
998
|
+
cause: err,
|
|
999
|
+
});
|
|
1000
|
+
}
|
|
1001
|
+
let checked;
|
|
1002
|
+
try {
|
|
1003
|
+
checked = checkAgainstManifest(id, manifest, index.files, "in the store's index");
|
|
1004
|
+
// A bundle of no files has no objects, and `loadRelease` asks for the directory.
|
|
1005
|
+
if (manifest.statics)
|
|
1006
|
+
fs.mkdirSync(path.join(staged, 'statics'), { recursive: true });
|
|
1007
|
+
// The deployment's own check, on the copy, before anything is visible.
|
|
1008
|
+
await loadRelease(id, staging);
|
|
1009
|
+
}
|
|
1010
|
+
catch (err) {
|
|
1011
|
+
throw new Error(`${err.message}. ${consequence}`, { cause: err });
|
|
1012
|
+
}
|
|
1013
|
+
fs.mkdirSync(root, { recursive: true });
|
|
1014
|
+
try {
|
|
1015
|
+
fs.renameSync(staged, target);
|
|
1016
|
+
}
|
|
1017
|
+
catch (err) {
|
|
1018
|
+
const code = err.code;
|
|
1019
|
+
if (code === 'ENOTEMPTY' || code === 'EEXIST') {
|
|
1020
|
+
throw new Error(`${target} appeared while this pull ran — it was left as it is, and the copy was discarded`, { cause: err });
|
|
1021
|
+
}
|
|
1022
|
+
throw err;
|
|
1023
|
+
}
|
|
1024
|
+
return {
|
|
1025
|
+
id,
|
|
1026
|
+
location: store.location,
|
|
1027
|
+
parts: tallyParts(index.files),
|
|
1028
|
+
moved: total,
|
|
1029
|
+
indexSha256,
|
|
1030
|
+
keptNewer: [],
|
|
1031
|
+
root: target,
|
|
1032
|
+
alreadyHere: false,
|
|
1033
|
+
checked,
|
|
1034
|
+
};
|
|
1035
|
+
}
|
|
1036
|
+
finally {
|
|
1037
|
+
fs.rmSync(staging, { recursive: true, force: true });
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
//# sourceMappingURL=artifact-store.js.map
|