@underpostnet/cyberia 3.2.80 → 3.3.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.
Files changed (162) hide show
  1. package/.env.example +50 -15
  2. package/.github/workflows/coverall.cyberia.ci.yml +87 -0
  3. package/.github/workflows/cyberia-client.cd.yml +2 -7
  4. package/.github/workflows/cyberia-server.cd.yml +2 -7
  5. package/.github/workflows/docker-image.cyberia-client.ci.yml +4 -4
  6. package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +4 -4
  7. package/.github/workflows/docker-image.cyberia-server.ci.yml +4 -4
  8. package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +4 -4
  9. package/.github/workflows/docker-image.engine-cyberia.ci.yml +3 -3
  10. package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +3 -3
  11. package/.github/workflows/engine-cyberia.cd.yml +3 -67
  12. package/.github/workflows/ghpkg.ci.yml +7 -1
  13. package/.github/workflows/pwa-microservices-template-page.cd.yml +1 -16
  14. package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
  15. package/.github/workflows/release.cd.yml +1 -9
  16. package/CHANGELOG.md +291 -1
  17. package/CLI-HELP.md +174 -23
  18. package/Dockerfile +1 -1
  19. package/Dockerfile.dev +1 -1
  20. package/Dockerfile.test +1 -1
  21. package/bin/build.js +7 -5
  22. package/bin/cyberia.js +272 -98
  23. package/bin/deploy.js +19 -17
  24. package/bin/index.js +272 -98
  25. package/compose.env +50 -15
  26. package/conf.js +2 -0
  27. package/deploy/dd-cyberia/deploy.sh +42 -0
  28. package/deploy/dd-cyberia/init.sh +63 -0
  29. package/deploy/dd-cyberia/sync-deploy.sh +194 -0
  30. package/deploy/lib/logging.sh +96 -0
  31. package/deploy/pwa-microservices-template/deploy.sh +72 -0
  32. package/deploy/release/deploy.sh +62 -0
  33. package/deployment.yaml +1 -210
  34. package/docker-compose.yml +90 -85
  35. package/hardhat/package-lock.json +139 -131
  36. package/hardhat/package.json +4 -4
  37. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +5 -1
  38. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
  39. package/manifests/cronjobs/dd-cron/dd-cron-vultr.yaml +52 -0
  40. package/manifests/deployment/dd-cyberia-development/deployment.yaml +1 -210
  41. package/manifests/deployment/dd-cyberia-development/gateway.yaml +80 -0
  42. package/manifests/deployment/dd-cyberia-development/httproute.yaml +504 -0
  43. package/manifests/deployment/dd-cyberia-development/proxy.yaml +12 -12
  44. package/manifests/deployment/dd-cyberia-development/pv-pvc.yaml +0 -82
  45. package/manifests/deployment/dd-cyberia-development/traffic-service.yaml +121 -0
  46. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  47. package/manifests/deployment/playwright/deployment.yaml +1 -1
  48. package/manifests/mongodb/kustomization.yaml +4 -1
  49. package/manifests/mongodb/statefulset.yaml +4 -0
  50. package/manifests/mongodb/storage-class.yaml +9 -2
  51. package/nginx.conf +86 -16
  52. package/package.json +2 -2
  53. package/proxy.yaml +12 -12
  54. package/pv-pvc.yaml +0 -82
  55. package/scripts/audit-selinux.sh +64 -0
  56. package/scripts/coverall-test-cyberia.sh +24 -0
  57. package/scripts/coverall-test.sh +24 -0
  58. package/scripts/gpu-diag.sh +0 -0
  59. package/scripts/ip-info.sh +0 -0
  60. package/scripts/k3s-node-setup.sh +18 -15
  61. package/scripts/kubeadm-node-setup.sh +12 -23
  62. package/scripts/link-local-underpost-cli.sh +0 -0
  63. package/scripts/lxd-vm-setup.sh +0 -0
  64. package/scripts/maas-nat-firewalld.sh +0 -0
  65. package/scripts/nat-iptables.sh +12 -4
  66. package/scripts/rhel-grpc-setup.sh +0 -0
  67. package/scripts/rocky-kickstart.sh +25 -9
  68. package/scripts/test-monitor.sh +4 -3
  69. package/src/api/cyberia-action/cyberia-action.model.js +1 -0
  70. package/src/api/cyberia-instance/cyberia-fallback-default-items.js +63 -0
  71. package/src/api/cyberia-instance/cyberia-fallback-world.js +49 -15
  72. package/src/api/cyberia-instance/cyberia-instance-map.service.js +8 -12
  73. package/src/api/cyberia-instance/cyberia-instance.controller.js +3 -0
  74. package/src/api/cyberia-instance/cyberia-instance.router.js +13 -0
  75. package/src/api/cyberia-instance/cyberia-instance.service.js +43 -0
  76. package/src/api/cyberia-instance/cyberia-portal-connector.js +7 -5
  77. package/src/api/cyberia-instance/cyberia-random-source.js +80 -0
  78. package/src/api/cyberia-instance/cyberia-world-generator.js +4 -3
  79. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +1 -0
  80. package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +87 -1
  81. package/src/api/object-layer/object-layer.model.js +204 -3
  82. package/src/api/object-layer/object-layer.service.js +1 -14
  83. package/src/cli/baremetal.js +1 -2
  84. package/src/cli/cloud-init.js +1 -1
  85. package/src/cli/cluster.js +786 -96
  86. package/src/cli/db.js +11 -4
  87. package/src/cli/deploy.js +1698 -177
  88. package/src/cli/docker-compose.js +19 -178
  89. package/src/cli/env.js +1 -1
  90. package/src/cli/image.js +15 -7
  91. package/src/cli/index.js +245 -44
  92. package/src/cli/ipfs.js +82 -11
  93. package/src/cli/lxd.js +1 -1
  94. package/src/cli/monitor.js +2 -2
  95. package/src/cli/release.js +57 -22
  96. package/src/cli/repository.js +12 -10
  97. package/src/cli/run.js +2195 -427
  98. package/src/cli/secrets.js +969 -0
  99. package/src/cli/ssh.js +206 -105
  100. package/src/cli/system.js +26 -13
  101. package/src/cli/test.js +1 -1
  102. package/src/cli/vultr.js +583 -0
  103. package/src/cli/wireguard.js +2125 -0
  104. package/src/client/components/cyberia/FallbackWorldEngineCyberia.js +368 -0
  105. package/src/client/components/cyberia/InstanceSelectionView.js +11 -8
  106. package/src/client/components/cyberia/SharedDefaultsCyberia.js +5 -0
  107. package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +33 -0
  108. package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +4 -0
  109. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +4 -0
  110. package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +106 -39
  111. package/src/client/public/cyberia-docs/ARCHITECTURE.md +35 -3
  112. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +44 -7
  113. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +1 -1
  114. package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
  115. package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
  116. package/src/client/services/cyberia-instance/cyberia-instance.service.js +40 -0
  117. package/src/client/services/object-layer/object-layer.management.js +4 -4
  118. package/src/client-builder/client-build.js +102 -13
  119. package/src/client-builder/ssr.js +27 -73
  120. package/src/db/mongo/MongoBootstrap.js +295 -54
  121. package/src/db/mongo/MongooseDB.js +51 -32
  122. package/src/index.js +25 -1
  123. package/src/projects/cyberia/besu-genesis-generator.js +3 -2
  124. package/src/projects/cyberia/catalog-cyberia.js +5 -0
  125. package/src/projects/cyberia/generate-saga.js +14 -23
  126. package/src/projects/cyberia/hot-reload-trigger.js +3 -3
  127. package/src/projects/cyberia/instance-data.js +63 -3
  128. package/src/projects/cyberia/object-layer.js +11 -21
  129. package/src/projects/underpost/catalog-underpost.js +4 -1
  130. package/src/runtime/cyberia-client/Dockerfile +1 -1
  131. package/src/runtime/cyberia-client/Dockerfile.dev +1 -1
  132. package/src/runtime/cyberia-server/Dockerfile +1 -1
  133. package/src/runtime/cyberia-server/Dockerfile.dev +1 -1
  134. package/src/runtime/engine-cyberia/Dockerfile +1 -1
  135. package/src/runtime/engine-cyberia/Dockerfile.dev +1 -1
  136. package/src/runtime/engine-cyberia/Dockerfile.test +1 -1
  137. package/src/runtime/engine-cyberia/compose.env +50 -15
  138. package/src/runtime/engine-cyberia/docker-compose.yml +90 -85
  139. package/src/runtime/engine-cyberia/nginx.conf +86 -16
  140. package/src/server/backup.js +1 -1
  141. package/src/server/conf.js +1216 -168
  142. package/src/server/cri.js +70 -0
  143. package/src/server/cron.js +249 -51
  144. package/src/server/dns.js +100 -6
  145. package/src/server/environment.js +98 -0
  146. package/src/server/forward-proxy.js +549 -0
  147. package/src/server/middlewares.js +56 -1
  148. package/src/server/process.js +0 -1
  149. package/src/server/selinux.js +185 -0
  150. package/src/server/systemd.js +205 -0
  151. package/src/server/underpost-compression.js +186 -0
  152. package/src/server/underpost-gateway.js +1083 -0
  153. package/src/server/underpost-ingress.js +380 -0
  154. package/test/cluster-instances.test.js +435 -0
  155. package/test/cyberia-instance-conf-defaults.test.js +1 -0
  156. package/test/deploy-node-placement.test.js +45 -0
  157. package/test/instance-traffic-plan.test.js +710 -0
  158. package/test/selinux.test.js +71 -0
  159. package/test/sops-secret-store.test.js +612 -0
  160. package/test/underpost-gateway.test.js +510 -0
  161. package/test/underpost-ingress.test.js +305 -0
  162. package/test/wireguard-edge.test.js +1177 -0
