cyberia 3.2.12 → 3.2.70

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.
Files changed (194) hide show
  1. package/.env.example +127 -68
  2. package/.github/workflows/cyberia-client.cd.yml +40 -0
  3. package/.github/workflows/cyberia-server.cd.yml +40 -0
  4. package/.github/workflows/docker-image.cyberia-client.ci.yml +49 -0
  5. package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +48 -0
  6. package/.github/workflows/docker-image.cyberia-server.ci.yml +69 -0
  7. package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +69 -0
  8. package/.github/workflows/docker-image.engine-cyberia.ci.yml +52 -0
  9. package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +52 -0
  10. package/.github/workflows/engine-cyberia.cd.yml +34 -24
  11. package/.github/workflows/engine-cyberia.ci.yml +27 -5
  12. package/.github/workflows/ghpkg.ci.yml +89 -1
  13. package/.github/workflows/gitlab.ci.yml +1 -1
  14. package/.github/workflows/hardhat.ci.yml +1 -1
  15. package/.github/workflows/npmpkg.ci.yml +19 -12
  16. package/.github/workflows/publish.ci.yml +2 -2
  17. package/.github/workflows/publish.cyberia.ci.yml +5 -16
  18. package/.github/workflows/pwa-microservices-template-page.cd.yml +1 -8
  19. package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
  20. package/CHANGELOG.md +451 -1
  21. package/CLI-HELP.md +1040 -1130
  22. package/Dockerfile +141 -43
  23. package/Dockerfile.dev +143 -0
  24. package/Dockerfile.test +165 -0
  25. package/README.md +1 -1
  26. package/baremetal/commission-workflows.json +1 -0
  27. package/bin/build.js +128 -136
  28. package/bin/build.template.js +25 -179
  29. package/bin/cyberia.js +1089 -188
  30. package/bin/deploy.js +6 -3
  31. package/bin/index.js +1089 -188
  32. package/bump.config.js +1 -0
  33. package/compose.env +131 -0
  34. package/conf.js +19 -1
  35. package/deployment.yaml +74 -2
  36. package/docker-compose.yml +316 -0
  37. package/hardhat/hardhat.config.js +2 -2
  38. package/hardhat/package-lock.json +620 -2041
  39. package/hardhat/package.json +7 -5
  40. package/hardhat/scripts/deployObjectLayerToken.js +18 -18
  41. package/hardhat/test/ObjectLayerToken.js +378 -274
  42. package/ipfs/configure-ipfs.sh +13 -0
  43. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +2 -2
  44. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
  45. package/manifests/deployment/dd-cyberia-development/deployment.yaml +74 -2
  46. package/manifests/deployment/dd-cyberia-development/grpc-service.yaml +17 -0
  47. package/manifests/deployment/dd-cyberia-development/pv-pvc.yaml +32 -0
  48. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  49. package/mongodb/entrypoint.sh +76 -0
  50. package/nginx.conf +87 -0
  51. package/package.json +34 -22
  52. package/pv-pvc.yaml +32 -0
  53. package/scripts/disk-clean.sh +85 -60
  54. package/scripts/kubeadm-node-setup.sh +317 -0
  55. package/scripts/link-local-underpost-cli.sh +6 -0
  56. package/scripts/rocky-kickstart.sh +877 -185
  57. package/scripts/rpmfusion-ffmpeg-setup.sh +26 -50
  58. package/scripts/test-monitor.sh +248 -0
  59. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +43 -7
  60. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +17 -25
  61. package/src/api/cyberia-action/cyberia-action.controller.js +19 -0
  62. package/src/api/cyberia-action/cyberia-action.model.js +21 -29
  63. package/src/api/cyberia-action/cyberia-action.router.js +42 -7
  64. package/src/api/cyberia-action/cyberia-action.service.js +20 -4
  65. package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +58 -57
  66. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +37 -6
  67. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +8 -2
  68. package/src/api/cyberia-entity/cyberia-entity.router.js +39 -7
  69. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +74 -0
  70. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.model.js +67 -0
  71. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +63 -0
  72. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +46 -0
  73. package/src/api/cyberia-instance/cyberia-fallback-world.js +62 -10
  74. package/src/api/cyberia-instance/cyberia-instance.model.js +32 -2
  75. package/src/api/cyberia-instance/cyberia-instance.router.js +6 -6
  76. package/src/api/cyberia-instance/cyberia-world-generator.js +116 -3
  77. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +3 -0
  78. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +39 -7
  79. package/src/api/cyberia-map/cyberia-map.router.js +21 -6
  80. package/src/api/cyberia-quest/cyberia-quest.controller.js +38 -0
  81. package/src/api/cyberia-quest/cyberia-quest.router.js +47 -7
  82. package/src/api/cyberia-quest/cyberia-quest.service.js +59 -4
  83. package/src/api/cyberia-saga/cyberia-saga.controller.js +74 -0
  84. package/src/api/cyberia-saga/cyberia-saga.model.js +59 -0
  85. package/src/api/cyberia-saga/cyberia-saga.router.js +63 -0
  86. package/src/api/cyberia-saga/cyberia-saga.service.js +42 -0
  87. package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +551 -122
  88. package/src/api/cyberia-skill/cyberia-skill.controller.js +74 -0
  89. package/src/api/cyberia-skill/cyberia-skill.model.js +50 -0
  90. package/src/api/cyberia-skill/cyberia-skill.router.js +63 -0
  91. package/src/api/cyberia-skill/cyberia-skill.service.js +42 -0
  92. package/src/api/ipfs/ipfs.service.js +28 -15
  93. package/src/api/object-layer/object-layer.router.js +25 -15
  94. package/src/api/object-layer/object-layer.service.js +15 -20
  95. package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +39 -7
  96. package/src/cli/baremetal.js +717 -16
  97. package/src/cli/cluster.js +80 -5
  98. package/src/cli/deploy.js +326 -292
  99. package/src/cli/docker-compose.js +648 -0
  100. package/src/cli/env.js +12 -6
  101. package/src/cli/fs.js +75 -30
  102. package/src/cli/image.js +187 -55
  103. package/src/cli/index.js +157 -6
  104. package/src/cli/kickstart.js +142 -20
  105. package/src/cli/monitor.js +387 -6
  106. package/src/cli/release.js +72 -15
  107. package/src/cli/repository.js +339 -40
  108. package/src/cli/run.js +678 -186
  109. package/src/cli/secrets.js +82 -48
  110. package/src/cli/ssh.js +234 -0
  111. package/src/cli/static.js +2 -2
  112. package/src/client/components/core/PanelForm.js +44 -44
  113. package/src/client/components/cyberia/ActionEngineCyberia.js +1867 -0
  114. package/src/client/components/cyberia/EntityEngineCyberia.js +585 -0
  115. package/src/client/components/cyberia/InstanceEngineCyberia.js +219 -13
  116. package/src/client/components/cyberia/MapEngineCyberia.js +154 -71
  117. package/src/client/components/cyberia/ObjectLayerEngineModal.js +40 -63
  118. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +34 -20
  119. package/src/client/components/cyberia/SharedDefaultsCyberia.js +195 -4
  120. package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +66 -0
  121. package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +8 -0
  122. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +8 -0
  123. package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +92 -20
  124. package/src/client/public/cyberia-docs/ARCHITECTURE.md +272 -50
  125. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +3 -3
  126. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +39 -22
  127. package/src/client/public/cyberia-docs/CYBERIA-LORE.md +88 -0
  128. package/src/client/public/cyberia-docs/CYBERIA-SAGA.md +394 -0
  129. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +28 -12
  130. package/src/client/public/cyberia-docs/CYBERIA.md +1 -1
  131. package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +27 -5
  132. package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
  133. package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
  134. package/src/client/services/cyberia-entity-type-default/cyberia-entity-type-default.service.js +99 -0
  135. package/src/client/services/cyberia-instance/cyberia-instance.management.js +2 -2
  136. package/src/client/services/cyberia-map/cyberia-map.management.js +2 -2
  137. package/src/client/services/cyberia-saga/cyberia-saga.service.js +99 -0
  138. package/src/client/services/cyberia-skill/cyberia-skill.service.js +99 -0
  139. package/src/client/services/object-layer/object-layer.management.js +6 -6
  140. package/src/{server → client-builder}/client-build-docs.js +15 -5
  141. package/src/{server → client-builder}/client-build-live.js +3 -3
  142. package/src/{server → client-builder}/client-build.js +25 -22
  143. package/src/{server → client-builder}/client-dev-server.js +3 -3
  144. package/src/{server → client-builder}/client-icons.js +2 -2
  145. package/src/{server → client-builder}/ssr.js +5 -5
  146. package/src/client.build.js +1 -3
  147. package/src/client.dev.js +1 -1
  148. package/src/db/mongo/MongoBootstrap.js +12 -12
  149. package/src/db/mongo/MongooseDB.js +2 -1
  150. package/src/grpc/cyberia/grpc-server.js +255 -70
  151. package/src/index.js +12 -1
  152. package/src/mailer/EmailRender.js +1 -1
  153. package/src/{server → projects/cyberia}/atlas-sprite-sheet-generator.js +2 -2
  154. package/src/{server → projects/cyberia}/besu-genesis-generator.js +3 -3
  155. package/src/projects/cyberia/catalog-cyberia.js +81 -0
  156. package/src/projects/cyberia/gemini-client.js +175 -0
  157. package/src/projects/cyberia/generate-saga.js +2107 -0
  158. package/src/{server → projects/cyberia}/ipfs-client.js +6 -4
  159. package/src/{server → projects/cyberia}/object-layer.js +12 -108
  160. package/src/{server → projects/cyberia}/semantic-layer-generator-floor.js +1 -1
  161. package/src/{server → projects/cyberia}/semantic-layer-generator-resource.js +1 -1
  162. package/src/{server → projects/cyberia}/semantic-layer-generator-skin.js +1 -1
  163. package/src/{server → projects/cyberia}/semantic-layer-generator.js +2 -2
  164. package/src/{server → projects/cyberia}/shape-generator.js +2 -2
  165. package/src/projects/underpost/catalog-underpost.js +60 -0
  166. package/src/runtime/cyberia-client/Dockerfile +31 -83
  167. package/src/runtime/cyberia-client/Dockerfile.dev +23 -30
  168. package/src/runtime/cyberia-server/Dockerfile +23 -42
  169. package/src/runtime/cyberia-server/Dockerfile.dev +20 -35
  170. package/src/runtime/engine-cyberia/Dockerfile +143 -0
  171. package/src/runtime/engine-cyberia/Dockerfile.dev +143 -0
  172. package/src/runtime/engine-cyberia/Dockerfile.test +165 -0
  173. package/src/runtime/engine-cyberia/compose.env +131 -0
  174. package/src/runtime/engine-cyberia/docker-compose.yml +316 -0
  175. package/src/runtime/engine-cyberia/ipfs/configure-ipfs.sh +13 -0
  176. package/src/runtime/engine-cyberia/mongodb/entrypoint.sh +76 -0
  177. package/src/runtime/engine-cyberia/nginx.conf +87 -0
  178. package/src/runtime/express/Express.js +2 -2
  179. package/src/runtime/nginx/Nginx.js +250 -0
  180. package/src/runtime/wp/Dockerfile +3 -3
  181. package/src/server/catalog.js +72 -0
  182. package/src/server/conf.js +415 -60
  183. package/src/server/runtime-status.js +252 -0
  184. package/src/server/start.js +42 -11
  185. package/src/server.js +6 -2
  186. package/test/cyberia-instance-conf-defaults.test.js +140 -0
  187. package/test/deploy-monitor.test.js +267 -0
  188. package/test/shape-generator.test.js +7 -1
  189. package/typedoc.dd-cyberia.json +3 -1
  190. package/typedoc.json +3 -1
  191. package/manifests/deployment/dd-test-development/deployment.yaml +0 -256
  192. package/manifests/deployment/dd-test-development/proxy.yaml +0 -102
  193. /package/src/client/ssr/{Render.js → RootDocument.js} +0 -0
  194. /package/src/{server → client-builder}/client-formatted.js +0 -0
