cyberia 3.2.9 → 3.2.22

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 (184) hide show
  1. package/.github/workflows/engine-cyberia.cd.yml +7 -0
  2. package/.github/workflows/engine-cyberia.ci.yml +14 -2
  3. package/.github/workflows/ghpkg.ci.yml +1 -0
  4. package/.github/workflows/npmpkg.ci.yml +10 -5
  5. package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
  6. package/.github/workflows/release.cd.yml +1 -0
  7. package/.vscode/extensions.json +9 -9
  8. package/.vscode/settings.json +20 -4
  9. package/CHANGELOG.md +363 -1
  10. package/CLI-HELP.md +975 -1061
  11. package/README.md +190 -348
  12. package/bin/build.js +102 -125
  13. package/bin/build.template.js +33 -0
  14. package/bin/cyberia.js +238 -56
  15. package/bin/deploy.js +16 -3
  16. package/bin/index.js +238 -56
  17. package/bump.config.js +26 -0
  18. package/conf.js +131 -24
  19. package/deployment.yaml +76 -2
  20. package/hardhat/package-lock.json +113 -144
  21. package/hardhat/package.json +4 -3
  22. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +2 -2
  23. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
  24. package/manifests/deployment/dd-cyberia-development/deployment.yaml +76 -2
  25. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  26. package/manifests/kind-config-dev.yaml +8 -0
  27. package/manifests/lxd/lxd-admin-profile.yaml +12 -3
  28. package/manifests/mongodb/pv-pvc.yaml +44 -8
  29. package/manifests/mongodb/statefulset.yaml +55 -68
  30. package/manifests/mongodb-4.4/headless-service.yaml +10 -0
  31. package/manifests/mongodb-4.4/kustomization.yaml +3 -1
  32. package/manifests/mongodb-4.4/mongodb-nodeport.yaml +17 -0
  33. package/manifests/mongodb-4.4/pv-pvc.yaml +10 -14
  34. package/manifests/mongodb-4.4/statefulset.yaml +79 -0
  35. package/manifests/mongodb-4.4/storage-class.yaml +9 -0
  36. package/manifests/valkey/statefulset.yaml +1 -1
  37. package/manifests/valkey/valkey-nodeport.yaml +17 -0
  38. package/package.json +31 -19
  39. package/scripts/ipxe-setup.sh +52 -49
  40. package/scripts/k3s-node-setup.sh +81 -46
  41. package/scripts/link-local-underpost-cli.sh +6 -0
  42. package/scripts/lxd-vm-setup.sh +193 -8
  43. package/scripts/maas-nat-firewalld.sh +145 -0
  44. package/scripts/test-monitor.sh +250 -0
  45. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +38 -33
  46. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +16 -16
  47. package/src/api/core/core.router.js +19 -14
  48. package/src/api/core/core.service.js +5 -5
  49. package/src/api/crypto/crypto.router.js +18 -12
  50. package/src/api/crypto/crypto.service.js +3 -3
  51. package/src/api/cyberia-action/cyberia-action.model.js +1 -1
  52. package/src/api/cyberia-action/cyberia-action.router.js +22 -18
  53. package/src/api/cyberia-action/cyberia-action.service.js +5 -5
  54. package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +74 -0
  55. package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +99 -0
  56. package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +98 -0
  57. package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +152 -0
  58. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +25 -20
  59. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +6 -6
  60. package/src/api/cyberia-entity/cyberia-entity.router.js +22 -18
  61. package/src/api/cyberia-entity/cyberia-entity.service.js +5 -5
  62. package/src/api/cyberia-instance/cyberia-fallback-world.js +79 -4
  63. package/src/api/cyberia-instance/cyberia-instance.router.js +57 -52
  64. package/src/api/cyberia-instance/cyberia-instance.service.js +10 -10
  65. package/src/api/cyberia-instance/cyberia-world-generator.js +3 -3
  66. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +14 -48
  67. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +22 -18
  68. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +5 -5
  69. package/src/api/cyberia-map/cyberia-map.router.js +35 -30
  70. package/src/api/cyberia-map/cyberia-map.service.js +7 -7
  71. package/src/api/cyberia-quest/cyberia-quest.model.js +1 -1
  72. package/src/api/cyberia-quest/cyberia-quest.router.js +22 -18
  73. package/src/api/cyberia-quest/cyberia-quest.service.js +5 -5
  74. package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +22 -18
  75. package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +5 -5
  76. package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +458 -0
  77. package/src/api/default/default.router.js +22 -18
  78. package/src/api/default/default.service.js +5 -5
  79. package/src/api/document/document.router.js +28 -23
  80. package/src/api/document/document.service.js +100 -23
  81. package/src/api/file/file.router.js +19 -13
  82. package/src/api/file/file.service.js +9 -7
  83. package/src/api/instance/instance.router.js +29 -24
  84. package/src/api/instance/instance.service.js +6 -6
  85. package/src/api/ipfs/ipfs.router.js +21 -16
  86. package/src/api/ipfs/ipfs.service.js +8 -8
  87. package/src/api/object-layer/object-layer.router.js +512 -507
  88. package/src/api/object-layer/object-layer.service.js +17 -14
  89. package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +22 -18
  90. package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +5 -5
  91. package/src/api/test/test.router.js +17 -12
  92. package/src/api/types.js +24 -0
  93. package/src/api/user/guest.service.js +5 -4
  94. package/src/api/user/user.router.js +297 -288
  95. package/src/api/user/user.service.js +100 -35
  96. package/src/cli/baremetal.js +132 -101
  97. package/src/cli/cluster.js +700 -232
  98. package/src/cli/db.js +59 -60
  99. package/src/cli/deploy.js +291 -294
  100. package/src/cli/env.js +1 -4
  101. package/src/cli/fs.js +13 -3
  102. package/src/cli/image.js +58 -4
  103. package/src/cli/index.js +127 -15
  104. package/src/cli/ipfs.js +4 -6
  105. package/src/cli/kubectl.js +4 -1
  106. package/src/cli/lxd.js +1099 -223
  107. package/src/cli/monitor.js +396 -9
  108. package/src/cli/release.js +355 -146
  109. package/src/cli/repository.js +169 -30
  110. package/src/cli/run.js +347 -117
  111. package/src/cli/secrets.js +11 -2
  112. package/src/cli/test.js +9 -3
  113. package/src/client/Default.index.js +9 -3
  114. package/src/client/components/core/Auth.js +5 -0
  115. package/src/client/components/core/ClientEvents.js +76 -0
  116. package/src/client/components/core/EventBus.js +4 -0
  117. package/src/client/components/core/Modal.js +82 -41
  118. package/src/client/components/core/PanelForm.js +14 -10
  119. package/src/client/components/core/Worker.js +162 -363
  120. package/src/client/components/cyberia/MapEngineCyberia.js +1 -1
  121. package/src/client/components/cyberia/SharedDefaultsCyberia.js +330 -0
  122. package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +55 -1
  123. package/src/client/public/cyberia-docs/ARCHITECTURE.md +223 -361
  124. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +114 -327
  125. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +200 -222
  126. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +212 -185
  127. package/src/client/public/cyberia-docs/CYBERIA.md +259 -0
  128. package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +2 -2
  129. package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +23 -1
  130. package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
  131. package/src/client/public/cyberia-docs/UNDERPOST-PLATFORM.md +106 -0
  132. package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
  133. package/src/client/services/cyberia-client-hints/cyberia-client-hints.service.js +99 -0
  134. package/src/client/ssr/views/CyberiaServerMetrics.js +982 -0
  135. package/src/client/sw/core.sw.js +174 -112
  136. package/src/db/DataBaseProvider.js +115 -15
  137. package/src/db/mariadb/MariaDB.js +2 -1
  138. package/src/db/mongo/MongoBootstrap.js +657 -0
  139. package/src/db/mongo/MongooseDB.js +130 -21
  140. package/src/grpc/cyberia/grpc-server.js +25 -57
  141. package/src/index.js +1 -1
  142. package/src/runtime/cyberia-client/Dockerfile +10 -7
  143. package/src/runtime/cyberia-client/Dockerfile.dev +67 -0
  144. package/src/runtime/cyberia-server/Dockerfile +11 -6
  145. package/src/runtime/cyberia-server/Dockerfile.dev +47 -0
  146. package/src/runtime/express/Express.js +2 -2
  147. package/src/runtime/wp/Dockerfile +3 -3
  148. package/src/runtime/wp/Wp.js +8 -5
  149. package/src/server/auth.js +2 -2
  150. package/src/server/catalog-underpost.js +61 -0
  151. package/src/server/catalog.js +77 -0
  152. package/src/server/client-build-docs.js +1 -1
  153. package/src/server/client-build.js +94 -129
  154. package/src/server/conf.js +496 -135
  155. package/src/server/ipfs-client.js +5 -3
  156. package/src/server/process.js +180 -19
  157. package/src/server/proxy.js +9 -2
  158. package/src/server/runtime-status.js +235 -0
  159. package/src/server/runtime.js +1 -1
  160. package/src/server/start.js +44 -11
  161. package/src/server/valkey.js +2 -0
  162. package/src/ws/IoInterface.js +16 -16
  163. package/src/ws/core/channels/core.ws.chat.js +11 -11
  164. package/src/ws/core/channels/core.ws.mailer.js +29 -29
  165. package/src/ws/core/channels/core.ws.stream.js +19 -19
  166. package/src/ws/core/core.ws.connection.js +8 -8
  167. package/src/ws/core/core.ws.server.js +6 -5
  168. package/src/ws/default/channels/default.ws.main.js +10 -10
  169. package/src/ws/default/default.ws.connection.js +4 -4
  170. package/src/ws/default/default.ws.server.js +4 -3
  171. package/test/deploy-monitor.test.js +251 -0
  172. package/bin/file.js +0 -202
  173. package/bin/vs.js +0 -74
  174. package/bin/zed.js +0 -84
  175. package/manifests/deployment/dd-test-development/deployment.yaml +0 -254
  176. package/manifests/deployment/dd-test-development/proxy.yaml +0 -102
  177. package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +0 -574
  178. package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +0 -467
  179. package/src/client/ssr/email/DefaultRecoverEmail.js +0 -21
  180. package/src/client/ssr/email/DefaultVerifyEmail.js +0 -17
  181. package/src/client/ssr/pages/CyberiaServerMetrics.js +0 -461
  182. /package/src/client/ssr/{offline → views}/Maintenance.js +0 -0
  183. /package/src/client/ssr/{offline → views}/NoNetworkConnection.js +0 -0
  184. /package/src/client/ssr/{pages → views}/Test.js +0 -0