package/compose.env CHANGED
@@ -40,29 +40,27 @@ VALKEY_HOST=valkey-service
40
40
  VALKEY_PORT=6379
41
41
 
42
42
  # --- Cyberia instance wiring (compose service DNS) ---------------------------
43
- # cyberia-server-* -> engine-cyberia authority endpoints. INTERNAL only: these
44
- # use the docker service DNS (engine-cyberia) and must never leak to browser
45
- # clients. Per-instance INSTANCE_CODE is set on each generated server service
46
- # from conf.instances.json (multiInstance) — not here.
47
- ENGINE_API_BASE_URL=http://engine-cyberia:4005
48
- ENGINE_GRPC_ADDRESS=engine-cyberia:50051
43
+ # cyberia-server-* -> stable engine gateway for HTTP and the raw engine runtime
44
+ # for gRPC. The public engine-cyberia name belongs to nginx, avoiding ambiguous
45
+ # Docker DNS while keeping one stable HTTP endpoint for every module.
46
+ ENGINE_API_BASE_URL=http://engine-cyberia
47
+ ENGINE_GRPC_ADDRESS=engine-cyberia-runtime:50051
49
48
 
50
49
  # Client-visible Content Authority origin, forwarded to browser/Raylib clients
51
50
  # for every engine-cyberia content/asset/metadata request. Host-reachable
