@underpostnet/cyberia 3.2.80 → 3.2.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +34 -15
- package/.github/workflows/cyberia-client.cd.yml +13 -1
- package/.github/workflows/cyberia-server.cd.yml +13 -1
- package/.github/workflows/docker-image.cyberia-client.ci.yml +4 -4
- package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +4 -4
- package/.github/workflows/docker-image.cyberia-server.ci.yml +4 -4
- package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +4 -4
- package/.github/workflows/docker-image.engine-cyberia.ci.yml +3 -3
- package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +3 -3
- package/.github/workflows/engine-cyberia.cd.yml +14 -3
- package/CHANGELOG.md +182 -1
- package/CLI-HELP.md +37 -16
- package/Dockerfile +1 -1
- package/Dockerfile.dev +1 -1
- package/Dockerfile.test +1 -1
- package/bin/cyberia.js +203 -49
- package/bin/deploy.js +18 -16
- package/bin/index.js +203 -49
- package/compose.env +34 -15
- package/deployment.yaml +1 -210
- package/docker-compose.yml +73 -62
- package/hardhat/package-lock.json +134 -126
- package/hardhat/package.json +2 -2
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +1 -210
- package/manifests/deployment/dd-cyberia-development/gateway.yaml +80 -0
- package/manifests/deployment/dd-cyberia-development/httproute.yaml +504 -0
- package/manifests/deployment/dd-cyberia-development/proxy.yaml +12 -12
- package/manifests/deployment/dd-cyberia-development/pv-pvc.yaml +0 -82
- package/manifests/deployment/dd-cyberia-development/traffic-service.yaml +121 -0
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/playwright/deployment.yaml +1 -1
- package/manifests/mongodb/kustomization.yaml +4 -1
- package/manifests/mongodb/statefulset.yaml +4 -0
- package/manifests/mongodb/storage-class.yaml +9 -2
- package/nginx.conf +86 -16
- package/package.json +2 -2
- package/proxy.yaml +12 -12
- package/pv-pvc.yaml +0 -82
- package/scripts/nat-iptables.sh +10 -4
- package/scripts/test-monitor.sh +4 -3
- package/src/api/cyberia-action/cyberia-action.model.js +1 -0
- package/src/api/cyberia-instance/cyberia-fallback-world.js +41 -14
- package/src/api/cyberia-instance/cyberia-instance-map.service.js +8 -12
- package/src/api/cyberia-instance/cyberia-portal-connector.js +7 -5
- package/src/api/cyberia-instance/cyberia-random-source.js +80 -0
- package/src/api/cyberia-instance/cyberia-world-generator.js +4 -3
- package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +73 -0
- package/src/cli/cluster.js +740 -55
- package/src/cli/db.js +2 -2
- package/src/cli/deploy.js +1679 -174
- package/src/cli/docker-compose.js +19 -178
- package/src/cli/image.js +15 -6
- package/src/cli/index.js +124 -35
- package/src/cli/ipfs.js +82 -11
- package/src/cli/monitor.js +1 -1
- package/src/cli/repository.js +1 -1
- package/src/cli/run.js +2161 -420
- package/src/cli/secrets.js +969 -0
- package/src/cli/ssh.js +8 -28
- package/src/client/components/cyberia/InstanceSelectionView.js +11 -8
- package/src/client/components/cyberia/SharedDefaultsCyberia.js +5 -0
- package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +106 -39
- package/src/client/public/cyberia-docs/ARCHITECTURE.md +18 -0
- package/src/client/public/cyberia-docs/CYBERIA-CLI.md +44 -7
- package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
- package/src/client-builder/client-build.js +94 -11
- package/src/client-builder/ssr.js +27 -73
- package/src/db/mongo/MongoBootstrap.js +295 -54
- package/src/db/mongo/MongooseDB.js +47 -32
- package/src/index.js +1 -1
- package/src/projects/cyberia/besu-genesis-generator.js +3 -2
- package/src/projects/cyberia/hot-reload-trigger.js +3 -3
- package/src/projects/cyberia/instance-data.js +42 -1
- package/src/runtime/cyberia-client/Dockerfile +1 -1
- package/src/runtime/cyberia-client/Dockerfile.dev +1 -1
- package/src/runtime/cyberia-server/Dockerfile +1 -1
- package/src/runtime/cyberia-server/Dockerfile.dev +1 -1
- package/src/runtime/engine-cyberia/Dockerfile +1 -1
- package/src/runtime/engine-cyberia/Dockerfile.dev +1 -1
- package/src/runtime/engine-cyberia/Dockerfile.test +1 -1
- package/src/runtime/engine-cyberia/compose.env +34 -15
- package/src/runtime/engine-cyberia/docker-compose.yml +73 -62
- package/src/runtime/engine-cyberia/nginx.conf +86 -16
- package/src/server/conf.js +1208 -70
- package/src/server/cri.js +70 -0
- package/src/server/underpost-gateway.js +1073 -0
- package/src/server/underpost-ingress.js +364 -0
- package/test/cluster-instances.test.js +435 -0
- package/test/deploy-node-placement.test.js +45 -0
- package/test/instance-traffic-plan.test.js +710 -0
- package/test/sops-secret-store.test.js +612 -0
- package/test/underpost-gateway.test.js +469 -0
- package/test/underpost-ingress.test.js +253 -0
package/CLI-HELP.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
## Underpost CLI
|
|
2
2
|
|
|
3
|
-
> underpost ci/cd cli v3.2.
|
|
3
|
+
> underpost ci/cd cli v3.2.90
|
|
4
4
|
|
|
5
5
|
**Usage:** `underpost [options] [command]`
|
|
6
6
|
|
|
@@ -411,7 +411,7 @@ Manages Kubernetes clusters, defaulting to Kind cluster initialization.
|
|
|
411
411
|
| Option | Description |
|
|
412
412
|
| --- | --- |
|
|
413
413
|
| `--reset` | Deletes all clusters and prunes all related data and caches. |
|
|
414
|
-
| `--reset-mongodb` | Performs a hard cleanup of only MongoDB-related resources (StatefulSet, PVCs/PVs, Secrets, ConfigMaps, caches) without restarting the whole node. |
|
|
414
|
+
| `--reset-mongodb` | Performs a hard cleanup of only MongoDB-related resources (StatefulSet, PVCs/PVs, Secrets, ConfigMaps, caches) without restarting the whole node. Combined with --mongodb it instead wipes the retained hostPath volumes as part of that deploy, so the replica set starts from empty data. |
|
|
415
415
|
| `--mariadb` | Initializes the cluster with a MariaDB statefulset. |
|
|
416
416
|
| `--mysql` | Initializes the cluster with a MySQL statefulset. |
|
|
417
417
|
| `--mongodb` | Initializes the cluster with a MongoDB statefulset. |
|
|
@@ -421,6 +421,9 @@ Manages Kubernetes clusters, defaulting to Kind cluster initialization.
|
|
|
421
421
|
| `--valkey` | Initializes the cluster with a Valkey service. |
|
|
422
422
|
| `--ipfs` | Initializes the cluster with an ipfs-cluster statefulset. |
|
|
423
423
|
| `--contour` | Initializes the cluster with Project Contour base HTTPProxy and Envoy. |
|
|
424
|
+
| `--gateway-api` | Initializes the cluster with the Gateway API control plane (CRDs, Envoy Gateway, GatewayClass) used by generated HTTPRoute + QUIC/HTTP3 manifests. With --dev the data plane binds the listener ports on the host network for direct browser access. |
|
|
425
|
+
| `--gateway-class <name>` | GatewayClass name to provision (default "eg"). |
|
|
426
|
+
| `--ingress-node <node-name>` | Dedicated node for underpost-ingress when both routing stacks coexist. Workload placement flags do not move it. |
|
|
424
427
|
| `--node-port` | Exposes enabled ready services (e.g. MongoDB 4.4, Valkey) to the host/public network via their NodePort Service manifest. |
|
|
425
428
|
| `--node-selector <k8s-node-name>` | Pins the just-deployed StatefulSet (MongoDB 4.4 / Valkey) to the given Kubernetes node once it is ready (via a kubernetes.io/hostname nodeSelector). |
|
|
426
429
|
| `--cert-manager` | Initializes the cluster with a Let's Encrypt production ClusterIssuer. |
|
|
@@ -468,13 +471,14 @@ Manages application deployments, defaulting to deploying development pods.
|
|
|
468
471
|
| `--remove` | Deletes specified deployments and their associated services. |
|
|
469
472
|
| `--sync` | Synchronizes deployment environment variables, ports, and replica counts. |
|
|
470
473
|
| `--info-router` | Displays the current router structure and configuration. |
|
|
471
|
-
| `--expose` | Exposes services matching the provided deployment ID list. |
|
|
472
474
|
| `--cert` | Resets TLS/SSL certificate secrets for deployments. |
|
|
473
475
|
| `--cert-hosts <hosts>` | Resets TLS/SSL certificate secrets for specified hosts. |
|
|
474
476
|
| `--self-signed` | Use a pre-created self-signed TLS secret (kubernetes.io/tls) instead of cert-manager. The secret must already exist in the namespace with the same name as the host. Enables TLS in the Contour HTTPProxy virtualhost without requiring a production ClusterIssuer. |
|
|
475
477
|
| `--node <node>` | Sets optional node for deployment operations. |
|
|
478
|
+
| `--ingress-node <node-name>` | Explicitly relocates the shared host-network ingress; ordinary --node placement never moves it. |
|
|
476
479
|
| `--ssh-key-path <path>` | Private key path for node SSH operations. Currently used when shipping a hostPath volume to a remote target node over SSH. Defaults to engine-private/deploy/id_rsa. |
|
|
477
480
|
| `--build-manifest` | Builds Kubernetes YAML manifests, including deployments, services, proxies, and secrets. |
|
|
481
|
+
| `--sync-static` | Places the SSR status pages and intercepted contexts in the gateway static utility tree, so the edge serves them instead of the application pods. Prefers the running workload and falls back to this checkout, so it can seed the tree before the deployment exists and refresh it once the deployment is Ready. |
|
|
478
482
|
| `--replicas <replicas>` | Sets a custom number of replicas for deployments. |
|
|
479
483
|
| `--image <image>` | Sets a custom image for deployments. |
|
|
480
484
|
| `--versions <deployment-versions>` | A comma-separated list of custom deployment versions. |
|
|
@@ -484,28 +488,25 @@ Manages application deployments, defaulting to deploying development pods.
|
|
|
484
488
|
| `--retry-count <count>` | Sets HTTPProxy per-route retry count (e.g., 3). |
|
|
485
489
|
| `--retry-per-try-timeout <duration>` | Sets HTTPProxy retry per-try timeout (e.g., "150ms"). |
|
|
486
490
|
| `--disable-update-deployment` | Disables updates to deployments. |
|
|
487
|
-
| `--disable-runtime-probes` |
|
|
491
|
+
| `--disable-runtime-probes` | Deprecated compatibility flag; readiness probes remain mandatory. Use --tcp-probes for legacy workloads. |
|
|
488
492
|
| `--tcp-probes` | Generates legacy TCP socket probes instead of HTTP internal-status probes (migration). |
|
|
489
493
|
| `--disable-update-proxy` | Disables updates to proxies. |
|
|
490
494
|
| `--disable-deployment-proxy` | Disables proxies of deployments. |
|
|
495
|
+
| `--gateway-api` | Routes through the Gateway API stack (Gateway + HTTPRoute) instead of the Contour HTTPProxy. Both manifest sets are always generated; this selects which one is applied. |
|
|
496
|
+
| `--gateway-class <name>` | GatewayClass name for generated Gateway manifests (default "eg"). |
|
|
497
|
+
| `--disable-http3` | Omits the QUIC/HTTP3 listener config and the Alt-Svc advertisement from Gateway API manifests. |
|
|
498
|
+
| `--quic-port <port>` | UDP port advertised for QUIC/HTTP3 in generated Gateway API manifests (default 443). |
|
|
491
499
|
| `--disable-update-volume` | Disables updates to volume mounts during deployment. |
|
|
492
|
-
| `--status` | Retrieves current network traffic data from resource deployments and the host machine network configuration. |
|
|
493
500
|
| `--kubeadm` | Enables the kubeadm context for deployment operations. |
|
|
494
501
|
| `--k3s` | Enables the k3s context for deployment operations. |
|
|
495
502
|
| `--kind` | Enables the kind context for deployment operations. |
|
|
496
503
|
| `--git-clean` | Runs git clean on volume mount paths before copying. |
|
|
497
504
|
| `--disable-update-underpost-config` | Disables updates to Underpost configuration during deployment. |
|
|
498
505
|
| `--namespace <namespace>` | Kubernetes namespace for deployment operations (defaults to "default"). |
|
|
499
|
-
| `--kind-type <kind-type>` | Specifies the Kind cluster type for deployment operations. |
|
|
500
|
-
| `--port <port>` | Sets up port forwarding from local to remote ports. |
|
|
501
|
-
| `--expose-port <port>` | Sets the local:remote port to expose when --expose is active (overrides auto-detected service port). |
|
|
502
|
-
| `--expose-local-port <port>` | Sets a different local port for --expose (e.g. 80) while keeping the remote service port. Useful for /etc/hosts local access without specifying a port in the browser. |
|
|
503
|
-
| `--local-proxy` | Forward all service TCP ports locally and start the Node.js path-routing proxy. Enables full path-based routing (e.g. /wp alongside /) without needing --expose-local-port. Requires --expose. |
|
|
504
506
|
| `--cmd <cmd>` | Custom initialization command for deployment (comma-separated commands). |
|
|
505
507
|
| `--skip-full-build` | Skip client bundle rebuild; container will pull pre-built bundle via pull-bundle instead. |
|
|
506
508
|
| `--pull-bundle` | Explicitly pull the pre-built client bundle from Cloudinary inside the container. Use together with --skip-full-build. |
|
|
507
509
|
| `--image-pull-policy <policy>` | Override container imagePullPolicy in the generated deployment manifest (Always, IfNotPresent, Never). Defaults to Never for localhost/ images and IfNotPresent otherwise. |
|
|
508
|
-
| `--tls` | Enables TLS for the local proxy started by --expose --local-proxy. The proxy will serve HTTPS on port 443 using self-signed certificates resolved from the local SSL store. Use together with --expose and --local-proxy. |
|
|
509
510
|
| `-h, --help` | display help for command |
|
|
510
511
|
|
|
511
512
|
---
|
|
@@ -514,13 +515,13 @@ Manages application deployments, defaulting to deploying development pods.
|
|
|
514
515
|
|
|
515
516
|
Manages secrets for various platforms.
|
|
516
517
|
|
|
517
|
-
**Usage:** `underpost secret [options]
|
|
518
|
+
**Usage:** `underpost secret [options] [platform]`
|
|
518
519
|
|
|
519
520
|
#### Arguments
|
|
520
521
|
|
|
521
522
|
| Argument | Description |
|
|
522
523
|
| --- | --- |
|
|
523
|
-
| `platform` | The secret management platform. Options: underpost, sanitizeSecretEnvFile, globalSecretClean. |
|
|
524
|
+
| `platform` | The secret management platform. Options: underpost, sops, sanitizeSecretEnvFile, globalSecretClean. Defaults to "sops". (default: "sops") |
|
|
524
525
|
|
|
525
526
|
#### Options
|
|
526
527
|
|
|
@@ -531,6 +532,17 @@ Manages secrets for various platforms.
|
|
|
531
532
|
| `--create-from-env` | Creates secrets from container environment variables (envFrom: secretRef). |
|
|
532
533
|
| `--global-clean` | Removes all filesystem traces of secrets (engine-private, .env, conf cache). |
|
|
533
534
|
| `--list` | Lists all available secrets for the platform. |
|
|
535
|
+
| `--encrypt <plaintext-path>` | Encrypts a plaintext Secret manifest into the Git-tracked SOPS store and shreds the source (sops platform). |
|
|
536
|
+
| `--apply` | Decrypts stored SOPS manifests and streams them into kubectl apply, without writing plaintext to disk (sops platform). |
|
|
537
|
+
| `--namespace <namespace>` | Kubernetes namespace for secret operations (defaults to "default"). |
|
|
538
|
+
| `--install-tools` | Installs the sops and age host binaries only, without running a full cluster host initialization. |
|
|
539
|
+
| `--rotate` | Re-keys every stored SOPS manifest onto --recipient. Secret values are unchanged, so no workload restart is needed. |
|
|
540
|
+
| `--recipient <age-public-key>` | Incoming Age public recipient for --rotate. |
|
|
541
|
+
| `--prune-recipients` | With --rotate, makes --recipient the only recipient, revoking every previous key (use after a key compromise). Requires --force, and revokes CI/CD keys too unless they are named in --keep-recipients. |
|
|
542
|
+
| `--keep-recipients <age-public-keys>` | Comma-separated recipients to retain while --prune-recipients revokes the rest (e.g. the CI/CD key). |
|
|
543
|
+
| `--purge <secret-name>` | Emergency removal: deletes the live Kubernetes Secret and takes its encrypted manifest out of the store. |
|
|
544
|
+
| `--force` | Confirms the irreversible variant: deletes the manifest instead of archiving it (--purge), revokes recipients (--rotate --prune-recipients), or replaces an existing manifest (--encrypt). |
|
|
545
|
+
| `--dry-run` | Reports what --apply, --rotate, or --purge would do without changing anything. |
|
|
534
546
|
| `-h, --help` | display help for command |
|
|
535
547
|
|
|
536
548
|
---
|
|
@@ -825,7 +837,7 @@ Runs specified scripts using various runners.
|
|
|
825
837
|
|
|
826
838
|
| Argument | Description |
|
|
827
839
|
| --- | --- |
|
|
828
|
-
| `runner-id` | The runner ID to run. Options: dev-cluster,
|
|
840
|
+
| `runner-id` | The runner ID to run. Options: status,expose,dev-cluster,metadata,ipfs-expose,svc-ls,svc-rm,node-move,dev-hosts-expose,dev-hosts-restore,cluster-build,template-deploy,template-deploy-local,docker-image,clean,pull,release-deploy,ssh-deploy,ide,crypto-policy,sync,stop,tz,get-traffic,restore-mongo,ingress-refresh,instance-promote,instance,deploy-key,instance-build-manifest,ls-deployments,host-update,install-crio,dd-container,ip-info,db-client,git-conf,promote,metrics,cluster,gateway-status,deploy,disk-clean,disk-devices,disk-usage,dev,service,etc-hosts,sh,log,ps,pid-info,background,ports,deploy-test,tf-vae-test,spark-template,pull-rocky-image,rmi,kill,generate-pass,sops-setup,sops-status,secret,underpost-config,gpu-env,tf-gpu-test,deploy-job,push-bundle,pull-bundle,build-cluster-deployment-manifests,monitor-ui,shared-dir,shared-dir-add-user. |
|
|
829
841
|
| `path` | The input value, identifier, or path for the operation. |
|
|
830
842
|
|
|
831
843
|
#### Options
|
|
@@ -839,8 +851,12 @@ Runs specified scripts using various runners.
|
|
|
839
851
|
| `--replicas <replicas>` | Sets a custom number of replicas for deployment. |
|
|
840
852
|
| `--pod-name <pod-name>` | Optional: Specifies the pod name for execution. |
|
|
841
853
|
| `--node-name <node-name>` | Optional: Specifies the node name for execution. |
|
|
854
|
+
| `--ingress-node <node-name>` | Dedicated node for the host-network underpost-ingress listener. Workload --node-name never relocates it. |
|
|
842
855
|
| `--ssh-key-path <path>` | Optional: Private key path for node SSH operations, forwarded to volume shipping over SSH. Defaults to engine-private/deploy/id_rsa. |
|
|
843
856
|
| `--port <port>` | Optional: Specifies the port for execution. |
|
|
857
|
+
| `--expose-container-ports <ports>` | Comma-separated Service/container ports; multiple matched resources consume values by resource index. |
|
|
858
|
+
| `--expose-host-ports <ports>` | Comma-separated host ports paired with container ports by resource/port index. |
|
|
859
|
+
| `--local-proxy` | Starts the development path proxy after the expose runner creates its port-forwards. |
|
|
844
860
|
| `--etc-hosts` | Enables etc-hosts context for the runner execution. |
|
|
845
861
|
| `--volume-host-path <volume-host-path>` | Optional: Specifies the volume host path for test execution. |
|
|
846
862
|
| `--volume-mount-path <volume-mount-path>` | Optional: Specifies the volume mount path for test execution. |
|
|
@@ -867,7 +883,7 @@ Runs specified scripts using various runners.
|
|
|
867
883
|
| `--limits-memory <limits-memory>` | Sets memory limit for the runner execution. |
|
|
868
884
|
| `--limits-cpu <limits-cpu>` | Sets CPU limit for the runner execution. |
|
|
869
885
|
| `--resource-template-id <resource-template-id >` | Specifies a resource template ID for the runner execution. |
|
|
870
|
-
| `--expose` | Enables
|
|
886
|
+
| `--expose` | Enables exposure-only behavior in compatible runners; the expose runner itself does not require this flag. |
|
|
871
887
|
| `--conf-server-path <conf-server-path>` | Sets a custom configuration server path. |
|
|
872
888
|
| `--underpost-root <underpost-root>` | Sets a custom Underpost root path. |
|
|
873
889
|
| `--cmd-cron-jobs <cmd-cron-jobs>` | Pre-script commands to run before cron job execution. |
|
|
@@ -876,7 +892,7 @@ Runs specified scripts using various runners.
|
|
|
876
892
|
| `--kubeadm` | Sets the kubeadm cluster context for the runner execution. |
|
|
877
893
|
| `--k3s` | Sets the k3s cluster context for the runner execution. |
|
|
878
894
|
| `--kind` | Sets the kind cluster context for the runner execution. |
|
|
879
|
-
| `--traffic <traffic>` | Blue/green traffic colour to bake into generated manifests (default: blue). |
|
|
895
|
+
| `--traffic <traffic>` | Blue/green traffic colour to bake into generated manifests (default: blue). `stop` accepts a comma list, e.g. blue,green. |
|
|
880
896
|
| `--git-clean` | Runs git clean on volume mount paths before copying. |
|
|
881
897
|
| `--deploy-id <deploy-id>` | Sets deploy id context for the runner execution. |
|
|
882
898
|
| `--user <user>` | Sets user context for the runner execution. |
|
|
@@ -887,6 +903,11 @@ Runs specified scripts using various runners.
|
|
|
887
903
|
| `--timeout-idle <duration>` | Sets HTTPProxy per-route idle timeout (e.g., "10s", "infinity"). |
|
|
888
904
|
| `--retry-count <count>` | Sets HTTPProxy per-route retry count (e.g., 3). |
|
|
889
905
|
| `--retry-per-try-timeout <duration>` | Sets HTTPProxy retry per-try timeout (e.g., "150ms"). |
|
|
906
|
+
| `--gateway-api` | Routes through the Gateway API stack (Gateway + HTTPRoute) instead of the Contour HTTPProxy. Both manifest sets are always generated; this selects which one is applied. |
|
|
907
|
+
| `--disable-gateway-api` | Falls back to the Contour HTTPProxy stack in runners where the Gateway API is the default (cluster). |
|
|
908
|
+
| `--gateway-class <name>` | GatewayClass name for generated Gateway manifests (default "eg"). |
|
|
909
|
+
| `--disable-http3` | Omits the QUIC/HTTP3 listener config and the Alt-Svc advertisement from Gateway API manifests. |
|
|
910
|
+
| `--quic-port <port>` | UDP port advertised for QUIC/HTTP3 in generated Gateway API manifests (default 443). |
|
|
890
911
|
| `--disable-private-conf-update` | Disables updates to private configuration during execution. |
|
|
891
912
|
| `--logs` | Streams logs during the runner execution. |
|
|
892
913
|
| `--monitor-status <status>` | Sets the status to monitor for pod/resource (default: "Running"). |
|
package/Dockerfile
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# Stage 1 — builder: clone the private deploy, build it, then scrub secrets.
|
|
7
7
|
# ---------------------------------------------------------------------------
|
|
8
8
|
FROM rockylinux/rockylinux:9 AS builder
|
|
9
|
-
ARG UNDERPOST_VERSION=3.2.
|
|
9
|
+
ARG UNDERPOST_VERSION=3.2.90
|
|
10
10
|
# Pin Node to an exact patch: dnf's nodejs:24 module lags (24.14.1) while
|
|
11
11
|
# underpost's dependencies require >=24.15.0, so install the official binary.
|
|
12
12
|
ARG NODE_VERSION=24.15.0
|
package/Dockerfile.dev
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# Stage 1 — builder: clone the private deploy, build it, then scrub secrets.
|
|
7
7
|
# ---------------------------------------------------------------------------
|
|
8
8
|
FROM rockylinux/rockylinux:9 AS builder
|
|
9
|
-
ARG UNDERPOST_VERSION=3.2.
|
|
9
|
+
ARG UNDERPOST_VERSION=3.2.90
|
|
10
10
|
# Pin Node to an exact patch: dnf's nodejs:24 module lags (24.14.1) while
|
|
11
11
|
# underpost's dependencies require >=24.15.0, so install the official binary.
|
|
12
12
|
ARG NODE_VERSION=24.15.0
|
package/Dockerfile.test
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# Stage 1 — builder: clone the private deploy, build it, then scrub secrets.
|
|
7
7
|
# ---------------------------------------------------------------------------
|
|
8
8
|
FROM rockylinux/rockylinux:9 AS builder
|
|
9
|
-
ARG UNDERPOST_VERSION=3.2.
|
|
9
|
+
ARG UNDERPOST_VERSION=3.2.90
|
|
10
10
|
# Pin Node to an exact patch: dnf's nodejs:24 module lags (24.14.1) while
|
|
11
11
|
# underpost's dependencies require >=24.15.0, so install the official binary.
|
|
12
12
|
ARG NODE_VERSION=24.15.0
|
package/bin/cyberia.js
CHANGED
|
@@ -17,7 +17,7 @@ import { shellExec } from '../src/server/process.js';
|
|
|
17
17
|
import { loggerFactory } from '../src/server/logger.js';
|
|
18
18
|
import { generateBesuManifests, deployBesu, removeBesu } from '../src/projects/cyberia/besu-genesis-generator.js';
|
|
19
19
|
import { DataBaseProviderService } from '../src/db/DataBaseProvider.js';
|
|
20
|
-
import { loadConfServerJson } from '../src/server/conf.js';
|
|
20
|
+
import { etcHostFactory, loadConfServerJson, normalizeInstanceTopology } from '../src/server/conf.js';
|
|
21
21
|
import {
|
|
22
22
|
ObjectLayerEngine,
|
|
23
23
|
resolveCanonicalCid,
|
|
@@ -51,6 +51,7 @@ import {
|
|
|
51
51
|
} from '../src/api/cyberia-server-defaults/cyberia-server-defaults.js';
|
|
52
52
|
|
|
53
53
|
import {
|
|
54
|
+
DEFAULT_INSTANCE_CODE,
|
|
54
55
|
ITEM_TYPES as itemTypes,
|
|
55
56
|
DefaultCyberiaItems,
|
|
56
57
|
} from '../src/client/components/cyberia/SharedDefaultsCyberia.js';
|
|
@@ -95,6 +96,22 @@ async function connectDbForChain({ envPath, mongoHost }) {
|
|
|
95
96
|
/** @type {Function} */
|
|
96
97
|
const logger = loggerFactory(import.meta);
|
|
97
98
|
|
|
99
|
+
const CYBERIA_DOCKER_HOST_ALIASES = ['cyberia-client', 'cyberia-server', 'engine-cyberia'];
|
|
100
|
+
|
|
101
|
+
const installCyberiaDockerHostAliases = () => {
|
|
102
|
+
try {
|
|
103
|
+
const { changed } = etcHostFactory(CYBERIA_DOCKER_HOST_ALIASES, {
|
|
104
|
+
append: true,
|
|
105
|
+
blockId: 'dd-cyberia-docker-compose',
|
|
106
|
+
});
|
|
107
|
+
return { aliases: CYBERIA_DOCKER_HOST_ALIASES, changed };
|
|
108
|
+
} catch (error) {
|
|
109
|
+
if (error?.code === 'EACCES' || error?.code === 'EPERM')
|
|
110
|
+
throw new Error('Cannot update /etc/hosts for Cyberia Docker aliases. Re-run the workflow as root.');
|
|
111
|
+
throw error;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
98
115
|
try {
|
|
99
116
|
const program = new Command();
|
|
100
117
|
|
|
@@ -219,7 +236,6 @@ try {
|
|
|
219
236
|
deployId,
|
|
220
237
|
host,
|
|
221
238
|
path,
|
|
222
|
-
db,
|
|
223
239
|
});
|
|
224
240
|
|
|
225
241
|
await DataBaseProviderService.load({
|
|
@@ -1954,7 +1970,7 @@ try {
|
|
|
1954
1970
|
? db.host
|
|
1955
1971
|
: db.host.replace('127.0.0.1', 'mongodb-0.mongodb-service');
|
|
1956
1972
|
|
|
1957
|
-
logger.info('instance env', { env: options.envPath, deployId, host, path
|
|
1973
|
+
logger.info('instance env', { env: options.envPath, deployId, host, path });
|
|
1958
1974
|
|
|
1959
1975
|
await DataBaseProviderService.load({
|
|
1960
1976
|
apis: [
|
|
@@ -3892,7 +3908,7 @@ try {
|
|
|
3892
3908
|
? db.host
|
|
3893
3909
|
: db.host.replace('127.0.0.1', 'mongodb-0.mongodb-service');
|
|
3894
3910
|
|
|
3895
|
-
logger.info('generate-saga', { deployId, host, path
|
|
3911
|
+
logger.info('generate-saga', { deployId, host, path });
|
|
3896
3912
|
|
|
3897
3913
|
await DataBaseProviderService.load({
|
|
3898
3914
|
apis: [
|
|
@@ -4835,6 +4851,7 @@ try {
|
|
|
4835
4851
|
'--clean',
|
|
4836
4852
|
'Restore repositories to canonical state (git checkout Dockerfile, etc.) before updating compose.env',
|
|
4837
4853
|
)
|
|
4854
|
+
.option('--test', 'Test DNS connectivity accross cyberia deployments')
|
|
4838
4855
|
.option('--reset', 'Reset the development environment before updating compose.env')
|
|
4839
4856
|
.action((options) => {
|
|
4840
4857
|
if (options.reset) {
|
|
@@ -4848,6 +4865,25 @@ try {
|
|
|
4848
4865
|
shellExec(`node bin run clean ./cyberia-client`);
|
|
4849
4866
|
return;
|
|
4850
4867
|
}
|
|
4868
|
+
if (options.test) {
|
|
4869
|
+
const testHosts = [
|
|
4870
|
+
'localhost',
|
|
4871
|
+
'localhost:4005',
|
|
4872
|
+
'localhost:8081',
|
|
4873
|
+
'localhost:8082',
|
|
4874
|
+
'engine-cyberia',
|
|
4875
|
+
'cyberia-server',
|
|
4876
|
+
'cyberia-client',
|
|
4877
|
+
];
|
|
4878
|
+
const testPaths = ['/', '/TEST', '/FOREST'];
|
|
4879
|
+
for (const host of testHosts) {
|
|
4880
|
+
for (const path of testPaths) {
|
|
4881
|
+
shellExec(`curl -L -v -i -s http://${host}${path} | head -n 10`, {
|
|
4882
|
+
silentOnError: true,
|
|
4883
|
+
});
|
|
4884
|
+
}
|
|
4885
|
+
}
|
|
4886
|
+
}
|
|
4851
4887
|
const envPath = `./engine-private/conf/dd-cyberia/docker-compose/cyberia/compose.env`;
|
|
4852
4888
|
const canonicalDevDockerfile = './src/runtime/engine-cyberia/Dockerfile.dev';
|
|
4853
4889
|
fs.writeFileSync(
|
|
@@ -4930,7 +4966,7 @@ try {
|
|
|
4930
4966
|
? db.host
|
|
4931
4967
|
: db.host.replace('127.0.0.1', 'mongodb-0.mongodb-service');
|
|
4932
4968
|
|
|
4933
|
-
logger.info('drop-db', { deployId, host, path
|
|
4969
|
+
logger.info('drop-db', { deployId, host, path });
|
|
4934
4970
|
|
|
4935
4971
|
const cyberiaCollections = [
|
|
4936
4972
|
'cyberia-entity',
|
|
@@ -4997,7 +5033,7 @@ try {
|
|
|
4997
5033
|
// no funca
|
|
4998
5034
|
if (options.loadTar) {
|
|
4999
5035
|
for (const imageId of dockerImageIds)
|
|
5000
|
-
if (imageId === id || id === '.') shellExec(`docker load -i ./${imageId}-dev_v3.2.
|
|
5036
|
+
if (imageId === id || id === '.') shellExec(`docker load -i ./${imageId}-dev_v3.2.90.tar`);
|
|
5001
5037
|
return;
|
|
5002
5038
|
}
|
|
5003
5039
|
switch (id) {
|
|
@@ -5008,7 +5044,7 @@ node bin/build dd-cyberia --update-private
|
|
|
5008
5044
|
node bin image --path src/runtime/engine-cyberia \
|
|
5009
5045
|
--docker-compose --pull-base --build \
|
|
5010
5046
|
--dockerfile-name Dockerfile.dev \
|
|
5011
|
-
--image-name engine-cyberia-dev:v3.2.
|
|
5047
|
+
--image-name engine-cyberia-dev:v3.2.90 \
|
|
5012
5048
|
--image-out-path .
|
|
5013
5049
|
`);
|
|
5014
5050
|
break;
|
|
@@ -5019,7 +5055,7 @@ cp -f src/runtime/cyberia-server/Dockerfile.dev cyberia-server/Dockerfile.dev
|
|
|
5019
5055
|
node bin image --path cyberia-server \
|
|
5020
5056
|
--docker-compose --pull-base --build \
|
|
5021
5057
|
--dockerfile-name Dockerfile.dev \
|
|
5022
|
-
--image-name cyberia-server-dev:v3.2.
|
|
5058
|
+
--image-name cyberia-server-dev:v3.2.90 \
|
|
5023
5059
|
--image-out-path .
|
|
5024
5060
|
`);
|
|
5025
5061
|
break;
|
|
@@ -5029,7 +5065,7 @@ cp -f src/runtime/cyberia-client/Dockerfile.dev cyberia-client/Dockerfile.dev
|
|
|
5029
5065
|
node bin image --path cyberia-client \
|
|
5030
5066
|
--docker-compose --pull-base --build \
|
|
5031
5067
|
--dockerfile-name Dockerfile.dev \
|
|
5032
|
-
--image-name cyberia-client-dev:v3.2.
|
|
5068
|
+
--image-name cyberia-client-dev:v3.2.90 \
|
|
5033
5069
|
--image-out-path .
|
|
5034
5070
|
`);
|
|
5035
5071
|
break;
|
|
@@ -5038,6 +5074,10 @@ node bin image --path cyberia-client \
|
|
|
5038
5074
|
|
|
5039
5075
|
for (const [cmd, action] of Object.entries(DOCKER_SCRIPTS))
|
|
5040
5076
|
runner.command(cmd).action(() => {
|
|
5077
|
+
if (cmd === 'docker:up' || cmd === 'docker:up:build' || cmd === 'docker:restart') {
|
|
5078
|
+
const { aliases, changed } = installCyberiaDockerHostAliases();
|
|
5079
|
+
logger.info(`Docker host aliases ${changed ? 'installed' : 'already configured'}`, { aliases });
|
|
5080
|
+
}
|
|
5041
5081
|
shellExec(action);
|
|
5042
5082
|
});
|
|
5043
5083
|
|
|
@@ -5074,7 +5114,7 @@ node bin image --path cyberia-client \
|
|
|
5074
5114
|
? db.host
|
|
5075
5115
|
: db.host.replace('127.0.0.1', 'mongodb-0.mongodb-service');
|
|
5076
5116
|
|
|
5077
|
-
logger.info('seed-dialogues', { deployId, host, path
|
|
5117
|
+
logger.info('seed-dialogues', { deployId, host, path });
|
|
5078
5118
|
|
|
5079
5119
|
await DataBaseProviderService.load({ apis: ['cyberia-dialogue'], host, path, db });
|
|
5080
5120
|
|
|
@@ -5129,7 +5169,7 @@ node bin image --path cyberia-client \
|
|
|
5129
5169
|
? db.host
|
|
5130
5170
|
: db.host.replace('127.0.0.1', 'mongodb-0.mongodb-service');
|
|
5131
5171
|
|
|
5132
|
-
logger.info('seed-actions-quests', { deployId, host, path
|
|
5172
|
+
logger.info('seed-actions-quests', { deployId, host, path });
|
|
5133
5173
|
|
|
5134
5174
|
await DataBaseProviderService.load({ apis: ['cyberia-action', 'cyberia-quest'], host, path, db });
|
|
5135
5175
|
|
|
@@ -5185,7 +5225,7 @@ node bin image --path cyberia-client \
|
|
|
5185
5225
|
? db.host
|
|
5186
5226
|
: db.host.replace('127.0.0.1', 'mongodb-0.mongodb-service');
|
|
5187
5227
|
|
|
5188
|
-
logger.info('seed-skills', { deployId, host, path
|
|
5228
|
+
logger.info('seed-skills', { deployId, host, path });
|
|
5189
5229
|
|
|
5190
5230
|
await DataBaseProviderService.load({ apis: ['cyberia-skill'], host, path, db });
|
|
5191
5231
|
|
|
@@ -5245,7 +5285,7 @@ node bin image --path cyberia-client \
|
|
|
5245
5285
|
? db.host
|
|
5246
5286
|
: db.host.replace('127.0.0.1', 'mongodb-0.mongodb-service');
|
|
5247
5287
|
|
|
5248
|
-
logger.info('seed-entities', { deployId, host, path
|
|
5288
|
+
logger.info('seed-entities', { deployId, host, path });
|
|
5249
5289
|
|
|
5250
5290
|
await DataBaseProviderService.load({ apis: ['cyberia-entity-type-default'], host, path, db });
|
|
5251
5291
|
|
|
@@ -5353,6 +5393,84 @@ node bin image --path cyberia-client \
|
|
|
5353
5393
|
logger.info('All semantic examples generated.');
|
|
5354
5394
|
});
|
|
5355
5395
|
|
|
5396
|
+
// Instance id → project root. Single source of truth for the workloads this
|
|
5397
|
+
// workflow builds: both the k8s manifests and the status page artifacts each
|
|
5398
|
+
// project ships are resolved from this list plus conf.instances.json.
|
|
5399
|
+
const CYBERIA_INSTANCE_PROJECTS = [
|
|
5400
|
+
{ id: 'mmo-client', rootPath: './cyberia-client' },
|
|
5401
|
+
{ id: 'mmo-server', rootPath: './cyberia-server' },
|
|
5402
|
+
];
|
|
5403
|
+
const CYBERIA_CONF_INSTANCES_PATH = './engine-private/conf/dd-cyberia/conf.instances.json';
|
|
5404
|
+
const CYBERIA_CONF_SSR_PATH = './engine-private/conf/dd-cyberia/conf.ssr.json';
|
|
5405
|
+
// Copy shared by the server and the client for a given status code. A status
|
|
5406
|
+
// without an entry falls back to its conf.ssr.json view title.
|
|
5407
|
+
const CYBERIA_STATUS_PAGE_META = {
|
|
5408
|
+
404: {
|
|
5409
|
+
title: 'Cyberia — Sector Not Found',
|
|
5410
|
+
description: 'Cyberia Online 404 — the requested sector is not on the grid.',
|
|
5411
|
+
},
|
|
5412
|
+
};
|
|
5413
|
+
|
|
5414
|
+
/**
|
|
5415
|
+
* Reads the raw (unexpanded) conf.instances.json entries.
|
|
5416
|
+
* @returns {Array<object>} Instance entries, or an empty list when unavailable.
|
|
5417
|
+
*/
|
|
5418
|
+
const readCyberiaConfInstances = () => {
|
|
5419
|
+
try {
|
|
5420
|
+
return JSON.parse(fs.readFileSync(CYBERIA_CONF_INSTANCES_PATH, 'utf8'));
|
|
5421
|
+
} catch (err) {
|
|
5422
|
+
logger.warn(`Could not read ${CYBERIA_CONF_INSTANCES_PATH}: ${err.message}`);
|
|
5423
|
+
return [];
|
|
5424
|
+
}
|
|
5425
|
+
};
|
|
5426
|
+
|
|
5427
|
+
/**
|
|
5428
|
+
* Resolves the SSR view that renders a status page. The view is declared in
|
|
5429
|
+
* conf.ssr.json as a route whose path is the bare status code (`/404`), the
|
|
5430
|
+
* same declaration the PWA build turns into `/404/index.html`.
|
|
5431
|
+
* @param {string} status - HTTP status code.
|
|
5432
|
+
* @returns {{ client: string, title: string }|null} View descriptor, or null when undeclared.
|
|
5433
|
+
*/
|
|
5434
|
+
const resolveStatusPageView = (status) => {
|
|
5435
|
+
if (!fs.existsSync(CYBERIA_CONF_SSR_PATH)) return null;
|
|
5436
|
+
const confSSR = JSON.parse(fs.readFileSync(CYBERIA_CONF_SSR_PATH, 'utf8'));
|
|
5437
|
+
for (const clientConf of Object.values(confSSR))
|
|
5438
|
+
for (const view of clientConf?.views || []) if (view.path === `/${status}`) return view;
|
|
5439
|
+
return null;
|
|
5440
|
+
};
|
|
5441
|
+
|
|
5442
|
+
/**
|
|
5443
|
+
* Renders one custom status page to a static HTML artifact. The workloads no
|
|
5444
|
+
* longer serve error pages themselves — the document is carried into the
|
|
5445
|
+
* gateway config by `run instance-build-manifest`, so this only has to place
|
|
5446
|
+
* it at the `hostPath` the instance declares.
|
|
5447
|
+
* @param {string} status - HTTP status code.
|
|
5448
|
+
* @param {string} outputPath - Destination HTML path.
|
|
5449
|
+
* @param {boolean} [dev] - Render the development variant.
|
|
5450
|
+
* @returns {boolean} True when the artifact was rendered.
|
|
5451
|
+
*/
|
|
5452
|
+
const buildCyberiaStatusPage = ({ status, outputPath, dev = false }) => {
|
|
5453
|
+
const view = resolveStatusPageView(status);
|
|
5454
|
+
const pagePath = `./src/client/ssr/views/${view?.client || `Cyberia${status}`}.js`;
|
|
5455
|
+
if (!fs.existsSync(pagePath)) {
|
|
5456
|
+
logger.warn(`[build-status-page] No SSR view for status ${status}; skipping`, { pagePath, outputPath });
|
|
5457
|
+
return false;
|
|
5458
|
+
}
|
|
5459
|
+
const meta = CYBERIA_STATUS_PAGE_META[status] || {};
|
|
5460
|
+
const title = meta.title || view?.title || `Cyberia — ${status}`;
|
|
5461
|
+
const description = meta.description || `Cyberia Online ${status}.`;
|
|
5462
|
+
shellExec(
|
|
5463
|
+
`node bin static --page ${pagePath}` +
|
|
5464
|
+
` --output-path ${outputPath}` +
|
|
5465
|
+
` --title '${title}'` +
|
|
5466
|
+
` --favicon /favicon.ico` +
|
|
5467
|
+
` --description '${description}'` +
|
|
5468
|
+
` --lang en` +
|
|
5469
|
+
` --env ${dev ? 'development' : 'production'}`,
|
|
5470
|
+
);
|
|
5471
|
+
return true;
|
|
5472
|
+
};
|
|
5473
|
+
|
|
5356
5474
|
runner
|
|
5357
5475
|
.command('build-manifest')
|
|
5358
5476
|
.option(
|
|
@@ -5385,24 +5503,24 @@ node bin image --path cyberia-client \
|
|
|
5385
5503
|
// A variant declared in conf.instances.json without the instance
|
|
5386
5504
|
// directory is silently skipped so the Dockerfile never tries to
|
|
5387
5505
|
// copy a non-existent directory and the container build does not fail.
|
|
5388
|
-
const confInstancesPath = './engine-private/conf/dd-cyberia/conf.instances.json';
|
|
5389
5506
|
const cyberiaInstancesDir = '/home/dd/cyberia-instances';
|
|
5390
5507
|
let instanceCodes = 'amethyst-strata-expansion,FOREST'; // fallback
|
|
5508
|
+
const confInstancesEntries = readCyberiaConfInstances();
|
|
5391
5509
|
try {
|
|
5392
|
-
const
|
|
5393
|
-
const serverInstances = confInstances.filter((inst) => inst.runtime === 'cyberia-server');
|
|
5510
|
+
const serverInstances = confInstancesEntries.filter((inst) => inst.runtime === 'cyberia-server');
|
|
5394
5511
|
const codes = new Set();
|
|
5395
5512
|
for (const inst of serverInstances) {
|
|
5396
5513
|
if (inst.multiInstance?.variants) {
|
|
5397
|
-
|
|
5398
|
-
|
|
5514
|
+
const topology = normalizeInstanceTopology(inst.multiInstance, `dd-cyberia/${inst.id}`);
|
|
5515
|
+
for (const v of topology.variants) {
|
|
5516
|
+
const code = v.path === '/' ? DEFAULT_INSTANCE_CODE : v.code;
|
|
5399
5517
|
// Skip codes that have no on-disk instance backup dir
|
|
5400
|
-
const instanceDir = `${cyberiaInstancesDir}/instances/${
|
|
5518
|
+
const instanceDir = `${cyberiaInstancesDir}/instances/${code}`;
|
|
5401
5519
|
if (!fs.existsSync(instanceDir)) {
|
|
5402
|
-
logger.info(`[build-manifest] Skipping code "${
|
|
5520
|
+
logger.info(`[build-manifest] Skipping code "${code}": no instance dir at ${instanceDir}`);
|
|
5403
5521
|
continue;
|
|
5404
5522
|
}
|
|
5405
|
-
codes.add(
|
|
5523
|
+
codes.add(code);
|
|
5406
5524
|
}
|
|
5407
5525
|
}
|
|
5408
5526
|
}
|
|
@@ -5413,7 +5531,7 @@ node bin image --path cyberia-client \
|
|
|
5413
5531
|
logger.warn(`[build-manifest] No valid instance codes found; keeping fallback: ${instanceCodes}`);
|
|
5414
5532
|
}
|
|
5415
5533
|
} catch (err) {
|
|
5416
|
-
logger.warn(`[build-manifest] Could not read ${
|
|
5534
|
+
logger.warn(`[build-manifest] Could not read ${CYBERIA_CONF_INSTANCES_PATH}: ${err.message}; using fallback`);
|
|
5417
5535
|
}
|
|
5418
5536
|
|
|
5419
5537
|
// ── Update Dockerfile.dev + Dockerfile INSTANCE_CODES build arg ──────
|
|
@@ -5474,29 +5592,38 @@ node bin image --path cyberia-client \
|
|
|
5474
5592
|
logger.warn(`[build-manifest] Could not update ${catalogPath}: ${err.message}`);
|
|
5475
5593
|
}
|
|
5476
5594
|
|
|
5595
|
+
// ── Build SSR views ──────────────────────────────────────────────────
|
|
5596
|
+
// Status pages are rendered BEFORE the manifests: the gateway manifests
|
|
5597
|
+
// embed each document declared under an instance's `customStatusPages`,
|
|
5598
|
+
// so the artifact has to exist at its `hostPath` by manifest time.
|
|
5599
|
+
const statusPagesBuilt = [];
|
|
5600
|
+
for (const { id, rootPath } of CYBERIA_INSTANCE_PROJECTS) {
|
|
5601
|
+
const instance = confInstancesEntries.find((entry) => entry.id === id);
|
|
5602
|
+
for (const page of instance?.customStatusPages || []) {
|
|
5603
|
+
if (!page?.status || !page?.hostPath) continue;
|
|
5604
|
+
const outputPath = nodePath.normalize(`${rootPath}/${page.hostPath}`);
|
|
5605
|
+
if (buildCyberiaStatusPage({ status: page.status, outputPath, dev: isDev }))
|
|
5606
|
+
statusPagesBuilt.push({ instance: id, status: page.status, outputPath });
|
|
5607
|
+
}
|
|
5608
|
+
}
|
|
5609
|
+
logger.info('[build-manifest] Custom status pages built', statusPagesBuilt);
|
|
5610
|
+
shellExec(
|
|
5611
|
+
`node bin/cyberia run-workflow build-server-dashboard --output-path ./cyberia-server/public/index.html`,
|
|
5612
|
+
);
|
|
5613
|
+
|
|
5477
5614
|
// ── Build dev manifests (always --kind --dev) ────────────────────────
|
|
5478
5615
|
{
|
|
5479
5616
|
const flags = `--kind --dev${nodeFlag}`;
|
|
5480
|
-
|
|
5481
|
-
|
|
5617
|
+
for (const { id, rootPath } of CYBERIA_INSTANCE_PROJECTS)
|
|
5618
|
+
shellExec(`node bin run instance-build-manifest 'dd-cyberia,${id},${rootPath}' ${flags}`);
|
|
5482
5619
|
}
|
|
5483
5620
|
// ── Build prod manifests (--kubeadm, no --dev) ───────────────────────
|
|
5484
5621
|
if (!isDev) {
|
|
5485
5622
|
const flags = `--kubeadm${nodeFlag}`;
|
|
5486
|
-
|
|
5487
|
-
|
|
5623
|
+
for (const { id, rootPath } of CYBERIA_INSTANCE_PROJECTS)
|
|
5624
|
+
shellExec(`node bin run instance-build-manifest 'dd-cyberia,${id},${rootPath}' ${flags}`);
|
|
5488
5625
|
}
|
|
5489
5626
|
|
|
5490
|
-
// ── Build SSR views ──────────────────────────────────────────────────
|
|
5491
|
-
const env404 = isDev ? ' --dev' : '';
|
|
5492
|
-
shellExec(
|
|
5493
|
-
`node bin/cyberia run-workflow build-cyberia-404 --output-path ./cyberia-server/public/404.html${env404}`,
|
|
5494
|
-
);
|
|
5495
|
-
shellExec(`node bin/cyberia run-workflow build-cyberia-404 --output-path ./cyberia-client/bin/404.html${env404}`);
|
|
5496
|
-
shellExec(
|
|
5497
|
-
`node bin/cyberia run-workflow build-server-dashboard --output-path ./cyberia-server/public/index.html`,
|
|
5498
|
-
);
|
|
5499
|
-
|
|
5500
5627
|
// Copy canonical doc sources into the generated project READMEs.
|
|
5501
5628
|
// Edit the canonical sources; never hand-edit these generated outputs.
|
|
5502
5629
|
fs.copyFileSync('./src/client/public/cyberia-docs/CYBERIA-CLIENT.md', './cyberia-client/README.md');
|
|
@@ -5565,27 +5692,54 @@ node bin image --path cyberia-client \
|
|
|
5565
5692
|
);
|
|
5566
5693
|
});
|
|
5567
5694
|
|
|
5695
|
+
runner
|
|
5696
|
+
.command('build-status-page')
|
|
5697
|
+
.requiredOption(
|
|
5698
|
+
'--status <status>',
|
|
5699
|
+
'HTTP status code to render (must be declared as an SSR view in conf.ssr.json).',
|
|
5700
|
+
)
|
|
5701
|
+
.option('--dev', 'Build a development variant of the status page.')
|
|
5702
|
+
.option(
|
|
5703
|
+
'--output-path <path>',
|
|
5704
|
+
'Output path for the rendered HTML. Defaults to the `hostPath` the mmo-server instance declares for the status.',
|
|
5705
|
+
)
|
|
5706
|
+
.description(
|
|
5707
|
+
'Build one custom status page artifact. The SSR view is resolved from the conf.ssr.json route whose path is ' +
|
|
5708
|
+
'the bare status code; the rendered document is served by the gateway, not by the workload.',
|
|
5709
|
+
)
|
|
5710
|
+
.action((options) => {
|
|
5711
|
+
const status = `${options.status}`;
|
|
5712
|
+
const statusPage = (
|
|
5713
|
+
readCyberiaConfInstances().find((entry) => entry.id === 'mmo-server')?.customStatusPages || []
|
|
5714
|
+
).find((page) => `${page.status}` === status);
|
|
5715
|
+
const outputPath =
|
|
5716
|
+
options.outputPath || (statusPage ? nodePath.normalize(`./cyberia-server/${statusPage.hostPath}`) : null);
|
|
5717
|
+
if (!outputPath) {
|
|
5718
|
+
logger.error(`[build-status-page] No --output-path and no customStatusPages entry for status ${status}`);
|
|
5719
|
+
return;
|
|
5720
|
+
}
|
|
5721
|
+
buildCyberiaStatusPage({ status, outputPath, dev: !!options.dev });
|
|
5722
|
+
});
|
|
5723
|
+
|
|
5568
5724
|
runner
|
|
5569
5725
|
.command('build-cyberia-404')
|
|
5570
5726
|
.option('--dev', 'Build a development variant of the 404 page.')
|
|
5571
5727
|
.option(
|
|
5572
5728
|
'--output-path <path>',
|
|
5573
5729
|
'Output path for the rendered 404.html (default: ./cyberia-server/public/404.html). ' +
|
|
5574
|
-
'The same page is served, sub-path aware, by every instance variant of both the ' +
|
|
5575
|
-
'cyberia-server
|
|
5730
|
+
'The same page is served, sub-path aware, by the gateway for every instance variant of both the ' +
|
|
5731
|
+
'cyberia-server and cyberia-client workloads.',
|
|
5732
|
+
)
|
|
5733
|
+
.description(
|
|
5734
|
+
'Build the cyberpunk pixel-art "sector not found" (404) page shared by the Cyberia server + client. ' +
|
|
5735
|
+
'Thin alias of `build-status-page --status 404`, kept as the entrypoint the instance CI workflows call.',
|
|
5576
5736
|
)
|
|
5577
|
-
.description('Build the cyberpunk pixel-art "sector not found" (404) page shared by the Cyberia server + client.')
|
|
5578
5737
|
.action((options) => {
|
|
5579
|
-
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
` --favicon /favicon.ico` +
|
|
5585
|
-
` --description 'Cyberia Online 404 — the requested sector is not on the grid.'` +
|
|
5586
|
-
` --lang en` +
|
|
5587
|
-
` --env ${options.dev ? 'development' : 'production'}`,
|
|
5588
|
-
);
|
|
5738
|
+
buildCyberiaStatusPage({
|
|
5739
|
+
status: '404',
|
|
5740
|
+
outputPath: options.outputPath || './cyberia-server/public/404.html',
|
|
5741
|
+
dev: !!options.dev,
|
|
5742
|
+
});
|
|
5589
5743
|
});
|
|
5590
5744
|
|
|
5591
5745
|
// Passthrough check: if the user invoked a command that is OWNED by the
|