@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,1112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProjectService — Manages projects and their stacks
|
|
3
|
+
*
|
|
4
|
+
* Wraps ProjectRegistry with stack lifecycle management.
|
|
5
|
+
* DI-managed singleton — resolves via PROJECT_SERVICE_TOKEN.
|
|
6
|
+
*
|
|
7
|
+
* Architecture:
|
|
8
|
+
* - Projects are monorepos with omnitron.config.ts
|
|
9
|
+
* - Each project has multiple stacks (dev, test, prod)
|
|
10
|
+
* - Stacks run simultaneously — starting one does not affect others
|
|
11
|
+
* - Each stack has its own namespace: project/stack/app
|
|
12
|
+
* - Remote/cluster stacks have slave daemons that collect data locally
|
|
13
|
+
* and sync to master when connectivity is available
|
|
14
|
+
*/
|
|
15
|
+
import fs from 'node:fs';
|
|
16
|
+
import path from 'node:path';
|
|
17
|
+
import { EventEmitter } from '@omnitron-dev/eventemitter';
|
|
18
|
+
import { ProjectRegistry } from '../project/registry.js';
|
|
19
|
+
import { StackInfrastructureManager } from '../infrastructure/stack-infra-manager.js';
|
|
20
|
+
import { resolveStack, resolvedConfigToEnv } from '../project/config-resolver.js';
|
|
21
|
+
import { SlaveConnector } from '../cluster/slave-connector.js';
|
|
22
|
+
import { RemoteDeployer } from './remote-deployer.service.js';
|
|
23
|
+
// =============================================================================
|
|
24
|
+
// ProjectService
|
|
25
|
+
// =============================================================================
|
|
26
|
+
export class ProjectService extends EventEmitter {
|
|
27
|
+
logger;
|
|
28
|
+
orchestrator;
|
|
29
|
+
fleetService;
|
|
30
|
+
syncService;
|
|
31
|
+
registry;
|
|
32
|
+
configRegistry = new Map();
|
|
33
|
+
stackStates = new Map();
|
|
34
|
+
infraManager;
|
|
35
|
+
slaveConnector = null;
|
|
36
|
+
deployer;
|
|
37
|
+
constructor(logger, orchestrator, fleetService, syncService) {
|
|
38
|
+
super();
|
|
39
|
+
this.logger = logger;
|
|
40
|
+
this.orchestrator = orchestrator;
|
|
41
|
+
this.fleetService = fleetService;
|
|
42
|
+
this.syncService = syncService;
|
|
43
|
+
this.registry = new ProjectRegistry();
|
|
44
|
+
this.infraManager = new StackInfrastructureManager(logger);
|
|
45
|
+
this.deployer = new RemoteDeployer(logger);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get or create the SlaveConnector (lazy — only created when first remote/cluster stack starts).
|
|
49
|
+
*/
|
|
50
|
+
getSlaveConnector() {
|
|
51
|
+
if (!this.slaveConnector) {
|
|
52
|
+
this.slaveConnector = new SlaveConnector(this.logger, this.fleetService, this.syncService ?? null);
|
|
53
|
+
}
|
|
54
|
+
return this.slaveConnector;
|
|
55
|
+
}
|
|
56
|
+
// ===========================================================================
|
|
57
|
+
// Projects
|
|
58
|
+
// ===========================================================================
|
|
59
|
+
/**
|
|
60
|
+
* Auto-detect project from CWD using the internal registry.
|
|
61
|
+
* Keeps in-memory state consistent (unlike creating a separate ProjectRegistry).
|
|
62
|
+
*/
|
|
63
|
+
autoDetectProject(cwd) {
|
|
64
|
+
const detected = this.registry.autoDetect(cwd);
|
|
65
|
+
return detected ? this.toProjectInfo(detected) : null;
|
|
66
|
+
}
|
|
67
|
+
listProjects() {
|
|
68
|
+
return this.registry.list().map((p) => this.toProjectInfo(p));
|
|
69
|
+
}
|
|
70
|
+
getProject(name) {
|
|
71
|
+
const project = this.registry.get(name);
|
|
72
|
+
if (!project)
|
|
73
|
+
throw new Error(`Project '${name}' not found`);
|
|
74
|
+
return this.toProjectInfo(project);
|
|
75
|
+
}
|
|
76
|
+
addProject(name, projectPath) {
|
|
77
|
+
const project = this.registry.add(name, projectPath);
|
|
78
|
+
this.logger.info({ project: name, path: projectPath }, 'Project registered');
|
|
79
|
+
this.emit('project:added', name, projectPath);
|
|
80
|
+
return this.toProjectInfo(project);
|
|
81
|
+
}
|
|
82
|
+
removeProject(name) {
|
|
83
|
+
// Stop all running stacks for this project first
|
|
84
|
+
const runningStacks = this.getRunningStacks(name);
|
|
85
|
+
if (runningStacks.length > 0) {
|
|
86
|
+
throw new Error(`Project '${name}' has running stacks: ${runningStacks.join(', ')}. Stop them first.`);
|
|
87
|
+
}
|
|
88
|
+
this.registry.remove(name);
|
|
89
|
+
this.configRegistry.delete(name);
|
|
90
|
+
this.logger.info({ project: name }, 'Project removed');
|
|
91
|
+
this.emit('project:removed', name);
|
|
92
|
+
}
|
|
93
|
+
async scanRequirements(projectName) {
|
|
94
|
+
const project = this.registry.get(projectName);
|
|
95
|
+
if (!project)
|
|
96
|
+
throw new Error(`Project '${projectName}' not found`);
|
|
97
|
+
const { scanRequirements } = await import('../project/requirements-scanner.js');
|
|
98
|
+
const config = await this.loadProjectConfig(projectName);
|
|
99
|
+
const rawReqs = await scanRequirements(config.apps, project.path);
|
|
100
|
+
// Map to DTO
|
|
101
|
+
const apps = {};
|
|
102
|
+
for (const [appName, reqs] of rawReqs.byApp) {
|
|
103
|
+
apps[appName] = {
|
|
104
|
+
postgres: !!reqs.database,
|
|
105
|
+
redis: !!reqs.redis,
|
|
106
|
+
s3: !!reqs.s3,
|
|
107
|
+
discovery: !!reqs.services?.discovery,
|
|
108
|
+
notifications: !!reqs.services?.notifications,
|
|
109
|
+
custom: [],
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
apps,
|
|
114
|
+
needsPostgres: Object.values(apps).some((a) => a.postgres),
|
|
115
|
+
needsRedis: Object.values(apps).some((a) => a.redis),
|
|
116
|
+
needsS3: Object.values(apps).some((a) => a.s3),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
// ===========================================================================
|
|
120
|
+
// User Stacks — persisted in omnitron.stacks.json in project root
|
|
121
|
+
// ===========================================================================
|
|
122
|
+
async createStack(project, input) {
|
|
123
|
+
// Validate stack name
|
|
124
|
+
if (!/^[a-z][a-z0-9-]*$/.test(input.name)) {
|
|
125
|
+
throw new Error('Stack name must start with a letter and contain only lowercase alphanumeric characters and hyphens');
|
|
126
|
+
}
|
|
127
|
+
// Validate type
|
|
128
|
+
const validTypes = ['local', 'remote', 'cluster'];
|
|
129
|
+
if (!validTypes.includes(input.type)) {
|
|
130
|
+
throw new Error(`Invalid stack type '${input.type}'. Must be one of: ${validTypes.join(', ')}`);
|
|
131
|
+
}
|
|
132
|
+
// Validate nodeIds for remote/cluster
|
|
133
|
+
if (input.type === 'remote') {
|
|
134
|
+
if (!input.nodeIds || input.nodeIds.length !== 1) {
|
|
135
|
+
throw new Error("Remote stacks require exactly 1 nodeId");
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else if (input.type === 'cluster') {
|
|
139
|
+
if (!input.nodeIds || input.nodeIds.length < 2) {
|
|
140
|
+
throw new Error("Cluster stacks require at least 2 nodeIds");
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Check for duplicates in both config stacks and user stacks
|
|
144
|
+
const config = await this.loadProjectConfig(project);
|
|
145
|
+
const allStacks = this.resolveStacks(config, project);
|
|
146
|
+
if (allStacks[input.name]) {
|
|
147
|
+
throw new Error(`Stack '${input.name}' already exists`);
|
|
148
|
+
}
|
|
149
|
+
// Build stack config
|
|
150
|
+
const stackConfig = {
|
|
151
|
+
type: input.type,
|
|
152
|
+
apps: input.apps,
|
|
153
|
+
...(input.nodeIds && input.type !== 'local' && {
|
|
154
|
+
nodes: input.nodeIds.map((id) => ({ host: id, role: 'app' })),
|
|
155
|
+
}),
|
|
156
|
+
};
|
|
157
|
+
// For local stacks, auto-generate optimal infrastructure from app requirements
|
|
158
|
+
if (input.type === 'local') {
|
|
159
|
+
const proj = this.registry.get(project);
|
|
160
|
+
this.logger.info({ project, projFound: !!proj, projPath: proj?.path }, 'Generating infrastructure for local stack');
|
|
161
|
+
if (proj) {
|
|
162
|
+
try {
|
|
163
|
+
const infrastructure = await this.generateDefaultInfrastructure(config, proj.path, input.apps);
|
|
164
|
+
// Only set if apps actually need infrastructure
|
|
165
|
+
if (infrastructure.postgres || infrastructure.redis || infrastructure.minio) {
|
|
166
|
+
stackConfig.infrastructure = infrastructure;
|
|
167
|
+
this.logger.info({
|
|
168
|
+
project,
|
|
169
|
+
stack: input.name,
|
|
170
|
+
postgres: !!infrastructure.postgres,
|
|
171
|
+
redis: !!infrastructure.redis,
|
|
172
|
+
minio: !!infrastructure.minio,
|
|
173
|
+
}, 'Auto-generated infrastructure config from app requirements');
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
this.logger.warn({ project, stack: input.name, error: err.message }, 'Failed to auto-generate infrastructure config — stack created without infrastructure');
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Persist to user stacks file
|
|
182
|
+
this.saveUserStack(project, input.name, stackConfig);
|
|
183
|
+
// For local stacks with infrastructure, verify Docker availability
|
|
184
|
+
if (input.type === 'local' && stackConfig.infrastructure) {
|
|
185
|
+
try {
|
|
186
|
+
const { isDockerAvailable, ensureImage } = await import('../infrastructure/container-runtime.js');
|
|
187
|
+
const dockerReady = await isDockerAvailable();
|
|
188
|
+
if (dockerReady) {
|
|
189
|
+
// Pull images in background (don't block stack creation)
|
|
190
|
+
const images = new Set();
|
|
191
|
+
if (stackConfig.infrastructure.postgres)
|
|
192
|
+
images.add('postgres:17-alpine');
|
|
193
|
+
if (stackConfig.infrastructure.redis)
|
|
194
|
+
images.add('redis:7-alpine');
|
|
195
|
+
if (stackConfig.infrastructure.minio)
|
|
196
|
+
images.add('minio/minio:latest');
|
|
197
|
+
for (const img of images) {
|
|
198
|
+
ensureImage(img).catch((err) => this.logger.warn({ image: img, error: err.message }, 'Failed to pull image'));
|
|
199
|
+
}
|
|
200
|
+
this.logger.info({ project, stack: input.name, images: [...images] }, 'Docker available — pulling images');
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
this.logger.warn({ project, stack: input.name }, 'Docker not available — containers will be created when Docker is running');
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
// Non-critical — Docker check is best-effort
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
this.logger.info({ project, stack: input.name, type: input.type }, 'Stack created');
|
|
211
|
+
this.emit('stack:created', project, input.name, input.type);
|
|
212
|
+
return this.toStackInfo(project, input.name, stackConfig);
|
|
213
|
+
}
|
|
214
|
+
async deleteStack(project, stackName) {
|
|
215
|
+
// Cannot delete config-defined stacks
|
|
216
|
+
const config = await this.loadProjectConfig(project);
|
|
217
|
+
const configStacks = config.stacks ?? {};
|
|
218
|
+
if (configStacks[stackName]) {
|
|
219
|
+
throw new Error(`Stack '${stackName}' is defined in omnitron.config.ts and cannot be deleted via API`);
|
|
220
|
+
}
|
|
221
|
+
// Must exist in user stacks
|
|
222
|
+
const userStacks = this.loadUserStacks(project);
|
|
223
|
+
if (!userStacks[stackName]) {
|
|
224
|
+
throw new Error(`Stack '${stackName}' not found`);
|
|
225
|
+
}
|
|
226
|
+
// Cannot delete running stacks
|
|
227
|
+
const stateKey = `${project}/${stackName}`;
|
|
228
|
+
const state = this.stackStates.get(stateKey);
|
|
229
|
+
if (state && state.status !== 'stopped') {
|
|
230
|
+
throw new Error(`Stack '${stackName}' is currently ${state.status}. Stop it first.`);
|
|
231
|
+
}
|
|
232
|
+
this.deleteUserStack(project, stackName);
|
|
233
|
+
this.stackStates.delete(stateKey);
|
|
234
|
+
this.logger.info({ project, stack: stackName }, 'Stack deleted');
|
|
235
|
+
this.emit('stack:deleted', project, stackName);
|
|
236
|
+
}
|
|
237
|
+
getUserStacksPath(project) {
|
|
238
|
+
const proj = this.registry.get(project);
|
|
239
|
+
if (!proj)
|
|
240
|
+
throw new Error(`Project '${project}' not found`);
|
|
241
|
+
return path.join(proj.path, 'omnitron.stacks.json');
|
|
242
|
+
}
|
|
243
|
+
loadUserStacks(project) {
|
|
244
|
+
const filePath = this.getUserStacksPath(project);
|
|
245
|
+
try {
|
|
246
|
+
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
247
|
+
return JSON.parse(raw);
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
return {};
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
saveUserStack(project, name, config) {
|
|
254
|
+
const filePath = this.getUserStacksPath(project);
|
|
255
|
+
const stacks = this.loadUserStacks(project);
|
|
256
|
+
stacks[name] = config;
|
|
257
|
+
fs.writeFileSync(filePath, JSON.stringify(stacks, null, 2), 'utf-8');
|
|
258
|
+
}
|
|
259
|
+
deleteUserStack(project, name) {
|
|
260
|
+
const filePath = this.getUserStacksPath(project);
|
|
261
|
+
const stacks = this.loadUserStacks(project);
|
|
262
|
+
delete stacks[name];
|
|
263
|
+
fs.writeFileSync(filePath, JSON.stringify(stacks, null, 2), 'utf-8');
|
|
264
|
+
}
|
|
265
|
+
// ===========================================================================
|
|
266
|
+
// Stacks
|
|
267
|
+
// ===========================================================================
|
|
268
|
+
listStacks(projectName) {
|
|
269
|
+
const config = this.getLoadedConfig(projectName);
|
|
270
|
+
if (!config)
|
|
271
|
+
return [];
|
|
272
|
+
const stacks = this.resolveStacks(config, projectName);
|
|
273
|
+
return Object.entries(stacks).map(([name, stackConfig]) => this.toStackInfo(projectName, name, stackConfig));
|
|
274
|
+
}
|
|
275
|
+
getStack(projectName, stackName) {
|
|
276
|
+
const config = this.getLoadedConfig(projectName);
|
|
277
|
+
if (!config)
|
|
278
|
+
throw new Error(`Project '${projectName}' config not loaded`);
|
|
279
|
+
const stacks = this.resolveStacks(config, projectName);
|
|
280
|
+
const stackConfig = stacks[stackName];
|
|
281
|
+
if (!stackConfig)
|
|
282
|
+
throw new Error(`Stack '${stackName}' not found in project '${projectName}'`);
|
|
283
|
+
return this.toStackInfo(projectName, stackName, stackConfig);
|
|
284
|
+
}
|
|
285
|
+
async startStack(projectName, stackName) {
|
|
286
|
+
const config = await this.loadProjectConfig(projectName);
|
|
287
|
+
const stacks = this.resolveStacks(config, projectName);
|
|
288
|
+
const stackConfig = stacks[stackName];
|
|
289
|
+
if (!stackConfig)
|
|
290
|
+
throw new Error(`Stack '${stackName}' not found in project '${projectName}'`);
|
|
291
|
+
const stateKey = `${projectName}/${stackName}`;
|
|
292
|
+
const existing = this.stackStates.get(stateKey);
|
|
293
|
+
if (existing?.status === 'running') {
|
|
294
|
+
this.logger.warn({ project: projectName, stack: stackName }, 'Stack already running');
|
|
295
|
+
return this.toStackInfo(projectName, stackName, stackConfig);
|
|
296
|
+
}
|
|
297
|
+
// Reset stale "starting" state (daemon may have restarted mid-launch)
|
|
298
|
+
if (existing?.status === 'starting') {
|
|
299
|
+
this.logger.warn({ project: projectName, stack: stackName }, 'Resetting stale "starting" state');
|
|
300
|
+
this.stackStates.delete(stateKey);
|
|
301
|
+
}
|
|
302
|
+
this.logger.info({ project: projectName, stack: stackName, type: stackConfig.type }, 'Starting stack');
|
|
303
|
+
const state = {
|
|
304
|
+
project: projectName,
|
|
305
|
+
stack: stackName,
|
|
306
|
+
status: 'starting',
|
|
307
|
+
config: stackConfig,
|
|
308
|
+
startedAt: null,
|
|
309
|
+
infraService: null,
|
|
310
|
+
};
|
|
311
|
+
this.stackStates.set(stateKey, state);
|
|
312
|
+
this.emit('stack:starting', projectName, stackName, stackConfig.type);
|
|
313
|
+
try {
|
|
314
|
+
if (stackConfig.type === 'local') {
|
|
315
|
+
await this.startLocalStack(projectName, stackName, stackConfig, config);
|
|
316
|
+
}
|
|
317
|
+
else if (stackConfig.type === 'remote') {
|
|
318
|
+
await this.startRemoteStack(projectName, stackName, stackConfig, config);
|
|
319
|
+
}
|
|
320
|
+
else if (stackConfig.type === 'cluster') {
|
|
321
|
+
await this.startClusterStack(projectName, stackName, stackConfig, config);
|
|
322
|
+
}
|
|
323
|
+
state.status = 'running';
|
|
324
|
+
state.startedAt = Date.now();
|
|
325
|
+
// Update registry with enabled stack
|
|
326
|
+
this.updateEnabledStacks(projectName, stackName, true);
|
|
327
|
+
this.emit('stack:started', projectName, stackName, stackConfig.type);
|
|
328
|
+
this.logger.info({ project: projectName, stack: stackName }, 'Stack started');
|
|
329
|
+
return this.toStackInfo(projectName, stackName, stackConfig);
|
|
330
|
+
}
|
|
331
|
+
catch (err) {
|
|
332
|
+
state.status = 'error';
|
|
333
|
+
this.emit('stack:error', projectName, stackName, err.message);
|
|
334
|
+
throw err;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
async stopStack(projectName, stackName) {
|
|
338
|
+
const stateKey = `${projectName}/${stackName}`;
|
|
339
|
+
const state = this.stackStates.get(stateKey);
|
|
340
|
+
if (!state || state.status === 'stopped') {
|
|
341
|
+
const config = this.getLoadedConfig(projectName);
|
|
342
|
+
const stacks = config ? this.resolveStacks(config, projectName) : {};
|
|
343
|
+
const stackConfig = stacks[stackName];
|
|
344
|
+
if (!stackConfig)
|
|
345
|
+
throw new Error(`Stack '${stackName}' not found`);
|
|
346
|
+
return this.toStackInfo(projectName, stackName, stackConfig);
|
|
347
|
+
}
|
|
348
|
+
this.logger.info({ project: projectName, stack: stackName }, 'Stopping stack');
|
|
349
|
+
state.status = 'stopping';
|
|
350
|
+
this.emit('stack:stopping', projectName, stackName);
|
|
351
|
+
try {
|
|
352
|
+
// Stop all apps with this stack's namespace prefix (reverse order for graceful shutdown)
|
|
353
|
+
const prefix = `${projectName}/${stackName}/`;
|
|
354
|
+
const handleNames = this.orchestrator.listHandleNames(prefix);
|
|
355
|
+
for (const name of handleNames.reverse()) {
|
|
356
|
+
try {
|
|
357
|
+
await this.orchestrator.stopApp(name);
|
|
358
|
+
}
|
|
359
|
+
catch (err) {
|
|
360
|
+
this.logger.warn({ app: name, error: err.message }, 'Failed to stop app during stack shutdown');
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
// Disconnect slave daemons for remote/cluster stacks
|
|
364
|
+
if (state.config.type !== 'local' && this.slaveConnector) {
|
|
365
|
+
for (const node of state.config.nodes ?? []) {
|
|
366
|
+
await this.slaveConnector.removeSlave(node.host, node.port ?? 9700);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
// Teardown per-stack infrastructure (namespaced containers)
|
|
370
|
+
await this.infraManager.teardownStack(projectName, stackName);
|
|
371
|
+
state.status = 'stopped';
|
|
372
|
+
state.startedAt = null;
|
|
373
|
+
this.updateEnabledStacks(projectName, stackName, false);
|
|
374
|
+
this.emit('stack:stopped', projectName, stackName, 'manual');
|
|
375
|
+
this.logger.info({ project: projectName, stack: stackName }, 'Stack stopped');
|
|
376
|
+
return this.toStackInfo(projectName, stackName, state.config);
|
|
377
|
+
}
|
|
378
|
+
catch (err) {
|
|
379
|
+
state.status = 'error';
|
|
380
|
+
throw err;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
getStackStatus(projectName, stackName) {
|
|
384
|
+
const stateKey = `${projectName}/${stackName}`;
|
|
385
|
+
const state = this.stackStates.get(stateKey);
|
|
386
|
+
const config = this.getLoadedConfig(projectName);
|
|
387
|
+
const stacks = config ? this.resolveStacks(config, projectName) : {};
|
|
388
|
+
const stackConfig = stacks[stackName] ?? state?.config;
|
|
389
|
+
if (!stackConfig)
|
|
390
|
+
throw new Error(`Stack '${stackName}' not found`);
|
|
391
|
+
const prefix = `${projectName}/${stackName}/`;
|
|
392
|
+
const apps = this.orchestrator.list().filter((a) => a.name.startsWith(prefix));
|
|
393
|
+
const onlineApps = apps.filter((a) => a.status === 'online');
|
|
394
|
+
// Derive status from app health if running
|
|
395
|
+
let status = state?.status ?? 'stopped';
|
|
396
|
+
if (status === 'running' && apps.length > 0 && onlineApps.length < apps.length) {
|
|
397
|
+
status = 'degraded';
|
|
398
|
+
}
|
|
399
|
+
return {
|
|
400
|
+
name: stackName,
|
|
401
|
+
type: stackConfig.type,
|
|
402
|
+
status,
|
|
403
|
+
totalApps: apps.length,
|
|
404
|
+
onlineApps: onlineApps.length,
|
|
405
|
+
totalNodes: stackConfig.nodes?.length ?? 1,
|
|
406
|
+
connectedNodes: stackConfig.type === 'local'
|
|
407
|
+
? 1
|
|
408
|
+
: (this.slaveConnector?.getConnections().filter((c) => c.stack === stackName && c.status === 'connected').length ?? 0),
|
|
409
|
+
totalCpu: apps.reduce((sum, a) => sum + a.cpu, 0),
|
|
410
|
+
totalMemory: apps.reduce((sum, a) => sum + a.memory, 0),
|
|
411
|
+
syncSummary: (stackConfig.type === 'remote' || stackConfig.type === 'cluster')
|
|
412
|
+
? {
|
|
413
|
+
totalSlaves: stackConfig.nodes?.filter((n) => n.role !== 'master').length ?? 0,
|
|
414
|
+
syncedSlaves: 0,
|
|
415
|
+
totalPending: 0,
|
|
416
|
+
}
|
|
417
|
+
: null,
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Get the infrastructure manager (for daemon-level access).
|
|
422
|
+
*/
|
|
423
|
+
getInfraManager() {
|
|
424
|
+
return this.infraManager;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Dispose of all resources held by this service.
|
|
428
|
+
* Called during daemon shutdown.
|
|
429
|
+
*/
|
|
430
|
+
async dispose() {
|
|
431
|
+
this.slaveConnector?.dispose();
|
|
432
|
+
await this.infraManager.teardownAll();
|
|
433
|
+
}
|
|
434
|
+
// ===========================================================================
|
|
435
|
+
// Config Management
|
|
436
|
+
// ===========================================================================
|
|
437
|
+
async loadProjectConfig(projectName) {
|
|
438
|
+
const project = this.registry.get(projectName);
|
|
439
|
+
if (!project)
|
|
440
|
+
throw new Error(`Project '${projectName}' not found`);
|
|
441
|
+
const { loadEcosystemConfig } = await import('../config/loader.js');
|
|
442
|
+
const config = await loadEcosystemConfig(project.path);
|
|
443
|
+
this.configRegistry.set(projectName, { config, loadedAt: Date.now() });
|
|
444
|
+
return config;
|
|
445
|
+
}
|
|
446
|
+
getLoadedConfig(projectName) {
|
|
447
|
+
return this.configRegistry.get(projectName)?.config ?? null;
|
|
448
|
+
}
|
|
449
|
+
async reloadConfig(projectName) {
|
|
450
|
+
if (projectName) {
|
|
451
|
+
await this.loadProjectConfig(projectName);
|
|
452
|
+
this.emit('project:config_reloaded', projectName);
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
for (const project of this.registry.list()) {
|
|
456
|
+
await this.loadProjectConfig(project.name);
|
|
457
|
+
this.emit('project:config_reloaded', project.name);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
// ===========================================================================
|
|
462
|
+
// Helpers
|
|
463
|
+
// ===========================================================================
|
|
464
|
+
getRunningStacks(projectName) {
|
|
465
|
+
const result = [];
|
|
466
|
+
for (const [, state] of this.stackStates) {
|
|
467
|
+
if (state.project === projectName && (state.status === 'running' || state.status === 'starting')) {
|
|
468
|
+
result.push(state.stack);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
return result;
|
|
472
|
+
}
|
|
473
|
+
/** Build the stack handle key for an app */
|
|
474
|
+
static handleKey(project, stack, app) {
|
|
475
|
+
return `${project}/${stack}/${app}`;
|
|
476
|
+
}
|
|
477
|
+
// ===========================================================================
|
|
478
|
+
// Infrastructure Generation & Validation
|
|
479
|
+
// ===========================================================================
|
|
480
|
+
/**
|
|
481
|
+
* Generate optimal default infrastructure config by scanning app requirements.
|
|
482
|
+
*
|
|
483
|
+
* Reads each app's config/default.json `omnitron` section (same pattern as
|
|
484
|
+
* requirements-scanner) and aggregates needs into a minimal InfrastructureConfig:
|
|
485
|
+
* - Any app with `database` → shared PostgreSQL with per-app databases
|
|
486
|
+
* - Any app with `redis` → shared Redis with auto-allocated DB indices
|
|
487
|
+
* - Any app with `s3` → shared MinIO with per-app buckets
|
|
488
|
+
*/
|
|
489
|
+
async generateDefaultInfrastructure(projectConfig, projectPath, appNames) {
|
|
490
|
+
// Resolve which apps to scan
|
|
491
|
+
const apps = appNames === 'all'
|
|
492
|
+
? projectConfig.apps.filter((a) => a.enabled !== false)
|
|
493
|
+
: projectConfig.apps.filter((a) => a.enabled !== false && appNames.includes(a.name));
|
|
494
|
+
// Read omnitron config from each app's config/default.json
|
|
495
|
+
const appConfigs = new Map();
|
|
496
|
+
for (const app of apps) {
|
|
497
|
+
if (!app.bootstrap)
|
|
498
|
+
continue;
|
|
499
|
+
const bootstrapPath = `${projectPath}/${app.bootstrap}`;
|
|
500
|
+
const srcDir = path.dirname(bootstrapPath);
|
|
501
|
+
const appRoot = path.resolve(srcDir, '..');
|
|
502
|
+
const configPath = path.join(appRoot, 'config', 'default.json');
|
|
503
|
+
try {
|
|
504
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
505
|
+
const json = JSON.parse(content);
|
|
506
|
+
if (json.omnitron) {
|
|
507
|
+
appConfigs.set(app.name, json.omnitron);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
catch (err) {
|
|
511
|
+
this.logger.debug({ app: app.name, configPath, error: err.message }, 'Could not read app config for infrastructure scan');
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
if (appConfigs.size === 0) {
|
|
515
|
+
return {};
|
|
516
|
+
}
|
|
517
|
+
// Aggregate needs
|
|
518
|
+
const needsPostgres = [...appConfigs.values()].some((c) => !!c.database);
|
|
519
|
+
const needsRedis = [...appConfigs.values()].some((c) => !!c.redis);
|
|
520
|
+
const needsS3 = [...appConfigs.values()].some((c) => !!c.s3);
|
|
521
|
+
const infrastructure = {};
|
|
522
|
+
// PostgreSQL: shared instance with per-app databases
|
|
523
|
+
if (needsPostgres) {
|
|
524
|
+
const databases = {};
|
|
525
|
+
for (const [appName, config] of appConfigs) {
|
|
526
|
+
if (config.database) {
|
|
527
|
+
const dbConfig = typeof config.database === 'object' ? config.database : {};
|
|
528
|
+
databases[appName] = {
|
|
529
|
+
migrate: true,
|
|
530
|
+
...(dbConfig.pool ? {} : {}),
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
infrastructure.postgres = {
|
|
535
|
+
port: 5432,
|
|
536
|
+
databases,
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
// Redis: shared instance with auto-allocated DB indices per app
|
|
540
|
+
if (needsRedis) {
|
|
541
|
+
const dbAllocations = {};
|
|
542
|
+
let nextDb = 0;
|
|
543
|
+
for (const [appName, config] of appConfigs) {
|
|
544
|
+
if (config.redis) {
|
|
545
|
+
dbAllocations[appName] = nextDb++;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
// Titan service modules get their own DB indices
|
|
549
|
+
for (const [appName, config] of appConfigs) {
|
|
550
|
+
if (config.services?.discovery) {
|
|
551
|
+
dbAllocations[`${appName}:discovery`] = nextDb++;
|
|
552
|
+
}
|
|
553
|
+
if (config.services?.notifications) {
|
|
554
|
+
dbAllocations[`${appName}:notifications`] = nextDb++;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
infrastructure.redis = {
|
|
558
|
+
port: 6379,
|
|
559
|
+
databases: dbAllocations,
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
// MinIO: shared instance with per-app buckets
|
|
563
|
+
if (needsS3) {
|
|
564
|
+
const buckets = [];
|
|
565
|
+
for (const [appName, config] of appConfigs) {
|
|
566
|
+
if (config.s3) {
|
|
567
|
+
const s3Config = typeof config.s3 === 'object' ? config.s3 : {};
|
|
568
|
+
buckets.push(s3Config.bucket ?? appName);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
infrastructure.minio = {
|
|
572
|
+
ports: { api: 9000, console: 9001 },
|
|
573
|
+
buckets,
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
return infrastructure;
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Validate that a stack's infrastructure config satisfies all app requirements.
|
|
580
|
+
* Returns issues if infrastructure is missing for apps that need it.
|
|
581
|
+
*/
|
|
582
|
+
async validateStackInfrastructure(projectName, stackName) {
|
|
583
|
+
const config = await this.loadProjectConfig(projectName);
|
|
584
|
+
const stacks = this.resolveStacks(config, projectName);
|
|
585
|
+
const stackConfig = stacks[stackName];
|
|
586
|
+
if (!stackConfig) {
|
|
587
|
+
return { valid: false, issues: [`Stack '${stackName}' not found`] };
|
|
588
|
+
}
|
|
589
|
+
const project = this.registry.get(projectName);
|
|
590
|
+
if (!project) {
|
|
591
|
+
return { valid: false, issues: [`Project '${projectName}' not found`] };
|
|
592
|
+
}
|
|
593
|
+
// Determine effective infrastructure: stack-level overrides ecosystem-level
|
|
594
|
+
const effectiveInfra = stackConfig.infrastructure ?? config.infrastructure;
|
|
595
|
+
const issues = [];
|
|
596
|
+
// Scan app requirements
|
|
597
|
+
const { scanRequirements } = await import('../project/requirements-scanner.js');
|
|
598
|
+
const appEntries = this.resolveStackApps(stackConfig, config);
|
|
599
|
+
const reqs = await scanRequirements(appEntries, project.path);
|
|
600
|
+
// Check PostgreSQL
|
|
601
|
+
if (reqs.databases.length > 0 && !effectiveInfra?.postgres) {
|
|
602
|
+
issues.push(`PostgreSQL required by ${reqs.databases.map((d) => d.app).join(', ')} but not configured in infrastructure`);
|
|
603
|
+
}
|
|
604
|
+
else if (reqs.databases.length > 0 && effectiveInfra?.postgres) {
|
|
605
|
+
// Check individual databases exist in config
|
|
606
|
+
const configuredDbs = new Set(Object.keys(effectiveInfra.postgres.databases ?? {}));
|
|
607
|
+
for (const db of reqs.databases) {
|
|
608
|
+
if (!configuredDbs.has(db.database)) {
|
|
609
|
+
issues.push(`Database '${db.database}' needed by '${db.app}' not found in postgres.databases`);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
// Check Redis
|
|
614
|
+
if (reqs.redis.appCount > 0 && !effectiveInfra?.redis) {
|
|
615
|
+
issues.push(`Redis required by ${reqs.redis.allocations.map((a) => a.app).join(', ')} but not configured in infrastructure`);
|
|
616
|
+
}
|
|
617
|
+
// Check S3/MinIO
|
|
618
|
+
if (reqs.buckets.length > 0 && !effectiveInfra?.minio) {
|
|
619
|
+
issues.push(`S3/MinIO required by ${reqs.buckets.map((b) => b.app).join(', ')} but not configured in infrastructure`);
|
|
620
|
+
}
|
|
621
|
+
else if (reqs.buckets.length > 0 && effectiveInfra?.minio) {
|
|
622
|
+
const configuredBuckets = new Set(effectiveInfra.minio.buckets ?? []);
|
|
623
|
+
for (const b of reqs.buckets) {
|
|
624
|
+
if (configuredBuckets.size > 0 && !configuredBuckets.has(b.bucket)) {
|
|
625
|
+
issues.push(`Bucket '${b.bucket}' needed by '${b.app}' not found in minio.buckets`);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
return { valid: issues.length === 0, issues };
|
|
630
|
+
}
|
|
631
|
+
// ===========================================================================
|
|
632
|
+
// Private — Stack Launchers
|
|
633
|
+
// ===========================================================================
|
|
634
|
+
async startLocalStack(projectName, stackName, stackConfig, ecosystemConfig) {
|
|
635
|
+
const stateKey = `${projectName}/${stackName}`;
|
|
636
|
+
const state = this.stackStates.get(stateKey);
|
|
637
|
+
// 0. Validate infrastructure covers app requirements (warn only, don't block)
|
|
638
|
+
try {
|
|
639
|
+
const validation = await this.validateStackInfrastructure(projectName, stackName);
|
|
640
|
+
if (!validation.valid) {
|
|
641
|
+
for (const issue of validation.issues) {
|
|
642
|
+
this.logger.warn({ project: projectName, stack: stackName, issue }, 'Infrastructure validation issue');
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
catch {
|
|
647
|
+
// Validation is best-effort — don't block stack start
|
|
648
|
+
}
|
|
649
|
+
// 1. Load bootstrap definitions (needed for both infra provisioning and config resolution)
|
|
650
|
+
const appDefinitions = new Map();
|
|
651
|
+
const appEntries = this.resolveStackApps(stackConfig, ecosystemConfig);
|
|
652
|
+
const project = this.registry.get(projectName);
|
|
653
|
+
for (const entry of appEntries) {
|
|
654
|
+
if (entry.bootstrap && project) {
|
|
655
|
+
try {
|
|
656
|
+
const bootstrapAbsPath = path.resolve(project.path, entry.bootstrap);
|
|
657
|
+
const { loadBootstrapConfig } = await import('../orchestrator/bootstrap-loader.js');
|
|
658
|
+
const definition = await loadBootstrapConfig(bootstrapAbsPath, { devMode: false });
|
|
659
|
+
// Populate omnitronConfig from app's config/default.json if not already set
|
|
660
|
+
if (!definition.omnitronConfig) {
|
|
661
|
+
const srcDir = path.dirname(bootstrapAbsPath);
|
|
662
|
+
const appRoot = path.resolve(srcDir, '..');
|
|
663
|
+
const configPath = path.join(appRoot, 'config', 'default.json');
|
|
664
|
+
try {
|
|
665
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
666
|
+
const json = JSON.parse(content);
|
|
667
|
+
if (json.omnitron) {
|
|
668
|
+
definition.omnitronConfig = json.omnitron;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
catch { /* config file missing — skip */ }
|
|
672
|
+
}
|
|
673
|
+
appDefinitions.set(entry.name, definition);
|
|
674
|
+
}
|
|
675
|
+
catch {
|
|
676
|
+
// Non-critical — app can start without definition
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
// 2. Provision per-stack infrastructure (built-in + app-declared services)
|
|
681
|
+
// Auto-detect core services (postgres, redis, minio) from app requirements,
|
|
682
|
+
// then merge with explicit infrastructure config (gateway, custom services).
|
|
683
|
+
// Merge stack-level + ecosystem-level infrastructure (stack overrides ecosystem, but both contribute)
|
|
684
|
+
let effectiveInfra;
|
|
685
|
+
if (stackConfig.infrastructure || ecosystemConfig.infrastructure) {
|
|
686
|
+
effectiveInfra = {
|
|
687
|
+
...ecosystemConfig.infrastructure,
|
|
688
|
+
...stackConfig.infrastructure,
|
|
689
|
+
// Deep-merge services maps from both levels
|
|
690
|
+
services: {
|
|
691
|
+
...ecosystemConfig.infrastructure?.services,
|
|
692
|
+
...stackConfig.infrastructure?.services,
|
|
693
|
+
},
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
if (project) {
|
|
697
|
+
try {
|
|
698
|
+
const { scanRequirements, buildInfraFromRequirements } = await import('../project/requirements-scanner.js');
|
|
699
|
+
const reqs = await scanRequirements(appEntries, project.path);
|
|
700
|
+
const autoInfra = buildInfraFromRequirements(reqs);
|
|
701
|
+
if (Object.keys(autoInfra).length > 0) {
|
|
702
|
+
const explicitServices = effectiveInfra?.services ?? {};
|
|
703
|
+
this.logger.info({ explicitServiceKeys: Object.keys(explicitServices), hasEffective: !!effectiveInfra }, 'Pre-merge: explicit services from config');
|
|
704
|
+
// Merge: auto-detected core services + explicit config (gateway, custom services)
|
|
705
|
+
effectiveInfra = {
|
|
706
|
+
...autoInfra,
|
|
707
|
+
...effectiveInfra,
|
|
708
|
+
services: { ...explicitServices },
|
|
709
|
+
};
|
|
710
|
+
this.logger.info({ project: projectName, stack: stackName, auto: Object.keys(autoInfra), explicit: Object.keys(effectiveInfra.services ?? {}) }, 'Merged auto-detected + explicit infrastructure');
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
catch (err) {
|
|
714
|
+
this.logger.warn({ error: err.message }, 'Failed to auto-detect infrastructure requirements');
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
if (effectiveInfra) {
|
|
718
|
+
try {
|
|
719
|
+
const infraService = await this.infraManager.provisionStack(projectName, stackName, stackConfig, effectiveInfra, appDefinitions, project?.path);
|
|
720
|
+
state.infraService = infraService;
|
|
721
|
+
}
|
|
722
|
+
catch (err) {
|
|
723
|
+
this.logger.error({ project: projectName, stack: stackName, error: err.message }, 'Failed to provision stack infrastructure — apps may fail to start');
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
// 2b. Run database migrations for apps that have migrate: true
|
|
727
|
+
if (effectiveInfra && project) {
|
|
728
|
+
await this.runStackMigrations(projectName, stackName, effectiveInfra, appEntries, project.path);
|
|
729
|
+
}
|
|
730
|
+
// 3. Resolve per-app infrastructure config via stack resolver
|
|
731
|
+
const portAllocation = this.infraManager.getPortAllocation(projectName, stackName);
|
|
732
|
+
const normalizedSvcs = this.infraManager.getNormalizedServices(projectName, stackName);
|
|
733
|
+
const resolvedStack = resolveStack(ecosystemConfig, projectName, stackName, stackConfig, appDefinitions, portAllocation ?? undefined, undefined, normalizedSvcs ?? undefined);
|
|
734
|
+
// 4. Start each app with namespaced handle key and resolved infra config
|
|
735
|
+
for (const entry of appEntries) {
|
|
736
|
+
const appConfig = resolvedStack.appConfigs.get(entry.name);
|
|
737
|
+
// Build environment variables from resolved infrastructure config
|
|
738
|
+
const infraEnv = appConfig ? resolvedConfigToEnv(appConfig, entry.name, stackName) : {};
|
|
739
|
+
this.logger.info({ app: entry.name, envKeys: Object.keys(infraEnv), hasS3: !!infraEnv['S3_ENDPOINT'], hasDb: !!infraEnv['DATABASE_URL'] }, 'Infrastructure env vars for app');
|
|
740
|
+
const namespacedEntry = {
|
|
741
|
+
...entry,
|
|
742
|
+
name: ProjectService.handleKey(projectName, stackName, entry.name),
|
|
743
|
+
// Resolve bootstrap to absolute path using project root — the orchestrator's
|
|
744
|
+
// cwd may differ from the project directory (e.g. daemon running from webapp/).
|
|
745
|
+
...(entry.bootstrap && project
|
|
746
|
+
? { bootstrap: path.resolve(project.path, entry.bootstrap) }
|
|
747
|
+
: {}),
|
|
748
|
+
// Set CWD to project root so child processes can resolve relative config paths
|
|
749
|
+
// (e.g., apps/storage/config/default.json) correctly.
|
|
750
|
+
...(project ? { cwd: project.path } : {}),
|
|
751
|
+
env: {
|
|
752
|
+
...entry.env,
|
|
753
|
+
...infraEnv,
|
|
754
|
+
...stackConfig.settings?.env,
|
|
755
|
+
OMNITRON_PROJECT: projectName,
|
|
756
|
+
OMNITRON_STACK: stackName,
|
|
757
|
+
OMNITRON_STACK_TYPE: 'local',
|
|
758
|
+
},
|
|
759
|
+
};
|
|
760
|
+
try {
|
|
761
|
+
await this.orchestrator.startApp(namespacedEntry, ecosystemConfig);
|
|
762
|
+
}
|
|
763
|
+
catch (err) {
|
|
764
|
+
this.logger.error({ app: entry.name, project: projectName, stack: stackName, error: err.message }, 'Failed to start app in stack');
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
async startRemoteStack(projectName, stackName, stackConfig, ecosystemConfig) {
|
|
769
|
+
const nodes = stackConfig.nodes ?? [];
|
|
770
|
+
if (nodes.length === 0) {
|
|
771
|
+
throw new Error(`Remote stack '${stackName}' has no nodes configured`);
|
|
772
|
+
}
|
|
773
|
+
this.logger.info({ project: projectName, stack: stackName, nodes: nodes.length }, 'Starting remote stack — deploying to slave daemons');
|
|
774
|
+
const connector = this.getSlaveConnector();
|
|
775
|
+
// Build artifacts for apps in this stack
|
|
776
|
+
const appEntries = this.resolveStackApps(stackConfig, ecosystemConfig);
|
|
777
|
+
const project = this.registry.get(projectName);
|
|
778
|
+
let artifacts = [];
|
|
779
|
+
if (project) {
|
|
780
|
+
try {
|
|
781
|
+
const { ArtifactBuilder } = await import('../project/artifact-builder.js');
|
|
782
|
+
const builder = new ArtifactBuilder(project.path);
|
|
783
|
+
artifacts = await builder.buildAll(appEntries);
|
|
784
|
+
this.logger.info({ artifacts: artifacts.map((a) => `${a.app}@${a.version}`), stack: stackName }, 'Artifacts built for deployment');
|
|
785
|
+
}
|
|
786
|
+
catch (err) {
|
|
787
|
+
this.logger.error({ error: err.message, stack: stackName }, 'Failed to build artifacts — deploying without rebuild');
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
// Resolve master address (from this daemon's perspective — what slaves connect to)
|
|
791
|
+
const { DEFAULT_DAEMON_CONFIG: _dc } = await import('../config/defaults.js');
|
|
792
|
+
const masterHost = _dc.host === '0.0.0.0' ? 'auto' : _dc.host;
|
|
793
|
+
const masterPort = _dc.port;
|
|
794
|
+
// Deploy to each node: provision slave → deploy artifacts → connect
|
|
795
|
+
for (const node of nodes) {
|
|
796
|
+
const nodeKey = `${node.host}:${node.port ?? 9700}`;
|
|
797
|
+
// 1. Provision slave: install runtime + omnitron + generate slave config + start daemon
|
|
798
|
+
const unsubProvision = this.deployer.onProgress((progress) => {
|
|
799
|
+
this.emit('stack:deploy_progress', projectName, stackName, progress);
|
|
800
|
+
});
|
|
801
|
+
const provisioned = await this.deployer.provisionSlaveNode(node, masterHost === 'auto' ? node.host : masterHost, // If master binds 0.0.0.0, slave uses its own view of master
|
|
802
|
+
masterPort, projectName);
|
|
803
|
+
unsubProvision();
|
|
804
|
+
if (!provisioned) {
|
|
805
|
+
this.logger.error({ node: nodeKey }, 'Failed to provision slave — skipping');
|
|
806
|
+
continue;
|
|
807
|
+
}
|
|
808
|
+
// 2. Deploy app artifacts via SSH
|
|
809
|
+
if (artifacts.length > 0) {
|
|
810
|
+
const unsubDeploy = this.deployer.onProgress((progress) => {
|
|
811
|
+
this.emit('stack:deploy_progress', projectName, stackName, progress);
|
|
812
|
+
});
|
|
813
|
+
const results = await this.deployer.deployToStack([node], artifacts, projectName);
|
|
814
|
+
unsubDeploy();
|
|
815
|
+
const failed = results.filter((r) => r.status === 'failed');
|
|
816
|
+
if (failed.length > 0) {
|
|
817
|
+
this.logger.warn({ node: nodeKey, failed: failed.map((f) => f.app) }, 'Some app deployments failed');
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
// 3. Connect master to slave daemon via Netron TCP
|
|
821
|
+
await connector.addSlave({
|
|
822
|
+
host: node.host,
|
|
823
|
+
port: node.port ?? 9700,
|
|
824
|
+
label: node.label,
|
|
825
|
+
stack: stackName,
|
|
826
|
+
project: projectName,
|
|
827
|
+
});
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
async startClusterStack(projectName, stackName, stackConfig, ecosystemConfig) {
|
|
831
|
+
const nodes = stackConfig.nodes ?? [];
|
|
832
|
+
if (nodes.length === 0) {
|
|
833
|
+
throw new Error(`Cluster stack '${stackName}' has no nodes configured`);
|
|
834
|
+
}
|
|
835
|
+
this.logger.info({ project: projectName, stack: stackName, nodes: nodes.length }, 'Starting cluster stack — coordinating slave daemons');
|
|
836
|
+
const connector = this.getSlaveConnector();
|
|
837
|
+
// Build artifacts
|
|
838
|
+
const appEntries = this.resolveStackApps(stackConfig, ecosystemConfig);
|
|
839
|
+
const project = this.registry.get(projectName);
|
|
840
|
+
let artifacts = [];
|
|
841
|
+
if (project) {
|
|
842
|
+
try {
|
|
843
|
+
const { ArtifactBuilder } = await import('../project/artifact-builder.js');
|
|
844
|
+
const builder = new ArtifactBuilder(project.path);
|
|
845
|
+
artifacts = await builder.buildAll(appEntries);
|
|
846
|
+
}
|
|
847
|
+
catch (err) {
|
|
848
|
+
this.logger.error({ error: err.message }, 'Artifact build failed');
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
// Resolve master address
|
|
852
|
+
const { DEFAULT_DAEMON_CONFIG: _dc } = await import('../config/defaults.js');
|
|
853
|
+
const masterHost = _dc.host === '0.0.0.0' ? 'auto' : _dc.host;
|
|
854
|
+
const masterPort = _dc.port;
|
|
855
|
+
// Provision all slave nodes in parallel (install runtime + omnitron + config)
|
|
856
|
+
const appNodes = nodes.filter((n) => n.role !== 'database' && n.role !== 'cache');
|
|
857
|
+
for (const node of appNodes) {
|
|
858
|
+
const unsubProvision = this.deployer.onProgress((progress) => {
|
|
859
|
+
this.emit('stack:deploy_progress', projectName, stackName, progress);
|
|
860
|
+
});
|
|
861
|
+
await this.deployer.provisionSlaveNode(node, masterHost === 'auto' ? node.host : masterHost, masterPort, projectName);
|
|
862
|
+
unsubProvision();
|
|
863
|
+
}
|
|
864
|
+
// Deploy app artifacts to all provisioned nodes
|
|
865
|
+
if (artifacts.length > 0 && appNodes.length > 0) {
|
|
866
|
+
const unsubDeploy = this.deployer.onProgress((progress) => {
|
|
867
|
+
this.emit('stack:deploy_progress', projectName, stackName, progress);
|
|
868
|
+
});
|
|
869
|
+
const results = await this.deployer.deployToStack(appNodes, artifacts, projectName, { concurrency: 5 });
|
|
870
|
+
unsubDeploy();
|
|
871
|
+
const successful = results.filter((r) => r.status === 'success').length;
|
|
872
|
+
const failed = results.filter((r) => r.status === 'failed').length;
|
|
873
|
+
this.logger.info({ successful, failed, total: results.length }, 'Cluster deployment complete');
|
|
874
|
+
}
|
|
875
|
+
// Connect to all slave daemons
|
|
876
|
+
for (const node of nodes) {
|
|
877
|
+
await connector.addSlave({
|
|
878
|
+
host: node.host,
|
|
879
|
+
port: node.port ?? 9700,
|
|
880
|
+
label: node.label,
|
|
881
|
+
stack: stackName,
|
|
882
|
+
project: projectName,
|
|
883
|
+
});
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
// ===========================================================================
|
|
887
|
+
// Private — Utilities
|
|
888
|
+
// ===========================================================================
|
|
889
|
+
/**
|
|
890
|
+
* Run database migrations for apps that declare migrate: true in their
|
|
891
|
+
* stack infrastructure config. Migrations are executed after databases are
|
|
892
|
+
* created but before apps are started, so apps always see a current schema.
|
|
893
|
+
*
|
|
894
|
+
* Convention: each app's migration script is at `apps/{appName}/src/database/migrate.ts`.
|
|
895
|
+
* The script reads DATABASE_URL or app-specific env vars and defaults to
|
|
896
|
+
* localhost:{port}/{dbName} with postgres:postgres — matching the stack's provisioned postgres.
|
|
897
|
+
*/
|
|
898
|
+
async runStackMigrations(projectName, stackName, infraConfig, appEntries, projectPath) {
|
|
899
|
+
const pgConfig = infraConfig.postgres;
|
|
900
|
+
if (!pgConfig?.databases)
|
|
901
|
+
return;
|
|
902
|
+
const appNames = new Set(appEntries.map((a) => a.name));
|
|
903
|
+
const port = pgConfig.port ?? 5432;
|
|
904
|
+
const user = pgConfig.user ?? 'postgres';
|
|
905
|
+
const password = typeof pgConfig.password === 'string' ? pgConfig.password : 'postgres';
|
|
906
|
+
for (const [dbName, dbConfig] of Object.entries(pgConfig.databases)) {
|
|
907
|
+
// Only run if migrate flag is set AND a matching app exists
|
|
908
|
+
if (!dbConfig || typeof dbConfig !== 'object' || !dbConfig.migrate)
|
|
909
|
+
continue;
|
|
910
|
+
if (!appNames.has(dbName))
|
|
911
|
+
continue;
|
|
912
|
+
const migrateScript = path.join(projectPath, 'apps', dbName, 'src', 'database', 'migrate.ts');
|
|
913
|
+
try {
|
|
914
|
+
await fs.promises.access(migrateScript);
|
|
915
|
+
}
|
|
916
|
+
catch {
|
|
917
|
+
this.logger.debug({ app: dbName, script: migrateScript }, 'Migration script not found — skipping');
|
|
918
|
+
continue;
|
|
919
|
+
}
|
|
920
|
+
this.logger.info({ project: projectName, stack: stackName, database: dbName }, 'Running database migrations');
|
|
921
|
+
try {
|
|
922
|
+
const { execFileSync } = await import('node:child_process');
|
|
923
|
+
execFileSync(process.execPath, ['--import', 'tsx/esm', migrateScript], {
|
|
924
|
+
cwd: path.join(projectPath, 'apps', dbName),
|
|
925
|
+
env: {
|
|
926
|
+
...process.env,
|
|
927
|
+
DATABASE_URL: `postgresql://${user}:${password}@localhost:${port}/${dbName}`,
|
|
928
|
+
// App-specific env vars (various naming conventions)
|
|
929
|
+
[`${dbName.toUpperCase()}__DATABASE__HOST`]: 'localhost',
|
|
930
|
+
[`${dbName.toUpperCase()}__DATABASE__PORT`]: String(port),
|
|
931
|
+
[`${dbName.toUpperCase()}__DATABASE__DATABASE`]: dbName,
|
|
932
|
+
[`${dbName.toUpperCase()}__DATABASE__USER`]: user,
|
|
933
|
+
[`${dbName.toUpperCase()}__DATABASE__PASSWORD`]: password,
|
|
934
|
+
},
|
|
935
|
+
timeout: 60_000,
|
|
936
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
937
|
+
});
|
|
938
|
+
this.logger.info({ database: dbName }, 'Migrations applied');
|
|
939
|
+
}
|
|
940
|
+
catch (err) {
|
|
941
|
+
const stderr = err.stderr?.toString?.()?.trim?.() ?? '';
|
|
942
|
+
this.logger.error({ database: dbName, error: err.message, stderr }, 'Migration failed — app may fail to start');
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
/**
|
|
947
|
+
* Resolve stacks from config + user stacks.
|
|
948
|
+
* User-created stacks (from omnitron.stacks.json) are merged with config stacks.
|
|
949
|
+
* Config stacks take precedence over user stacks with the same name.
|
|
950
|
+
* No implicit fallbacks — stacks must be created explicitly.
|
|
951
|
+
*/
|
|
952
|
+
resolveStacks(config, projectName) {
|
|
953
|
+
const configStacks = config.stacks ?? {};
|
|
954
|
+
if (projectName) {
|
|
955
|
+
const userStacks = this.loadUserStacks(projectName);
|
|
956
|
+
return { ...userStacks, ...configStacks };
|
|
957
|
+
}
|
|
958
|
+
return configStacks;
|
|
959
|
+
}
|
|
960
|
+
resolveStackApps(stackConfig, ecosystemConfig) {
|
|
961
|
+
const allApps = ecosystemConfig.apps.filter((a) => a.enabled !== false);
|
|
962
|
+
if (!stackConfig.apps || stackConfig.apps === 'all') {
|
|
963
|
+
return allApps;
|
|
964
|
+
}
|
|
965
|
+
return allApps.filter((a) => Array.isArray(stackConfig.apps) ? stackConfig.apps.includes(a.name) : true);
|
|
966
|
+
}
|
|
967
|
+
updateEnabledStacks(projectName, stackName, enabled) {
|
|
968
|
+
const project = this.registry.get(projectName);
|
|
969
|
+
if (!project)
|
|
970
|
+
return;
|
|
971
|
+
const enabledStacks = new Set(project.enabledStacks ?? []);
|
|
972
|
+
if (enabled) {
|
|
973
|
+
enabledStacks.add(stackName);
|
|
974
|
+
}
|
|
975
|
+
else {
|
|
976
|
+
enabledStacks.delete(stackName);
|
|
977
|
+
}
|
|
978
|
+
project.enabledStacks = [...enabledStacks];
|
|
979
|
+
// Persist to disk via registry
|
|
980
|
+
try {
|
|
981
|
+
this.registry.persist();
|
|
982
|
+
}
|
|
983
|
+
catch {
|
|
984
|
+
// Non-critical — runtime state is authoritative
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
toProjectInfo(project) {
|
|
988
|
+
const config = this.configRegistry.get(project.name)?.config;
|
|
989
|
+
const stacks = config ? this.resolveStacks(config, project.name) : {};
|
|
990
|
+
const runningStacks = this.getRunningStacks(project.name);
|
|
991
|
+
return {
|
|
992
|
+
name: project.name,
|
|
993
|
+
displayName: config?.project ?? project.name,
|
|
994
|
+
path: project.path,
|
|
995
|
+
registeredAt: project.registeredAt,
|
|
996
|
+
enabledStacks: project.enabledStacks ?? [],
|
|
997
|
+
runningStacks: runningStacks.length,
|
|
998
|
+
totalStacks: Object.keys(stacks).length,
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
1001
|
+
toStackInfo(projectName, stackName, config) {
|
|
1002
|
+
const stateKey = `${projectName}/${stackName}`;
|
|
1003
|
+
const state = this.stackStates.get(stateKey);
|
|
1004
|
+
const prefix = `${projectName}/${stackName}/`;
|
|
1005
|
+
// Get apps running in this stack
|
|
1006
|
+
const stackApps = this.orchestrator.list({ prefix });
|
|
1007
|
+
const runningByName = new Map(stackApps.map((a) => [a.name.replace(prefix, ''), a]));
|
|
1008
|
+
// Build app list from config — include both running and stopped apps
|
|
1009
|
+
const ecosystemConfig = this.getLoadedConfig(projectName);
|
|
1010
|
+
const configuredApps = ecosystemConfig ? this.resolveStackApps(config, ecosystemConfig) : [];
|
|
1011
|
+
const apps = configuredApps.map((entry) => {
|
|
1012
|
+
const running = runningByName.get(entry.name);
|
|
1013
|
+
if (running) {
|
|
1014
|
+
runningByName.delete(entry.name);
|
|
1015
|
+
return {
|
|
1016
|
+
name: entry.name,
|
|
1017
|
+
handleKey: running.name,
|
|
1018
|
+
status: running.status,
|
|
1019
|
+
pid: running.pid,
|
|
1020
|
+
instances: running.instances,
|
|
1021
|
+
uptime: running.uptime,
|
|
1022
|
+
};
|
|
1023
|
+
}
|
|
1024
|
+
// App is configured but not running
|
|
1025
|
+
return {
|
|
1026
|
+
name: entry.name,
|
|
1027
|
+
handleKey: `${prefix}${entry.name}`,
|
|
1028
|
+
status: 'stopped',
|
|
1029
|
+
pid: null,
|
|
1030
|
+
instances: 0,
|
|
1031
|
+
uptime: 0,
|
|
1032
|
+
};
|
|
1033
|
+
});
|
|
1034
|
+
// Include any running apps not in config (shouldn't happen, but be safe)
|
|
1035
|
+
for (const [name, running] of runningByName) {
|
|
1036
|
+
apps.push({
|
|
1037
|
+
name,
|
|
1038
|
+
handleKey: running.name,
|
|
1039
|
+
status: running.status,
|
|
1040
|
+
pid: running.pid,
|
|
1041
|
+
instances: running.instances,
|
|
1042
|
+
uptime: running.uptime,
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
1045
|
+
// Populate real node connectivity from SlaveConnector
|
|
1046
|
+
const slaveConnections = this.slaveConnector?.getConnections() ?? [];
|
|
1047
|
+
const nodes = (config.nodes ?? []).map((n) => {
|
|
1048
|
+
const port = n.port ?? 9700;
|
|
1049
|
+
const conn = slaveConnections.find((c) => c.host === n.host && c.port === port);
|
|
1050
|
+
const connected = conn?.status === 'connected';
|
|
1051
|
+
return {
|
|
1052
|
+
host: n.host,
|
|
1053
|
+
port,
|
|
1054
|
+
role: n.role,
|
|
1055
|
+
label: n.label ?? null,
|
|
1056
|
+
daemonRole: n.role === 'master' ? 'master' : 'slave',
|
|
1057
|
+
connected,
|
|
1058
|
+
lastSeen: conn?.lastHeartbeat ?? null,
|
|
1059
|
+
syncStatus: null,
|
|
1060
|
+
};
|
|
1061
|
+
});
|
|
1062
|
+
// For local stacks, add implicit local node
|
|
1063
|
+
if (config.type === 'local' && nodes.length === 0) {
|
|
1064
|
+
nodes.push({
|
|
1065
|
+
host: 'localhost',
|
|
1066
|
+
port: 9700,
|
|
1067
|
+
role: 'app',
|
|
1068
|
+
label: 'Local',
|
|
1069
|
+
daemonRole: 'master',
|
|
1070
|
+
connected: true,
|
|
1071
|
+
lastSeen: Date.now(),
|
|
1072
|
+
syncStatus: null,
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
1075
|
+
// Populate infrastructure status from actual InfrastructureService
|
|
1076
|
+
const infraInstance = this.infraManager.getInstance(projectName, stackName);
|
|
1077
|
+
const infraState = infraInstance?.getState();
|
|
1078
|
+
const infraServices = {};
|
|
1079
|
+
if (infraState?.services) {
|
|
1080
|
+
// Container names are "{project}-{stack}-{service}" (e.g. omni-dev-postgres).
|
|
1081
|
+
// UI looks up by service name (e.g. "postgres"), so strip the stack prefix.
|
|
1082
|
+
const stackPrefix = `${projectName}-${stackName}-`;
|
|
1083
|
+
for (const [containerName, svcState] of Object.entries(infraState.services)) {
|
|
1084
|
+
const serviceName = containerName.startsWith(stackPrefix)
|
|
1085
|
+
? containerName.slice(stackPrefix.length)
|
|
1086
|
+
: containerName;
|
|
1087
|
+
infraServices[serviceName] = {
|
|
1088
|
+
status: svcState.status === 'running' ? 'running' : svcState.error ? 'error' : 'stopped',
|
|
1089
|
+
containerName: svcState.name,
|
|
1090
|
+
port: svcState.ports ? Object.values(svcState.ports)[0] ?? null : null,
|
|
1091
|
+
};
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
const infrastructure = {
|
|
1095
|
+
ready: infraState?.ready ?? false,
|
|
1096
|
+
services: infraServices,
|
|
1097
|
+
};
|
|
1098
|
+
return {
|
|
1099
|
+
name: stackName,
|
|
1100
|
+
type: config.type,
|
|
1101
|
+
status: state?.status ?? 'stopped',
|
|
1102
|
+
config,
|
|
1103
|
+
nodes,
|
|
1104
|
+
apps,
|
|
1105
|
+
infrastructure,
|
|
1106
|
+
portRange: config.portRange ?? null,
|
|
1107
|
+
startedAt: state?.startedAt ? new Date(state.startedAt).toISOString() : null,
|
|
1108
|
+
uptime: state?.startedAt ? Date.now() - state.startedAt : 0,
|
|
1109
|
+
};
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
//# sourceMappingURL=project.service.js.map
|