@@ -0,0 +1,267 @@
1
+ /**
2
+ * @module deploy-monitor.test
3
+ * @description End-to-end test of the two-phase deployment readiness contract
4
+ * between the in-pod runtime (`start.js` / `runtime-status.js`) and the CD-runner
5
+ * monitor (`Underpost.monitor.monitorReadyRunner`), exercised as real OS
6
+ * processes coordinating through the shared underpost env file and a real HTTP
7
+ * internal status endpoint.
8
+ *
9
+ * Contract under test:
10
+ *
11
+ * - The in-pod runtime publishes only `container-status` (Phase 2) and serves
12
+ * it over `GET /_internal/status`. It never propagates an exit code.
13
+ *
14
+ * - monitorReadyRunner (CD runner) confirms BOTH phases before exiting 0:
15
+ * Phase 1 — Kubernetes pod `Ready` condition (kubectl get pod -o json).
16
+ * Phase 2 — runtime `running-deployment` read over HTTP via
17
+ * `kubectl port-forward` to the internal endpoint.
18
+ * It throws (→ exit 1) on explicit runtime `error`, and returns (→ exit 0)
19
+ * only once both phases are satisfied.
20
+ *
21
+ * The cluster surface is supplied by fake `sudo`/`kubectl` binaries on PATH:
22
+ * - `get pods` / `get pod -o json` report one pod whose Ready condition is
23
+ * driven by FAKE_POD_READY.
24
+ * - `port-forward` is a no-op sleep; the monitor's HTTP GET reaches a REAL
25
+ * internal status server bound in this test process (localPort == port),
26
+ * which reads the same env file the runtime writes.
27
+ *
28
+ * The env file is redirected under a temp `npm_config_prefix`, so the test
29
+ * needs no cluster, no root, and never touches the machine's global install.
30
+ *
31
+ * Uses 'chai' for assertions.
32
+ */
33
+
34
+ import { expect } from 'chai';
35
+ import fs from 'fs-extra';
36
+ import os from 'node:os';
37
+ import path from 'node:path';
38
+ import { fileURLToPath, pathToFileURL } from 'node:url';
39
+ import Underpost from '../src/index.js';
40
+ import { shellExec } from '../src/server/process.js';
41
+ import { startInternalStatusServer, stopInternalStatusServer } from '../src/server/runtime-status.js';
42
+
43
+ const node = process.execPath;
44
+ const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
45
+
46
+ const DEPLOY_ID = 'dd-test';
47
+ const ENV = 'production';
48
+ const TRAFFIC = 'green';
49
+ const POD_NAME = `${DEPLOY_ID}-${ENV}-${TRAFFIC}-pod`;
50
+ const RUNNING_STATUS = `${DEPLOY_ID}-${ENV}-running-deployment`;
51
+ const INIT_STATUS = `${DEPLOY_ID}-${ENV}-initializing-deployment`;
52
+ const BUILD_STATUS = `${DEPLOY_ID}-${ENV}-build-deployment`;
53
+
54
+ const INTERNAL_PORT = 39517; // internal status endpoint (real server bound here)
55
+ const CLOSED_PORT = 39518; // no server — used to force a transport failure
56
+
57
+ describe('Deploy monitor — two-phase state machine (e2e, real HTTP transport)', function () {
58
+ this.timeout(60000);
59
+
60
+ let prevPrefix;
61
+ let tmpPrefix;
62
+ let fakeBinDir;
63
+ let envFile;
64
+ let monitorScriptPath;
65
+
66
+ before(() => {
67
+ prevPrefix = process.env.npm_config_prefix;
68
+ tmpPrefix = fs.mkdtempSync(path.join(os.tmpdir(), 'underpost-e2e-'));
69
+ process.env.npm_config_prefix = tmpPrefix;
70
+
71
+ Underpost.env.set('container-status', 'init');
72
+ Underpost.env.set('start-container-status', '');
73
+ const npmRoot = shellExec('npm root -g', { stdout: true, silent: true, disableLog: true }).trim();
74
+ envFile = path.join(npmRoot, 'underpost', '.env');
75
+
76
+ process.env.UNDERPOST_INTERNAL_PORT = String(INTERNAL_PORT);
77
+ startInternalStatusServer(INTERNAL_PORT);
78
+
79
+ fakeBinDir = path.join(tmpPrefix, 'fakebin');
80
+ fs.ensureDirSync(fakeBinDir);
81
+
82
+ const sudoPath = path.join(fakeBinDir, 'sudo');
83
+ fs.writeFileSync(
84
+ sudoPath,
85
+ `#!/usr/bin/env bash
86
+ while [[ "$1" == -* || "$1" == "--" ]]; do shift; done
87
+ exec "$@"
88
+ `,
89
+ );
90
+
91
+ const kubectlPath = path.join(fakeBinDir, 'kubectl');
92
+ fs.writeFileSync(
93
+ kubectlPath,
94
+ `#!/usr/bin/env bash
95
+ verb="$1"; kind="$2"
96
+ if [[ "$verb" == "get" && "$kind" == "pods" ]]; then
97
+ printf 'NAME READY STATUS RESTARTS AGE\\n'
98
+ printf '%s 1/1 Running 0 1m\\n' "$POD_NAME"
99
+ exit 0
100
+ fi
101
+ if [[ "$verb" == "get" && "$kind" == "pod" ]]; then
102
+ printf '{"status":{"conditions":[{"type":"Ready","status":"%s"}]}}\\n' "\${FAKE_POD_READY:-True}"
103
+ exit 0
104
+ fi
105
+ if [[ "$verb" == "port-forward" ]]; then
106
+ sleep 30
107
+ exit 0
108
+ fi
109
+ if [[ "$verb" == "exec" ]]; then
110
+ grep -E '^container-status=' "$UNDERPOST_ENV_FILE" 2>/dev/null | tail -n1 | sed -E 's/^container-status=//'
111
+ exit 0
112
+ fi
113
+ exit 0
114
+ `,
115
+ );
116
+ fs.chmodSync(sudoPath, 0o755);
117
+ fs.chmodSync(kubectlPath, 0o755);
118
+
119
+ monitorScriptPath = path.join(tmpPrefix, 'monitor-ready.mjs');
120
+ fs.writeFileSync(
121
+ monitorScriptPath,
122
+ `import Underpost from ${JSON.stringify(pathToFileURL(path.join(repoRoot, 'src/index.js')).href)};
123
+ const options = {};
124
+ if (process.env.MON_READY_GATE) options.readyGate = process.env.MON_READY_GATE;
125
+ if (process.env.MON_TRANSPORT) options.statusTransport = process.env.MON_TRANSPORT;
126
+ try {
127
+ await Underpost.monitor.monitorReadyRunner(${JSON.stringify(DEPLOY_ID)}, ${JSON.stringify(ENV)}, ${JSON.stringify(
128
+ TRAFFIC,
129
+ )}, [], 'default', options);
130
+ process.exit(0);
131
+ } catch (_) {
132
+ process.exit(1);
133
+ }
134
+ `,
135
+ );
136
+ });
137
+
138
+ after(async () => {
139
+ await stopInternalStatusServer();
140
+ delete process.env.UNDERPOST_INTERNAL_PORT;
141
+ if (prevPrefix === undefined) delete process.env.npm_config_prefix;
142
+ else process.env.npm_config_prefix = prevPrefix;
143
+ fs.removeSync(tmpPrefix);
144
+ });
145
+
146
+ beforeEach(() => {
147
+ // Deploy in flight: app not yet reporting running.
148
+ Underpost.env.set('container-status', INIT_STATUS);
149
+ // start-container-status is unset (empty) — the readinessProbe
150
+ // sees 503 until the start pipeline completes and stamps this key.
151
+ Underpost.env.set('start-container-status', '');
152
+ });
153
+
154
+ const spawnMonitor = (overrides = {}) =>
155
+ new Promise((resolve) => {
156
+ const envVars = {
157
+ PATH: `${fakeBinDir}:${process.env.PATH}`,
158
+ UNDERPOST_ENV_FILE: envFile,
159
+ POD_NAME,
160
+ npm_config_prefix: tmpPrefix,
161
+ UNDERPOST_INTERNAL_PORT: String(INTERNAL_PORT),
162
+ UNDERPOST_PF_LOCAL_PORT: String(INTERNAL_PORT),
163
+ UNDERPOST_MONITOR_DELAY_MS: '100',
164
+ UNDERPOST_MONITOR_MAX_ITERATIONS: '60',
165
+ UNDERPOST_PF_ATTEMPTS: '3',
166
+ FAKE_POD_READY: 'True',
167
+ ...overrides,
168
+ };
169
+ const prefix = Object.entries(envVars)
170
+ .map(([k, v]) => `${k}="${v}"`)
171
+ .join(' ');
172
+ shellExec(`${prefix} ${node} ${monitorScriptPath}`, {
173
+ async: true,
174
+ silent: true,
175
+ disableLog: true,
176
+ callback: (code) => resolve(code),
177
+ });
178
+ });
179
+
180
+ it('success (default exec transport): both phases satisfied → monitor exits 0', async () => {
181
+ Underpost.env.set('container-status', RUNNING_STATUS);
182
+ // start-container-status not needed for monitor (reads container-status);
183
+ // this test exercises the default exec transport path.
184
+ const code = await spawnMonitor({ FAKE_POD_READY: 'True' });
185
+ expect(code).to.equal(0);
186
+ });
187
+
188
+ it('success (opt-in http transport): both phases satisfied → monitor exits 0', async () => {
189
+ Underpost.env.set('container-status', RUNNING_STATUS);
190
+ Underpost.env.set('start-container-status', RUNNING_STATUS);
191
+ const code = await spawnMonitor({ FAKE_POD_READY: 'True', MON_TRANSPORT: 'http' });
192
+ expect(code).to.equal(0);
193
+ });
194
+
195
+ it('runtime failure: container-status=error → monitor exits 1', async () => {
196
+ const monitorExit = spawnMonitor({ FAKE_POD_READY: 'True' });
197
+ Underpost.env.set('container-status', 'error');
198
+ expect(await monitorExit).to.equal(1);
199
+ });
200
+
201
+ it('readiness mismatch: runtime running but pod not Ready → never succeeds (exits 1)', async () => {
202
+ // Phase 2 satisfied, Phase 1 not: success requires BOTH, so it must time out.
203
+ Underpost.env.set('container-status', RUNNING_STATUS);
204
+ // start-container-status is NOT set — the readinessProbe would fail,
205
+ // but the monitor only checks container-status via exec/http transport.
206
+ const code = await spawnMonitor({ FAKE_POD_READY: 'False', UNDERPOST_MONITOR_MAX_ITERATIONS: '4' });
207
+ expect(code).to.equal(1);
208
+ });
209
+
210
+ it('transport failure (http): endpoint unreachable is never success (exits 1)', async () => {
211
+ Underpost.env.set('container-status', RUNNING_STATUS);
212
+ const code = await spawnMonitor({
213
+ MON_TRANSPORT: 'http',
214
+ UNDERPOST_INTERNAL_PORT: String(CLOSED_PORT),
215
+ UNDERPOST_PF_LOCAL_PORT: String(CLOSED_PORT),
216
+ UNDERPOST_MONITOR_MAX_ITERATIONS: '3',
217
+ });
218
+ expect(code).to.equal(1);
219
+ });
220
+
221
+ it('timeout: runtime stuck initializing → monitor exits 1', async () => {
222
+ Underpost.env.set('container-status', INIT_STATUS);
223
+ // start-container-status remains unset — readinessProbe returns 503
224
+ // (correct, since the runtime is still initializing).
225
+ const code = await spawnMonitor({ FAKE_POD_READY: 'True', UNDERPOST_MONITOR_MAX_ITERATIONS: '4' });
226
+ expect(code).to.equal(1);
227
+ });
228
+
229
+ it('regression: advanced pod whose runtime status falls back → monitor exits 1', async () => {
230
+ // Pod advances past build, then its reported status regresses (pod restart);
231
+ // the monitor must treat this as a failure rather than wait it out.
232
+ Underpost.env.set('container-status', INIT_STATUS);
233
+ const monitorExit = spawnMonitor({ FAKE_POD_READY: 'False', UNDERPOST_MONITOR_MAX_ITERATIONS: '120' });
234
+ await new Promise((r) => setTimeout(r, 1500));
235
+ Underpost.env.set('container-status', BUILD_STATUS);
236
+ expect(await monitorExit).to.equal(1);
237
+ });
238
+
239
+ it('readinessProbe: start-container-status set → returns 200 (probe passes)', async () => {
240
+ Underpost.env.set('start-container-status', RUNNING_STATUS);
241
+ const res = await fetch(`http://127.0.0.1:${INTERNAL_PORT}/_internal/ready`);
242
+ expect(res.status).to.equal(200);
243
+ const body = await res.json();
244
+ expect(body.status).to.equal('running-deployment');
245
+ });
246
+
247
+ it('readinessProbe: start-container-status unset → returns 503 (probe fails)', async () => {
248
+ // Unset from beforeEach re-stamp; clear it.
249
+ Underpost.env.set('start-container-status', '');
250
+ const res = await fetch(`http://127.0.0.1:${INTERNAL_PORT}/_internal/ready`);
251
+ expect(res.status).to.equal(503);
252
+ });
253
+
254
+ // Custom instances (cyberia-*) gate on K8s Ready and read status via exec;
255
+ // their runtime never stamps `running-deployment` (stays `initializing`).
256
+ it('instance (kubernetes gate + exec): K8s Ready with initializing status → exits 0', async () => {
257
+ Underpost.env.set('container-status', INIT_STATUS);
258
+ const code = await spawnMonitor({ FAKE_POD_READY: 'True', MON_READY_GATE: 'kubernetes', MON_TRANSPORT: 'exec' });
259
+ expect(code).to.equal(0);
260
+ });
261
+
262
+ it('instance (kubernetes gate + exec): container-status=error → exits 1', async () => {
263
+ const monitorExit = spawnMonitor({ FAKE_POD_READY: 'True', MON_READY_GATE: 'kubernetes', MON_TRANSPORT: 'exec' });
264
+ Underpost.env.set('container-status', 'error');
265
+ expect(await monitorExit).to.equal(1);
266
+ });
267
+ });
@@ -6,7 +6,13 @@
6
6
  */
