@omnitron-dev/omnitron 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +35 -0
- package/dist/cli/omnitron.d.ts +9 -0
- package/dist/cli/omnitron.d.ts.map +1 -0
- package/dist/cli/omnitron.js +768 -0
- package/dist/cli/omnitron.js.map +1 -0
- package/dist/cluster/cluster.rpc-service.d.ts +48 -0
- package/dist/cluster/cluster.rpc-service.d.ts.map +1 -0
- package/dist/cluster/cluster.rpc-service.js +105 -0
- package/dist/cluster/cluster.rpc-service.js.map +1 -0
- package/dist/cluster/config-sync.d.ts +89 -0
- package/dist/cluster/config-sync.d.ts.map +1 -0
- package/dist/cluster/config-sync.js +162 -0
- package/dist/cluster/config-sync.js.map +1 -0
- package/dist/cluster/index.d.ts +9 -0
- package/dist/cluster/index.d.ts.map +1 -0
- package/dist/cluster/index.js +7 -0
- package/dist/cluster/index.js.map +1 -0
- package/dist/cluster/leader-election.d.ts +145 -0
- package/dist/cluster/leader-election.d.ts.map +1 -0
- package/dist/cluster/leader-election.js +410 -0
- package/dist/cluster/leader-election.js.map +1 -0
- package/dist/cluster/slave-connector.d.ts +104 -0
- package/dist/cluster/slave-connector.d.ts.map +1 -0
- package/dist/cluster/slave-connector.js +316 -0
- package/dist/cluster/slave-connector.js.map +1 -0
- package/dist/commands/backup.d.ts +9 -0
- package/dist/commands/backup.d.ts.map +1 -0
- package/dist/commands/backup.js +81 -0
- package/dist/commands/backup.js.map +1 -0
- package/dist/commands/cluster.d.ts +9 -0
- package/dist/commands/cluster.d.ts.map +1 -0
- package/dist/commands/cluster.js +148 -0
- package/dist/commands/cluster.js.map +1 -0
- package/dist/commands/daemon-cmd.d.ts +11 -0
- package/dist/commands/daemon-cmd.d.ts.map +1 -0
- package/dist/commands/daemon-cmd.js +182 -0
- package/dist/commands/daemon-cmd.js.map +1 -0
- package/dist/commands/deploy.d.ts +17 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +110 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/dev.d.ts +23 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +76 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/discover.d.ts +9 -0
- package/dist/commands/discover.d.ts.map +1 -0
- package/dist/commands/discover.js +124 -0
- package/dist/commands/discover.js.map +1 -0
- package/dist/commands/env.d.ts +5 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +30 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/exec.d.ts +5 -0
- package/dist/commands/exec.d.ts.map +1 -0
- package/dist/commands/exec.js +36 -0
- package/dist/commands/exec.js.map +1 -0
- package/dist/commands/fleet.d.ts +9 -0
- package/dist/commands/fleet.d.ts.map +1 -0
- package/dist/commands/fleet.js +136 -0
- package/dist/commands/fleet.js.map +1 -0
- package/dist/commands/health-check.d.ts +12 -0
- package/dist/commands/health-check.d.ts.map +1 -0
- package/dist/commands/health-check.js +91 -0
- package/dist/commands/health-check.js.map +1 -0
- package/dist/commands/health.d.ts +7 -0
- package/dist/commands/health.d.ts.map +1 -0
- package/dist/commands/health.js +44 -0
- package/dist/commands/health.js.map +1 -0
- package/dist/commands/infra.d.ts +32 -0
- package/dist/commands/infra.d.ts.map +1 -0
- package/dist/commands/infra.js +179 -0
- package/dist/commands/infra.js.map +1 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +78 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/inspect.d.ts +7 -0
- package/dist/commands/inspect.d.ts.map +1 -0
- package/dist/commands/inspect.js +95 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/k8s.d.ts +7 -0
- package/dist/commands/k8s.d.ts.map +1 -0
- package/dist/commands/k8s.js +74 -0
- package/dist/commands/k8s.js.map +1 -0
- package/dist/commands/kb.d.ts +21 -0
- package/dist/commands/kb.d.ts.map +1 -0
- package/dist/commands/kb.js +137 -0
- package/dist/commands/kb.js.map +1 -0
- package/dist/commands/list.d.ts +7 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +77 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/logs.d.ts +17 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +287 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/metrics.d.ts +7 -0
- package/dist/commands/metrics.d.ts.map +1 -0
- package/dist/commands/metrics.js +64 -0
- package/dist/commands/metrics.js.map +1 -0
- package/dist/commands/monit.d.ts +7 -0
- package/dist/commands/monit.d.ts.map +1 -0
- package/dist/commands/monit.js +90 -0
- package/dist/commands/monit.js.map +1 -0
- package/dist/commands/node.d.ts +33 -0
- package/dist/commands/node.d.ts.map +1 -0
- package/dist/commands/node.js +169 -0
- package/dist/commands/node.js.map +1 -0
- package/dist/commands/pipeline.d.ts +9 -0
- package/dist/commands/pipeline.d.ts.map +1 -0
- package/dist/commands/pipeline.js +89 -0
- package/dist/commands/pipeline.js.map +1 -0
- package/dist/commands/project.d.ts +11 -0
- package/dist/commands/project.d.ts.map +1 -0
- package/dist/commands/project.js +54 -0
- package/dist/commands/project.js.map +1 -0
- package/dist/commands/reload.d.ts +5 -0
- package/dist/commands/reload.d.ts.map +1 -0
- package/dist/commands/reload.js +31 -0
- package/dist/commands/reload.js.map +1 -0
- package/dist/commands/remote.d.ts +13 -0
- package/dist/commands/remote.d.ts.map +1 -0
- package/dist/commands/remote.js +88 -0
- package/dist/commands/remote.js.map +1 -0
- package/dist/commands/restart.d.ts +5 -0
- package/dist/commands/restart.d.ts.map +1 -0
- package/dist/commands/restart.js +31 -0
- package/dist/commands/restart.js.map +1 -0
- package/dist/commands/scale.d.ts +5 -0
- package/dist/commands/scale.d.ts.map +1 -0
- package/dist/commands/scale.js +29 -0
- package/dist/commands/scale.js.map +1 -0
- package/dist/commands/secret.d.ts +14 -0
- package/dist/commands/secret.d.ts.map +1 -0
- package/dist/commands/secret.js +148 -0
- package/dist/commands/secret.js.map +1 -0
- package/dist/commands/stack.d.ts +18 -0
- package/dist/commands/stack.d.ts.map +1 -0
- package/dist/commands/stack.js +252 -0
- package/dist/commands/stack.js.map +1 -0
- package/dist/commands/start.d.ts +7 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +43 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +9 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +70 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +10 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +69 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/commands/up.d.ts +47 -0
- package/dist/commands/up.d.ts.map +1 -0
- package/dist/commands/up.js +278 -0
- package/dist/commands/up.js.map +1 -0
- package/dist/commands/webapp.d.ts +17 -0
- package/dist/commands/webapp.d.ts.map +1 -0
- package/dist/commands/webapp.js +103 -0
- package/dist/commands/webapp.js.map +1 -0
- package/dist/config/defaults.d.ts +22 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +76 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/define-app.d.ts +6 -0
- package/dist/config/define-app.d.ts.map +1 -0
- package/dist/config/define-app.js +38 -0
- package/dist/config/define-app.js.map +1 -0
- package/dist/config/define-ecosystem.d.ts +6 -0
- package/dist/config/define-ecosystem.d.ts.map +1 -0
- package/dist/config/define-ecosystem.js +21 -0
- package/dist/config/define-ecosystem.js.map +1 -0
- package/dist/config/define-system.d.ts +9 -0
- package/dist/config/define-system.d.ts.map +1 -0
- package/dist/config/define-system.js +106 -0
- package/dist/config/define-system.js.map +1 -0
- package/dist/config/index.d.ts +7 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +6 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +11 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +68 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/omnitron-config.schema.d.ts +14 -0
- package/dist/config/omnitron-config.schema.d.ts.map +1 -0
- package/dist/config/omnitron-config.schema.js +35 -0
- package/dist/config/omnitron-config.schema.js.map +1 -0
- package/dist/config/types.d.ts +807 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +7 -0
- package/dist/config/types.js.map +1 -0
- package/dist/daemon/daemon-client.d.ts +147 -0
- package/dist/daemon/daemon-client.d.ts.map +1 -0
- package/dist/daemon/daemon-client.js +256 -0
- package/dist/daemon/daemon-client.js.map +1 -0
- package/dist/daemon/daemon-entry.d.ts +9 -0
- package/dist/daemon/daemon-entry.d.ts.map +1 -0
- package/dist/daemon/daemon-entry.js +62 -0
- package/dist/daemon/daemon-entry.js.map +1 -0
- package/dist/daemon/daemon-scheduler.d.ts +32 -0
- package/dist/daemon/daemon-scheduler.d.ts.map +1 -0
- package/dist/daemon/daemon-scheduler.js +93 -0
- package/dist/daemon/daemon-scheduler.js.map +1 -0
- package/dist/daemon/daemon.d.ts +115 -0
- package/dist/daemon/daemon.d.ts.map +1 -0
- package/dist/daemon/daemon.js +1202 -0
- package/dist/daemon/daemon.js.map +1 -0
- package/dist/daemon/daemon.module.d.ts +50 -0
- package/dist/daemon/daemon.module.d.ts.map +1 -0
- package/dist/daemon/daemon.module.js +506 -0
- package/dist/daemon/daemon.module.js.map +1 -0
- package/dist/daemon/daemon.rpc-service.d.ts +122 -0
- package/dist/daemon/daemon.rpc-service.d.ts.map +1 -0
- package/dist/daemon/daemon.rpc-service.js +452 -0
- package/dist/daemon/daemon.rpc-service.js.map +1 -0
- package/dist/daemon/pid-manager.d.ts +43 -0
- package/dist/daemon/pid-manager.d.ts.map +1 -0
- package/dist/daemon/pid-manager.js +103 -0
- package/dist/daemon/pid-manager.js.map +1 -0
- package/dist/daemon/state-store.d.ts +26 -0
- package/dist/daemon/state-store.d.ts.map +1 -0
- package/dist/daemon/state-store.js +34 -0
- package/dist/daemon/state-store.js.map +1 -0
- package/dist/database/index.d.ts +10 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +10 -0
- package/dist/database/index.js.map +1 -0
- package/dist/database/migrate.d.ts +11 -0
- package/dist/database/migrate.d.ts.map +1 -0
- package/dist/database/migrate.js +62 -0
- package/dist/database/migrate.js.map +1 -0
- package/dist/database/migrations/001_initial_schema.d.ts +12 -0
- package/dist/database/migrations/001_initial_schema.d.ts.map +1 -0
- package/dist/database/migrations/001_initial_schema.js +246 -0
- package/dist/database/migrations/001_initial_schema.js.map +1 -0
- package/dist/database/migrations/002_metrics_raw.d.ts +17 -0
- package/dist/database/migrations/002_metrics_raw.d.ts.map +1 -0
- package/dist/database/migrations/002_metrics_raw.js +44 -0
- package/dist/database/migrations/002_metrics_raw.js.map +1 -0
- package/dist/database/migrations/003_pipelines_traces.d.ts +14 -0
- package/dist/database/migrations/003_pipelines_traces.d.ts.map +1 -0
- package/dist/database/migrations/003_pipelines_traces.js +108 -0
- package/dist/database/migrations/003_pipelines_traces.js.map +1 -0
- package/dist/database/migrations/004_sync_buffer.d.ts +17 -0
- package/dist/database/migrations/004_sync_buffer.d.ts.map +1 -0
- package/dist/database/migrations/004_sync_buffer.js +59 -0
- package/dist/database/migrations/004_sync_buffer.js.map +1 -0
- package/dist/database/migrations/005_node_health_checks.d.ts +11 -0
- package/dist/database/migrations/005_node_health_checks.d.ts.map +1 -0
- package/dist/database/migrations/005_node_health_checks.js +71 -0
- package/dist/database/migrations/005_node_health_checks.js.map +1 -0
- package/dist/database/schema.d.ts +217 -0
- package/dist/database/schema.d.ts.map +1 -0
- package/dist/database/schema.js +9 -0
- package/dist/database/schema.js.map +1 -0
- package/dist/execution/execution.service.d.ts +72 -0
- package/dist/execution/execution.service.d.ts.map +1 -0
- package/dist/execution/execution.service.js +191 -0
- package/dist/execution/execution.service.js.map +1 -0
- package/dist/execution/index.d.ts +3 -0
- package/dist/execution/index.d.ts.map +1 -0
- package/dist/execution/index.js +2 -0
- package/dist/execution/index.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/infrastructure/config-normalizer.d.ts +13 -0
- package/dist/infrastructure/config-normalizer.d.ts.map +1 -0
- package/dist/infrastructure/config-normalizer.js +84 -0
- package/dist/infrastructure/config-normalizer.js.map +1 -0
- package/dist/infrastructure/container-runtime.d.ts +63 -0
- package/dist/infrastructure/container-runtime.d.ts.map +1 -0
- package/dist/infrastructure/container-runtime.js +304 -0
- package/dist/infrastructure/container-runtime.js.map +1 -0
- package/dist/infrastructure/gateway-generator.d.ts +63 -0
- package/dist/infrastructure/gateway-generator.d.ts.map +1 -0
- package/dist/infrastructure/gateway-generator.js +253 -0
- package/dist/infrastructure/gateway-generator.js.map +1 -0
- package/dist/infrastructure/index.d.ts +5 -0
- package/dist/infrastructure/index.d.ts.map +1 -0
- package/dist/infrastructure/index.js +5 -0
- package/dist/infrastructure/index.js.map +1 -0
- package/dist/infrastructure/infrastructure-gate.d.ts +48 -0
- package/dist/infrastructure/infrastructure-gate.d.ts.map +1 -0
- package/dist/infrastructure/infrastructure-gate.js +92 -0
- package/dist/infrastructure/infrastructure-gate.js.map +1 -0
- package/dist/infrastructure/infrastructure.service.d.ts +84 -0
- package/dist/infrastructure/infrastructure.service.d.ts.map +1 -0
- package/dist/infrastructure/infrastructure.service.js +502 -0
- package/dist/infrastructure/infrastructure.service.js.map +1 -0
- package/dist/infrastructure/presets/gateway-openresty.d.ts +10 -0
- package/dist/infrastructure/presets/gateway-openresty.d.ts.map +1 -0
- package/dist/infrastructure/presets/gateway-openresty.js +30 -0
- package/dist/infrastructure/presets/gateway-openresty.js.map +1 -0
- package/dist/infrastructure/presets/index.d.ts +14 -0
- package/dist/infrastructure/presets/index.d.ts.map +1 -0
- package/dist/infrastructure/presets/index.js +24 -0
- package/dist/infrastructure/presets/index.js.map +1 -0
- package/dist/infrastructure/presets/minio.d.ts +10 -0
- package/dist/infrastructure/presets/minio.d.ts.map +1 -0
- package/dist/infrastructure/presets/minio.js +60 -0
- package/dist/infrastructure/presets/minio.js.map +1 -0
- package/dist/infrastructure/presets/postgres.d.ts +9 -0
- package/dist/infrastructure/presets/postgres.d.ts.map +1 -0
- package/dist/infrastructure/presets/postgres.js +80 -0
- package/dist/infrastructure/presets/postgres.js.map +1 -0
- package/dist/infrastructure/presets/redis.d.ts +9 -0
- package/dist/infrastructure/presets/redis.d.ts.map +1 -0
- package/dist/infrastructure/presets/redis.js +32 -0
- package/dist/infrastructure/presets/redis.js.map +1 -0
- package/dist/infrastructure/presets/registry.d.ts +21 -0
- package/dist/infrastructure/presets/registry.d.ts.map +1 -0
- package/dist/infrastructure/presets/registry.js +87 -0
- package/dist/infrastructure/presets/registry.js.map +1 -0
- package/dist/infrastructure/presets/types.d.ts +88 -0
- package/dist/infrastructure/presets/types.d.ts.map +1 -0
- package/dist/infrastructure/presets/types.js +14 -0
- package/dist/infrastructure/presets/types.js.map +1 -0
- package/dist/infrastructure/runtime/types.d.ts +35 -0
- package/dist/infrastructure/runtime/types.d.ts.map +1 -0
- package/dist/infrastructure/runtime/types.js +9 -0
- package/dist/infrastructure/runtime/types.js.map +1 -0
- package/dist/infrastructure/server-registry.d.ts +16 -0
- package/dist/infrastructure/server-registry.d.ts.map +1 -0
- package/dist/infrastructure/server-registry.js +45 -0
- package/dist/infrastructure/server-registry.js.map +1 -0
- package/dist/infrastructure/service-resolver.d.ts +93 -0
- package/dist/infrastructure/service-resolver.d.ts.map +1 -0
- package/dist/infrastructure/service-resolver.js +419 -0
- package/dist/infrastructure/service-resolver.js.map +1 -0
- package/dist/infrastructure/stack-infra-manager.d.ts +81 -0
- package/dist/infrastructure/stack-infra-manager.d.ts.map +1 -0
- package/dist/infrastructure/stack-infra-manager.js +309 -0
- package/dist/infrastructure/stack-infra-manager.js.map +1 -0
- package/dist/infrastructure/types.d.ts +413 -0
- package/dist/infrastructure/types.d.ts.map +1 -0
- package/dist/infrastructure/types.js +10 -0
- package/dist/infrastructure/types.js.map +1 -0
- package/dist/mcp/mcp-bridge.d.ts +21 -0
- package/dist/mcp/mcp-bridge.d.ts.map +1 -0
- package/dist/mcp/mcp-bridge.js +126 -0
- package/dist/mcp/mcp-bridge.js.map +1 -0
- package/dist/mcp/tool-groups/apps.tools.d.ts +7 -0
- package/dist/mcp/tool-groups/apps.tools.d.ts.map +1 -0
- package/dist/mcp/tool-groups/apps.tools.js +104 -0
- package/dist/mcp/tool-groups/apps.tools.js.map +1 -0
- package/dist/mcp/tool-groups/infra.tools.d.ts +7 -0
- package/dist/mcp/tool-groups/infra.tools.d.ts.map +1 -0
- package/dist/mcp/tool-groups/infra.tools.js +80 -0
- package/dist/mcp/tool-groups/infra.tools.js.map +1 -0
- package/dist/mcp/tool-groups/kb.tools.d.ts +7 -0
- package/dist/mcp/tool-groups/kb.tools.d.ts.map +1 -0
- package/dist/mcp/tool-groups/kb.tools.js +147 -0
- package/dist/mcp/tool-groups/kb.tools.js.map +1 -0
- package/dist/mcp/tool-groups/management.tools.d.ts +7 -0
- package/dist/mcp/tool-groups/management.tools.d.ts.map +1 -0
- package/dist/mcp/tool-groups/management.tools.js +263 -0
- package/dist/mcp/tool-groups/management.tools.js.map +1 -0
- package/dist/mcp/tool-groups/monitoring.tools.d.ts +6 -0
- package/dist/mcp/tool-groups/monitoring.tools.d.ts.map +1 -0
- package/dist/mcp/tool-groups/monitoring.tools.js +52 -0
- package/dist/mcp/tool-groups/monitoring.tools.js.map +1 -0
- package/dist/mcp/types.d.ts +23 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +2 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/monitoring/app-health.indicator.d.ts +16 -0
- package/dist/monitoring/app-health.indicator.d.ts.map +1 -0
- package/dist/monitoring/app-health.indicator.js +45 -0
- package/dist/monitoring/app-health.indicator.js.map +1 -0
- package/dist/monitoring/docker-health.indicator.d.ts +19 -0
- package/dist/monitoring/docker-health.indicator.d.ts.map +1 -0
- package/dist/monitoring/docker-health.indicator.js +52 -0
- package/dist/monitoring/docker-health.indicator.js.map +1 -0
- package/dist/monitoring/health.service.d.ts +14 -0
- package/dist/monitoring/health.service.d.ts.map +1 -0
- package/dist/monitoring/health.service.js +50 -0
- package/dist/monitoring/health.service.js.map +1 -0
- package/dist/monitoring/log-manager.d.ts +88 -0
- package/dist/monitoring/log-manager.d.ts.map +1 -0
- package/dist/monitoring/log-manager.js +353 -0
- package/dist/monitoring/log-manager.js.map +1 -0
- package/dist/monitoring/metrics.service.d.ts +14 -0
- package/dist/monitoring/metrics.service.d.ts.map +1 -0
- package/dist/monitoring/metrics.service.js +40 -0
- package/dist/monitoring/metrics.service.js.map +1 -0
- package/dist/orchestrator/app-handle.d.ts +51 -0
- package/dist/orchestrator/app-handle.d.ts.map +1 -0
- package/dist/orchestrator/app-handle.js +90 -0
- package/dist/orchestrator/app-handle.js.map +1 -0
- package/dist/orchestrator/bootstrap-loader.d.ts +36 -0
- package/dist/orchestrator/bootstrap-loader.d.ts.map +1 -0
- package/dist/orchestrator/bootstrap-loader.js +118 -0
- package/dist/orchestrator/bootstrap-loader.js.map +1 -0
- package/dist/orchestrator/bootstrap-process.d.ts +73 -0
- package/dist/orchestrator/bootstrap-process.d.ts.map +1 -0
- package/dist/orchestrator/bootstrap-process.js +342 -0
- package/dist/orchestrator/bootstrap-process.js.map +1 -0
- package/dist/orchestrator/bootstrap-runner.d.ts +15 -0
- package/dist/orchestrator/bootstrap-runner.d.ts.map +1 -0
- package/dist/orchestrator/bootstrap-runner.js +152 -0
- package/dist/orchestrator/bootstrap-runner.js.map +1 -0
- package/dist/orchestrator/build-service.d.ts +70 -0
- package/dist/orchestrator/build-service.d.ts.map +1 -0
- package/dist/orchestrator/build-service.js +313 -0
- package/dist/orchestrator/build-service.js.map +1 -0
- package/dist/orchestrator/classic-launcher.d.ts +17 -0
- package/dist/orchestrator/classic-launcher.d.ts.map +1 -0
- package/dist/orchestrator/classic-launcher.js +111 -0
- package/dist/orchestrator/classic-launcher.js.map +1 -0
- package/dist/orchestrator/dependency-resolver.d.ts +14 -0
- package/dist/orchestrator/dependency-resolver.d.ts.map +1 -0
- package/dist/orchestrator/dependency-resolver.js +56 -0
- package/dist/orchestrator/dependency-resolver.js.map +1 -0
- package/dist/orchestrator/file-watcher.d.ts +53 -0
- package/dist/orchestrator/file-watcher.d.ts.map +1 -0
- package/dist/orchestrator/file-watcher.js +307 -0
- package/dist/orchestrator/file-watcher.js.map +1 -0
- package/dist/orchestrator/module-worker-process.d.ts +37 -0
- package/dist/orchestrator/module-worker-process.d.ts.map +1 -0
- package/dist/orchestrator/module-worker-process.js +187 -0
- package/dist/orchestrator/module-worker-process.js.map +1 -0
- package/dist/orchestrator/orchestrator.service.d.ts +170 -0
- package/dist/orchestrator/orchestrator.service.d.ts.map +1 -0
- package/dist/orchestrator/orchestrator.service.js +1146 -0
- package/dist/orchestrator/orchestrator.service.js.map +1 -0
- package/dist/orchestrator/service-router.d.ts +78 -0
- package/dist/orchestrator/service-router.d.ts.map +1 -0
- package/dist/orchestrator/service-router.js +148 -0
- package/dist/orchestrator/service-router.js.map +1 -0
- package/dist/orchestrator/topology-proxy.d.ts +65 -0
- package/dist/orchestrator/topology-proxy.d.ts.map +1 -0
- package/dist/orchestrator/topology-proxy.js +209 -0
- package/dist/orchestrator/topology-proxy.js.map +1 -0
- package/dist/orchestrator/topology-relay.d.ts +111 -0
- package/dist/orchestrator/topology-relay.d.ts.map +1 -0
- package/dist/orchestrator/topology-relay.js +255 -0
- package/dist/orchestrator/topology-relay.js.map +1 -0
- package/dist/orchestrator/ts-compiler.d.ts +55 -0
- package/dist/orchestrator/ts-compiler.d.ts.map +1 -0
- package/dist/orchestrator/ts-compiler.js +166 -0
- package/dist/orchestrator/ts-compiler.js.map +1 -0
- package/dist/project/artifact-builder.d.ts +63 -0
- package/dist/project/artifact-builder.d.ts.map +1 -0
- package/dist/project/artifact-builder.js +193 -0
- package/dist/project/artifact-builder.js.map +1 -0
- package/dist/project/config-resolver.d.ts +110 -0
- package/dist/project/config-resolver.d.ts.map +1 -0
- package/dist/project/config-resolver.js +563 -0
- package/dist/project/config-resolver.js.map +1 -0
- package/dist/project/dependency-analyzer.d.ts +53 -0
- package/dist/project/dependency-analyzer.d.ts.map +1 -0
- package/dist/project/dependency-analyzer.js +135 -0
- package/dist/project/dependency-analyzer.js.map +1 -0
- package/dist/project/index.d.ts +10 -0
- package/dist/project/index.d.ts.map +1 -0
- package/dist/project/index.js +6 -0
- package/dist/project/index.js.map +1 -0
- package/dist/project/registry.d.ts +28 -0
- package/dist/project/registry.d.ts.map +1 -0
- package/dist/project/registry.js +117 -0
- package/dist/project/registry.js.map +1 -0
- package/dist/project/requirements-scanner.d.ts +65 -0
- package/dist/project/requirements-scanner.d.ts.map +1 -0
- package/dist/project/requirements-scanner.js +217 -0
- package/dist/project/requirements-scanner.js.map +1 -0
- package/dist/services/alert.rpc-service.d.ts +41 -0
- package/dist/services/alert.rpc-service.d.ts.map +1 -0
- package/dist/services/alert.rpc-service.js +102 -0
- package/dist/services/alert.rpc-service.js.map +1 -0
- package/dist/services/alert.service.d.ts +83 -0
- package/dist/services/alert.service.d.ts.map +1 -0
- package/dist/services/alert.service.js +277 -0
- package/dist/services/alert.service.js.map +1 -0
- package/dist/services/auth-context.d.ts +39 -0
- package/dist/services/auth-context.d.ts.map +1 -0
- package/dist/services/auth-context.js +66 -0
- package/dist/services/auth-context.js.map +1 -0
- package/dist/services/auth-middleware.d.ts +47 -0
- package/dist/services/auth-middleware.d.ts.map +1 -0
- package/dist/services/auth-middleware.js +158 -0
- package/dist/services/auth-middleware.js.map +1 -0
- package/dist/services/auth.rpc-service.d.ts +61 -0
- package/dist/services/auth.rpc-service.d.ts.map +1 -0
- package/dist/services/auth.rpc-service.js +131 -0
- package/dist/services/auth.rpc-service.js.map +1 -0
- package/dist/services/auth.service.d.ts +70 -0
- package/dist/services/auth.service.d.ts.map +1 -0
- package/dist/services/auth.service.js +310 -0
- package/dist/services/auth.service.js.map +1 -0
- package/dist/services/backup.rpc-service.d.ts +37 -0
- package/dist/services/backup.rpc-service.d.ts.map +1 -0
- package/dist/services/backup.rpc-service.js +85 -0
- package/dist/services/backup.rpc-service.js.map +1 -0
- package/dist/services/backup.service.d.ts +45 -0
- package/dist/services/backup.service.d.ts.map +1 -0
- package/dist/services/backup.service.js +299 -0
- package/dist/services/backup.service.js.map +1 -0
- package/dist/services/deploy.rpc-service.d.ts +26 -0
- package/dist/services/deploy.rpc-service.d.ts.map +1 -0
- package/dist/services/deploy.rpc-service.js +61 -0
- package/dist/services/deploy.rpc-service.js.map +1 -0
- package/dist/services/deploy.service.d.ts +85 -0
- package/dist/services/deploy.service.d.ts.map +1 -0
- package/dist/services/deploy.service.js +269 -0
- package/dist/services/deploy.service.js.map +1 -0
- package/dist/services/discovery.rpc-service.d.ts +16 -0
- package/dist/services/discovery.rpc-service.d.ts.map +1 -0
- package/dist/services/discovery.rpc-service.js +55 -0
- package/dist/services/discovery.rpc-service.js.map +1 -0
- package/dist/services/discovery.service.d.ts +43 -0
- package/dist/services/discovery.service.d.ts.map +1 -0
- package/dist/services/discovery.service.js +178 -0
- package/dist/services/discovery.service.js.map +1 -0
- package/dist/services/environment.rpc-service.d.ts +22 -0
- package/dist/services/environment.rpc-service.d.ts.map +1 -0
- package/dist/services/environment.rpc-service.js +65 -0
- package/dist/services/environment.rpc-service.js.map +1 -0
- package/dist/services/environment.service.d.ts +87 -0
- package/dist/services/environment.service.d.ts.map +1 -0
- package/dist/services/environment.service.js +220 -0
- package/dist/services/environment.service.js.map +1 -0
- package/dist/services/event-broadcaster.rpc-service.d.ts +44 -0
- package/dist/services/event-broadcaster.rpc-service.d.ts.map +1 -0
- package/dist/services/event-broadcaster.rpc-service.js +84 -0
- package/dist/services/event-broadcaster.rpc-service.js.map +1 -0
- package/dist/services/event-broadcaster.service.d.ts +42 -0
- package/dist/services/event-broadcaster.service.d.ts.map +1 -0
- package/dist/services/event-broadcaster.service.js +87 -0
- package/dist/services/event-broadcaster.service.js.map +1 -0
- package/dist/services/fleet.rpc-service.d.ts +37 -0
- package/dist/services/fleet.rpc-service.d.ts.map +1 -0
- package/dist/services/fleet.rpc-service.js +104 -0
- package/dist/services/fleet.rpc-service.js.map +1 -0
- package/dist/services/fleet.service.d.ts +104 -0
- package/dist/services/fleet.service.d.ts.map +1 -0
- package/dist/services/fleet.service.js +243 -0
- package/dist/services/fleet.service.js.map +1 -0
- package/dist/services/health-check.rpc-service.d.ts +18 -0
- package/dist/services/health-check.rpc-service.d.ts.map +1 -0
- package/dist/services/health-check.rpc-service.js +64 -0
- package/dist/services/health-check.rpc-service.js.map +1 -0
- package/dist/services/health-check.service.d.ts +53 -0
- package/dist/services/health-check.service.d.ts.map +1 -0
- package/dist/services/health-check.service.js +232 -0
- package/dist/services/health-check.service.js.map +1 -0
- package/dist/services/infrastructure.rpc-service.d.ts +18 -0
- package/dist/services/infrastructure.rpc-service.d.ts.map +1 -0
- package/dist/services/infrastructure.rpc-service.js +64 -0
- package/dist/services/infrastructure.rpc-service.js.map +1 -0
- package/dist/services/kubernetes.rpc-service.d.ts +54 -0
- package/dist/services/kubernetes.rpc-service.d.ts.map +1 -0
- package/dist/services/kubernetes.rpc-service.js +112 -0
- package/dist/services/kubernetes.rpc-service.js.map +1 -0
- package/dist/services/kubernetes.service.d.ts +71 -0
- package/dist/services/kubernetes.service.d.ts.map +1 -0
- package/dist/services/kubernetes.service.js +244 -0
- package/dist/services/kubernetes.service.js.map +1 -0
- package/dist/services/log-collector.rpc-service.d.ts +38 -0
- package/dist/services/log-collector.rpc-service.d.ts.map +1 -0
- package/dist/services/log-collector.rpc-service.js +74 -0
- package/dist/services/log-collector.rpc-service.js.map +1 -0
- package/dist/services/log-collector.service.d.ts +96 -0
- package/dist/services/log-collector.service.d.ts.map +1 -0
- package/dist/services/log-collector.service.js +303 -0
- package/dist/services/log-collector.service.js.map +1 -0
- package/dist/services/metrics-collector.service.d.ts +103 -0
- package/dist/services/metrics-collector.service.d.ts.map +1 -0
- package/dist/services/metrics-collector.service.js +235 -0
- package/dist/services/metrics-collector.service.js.map +1 -0
- package/dist/services/metrics.rpc-service.d.ts +41 -0
- package/dist/services/metrics.rpc-service.d.ts.map +1 -0
- package/dist/services/metrics.rpc-service.js +90 -0
- package/dist/services/metrics.rpc-service.js.map +1 -0
- package/dist/services/metrics.service.d.ts +72 -0
- package/dist/services/metrics.service.d.ts.map +1 -0
- package/dist/services/metrics.service.js +185 -0
- package/dist/services/metrics.service.js.map +1 -0
- package/dist/services/netron-telemetry-transport.d.ts +42 -0
- package/dist/services/netron-telemetry-transport.d.ts.map +1 -0
- package/dist/services/netron-telemetry-transport.js +97 -0
- package/dist/services/netron-telemetry-transport.js.map +1 -0
- package/dist/services/node-health.repository.d.ts +65 -0
- package/dist/services/node-health.repository.d.ts.map +1 -0
- package/dist/services/node-health.repository.js +132 -0
- package/dist/services/node-health.repository.js.map +1 -0
- package/dist/services/node-manager.rpc-service.d.ts +66 -0
- package/dist/services/node-manager.rpc-service.d.ts.map +1 -0
- package/dist/services/node-manager.rpc-service.js +229 -0
- package/dist/services/node-manager.rpc-service.js.map +1 -0
- package/dist/services/node-manager.service.d.ts +149 -0
- package/dist/services/node-manager.service.d.ts.map +1 -0
- package/dist/services/node-manager.service.js +547 -0
- package/dist/services/node-manager.service.js.map +1 -0
- package/dist/services/pipeline.rpc-service.d.ts +37 -0
- package/dist/services/pipeline.rpc-service.d.ts.map +1 -0
- package/dist/services/pipeline.rpc-service.js +102 -0
- package/dist/services/pipeline.rpc-service.js.map +1 -0
- package/dist/services/pipeline.service.d.ts +77 -0
- package/dist/services/pipeline.service.d.ts.map +1 -0
- package/dist/services/pipeline.service.js +278 -0
- package/dist/services/pipeline.service.js.map +1 -0
- package/dist/services/project.rpc-service.d.ts +73 -0
- package/dist/services/project.rpc-service.d.ts.map +1 -0
- package/dist/services/project.rpc-service.js +184 -0
- package/dist/services/project.rpc-service.js.map +1 -0
- package/dist/services/project.service.d.ts +123 -0
- package/dist/services/project.service.d.ts.map +1 -0
- package/dist/services/project.service.js +1112 -0
- package/dist/services/project.service.js.map +1 -0
- package/dist/services/remote-deployer.service.d.ts +85 -0
- package/dist/services/remote-deployer.service.d.ts.map +1 -0
- package/dist/services/remote-deployer.service.js +332 -0
- package/dist/services/remote-deployer.service.js.map +1 -0
- package/dist/services/remote-ops.service.d.ts +72 -0
- package/dist/services/remote-ops.service.d.ts.map +1 -0
- package/dist/services/remote-ops.service.js +132 -0
- package/dist/services/remote-ops.service.js.map +1 -0
- package/dist/services/secrets.rpc-service.d.ts +45 -0
- package/dist/services/secrets.rpc-service.d.ts.map +1 -0
- package/dist/services/secrets.rpc-service.js +81 -0
- package/dist/services/secrets.rpc-service.js.map +1 -0
- package/dist/services/secrets.service.d.ts +57 -0
- package/dist/services/secrets.service.d.ts.map +1 -0
- package/dist/services/secrets.service.js +211 -0
- package/dist/services/secrets.service.js.map +1 -0
- package/dist/services/slave-storage.service.d.ts +69 -0
- package/dist/services/slave-storage.service.d.ts.map +1 -0
- package/dist/services/slave-storage.service.js +131 -0
- package/dist/services/slave-storage.service.js.map +1 -0
- package/dist/services/sync.rpc-service.d.ts +37 -0
- package/dist/services/sync.rpc-service.d.ts.map +1 -0
- package/dist/services/sync.rpc-service.js +72 -0
- package/dist/services/sync.rpc-service.js.map +1 -0
- package/dist/services/sync.service.d.ts +121 -0
- package/dist/services/sync.service.d.ts.map +1 -0
- package/dist/services/sync.service.js +440 -0
- package/dist/services/sync.service.js.map +1 -0
- package/dist/services/system-info.rpc-service.d.ts +12 -0
- package/dist/services/system-info.rpc-service.d.ts.map +1 -0
- package/dist/services/system-info.rpc-service.js +37 -0
- package/dist/services/system-info.rpc-service.js.map +1 -0
- package/dist/services/system-info.service.d.ts +89 -0
- package/dist/services/system-info.service.d.ts.map +1 -0
- package/dist/services/system-info.service.js +151 -0
- package/dist/services/system-info.service.js.map +1 -0
- package/dist/services/telemetry.rpc-service.d.ts +27 -0
- package/dist/services/telemetry.rpc-service.d.ts.map +1 -0
- package/dist/services/telemetry.rpc-service.js +56 -0
- package/dist/services/telemetry.rpc-service.js.map +1 -0
- package/dist/services/telemetry.service.d.ts +31 -0
- package/dist/services/telemetry.service.d.ts.map +1 -0
- package/dist/services/telemetry.service.js +134 -0
- package/dist/services/telemetry.service.js.map +1 -0
- package/dist/services/trace-collector.rpc-service.d.ts +24 -0
- package/dist/services/trace-collector.rpc-service.d.ts.map +1 -0
- package/dist/services/trace-collector.rpc-service.js +75 -0
- package/dist/services/trace-collector.rpc-service.js.map +1 -0
- package/dist/services/trace-collector.service.d.ts +76 -0
- package/dist/services/trace-collector.service.d.ts.map +1 -0
- package/dist/services/trace-collector.service.js +201 -0
- package/dist/services/trace-collector.service.js.map +1 -0
- package/dist/shared/dto/project.d.ts +156 -0
- package/dist/shared/dto/project.d.ts.map +1 -0
- package/dist/shared/dto/project.js +8 -0
- package/dist/shared/dto/project.js.map +1 -0
- package/dist/shared/dto/services.d.ts +254 -0
- package/dist/shared/dto/services.d.ts.map +1 -0
- package/dist/shared/dto/services.js +7 -0
- package/dist/shared/dto/services.js.map +1 -0
- package/dist/shared/dto/types.d.ts +5 -0
- package/dist/shared/dto/types.d.ts.map +1 -0
- package/dist/shared/dto/types.js +5 -0
- package/dist/shared/dto/types.js.map +1 -0
- package/dist/shared/events.d.ts +215 -0
- package/dist/shared/events.d.ts.map +1 -0
- package/dist/shared/events.js +101 -0
- package/dist/shared/events.js.map +1 -0
- package/dist/shared/format.d.ts +18 -0
- package/dist/shared/format.d.ts.map +1 -0
- package/dist/shared/format.js +93 -0
- package/dist/shared/format.js.map +1 -0
- package/dist/shared/roles.d.ts +31 -0
- package/dist/shared/roles.d.ts.map +1 -0
- package/dist/shared/roles.js +39 -0
- package/dist/shared/roles.js.map +1 -0
- package/dist/shared/tokens.d.ts +70 -0
- package/dist/shared/tokens.d.ts.map +1 -0
- package/dist/shared/tokens.js +46 -0
- package/dist/shared/tokens.js.map +1 -0
- package/dist/shared/xec-loader.d.ts +17 -0
- package/dist/shared/xec-loader.d.ts.map +1 -0
- package/dist/shared/xec-loader.js +41 -0
- package/dist/shared/xec-loader.js.map +1 -0
- package/dist/supervisor/omnitron-supervisor.d.ts +21 -0
- package/dist/supervisor/omnitron-supervisor.d.ts.map +1 -0
- package/dist/supervisor/omnitron-supervisor.js +43 -0
- package/dist/supervisor/omnitron-supervisor.js.map +1 -0
- package/dist/supervisor/restart-policy.d.ts +11 -0
- package/dist/supervisor/restart-policy.d.ts.map +1 -0
- package/dist/supervisor/restart-policy.js +33 -0
- package/dist/supervisor/restart-policy.js.map +1 -0
- package/dist/webapp/static-server.d.ts +24 -0
- package/dist/webapp/static-server.d.ts.map +1 -0
- package/dist/webapp/static-server.js +152 -0
- package/dist/webapp/static-server.js.map +1 -0
- package/dist/webapp/webapp.service.d.ts +55 -0
- package/dist/webapp/webapp.service.d.ts.map +1 -0
- package/dist/webapp/webapp.service.js +233 -0
- package/dist/webapp/webapp.service.js.map +1 -0
- package/dist/workers/health-monitor-process.d.ts +41 -0
- package/dist/workers/health-monitor-process.d.ts.map +1 -0
- package/dist/workers/health-monitor-process.js +128 -0
- package/dist/workers/health-monitor-process.js.map +1 -0
- package/dist/workers/health-monitor.module.d.ts +11 -0
- package/dist/workers/health-monitor.module.d.ts.map +1 -0
- package/dist/workers/health-monitor.module.js +29 -0
- package/dist/workers/health-monitor.module.js.map +1 -0
- package/dist/workers/health-monitor.service.d.ts +55 -0
- package/dist/workers/health-monitor.service.d.ts.map +1 -0
- package/dist/workers/health-monitor.service.js +402 -0
- package/dist/workers/health-monitor.service.js.map +1 -0
- package/dist/workers/system-worker-manager.d.ts +47 -0
- package/dist/workers/system-worker-manager.d.ts.map +1 -0
- package/dist/workers/system-worker-manager.js +98 -0
- package/dist/workers/system-worker-manager.js.map +1 -0
- package/dist/workers/types.d.ts +80 -0
- package/dist/workers/types.d.ts.map +1 -0
- package/dist/workers/types.js +8 -0
- package/dist/workers/types.js.map +1 -0
- package/package.json +85 -0
- package/webapp/dist/assets/Chip-BySxTjyN.js +1 -0
- package/webapp/dist/assets/DialogContentText-YQWiAVrU.js +1 -0
- package/webapp/dist/assets/DialogTitle-CDkgUIwp.js +1 -0
- package/webapp/dist/assets/FormControlLabel-Bu3CCsBM.js +1 -0
- package/webapp/dist/assets/Grid-BFY8hAzL.js +1 -0
- package/webapp/dist/assets/InputAdornment-_Dayk-3y.js +3 -0
- package/webapp/dist/assets/Skeleton-BGj6Sw8m.js +37 -0
- package/webapp/dist/assets/Switch-CA6682vv.js +1 -0
- package/webapp/dist/assets/TableContainer-4epq10KJ.js +1 -0
- package/webapp/dist/assets/TextField-C73KHMVN.js +1 -0
- package/webapp/dist/assets/alerts-JEQALS7Y.js +1 -0
- package/webapp/dist/assets/apps-DMPysEKB.js +1 -0
- package/webapp/dist/assets/client-DlGPter5.js +110 -0
- package/webapp/dist/assets/constants-DqFQJ27U.js +1 -0
- package/webapp/dist/assets/containers-CvkC7do8.js +1 -0
- package/webapp/dist/assets/dashboard-C0Fre9pC.js +1 -0
- package/webapp/dist/assets/dashboard-builder-DAghqdpE.js +1 -0
- package/webapp/dist/assets/deployments-Cg1lI1uT.js +1 -0
- package/webapp/dist/assets/detail-CyFtEson.js +1 -0
- package/webapp/dist/assets/detail-DqoSGKT1.js +8 -0
- package/webapp/dist/assets/formatters-J3Xqn6BQ.js +1 -0
- package/webapp/dist/assets/fs-uP8eiZAR.js +1 -0
- package/webapp/dist/assets/icons-ynIWYfBP.js +3 -0
- package/webapp/dist/assets/index-CHVXOsTS.css +1 -0
- package/webapp/dist/assets/index-vKrDmEA_.js +259 -0
- package/webapp/dist/assets/inter-cyrillic-400-normal-HOLc17fK.woff +0 -0
- package/webapp/dist/assets/inter-cyrillic-400-normal-obahsSVq.woff2 +0 -0
- package/webapp/dist/assets/inter-cyrillic-500-normal-BasfLYem.woff2 +0 -0
- package/webapp/dist/assets/inter-cyrillic-500-normal-CxZf_p3X.woff +0 -0
- package/webapp/dist/assets/inter-cyrillic-600-normal-4D_pXhcN.woff +0 -0
- package/webapp/dist/assets/inter-cyrillic-600-normal-CWCymEST.woff2 +0 -0
- package/webapp/dist/assets/inter-cyrillic-700-normal-CjBOestx.woff2 +0 -0
- package/webapp/dist/assets/inter-cyrillic-700-normal-DrXBdSj3.woff +0 -0
- package/webapp/dist/assets/inter-cyrillic-ext-400-normal-BQZuk6qB.woff2 +0 -0
- package/webapp/dist/assets/inter-cyrillic-ext-400-normal-DQukG94-.woff +0 -0
- package/webapp/dist/assets/inter-cyrillic-ext-500-normal-B0yAr1jD.woff2 +0 -0
- package/webapp/dist/assets/inter-cyrillic-ext-500-normal-BmqWE9Dz.woff +0 -0
- package/webapp/dist/assets/inter-cyrillic-ext-600-normal-Bcila6Z-.woff +0 -0
- package/webapp/dist/assets/inter-cyrillic-ext-600-normal-Dfes3d0z.woff2 +0 -0
- package/webapp/dist/assets/inter-cyrillic-ext-700-normal-BjwYoWNd.woff2 +0 -0
- package/webapp/dist/assets/inter-cyrillic-ext-700-normal-LO58E6JB.woff +0 -0
- package/webapp/dist/assets/inter-greek-400-normal-B4URO6DV.woff2 +0 -0
- package/webapp/dist/assets/inter-greek-400-normal-q2sYcFCs.woff +0 -0
- package/webapp/dist/assets/inter-greek-500-normal-BIZE56-Y.woff2 +0 -0
- package/webapp/dist/assets/inter-greek-500-normal-Xzm54t5V.woff +0 -0
- package/webapp/dist/assets/inter-greek-600-normal-BZpKdvQh.woff +0 -0
- package/webapp/dist/assets/inter-greek-600-normal-plRanbMR.woff2 +0 -0
- package/webapp/dist/assets/inter-greek-700-normal-BUv2fZ6O.woff +0 -0
- package/webapp/dist/assets/inter-greek-700-normal-C3JjAnD8.woff2 +0 -0
- package/webapp/dist/assets/inter-greek-ext-400-normal-DGGRlc-M.woff2 +0 -0
- package/webapp/dist/assets/inter-greek-ext-400-normal-KugGGMne.woff +0 -0
- package/webapp/dist/assets/inter-greek-ext-500-normal-2j5mBUwD.woff +0 -0
- package/webapp/dist/assets/inter-greek-ext-500-normal-C4iEst2y.woff2 +0 -0
- package/webapp/dist/assets/inter-greek-ext-600-normal-B8X0CLgF.woff +0 -0
- package/webapp/dist/assets/inter-greek-ext-600-normal-DRtmH8MT.woff2 +0 -0
- package/webapp/dist/assets/inter-greek-ext-700-normal-BoQ6DsYi.woff +0 -0
- package/webapp/dist/assets/inter-greek-ext-700-normal-qfdV9bQt.woff2 +0 -0
- package/webapp/dist/assets/inter-latin-400-normal-C38fXH4l.woff2 +0 -0
- package/webapp/dist/assets/inter-latin-400-normal-CyCys3Eg.woff +0 -0
- package/webapp/dist/assets/inter-latin-500-normal-BL9OpVg8.woff +0 -0
- package/webapp/dist/assets/inter-latin-500-normal-Cerq10X2.woff2 +0 -0
- package/webapp/dist/assets/inter-latin-600-normal-CiBQ2DWP.woff +0 -0
- package/webapp/dist/assets/inter-latin-600-normal-LgqL8muc.woff2 +0 -0
- package/webapp/dist/assets/inter-latin-700-normal-BLAVimhd.woff +0 -0
- package/webapp/dist/assets/inter-latin-700-normal-Yt3aPRUw.woff2 +0 -0
- package/webapp/dist/assets/inter-latin-ext-400-normal-77YHD8bZ.woff +0 -0
- package/webapp/dist/assets/inter-latin-ext-400-normal-C1nco2VV.woff2 +0 -0
- package/webapp/dist/assets/inter-latin-ext-500-normal-BxGbmqWO.woff +0 -0
- package/webapp/dist/assets/inter-latin-ext-500-normal-CV4jyFjo.woff2 +0 -0
- package/webapp/dist/assets/inter-latin-ext-600-normal-CIVaiw4L.woff +0 -0
- package/webapp/dist/assets/inter-latin-ext-600-normal-D2bJ5OIk.woff2 +0 -0
- package/webapp/dist/assets/inter-latin-ext-700-normal-Ca8adRJv.woff2 +0 -0
- package/webapp/dist/assets/inter-latin-ext-700-normal-TidjK2hL.woff +0 -0
- package/webapp/dist/assets/inter-vietnamese-400-normal-Bbgyi5SW.woff +0 -0
- package/webapp/dist/assets/inter-vietnamese-400-normal-DMkecbls.woff2 +0 -0
- package/webapp/dist/assets/inter-vietnamese-500-normal-DOriooB6.woff2 +0 -0
- package/webapp/dist/assets/inter-vietnamese-500-normal-mJboJaSs.woff +0 -0
- package/webapp/dist/assets/inter-vietnamese-600-normal-BuLX-rYi.woff +0 -0
- package/webapp/dist/assets/inter-vietnamese-600-normal-Cc8MFFhd.woff2 +0 -0
- package/webapp/dist/assets/inter-vietnamese-700-normal-BZaoP0fm.woff +0 -0
- package/webapp/dist/assets/inter-vietnamese-700-normal-DlLaEgI2.woff2 +0 -0
- package/webapp/dist/assets/isMuiElement-BRL3YuCT.js +1 -0
- package/webapp/dist/assets/logs-IovIij1C.js +11 -0
- package/webapp/dist/assets/metrics-Dufwtwjq.js +1 -0
- package/webapp/dist/assets/nodes-Brvu8W3j.js +7 -0
- package/webapp/dist/assets/pipelines-t40X4MuC.js +4 -0
- package/webapp/dist/assets/prop-types-CvVtHxp4.js +1 -0
- package/webapp/dist/assets/react-apexcharts.esm-CLO6gala.js +954 -0
- package/webapp/dist/assets/settings-DTAIST3v.js +1 -0
- package/webapp/dist/assets/sign-in-DQEAkJum.js +1 -0
- package/webapp/dist/assets/stacks-BjM1f45N.js +1 -0
- package/webapp/dist/assets/system-info-BQSbSEK-.js +1 -0
- package/webapp/dist/assets/topology-6N8-Az_Z.js +12 -0
- package/webapp/dist/assets/topology-CHpVij2M.css +1 -0
- package/webapp/dist/assets/traces-DVXyb-4m.js +1 -0
- package/webapp/dist/assets/use-stack-context-CbE8fxBA.js +1 -0
- package/webapp/dist/favicon.png +0 -0
- package/webapp/dist/index.html +19 -0
- package/webapp/dist/logo.svg +80 -0
|
@@ -0,0 +1,1202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OmnitronDaemon — The daemon IS a Titan Application
|
|
3
|
+
*
|
|
4
|
+
* Bootstraps via Application.create(), uses Nexus DI, and registers four
|
|
5
|
+
* Netron transport servers:
|
|
6
|
+
*
|
|
7
|
+
* 1. Unix socket (local) — CLI <-> daemon RPC. High-performance, secure.
|
|
8
|
+
* 2. TCP (remote) — omnitron <-> omnitron fleet communication.
|
|
9
|
+
* 3. HTTP (webapp) — serves Omnitron Console SPA + Netron RPC on port 9800.
|
|
10
|
+
* 4. WebSocket — real-time event push to webapp clients.
|
|
11
|
+
*
|
|
12
|
+
* Architecture completion:
|
|
13
|
+
* - InfrastructureGate: apps wait for infra before starting
|
|
14
|
+
* - titan-scheduler: replaces bare setInterval calls
|
|
15
|
+
* - titan-health: custom health indicators (Docker, apps, memory, event loop)
|
|
16
|
+
* - Typed events: domain events broadcast via WebSocket
|
|
17
|
+
* - RBAC: role-based access on all RPC endpoints (admin/operator/viewer)
|
|
18
|
+
* - Config resolution: secrets + env-aware injection into apps
|
|
19
|
+
*/
|
|
20
|
+
import { Application, ShutdownReason, ShutdownPriority, ApplicationEvent } from '@omnitron-dev/titan';
|
|
21
|
+
import { UnixSocketTransport } from '@omnitron-dev/titan/netron/transport/unix';
|
|
22
|
+
import { TcpTransport } from '@omnitron-dev/titan/netron/transport/tcp';
|
|
23
|
+
import { HttpTransport } from '@omnitron-dev/titan/netron/transport/http';
|
|
24
|
+
import { WebSocketTransport } from '@omnitron-dev/titan/netron/transport/websocket';
|
|
25
|
+
import { LOGGER_SERVICE_TOKEN } from '@omnitron-dev/titan/module/logger';
|
|
26
|
+
import { SCHEDULER_SERVICE_TOKEN } from '@omnitron-dev/titan-scheduler';
|
|
27
|
+
import { HEALTH_SERVICE_TOKEN as TITAN_HEALTH_TOKEN } from '@omnitron-dev/titan-health';
|
|
28
|
+
import os from 'node:os';
|
|
29
|
+
import { CLI_VERSION, DEFAULT_DAEMON_CONFIG } from '../config/defaults.js';
|
|
30
|
+
import { createDaemonModule, getDaemonLogStream, getDaemonErrorStream, getDaemonLogCollectorStream } from './daemon.module.js';
|
|
31
|
+
import { DaemonRpcService } from './daemon.rpc-service.js';
|
|
32
|
+
import { AuthRpcService } from '../services/auth.rpc-service.js';
|
|
33
|
+
import { LogsRpcService } from '../services/log-collector.rpc-service.js';
|
|
34
|
+
import { EventBroadcasterService } from '../services/event-broadcaster.service.js';
|
|
35
|
+
import { EventBroadcasterRpcService } from '../services/event-broadcaster.rpc-service.js';
|
|
36
|
+
import { ProjectRpcService } from '../services/project.rpc-service.js';
|
|
37
|
+
import { SyncService } from '../services/sync.service.js';
|
|
38
|
+
import { SyncRpcService } from '../services/sync.rpc-service.js';
|
|
39
|
+
import { SystemInfoService } from '../services/system-info.service.js';
|
|
40
|
+
import { SystemInfoRpcService } from '../services/system-info.rpc-service.js';
|
|
41
|
+
import { PidManager } from './pid-manager.js';
|
|
42
|
+
import { FileWatcher } from '../orchestrator/file-watcher.js';
|
|
43
|
+
import { InfrastructureService } from '../infrastructure/infrastructure.service.js';
|
|
44
|
+
import { DockerHealthIndicator } from '../monitoring/docker-health.indicator.js';
|
|
45
|
+
import { AppHealthIndicator } from '../monitoring/app-health.indicator.js';
|
|
46
|
+
import { registerDaemonJobs } from './daemon-scheduler.js';
|
|
47
|
+
import { METRICS_SERVICE_TOKEN as TITAN_METRICS_TOKEN } from '@omnitron-dev/titan-metrics';
|
|
48
|
+
import { ORCHESTRATOR_TOKEN, LOG_MANAGER_TOKEN, STATE_STORE_TOKEN, OMNITRON_DB_TOKEN, AUTH_SERVICE_TOKEN, LOG_COLLECTOR_TOKEN, FLEET_SERVICE_TOKEN, ALERT_SERVICE_TOKEN, HEALTH_CHECK_SERVICE_TOKEN, DISCOVERY_SERVICE_TOKEN, KUBERNETES_SERVICE_TOKEN, PIPELINE_SERVICE_TOKEN, TRACE_COLLECTOR_TOKEN, BACKUP_SERVICE_TOKEN, SECRETS_SERVICE_TOKEN, TELEMETRY_RELAY_TOKEN, DEPLOY_SERVICE_TOKEN, INFRASTRUCTURE_GATE_TOKEN, PROJECT_SERVICE_TOKEN, SLAVE_STORAGE_TOKEN, } from '../shared/tokens.js';
|
|
49
|
+
import { APP_EVENTS, INFRA_EVENTS, DAEMON_EVENTS, PROJECT_EVENTS, STACK_EVENTS, NODE_EVENTS, } from '../shared/events.js';
|
|
50
|
+
import { JWT_SERVICE_TOKEN } from '@omnitron-dev/titan-auth';
|
|
51
|
+
import { AuthenticationManager } from '@omnitron-dev/titan/netron/auth';
|
|
52
|
+
import { createAuthContextWrapper } from '../services/auth-context.js';
|
|
53
|
+
export class OmnitronDaemon {
|
|
54
|
+
app = null;
|
|
55
|
+
pidManager = null;
|
|
56
|
+
fileWatcher = null;
|
|
57
|
+
infraService = null;
|
|
58
|
+
eventBroadcaster = null;
|
|
59
|
+
syncService = null;
|
|
60
|
+
nodeManagerService = null;
|
|
61
|
+
nodeManagerRpcService = null;
|
|
62
|
+
systemWorkerManager = null;
|
|
63
|
+
leaderElection = null;
|
|
64
|
+
configSyncService = null;
|
|
65
|
+
dc = DEFAULT_DAEMON_CONFIG;
|
|
66
|
+
/** Daemon config accessor for external use (e.g., DaemonRpcService) */
|
|
67
|
+
get daemonConfig() { return this.dc; }
|
|
68
|
+
async start(config, options, daemonConfig) {
|
|
69
|
+
this.dc = daemonConfig ?? DEFAULT_DAEMON_CONFIG;
|
|
70
|
+
const pidFile = this.dc.pidFile.replace('~', process.env['HOME'] ?? '');
|
|
71
|
+
this.pidManager = new PidManager(pidFile);
|
|
72
|
+
if (this.pidManager.isRunning()) {
|
|
73
|
+
const existingPid = this.pidManager.getPid();
|
|
74
|
+
throw new Error(`Omnitron daemon already running (PID: ${existingPid})`);
|
|
75
|
+
}
|
|
76
|
+
this.pidManager.write();
|
|
77
|
+
// 1. Create Titan Application (the daemon itself)
|
|
78
|
+
const DaemonModule = createDaemonModule(config, this.dc);
|
|
79
|
+
this.app = await Application.create(DaemonModule, {
|
|
80
|
+
name: 'omnitron',
|
|
81
|
+
version: CLI_VERSION,
|
|
82
|
+
});
|
|
83
|
+
// 2. Register transports (Unix, TCP, HTTP, WebSocket)
|
|
84
|
+
await this.registerTransports(this.dc);
|
|
85
|
+
// 3. Resolve and expose RPC services via Netron
|
|
86
|
+
await this.exposeRpcServices(config, this.dc);
|
|
87
|
+
// 4. Start the Titan Application (boots DI, starts Netron, opens transports)
|
|
88
|
+
await this.app.start();
|
|
89
|
+
const loggerModule = await this.app.container.resolveAsync(LOGGER_SERVICE_TOKEN);
|
|
90
|
+
const logger = loggerModule.logger;
|
|
91
|
+
logger.info({
|
|
92
|
+
socketPath: this.dc.socketPath,
|
|
93
|
+
port: this.dc.port,
|
|
94
|
+
httpPort: this.dc.httpPort,
|
|
95
|
+
wsPort: (this.dc.httpPort ?? 9800) + 2,
|
|
96
|
+
host: this.dc.host,
|
|
97
|
+
pid: process.pid,
|
|
98
|
+
version: CLI_VERSION,
|
|
99
|
+
}, 'Omnitron daemon started');
|
|
100
|
+
// 5. Wire log persistence
|
|
101
|
+
await this.wireLogPersistence();
|
|
102
|
+
// 5.5. Check for crash recovery
|
|
103
|
+
await this.checkCrashRecovery(logger);
|
|
104
|
+
// 6. Provision infrastructure (omnitron-pg + app infra from config.infrastructure)
|
|
105
|
+
await this.startInfrastructure(config, options, logger);
|
|
106
|
+
// 7. Register custom health indicators (Docker + apps)
|
|
107
|
+
await this.registerHealthIndicators();
|
|
108
|
+
// 8. File watching (dev mode)
|
|
109
|
+
this.startFileWatcher(config, options, logger);
|
|
110
|
+
// 8.5. Wire daemon Netron to orchestrator for native topology routing
|
|
111
|
+
{
|
|
112
|
+
const orchestrator = await this.app.container.resolveAsync(ORCHESTRATOR_TOKEN);
|
|
113
|
+
if (this.app.netron) {
|
|
114
|
+
const socketPath = this.dc.socketPath.replace('~', process.env['HOME'] ?? '');
|
|
115
|
+
orchestrator.setDaemonNetron(this.app.netron, socketPath);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// 8.8. Start webapp (nginx container serving Console UI) if enabled
|
|
119
|
+
{
|
|
120
|
+
const { readSavedDaemonConfig } = await import('../commands/up.js');
|
|
121
|
+
const savedConfig = readSavedDaemonConfig();
|
|
122
|
+
if (savedConfig?.webapp) {
|
|
123
|
+
try {
|
|
124
|
+
const { WebappService } = await import('../webapp/webapp.service.js');
|
|
125
|
+
const webapp = new WebappService(logger, process.cwd(), (this.dc.httpPort ?? 9800) + 1, this.dc.httpPort ?? 9800);
|
|
126
|
+
await webapp.start();
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
logger.warn({ error: err.message }, 'Webapp failed to start — Console UI may not be available');
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// 9. Start managed apps (waits for infra gate if apps have `requires`)
|
|
134
|
+
await this.startApps(config, logger);
|
|
135
|
+
// 10. Start background tasks via titan-scheduler (replaces bare setInterval)
|
|
136
|
+
await this.startScheduledTasks(config, logger);
|
|
137
|
+
// 11. Start remaining background services (telemetry, traces, leader election)
|
|
138
|
+
await this.startBackgroundServices(config, logger);
|
|
139
|
+
// 11.5. Start health monitor system worker (master only)
|
|
140
|
+
await this.startHealthMonitorWorker(logger);
|
|
141
|
+
// 12. Wire event broadcasting (orchestrator events → WebSocket push)
|
|
142
|
+
await this.wireEventBroadcasting(logger);
|
|
143
|
+
// 13. Register shutdown tasks — Application handles SIGTERM/SIGINT
|
|
144
|
+
// and calls shutdown tasks in priority order before process.exit()
|
|
145
|
+
this.registerShutdownTasks(this.app);
|
|
146
|
+
// 15. Broadcast daemon.started event
|
|
147
|
+
this.eventBroadcaster?.broadcast(DAEMON_EVENTS.STARTED, {
|
|
148
|
+
version: CLI_VERSION,
|
|
149
|
+
pid: process.pid,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
// ============================================================================
|
|
153
|
+
// Transport Registration
|
|
154
|
+
// ============================================================================
|
|
155
|
+
async registerTransports(dc) {
|
|
156
|
+
if (!this.app?.netron)
|
|
157
|
+
return;
|
|
158
|
+
// Unix socket — local CLI <-> daemon (primary, high-performance)
|
|
159
|
+
this.app.netron.registerTransport('unix', () => new UnixSocketTransport());
|
|
160
|
+
this.app.netron.registerTransportServer('unix', {
|
|
161
|
+
name: 'daemon-local',
|
|
162
|
+
options: {
|
|
163
|
+
path: dc.socketPath.replace('~', process.env['HOME'] ?? ''),
|
|
164
|
+
force: true,
|
|
165
|
+
mode: 0o600, // Owner-only access for security
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
// TCP — remote fleet communication (cross-server)
|
|
169
|
+
this.app.netron.registerTransport('tcp', () => new TcpTransport());
|
|
170
|
+
this.app.netron.registerTransportServer('tcp', {
|
|
171
|
+
name: 'daemon-fleet',
|
|
172
|
+
options: {
|
|
173
|
+
port: dc.port,
|
|
174
|
+
host: dc.host,
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
// Auth — JWT validation + session check + role extraction
|
|
178
|
+
const isSlave = dc.role === 'slave';
|
|
179
|
+
const jwtService = await this.app.container.resolveAsync(JWT_SERVICE_TOKEN);
|
|
180
|
+
const logModule = await this.app.container.resolveAsync(LOGGER_SERVICE_TOKEN);
|
|
181
|
+
const authLogger = logModule.logger.child({ component: 'auth' });
|
|
182
|
+
// On master: full JWT + session validation via AuthService (PG-backed)
|
|
183
|
+
// On slave: JWT-only validation (no session DB — no PG)
|
|
184
|
+
const authService = !isSlave
|
|
185
|
+
? await this.app.container.resolveAsync(AUTH_SERVICE_TOKEN)
|
|
186
|
+
: null;
|
|
187
|
+
const authManager = new AuthenticationManager(authLogger, {
|
|
188
|
+
authenticate: async () => {
|
|
189
|
+
throw new Error('Credential authentication not supported. Use JWT Bearer token.');
|
|
190
|
+
},
|
|
191
|
+
validateToken: async (token) => {
|
|
192
|
+
// JWT verification with caching via titan-auth JWTService
|
|
193
|
+
const payload = await jwtService.verify(token);
|
|
194
|
+
// Session validation — master only (requires PG for omnitron_sessions)
|
|
195
|
+
if (authService) {
|
|
196
|
+
const sessionId = payload['sid'];
|
|
197
|
+
if (sessionId) {
|
|
198
|
+
const session = await authService.validateToken(token);
|
|
199
|
+
if (!session) {
|
|
200
|
+
const err = new Error('Session has been revoked or expired');
|
|
201
|
+
err.code = 'SESSION_REVOKED';
|
|
202
|
+
err.statusCode = 401;
|
|
203
|
+
throw err;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// Role is now in JWT claims (set by AuthService.issueToken)
|
|
208
|
+
const role = payload['role'] ?? 'viewer';
|
|
209
|
+
const sessionId = payload['sid'];
|
|
210
|
+
return {
|
|
211
|
+
userId: payload.sub,
|
|
212
|
+
roles: [role],
|
|
213
|
+
permissions: [],
|
|
214
|
+
token: { type: 'bearer' },
|
|
215
|
+
metadata: {
|
|
216
|
+
sessionId,
|
|
217
|
+
isServiceRole: role === 'service_role',
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
},
|
|
221
|
+
tokenCache: { enabled: true, ttl: 10_000 },
|
|
222
|
+
});
|
|
223
|
+
this.app.netron.configureAuth(authManager);
|
|
224
|
+
const authContextWrapper = createAuthContextWrapper();
|
|
225
|
+
// HTTP — Netron RPC API (internal port, nginx proxies from public port)
|
|
226
|
+
const internalHttpPort = (dc.httpPort ?? 9800) + 1;
|
|
227
|
+
this.app.netron.registerTransport('http', () => new HttpTransport());
|
|
228
|
+
this.app.netron.registerTransportServer('http', {
|
|
229
|
+
name: 'daemon-http',
|
|
230
|
+
options: {
|
|
231
|
+
port: internalHttpPort,
|
|
232
|
+
host: '0.0.0.0',
|
|
233
|
+
cors: true,
|
|
234
|
+
invocationWrapper: authContextWrapper,
|
|
235
|
+
},
|
|
236
|
+
});
|
|
237
|
+
// WebSocket — real-time event push to webapp clients
|
|
238
|
+
const wsPort = (dc.httpPort ?? 9800) + 2;
|
|
239
|
+
this.app.netron.registerTransport('websocket', () => new WebSocketTransport());
|
|
240
|
+
this.app.netron.registerTransportServer('websocket', {
|
|
241
|
+
name: 'daemon-ws',
|
|
242
|
+
options: {
|
|
243
|
+
port: wsPort,
|
|
244
|
+
host: '0.0.0.0',
|
|
245
|
+
invocationWrapper: authContextWrapper,
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
// ============================================================================
|
|
250
|
+
// RPC Service Exposure
|
|
251
|
+
// ============================================================================
|
|
252
|
+
async exposeRpcServices(config, dc) {
|
|
253
|
+
if (!this.app?.netron)
|
|
254
|
+
return;
|
|
255
|
+
const container = this.app.container;
|
|
256
|
+
const isSlave = dc.role === 'slave';
|
|
257
|
+
// Core services (available on both master and slave)
|
|
258
|
+
const orchestrator = await container.resolveAsync(ORCHESTRATOR_TOKEN);
|
|
259
|
+
const titanHealth = await container.resolveAsync(TITAN_HEALTH_TOKEN);
|
|
260
|
+
const logManager = await container.resolveAsync(LOG_MANAGER_TOKEN);
|
|
261
|
+
const logCollector = await container.resolveAsync(LOG_COLLECTOR_TOKEN);
|
|
262
|
+
const loggerModule = await container.resolveAsync(LOGGER_SERVICE_TOKEN);
|
|
263
|
+
const rpcService = new DaemonRpcService(orchestrator, titanHealth, logManager, config, this);
|
|
264
|
+
await this.app.netron.peer.exposeService(rpcService);
|
|
265
|
+
// Logs RPC service (works on both master and slave — uses PG or SQLite)
|
|
266
|
+
const logsRpcService = new LogsRpcService(logCollector);
|
|
267
|
+
await this.app.netron.peer.exposeService(logsRpcService);
|
|
268
|
+
// Metrics RPC service — provided by TitanMetricsModule
|
|
269
|
+
const metricsService = await container.resolveAsync(TITAN_METRICS_TOKEN);
|
|
270
|
+
const { MetricsRpcService: MetricsRpc } = await import('@omnitron-dev/titan-metrics');
|
|
271
|
+
const metricsRpcService = new MetricsRpc(metricsService);
|
|
272
|
+
await this.app.netron.peer.exposeService(metricsRpcService);
|
|
273
|
+
// HealthCheck RPC service (no DB dependency)
|
|
274
|
+
const { HealthCheckRpcService: HealthCheckRpc } = await import('../services/health-check.rpc-service.js');
|
|
275
|
+
const healthCheckService = await container.resolveAsync(HEALTH_CHECK_SERVICE_TOKEN);
|
|
276
|
+
const healthCheckRpcService = new HealthCheckRpc(healthCheckService);
|
|
277
|
+
await this.app.netron.peer.exposeService(healthCheckRpcService);
|
|
278
|
+
// Secrets RPC service (file-based, no DB dependency)
|
|
279
|
+
const { SecretsRpcService: SecretsRpc } = await import('../services/secrets.rpc-service.js');
|
|
280
|
+
const secretsService = await container.resolveAsync(SECRETS_SERVICE_TOKEN);
|
|
281
|
+
const secretsRpcService = new SecretsRpc(secretsService);
|
|
282
|
+
await this.app.netron.peer.exposeService(secretsRpcService);
|
|
283
|
+
// Kubernetes RPC service (no DB dependency)
|
|
284
|
+
const { KubernetesRpcService: K8sRpc } = await import('../services/kubernetes.rpc-service.js');
|
|
285
|
+
const kubernetesService = await container.resolveAsync(KUBERNETES_SERVICE_TOKEN);
|
|
286
|
+
const kubernetesRpcService = new K8sRpc(kubernetesService);
|
|
287
|
+
await this.app.netron.peer.exposeService(kubernetesRpcService);
|
|
288
|
+
// Backup RPC service (no DB dependency)
|
|
289
|
+
const { BackupRpcService: BackupRpc } = await import('../services/backup.rpc-service.js');
|
|
290
|
+
const backupService = await container.resolveAsync(BACKUP_SERVICE_TOKEN);
|
|
291
|
+
const backupRpcService = new BackupRpc(backupService);
|
|
292
|
+
await this.app.netron.peer.exposeService(backupRpcService);
|
|
293
|
+
// Infrastructure RPC service (reports infra state — slave has no infra)
|
|
294
|
+
const { InfrastructureRpcService: InfraRpc } = await import('../services/infrastructure.rpc-service.js');
|
|
295
|
+
const infraRpcService = new InfraRpc(() => this.infraService);
|
|
296
|
+
await this.app.netron.peer.exposeService(infraRpcService);
|
|
297
|
+
// Project + Stack management RPC service
|
|
298
|
+
const projectService = await container.resolveAsync(PROJECT_SERVICE_TOKEN);
|
|
299
|
+
const projectRpcService = new ProjectRpcService(projectService);
|
|
300
|
+
await this.app.netron.peer.exposeService(projectRpcService);
|
|
301
|
+
// Sync service (slave→master data replication)
|
|
302
|
+
const syncNodeId = `${os.hostname()}-${dc.port}`;
|
|
303
|
+
let syncDb;
|
|
304
|
+
if (isSlave) {
|
|
305
|
+
const slaveStorage = await container.resolveAsync(SLAVE_STORAGE_TOKEN);
|
|
306
|
+
syncDb = await slaveStorage.getDb();
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
syncDb = await container.resolveAsync(OMNITRON_DB_TOKEN);
|
|
310
|
+
}
|
|
311
|
+
this.syncService = new SyncService(syncDb, loggerModule.logger.child({ component: 'sync' }), syncNodeId, dc.role, dc.sync);
|
|
312
|
+
const syncRpcService = new SyncRpcService(this.syncService);
|
|
313
|
+
await this.app.netron.peer.exposeService(syncRpcService);
|
|
314
|
+
// System info service (real-time OS/hardware metrics)
|
|
315
|
+
const systemInfoService = new SystemInfoService(loggerModule.logger.child({ component: 'sysinfo' }), dc.role);
|
|
316
|
+
const systemInfoRpcService = new SystemInfoRpcService(systemInfoService);
|
|
317
|
+
await this.app.netron.peer.exposeService(systemInfoRpcService);
|
|
318
|
+
// Event Broadcaster RPC service (WebSocket subscriptions)
|
|
319
|
+
this.eventBroadcaster = new EventBroadcasterService(loggerModule.logger);
|
|
320
|
+
const eventBroadcasterRpcService = new EventBroadcasterRpcService(this.eventBroadcaster);
|
|
321
|
+
await this.app.netron.peer.exposeService(eventBroadcasterRpcService);
|
|
322
|
+
// Node manager — file-based, no PG (master only — manages infrastructure nodes)
|
|
323
|
+
// Health checks delegated to dedicated system worker (started later after infra is ready)
|
|
324
|
+
if (!isSlave) {
|
|
325
|
+
const { NodeManagerService } = await import('../services/node-manager.service.js');
|
|
326
|
+
const { NodeManagerRpcService } = await import('../services/node-manager.rpc-service.js');
|
|
327
|
+
const secretsService = await container.resolveAsync(SECRETS_SERVICE_TOKEN);
|
|
328
|
+
const nodeManager = new NodeManagerService(loggerModule.logger.child({ component: 'nodes' }), secretsService);
|
|
329
|
+
this.nodeManagerService = nodeManager;
|
|
330
|
+
const nodeManagerRpcService = new NodeManagerRpcService(nodeManager);
|
|
331
|
+
this.nodeManagerRpcService = nodeManagerRpcService;
|
|
332
|
+
await this.app.netron.peer.exposeService(nodeManagerRpcService);
|
|
333
|
+
}
|
|
334
|
+
// =====================================================================
|
|
335
|
+
// Master-only RPC services (require PostgreSQL)
|
|
336
|
+
// =====================================================================
|
|
337
|
+
if (!isSlave) {
|
|
338
|
+
// Auth RPC service
|
|
339
|
+
const authService = await container.resolveAsync(AUTH_SERVICE_TOKEN);
|
|
340
|
+
const authRpcService = new AuthRpcService(authService);
|
|
341
|
+
await this.app.netron.peer.exposeService(authRpcService);
|
|
342
|
+
// Alert RPC service
|
|
343
|
+
const { AlertRpcService: AlertRpc } = await import('../services/alert.rpc-service.js');
|
|
344
|
+
const alertService = await container.resolveAsync(ALERT_SERVICE_TOKEN);
|
|
345
|
+
const alertRpcService = new AlertRpc(alertService);
|
|
346
|
+
await this.app.netron.peer.exposeService(alertRpcService);
|
|
347
|
+
// Telemetry relay RPC service
|
|
348
|
+
const { TelemetryRpcService: TelemetryRpc } = await import('../services/telemetry.rpc-service.js');
|
|
349
|
+
const telemetryRelay = await container.resolveAsync(TELEMETRY_RELAY_TOKEN);
|
|
350
|
+
const telemetryRpcService = new TelemetryRpc(telemetryRelay);
|
|
351
|
+
await this.app.netron.peer.exposeService(telemetryRpcService);
|
|
352
|
+
// Fleet management RPC service
|
|
353
|
+
const { FleetRpcService: FleetRpc } = await import('../services/fleet.rpc-service.js');
|
|
354
|
+
const fleetService = await container.resolveAsync(FLEET_SERVICE_TOKEN);
|
|
355
|
+
const fleetRpcService = new FleetRpc(fleetService);
|
|
356
|
+
await this.app.netron.peer.exposeService(fleetRpcService);
|
|
357
|
+
// Discovery RPC service
|
|
358
|
+
const { DiscoveryRpcService: DiscoveryRpc } = await import('../services/discovery.rpc-service.js');
|
|
359
|
+
const discoveryService = await container.resolveAsync(DISCOVERY_SERVICE_TOKEN);
|
|
360
|
+
const discoveryRpcService = new DiscoveryRpc(discoveryService);
|
|
361
|
+
await this.app.netron.peer.exposeService(discoveryRpcService);
|
|
362
|
+
// Pipeline RPC service
|
|
363
|
+
const { PipelineRpcService: PipelineRpc } = await import('../services/pipeline.rpc-service.js');
|
|
364
|
+
const pipelineService = await container.resolveAsync(PIPELINE_SERVICE_TOKEN);
|
|
365
|
+
const pipelineRpcService = new PipelineRpc(pipelineService);
|
|
366
|
+
await this.app.netron.peer.exposeService(pipelineRpcService);
|
|
367
|
+
// Trace collector RPC service
|
|
368
|
+
const { TraceRpcService: TraceRpc } = await import('../services/trace-collector.rpc-service.js');
|
|
369
|
+
const traceCollector = await container.resolveAsync(TRACE_COLLECTOR_TOKEN);
|
|
370
|
+
const traceRpcService = new TraceRpc(traceCollector);
|
|
371
|
+
await this.app.netron.peer.exposeService(traceRpcService);
|
|
372
|
+
// Deploy RPC service
|
|
373
|
+
const { DeployRpcService: DeployRpc } = await import('../services/deploy.rpc-service.js');
|
|
374
|
+
const deployService = await container.resolveAsync(DEPLOY_SERVICE_TOKEN);
|
|
375
|
+
const deployRpcService = new DeployRpc(deployService);
|
|
376
|
+
await this.app.netron.peer.exposeService(deployRpcService);
|
|
377
|
+
}
|
|
378
|
+
// Cluster — leader election + config sync (optional, enabled via config, master only)
|
|
379
|
+
// LeaderElection is created here once and stored; startBackgroundServices() starts it.
|
|
380
|
+
if (dc.cluster?.enabled && !isSlave) {
|
|
381
|
+
const { LeaderElection } = await import('../cluster/leader-election.js');
|
|
382
|
+
const { ClusterRpcService: ClusterRpc } = await import('../cluster/cluster.rpc-service.js');
|
|
383
|
+
const nodeId = `${os.hostname()}-${dc.port}`;
|
|
384
|
+
const clusterFleetService = await container.resolveAsync(FLEET_SERVICE_TOKEN);
|
|
385
|
+
this.leaderElection = new LeaderElection(nodeId, clusterFleetService, loggerModule.logger, {
|
|
386
|
+
...(dc.cluster.electionTimeout && { electionTimeout: dc.cluster.electionTimeout }),
|
|
387
|
+
...(dc.cluster.heartbeatInterval != null && { heartbeatInterval: dc.cluster.heartbeatInterval }),
|
|
388
|
+
});
|
|
389
|
+
const clusterRpcService = new ClusterRpc(this.leaderElection);
|
|
390
|
+
await this.app.netron.peer.exposeService(clusterRpcService);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
// ============================================================================
|
|
394
|
+
// Log Persistence Wiring
|
|
395
|
+
// ============================================================================
|
|
396
|
+
async wireLogPersistence() {
|
|
397
|
+
if (!this.app)
|
|
398
|
+
return;
|
|
399
|
+
const orchestrator = await this.app.container.resolveAsync(ORCHESTRATOR_TOKEN);
|
|
400
|
+
const logManager = await this.app.container.resolveAsync(LOG_MANAGER_TOKEN);
|
|
401
|
+
const logCollector = await this.app.container.resolveAsync(LOG_COLLECTOR_TOKEN);
|
|
402
|
+
orchestrator.onAppLog((appName, line) => {
|
|
403
|
+
logManager.appendToFile(appName, line);
|
|
404
|
+
logCollector.ingestPinoLine(appName, line);
|
|
405
|
+
});
|
|
406
|
+
// Wire daemon's own logs into LogCollector (buffered since pino starts before DI)
|
|
407
|
+
const collectorStream = getDaemonLogCollectorStream();
|
|
408
|
+
if (collectorStream) {
|
|
409
|
+
collectorStream.setCollector(logCollector);
|
|
410
|
+
}
|
|
411
|
+
logManager.onRotate((appName) => {
|
|
412
|
+
if (appName === 'omnitron') {
|
|
413
|
+
getDaemonLogStream()?.reopen();
|
|
414
|
+
getDaemonErrorStream()?.reopen();
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
// ============================================================================
|
|
419
|
+
// Crash Recovery Check
|
|
420
|
+
// ============================================================================
|
|
421
|
+
async checkCrashRecovery(logger) {
|
|
422
|
+
if (!this.app)
|
|
423
|
+
return;
|
|
424
|
+
const stateStore = await this.app.container.resolveAsync(STATE_STORE_TOKEN);
|
|
425
|
+
const previousState = stateStore.load();
|
|
426
|
+
if (previousState) {
|
|
427
|
+
const runningApps = previousState.apps.filter((a) => a.status === 'online' || a.status === 'starting');
|
|
428
|
+
if (runningApps.length > 0) {
|
|
429
|
+
logger.warn({
|
|
430
|
+
previousApps: runningApps.map((a) => ({ name: a.name, pid: a.pid, status: a.status })),
|
|
431
|
+
crashedAt: new Date(previousState.updatedAt).toISOString(),
|
|
432
|
+
}, 'Detected unclean shutdown — previous daemon had running apps');
|
|
433
|
+
}
|
|
434
|
+
stateStore.clear();
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
// ============================================================================
|
|
438
|
+
// Infrastructure Provisioning (Phase 1: full pipeline with gate)
|
|
439
|
+
// ============================================================================
|
|
440
|
+
async startInfrastructure(config, options, logger) {
|
|
441
|
+
if (!this.app)
|
|
442
|
+
return;
|
|
443
|
+
const gate = await this.app.container.resolveAsync(INFRASTRUCTURE_GATE_TOKEN);
|
|
444
|
+
if (options?.noInfra) {
|
|
445
|
+
gate.markFailed('Infrastructure provisioning skipped (--no-infra)');
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
const isSlave = this.dc.role === 'slave';
|
|
449
|
+
const startTime = Date.now();
|
|
450
|
+
// Step 1: Provision omnitron's own database (omnitron-pg)
|
|
451
|
+
// Slave daemons use SQLite — no Docker, no PostgreSQL
|
|
452
|
+
if (isSlave) {
|
|
453
|
+
logger.info({ role: 'slave' }, 'Slave mode — skipping omnitron-pg provisioning (using SQLite)');
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
try {
|
|
457
|
+
const { resolveOmnitronPg } = await import('../infrastructure/service-resolver.js');
|
|
458
|
+
const { createContainer, getContainerState, waitForHealthy, ensureImage, removeContainer, createVolume } = await import('../infrastructure/container-runtime.js');
|
|
459
|
+
const pgSpec = resolveOmnitronPg();
|
|
460
|
+
const existing = await getContainerState(pgSpec.name);
|
|
461
|
+
if (!existing || existing.status !== 'running') {
|
|
462
|
+
logger.info('Provisioning omnitron-pg...');
|
|
463
|
+
if (existing)
|
|
464
|
+
await removeContainer(pgSpec.name);
|
|
465
|
+
await ensureImage(pgSpec.image);
|
|
466
|
+
for (const vol of pgSpec.volumes) {
|
|
467
|
+
if (!vol.source.startsWith('/'))
|
|
468
|
+
await createVolume(vol.source);
|
|
469
|
+
}
|
|
470
|
+
await createContainer(pgSpec);
|
|
471
|
+
await waitForHealthy(pgSpec.name, 60_000);
|
|
472
|
+
logger.info('omnitron-pg ready');
|
|
473
|
+
}
|
|
474
|
+
else {
|
|
475
|
+
logger.debug('omnitron-pg already running');
|
|
476
|
+
}
|
|
477
|
+
await this.runOmnitronMigrations(logger);
|
|
478
|
+
}
|
|
479
|
+
catch (err) {
|
|
480
|
+
logger.error({ error: err.message }, 'Failed to provision omnitron-pg');
|
|
481
|
+
logger.warn('Continuing without internal database — some features will be unavailable');
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
// Step 2: Provision app infrastructure (postgres, redis, minio) if declared
|
|
485
|
+
// Slave daemons never provision Docker infrastructure
|
|
486
|
+
if (config.infrastructure && !isSlave) {
|
|
487
|
+
try {
|
|
488
|
+
this.infraService = new InfrastructureService(logger, config.infrastructure);
|
|
489
|
+
const infraState = await this.infraService.provision();
|
|
490
|
+
const provisionTimeMs = Date.now() - startTime;
|
|
491
|
+
gate.markReady(infraState);
|
|
492
|
+
this.eventBroadcaster?.broadcast(INFRA_EVENTS.READY, {
|
|
493
|
+
services: Object.keys(infraState.services),
|
|
494
|
+
provisionTimeMs,
|
|
495
|
+
});
|
|
496
|
+
logger.info({ services: Object.keys(infraState.services), provisionTimeMs }, 'App infrastructure provisioned and healthy');
|
|
497
|
+
}
|
|
498
|
+
catch (err) {
|
|
499
|
+
const reason = err.message;
|
|
500
|
+
gate.markFailed(reason);
|
|
501
|
+
this.eventBroadcaster?.broadcast(INFRA_EVENTS.FAILED, {
|
|
502
|
+
error: reason,
|
|
503
|
+
});
|
|
504
|
+
logger.error({ error: reason }, 'Failed to provision app infrastructure');
|
|
505
|
+
logger.warn('Apps with infrastructure requirements may fail to start');
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
else {
|
|
509
|
+
// No infrastructure declared — mark gate as ready with empty state
|
|
510
|
+
gate.markReady({ services: {}, ready: true });
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Remove orphan containers that Docker auto-restarted after a system reboot
|
|
515
|
+
* but don't belong to any currently registered project/stack.
|
|
516
|
+
*
|
|
517
|
+
* Containers are identified via the `omnitron.managed=true` label.
|
|
518
|
+
* Internal containers (omnitron-pg, omnitron-nginx) are always kept.
|
|
519
|
+
* Stack containers without `omnitron.stack` label (legacy) that conflict
|
|
520
|
+
* with current stack containers are stopped.
|
|
521
|
+
*/
|
|
522
|
+
async reconcileOrphanContainers(logger, projects, projectService) {
|
|
523
|
+
const { listManagedContainers, stopContainer, removeContainer } = await import('../infrastructure/container-runtime.js');
|
|
524
|
+
const managed = await listManagedContainers();
|
|
525
|
+
if (managed.length === 0)
|
|
526
|
+
return;
|
|
527
|
+
// Build set of expected container name prefixes from registered projects/stacks
|
|
528
|
+
const expectedPrefixes = new Set();
|
|
529
|
+
const internalNames = new Set(['omnitron-pg', 'omnitron-nginx']);
|
|
530
|
+
for (const project of projects) {
|
|
531
|
+
const stacks = projectService.listStacks(project.name);
|
|
532
|
+
for (const stack of stacks) {
|
|
533
|
+
expectedPrefixes.add(`${project.name}-${stack.name}-`);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
let orphanCount = 0;
|
|
537
|
+
for (const container of managed) {
|
|
538
|
+
// Always keep internal omnitron containers
|
|
539
|
+
if (internalNames.has(container.name))
|
|
540
|
+
continue;
|
|
541
|
+
// Keep containers that match a known project/stack prefix
|
|
542
|
+
if ([...expectedPrefixes].some((prefix) => container.name.startsWith(prefix)))
|
|
543
|
+
continue;
|
|
544
|
+
// This container is an orphan — stop and remove it
|
|
545
|
+
logger.info({ container: container.name, status: container.status }, 'Removing orphan container (not part of any registered stack)');
|
|
546
|
+
try {
|
|
547
|
+
if (container.status === 'running')
|
|
548
|
+
await stopContainer(container.name);
|
|
549
|
+
await removeContainer(container.name);
|
|
550
|
+
orphanCount++;
|
|
551
|
+
}
|
|
552
|
+
catch (err) {
|
|
553
|
+
logger.warn({ container: container.name, error: err.message }, 'Failed to remove orphan container');
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
if (orphanCount > 0) {
|
|
557
|
+
logger.info({ removed: orphanCount }, 'Orphan container cleanup complete');
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
async runOmnitronMigrations(logger) {
|
|
561
|
+
try {
|
|
562
|
+
const { Kysely, PostgresDialect, Migrator } = await import('kysely');
|
|
563
|
+
const pg = await import('pg');
|
|
564
|
+
const m001 = await import('../database/migrations/001_initial_schema.js');
|
|
565
|
+
const m002 = await import('../database/migrations/002_metrics_raw.js');
|
|
566
|
+
const m003 = await import('../database/migrations/003_pipelines_traces.js');
|
|
567
|
+
const m004 = await import('../database/migrations/004_sync_buffer.js');
|
|
568
|
+
const m005 = await import('../database/migrations/005_node_health_checks.js');
|
|
569
|
+
const pool = new pg.default.Pool({
|
|
570
|
+
host: 'localhost', port: 5480,
|
|
571
|
+
database: 'omnitron', user: 'omnitron', password: 'omnitron',
|
|
572
|
+
});
|
|
573
|
+
const db = new Kysely({ dialect: new PostgresDialect({ pool }) });
|
|
574
|
+
try {
|
|
575
|
+
const migrator = new Migrator({
|
|
576
|
+
db,
|
|
577
|
+
provider: {
|
|
578
|
+
async getMigrations() {
|
|
579
|
+
return {
|
|
580
|
+
'001_initial_schema': { up: m001.up, down: m001.down },
|
|
581
|
+
'002_metrics_raw': { up: m002.up, down: m002.down },
|
|
582
|
+
'003_pipelines_traces': { up: m003.up, down: m003.down },
|
|
583
|
+
'004_sync_buffer': { up: m004.up, down: m004.down },
|
|
584
|
+
'005_node_health_checks': { up: m005.up, down: m005.down },
|
|
585
|
+
};
|
|
586
|
+
},
|
|
587
|
+
},
|
|
588
|
+
});
|
|
589
|
+
const { results, error } = await migrator.migrateToLatest();
|
|
590
|
+
const applied = results?.filter((r) => r.status === 'Success') ?? [];
|
|
591
|
+
if (applied.length > 0) {
|
|
592
|
+
logger.info({ migrations: applied.map((r) => r.migrationName) }, `Applied ${applied.length} migration(s)`);
|
|
593
|
+
}
|
|
594
|
+
if (error)
|
|
595
|
+
logger.warn({ error: String(error) }, 'Migration warning');
|
|
596
|
+
}
|
|
597
|
+
finally {
|
|
598
|
+
await db.destroy();
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
catch (err) {
|
|
602
|
+
logger.warn({ error: err.message }, 'Could not run migrations — will retry on next start');
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
// ============================================================================
|
|
606
|
+
// Health Indicators (Phase 2: titan-health custom indicators)
|
|
607
|
+
// ============================================================================
|
|
608
|
+
async registerHealthIndicators() {
|
|
609
|
+
if (!this.app)
|
|
610
|
+
return;
|
|
611
|
+
try {
|
|
612
|
+
const titanHealth = await this.app.container.resolveAsync(TITAN_HEALTH_TOKEN);
|
|
613
|
+
const orchestrator = await this.app.container.resolveAsync(ORCHESTRATOR_TOKEN);
|
|
614
|
+
// Docker containers health indicator
|
|
615
|
+
titanHealth.registerIndicator(new DockerHealthIndicator(() => this.infraService));
|
|
616
|
+
// Managed apps health indicator
|
|
617
|
+
titanHealth.registerIndicator(new AppHealthIndicator(orchestrator));
|
|
618
|
+
}
|
|
619
|
+
catch {
|
|
620
|
+
// Health module may not be available — non-critical
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
// ============================================================================
|
|
624
|
+
// File Watching (dev mode)
|
|
625
|
+
// ============================================================================
|
|
626
|
+
startFileWatcher(config, options, logger) {
|
|
627
|
+
if (!options?.watch || options?.noWatch || !this.app)
|
|
628
|
+
return;
|
|
629
|
+
this.app.container.resolveAsync(ORCHESTRATOR_TOKEN).then((orchestrator) => {
|
|
630
|
+
orchestrator.devMode = true;
|
|
631
|
+
this.fileWatcher = new FileWatcher(logger, orchestrator, config, process.cwd());
|
|
632
|
+
this.fileWatcher.start(options.watchApps);
|
|
633
|
+
const watched = this.fileWatcher.getWatchedApps();
|
|
634
|
+
for (const w of watched) {
|
|
635
|
+
logger.info({ app: w.name, directory: w.directory }, 'Watching for changes');
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
// ============================================================================
|
|
640
|
+
// Start Managed Apps
|
|
641
|
+
// ============================================================================
|
|
642
|
+
/**
|
|
643
|
+
* Start all projects and their enabled stacks.
|
|
644
|
+
*
|
|
645
|
+
* The daemon is a UNIFIED CONTROL PLANE — it manages ALL registered projects
|
|
646
|
+
* and ALL their stacks simultaneously. A single host can run:
|
|
647
|
+
* - Project A: dev (local), test (remote), prod (cluster)
|
|
648
|
+
* - Project B: dev (local)
|
|
649
|
+
* - Project C: dev (local), staging (remote)
|
|
650
|
+
* All at the same time.
|
|
651
|
+
*/
|
|
652
|
+
async startApps(_config, logger) {
|
|
653
|
+
if (!this.app)
|
|
654
|
+
return;
|
|
655
|
+
const projectService = await this.app.container.resolveAsync(PROJECT_SERVICE_TOKEN);
|
|
656
|
+
let allProjects = projectService.listProjects();
|
|
657
|
+
// Auto-register project from CWD if no projects registered
|
|
658
|
+
if (allProjects.length === 0) {
|
|
659
|
+
try {
|
|
660
|
+
// Use ProjectService's own registry to auto-detect — keeps in-memory state consistent
|
|
661
|
+
projectService.autoDetectProject();
|
|
662
|
+
allProjects = projectService.listProjects();
|
|
663
|
+
if (allProjects.length > 0) {
|
|
664
|
+
const p = allProjects[0];
|
|
665
|
+
await projectService.loadProjectConfig(p.name);
|
|
666
|
+
logger.info({ project: p.name, path: p.path }, 'Auto-registered project from CWD');
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
catch (err) {
|
|
670
|
+
logger.debug({ error: err.message }, 'No project auto-detected from CWD');
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
if (allProjects.length === 0) {
|
|
674
|
+
logger.info('No projects registered. Use `omnitron project add <name> <path>` or run from a directory with omnitron.config.ts');
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
// Reconcile orphan containers: stop/remove any omnitron.managed containers
|
|
678
|
+
// that don't belong to current registered projects/stacks (e.g. leftovers from
|
|
679
|
+
// a previous session or auto-restarted by Docker after a system reboot).
|
|
680
|
+
try {
|
|
681
|
+
await this.reconcileOrphanContainers(logger, allProjects, projectService);
|
|
682
|
+
}
|
|
683
|
+
catch (err) {
|
|
684
|
+
logger.warn({ error: err.message }, 'Orphan container reconciliation failed — continuing');
|
|
685
|
+
}
|
|
686
|
+
// Iterate ALL registered projects and start their enabled stacks
|
|
687
|
+
let totalStacks = 0;
|
|
688
|
+
for (const project of allProjects) {
|
|
689
|
+
// Load project config (populates internal cache used by listStacks)
|
|
690
|
+
try {
|
|
691
|
+
await projectService.loadProjectConfig(project.name);
|
|
692
|
+
}
|
|
693
|
+
catch (err) {
|
|
694
|
+
logger.warn({ project: project.name, error: err.message }, 'Failed to load project config — skipping');
|
|
695
|
+
continue;
|
|
696
|
+
}
|
|
697
|
+
// Only start stacks that were explicitly enabled (persisted in registry).
|
|
698
|
+
// Stacks are never auto-started — user must explicitly start via CLI or webapp.
|
|
699
|
+
// Use listStacks() to include user stacks from omnitron.stacks.json (not just config stacks).
|
|
700
|
+
const availableStacks = projectService.listStacks(project.name).map((s) => s.name);
|
|
701
|
+
const enabledStacks = (project.enabledStacks ?? [])
|
|
702
|
+
.filter((s) => availableStacks.includes(s));
|
|
703
|
+
if (enabledStacks.length === 0) {
|
|
704
|
+
logger.debug({ project: project.name }, 'No enabled stacks — skipping');
|
|
705
|
+
continue;
|
|
706
|
+
}
|
|
707
|
+
logger.info({ project: project.name, stacks: enabledStacks }, 'Starting project stacks');
|
|
708
|
+
// Start each enabled stack
|
|
709
|
+
for (const stackName of enabledStacks) {
|
|
710
|
+
try {
|
|
711
|
+
await projectService.startStack(project.name, stackName);
|
|
712
|
+
totalStacks++;
|
|
713
|
+
logger.info({ project: project.name, stack: stackName }, 'Stack started');
|
|
714
|
+
}
|
|
715
|
+
catch (err) {
|
|
716
|
+
logger.error({ project: project.name, stack: stackName, error: err.message }, 'Failed to start stack — continuing with remaining');
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
logger.info({ projects: allProjects.length, stacks: totalStacks }, 'All projects and stacks initialized');
|
|
721
|
+
}
|
|
722
|
+
// ============================================================================
|
|
723
|
+
// Scheduled Tasks (Phase 2: titan-scheduler replaces bare setInterval)
|
|
724
|
+
// ============================================================================
|
|
725
|
+
async startScheduledTasks(config, logger) {
|
|
726
|
+
if (!this.app)
|
|
727
|
+
return;
|
|
728
|
+
const container = this.app.container;
|
|
729
|
+
const isSlave = this.dc.role === 'slave';
|
|
730
|
+
try {
|
|
731
|
+
const scheduler = await container.resolveAsync(SCHEDULER_SERVICE_TOKEN);
|
|
732
|
+
const orchestrator = await container.resolveAsync(ORCHESTRATOR_TOKEN);
|
|
733
|
+
const titanMetrics = await container.resolveAsync(TITAN_METRICS_TOKEN);
|
|
734
|
+
const logManager = await container.resolveAsync(LOG_MANAGER_TOKEN);
|
|
735
|
+
// Master-only services (require PG)
|
|
736
|
+
const authService = !isSlave ? await container.resolveAsync(AUTH_SERVICE_TOKEN) : null;
|
|
737
|
+
const alertService = !isSlave ? await container.resolveAsync(ALERT_SERVICE_TOKEN) : null;
|
|
738
|
+
const fleetService = !isSlave ? await container.resolveAsync(FLEET_SERVICE_TOKEN) : null;
|
|
739
|
+
registerDaemonJobs(scheduler, {
|
|
740
|
+
logger,
|
|
741
|
+
orchestrator,
|
|
742
|
+
authService,
|
|
743
|
+
metricsService: titanMetrics,
|
|
744
|
+
alertService,
|
|
745
|
+
fleetService,
|
|
746
|
+
logManager,
|
|
747
|
+
infraService: this.infraService,
|
|
748
|
+
metricsInterval: config.monitoring.metrics.interval,
|
|
749
|
+
healthCheckInterval: config.monitoring.healthCheck.interval,
|
|
750
|
+
});
|
|
751
|
+
// Start titan-metrics collection + flush
|
|
752
|
+
titanMetrics.start();
|
|
753
|
+
logger.info('Daemon scheduler started with all periodic jobs');
|
|
754
|
+
}
|
|
755
|
+
catch (err) {
|
|
756
|
+
logger.warn({ error: err.message }, 'Failed to start scheduler — falling back to manual timers');
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
// ============================================================================
|
|
760
|
+
// Background Services (telemetry, traces, fleet, leader election)
|
|
761
|
+
// ============================================================================
|
|
762
|
+
async startBackgroundServices(config, logger) {
|
|
763
|
+
if (!this.app)
|
|
764
|
+
return;
|
|
765
|
+
const container = this.app.container;
|
|
766
|
+
const isSlave = this.dc.role === 'slave';
|
|
767
|
+
// Start telemetry relay (master only — requires PG)
|
|
768
|
+
if (!isSlave) {
|
|
769
|
+
try {
|
|
770
|
+
const telemetryRelay = await container.resolveAsync(TELEMETRY_RELAY_TOKEN);
|
|
771
|
+
await telemetryRelay.start();
|
|
772
|
+
logger.info({ nodeId: telemetryRelay.nodeId, role: telemetryRelay.role }, 'Telemetry relay started');
|
|
773
|
+
}
|
|
774
|
+
catch (err) {
|
|
775
|
+
logger.warn({ error: err.message }, 'Telemetry relay failed to start');
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
// Register self in fleet (master only — requires PG)
|
|
779
|
+
if (!isSlave) {
|
|
780
|
+
try {
|
|
781
|
+
const fleetService = await container.resolveAsync(FLEET_SERVICE_TOKEN);
|
|
782
|
+
await fleetService.registerNode({
|
|
783
|
+
hostname: os.hostname(),
|
|
784
|
+
address: this.dc.host === '0.0.0.0' ? '127.0.0.1' : this.dc.host,
|
|
785
|
+
port: this.dc.port,
|
|
786
|
+
role: 'leader',
|
|
787
|
+
metadata: { pid: process.pid, version: CLI_VERSION, httpPort: this.dc.httpPort },
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
catch {
|
|
791
|
+
// Non-critical — DB may not be ready
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
// Start sync service (slave→master data replication)
|
|
795
|
+
// Slaves buffer data locally and wait for master to connect and pull.
|
|
796
|
+
// Master initiates connections to slaves (slaves are always reachable).
|
|
797
|
+
if (this.syncService) {
|
|
798
|
+
this.syncService.start();
|
|
799
|
+
if (this.dc.role === 'slave') {
|
|
800
|
+
logger.info({ role: 'slave' }, 'Sync service started — buffering locally, waiting for master to connect');
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
// Start trace collector (master only — requires PG)
|
|
804
|
+
if (!isSlave) {
|
|
805
|
+
try {
|
|
806
|
+
const traceCollector = await container.resolveAsync(TRACE_COLLECTOR_TOKEN);
|
|
807
|
+
traceCollector.start();
|
|
808
|
+
logger.info('Trace collector started');
|
|
809
|
+
}
|
|
810
|
+
catch (err) {
|
|
811
|
+
logger.warn({ error: err.message }, 'Trace collector failed to start');
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
// Start leader election (cluster mode, master only)
|
|
815
|
+
// LeaderElection instance is already created in exposeRpcServices(); just start it here.
|
|
816
|
+
if (this.leaderElection && !isSlave) {
|
|
817
|
+
try {
|
|
818
|
+
await this.leaderElection.start();
|
|
819
|
+
logger.info({ cluster: true }, 'Leader election started');
|
|
820
|
+
const loggerModule = await container.resolveAsync(LOGGER_SERVICE_TOKEN);
|
|
821
|
+
const { ConfigSyncService } = await import('../cluster/config-sync.js');
|
|
822
|
+
this.configSyncService = new ConfigSyncService(config, loggerModule.logger);
|
|
823
|
+
}
|
|
824
|
+
catch (err) {
|
|
825
|
+
logger.warn({ error: err.message }, 'Leader election failed to start');
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
// ============================================================================
|
|
830
|
+
// Health Monitor System Worker
|
|
831
|
+
// ============================================================================
|
|
832
|
+
async startHealthMonitorWorker(logger) {
|
|
833
|
+
if (!this.app || !this.nodeManagerService || this.dc.role === 'slave')
|
|
834
|
+
return;
|
|
835
|
+
try {
|
|
836
|
+
const titanPm = await import('@omnitron-dev/titan-pm');
|
|
837
|
+
const { SystemWorkerManager } = await import('../workers/system-worker-manager.js');
|
|
838
|
+
const { fileURLToPath } = await import('node:url');
|
|
839
|
+
const nodePath = await import('node:path');
|
|
840
|
+
// Resolve PM from DI
|
|
841
|
+
const pm = await this.app.container.resolveAsync(titanPm.PM_MANAGER_TOKEN);
|
|
842
|
+
const loggerModule = await this.app.container.resolveAsync(LOGGER_SERVICE_TOKEN);
|
|
843
|
+
this.systemWorkerManager = new SystemWorkerManager(pm, loggerModule.logger.child({ component: 'system-workers' }));
|
|
844
|
+
// Build health monitor config
|
|
845
|
+
const hmDefaults = this.dc.healthMonitor ?? {};
|
|
846
|
+
const healthConfig = {
|
|
847
|
+
intervalMs: hmDefaults.intervalMs ?? 30_000,
|
|
848
|
+
concurrency: hmDefaults.concurrency ?? 20,
|
|
849
|
+
offlineTimeoutMs: hmDefaults.offlineTimeoutMs ?? 90_000,
|
|
850
|
+
pingTimeout: hmDefaults.pingTimeout ?? 5_000,
|
|
851
|
+
sshTimeout: hmDefaults.sshTimeout ?? 10_000,
|
|
852
|
+
omnitronCheckTimeout: hmDefaults.omnitronCheckTimeout ?? 15_000,
|
|
853
|
+
pingEnabled: hmDefaults.pingEnabled ?? true,
|
|
854
|
+
retentionDays: hmDefaults.retentionDays ?? 7,
|
|
855
|
+
dbUrl: 'postgresql://omnitron:omnitron@localhost:5480/omnitron',
|
|
856
|
+
};
|
|
857
|
+
// Get worker process path — .ts when running via tsx, .js when compiled
|
|
858
|
+
const thisDir = nodePath.dirname(fileURLToPath(import.meta.url));
|
|
859
|
+
const isTsx = process.execArgv.some((a) => a.includes('tsx'));
|
|
860
|
+
const ext = isTsx ? '.ts' : '.js';
|
|
861
|
+
const workerPath = nodePath.resolve(thisDir, '..', 'workers', `health-monitor-process${ext}`);
|
|
862
|
+
// Convert nodes to check targets
|
|
863
|
+
const nodesJson = JSON.stringify(await this.nodeManagerService.getNodeCheckTargets());
|
|
864
|
+
const configJson = JSON.stringify(healthConfig);
|
|
865
|
+
const spawnOpts = {};
|
|
866
|
+
if (process.execArgv.some((a) => a.includes('tsx'))) {
|
|
867
|
+
spawnOpts.execArgv = ['--import', 'tsx/esm'];
|
|
868
|
+
}
|
|
869
|
+
spawnOpts.startupTimeout = 30_000;
|
|
870
|
+
const proxy = await this.systemWorkerManager.spawn('health-monitor', workerPath, { configJson, nodesJson }, spawnOpts);
|
|
871
|
+
// Wire IPC: worker → master status cache updates via PM's public API
|
|
872
|
+
const nodeManager = this.nodeManagerService;
|
|
873
|
+
const eventBroadcaster = this.eventBroadcaster;
|
|
874
|
+
this.systemWorkerManager.onMessage('health-monitor', (msg) => {
|
|
875
|
+
if (msg?.type === 'health:status_batch' && Array.isArray(msg.summaries)) {
|
|
876
|
+
nodeManager.updateStatusCacheFromWorker(msg.summaries);
|
|
877
|
+
// Broadcast node status updates via WebSocket
|
|
878
|
+
if (eventBroadcaster) {
|
|
879
|
+
const online = msg.summaries.filter((s) => s.status === 'online').length;
|
|
880
|
+
const degraded = msg.summaries.filter((s) => s.status === 'degraded').length;
|
|
881
|
+
const offline = msg.summaries.filter((s) => s.status === 'offline').length;
|
|
882
|
+
eventBroadcaster.broadcast(NODE_EVENTS.CHECK_COMPLETED, {
|
|
883
|
+
nodeCount: msg.summaries.length,
|
|
884
|
+
onlineCount: online,
|
|
885
|
+
degradedCount: degraded,
|
|
886
|
+
offlineCount: offline,
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
});
|
|
891
|
+
// Wire node CRUD events → sync to worker
|
|
892
|
+
const syncNodesToWorker = async () => {
|
|
893
|
+
const targets = await nodeManager.getNodeCheckTargets();
|
|
894
|
+
proxy.updateNodes(JSON.stringify(targets)).catch(() => { });
|
|
895
|
+
};
|
|
896
|
+
nodeManager.on('node:added', syncNodesToWorker);
|
|
897
|
+
nodeManager.on('node:updated', syncNodesToWorker);
|
|
898
|
+
nodeManager.on('node:removed', syncNodesToWorker);
|
|
899
|
+
// Wire RPC service to use worker proxy + PG repository for direct reads
|
|
900
|
+
if (this.nodeManagerRpcService) {
|
|
901
|
+
this.nodeManagerRpcService.setHealthWorkerProxy(proxy);
|
|
902
|
+
// Wire PG repository for direct history reads (bypasses worker)
|
|
903
|
+
try {
|
|
904
|
+
const db = await this.app.container.resolveAsync(OMNITRON_DB_TOKEN);
|
|
905
|
+
const { NodeHealthRepository } = await import('../services/node-health.repository.js');
|
|
906
|
+
this.nodeManagerRpcService.setHealthRepository(new NodeHealthRepository(db));
|
|
907
|
+
}
|
|
908
|
+
catch {
|
|
909
|
+
logger.warn({}, 'Could not wire health repository — PG may not be ready');
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
logger.info({ intervalMs: healthConfig.intervalMs }, 'Health monitor system worker started');
|
|
913
|
+
}
|
|
914
|
+
catch (err) {
|
|
915
|
+
logger.warn({ error: err.message }, 'Health monitor worker failed to start — falling back to direct checks');
|
|
916
|
+
// Fallback: start legacy periodic checks if worker fails
|
|
917
|
+
// This ensures node status still works even without the worker
|
|
918
|
+
if (this.nodeManagerService) {
|
|
919
|
+
const intervalMs = this.dc.healthMonitor?.intervalMs ?? 30_000;
|
|
920
|
+
const timer = setInterval(() => void this.nodeManagerService?.checkAllNodes(), intervalMs);
|
|
921
|
+
timer.unref();
|
|
922
|
+
void this.nodeManagerService.checkAllNodes();
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
// ============================================================================
|
|
927
|
+
// Event Broadcasting (Phase 3: orchestrator events → WebSocket push)
|
|
928
|
+
// ============================================================================
|
|
929
|
+
async wireEventBroadcasting(logger) {
|
|
930
|
+
if (!this.app || !this.eventBroadcaster)
|
|
931
|
+
return;
|
|
932
|
+
const orchestrator = await this.app.container.resolveAsync(ORCHESTRATOR_TOKEN);
|
|
933
|
+
const broadcaster = this.eventBroadcaster;
|
|
934
|
+
// Wire orchestrator events to broadcaster
|
|
935
|
+
orchestrator.on('app:online', (appName) => {
|
|
936
|
+
const handle = orchestrator.getHandle(appName);
|
|
937
|
+
broadcaster.broadcast(APP_EVENTS.STARTED, {
|
|
938
|
+
name: appName,
|
|
939
|
+
pid: handle?.pid ?? null,
|
|
940
|
+
mode: handle?.mode ?? 'bootstrap',
|
|
941
|
+
instances: handle?.instanceCount ?? 1,
|
|
942
|
+
});
|
|
943
|
+
});
|
|
944
|
+
orchestrator.on('app:crash', (appName, error) => {
|
|
945
|
+
const handle = orchestrator.getHandle(appName);
|
|
946
|
+
broadcaster.broadcast(APP_EVENTS.CRASHED, {
|
|
947
|
+
name: appName,
|
|
948
|
+
error: error.message,
|
|
949
|
+
restarts: handle?.restarts ?? 0,
|
|
950
|
+
critical: handle?.entry.critical ?? false,
|
|
951
|
+
});
|
|
952
|
+
});
|
|
953
|
+
orchestrator.on('app:restart', (appName, attempt) => {
|
|
954
|
+
broadcaster.broadcast(APP_EVENTS.RESTARTING, {
|
|
955
|
+
name: appName,
|
|
956
|
+
attempt,
|
|
957
|
+
});
|
|
958
|
+
});
|
|
959
|
+
// Wire project/stack events
|
|
960
|
+
const projectService = await this.app.container.resolveAsync(PROJECT_SERVICE_TOKEN);
|
|
961
|
+
projectService.on('project:added', (name, projectPath) => {
|
|
962
|
+
broadcaster.broadcast(PROJECT_EVENTS.ADDED, {
|
|
963
|
+
name,
|
|
964
|
+
path: projectPath,
|
|
965
|
+
});
|
|
966
|
+
});
|
|
967
|
+
projectService.on('project:removed', (name) => {
|
|
968
|
+
broadcaster.broadcast(PROJECT_EVENTS.REMOVED, { name });
|
|
969
|
+
});
|
|
970
|
+
projectService.on('project:config_reloaded', (name) => {
|
|
971
|
+
broadcaster.broadcast(PROJECT_EVENTS.CONFIG_RELOADED, { name });
|
|
972
|
+
});
|
|
973
|
+
projectService.on('stack:started', (project, stack, type) => {
|
|
974
|
+
broadcaster.broadcast(STACK_EVENTS.STARTED, {
|
|
975
|
+
project,
|
|
976
|
+
stack,
|
|
977
|
+
type: type,
|
|
978
|
+
appCount: 0,
|
|
979
|
+
nodeCount: 0,
|
|
980
|
+
});
|
|
981
|
+
});
|
|
982
|
+
projectService.on('stack:stopped', (project, stack, reason) => {
|
|
983
|
+
broadcaster.broadcast(STACK_EVENTS.STOPPED, {
|
|
984
|
+
project,
|
|
985
|
+
stack,
|
|
986
|
+
reason: reason,
|
|
987
|
+
});
|
|
988
|
+
});
|
|
989
|
+
projectService.on('stack:error', (project, stack, error) => {
|
|
990
|
+
broadcaster.broadcast(STACK_EVENTS.ERROR, {
|
|
991
|
+
project,
|
|
992
|
+
stack,
|
|
993
|
+
error,
|
|
994
|
+
});
|
|
995
|
+
});
|
|
996
|
+
projectService.on('stack:deploy_progress', (project, stack, progress) => {
|
|
997
|
+
broadcaster.broadcast(STACK_EVENTS.DEPLOY_PROGRESS, {
|
|
998
|
+
project,
|
|
999
|
+
stack,
|
|
1000
|
+
...progress,
|
|
1001
|
+
});
|
|
1002
|
+
});
|
|
1003
|
+
logger.debug('Event broadcasting wired to orchestrator and project service');
|
|
1004
|
+
}
|
|
1005
|
+
// ============================================================================
|
|
1006
|
+
// Watch Mode Control (used by DaemonRpcService)
|
|
1007
|
+
// ============================================================================
|
|
1008
|
+
async enableWatch(apps) {
|
|
1009
|
+
if (!this.app)
|
|
1010
|
+
throw new Error('Daemon not started');
|
|
1011
|
+
const orchestrator = await this.app.container.resolveAsync(ORCHESTRATOR_TOKEN);
|
|
1012
|
+
const loggerModule = await this.app.container.resolveAsync(LOGGER_SERVICE_TOKEN);
|
|
1013
|
+
if (this.fileWatcher) {
|
|
1014
|
+
this.fileWatcher.stop();
|
|
1015
|
+
}
|
|
1016
|
+
const config = await this.getConfig();
|
|
1017
|
+
this.fileWatcher = new FileWatcher(loggerModule.logger, orchestrator, config, process.cwd());
|
|
1018
|
+
this.fileWatcher.start(apps);
|
|
1019
|
+
return this.fileWatcher.getWatchedApps();
|
|
1020
|
+
}
|
|
1021
|
+
disableWatch() {
|
|
1022
|
+
if (this.fileWatcher) {
|
|
1023
|
+
this.fileWatcher.stop();
|
|
1024
|
+
this.fileWatcher = null;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
getWatchStatus() {
|
|
1028
|
+
if (!this.fileWatcher)
|
|
1029
|
+
return { enabled: false, apps: [] };
|
|
1030
|
+
return { enabled: true, apps: this.fileWatcher.getWatchedApps() };
|
|
1031
|
+
}
|
|
1032
|
+
async getConfig() {
|
|
1033
|
+
const { loadEcosystemConfig } = await import('../config/loader.js');
|
|
1034
|
+
return loadEcosystemConfig();
|
|
1035
|
+
}
|
|
1036
|
+
// ============================================================================
|
|
1037
|
+
// Lifecycle
|
|
1038
|
+
// ============================================================================
|
|
1039
|
+
/**
|
|
1040
|
+
* Trigger graceful shutdown via Application's lifecycle system.
|
|
1041
|
+
* Called by DaemonRpcService.shutdown() for the `omnitron shutdown` CLI command.
|
|
1042
|
+
*/
|
|
1043
|
+
async stop() {
|
|
1044
|
+
if (!this.app)
|
|
1045
|
+
return;
|
|
1046
|
+
await this.app.shutdown(ShutdownReason.Manual);
|
|
1047
|
+
// Application doesn't process.exit() for Manual reason — do it explicitly
|
|
1048
|
+
process.exit(0);
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* Register all daemon shutdown tasks with Application's lifecycle system.
|
|
1052
|
+
*
|
|
1053
|
+
* Application handles SIGTERM/SIGINT/SIGHUP automatically and runs
|
|
1054
|
+
* shutdown tasks in priority order before calling app.stop() and process.exit().
|
|
1055
|
+
*
|
|
1056
|
+
* Priority order (lower = first):
|
|
1057
|
+
* First (0) — Broadcast stopping event, stop file watcher
|
|
1058
|
+
* VeryHigh (10) — Stop managed apps (orchestrator.stopAll)
|
|
1059
|
+
* High (20) — Stop background services (scheduler, telemetry, alerts, fleet)
|
|
1060
|
+
* Normal (50) — Stop system workers, node manager, sync, cluster
|
|
1061
|
+
* Low (80) — Flush logs to DB, clear state
|
|
1062
|
+
* VeryLow (90) — Dispose project service, teardown infrastructure
|
|
1063
|
+
* Last (100) — Remove PID file
|
|
1064
|
+
*/
|
|
1065
|
+
registerShutdownTasks(app) {
|
|
1066
|
+
const container = app.container;
|
|
1067
|
+
// Broadcast DAEMON_EVENTS.STOPPING on shutdown start
|
|
1068
|
+
app.on(ApplicationEvent.ShutdownStart, ({ reason, details }) => {
|
|
1069
|
+
this.eventBroadcaster?.broadcast(DAEMON_EVENTS.STOPPING, {
|
|
1070
|
+
reason,
|
|
1071
|
+
signal: details?.signal,
|
|
1072
|
+
});
|
|
1073
|
+
});
|
|
1074
|
+
// --- Priority: First (0) — Immediate cleanup ---
|
|
1075
|
+
app.registerShutdownTask('stop-file-watcher-and-webapp', async () => {
|
|
1076
|
+
if (this.fileWatcher) {
|
|
1077
|
+
this.fileWatcher.stop();
|
|
1078
|
+
this.fileWatcher = null;
|
|
1079
|
+
}
|
|
1080
|
+
if (this.eventBroadcaster) {
|
|
1081
|
+
this.eventBroadcaster.clear();
|
|
1082
|
+
this.eventBroadcaster = null;
|
|
1083
|
+
}
|
|
1084
|
+
// Stop webapp nginx container (non-blocking — don't wait if slow)
|
|
1085
|
+
try {
|
|
1086
|
+
const { removeContainer } = await import('../infrastructure/container-runtime.js');
|
|
1087
|
+
void removeContainer('omnitron-nginx');
|
|
1088
|
+
}
|
|
1089
|
+
catch { /* non-critical */ }
|
|
1090
|
+
}, ShutdownPriority.First);
|
|
1091
|
+
// --- Priority: VeryHigh (10) — Stop managed apps (fast — 5s per app max) ---
|
|
1092
|
+
app.registerShutdownTask('stop-managed-apps', async () => {
|
|
1093
|
+
const orchestrator = await container.resolveAsync(ORCHESTRATOR_TOKEN);
|
|
1094
|
+
await orchestrator.stopAll(true); // force=true for fast shutdown (SIGTERM + 5s → SIGKILL)
|
|
1095
|
+
}, ShutdownPriority.VeryHigh);
|
|
1096
|
+
// --- Priority: High (20) — Stop background services ---
|
|
1097
|
+
app.registerShutdownTask('stop-background-services', async () => {
|
|
1098
|
+
try {
|
|
1099
|
+
const relay = await container.resolveAsync(TELEMETRY_RELAY_TOKEN);
|
|
1100
|
+
await relay.stop();
|
|
1101
|
+
}
|
|
1102
|
+
catch { /* non-critical */ }
|
|
1103
|
+
try {
|
|
1104
|
+
const mc = await container.resolveAsync(TITAN_METRICS_TOKEN);
|
|
1105
|
+
await mc.stop();
|
|
1106
|
+
}
|
|
1107
|
+
catch { /* non-critical */ }
|
|
1108
|
+
try {
|
|
1109
|
+
const alert = await container.resolveAsync(ALERT_SERVICE_TOKEN);
|
|
1110
|
+
alert.stop();
|
|
1111
|
+
}
|
|
1112
|
+
catch { /* non-critical */ }
|
|
1113
|
+
try {
|
|
1114
|
+
const fleet = await container.resolveAsync(FLEET_SERVICE_TOKEN);
|
|
1115
|
+
fleet.stopHeartbeatSweep();
|
|
1116
|
+
}
|
|
1117
|
+
catch { /* non-critical */ }
|
|
1118
|
+
try {
|
|
1119
|
+
const tc = await container.resolveAsync(TRACE_COLLECTOR_TOKEN);
|
|
1120
|
+
await tc.stop();
|
|
1121
|
+
}
|
|
1122
|
+
catch { /* non-critical */ }
|
|
1123
|
+
}, ShutdownPriority.High);
|
|
1124
|
+
// --- Priority: Normal (50) — System workers, node manager, sync, cluster ---
|
|
1125
|
+
app.registerShutdownTask('stop-system-services', async () => {
|
|
1126
|
+
if (this.syncService) {
|
|
1127
|
+
try {
|
|
1128
|
+
await this.syncService.stop();
|
|
1129
|
+
}
|
|
1130
|
+
catch { /* non-critical */ }
|
|
1131
|
+
this.syncService = null;
|
|
1132
|
+
}
|
|
1133
|
+
try {
|
|
1134
|
+
if (this.leaderElection?.stop)
|
|
1135
|
+
this.leaderElection.stop();
|
|
1136
|
+
}
|
|
1137
|
+
catch { /* non-critical */ }
|
|
1138
|
+
try {
|
|
1139
|
+
if (this.configSyncService?.stopPeriodicSync)
|
|
1140
|
+
this.configSyncService.stopPeriodicSync();
|
|
1141
|
+
}
|
|
1142
|
+
catch { /* non-critical */ }
|
|
1143
|
+
if (this.systemWorkerManager) {
|
|
1144
|
+
try {
|
|
1145
|
+
await this.systemWorkerManager.stopAll();
|
|
1146
|
+
}
|
|
1147
|
+
catch { /* non-critical */ }
|
|
1148
|
+
this.systemWorkerManager = null;
|
|
1149
|
+
}
|
|
1150
|
+
if (this.nodeManagerRpcService) {
|
|
1151
|
+
this.nodeManagerRpcService.setHealthWorkerProxy(null);
|
|
1152
|
+
this.nodeManagerRpcService.setHealthRepository(null);
|
|
1153
|
+
this.nodeManagerRpcService = null;
|
|
1154
|
+
}
|
|
1155
|
+
if (this.nodeManagerService) {
|
|
1156
|
+
try {
|
|
1157
|
+
await this.nodeManagerService.dispose();
|
|
1158
|
+
}
|
|
1159
|
+
catch { /* non-critical */ }
|
|
1160
|
+
this.nodeManagerService = null;
|
|
1161
|
+
}
|
|
1162
|
+
try {
|
|
1163
|
+
const bs = await container.resolveAsync(BACKUP_SERVICE_TOKEN);
|
|
1164
|
+
bs.dispose();
|
|
1165
|
+
}
|
|
1166
|
+
catch { /* non-critical */ }
|
|
1167
|
+
}, ShutdownPriority.Normal);
|
|
1168
|
+
// --- Priority: Low (80) — Flush logs, clear state ---
|
|
1169
|
+
app.registerShutdownTask('flush-and-clear', async () => {
|
|
1170
|
+
try {
|
|
1171
|
+
const logCollector = await container.resolveAsync(LOG_COLLECTOR_TOKEN);
|
|
1172
|
+
await logCollector.dispose();
|
|
1173
|
+
}
|
|
1174
|
+
catch { /* non-critical */ }
|
|
1175
|
+
try {
|
|
1176
|
+
const stateStore = await container.resolveAsync(STATE_STORE_TOKEN);
|
|
1177
|
+
stateStore.clear();
|
|
1178
|
+
}
|
|
1179
|
+
catch { /* non-critical */ }
|
|
1180
|
+
}, ShutdownPriority.Low);
|
|
1181
|
+
// --- Priority: VeryLow (90) — Project service, infrastructure teardown ---
|
|
1182
|
+
app.registerShutdownTask('teardown-infrastructure', async () => {
|
|
1183
|
+
try {
|
|
1184
|
+
const projectSvc = await container.resolveAsync(PROJECT_SERVICE_TOKEN);
|
|
1185
|
+
await projectSvc.dispose();
|
|
1186
|
+
}
|
|
1187
|
+
catch { /* non-critical */ }
|
|
1188
|
+
if (this.infraService) {
|
|
1189
|
+
try {
|
|
1190
|
+
await this.infraService.teardown();
|
|
1191
|
+
}
|
|
1192
|
+
catch { /* best-effort */ }
|
|
1193
|
+
this.infraService = null;
|
|
1194
|
+
}
|
|
1195
|
+
}, ShutdownPriority.VeryLow);
|
|
1196
|
+
// --- Priority: Last (100) — PID file removal ---
|
|
1197
|
+
app.registerShutdownTask('remove-pid', () => {
|
|
1198
|
+
this.pidManager?.remove();
|
|
1199
|
+
}, ShutdownPriority.Last);
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
//# sourceMappingURL=daemon.js.map
|