52
- # (docker publishes engine-cyberia :4005). Distinct from ENGINE_API_BASE_URL:
51
+ # (Docker publishes the raw engine runtime on host :4005). Unlike the internal
52
+ # ENGINE_API_BASE_URL, this value is consumed outside the Compose network:
53
53
  # the two responsibilities must never overwrite each other.
54
54
  ENGINE_PUBLIC_URL=http://localhost:4005
55
55
  ENGINE_GRPC_RELOAD_INTERVAL_SEC=300
56
56
 
57
57
  # --- Browser-facing client runtime config (injected by docker-driver.py) -----
58
58
  # The single WASM bundle resolves its instance from the URL sub-path and builds
59
- # its endpoints from these origins. They point at the nginx proxy on localhost:80
60
- # (the single gateway that path-routes WS -> server, /api + /assets -> engine),
61
- # NOT at the raw client/engine container ports — a WS to the client port (8082)
62
- # has no server behind it. So this must be the proxy origin, not :8082 / :4005.
63
- # http://localhost/ -> default instance, ws -> ws://localhost/ws
64
- # http://localhost/FOREST -> FOREST instance, ws -> ws://localhost/FOREST/ws
65
- CYBERIA_WS_ORIGIN=ws://localhost
59
+ # its endpoints from these origins. HTTP client/API traffic uses nginx on :80;
60
+ # WebSocket traffic uses the dedicated multi-path server gateway on :8081.
61
+ # http://localhost/ -> default, ws://localhost:8081/ws
62
+ # http://localhost/FOREST -> FOREST, ws://localhost:8081/FOREST/ws
63
+ CYBERIA_WS_ORIGIN=ws://localhost:8081
66
64
  CYBERIA_ENGINE_API_ORIGIN=http://localhost
67
65
  CYBERIA_DEFAULT_INSTANCE=amethyst-strata-expansion
68
66
 
@@ -72,6 +70,22 @@ CYBERIA_DEFAULT_INSTANCE=amethyst-strata-expansion
72
70
  CYBERIA_SERVER_APP_ENV=development
73
71
  CYBERIA_SERVER_LOG_LEVEL=
74
72
 
73
+ # --- cyberia-server WebSocket admission and rate limits ----------------------
74
+ # Unset keeps the built-in default. An explicit 0 turns that one limit off.
75
+ # The startup log prints the effective profile ("ws limits: ...").
76
+ #
77
+ # Set CYBERIA_DISABLE_CONNECTION_LIMITS=1 to turn every limit off. The load test
78
+ # (test/cyberia-load.test.js) drives every simulated client from one address, so
79
+ # it needs this. NEVER enable it on a public deploy.
80
+ CYBERIA_DISABLE_CONNECTION_LIMITS=
81
+ CYBERIA_MAX_CONNECTIONS=
82
+ CYBERIA_MAX_CONNECTIONS_PER_IP=
83
+ CYBERIA_CONNECT_RATE_PER_IP=
84
+ CYBERIA_CONNECT_BURST_PER_IP=
85
+ CYBERIA_MESSAGE_RATE=
86
+ CYBERIA_MESSAGE_BURST=
87
+ CYBERIA_MAX_STRIKES=
88
+
75
89
  # --- engine-cyberia runtime env (loaded into the container via env_file) -----
76
90
  # The dd-cyberia engine (engine-private/conf/dd-cyberia/conf.server.json) needs
77
91
  # these to boot: DB auth + per-site DB names, the base PORT (the cyberia host is
@@ -82,6 +96,7 @@ NODE_OPTIONS=--max-old-space-size=8192
82
96
  BASE_API=api
83
97
  DEFAULT_DEPLOY_ID=dd-cyberia
84
98
  DEPLOY_ID=dd-cyberia
99
+ # Configuration/DB selector from conf.server.json; this is not a Docker DNS alias.
85
100
  DEFAULT_DEPLOY_HOST=www.cyberiaonline.com
