@omnitron-dev/omnitron 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/omnitron.js +32 -1
- package/dist/cli/omnitron.js.map +1 -1
- package/dist/cluster/leader-election.d.ts.map +1 -1
- package/dist/cluster/leader-election.js +0 -2
- package/dist/cluster/leader-election.js.map +1 -1
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/env.js +10 -2
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/health.d.ts.map +1 -1
- package/dist/commands/health.js +10 -2
- package/dist/commands/health.js.map +1 -1
- package/dist/commands/inspect-graph.d.ts +20 -0
- package/dist/commands/inspect-graph.d.ts.map +1 -0
- package/dist/commands/inspect-graph.js +78 -0
- package/dist/commands/inspect-graph.js.map +1 -0
- package/dist/commands/inspect.d.ts.map +1 -1
- package/dist/commands/inspect.js +10 -2
- package/dist/commands/inspect.js.map +1 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +11 -1
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/logs.d.ts.map +1 -1
- package/dist/commands/logs.js +17 -3
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/metrics.d.ts.map +1 -1
- package/dist/commands/metrics.js +10 -2
- package/dist/commands/metrics.js.map +1 -1
- package/dist/commands/monit.d.ts.map +1 -1
- package/dist/commands/monit.js +9 -0
- package/dist/commands/monit.js.map +1 -1
- package/dist/commands/output.d.ts +35 -0
- package/dist/commands/output.d.ts.map +1 -0
- package/dist/commands/output.js +63 -0
- package/dist/commands/output.js.map +1 -0
- package/dist/commands/stack.d.ts.map +1 -1
- package/dist/commands/stack.js +22 -7
- package/dist/commands/stack.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +17 -0
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/tor.d.ts +13 -0
- package/dist/commands/tor.d.ts.map +1 -0
- package/dist/commands/tor.js +100 -0
- package/dist/commands/tor.js.map +1 -0
- package/dist/commands/up.js +1 -1
- package/dist/commands/up.js.map +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +29 -5
- package/dist/config/loader.js.map +1 -1
- package/dist/config/types.d.ts +14 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/daemon/daemon-client.d.ts +14 -0
- package/dist/daemon/daemon-client.d.ts.map +1 -1
- package/dist/daemon/daemon-client.js +4 -0
- package/dist/daemon/daemon-client.js.map +1 -1
- package/dist/daemon/daemon-entry.js +17 -23
- package/dist/daemon/daemon-entry.js.map +1 -1
- package/dist/daemon/daemon.d.ts +2 -0
- package/dist/daemon/daemon.d.ts.map +1 -1
- package/dist/daemon/daemon.js +118 -7
- package/dist/daemon/daemon.js.map +1 -1
- package/dist/daemon/daemon.module.d.ts.map +1 -1
- package/dist/daemon/daemon.module.js +41 -14
- package/dist/daemon/daemon.module.js.map +1 -1
- package/dist/daemon/daemon.rpc-service.d.ts +19 -0
- package/dist/daemon/daemon.rpc-service.d.ts.map +1 -1
- package/dist/daemon/daemon.rpc-service.js +14 -0
- package/dist/daemon/daemon.rpc-service.js.map +1 -1
- package/dist/daemon/pid-manager.d.ts +55 -4
- package/dist/daemon/pid-manager.d.ts.map +1 -1
- package/dist/daemon/pid-manager.js +123 -16
- package/dist/daemon/pid-manager.js.map +1 -1
- package/dist/daemon/state-store.d.ts.map +1 -1
- package/dist/daemon/state-store.js +43 -1
- package/dist/daemon/state-store.js.map +1 -1
- package/dist/infrastructure/container-runtime.d.ts +10 -0
- package/dist/infrastructure/container-runtime.d.ts.map +1 -1
- package/dist/infrastructure/container-runtime.js +111 -36
- package/dist/infrastructure/container-runtime.js.map +1 -1
- package/dist/infrastructure/infrastructure.service.d.ts +41 -0
- package/dist/infrastructure/infrastructure.service.d.ts.map +1 -1
- package/dist/infrastructure/infrastructure.service.js +157 -8
- package/dist/infrastructure/infrastructure.service.js.map +1 -1
- package/dist/infrastructure/phantom-endpoint-janitor.d.ts +72 -0
- package/dist/infrastructure/phantom-endpoint-janitor.d.ts.map +1 -0
- package/dist/infrastructure/phantom-endpoint-janitor.js +149 -0
- package/dist/infrastructure/phantom-endpoint-janitor.js.map +1 -0
- package/dist/infrastructure/presets/index.d.ts.map +1 -1
- package/dist/infrastructure/presets/index.js +2 -0
- package/dist/infrastructure/presets/index.js.map +1 -1
- package/dist/infrastructure/presets/postgres.d.ts.map +1 -1
- package/dist/infrastructure/presets/postgres.js +9 -3
- package/dist/infrastructure/presets/postgres.js.map +1 -1
- package/dist/infrastructure/presets/redis.d.ts.map +1 -1
- package/dist/infrastructure/presets/redis.js +10 -4
- package/dist/infrastructure/presets/redis.js.map +1 -1
- package/dist/infrastructure/presets/registry.d.ts.map +1 -1
- package/dist/infrastructure/presets/registry.js +12 -0
- package/dist/infrastructure/presets/registry.js.map +1 -1
- package/dist/infrastructure/presets/tor.d.ts +74 -0
- package/dist/infrastructure/presets/tor.d.ts.map +1 -0
- package/dist/infrastructure/presets/tor.js +176 -0
- package/dist/infrastructure/presets/tor.js.map +1 -0
- package/dist/infrastructure/service-resolver.d.ts +31 -0
- package/dist/infrastructure/service-resolver.d.ts.map +1 -1
- package/dist/infrastructure/service-resolver.js +60 -9
- package/dist/infrastructure/service-resolver.js.map +1 -1
- package/dist/infrastructure/stack-infra-manager.d.ts +1 -1
- package/dist/infrastructure/stack-infra-manager.js +1 -1
- package/dist/infrastructure/types.d.ts +17 -0
- package/dist/infrastructure/types.d.ts.map +1 -1
- package/dist/observability/index.d.ts +4 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +3 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/metrics-bridge.d.ts +87 -0
- package/dist/observability/metrics-bridge.d.ts.map +1 -0
- package/dist/observability/metrics-bridge.js +295 -0
- package/dist/observability/metrics-bridge.js.map +1 -0
- package/dist/observability/metrics-server.d.ts +68 -0
- package/dist/observability/metrics-server.d.ts.map +1 -0
- package/dist/observability/metrics-server.js +146 -0
- package/dist/observability/metrics-server.js.map +1 -0
- package/dist/orchestrator/app-handle.d.ts +13 -1
- package/dist/orchestrator/app-handle.d.ts.map +1 -1
- package/dist/orchestrator/app-handle.js +12 -0
- package/dist/orchestrator/app-handle.js.map +1 -1
- package/dist/orchestrator/bootstrap-process.d.ts +49 -0
- package/dist/orchestrator/bootstrap-process.d.ts.map +1 -1
- package/dist/orchestrator/bootstrap-process.js +167 -0
- package/dist/orchestrator/bootstrap-process.js.map +1 -1
- package/dist/orchestrator/build-service.d.ts +50 -3
- package/dist/orchestrator/build-service.d.ts.map +1 -1
- package/dist/orchestrator/build-service.js +357 -85
- package/dist/orchestrator/build-service.js.map +1 -1
- package/dist/orchestrator/file-watcher.d.ts.map +1 -1
- package/dist/orchestrator/file-watcher.js +60 -38
- package/dist/orchestrator/file-watcher.js.map +1 -1
- package/dist/orchestrator/orchestrator.service.d.ts +176 -3
- package/dist/orchestrator/orchestrator.service.d.ts.map +1 -1
- package/dist/orchestrator/orchestrator.service.js +587 -56
- package/dist/orchestrator/orchestrator.service.js.map +1 -1
- package/dist/orchestrator/process-janitor.d.ts +153 -0
- package/dist/orchestrator/process-janitor.d.ts.map +1 -0
- package/dist/orchestrator/process-janitor.js +279 -0
- package/dist/orchestrator/process-janitor.js.map +1 -0
- package/dist/project/config-resolver.d.ts.map +1 -1
- package/dist/project/config-resolver.js +38 -12
- package/dist/project/config-resolver.js.map +1 -1
- package/dist/project/registry.d.ts +1 -0
- package/dist/project/registry.d.ts.map +1 -1
- package/dist/project/registry.js +30 -0
- package/dist/project/registry.js.map +1 -1
- package/dist/services/auth.service.d.ts.map +1 -1
- package/dist/services/auth.service.js +9 -2
- package/dist/services/auth.service.js.map +1 -1
- package/dist/services/netron-telemetry-transport.d.ts.map +1 -1
- package/dist/services/netron-telemetry-transport.js +0 -4
- package/dist/services/netron-telemetry-transport.js.map +1 -1
- package/dist/services/node-manager.service.js +1 -1
- package/dist/services/node-manager.service.js.map +1 -1
- package/dist/services/pipeline.service.d.ts +15 -0
- package/dist/services/pipeline.service.d.ts.map +1 -1
- package/dist/services/pipeline.service.js +53 -2
- package/dist/services/pipeline.service.js.map +1 -1
- package/dist/services/project.rpc-service.d.ts +4 -0
- package/dist/services/project.rpc-service.d.ts.map +1 -1
- package/dist/services/project.rpc-service.js +9 -0
- package/dist/services/project.rpc-service.js.map +1 -1
- package/dist/services/project.service.d.ts +9 -0
- package/dist/services/project.service.d.ts.map +1 -1
- package/dist/services/project.service.js +148 -21
- package/dist/services/project.service.js.map +1 -1
- package/dist/shared/dto/project.d.ts +1 -1
- package/dist/shared/dto/project.d.ts.map +1 -1
- package/dist/shared/dto/services.d.ts +24 -0
- package/dist/shared/dto/services.d.ts.map +1 -1
- package/dist/workers/health-monitor.service.d.ts.map +1 -1
- package/dist/workers/health-monitor.service.js +4 -1
- package/dist/workers/health-monitor.service.js.map +1 -1
- package/dist/workers/types.d.ts +3 -0
- package/dist/workers/types.d.ts.map +1 -1
- package/package.json +19 -18
- package/webapp/dist/assets/Badge-D2ZBP5iK.js +1 -0
- package/webapp/dist/assets/Card-vO88g06B.js +1 -0
- package/webapp/dist/assets/CardActions-C9h7Q2wW.js +1 -0
- package/webapp/dist/assets/CardContent-BA_Xmmhk.js +1 -0
- package/webapp/dist/assets/CardHeader-ceIs__6x.js +1 -0
- package/webapp/dist/assets/Chip-Ckk0xUhK.js +1 -0
- package/webapp/dist/assets/DialogActions-BhHM7hov.js +1 -0
- package/webapp/dist/assets/DialogContentText-BT2JQRmK.js +1 -0
- package/webapp/dist/assets/FormControlLabel-CcQByVS8.js +1 -0
- package/webapp/dist/assets/Grid-14PETRQW.js +1 -0
- package/webapp/dist/assets/InputAdornment-B8aHIsQ7.js +1 -0
- package/webapp/dist/assets/Skeleton-B74-Ds6O.js +37 -0
- package/webapp/dist/assets/Switch-DvWD2wh4.js +1 -0
- package/webapp/dist/assets/SwitchBase-CDU4nY8O.js +1 -0
- package/webapp/dist/assets/Tab-DcCOYYp5.js +1 -0
- package/webapp/dist/assets/TableContainer-CzTh4mu-.js +1 -0
- package/webapp/dist/assets/TableRow-BySEreZR.js +2 -0
- package/webapp/dist/assets/TextField-BLf-BHz2.js +1 -0
- package/webapp/dist/assets/alerts-DnRbT41C.js +1 -0
- package/webapp/dist/assets/apps-CdR0VH2d.js +1 -0
- package/webapp/dist/assets/chunk-DtcAfS_W.js +1 -0
- package/webapp/dist/assets/client-DU8I_lDc.js +2 -0
- package/webapp/dist/assets/containers-Dw-rRXV1.js +1 -0
- package/webapp/dist/assets/dashboard-CzgB0uZz.js +1 -0
- package/webapp/dist/assets/dashboard-builder-DsA0yg33.js +1 -0
- package/webapp/dist/assets/deployments-DtQAoIcQ.js +1 -0
- package/webapp/dist/assets/detail-BJR-G7JG.js +1 -0
- package/webapp/dist/assets/detail-nlCeSltl.js +8 -0
- package/webapp/dist/assets/index-ByQDwp2r.js +566 -0
- package/webapp/dist/assets/isMuiElement-DwF2naaF.js +1 -0
- package/webapp/dist/assets/logs-Kn8o4H7k.js +11 -0
- package/webapp/dist/assets/metrics-DN8Zu5wT.js +2 -0
- package/webapp/dist/assets/nodes-Bgch7AtN.js +7 -0
- package/webapp/dist/assets/pipelines-Cry3qm-S.js +4 -0
- package/webapp/dist/assets/popper-BJFSj6rc.js +1 -0
- package/webapp/dist/assets/preload-helper-DSXbuxSR.js +1 -0
- package/webapp/dist/assets/projects-Dym2GI1U.js +1 -0
- package/webapp/dist/assets/react-apexcharts.esm-CSGK5Cxn.js +958 -0
- package/webapp/dist/assets/react-apexcharts.esm-DEAWOwx5.js +1003 -0
- package/webapp/dist/assets/settings-va3zTcow.js +1 -0
- package/webapp/dist/assets/sign-in-ik35umbp.js +1 -0
- package/webapp/dist/assets/stacks-CVFOnxbF.js +1 -0
- package/webapp/dist/assets/system-info-npIXAjX2.js +1 -0
- package/webapp/dist/assets/topology-bDe70vLs.js +12 -0
- package/webapp/dist/assets/traces-DIIcT8DF.js +1 -0
- package/webapp/dist/assets/use-stack-context-DHLwZv1r.js +1 -0
- package/webapp/dist/index.html +5 -6
- package/webapp/dist/assets/Chip-BySxTjyN.js +0 -1
- package/webapp/dist/assets/DialogContentText-YQWiAVrU.js +0 -1
- package/webapp/dist/assets/DialogTitle-CDkgUIwp.js +0 -1
- package/webapp/dist/assets/FormControlLabel-Bu3CCsBM.js +0 -1
- package/webapp/dist/assets/Grid-BFY8hAzL.js +0 -1
- package/webapp/dist/assets/InputAdornment-_Dayk-3y.js +0 -3
- package/webapp/dist/assets/Skeleton-BGj6Sw8m.js +0 -37
- package/webapp/dist/assets/Switch-CA6682vv.js +0 -1
- package/webapp/dist/assets/TableContainer-4epq10KJ.js +0 -1
- package/webapp/dist/assets/TextField-C73KHMVN.js +0 -1
- package/webapp/dist/assets/alerts-JEQALS7Y.js +0 -1
- package/webapp/dist/assets/apps-DMPysEKB.js +0 -1
- package/webapp/dist/assets/client-DlGPter5.js +0 -110
- package/webapp/dist/assets/containers-CvkC7do8.js +0 -1
- package/webapp/dist/assets/dashboard-C0Fre9pC.js +0 -1
- package/webapp/dist/assets/dashboard-builder-DAghqdpE.js +0 -1
- package/webapp/dist/assets/deployments-Cg1lI1uT.js +0 -1
- package/webapp/dist/assets/detail-CyFtEson.js +0 -1
- package/webapp/dist/assets/detail-DqoSGKT1.js +0 -8
- package/webapp/dist/assets/icons-ynIWYfBP.js +0 -3
- package/webapp/dist/assets/index-vKrDmEA_.js +0 -259
- package/webapp/dist/assets/isMuiElement-BRL3YuCT.js +0 -1
- package/webapp/dist/assets/logs-IovIij1C.js +0 -11
- package/webapp/dist/assets/metrics-Dufwtwjq.js +0 -1
- package/webapp/dist/assets/nodes-Brvu8W3j.js +0 -7
- package/webapp/dist/assets/pipelines-t40X4MuC.js +0 -4
- package/webapp/dist/assets/prop-types-CvVtHxp4.js +0 -1
- package/webapp/dist/assets/react-apexcharts.esm-CLO6gala.js +0 -954
- package/webapp/dist/assets/settings-DTAIST3v.js +0 -1
- package/webapp/dist/assets/sign-in-DQEAkJum.js +0 -1
- package/webapp/dist/assets/stacks-BjM1f45N.js +0 -1
- package/webapp/dist/assets/system-info-BQSbSEK-.js +0 -1
- package/webapp/dist/assets/topology-6N8-Az_Z.js +0 -12
- package/webapp/dist/assets/traces-DVXyb-4m.js +0 -1
- package/webapp/dist/assets/use-stack-context-CbE8fxBA.js +0 -1
- /package/webapp/dist/assets/{constants-DqFQJ27U.js → constants-BgnT-Xdy.js} +0 -0
- /package/webapp/dist/assets/{formatters-J3Xqn6BQ.js → formatters-Do41SRmE.js} +0 -0
- /package/webapp/dist/assets/{fs-uP8eiZAR.js → fs-CgZLtHiQ.js} +0 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phantom-endpoint janitor (T#75).
|
|
3
|
+
*
|
|
4
|
+
* Docker networks accumulate "phantom endpoint" records when a
|
|
5
|
+
* container is removed while the dockerd daemon is restarting,
|
|
6
|
+
* during host suspend/resume cycles, or when a `docker rm -f`
|
|
7
|
+
* arrives mid-network-disconnect. The network's internal endpoint
|
|
8
|
+
* table keeps a stale row pointing at a container that no longer
|
|
9
|
+
* exists. The visible symptom is a recreation failure with:
|
|
10
|
+
*
|
|
11
|
+
* Error response from daemon: endpoint with name X
|
|
12
|
+
* already exists in network managed-net
|
|
13
|
+
*
|
|
14
|
+
* The existing T#58 work avoids the bridge default to sidestep the
|
|
15
|
+
* worst class of this. The managed network is still susceptible
|
|
16
|
+
* after dockerd / host restarts, just less frequently. T#75 is the
|
|
17
|
+
* active cleanup: every interval, list the endpoints in each
|
|
18
|
+
* managed network, look each one up as a container, and force-
|
|
19
|
+
* disconnect every endpoint whose container has vanished.
|
|
20
|
+
*
|
|
21
|
+
* Implementation notes:
|
|
22
|
+
* - We shell out to `docker network inspect` / `docker network
|
|
23
|
+
* disconnect` rather than the engine adapter — the adapter
|
|
24
|
+
* doesn't expose network APIs and this code path is rare
|
|
25
|
+
* (one sweep per `intervalMs`).
|
|
26
|
+
* - The whole loop is wrapped in a single in-flight guard so
|
|
27
|
+
* two overlapping sweeps can't both try to disconnect the
|
|
28
|
+
* same endpoint and produce noisy errors.
|
|
29
|
+
* - All errors are caught and logged — a docker-daemon hiccup
|
|
30
|
+
* during one sweep must NOT prevent the next one from running.
|
|
31
|
+
*/
|
|
32
|
+
import { spawn } from 'node:child_process';
|
|
33
|
+
export class PhantomEndpointJanitor {
|
|
34
|
+
opts;
|
|
35
|
+
timer = null;
|
|
36
|
+
sweeping = false;
|
|
37
|
+
constructor(opts) {
|
|
38
|
+
this.opts = opts;
|
|
39
|
+
}
|
|
40
|
+
start() {
|
|
41
|
+
if (this.timer)
|
|
42
|
+
return;
|
|
43
|
+
const intervalMs = this.opts.intervalMs ?? 60_000;
|
|
44
|
+
this.timer = setInterval(() => {
|
|
45
|
+
void this.sweepAll().catch((err) => {
|
|
46
|
+
this.opts.logger.error({ err }, 'phantom-endpoint janitor: sweep loop crashed');
|
|
47
|
+
});
|
|
48
|
+
}, intervalMs);
|
|
49
|
+
this.timer.unref();
|
|
50
|
+
this.opts.logger.info({ networks: this.opts.networks, intervalMs }, 'phantom-endpoint janitor: started (T#75)');
|
|
51
|
+
}
|
|
52
|
+
stop() {
|
|
53
|
+
if (!this.timer)
|
|
54
|
+
return;
|
|
55
|
+
clearInterval(this.timer);
|
|
56
|
+
this.timer = null;
|
|
57
|
+
}
|
|
58
|
+
/** Run a single sweep across every managed network. Public for tests + ops triggers. */
|
|
59
|
+
async sweepAll() {
|
|
60
|
+
if (this.sweeping)
|
|
61
|
+
return 0;
|
|
62
|
+
this.sweeping = true;
|
|
63
|
+
let totalCleaned = 0;
|
|
64
|
+
try {
|
|
65
|
+
for (const net of this.opts.networks) {
|
|
66
|
+
try {
|
|
67
|
+
const cleaned = await this.sweepNetwork(net);
|
|
68
|
+
totalCleaned += cleaned;
|
|
69
|
+
this.opts.onCleanup?.(net, cleaned);
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
this.opts.logger.warn({ err, network: net }, 'phantom-endpoint janitor: per-network sweep failed (continuing)');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
this.sweeping = false;
|
|
78
|
+
}
|
|
79
|
+
return totalCleaned;
|
|
80
|
+
}
|
|
81
|
+
async sweepNetwork(network) {
|
|
82
|
+
const inspect = await this.runDocker(['network', 'inspect', network]);
|
|
83
|
+
if (!inspect.ok) {
|
|
84
|
+
// Network doesn't exist or docker daemon unreachable. Either
|
|
85
|
+
// way, nothing to clean.
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
88
|
+
let networks = [];
|
|
89
|
+
try {
|
|
90
|
+
networks = JSON.parse(inspect.stdout);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return 0;
|
|
94
|
+
}
|
|
95
|
+
const endpoints = networks[0]?.Containers ?? {};
|
|
96
|
+
let cleaned = 0;
|
|
97
|
+
for (const [containerId, info] of Object.entries(endpoints)) {
|
|
98
|
+
// Check whether the container still exists. `docker inspect`
|
|
99
|
+
// returns exit code 1 with "No such object" when it doesn't.
|
|
100
|
+
const exists = await this.runDocker(['inspect', '--type=container', '--format', '{{.Id}}', containerId]);
|
|
101
|
+
if (exists.ok)
|
|
102
|
+
continue;
|
|
103
|
+
// Phantom — force-disconnect.
|
|
104
|
+
const disconnect = await this.runDocker(['network', 'disconnect', network, containerId, '--force']);
|
|
105
|
+
if (disconnect.ok) {
|
|
106
|
+
cleaned++;
|
|
107
|
+
this.opts.logger.info({ network, containerId, name: info?.Name }, 'phantom-endpoint janitor: disconnected phantom endpoint (T#75)');
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
this.opts.logger.warn({ network, containerId, stderr: disconnect.stderr }, 'phantom-endpoint janitor: failed to disconnect phantom — will retry next sweep');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return cleaned;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Run `docker <args>` and return stdout/stderr/exit-code. Never throws —
|
|
117
|
+
* a missing docker binary or a hung daemon shouldn't crash the daemon.
|
|
118
|
+
*
|
|
119
|
+
* Visible for testing via subclassing — overrides go through this
|
|
120
|
+
* single seam so tests can drive deterministic responses without
|
|
121
|
+
* needing a real Docker daemon. Production callers should not
|
|
122
|
+
* subclass.
|
|
123
|
+
*/
|
|
124
|
+
runDocker(args) {
|
|
125
|
+
return new Promise((resolve) => {
|
|
126
|
+
const child = spawn('docker', args, { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
127
|
+
let stdout = '';
|
|
128
|
+
let stderr = '';
|
|
129
|
+
const timeout = setTimeout(() => {
|
|
130
|
+
try {
|
|
131
|
+
child.kill('SIGKILL');
|
|
132
|
+
}
|
|
133
|
+
catch { /* */ }
|
|
134
|
+
resolve({ ok: false, stdout, stderr: stderr + '\n[janitor: timeout]' });
|
|
135
|
+
}, 10_000);
|
|
136
|
+
child.stdout?.on('data', (c) => { stdout += c.toString(); });
|
|
137
|
+
child.stderr?.on('data', (c) => { stderr += c.toString(); });
|
|
138
|
+
child.on('error', () => {
|
|
139
|
+
clearTimeout(timeout);
|
|
140
|
+
resolve({ ok: false, stdout, stderr: stderr + '\n[janitor: spawn error]' });
|
|
141
|
+
});
|
|
142
|
+
child.on('close', (code) => {
|
|
143
|
+
clearTimeout(timeout);
|
|
144
|
+
resolve({ ok: code === 0, stdout, stderr });
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=phantom-endpoint-janitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phantom-endpoint-janitor.js","sourceRoot":"","sources":["../../src/infrastructure/phantom-endpoint-janitor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/presets/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAE9F,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/presets/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAE9F,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAO/C;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,cAAc,CAUtD"}
|
|
@@ -10,6 +10,7 @@ import { postgresPreset } from './postgres.js';
|
|
|
10
10
|
import { redisPreset } from './redis.js';
|
|
11
11
|
import { minioPreset } from './minio.js';
|
|
12
12
|
import { gatewayOpenrestyPreset } from './gateway-openresty.js';
|
|
13
|
+
import { torPreset } from './tor.js';
|
|
13
14
|
/**
|
|
14
15
|
* Create a PresetRegistry populated with all built-in presets.
|
|
15
16
|
*/
|
|
@@ -19,6 +20,7 @@ export function createDefaultRegistry() {
|
|
|
19
20
|
registry.register(redisPreset);
|
|
20
21
|
registry.register(minioPreset);
|
|
21
22
|
registry.register(gatewayOpenrestyPreset);
|
|
23
|
+
registry.register(torPreset);
|
|
22
24
|
return registry;
|
|
23
25
|
}
|
|
24
26
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infrastructure/presets/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infrastructure/presets/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC;;GAEG;AACH,MAAM,UAAU,qBAAqB;IACnC,MAAM,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAC;IAEtC,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAE7B,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/presets/postgres.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAyB,MAAM,YAAY,CAAC;AAExE,eAAO,MAAM,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/presets/postgres.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAyB,MAAM,YAAY,CAAC;AAExE,eAAO,MAAM,cAAc,EAAE,cAiF5B,CAAC"}
|
|
@@ -11,11 +11,17 @@ export const postgresPreset = {
|
|
|
11
11
|
defaultPorts: { main: 5432 },
|
|
12
12
|
defaultSecrets: { user: 'postgres', password: 'postgres' },
|
|
13
13
|
defaultHealthCheck: {
|
|
14
|
+
// pg_isready returns 0 the moment the postmaster accepts connections
|
|
15
|
+
// — but the moment isn't quite app-ready: WAL replay or extension
|
|
16
|
+
// creation can still be running. Use a real `SELECT 1` against
|
|
17
|
+
// postgres user (always exists) so we don't mark healthy until the
|
|
18
|
+
// executor is functional. Higher retry count covers slow boots
|
|
19
|
+
// (volume create + WAL replay can take 15s+).
|
|
14
20
|
type: 'command',
|
|
15
|
-
target: '
|
|
16
|
-
interval: '
|
|
21
|
+
target: 'sh -c "psql -U postgres -d postgres -h /var/run/postgresql -tAc \\"SELECT 1\\" | grep -q 1"',
|
|
22
|
+
interval: '3s',
|
|
17
23
|
timeout: '5s',
|
|
18
|
-
retries:
|
|
24
|
+
retries: 30,
|
|
19
25
|
},
|
|
20
26
|
defaultDocker: {
|
|
21
27
|
command: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../../src/infrastructure/presets/postgres.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,CAAC,MAAM,cAAc,GAAmB;IAC5C,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,UAAU;IAChB,YAAY,EAAE,oBAAoB;IAClC,YAAY,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IAC5B,cAAc,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE;IAE1D,kBAAkB,EAAE;QAClB,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../../src/infrastructure/presets/postgres.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/presets/redis.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,eAAO,MAAM,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/presets/redis.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,eAAO,MAAM,WAAW,EAAE,cAiCzB,CAAC"}
|
|
@@ -11,11 +11,17 @@ export const redisPreset = {
|
|
|
11
11
|
defaultPorts: { main: 6379 },
|
|
12
12
|
defaultSecrets: {},
|
|
13
13
|
defaultHealthCheck: {
|
|
14
|
+
// The naive `redis-cli ping` exits 0 even when redis is still
|
|
15
|
+
// loading its RDB and replies "LOADING Redis is loading the dataset
|
|
16
|
+
// in memory" — Docker's HEALTHCHECK then marks the container healthy
|
|
17
|
+
// and apps that try to connect get told their commands aren't
|
|
18
|
+
// accepted yet. The grep below requires the literal "PONG" reply,
|
|
19
|
+
// which redis only sends once it has fully loaded.
|
|
14
20
|
type: 'command',
|
|
15
|
-
target: 'redis-cli ping',
|
|
16
|
-
interval: '
|
|
17
|
-
timeout: '
|
|
18
|
-
retries:
|
|
21
|
+
target: 'sh -c "redis-cli ping | grep -q PONG"',
|
|
22
|
+
interval: '3s',
|
|
23
|
+
timeout: '3s',
|
|
24
|
+
retries: 30,
|
|
19
25
|
},
|
|
20
26
|
defaultDocker: {
|
|
21
27
|
command: ['redis-server', '--appendonly', 'yes', '--maxmemory-policy', 'allkeys-lru'],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../../src/infrastructure/presets/redis.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,CAAC,MAAM,WAAW,GAAmB;IACzC,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,OAAO;IACb,YAAY,EAAE,gBAAgB;IAC9B,YAAY,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IAC5B,cAAc,EAAE,EAAE;IAElB,kBAAkB,EAAE;QAClB,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../../src/infrastructure/presets/redis.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,CAAC,MAAM,WAAW,GAAmB;IACzC,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,OAAO;IACb,YAAY,EAAE,gBAAgB;IAC9B,YAAY,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IAC5B,cAAc,EAAE,EAAE;IAElB,kBAAkB,EAAE;QAClB,8DAA8D;QAC9D,oEAAoE;QACpE,qEAAqE;QACrE,8DAA8D;QAC9D,kEAAkE;QAClE,mDAAmD;QACnD,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,uCAAuC;QAC/C,QAAQ,EAAE,IAAI;QACd,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,EAAE;KACZ;IAED,aAAa,EAAE;QACb,OAAO,EAAE,CAAC,cAAc,EAAE,cAAc,EAAE,KAAK,EAAE,oBAAoB,EAAE,aAAa,CAAC;QACrF,OAAO,EAAE;YACP,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;SACtC;KACF;IAED,oBAAoB;QAClB,OAAO;YACL,SAAS,EAAE,gCAAgC;SAC5C,CAAC;IACJ,CAAC;CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/presets/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,KAAK,EAAE,mBAAmB,EAAwB,MAAM,aAAa,CAAC;AAE7E,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAE7D,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAItC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI7C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,IAAI,IAAI,MAAM,EAAE;IAIhB;;;OAGG;IACH,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,mBAAmB;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/presets/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,KAAK,EAAE,mBAAmB,EAAwB,MAAM,aAAa,CAAC;AAE7E,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAE7D,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAItC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI7C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,IAAI,IAAI,MAAM,EAAE;IAIhB;;;OAGG;IACH,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,mBAAmB;CA6E/E"}
|
|
@@ -50,6 +50,18 @@ export class PresetRegistry {
|
|
|
50
50
|
dockerEnv['MINIO_ROOT_USER'] = mergedSecrets['accessKey'] ?? 'minioadmin';
|
|
51
51
|
dockerEnv['MINIO_ROOT_PASSWORD'] = mergedSecrets['secretKey'] ?? 'minioadmin';
|
|
52
52
|
}
|
|
53
|
+
else if (preset.name === 'tor') {
|
|
54
|
+
// Tor preset reads its hidden-service map from a single JSON env var —
|
|
55
|
+
// simpler than parametrising arbitrary numbers of HiddenServiceDir/Port
|
|
56
|
+
// pairs through individual variables. The torrc generator (see
|
|
57
|
+
// tor.ts ENTRYPOINT_SHELL) iterates over this list with `jq`.
|
|
58
|
+
const torCfg = (config.config ?? {});
|
|
59
|
+
const hsArr = Array.isArray(torCfg.hiddenServices) ? torCfg.hiddenServices : [];
|
|
60
|
+
dockerEnv['OMNITRON_TOR_HIDDEN_SERVICES_JSON'] = JSON.stringify(hsArr);
|
|
61
|
+
if (Array.isArray(torCfg.extraTorrc) && torCfg.extraTorrc.length > 0) {
|
|
62
|
+
dockerEnv['OMNITRON_TOR_EXTRA_TORRC'] = torCfg.extraTorrc.join('\n');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
53
65
|
if (config.docker?.environment) {
|
|
54
66
|
Object.assign(dockerEnv, config.docker.environment);
|
|
55
67
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/infrastructure/presets/registry.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/infrastructure/presets/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,OAAO,cAAc;IACR,OAAO,GAAG,IAAI,GAAG,EAA0B,CAAC;IAE7D,QAAQ,CAAC,MAAsB;QAC7B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,WAAmB,EAAE,MAA4B;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,2BAA2B,MAAM,CAAC,MAAM,kBAAkB,WAAW,KAAK;gBAC1E,sBAAsB,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/C,CAAC;QACJ,CAAC;QAED,kDAAkD;QAClD,MAAM,aAAa,GAA2B,EAAE,GAAG,MAAM,CAAC,cAAc,EAAE,CAAC;QAC3E,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;gBACpD,aAAa,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAC1D,CAAC;QACH,CAAC;QAED,cAAc;QACd,MAAM,WAAW,GAAG,EAAE,GAAG,MAAM,CAAC,YAAY,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;QAEhE,gEAAgE;QAChE,MAAM,SAAS,GAA2B,EAAE,GAAG,MAAM,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC;QAClF,iDAAiD;QACjD,kDAAkD;QAClD,8EAA8E;QAC9E,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC/B,SAAS,CAAC,eAAe,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC;YACjE,SAAS,CAAC,mBAAmB,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC;QAC3E,CAAC;aAAM,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACnC,SAAS,CAAC,iBAAiB,CAAC,GAAG,aAAa,CAAC,WAAW,CAAC,IAAI,YAAY,CAAC;YAC1E,SAAS,CAAC,qBAAqB,CAAC,GAAG,aAAa,CAAC,WAAW,CAAC,IAAI,YAAY,CAAC;QAChF,CAAC;aAAM,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACjC,uEAAuE;YACvE,wEAAwE;YACxE,+DAA+D;YAC/D,8DAA8D;YAC9D,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAA0D,CAAC;YAC9F,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;YAChF,SAAS,CAAC,mCAAmC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACvE,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrE,SAAS,CAAC,0BAA0B,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;YAC/B,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACtD,CAAC;QAED,sBAAsB;QACtB,MAAM,MAAM,GAAyB;YACnC,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,YAAY;YAC1C,GAAG,MAAM,CAAC,aAAa;YACvB,GAAG,MAAM,CAAC,MAAM;YAChB,WAAW,EAAE,SAAS;SACvB,CAAC;QAEF,0EAA0E;QAC1E,IAAI,WAAW,GAAG,MAAM,CAAC,kBAAkB,CAAC;QAC5C,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;YACxD,WAAW,GAAG,EAAE,GAAG,WAAW,EAAE,MAAM,EAAE,iBAAiB,aAAa,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACrF,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC;YACzD,WAAW,GAAG,EAAE,GAAG,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,aAAa,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QAC9G,CAAC;QAED,MAAM,MAAM,GAAwB;YAClC,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,KAAK,EAAE,WAAW;YAClB,GAAG,EAAE,MAAM,CAAC,oBAAoB,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,IAAI,EAAE;YAC7D,WAAW;YACX,OAAO,EAAE,aAAa;YACtB,MAAM;YACN,OAAO,EAAE,MAAM,CAAC,MAAM;SACvB,CAAC;QACF,IAAI,MAAM,CAAC,SAAS;YAAE,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAC1D,IAAI,MAAM,CAAC,MAAM;YAAE,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC;QACxD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tor Hidden Service Preset
|
|
3
|
+
*
|
|
4
|
+
* Runs a Tor daemon configured for **hidden-service-only** operation —
|
|
5
|
+
* SocksPort/ORPort/ExitPolicy are all locked down so the container cannot
|
|
6
|
+
* be abused as a relay or open SOCKS proxy. Hidden services map onion
|
|
7
|
+
* addresses to backend services declared in `config.hiddenServices`.
|
|
8
|
+
*
|
|
9
|
+
* Design choices for industrial-grade anonymity:
|
|
10
|
+
*
|
|
11
|
+
* - HiddenServiceVersion 3 (256-bit Ed25519, default in modern tor).
|
|
12
|
+
* - SocksPort 0 → no client SOCKS proxy is opened.
|
|
13
|
+
* - ClientOnly 0 → we are not relaying client circuits.
|
|
14
|
+
* - ORPort 0 / DirPort 0 → not a relay, not a directory server.
|
|
15
|
+
* - ExitPolicy reject *:* → never serve as exit node.
|
|
16
|
+
* - DisableDebuggerAttachment 1 — prevents ptrace + similar leaks.
|
|
17
|
+
* - HardwareAccel 1 — uses CPU AES-NI when available.
|
|
18
|
+
* - SafeLogging 1 — log scrubbing of identifying info.
|
|
19
|
+
* - HiddenServiceEnableIntroDoSDefense 1 — circuit-level rate limiting
|
|
20
|
+
* against introduction-point flooding (tor 0.4.7+).
|
|
21
|
+
* - HiddenServicePoWDefensesEnabled 1 — proof-of-work mitigation
|
|
22
|
+
* for the introduction layer (tor 0.4.8+).
|
|
23
|
+
*
|
|
24
|
+
* Networking:
|
|
25
|
+
*
|
|
26
|
+
* The container needs to reach backend services that may be running on
|
|
27
|
+
* the host (e.g. omnitron's webapp via omnitron-nginx, or any user-bound
|
|
28
|
+
* dev/prod service). We add `host.docker.internal` → `host-gateway` so
|
|
29
|
+
* HiddenServicePort targets like `host.docker.internal:9800` work
|
|
30
|
+
* identically on macOS, Linux, and Windows.
|
|
31
|
+
*
|
|
32
|
+
* State:
|
|
33
|
+
*
|
|
34
|
+
* `/var/lib/tor` is a persistent volume — that's where hidden service
|
|
35
|
+
* keys live (`<name>/hs_ed25519_secret_key`, `<name>/hostname`). Losing
|
|
36
|
+
* that volume rotates the .onion address. CLI command `omnitron tor`
|
|
37
|
+
* reads the hostname files via `docker exec`.
|
|
38
|
+
*
|
|
39
|
+
* Configuration in omnitron.config.ts:
|
|
40
|
+
*
|
|
41
|
+
* services: {
|
|
42
|
+
* tor: {
|
|
43
|
+
* preset: 'tor',
|
|
44
|
+
* config: {
|
|
45
|
+
* hiddenServices: [
|
|
46
|
+
* { name: 'webapp', virtualPort: 80, target: 'host.docker.internal:9800' },
|
|
47
|
+
* { name: 'portal', virtualPort: 80, target: 'host.docker.internal:7080' },
|
|
48
|
+
* ],
|
|
49
|
+
* },
|
|
50
|
+
* },
|
|
51
|
+
* },
|
|
52
|
+
*/
|
|
53
|
+
import type { IServicePreset } from './types.js';
|
|
54
|
+
/** User-provided per-hidden-service config. */
|
|
55
|
+
export interface ITorHiddenServiceConfig {
|
|
56
|
+
/** Logical name — also the directory name under /var/lib/tor/. */
|
|
57
|
+
name: string;
|
|
58
|
+
/** Port advertised on the .onion address (clients connect here). */
|
|
59
|
+
virtualPort: number;
|
|
60
|
+
/** Backend address `host:port` that tor forwards plaintext traffic to. */
|
|
61
|
+
target: string;
|
|
62
|
+
}
|
|
63
|
+
/** User-provided tor preset config. */
|
|
64
|
+
export interface ITorPresetConfig {
|
|
65
|
+
/** Hidden services to expose. Each gets its own .onion address. */
|
|
66
|
+
hiddenServices: ITorHiddenServiceConfig[];
|
|
67
|
+
/**
|
|
68
|
+
* Extra raw torrc lines appended verbatim. Use sparingly — most
|
|
69
|
+
* hardening is already applied by the preset.
|
|
70
|
+
*/
|
|
71
|
+
extraTorrc?: string[];
|
|
72
|
+
}
|
|
73
|
+
export declare const torPreset: IServicePreset;
|
|
74
|
+
//# sourceMappingURL=tor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tor.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/presets/tor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,+CAA+C;AAC/C,MAAM,WAAW,uBAAuB;IACtC,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,uCAAuC;AACvC,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,cAAc,EAAE,uBAAuB,EAAE,CAAC;IAC1C;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAwFD,eAAO,MAAM,SAAS,EAAE,cAyCvB,CAAC"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tor Hidden Service Preset
|
|
3
|
+
*
|
|
4
|
+
* Runs a Tor daemon configured for **hidden-service-only** operation —
|
|
5
|
+
* SocksPort/ORPort/ExitPolicy are all locked down so the container cannot
|
|
6
|
+
* be abused as a relay or open SOCKS proxy. Hidden services map onion
|
|
7
|
+
* addresses to backend services declared in `config.hiddenServices`.
|
|
8
|
+
*
|
|
9
|
+
* Design choices for industrial-grade anonymity:
|
|
10
|
+
*
|
|
11
|
+
* - HiddenServiceVersion 3 (256-bit Ed25519, default in modern tor).
|
|
12
|
+
* - SocksPort 0 → no client SOCKS proxy is opened.
|
|
13
|
+
* - ClientOnly 0 → we are not relaying client circuits.
|
|
14
|
+
* - ORPort 0 / DirPort 0 → not a relay, not a directory server.
|
|
15
|
+
* - ExitPolicy reject *:* → never serve as exit node.
|
|
16
|
+
* - DisableDebuggerAttachment 1 — prevents ptrace + similar leaks.
|
|
17
|
+
* - HardwareAccel 1 — uses CPU AES-NI when available.
|
|
18
|
+
* - SafeLogging 1 — log scrubbing of identifying info.
|
|
19
|
+
* - HiddenServiceEnableIntroDoSDefense 1 — circuit-level rate limiting
|
|
20
|
+
* against introduction-point flooding (tor 0.4.7+).
|
|
21
|
+
* - HiddenServicePoWDefensesEnabled 1 — proof-of-work mitigation
|
|
22
|
+
* for the introduction layer (tor 0.4.8+).
|
|
23
|
+
*
|
|
24
|
+
* Networking:
|
|
25
|
+
*
|
|
26
|
+
* The container needs to reach backend services that may be running on
|
|
27
|
+
* the host (e.g. omnitron's webapp via omnitron-nginx, or any user-bound
|
|
28
|
+
* dev/prod service). We add `host.docker.internal` → `host-gateway` so
|
|
29
|
+
* HiddenServicePort targets like `host.docker.internal:9800` work
|
|
30
|
+
* identically on macOS, Linux, and Windows.
|
|
31
|
+
*
|
|
32
|
+
* State:
|
|
33
|
+
*
|
|
34
|
+
* `/var/lib/tor` is a persistent volume — that's where hidden service
|
|
35
|
+
* keys live (`<name>/hs_ed25519_secret_key`, `<name>/hostname`). Losing
|
|
36
|
+
* that volume rotates the .onion address. CLI command `omnitron tor`
|
|
37
|
+
* reads the hostname files via `docker exec`.
|
|
38
|
+
*
|
|
39
|
+
* Configuration in omnitron.config.ts:
|
|
40
|
+
*
|
|
41
|
+
* services: {
|
|
42
|
+
* tor: {
|
|
43
|
+
* preset: 'tor',
|
|
44
|
+
* config: {
|
|
45
|
+
* hiddenServices: [
|
|
46
|
+
* { name: 'webapp', virtualPort: 80, target: 'host.docker.internal:9800' },
|
|
47
|
+
* { name: 'portal', virtualPort: 80, target: 'host.docker.internal:7080' },
|
|
48
|
+
* ],
|
|
49
|
+
* },
|
|
50
|
+
* },
|
|
51
|
+
* },
|
|
52
|
+
*/
|
|
53
|
+
/**
|
|
54
|
+
* Inline shell that installs tor (~5s on first run, cached afterward),
|
|
55
|
+
* generates a hardened torrc from `OMNITRON_TOR_HIDDEN_SERVICES_JSON`,
|
|
56
|
+
* and execs the daemon as the `tor` user.
|
|
57
|
+
*
|
|
58
|
+
* Why inline rather than a custom Dockerfile: keeps the preset hermetic.
|
|
59
|
+
* No image build step, no separate registry, no image-tag drift.
|
|
60
|
+
*/
|
|
61
|
+
const ENTRYPOINT_SHELL = `set -eu
|
|
62
|
+
|
|
63
|
+
# Install tor + jq. The Alpine tor package automatically creates a
|
|
64
|
+
# 'tor' system user (uid 100, gid 101). Idempotent across restarts.
|
|
65
|
+
apk add --no-cache tor jq >/dev/null 2>&1 || apk add tor jq >/dev/null 2>&1
|
|
66
|
+
|
|
67
|
+
# Build torrc from the env-passed JSON config.
|
|
68
|
+
TORRC=/etc/tor/torrc
|
|
69
|
+
mkdir -p /etc/tor /var/lib/tor
|
|
70
|
+
cat > "$TORRC" <<'TORRC_EOF'
|
|
71
|
+
# ============================================================
|
|
72
|
+
# Hidden-service-only Tor configuration (omnitron preset)
|
|
73
|
+
# ============================================================
|
|
74
|
+
# Process identity — tor drops privileges to this user after binding.
|
|
75
|
+
User tor
|
|
76
|
+
|
|
77
|
+
# Lockdown: no client/relay/exit functionality, only HSes.
|
|
78
|
+
SocksPort 0
|
|
79
|
+
ClientOnly 0
|
|
80
|
+
ORPort 0
|
|
81
|
+
DirPort 0
|
|
82
|
+
ExitRelay 0
|
|
83
|
+
ExitPolicy reject *:*
|
|
84
|
+
ExitPolicy reject6 *:*
|
|
85
|
+
BridgeRelay 0
|
|
86
|
+
|
|
87
|
+
# Operational hardening
|
|
88
|
+
DataDirectory /var/lib/tor
|
|
89
|
+
RunAsDaemon 0
|
|
90
|
+
HardwareAccel 1
|
|
91
|
+
DisableDebuggerAttachment 1
|
|
92
|
+
SafeLogging 1
|
|
93
|
+
LogTimeGranularity 1000
|
|
94
|
+
Log notice stdout
|
|
95
|
+
|
|
96
|
+
# IPv4 only by default — IPv6 onion service traffic still works
|
|
97
|
+
ClientUseIPv6 0
|
|
98
|
+
ClientPreferIPv6ORPort 0
|
|
99
|
+
|
|
100
|
+
# Avoid filesystem races on shared volumes
|
|
101
|
+
AvoidDiskWrites 1
|
|
102
|
+
TORRC_EOF
|
|
103
|
+
|
|
104
|
+
# Append per-hidden-service stanzas. Each gets:
|
|
105
|
+
# - HiddenServiceVersion 3 (Ed25519, 56-char .onion)
|
|
106
|
+
# - HiddenServiceEnableIntroDoSDefense (DoS mitigation at intro layer)
|
|
107
|
+
# - HiddenServicePoWDefensesEnabled (PoW puzzles for clients)
|
|
108
|
+
echo "$OMNITRON_TOR_HIDDEN_SERVICES_JSON" | jq -c '.[]' | while IFS= read -r svc; do
|
|
109
|
+
name=$(printf '%s' "$svc" | jq -r .name)
|
|
110
|
+
vport=$(printf '%s' "$svc" | jq -r .virtualPort)
|
|
111
|
+
target=$(printf '%s' "$svc" | jq -r .target)
|
|
112
|
+
{
|
|
113
|
+
echo
|
|
114
|
+
echo "# --- Hidden service: $name ---"
|
|
115
|
+
echo "HiddenServiceDir /var/lib/tor/$name"
|
|
116
|
+
echo "HiddenServiceVersion 3"
|
|
117
|
+
echo "HiddenServiceEnableIntroDoSDefense 1"
|
|
118
|
+
echo "HiddenServicePoWDefensesEnabled 1"
|
|
119
|
+
echo "HiddenServicePort $vport $target"
|
|
120
|
+
} >> "$TORRC"
|
|
121
|
+
done
|
|
122
|
+
|
|
123
|
+
# Append any user-provided raw torrc lines.
|
|
124
|
+
if [ -n "\${OMNITRON_TOR_EXTRA_TORRC:-}" ]; then
|
|
125
|
+
printf '\\n# --- User-provided torrc additions ---\\n%s\\n' "$OMNITRON_TOR_EXTRA_TORRC" >> "$TORRC"
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
# Hidden service directories must be owned by the tor user with mode 0700,
|
|
129
|
+
# otherwise tor refuses to start. Re-apply on every boot in case the volume
|
|
130
|
+
# was created externally with different permissions.
|
|
131
|
+
chown -R tor:tor /var/lib/tor 2>/dev/null || true
|
|
132
|
+
chmod 700 /var/lib/tor
|
|
133
|
+
|
|
134
|
+
# Run tor as root and let it drop privileges via the 'User tor' directive.
|
|
135
|
+
# This avoids needing su-exec/gosu, which aren't in alpine by default.
|
|
136
|
+
exec tor -f "$TORRC"
|
|
137
|
+
`;
|
|
138
|
+
export const torPreset = {
|
|
139
|
+
name: 'tor',
|
|
140
|
+
type: 'gateway',
|
|
141
|
+
defaultImage: 'alpine:3.20',
|
|
142
|
+
// No host-side ports: hidden services are reachable only via the Tor
|
|
143
|
+
// network. Exposing 9050 etc. would defeat the entire point.
|
|
144
|
+
defaultPorts: {},
|
|
145
|
+
defaultSecrets: {},
|
|
146
|
+
defaultHealthCheck: {
|
|
147
|
+
// Tor takes 30-90s to bootstrap an HS on first start. We watch for the
|
|
148
|
+
// hostname file to be written — that's the unambiguous signal that the
|
|
149
|
+
// hidden service has been published.
|
|
150
|
+
type: 'command',
|
|
151
|
+
target: 'pgrep tor >/dev/null && [ "$(ls /var/lib/tor 2>/dev/null | wc -l)" -gt 0 ] || exit 1',
|
|
152
|
+
interval: '15s',
|
|
153
|
+
timeout: '5s',
|
|
154
|
+
retries: 20,
|
|
155
|
+
startPeriod: '120s',
|
|
156
|
+
},
|
|
157
|
+
defaultDocker: {
|
|
158
|
+
command: ['sh', '-c', ENTRYPOINT_SHELL],
|
|
159
|
+
volumes: {
|
|
160
|
+
data: { source: '', target: '/var/lib/tor' },
|
|
161
|
+
},
|
|
162
|
+
// host-gateway lets the container reach host-bound services (vite dev
|
|
163
|
+
// server, omnitron-nginx published port) on every platform.
|
|
164
|
+
extraHosts: ['host.docker.internal:host-gateway'],
|
|
165
|
+
environment: {
|
|
166
|
+
// Default torrc has tor user; keep umask tight on key files.
|
|
167
|
+
UMASK: '077',
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
generateEnvTemplates() {
|
|
171
|
+
// No app-facing env: backends remain agnostic to whether they're being
|
|
172
|
+
// accessed via Tor or directly. Use `omnitron tor` to inspect onions.
|
|
173
|
+
return {};
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
//# sourceMappingURL=tor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tor.js","sourceRoot":"","sources":["../../../src/infrastructure/presets/tor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAyBH;;;;;;;GAOG;AACH,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4ExB,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAmB;IACvC,IAAI,EAAE,KAAK;IACX,IAAI,EAAE,SAAS;IACf,YAAY,EAAE,aAAa;IAC3B,qEAAqE;IACrE,6DAA6D;IAC7D,YAAY,EAAE,EAAE;IAChB,cAAc,EAAE,EAAE;IAElB,kBAAkB,EAAE;QAClB,uEAAuE;QACvE,uEAAuE;QACvE,qCAAqC;QACrC,IAAI,EAAE,SAAS;QACf,MAAM,EACJ,sFAAsF;QACxF,QAAQ,EAAE,KAAK;QACf,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,MAAM;KACpB;IAED,aAAa,EAAE;QACb,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,gBAAgB,CAAC;QACvC,OAAO,EAAE;YACP,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE;SAC7C;QACD,sEAAsE;QACtE,4DAA4D;QAC5D,UAAU,EAAE,CAAC,mCAAmC,CAAC;QACjD,WAAW,EAAE;YACX,6DAA6D;YAC7D,KAAK,EAAE,KAAK;SACb;KACF;IAED,oBAAoB;QAClB,uEAAuE;QACvE,sEAAsE;QACtE,OAAO,EAAE,CAAC;IACZ,CAAC;CACF,CAAC"}
|
|
@@ -12,6 +12,37 @@ import type { InfrastructureConfig, GatewayServiceConfig, ResolvedContainer, ISe
|
|
|
12
12
|
export declare function setContainerPrefix(project: string, env: string): void;
|
|
13
13
|
/** Get current prefix */
|
|
14
14
|
export declare function getContainerPrefix(): string;
|
|
15
|
+
/**
|
|
16
|
+
* Convention-derived managed network name.
|
|
17
|
+
*
|
|
18
|
+
* Every container provisioned by omnitron lives on a named bridge network
|
|
19
|
+
* (instead of docker's default `bridge`). This is the central piece that
|
|
20
|
+
* eliminates a whole class of failures we observed in production:
|
|
21
|
+
*
|
|
22
|
+
* - Docker's default `bridge` accumulates **phantom endpoint records**
|
|
23
|
+
* after dockerd restarts (host sleep/wake on macOS, dockerd crash).
|
|
24
|
+
* Recreating any container by name then fails with
|
|
25
|
+
* `endpoint with name X already exists in network bridge` — and
|
|
26
|
+
* `docker network disconnect -f bridge X` reports "not found" because
|
|
27
|
+
* the endpoint is dangling in dockerd's internal state, not actually
|
|
28
|
+
* attached. A named network has no such global pollution; if it gets
|
|
29
|
+
* corrupted we can blow it away and rebuild it without touching every
|
|
30
|
+
* other container on the host.
|
|
31
|
+
* - Inter-service DNS-by-name only works on named networks, so apps that
|
|
32
|
+
* need to reach `postgres:5432` from another container can do so
|
|
33
|
+
* without leaking host ports.
|
|
34
|
+
*
|
|
35
|
+
* Convention `${project}_default` matches what docker-compose creates by
|
|
36
|
+
* default for `${project}` → seamless coexistence with compose-managed
|
|
37
|
+
* adjacent infrastructure.
|
|
38
|
+
*/
|
|
39
|
+
export declare function getManagedNetwork(): string;
|
|
40
|
+
/**
|
|
41
|
+
* Stamp the managed network onto a container spec when it doesn't already
|
|
42
|
+
* declare one. Centralised so every resolver — preset and built-in alike —
|
|
43
|
+
* gets the same defaults without each having to remember.
|
|
44
|
+
*/
|
|
45
|
+
export declare function applyManagedDefaults(spec: ResolvedContainer): ResolvedContainer;
|
|
15
46
|
/** Set stack labels for subsequent container creation calls */
|
|
16
47
|
export declare function setStackLabels(project: string, stack: string): void;
|
|
17
48
|
/** Clear stack labels (for internal/global containers) */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-resolver.d.ts","sourceRoot":"","sources":["../../src/infrastructure/service-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EAEnB,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AAepB,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAErE;AAED,yBAAyB;AACzB,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;
|
|
1
|
+
{"version":3,"file":"service-resolver.d.ts","sourceRoot":"","sources":["../../src/infrastructure/service-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EAEnB,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AAepB,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAErE;AAED,yBAAyB;AACzB,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,GAAG,iBAAiB,CAG/E;AASD,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAOnE;AAED,0DAA0D;AAC1D,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAWD;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,mBAAmB,EAChC,QAAQ,CAAC,EAAE,gBAAgB,EAC3B,OAAO,CAAC,EAAE,MAAM,GACf,iBAAiB,GAAG,IAAI,CAyE1B;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,EACnD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAC5C,OAAO,CAAC,EAAE,MAAM,GACf,iBAAiB,EAAE,CA0BrB;AAiFD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,iBAAiB,CAuCpB;AAMD;;;;;;;GAOG;AACH;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,oBAAoB,EAC5B,WAAW,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EAC1E,WAAW,EAAE,MAAM,GAClB,iBAAiB,CAgEnB;AAMD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,iBAAiB,CAwCpB;AAMD;;;;;;;;GAQG;AACH;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,oBAAoB,EAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,GACvD,iBAAiB,EAAE,CAKrB"}
|