@@ -0,0 +1,251 @@
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
+ const npmRoot = shellExec('npm root -g', { stdout: true, silent: true, disableLog: true }).trim();
73
+ envFile = path.join(npmRoot, 'underpost', '.env');
74
+
75
+ // Real in-pod internal status server: serves container-status from the same
76
+ // env file the runtime writes. Bound in this test process; the monitor's
77
+ // port-forward tunnel (localPort == INTERNAL_PORT) resolves straight to it.
78
+ process.env.UNDERPOST_INTERNAL_PORT = String(INTERNAL_PORT);
79
+ startInternalStatusServer(INTERNAL_PORT);
80
+
81
+ fakeBinDir = path.join(tmpPrefix, 'fakebin');
82
+ fs.ensureDirSync(fakeBinDir);
83
+
84
+ const sudoPath = path.join(fakeBinDir, 'sudo');
85
+ fs.writeFileSync(
86
+ sudoPath,
87
+ `#!/usr/bin/env bash
88
+ while [[ "$1" == -* || "$1" == "--" ]]; do shift; done
89
+ exec "$@"
90
+ `,
91
+ );
92
+
93
+ const kubectlPath = path.join(fakeBinDir, 'kubectl');
94
+ fs.writeFileSync(
95
+ kubectlPath,
96
+ `#!/usr/bin/env bash
97
+ verb="$1"; kind="$2"
98
+ if [[ "$verb" == "get" && "$kind" == "pods" ]]; then
99
+ printf 'NAME READY STATUS RESTARTS AGE\\n'
100
+ printf '%s 1/1 Running 0 1m\\n' "$POD_NAME"
101
+ exit 0
102
+ fi
103
+ if [[ "$verb" == "get" && "$kind" == "pod" ]]; then
104
+ printf '{"status":{"conditions":[{"type":"Ready","status":"%s"}]}}\\n' "\${FAKE_POD_READY:-True}"
105
+ exit 0
106
+ fi
107
+ if [[ "$verb" == "port-forward" ]]; then
108
+ sleep 30
109
+ exit 0
110
+ fi
111
+ if [[ "$verb" == "exec" ]]; then
112
+ grep -E '^container-status=' "$UNDERPOST_ENV_FILE" 2>/dev/null | tail -n1 | sed -E 's/^container-status=//'
113
+ exit 0
114
+ fi
115
+ exit 0
116
+ `,
117
+ );
118
+ fs.chmodSync(sudoPath, 0o755);
119
+ fs.chmodSync(kubectlPath, 0o755);
120
+
121
+ monitorScriptPath = path.join(tmpPrefix, 'monitor-ready.mjs');
122
+ fs.writeFileSync(
123
+ monitorScriptPath,
124
+ `import Underpost from ${JSON.stringify(pathToFileURL(path.join(repoRoot, 'src/index.js')).href)};
125
+ const options = {};
126
+ if (process.env.MON_READY_GATE) options.readyGate = process.env.MON_READY_GATE;
127
+ if (process.env.MON_TRANSPORT) options.statusTransport = process.env.MON_TRANSPORT;
128
+ try {
129
+ await Underpost.monitor.monitorReadyRunner(${JSON.stringify(DEPLOY_ID)}, ${JSON.stringify(ENV)}, ${JSON.stringify(
130
+ TRAFFIC,
131
+ )}, [], 'default', options);
132
+ process.exit(0);
133
+ } catch (_) {
134
+ process.exit(1);
135
+ }
136
+ `,
137
+ );
138
+ });
139
+
140
+ after(async () => {
141
+ await stopInternalStatusServer();
142
+ delete process.env.UNDERPOST_INTERNAL_PORT;
143
+ if (prevPrefix === undefined) delete process.env.npm_config_prefix;
144
+ else process.env.npm_config_prefix = prevPrefix;
145
+ fs.removeSync(tmpPrefix);
146
+ });
147
+
148
+ beforeEach(() => {
149
+ // Deploy in flight: app not yet reporting running.
150
+ Underpost.env.set('container-status', INIT_STATUS);
151
+ });
152
+
153
+ // Spawns the real monitorReadyRunner with the fake cluster on PATH; resolves
154
+ // with its exit code. `overrides` inject deterministic timing / target port.
155
+ const spawnMonitor = (overrides = {}) =>
156
+ new Promise((resolve) => {
157
+ const envVars = {
158
+ PATH: `${fakeBinDir}:${process.env.PATH}`,
159
+ UNDERPOST_ENV_FILE: envFile,
160
+ POD_NAME,
161
+ npm_config_prefix: tmpPrefix,
162
+ UNDERPOST_INTERNAL_PORT: String(INTERNAL_PORT),
163
+ // Pin the tunnel's local port so the no-op fake port-forward + the real
164
+ // internal server (bound to INTERNAL_PORT in this process) resolve to the
165
+ // same address the monitor's HTTP GET targets.
166
+ UNDERPOST_PF_LOCAL_PORT: String(INTERNAL_PORT),
167
+ UNDERPOST_MONITOR_DELAY_MS: '100',
168
+ UNDERPOST_MONITOR_MAX_ITERATIONS: '60',
169
+ UNDERPOST_PF_ATTEMPTS: '3',
170
+ FAKE_POD_READY: 'True',
171
+ ...overrides,
172
+ };
173
+ const prefix = Object.entries(envVars)
174
+ .map(([k, v]) => `${k}="${v}"`)
175
+ .join(' ');
176
+ shellExec(`${prefix} ${node} ${monitorScriptPath}`, {
177
+ async: true,
178
+ silent: true,
179
+ disableLog: true,
180
+ callback: (code) => resolve(code),
181
+ });
182
+ });
183
+
184
+ it('success (default exec transport): both phases satisfied → monitor exits 0', async () => {
185
+ Underpost.env.set('container-status', RUNNING_STATUS);
186
+ const code = await spawnMonitor({ FAKE_POD_READY: 'True' });
187
+ expect(code).to.equal(0);
188
+ });
189
+
190
+ it('success (opt-in http transport): both phases satisfied → monitor exits 0', async () => {
191
+ Underpost.env.set('container-status', RUNNING_STATUS);
192
+ const code = await spawnMonitor({ FAKE_POD_READY: 'True', MON_TRANSPORT: 'http' });
193
+ expect(code).to.equal(0);
194
+ });
195
+
196
+ it('runtime failure: container-status=error → monitor exits 1', async () => {
197
+ const monitorExit = spawnMonitor({ FAKE_POD_READY: 'True' });
198
+ Underpost.env.set('container-status', 'error');
199
+ expect(await monitorExit).to.equal(1);
200
+ });
201
+
202
+ it('readiness mismatch: runtime running but pod not Ready → never succeeds (exits 1)', async () => {
203
+ // Phase 2 satisfied, Phase 1 not: success requires BOTH, so it must time out.
204
+ Underpost.env.set('container-status', RUNNING_STATUS);
205
+ const code = await spawnMonitor({ FAKE_POD_READY: 'False', UNDERPOST_MONITOR_MAX_ITERATIONS: '4' });
206
+ expect(code).to.equal(1);
207
+ });
208
+
209
+ it('transport failure (http): endpoint unreachable is never success (exits 1)', async () => {
210
+ // Opt into http and point the monitor at a port with no internal server; the
211
+ // HTTP read always fails, so runtime readiness is never confirmed → timeout.
212
+ Underpost.env.set('container-status', RUNNING_STATUS);
213
+ const code = await spawnMonitor({
214
+ MON_TRANSPORT: 'http',
215
+ UNDERPOST_INTERNAL_PORT: String(CLOSED_PORT),
216
+ UNDERPOST_PF_LOCAL_PORT: String(CLOSED_PORT),
217
+ UNDERPOST_MONITOR_MAX_ITERATIONS: '3',
218
+ });
219
+ expect(code).to.equal(1);
220
+ });
221
+
222
+ it('timeout: runtime stuck initializing → monitor exits 1', async () => {
223
+ Underpost.env.set('container-status', INIT_STATUS);
224
+ const code = await spawnMonitor({ FAKE_POD_READY: 'True', UNDERPOST_MONITOR_MAX_ITERATIONS: '4' });
225
+ expect(code).to.equal(1);
226
+ });
227
+
228
+ it('regression: advanced pod whose runtime status falls back → monitor exits 1', async () => {
229
+ // Pod advances past build, then its reported status regresses (pod restart);
230
+ // the monitor must treat this as a failure rather than wait it out.
231
+ Underpost.env.set('container-status', INIT_STATUS);
232
+ const monitorExit = spawnMonitor({ FAKE_POD_READY: 'False', UNDERPOST_MONITOR_MAX_ITERATIONS: '120' });
233
+ await new Promise((r) => setTimeout(r, 1500));
234
+ Underpost.env.set('container-status', BUILD_STATUS);
235
+ expect(await monitorExit).to.equal(1);
236
+ });
237
+
238
+ // Custom instances (cyberia-*) gate on K8s Ready and read status via exec;
239
+ // their runtime never stamps `running-deployment` (stays `initializing`).
240
+ it('instance (kubernetes gate + exec): K8s Ready with initializing status → exits 0', async () => {
241
+ Underpost.env.set('container-status', INIT_STATUS);
242
+ const code = await spawnMonitor({ FAKE_POD_READY: 'True', MON_READY_GATE: 'kubernetes', MON_TRANSPORT: 'exec' });
243
+ expect(code).to.equal(0);
244
+ });
245
+
246
+ it('instance (kubernetes gate + exec): container-status=error → exits 1', async () => {
247
+ const monitorExit = spawnMonitor({ FAKE_POD_READY: 'True', MON_READY_GATE: 'kubernetes', MON_TRANSPORT: 'exec' });
248
+ Underpost.env.set('container-status', 'error');
249
+ expect(await monitorExit).to.equal(1);
250
+ });
251
+ });
package/bin/file.js DELETED
@@ -1,202 +0,0 @@
1
- import fs from 'fs-extra';
2
-
3
- import { loggerFactory } from '../src/server/logger.js';
4
- import {
5
- cap,
6
- getCapVariableName,
7
- getDirname,
8
- newInstance,
9
- uniqueArray,
10
- } from '../src/client/components/core/CommonJs.js';
11
- import { shellCd, shellExec } from '../src/server/process.js';
12
- import walk from 'ignore-walk';
13
- import { validateTemplatePath } from '../src/server/conf.js';
14
- import dotenv from 'dotenv';
15
-
16
- const logger = loggerFactory(import.meta);
17
-
18
- dotenv.config({ path: `./engine-private/conf/dd-cron/.env.production`, override: true });
19
-
20
- logger.info('argv', process.argv);
21
-
22
- let [exe, dir, type] = process.argv;
23
- let rawPath = process.argv[3].replaceAll(`'`, '');
24
- let toPath = process.argv[4].replaceAll(`'`, '');
25
- let path = `${rawPath}`.split('/');
26
- path.pop();
27
- path = path.join('/');
28
- const file = `${rawPath}`.split('/').pop();
29
- const ext = file.split('.')[1];
30
- let name = getCapVariableName(file.split('.')[0]);
31
- let content = '';
32
-
33
- logger.info('File metadata', { path, file, ext, name });
34
-
35
- try {
36
- switch (type) {
37
- case 'update-template':
38
- case 'copy-src':
39
- console.log({ rawPath, toPath });
40
-
41
- let result = await new Promise((resolve) =>
42
- walk(
43
- {
44
- path: rawPath, // root dir to start in. defaults to process.cwd()
45
- ignoreFiles: [`.gitignore`], // list of filenames. defaults to ['.ignore']
46
- includeEmpty: false, // true to include empty dirs, default false
47
- follow: false, // true to follow symlink dirs, default false
48
- },
49
- (...args) => resolve(args[1]),
50
- ),
51
- );
52
-
53
- result = result.filter((path) => !path.startsWith('.git'));
54
-
55
- console.log('copy paths', result);
56
-
57
- if (type === 'update-template') {
58
- if (!fs.existsSync(toPath))
59
- shellExec(`cd .. && underpost clone ${process.env.GITHUB_USERNAME}/pwa-microservices-template`);
60
- else {
61
- shellExec(`cd ${toPath} && git reset && git checkout . && git clean -f -d`);
62
- shellExec(`underpost pull ${toPath} ${process.env.GITHUB_USERNAME}/pwa-microservices-template`);
63
- shellExec(`sudo rm -rf ${toPath}/engine-private`);
64
- shellExec(`sudo rm -rf ${toPath}/logs`);
65
- }
66
- } else {
67
- fs.removeSync(toPath);
68
- }
69
-
70
- for (const copyPath of result) {
71
- if (copyPath === 'NaN') continue;
72
- const folder = getDirname(`${toPath}/${copyPath}`);
73
- const absolutePath = `${rawPath}/${copyPath}`;
74
-
75
- if (type === 'update-template' && !validateTemplatePath(absolutePath)) continue;
76
-
77
- if (!fs.existsSync(folder)) fs.mkdirSync(folder, { recursive: true });
78
-
79
- logger.info('build', `${toPath}/${copyPath}`);
80
-
81
- fs.copyFileSync(absolutePath, `${toPath}/${copyPath}`);
82
- }
83
-
84
- if (type === 'update-template') {
85
- fs.copySync(`./.vscode`, `../pwa-microservices-template/.vscode`);
86
- // fs.copySync(`./.github`, `../pwa-microservices-template/.github`);
87
- fs.copySync(`./src/client/public/default`, `../pwa-microservices-template/src/client/public/default`);
88
-
89
- for (const checkoutPath of ['README.md', 'package.json'])
90
- shellExec(`cd ../pwa-microservices-template && git checkout ${checkoutPath}`);
91
-
92
- for (const deletePath of [
93
- './.github',
94
- './manifests/deployment/dd-lampp-development',
95
- './manifests/deployment/dd-cyberia-development',
96
- './manifests/deployment/dd-core-development',
97
- './manifests/deployment/dd-template-development',
98
- './src/server/object-layer.js',
99
- './src/server/atlas-sprite-sheet-generator.js',
100
- './src/server/shape-generator.js',
101
- './src/server/semantic-layer-generator.js',
102
- './src/server/semantic-layer-generator-floor.js',
103
- './src/server/semantic-layer-generator-skin.js',
104
- './src/server/semantic-layer-generator-resource.js',
105
- './src/server/besu-genesis-generator.js',
106
- './src/grpc/cyberia',
107
- './src/runtime/cyberia-server',
108
- './src/runtime/cyberia-client',
109
- './test/shape-generator.test.js',
110
- './src/client/public/cyberia-docs',
111
- 'bin/cyberia.js',
112
- ]) {
113
- if (fs.existsSync(deletePath)) fs.removeSync('../pwa-microservices-template/' + deletePath);
114
- }
115
-
116
- fs.mkdirSync(`../pwa-microservices-template/.github/workflows`, {
117
- recursive: true,
118
- });
119
- for (const _path of [
120
- `./.github/workflows/pwa-microservices-template-page.cd.yml`,
121
- `./.github/workflows/pwa-microservices-template-test.ci.yml`,
122
- `./.github/workflows/npmpkg.ci.yml`,
123
- `./.github/workflows/ghpkg.ci.yml`,
124
- `./.github/workflows/gitlab.ci.yml`,
125
- `./.github/workflows/publish.ci.yml`,
126
- `./.github/workflows/release.cd.yml`,
127
- `./src/client/services/user/guest.service.js`,
128
- './src/api/user/guest.service.js',
129
- './src/ws/IoInterface.js',
130
- './src/ws/IoServer.js',
131
- ])
132
- fs.copyFileSync(_path, `../pwa-microservices-template/${_path}`);
133
-
134
- const originPackageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
135
- const templatePackageJson = JSON.parse(fs.readFileSync('../pwa-microservices-template/package.json', 'utf8'));
136
-
137
- const name = templatePackageJson.name;
138
- const description = templatePackageJson.description;
139
- const dev = templatePackageJson.scripts.dev;
140
- const build = templatePackageJson.scripts.build;
141
-
142
- templatePackageJson.dependencies = originPackageJson.dependencies;
143
- templatePackageJson.devDependencies = originPackageJson.devDependencies;
144
- templatePackageJson.version = originPackageJson.version;
145
- templatePackageJson.scripts = originPackageJson.scripts;
146
- templatePackageJson.overrides = originPackageJson.overrides;
147
- templatePackageJson.name = name;
148
- templatePackageJson.description = description;
149
- // templatePackageJson.scripts.dev = dev;
150
- // templatePackageJson.scripts.build = build;
151
- templatePackageJson.keywords = uniqueArray(
152
- ['pwa', 'microservices', 'template', 'builder'].concat(templatePackageJson.keywords),
153
- );
154
- delete templatePackageJson.scripts['update:template'];
155
- fs.writeFileSync(
156
- '../pwa-microservices-template/package.json',
157
- JSON.stringify(templatePackageJson, null, 4),
158
- 'utf8',
159
- );
160
- const originPackageLockJson = JSON.parse(fs.readFileSync('./package-lock.json', 'utf8'));
161
-
162
- const templatePackageLockJson = JSON.parse(
163
- fs.readFileSync('../pwa-microservices-template/package-lock.json', 'utf8'),
164
- );
165
-
166
- const originBasePackageLock = newInstance(templatePackageLockJson.packages['']);
167
- templatePackageLockJson.name = name;
168
- templatePackageLockJson.version = originPackageLockJson.version;
169
- templatePackageLockJson.packages = originPackageLockJson.packages;
170
- templatePackageLockJson.packages[''].name = name;
171
- templatePackageLockJson.packages[''].version = originPackageLockJson.version;
172
- templatePackageLockJson.packages[''].hasInstallScript = originBasePackageLock.hasInstallScript;
173
- templatePackageLockJson.packages[''].license = originBasePackageLock.license;
174
- fs.writeFileSync(
175
- '../pwa-microservices-template/package-lock.json',
176
- JSON.stringify(templatePackageLockJson, null, 4),
177
- 'utf8',
178
- );
179
- // Regenerate package-lock.json to match the modified package.json
180
- // shellExec(`cd ../pwa-microservices-template && npm install --package-lock-only --ignore-scripts`);
181
- fs.writeFileSync(
182
- '../pwa-microservices-template/README.md',
183
- fs
184
- .readFileSync('./README.md', 'utf8')
185
- .replace('<!-- template-title -->', '#### Base template for pwa/api-rest projects.'),
186
- 'utf8',
187
- );
188
- }
189
-
190
- break;
191
- case 'create':
192
- const buildPath = `${path}/${name}${ext ? `.${ext}` : ''}`;
193
- logger.info('Build path', buildPath);
194
- fs.mkdirSync(path, { recursive: true });
195
- fs.writeFileSync(buildPath, content, 'utf8');
196
- default:
197
- logger.error('not found operator');
198
- break;
199
- }
200
- } catch (error) {
201
- logger.error(error, error.stack);
202
- }
package/bin/vs.js DELETED
@@ -1,74 +0,0 @@
1
- import fs from 'fs-extra';
2
- import { shellExec } from '../src/server/process.js';
3
- import { loggerFactory } from '../src/server/logger.js';
4
-
5
- const logger = loggerFactory(import.meta);
6
-
7
- const vsCodeRootPath = '/root/.vscode-root';
8
- const vsConfigRootPath = '/root/.config/Code';
9
-
10
- const vsProgram = 'code';
11
-
12
- switch (process.argv[2]) {
13
- case 'info': {
14
- logger.info('Formatted', 'Ctrl shift I');
15
- logger.info('Command', 'Ctrl shift P');
16
- logger.info('Search', 'Ctrl shift F');
17
- logger.info('Debug', 'Ctrl shift D');
18
- logger.info('New File', 'Ctrl N');
19
- logger.info('Change tab', 'Ctrl Tab');
20
- logger.info('Fold All', 'Ctrl K + Ctrl 0');
21
- logger.info('Unfold All', 'Ctrl K + Ctrl J');
22
- logger.info('Close All tabs', 'Ctrl K + W');
23
- logger.info('Go to line number', 'Ctrl G');
24
- logger.info('Change current project folder', 'Ctrl K + Ctrl O');
25
- logger.info('Open new vs windows', 'Ctrl Shift N');
26
- logger.info('Close current vs windows', 'Ctrl Shift W');
27
- logger.info('Preview md', 'Ctrl shift V');
28
- logger.info('Open git changes', 'Ctrl G + G');
29
- logger.warn('Terminal shortcut configure with command pallette', 'Ctl shift T');
30
- break;
31
- }
32
- case 'import':
33
- {
34
- const extensions = JSON.parse(fs.readFileSync(`./.vscode/extensions.json`, 'utf8'));
35
- extensions.recommendations.map((extension) => {
36
- if (extension)
37
- shellExec(
38
- `sudo ${vsProgram} --user-data-dir="${vsCodeRootPath}" --no-sandbox --install-extension ${extension}`,
39
- );
40
- });
41
- }
42
- break;
43
- case 'export':
44
- {
45
- shellExec(
46
- `sudo ${vsProgram} --user-data-dir="${vsCodeRootPath}" --no-sandbox --list-extensions > vs-extensions.txt`,
47
- );
48
- fs.writeFileSync(
49
- `./.vscode/extensions.json`,
50
- JSON.stringify(
51
- {
52
- recommendations: fs
53
- .readFileSync(`./vs-extensions.txt`, 'utf8')
54
- .split(`\n`)
55
- .filter((ext) => ext.trim()),
56
- },
57
- null,
58
- 4,
59
- ),
60
- 'utf8',
61
- );
62
- fs.removeSync(`./vs-extensions.txt`);
63
- }
64
- break;
65
-
66
- case 'clean': {
67
- shellExec(`sudo rm -rf ${vsCodeRootPath}/*`);
68
- shellExec(`sudo rm -rf ${vsConfigRootPath}`);
69
- break;
70
- }
71
- default:
72
- shellExec(`sudo ${vsProgram} ${process.argv[2]} --user-data-dir="${vsCodeRootPath}" --no-sandbox`);
73
- break;
74
- }
package/bin/zed.js DELETED
@@ -1,84 +0,0 @@
1
- import { shellExec } from '../src/server/process.js';
2
- import fs from 'fs-extra';
3
- import { loggerFactory } from '../src/server/logger.js';
4
- import { getUnderpostRootPath } from '../src/server/conf.js';
5
-
6
- const logger = loggerFactory(import.meta);
7
- const underpostRoot = getUnderpostRootPath();
8
-
9
- const settings = {
10
- ui_font_size: 16,
11
- buffer_font_size: 15,
12
- theme: {
13
- mode: 'system',
14
- light: 'One Dark',
15
- dark: 'One Dark',
16
- },
17
-
18
- features: {
19
- edit_prediction_provider: 'copilot',
20
- copilot: true,
21
- },
22
-
23
- show_edit_predictions: true,
24
-
25
- edit_predictions: {
26
- mode: 'eager',
27
- },
28
- };
29
-
30
- const keyMap = [
31
- {
32
- context: 'Editor',
33
- bindings: {
34
- 'ctrl-c': 'editor::Copy',
35
- 'ctrl-x': 'editor::Cut',
36
- 'ctrl-v': 'editor::Paste',
37
- 'ctrl-shift-c': 'editor::CopyAndTrim',
38
- 'ctrl-shift-v': 'editor::Paste',
39
- 'cmd-c': 'editor::Copy',
40
- 'cmd-x': 'editor::Cut',
41
- 'cmd-v': 'editor::Paste',
42
- },
43
- },
44
- {
45
- context: 'Terminal',
46
- bindings: {
47
- 'ctrl-shift-c': 'terminal::Copy',
48
- 'ctrl-shift-v': 'terminal::Paste',
49
- 'cmd-shift-c': 'terminal::Copy',
50
- 'cmd-shift-v': 'terminal::Paste',
51
- },
52
- },
53
- {
54
- context: 'Editor && edit_prediction',
55
- bindings: {
56
- tab: 'editor::AcceptEditPrediction',
57
- 'alt-tab': 'editor::AcceptEditPrediction',
58
- 'alt-l': null,
59
- },
60
- },
61
- {
62
- context: 'Editor && edit_prediction_conflict',
63
- bindings: {
64
- 'alt-l': 'editor::AcceptEditPrediction',
65
- tab: 'editor::ComposeCompletion',
66
- },
67
- },
68
- ];
69
-
70
- if (!fs.existsSync('/root/.config/zed')) fs.mkdirSync('/root/.config/zed', { recursive: true });
71
- fs.writeFileSync(`/root/.config/zed/settings.json`, JSON.stringify(settings, null, 4), 'utf8');
72
- fs.writeFileSync(`/root/.config/zed/keymap.json`, JSON.stringify(keyMap, null, 4), 'utf8');
73
-
74
- shellExec(`ZED_ALLOW_ROOT=true zed ${process.argv[2] ? process.argv[2] : '.'}`);
75
-
76
- logger.info('Connect copilot device', 'https://github.com/login/device');
77
- logger.info('Comments', 'Ctrl shift 7');
78
- logger.info('Unfold', 'Ctrl K + Ctrl J');
79
- logger.info('Fold', 'Ctrl K + Ctrl 0');
80
- logger.info('Command Palette', 'Ctrl Shift P');
81
- logger.info('Open File', 'Ctrl P');
82
- logger.info('Find in Files', 'Ctrl Shift F');
83
- logger.info('Go to Line', 'Ctrl G');
84
- logger.info('New file', 'Ctrl N');