86
101
  DEFAULT_DEPLOY_PATH=/
87
102
  DISABLE_API_RATE_LIMIT=true
@@ -131,7 +146,25 @@ IPFS_CLUSTER_API_URL=http://ipfs-cluster:9094
131
146
  # in docker-compose.yml). Override for a real/shared cluster.
132
147
  # CLUSTER_SECRET=
133
148
 
134
- # --- Host-published ports ----------------------------------------------------
149
+ # --- Local access ------------------------------------------------------------
150
+ # Client gateway: http://localhost/{,FOREST,TEST}
151
+ # Client port alias: http://localhost:8082/{,FOREST,TEST}
152
+ # Server gateway: http://localhost:8081/{,FOREST,TEST}
153
+ # Engine authority: http://localhost:4005
154
+ # Docker-network gateways:
155
+ # http://cyberia-client/{,FOREST,TEST}
156
+ # http://cyberia-server/{,FOREST,TEST}
157
+ # http://engine-cyberia/
158
+ #
159
+ # The *.localhost aliases normally resolve to loopback without configuration:
160
+ # http://client.cyberia.localhost/{,FOREST,TEST}
161
+ # http://server.cyberia.localhost/{,FOREST,TEST}
162
+ # http://engine.cyberia.localhost/
163
+ # `node bin/cyberia run-workflow docker:up` maintains this host entry (the
164
+ # aliases already work between containers):
165
+ # 127.0.0.1 cyberia-client cyberia-server engine-cyberia
166
+ #
167
+ # Host-published ports:
135
168
  PROXY_HTTP_PORT=80
136
169
  IPFS_API_PORT=5001
137
170
  IPFS_GATEWAY_PORT=8080
@@ -140,5 +173,7 @@ MONGO_HOST_PORT=27017
140
173
  VALKEY_NODEPORT=32079
141
174
  ENGINE_CYBERIA_REST_PORT=4005
142
175
  ENGINE_CYBERIA_GRPC_PORT=50051
176
+ # Multi-path nginx server gateway, not a single server container publication.
143
177
  CYBERIA_SERVER_PORT=8081
178
+ # Multi-path nginx client gateway; raw client containers remain internal.
144
179
  CYBERIA_CLIENT_PORT=8082
package/conf.js CHANGED
@@ -179,6 +179,7 @@ const DefaultConf = /**/ {
179
179
  'InstanceEngineCyberia',
180
180
  'ActionEngineCyberia',
181
181
  'EntityEngineCyberia',
182
+ 'FallbackWorldEngineCyberia',
182
183
  'InstanceSelectionView',
183
184
  ],