7
7
 
8
8
  import { expect } from 'chai';
9
- import { generateShape, registerShape, listShapes, toPixelCoords, renderGrid } from '../src/server/shape-generator.js';
9
+ import {
10
+ generateShape,
11
+ registerShape,
12
+ listShapes,
13
+ toPixelCoords,
14
+ renderGrid,
15
+ } from '../src/projects/cyberia/shape-generator.js';
10
16
 
11
17
  describe('Shape Generator Module Tests', () => {
12
18
  // --- Deterministic Seed Tests ---
@@ -8,7 +8,9 @@
8
8
  "./src/ws",
9
9
  "./src/grpc",
10
10
  "./src/mailer",
11
- "./src/runtime"
11
+ "./src/runtime",
12
+ "./src/client-builder",
13
+ "./src/projects/cyberia"
12
14
  ],
13
15
  "entryPointStrategy": "expand",
14
16
  "exclude": ["**/node_modules/**", "**/docs/**", "**/client/**", "**/hardhat/**"],
package/typedoc.json CHANGED
@@ -8,7 +8,9 @@
8
8
  "./src/ws",
9
9
  "./src/grpc",
10
10
  "./src/mailer",
11
- "./src/runtime"
11
+ "./src/runtime",
12
+ "./src/client-builder",
13
+ "./src/projects/cyberia"
12
14
  ],