184
185
  core: [
@@ -264,6 +265,7 @@ const DefaultConf = /**/ {
264
265
  { path: '/docs', client: 'CyberiaPortal', ssr: 'CyberiaPortal' },
265
266
  { path: '/cyberia-action-engine', client: 'CyberiaPortal', ssr: 'CyberiaPortal' },
266
267
  { path: '/cyberia-entity-engine', client: 'CyberiaPortal', ssr: 'CyberiaPortal' },
268
+ { path: '/fallback-world-engine', client: 'CyberiaPortal', ssr: 'CyberiaPortal' },
267
269
  { path: '/instance-selection', title: 'Select World', client: 'CyberiaPortal', ssr: 'CyberiaPortal' },
268
270
  ],
269
271
  dists: [
@@ -0,0 +1,42 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
+ source "$SCRIPT_DIR/../lib/logging.sh"
6
+
7
+ ENGINE_ROOT=/home/dd/engine
8
+ INGRESS_NODE=localhost.localdomain
9
+
10
+ main() {
11
+ echo "Starting remote deploy"
12
+
13
+ run_quiet \
14
+ "Pull repository" \
15
+ "Target pod:" \
16
+ 14 \
17
+ sudo -n -- /bin/bash -lc \
18
+ "cd $ENGINE_ROOT && node bin run pull"
19
+
20
+ run_quiet \
21
+ "Install dependencies" \
22
+ "Target pod:" \
23
+ 14 \
24
+ sudo -n -- /bin/bash -lc \
25
+ "cd $ENGINE_ROOT && npm install"
26
+
27
+ run_quiet \
28
+ "Sync secrets" \
29
+ "Target pod:" \
30
+ 14 \
31
+ sudo -n -- /bin/bash -lc \
32
+ "cd $ENGINE_ROOT && node bin run secret"
33
+
34
+ run_quiet \
35
+ "Deploy dd-cyberia" \
36
+ "Target pod:" \
37
+ 14 \
38
+ sudo -n -- /bin/bash -lc \
39
+ "cd $ENGINE_ROOT && node bin run deploy dd-cyberia --gateway-api --ingress-node ${INGRESS_NODE}"
40
+ }
41
+
42
+ main "$@"
@@ -0,0 +1,63 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
+ source "$SCRIPT_DIR/../lib/logging.sh"
6
+
7
+ ENGINE_ROOT=/home/dd/engine
8
+ INGRESS_NODE=localhost.localdomain
9
+
10
+ main() {
11
+ echo "Starting init deploy"
12
+
13
+ run_quiet \
14
+ "Pull repository" \
15
+ "Target pod:" \
16
+ 14 \
17
+ sudo -n -- /bin/bash -lc \
18
+ "cd $ENGINE_ROOT && node bin run pull"
19
+
20
+ run_quiet \
21
+ "Install dependencies" \
22
+ "Target pod:" \
23
+ 14 \
24
+ sudo -n -- /bin/bash -lc \
25
+ "cd $ENGINE_ROOT && npm install"
26
+
27
+ run_quiet \
28
+ "Sync secrets" \
29
+ "Target pod:" \
30
+ 14 \
31
+ sudo -n -- /bin/bash -lc \
32
+ "cd $ENGINE_ROOT && node bin run secret"
33
+
34
+ run_quiet \
35
+ "Build dd-cyberia configuration" \
36
+ "Target pod:" \
37
+ 14 \
38
+ sudo -n -- /bin/bash -lc \
39
+ "cd $ENGINE_ROOT && node bin/build dd-cyberia --conf"
40
+
41
+ run_quiet \
42
+ "Deploy dd-cyberia production" \
43
+ "Target pod:" \
44
+ 14 \
45
+ sudo -n -- /bin/bash -lc \
46
+ "cd $ENGINE_ROOT && node bin deploy dd-cyberia production --kubeadm --gateway-api --ingress-node ${INGRESS_NODE} --sync --build-manifest --timeout-response 300000ms --versions green --replicas 1"
47
+
48
+ run_quiet \
49
+ "Clean dd-cyberia working tree" \
50
+ "Target pod:" \
51
+ 14 \
52
+ sudo -n -- /bin/bash -lc \
53
+ "cd $ENGINE_ROOT && node bin deploy dd-cyberia production --kubeadm --gateway-api --ingress-node ${INGRESS_NODE} --disable-update-proxy --git-clean"
54
+
55
+ run_quiet \
56
+ "Promote dd-cyberia deployment" \
57
+ "Target pod:" \
58
+ 14 \
59
+ sudo -n -- /bin/bash -lc \
60
+ "cd $ENGINE_ROOT && node bin monitor dd-cyberia production --ready-deployment --promote --timeout-response 300000ms --versions green --replicas 1"
61
+ }
62
+
63
+ main "$@"
@@ -0,0 +1,194 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
+ source "$SCRIPT_DIR/../lib/logging.sh"
6
+
7
+ ENGINE_ROOT=/home/dd/engine
8
+ TARGET_NODE=localhost.localdomain
9
+ INGRESS_NODE=localhost.localdomain
10
+
11
+ # Asset repositories are committed only when they actually changed, so the
12
+ # status query stays outside run_quiet: its stdout is the value we branch on.
13
+ has_changes() {
14
+ local path="$1"
15
+
16
+ sudo -n -- /bin/bash -lc \
17
+ "cd $ENGINE_ROOT && node bin cmt $path --has-changes" | tr -d '\n'
18
+ }
19
+
20
+ main() {
21
+ echo "Starting remote sync and deploy"
22
+
23
+ run_quiet \
24
+ "Pull repository" \
25
+ "Target pod:" \
26
+ 14 \
27
+ sudo -n -- /bin/bash -lc \
28
+ "cd $ENGINE_ROOT && node bin run pull"
29
+
30
+ run_quiet \
31
+ "Install dependencies" \
32
+ "Target pod:" \
33
+ 14 \
34
+ sudo -n -- /bin/bash -lc \
35
+ "cd $ENGINE_ROOT && npm install"
36
+
37
+ run_quiet \
38
+ "Sync secrets" \
39
+ "Target pod:" \
40
+ 14 \
41
+ sudo -n -- /bin/bash -lc \
42
+ "cd $ENGINE_ROOT && node bin run secret"
43
+
44
+ run_quiet \
45
+ "Run tests" \
46
+ "Target pod:" \
47
+ 14 \
48
+ sudo -n -- /bin/bash -lc \
49
+ "cd $ENGINE_ROOT && npm run test"
50
+
51
+ run_quiet \
52
+ "Clean cyberia public assets" \
53
+ "Target pod:" \
54
+ 14 \
55
+ sudo -n -- /bin/bash -lc \
56
+ "cd $ENGINE_ROOT && node bin run clean src/client/public/cyberia"
57
+
58
+ run_quiet \
59
+ "Clean underpost public assets" \
60
+ "Target pod:" \
61
+ 14 \
62
+ sudo -n -- /bin/bash -lc \
63
+ "cd $ENGINE_ROOT && node bin run clean src/client/public/underpost"
64
+
65
+ run_quiet \
66
+ "Initialize cyberia assets repository" \
67
+ "Target pod:" \
68
+ 14 \
69
+ sudo -n -- /bin/bash -lc \
70
+ "cd $ENGINE_ROOT && node bin cmt src/client/public/cyberia --init-repo"
71
+
72
+ run_quiet \
73
+ "Initialize underpost assets repository" \
74
+ "Target pod:" \
75
+ 14 \
76
+ sudo -n -- /bin/bash -lc \
77
+ "cd $ENGINE_ROOT && node bin cmt src/client/public/underpost --init-repo"
78
+
79
+ run_quiet \
80
+ "Pull cyberia public assets" \
81
+ "Target pod:" \
82
+ 14 \
83
+ sudo -n -- /bin/bash -lc \
84
+ "cd $ENGINE_ROOT && node bin fs src/client/public/cyberia --pull --recursive --deploy-id dd-cyberia"
85
+
86
+ run_quiet \
87
+ "Pull underpost public assets" \
88
+ "Target pod:" \
89
+ 14 \
90
+ sudo -n -- /bin/bash -lc \
91
+ "cd $ENGINE_ROOT && node bin fs src/client/public/underpost --pull --recursive --deploy-id dd-cyberia --storage-file-path './engine-private/conf/dd-cyberia/storage.underpost.json'"
92
+
93
+ if [ "$(has_changes src/client/public/cyberia)" = "1" ]; then
94
+ run_quiet \
95
+ "Commit cyberia public assets" \
96
+ "Target pod:" \
97
+ 14 \
98
+ sudo -n -- /bin/bash -lc \
99
+ "cd $ENGINE_ROOT && node bin cmt src/client/public/cyberia feat 'Update cyberia public assets'"
100
+ fi
101
+
102
+ if [ "$(has_changes src/client/public/underpost)" = "1" ]; then
103
+ run_quiet \
104
+ "Commit underpost public assets" \
105
+ "Target pod:" \
106
+ 14 \
107
+ sudo -n -- /bin/bash -lc \
108
+ "cd $ENGINE_ROOT && node bin cmt src/client/public/underpost feat 'Update underpost public assets'"
109
+ fi
110
+
111
+ run_quiet \
112
+ "Apply format fixes" \
113
+ "Target pod:" \
114
+ 14 \
115
+ sudo -n -- /bin/bash -lc \
116
+ "cd $ENGINE_ROOT && npm run fix"
117
+
118
+ run_quiet \
119
+ "Reinstall dependencies" \
120
+ "Target pod:" \
121
+ 14 \
122
+ sudo -n -- /bin/bash -lc \
123
+ "cd $ENGINE_ROOT && npm install"
124
+
125
+ run_quiet \
126
+ "Build cyberia deployment bundle" \
127
+ "Target pod:" \
128
+ 14 \
129
+ sudo -n -- /bin/bash -lc \
130
+ "cd $ENGINE_ROOT && node bin/deploy cyberia"
131
+
132
+ run_quiet \
133
+ "Clean build artifacts" \
134
+ "Target pod:" \
135
+ 14 \
136
+ sudo -n -- /bin/bash -lc \
137
+ "cd $ENGINE_ROOT && underpost run clean"
138
+
139
+ run_quiet \
140
+ "Load dd-cyberia production environment" \
141
+ "Target pod:" \
142
+ 14 \
143
+ sudo -n -- /bin/bash -lc \
144
+ "cd $ENGINE_ROOT && node bin env dd-cyberia production"
145
+
146
+ run_quiet \
147
+ "Build cyberia manifests" \
148
+ "Target pod:" \
149
+ 14 \
150
+ sudo -n -- /bin/bash -lc \
151
+ "cd $ENGINE_ROOT && node bin/cyberia run-workflow build-manifest"
152
+
153
+ run_quiet \
154
+ "Sync dd-cyberia cluster" \
155
+ "Target pod:" \
156
+ 14 \
157
+ sudo -n -- /bin/bash -lc \
158
+ "cd $ENGINE_ROOT && node bin run sync 'dd-cyberia,1,,underpost/engine-cyberia:latest' \
159
+ --kubeadm \
160
+ --deploy-id-cron-jobs none \
161
+ --timeout-response 300000ms \
162
+ --node-name ${TARGET_NODE} \
163
+ --gateway-api \
164
+ --ingress-node ${INGRESS_NODE} \
165
+ --ssh-key-path /home/dd/tmp/897as9dxhaskd9 \
166
+ --image-pull-policy Always \
167
+ --cmd 'cd /home/dd/engine, \
168
+ underpost clone underpostnet/engine-cyberia, \
169
+ mkdir -p /home/dd/engine/src/client/public/itemledger \
170
+ /home/dd/engine/src/client/public/cryptokoyn \
171
+ /home/dd/engine/src/client/components/cryptokoyn \
172
+ /home/dd/engine/src/client/components/itemledger \
173
+ /home/dd/engine/hardhat, \
174
+ cp -a ./engine-cyberia/src/client/public/itemledger/. /home/dd/engine/src/client/public/itemledger/, \
175
+ cp -a ./engine-cyberia/src/client/public/cryptokoyn/. /home/dd/engine/src/client/public/cryptokoyn/, \
176
+ cp -a ./engine-cyberia/src/client/components/cryptokoyn/. /home/dd/engine/src/client/components/cryptokoyn/, \
177
+ cp -a ./engine-cyberia/src/client/components/itemledger/. /home/dd/engine/src/client/components/itemledger/, \
178
+ cp -a ./engine-cyberia/src/client/Itemledger.index.js /home/dd/engine/src/client/Itemledger.index.js, \
179
+ cp -a ./engine-cyberia/src/client/Cryptokoyn.index.js /home/dd/engine/src/client/Cryptokoyn.index.js, \
180
+ rm -rf ./engine-cyberia, \
181
+ sudo rm -rf ./engine-private/, \
182
+ node bin clone underpostnet/engine-cyberia-private, \
183
+ sudo mv ./engine-cyberia-private ./engine-private, \
184
+ node bin env dd-cyberia production, \
185
+ node ./engine-private/itc-scripts/dd-cyberia-0.js, \
186
+ sudo chown -R dd:dd /home/dd/engine/src/client/public/cyberia, \
187
+ node bin/cyberia run-workflow import-default-items --clean, \
188
+ node bin/cyberia run-workflow import-default-items, \
189
+ node bin env dd-cyberia production, \
190
+ node bin client dd-cyberia, \
191
+ node bin start dd-cyberia production --run'"
192
+ }
193
+
194
+ main "$@"
@@ -0,0 +1,96 @@
1
+ # Shared logging helpers for deploy/<deploy-id>/*.sh. Sourced, never executed directly.
2
+ #
3
+ # Deploy script contract:
4
+ # - one run_quiet call per remote command, with its own label
5
+ # - the body lives in main(), invoked on the last line: the first remote command
6
+ # pulls this repository, rewriting the running script while bash reads it
7
+ #
8
+ # run_quiet hides normal output, prints only `patterns` matches plus the next
9
+ # `lines_after` lines, and returns the command's exit status so `set -e` stops
10
+ # the deployment. On failure it keeps two temp files and prints their paths in
11
+ # red instead of their contents: the command's own stderr (native error message
12
+ # and stack trace) and the full unfiltered log up to the error.
13
+
14
+ RUN_QUIET_RED=$'\033[0;31m'
15
+ RUN_QUIET_RESET=$'\033[0m'
16
+
17
+ RUN_QUIET_NODE_NAME=$(hostname 2>/dev/null | tr '[:upper:]' '[:lower:]')
18
+ RUN_QUIET_NODE_TAG=${RUN_QUIET_NODE_NAME:+ [$RUN_QUIET_NODE_NAME]}
19
+
20
+ run_quiet() {
21
+ local label="$1"
22
+ local patterns="$2"
23
+ local lines_after="$3"
24
+ shift 3
25
+
26
+ local debug_log
27
+ local error_log
28
+ local fifo_dir
29
+ local filter_pid
30
+ local stderr_pid
31
+ local status=0
32
+
33
+ echo "$(date -Is) $RUN_QUIET_NODE_TAG ▶ $label"
34
+
35
+ debug_log=$(mktemp --suffix=.debug.log)
36
+ error_log=$(mktemp --suffix=.error.log)
37
+ fifo_dir=$(mktemp -d)
38
+ mkfifo "$fifo_dir/merged" "$fifo_dir/stderr"
39
+
40
+ # The filter reads the live stream rather than the finished log: a deployment
41
+ # monitor prints its matches for minutes before exiting, so a pass over the
42
+ # completed file would show nothing until then. fflush defeats awk's block
43
+ # buffering, which otherwise withholds matches whenever stdout is a pipe.
44
+ # awk writes the debug log itself rather than piping through tee, so the
45
+ # reader stays a single process that a kill can always release.
46
+ awk \
47
+ -v pattern="$patterns" \
48
+ -v lines_after="$lines_after" \
49
+ -v debug_log="$debug_log" '
50
+ {
51
+ print > debug_log
52
+ }
53
+ $0 ~ pattern {
54
+ remaining = lines_after + 1
55
+ }
56
+ remaining > 0 {
57
+ print
58
+ fflush()
59
+ remaining--
60
+ }
61
+ ' <"$fifo_dir/merged" &
62
+ filter_pid=$!
63
+
64
+ # stderr is duplicated: on its own for the native error and stack trace, and
65
+ # into the merged stream so both the debug log and the filter see it in
66
+ # chronological order with stdout.
67
+ tee -a "$error_log" <"$fifo_dir/stderr" >"$fifo_dir/merged" &
68
+ stderr_pid=$!
69
+
70
+ "$@" >"$fifo_dir/merged" 2>"$fifo_dir/stderr" || status=$?
71
+
72
+ # Drain both readers before the paths are printed, or the trace can still be
73
+ # in flight. Bounded: a command that leaks a child holding a stream open must
74
+ # not hang the deployment, and by then everything read has been written.
75
+ run_quiet_drain "$stderr_pid"
76
+ run_quiet_drain "$filter_pid"
77
+ rm -rf "$fifo_dir"
78
+
79
+ if [ "$status" -ne 0 ]; then
80
+ printf '%s✖ %s failed (exit %s)\n error trace: %s\n debug log: %s%s\n' \
81
+ "$RUN_QUIET_RED" "$label" "$status" "$error_log" "$debug_log" "$RUN_QUIET_RESET" >&2
82
+ return "$status"
83
+ fi
84
+
85
+ rm -f "$debug_log" "$error_log"
86
+
87
+ return "$status"
88
+ }
89
+
90
+ run_quiet_drain() {
91
+ local pid="$1"
92
+
93
+ timeout 10 tail --pid="$pid" -f /dev/null 2>/dev/null || true
94
+ kill "$pid" 2>/dev/null || true
95
+ wait "$pid" 2>/dev/null || true
96
+ }
@@ -0,0 +1,72 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
+ source "$SCRIPT_DIR/../lib/logging.sh"
6
+
7
+ # Runs in the workflow's rockylinux:9 container against the checked-out
8
+ # workspace instead of over SSH, so the repository root is this script's
9
+ # grandparent rather than a fixed remote path.
10
+ REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
11
+
12
+ main() {
13
+ echo "Starting github pages deploy"
14
+
15
+ cd "$REPO_ROOT"
16
+
17
+ run_quiet \
18
+ "Install required packages" \
19
+ "Target pod:" \
20
+ 14 \
21
+ dnf install -y sudo tar gzip bzip2 git
22
+
23
+ run_quiet \
24
+ "Install curl" \
25
+ "Target pod:" \
26
+ 14 \
27
+ dnf install -y curl --allowerasing
28
+
29
+ run_quiet \
30
+ "Add Node.js repository" \
31
+ "Target pod:" \
32
+ 14 \
33
+ bash -c "curl -fsSL https://rpm.nodesource.com/setup_24.x | bash -"
34
+
35
+ run_quiet \
36
+ "Install Node.js" \
37
+ "Target pod:" \
38
+ 14 \
39
+ dnf install nodejs -y
40
+
41
+ run_quiet \
42
+ "Install dependencies" \
43
+ "Target pod:" \
44
+ 14 \
45
+ npm install
46
+
47
+ run_quiet \
48
+ "Build dd-github-pages configuration" \
49
+ "Target pod:" \
50
+ 14 \
51
+ node bin new --default-conf --conf-workflow-id dd-github-pages
52
+
53
+ run_quiet \
54
+ "Create dd-github-pages deployment" \
55
+ "Target pod:" \
56
+ 14 \
57
+ node bin new --deploy-id dd-github-pages
58
+
59
+ run_quiet \
60
+ "Load dd-github-pages production environment" \
61
+ "Target pod:" \
62
+ 14 \
63
+ node bin env dd-github-pages production
64
+
65
+ run_quiet \
66
+ "Build dd-github-pages client" \
67
+ "Target pod:" \
68
+ 14 \
69
+ env NODE_ENV=production node bin client dd-github-pages '' underpostnet.github.io /pwa-microservices-template-ghpkg
70
+ }
71
+
72
+ main "$@"
@@ -0,0 +1,62 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
+ source "$SCRIPT_DIR/../lib/logging.sh"
6
+
7
+ ENGINE_ROOT=/home/dd/engine
8
+
9
+ main() {
10
+ echo "Starting remote release deploy"
11
+
12
+ run_quiet \
13
+ "Pull repository" \
14
+ "Target pod:" \
15
+ 14 \
16
+ sudo -n -- /bin/bash -lc \
17
+ "cd $ENGINE_ROOT && node bin run pull"
18
+
19
+ run_quiet \
20
+ "Install dependencies" \
21
+ "Target pod:" \
22
+ 14 \
23
+ sudo -n -- /bin/bash -lc \
24
+ "cd $ENGINE_ROOT && npm install"
25
+
26
+ run_quiet \
27
+ "Sync secrets" \
28
+ "Target pod:" \
29
+ 14 \
30
+ sudo -n -- /bin/bash -lc \
31
+ "cd $ENGINE_ROOT && node bin run secret"
32
+
33
+ run_quiet \
34
+ "Install underpost CLI" \
35
+ "Target pod:" \
36
+ 14 \
37
+ sudo -n -- /bin/bash -lc \
38
+ "cd $ENGINE_ROOT && npm install -g underpost"
39
+
40
+ run_quiet \
41
+ "Resync secrets" \
42
+ "Target pod:" \
43
+ 14 \
44
+ sudo -n -- /bin/bash -lc \
45
+ "cd $ENGINE_ROOT && node bin run secret"
46
+
47
+ run_quiet \
48
+ "Configure git" \
49
+ "Target pod:" \
50
+ 14 \
51
+ sudo -n -- /bin/bash -lc \
52
+ "cd $ENGINE_ROOT && node bin run --dev git-conf"
53
+
54
+ run_quiet \
55
+ "Build and publish docker images" \
56
+ "Target pod:" \
57
+ 14 \
58
+ sudo -n -- /bin/bash -lc \
59
+ "cd $ENGINE_ROOT && node bin run docker-image"
60
+ }
61
+
62
+ main "$@"