13
15
  "entryPointStrategy": "expand",
14
16
  "exclude": ["**/node_modules/**", "**/docs/**", "**/client/**", "**/hardhat/**"],
@@ -1,256 +0,0 @@
1
- ---
2
- apiVersion: apps/v1
3
- kind: Deployment
4
- metadata:
5
- name: dd-test-development-blue
6
- namespace: default
7
- labels:
8
- app: dd-test-development-blue
9
- deploy-id: dd-test-development
10
- spec:
11
- replicas: 1
12
- selector:
13
- matchLabels:
14
- app: dd-test-development-blue
15
- template:
16
- metadata:
17
- labels:
18
- app: dd-test-development-blue
19
- deploy-id: dd-test-development
20
- spec:
21
- containers:
22
- - name: dd-test-development-blue
23
- image: underpost/underpost-engine:v3.2.12
24
- imagePullPolicy: IfNotPresent
25
- envFrom:
26
- - secretRef:
27
- name: underpost-config
28
-
29
- command:
30
- - /bin/sh
31
- - -c
32
- - >
33
- underpost secret underpost --create-from-env &&
34
- underpost start --build --run dd-test development
35
-
36
-
37
-
38
- ---
39
- apiVersion: v1
40
- kind: Service
41
- metadata:
42
- name: dd-test-development-blue-service
43
- namespace: default
44
- spec:
45
- selector:
46
- app: dd-test-development-blue
47
- ports:
48
- - name: 'tcp-4033'
49
- protocol: TCP
50
- port: 4033
51
- targetPort: 4033
52
- - name: 'udp-4033'
53
- protocol: UDP
54
- port: 4033
55
- targetPort: 4033
56
-
57
- - name: 'tcp-4034'
58
- protocol: TCP
59
- port: 4034
60
- targetPort: 4034
61
- - name: 'udp-4034'
62
- protocol: UDP
63
- port: 4034
64
- targetPort: 4034
65
-
66
- - name: 'tcp-4035'
67
- protocol: TCP
68
- port: 4035
69
- targetPort: 4035
70
- - name: 'udp-4035'
71
- protocol: UDP
72
- port: 4035
73
- targetPort: 4035
74
-
75
- - name: 'tcp-4036'
76
- protocol: TCP
77
- port: 4036
78
- targetPort: 4036
79
- - name: 'udp-4036'
80
- protocol: UDP
81
- port: 4036
82
- targetPort: 4036
83
-
84
- - name: 'tcp-4037'
85
- protocol: TCP
86
- port: 4037
87
- targetPort: 4037
88
- - name: 'udp-4037'
89
- protocol: UDP
90
- port: 4037
91
- targetPort: 4037
92
-
93
- - name: 'tcp-4038'
94
- protocol: TCP
95
- port: 4038
96
- targetPort: 4038
97
- - name: 'udp-4038'
98
- protocol: UDP
99
- port: 4038
100
- targetPort: 4038
101
-
102
- - name: 'tcp-4039'
103
- protocol: TCP
104
- port: 4039
105
- targetPort: 4039
106
- - name: 'udp-4039'
107
- protocol: UDP
108
- port: 4039
109
- targetPort: 4039
110
-
111
- - name: 'tcp-4040'
112
- protocol: TCP
113
- port: 4040
114
- targetPort: 4040
115
- - name: 'udp-4040'
116
- protocol: UDP
117
- port: 4040
118
- targetPort: 4040
119
-
120
- - name: 'tcp-4041'
121
- protocol: TCP
122
- port: 4041
123
- targetPort: 4041
124
- - name: 'udp-4041'
125
- protocol: UDP
126
- port: 4041
127
- targetPort: 4041
128
- type: LoadBalancer
129
- ---
130
- apiVersion: apps/v1
131
- kind: Deployment
132
- metadata:
133
- name: dd-test-development-green
134
- namespace: default
135
- labels:
136
- app: dd-test-development-green
137
- deploy-id: dd-test-development
138
- spec:
139
- replicas: 1
140
- selector:
141
- matchLabels:
142
- app: dd-test-development-green
143
- template:
144
- metadata:
145
- labels:
146
- app: dd-test-development-green
147
- deploy-id: dd-test-development
148
- spec:
149
- containers:
150
- - name: dd-test-development-green
151
- image: underpost/underpost-engine:v3.2.12
152
- imagePullPolicy: IfNotPresent
153
- envFrom:
154
- - secretRef:
155
- name: underpost-config
156
-
157
- command:
158
- - /bin/sh
159
- - -c
160
- - >
161
- underpost secret underpost --create-from-env &&
162
- underpost start --build --run dd-test development
163
-
164
-
165
-
166
- ---
167
- apiVersion: v1
168
- kind: Service
169
- metadata:
170
- name: dd-test-development-green-service
171
- namespace: default
172
- spec:
173
- selector:
174
- app: dd-test-development-green
175
- ports:
176
- - name: 'tcp-4033'
177
- protocol: TCP
178
- port: 4033
179
- targetPort: 4033
180
- - name: 'udp-4033'
181
- protocol: UDP
182
- port: 4033
183
- targetPort: 4033
184
-
185
- - name: 'tcp-4034'
186
- protocol: TCP
187
- port: 4034
188
- targetPort: 4034
189
- - name: 'udp-4034'
190
- protocol: UDP
191
- port: 4034
192
- targetPort: 4034
193
-
194
- - name: 'tcp-4035'
195
- protocol: TCP
196
- port: 4035
197
- targetPort: 4035
198
- - name: 'udp-4035'
199
- protocol: UDP
200
- port: 4035
201
- targetPort: 4035
202
-
203
- - name: 'tcp-4036'
204
- protocol: TCP
205
- port: 4036
206
- targetPort: 4036
207
- - name: 'udp-4036'
208
- protocol: UDP
209
- port: 4036
210
- targetPort: 4036
211
-
212
- - name: 'tcp-4037'
213
- protocol: TCP
214
- port: 4037
215
- targetPort: 4037
216
- - name: 'udp-4037'
217
- protocol: UDP
218
- port: 4037
219
- targetPort: 4037
220
-
221
- - name: 'tcp-4038'
222
- protocol: TCP
223
- port: 4038
224
- targetPort: 4038
225
- - name: 'udp-4038'
226
- protocol: UDP
227
- port: 4038
228
- targetPort: 4038
229
-
230
- - name: 'tcp-4039'
231
- protocol: TCP
232
- port: 4039
233
- targetPort: 4039
234
- - name: 'udp-4039'
235
- protocol: UDP
236
- port: 4039
237
- targetPort: 4039
238
-
239
- - name: 'tcp-4040'
240
- protocol: TCP
241
- port: 4040
242
- targetPort: 4040
243
- - name: 'udp-4040'
244
- protocol: UDP
245
- port: 4040
246
- targetPort: 4040
247
-
248
- - name: 'tcp-4041'
249
- protocol: TCP
250
- port: 4041
251
- targetPort: 4041
252
- - name: 'udp-4041'
253
- protocol: UDP
254
- port: 4041
255
- targetPort: 4041
256
- type: LoadBalancer
@@ -1,102 +0,0 @@
1
-
2
- ---
3
- apiVersion: projectcontour.io/v1
4
- kind: HTTPProxy
5
- metadata:
6
- name: test.nexodev.org
7
- namespace: default
8
- spec:
9
- virtualhost:
10
- fqdn: test.nexodev.org
11
- routes:
12
- - conditions:
13
- - prefix: /wp
14
-
15
- enableWebsockets: true
16
- services:
17
- - name: dd-test-development-blue-service
18
- port: 4033
19
- weight: 100
20
-
21
- - conditions:
22
- - prefix: /
23
-
24
- enableWebsockets: true
25
- services:
26
- - name: dd-test-development-blue-service
27
- port: 4034
28
- weight: 100
29
-
30
- - conditions:
31
- - prefix: /peer
32
-
33
- enableWebsockets: true
34
- services:
35
- - name: dd-test-development-blue-service
36
- port: 4035
37
- weight: 100
38
-
39
- - conditions:
40
- - prefix: /r1
41
-
42
- enableWebsockets: true
43
- services:
44
- - name: dd-test-development-blue-service
45
- port: 4036
46
- weight: 100
47
-
48
- - conditions:
49
- - prefix: /r1/peer
50
-
51
- enableWebsockets: true
52
- services:
53
- - name: dd-test-development-blue-service
54
- port: 4037
55
- weight: 100
56
-
57
- - conditions:
58
- - prefix: /r2
59
-
60
- enableWebsockets: true
61
- services:
62
- - name: dd-test-development-blue-service
63
- port: 4038
64
- weight: 100
65
-
66
- - conditions:
67
- - prefix: /r2/peer
68
-
69
- enableWebsockets: true
70
- services:
71
- - name: dd-test-development-blue-service
72
- port: 4039
73
- weight: 100
74
-
75
- ---
76
- apiVersion: projectcontour.io/v1
77
- kind: HTTPProxy
78
- metadata:
79
- name: stagging.nexodev.org
80
- namespace: default
81
- spec:
82
- virtualhost:
83
- fqdn: stagging.nexodev.org
84
- routes:
85
- - conditions:
86
- - prefix: /
87
-
88
- enableWebsockets: true
89
- services:
90
- - name: dd-test-development-blue-service
91
- port: 4040
92
- weight: 100
93
-
94
- - conditions:
95
- - prefix: /peer
96
-
97
- enableWebsockets: true
98
- services:
99
- - name: dd-test-development-blue-service
100
- port: 4041
101
- weight: 100
102
-
File without changes