underpost 3.2.90 → 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 (71) hide show
  1. package/.github/workflows/ghpkg.ci.yml +7 -1
  2. package/.github/workflows/pwa-microservices-template-page.cd.yml +1 -16
  3. package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
  4. package/.github/workflows/release.cd.yml +1 -9
  5. package/CHANGELOG.md +110 -1
  6. package/CLI-HELP.md +139 -9
  7. package/README.md +5 -2
  8. package/bin/build.js +7 -5
  9. package/bin/deploy.js +1 -1
  10. package/deploy/lib/logging.sh +96 -0
  11. package/deploy/pwa-microservices-template/deploy.sh +72 -0
  12. package/deploy/release/deploy.sh +62 -0
  13. package/docker-compose.yml +1 -1
  14. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +5 -1
  15. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
  16. package/manifests/cronjobs/dd-cron/dd-cron-vultr.yaml +52 -0
  17. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  18. package/package.json +5 -5
  19. package/scripts/audit-selinux.sh +64 -0
  20. package/scripts/coverall-test.sh +24 -0
  21. package/scripts/gpu-diag.sh +0 -0
  22. package/scripts/ip-info.sh +0 -0
  23. package/scripts/k3s-node-setup.sh +18 -15
  24. package/scripts/kubeadm-node-setup.sh +12 -23
  25. package/scripts/link-local-underpost-cli.sh +0 -0
  26. package/scripts/lxd-vm-setup.sh +0 -0
  27. package/scripts/maas-nat-firewalld.sh +0 -0
  28. package/scripts/nat-iptables.sh +2 -0
  29. package/scripts/rhel-grpc-setup.sh +0 -0
  30. package/scripts/rocky-kickstart.sh +25 -9
  31. package/scripts/test-monitor.sh +1 -1
  32. package/src/cli/baremetal.js +1 -2
  33. package/src/cli/cloud-init.js +1 -1
  34. package/src/cli/cluster.js +73 -68
  35. package/src/cli/db.js +9 -2
  36. package/src/cli/deploy.js +21 -5
  37. package/src/cli/docker-compose.js +1 -1
  38. package/src/cli/env.js +1 -1
  39. package/src/cli/image.js +0 -1
  40. package/src/cli/index.js +121 -9
  41. package/src/cli/lxd.js +1 -1
  42. package/src/cli/monitor.js +1 -1
  43. package/src/cli/release.js +57 -22
  44. package/src/cli/repository.js +11 -9
  45. package/src/cli/run.js +36 -9
  46. package/src/cli/ssh.js +198 -77
  47. package/src/cli/system.js +26 -13
  48. package/src/cli/test.js +1 -1
  49. package/src/cli/vultr.js +583 -0
  50. package/src/cli/wireguard.js +2125 -0
  51. package/src/client-builder/client-build.js +20 -14
  52. package/src/db/mongo/MongooseDB.js +4 -0
  53. package/src/index.js +25 -1
  54. package/src/projects/underpost/catalog-underpost.js +4 -1
  55. package/src/server/backup.js +1 -1
  56. package/src/server/conf.js +18 -108
  57. package/src/server/cron.js +249 -51
  58. package/src/server/dns.js +100 -6
  59. package/src/server/environment.js +98 -0
  60. package/src/server/forward-proxy.js +549 -0
  61. package/src/server/middlewares.js +56 -1
  62. package/src/server/process.js +0 -1
  63. package/src/server/selinux.js +185 -0
  64. package/src/server/systemd.js +205 -0
  65. package/src/server/underpost-compression.js +186 -0
  66. package/src/server/underpost-gateway.js +20 -10
  67. package/src/server/underpost-ingress.js +18 -2
  68. package/test/selinux.test.js +71 -0
  69. package/test/underpost-gateway.test.js +41 -0
  70. package/test/underpost-ingress.test.js +52 -0
  71. package/test/wireguard-edge.test.js +1177 -0
@@ -20,7 +20,13 @@ permissions:
20
20
  id-token: write
21
21
  jobs:
22
22
  pwa-microservices-template-ghpk:
23
- if: github.repository == 'underpostnet/pwa-microservices-template' && startsWith(github.event.head_commit.message, 'ci(package-pwa-microservices-template-ghpkg)')
23
+ if: >-
24
+ github.repository == 'underpostnet/pwa-microservices-template' &&
25
+ (
26
+ startsWith(github.event.head_commit.message, 'ci(package-pwa-microservices-template-ghpkg)')
27
+ ||
28
+ github.event_name == 'workflow_dispatch'
29
+ )
24
30
  name: Update github repo package Jobs
25
31
  runs-on: ubuntu-latest
26
32
  container:
@@ -32,23 +32,8 @@ jobs:
32
32
  # - name: Checkout LFS objects
33
33
  # run: git lfs checkout
34
34
 
35
- - name: Install required packages
36
- run: |
37
- dnf install -y sudo tar gzip bzip2 git
38
- dnf install -y curl --allowerasing
39
-
40
- - name: Install Node.js
41
- run: |
42
- curl -fsSL https://rpm.nodesource.com/setup_24.x | bash -
43
- dnf install nodejs -y
44
-
45
35
  - name: Build the site
46
- run: |
47
- npm install
48
- node bin new --default-conf --conf-workflow-id dd-github-pages
49
- node bin new --deploy-id dd-github-pages
50
- node bin env dd-github-pages production
51
- NODE_ENV=production node bin client dd-github-pages '' underpostnet.github.io /pwa-microservices-template-ghpkg
36
+ run: bash deploy/pwa-microservices-template/deploy.sh
52
37
  # git lfs install
53
38
  # git lfs track
54
39
  # git lfs ls-files
@@ -30,4 +30,4 @@ jobs:
30
30
  run: npm install
31
31
 
32
32
  - name: Run test
33
- run: npm test
33
+ run: scripts/coverall-test.sh
@@ -35,12 +35,4 @@ jobs:
35
35
  script: |
36
36
  set -e
37
37
  set -o pipefail
38
- echo "Starting remote release deploy"
39
- cd /home/dd/engine
40
- sudo -n -- /bin/bash -lc "node bin run pull"
41
- sudo -n -- /bin/bash -lc "npm install"
42
- sudo -n -- /bin/bash -lc "node bin run secret"
43
- sudo -n -- /bin/bash -lc "npm install -g underpost"
44
- sudo -n -- /bin/bash -lc "node bin run secret"
45
- sudo -n -- /bin/bash -lc "node bin run --dev git-conf"
46
- sudo -n -- /bin/bash -lc "node bin run docker-image"
38
+ bash /home/dd/engine/deploy/release/deploy.sh
package/CHANGELOG.md CHANGED
@@ -1,6 +1,115 @@
1
1
  # Changelog
2
2
 
3
- ## 2026-08-11
3
+ ## 2026-08-18
4
+
5
+ ### github-actions
6
+
7
+ - Add workflow_dispatch trigger event handling in .github/workflows/ghpkg.ci.yml ([e21320cf](https://github.com/underpostnet/engine/commit/e21320cf7542680823758f331bd34d619ca185cd))
8
+ - Reorder coverall test list ([eb20336b](https://github.com/underpostnet/engine/commit/eb20336b29e87f4371528f78099768e8ee36b586))
9
+ - Replace default npm coverall test with scripts/coverall-test.sh ([3471f300](https://github.com/underpostnet/engine/commit/3471f3009391a3f8a1a66cedd1e4761fe5f76712))
10
+ - Refactor move CD workflow commands into deployment scripts with run_quiet wrapper ([222a18d7](https://github.com/underpostnet/engine/commit/222a18d719f33fd678a72f9b05639f86ec4037cd))
11
+ - Update .github/workflows/engine-test.cd.yml ([94e42e58](https://github.com/underpostnet/engine/commit/94e42e58ee4f9eb6542a010e96899000458f3a7b))
12
+ - Add import-default-items steps to cyberia CD ([350444f9](https://github.com/underpostnet/engine/commit/350444f9fb4b34cd15541458c1897299fed7b287))
13
+ - Update.github/workflows/engine-cyberia.cd.yml ([53e9da17](https://github.com/underpostnet/engine/commit/53e9da17127a850aebaa0e5e0e90b593ee0ac03d))
14
+ - Update base node in engine-core CD pipeline ([fa039f25](https://github.com/underpostnet/engine/commit/fa039f25763bb719496b73dd8044af4570be859e))
15
+
16
+ ### cli-cyberia
17
+
18
+ - Include deploy strategies in generated projects ([66bc733e](https://github.com/underpostnet/engine/commit/66bc733eb22bd74aff5ff249dade0959c876cdae))
19
+ - Refactor make data.item.id is now a unique index for every case ([1391efce](https://github.com/underpostnet/engine/commit/1391efce32f96f56271a1060304bb7b26556b80d))
20
+ - Add WebSocket load test runner command ([eebec67e](https://github.com/underpostnet/engine/commit/eebec67edd1bfda0bf6f8205305a90cd73441e4c))
21
+
22
+ ### engine
23
+
24
+ - Expand server module JSDoc annotations ([213a5519](https://github.com/underpostnet/engine/commit/213a55191dc388d227315f07116148d5b731b883))
25
+ - Move writeEnv helper into environment module ([9c57e362](https://github.com/underpostnet/engine/commit/9c57e3629a682da0c7aa45e0cb24d24d3af3cdab))
26
+ - Fix SELinux host paths mounts logic and definition ([6cf8dda1](https://github.com/underpostnet/engine/commit/6cf8dda113b92fea011e3825035147ae33a1bc7f))
27
+ - Extract environment and cron deploy helpers into dedicated modules ([6ba3fa4c](https://github.com/underpostnet/engine/commit/6ba3fa4c372a2eb1afe87c6fc5c0681209a96b07))
28
+ - Enforce SELinux across cluster, SSH, and provisioning ([9d57a359](https://github.com/underpostnet/engine/commit/9d57a359dd94067dfb48fceab9006e3ef3d7d502))
29
+
30
+ ### cli-wireguard
31
+
32
+ - Add SSH forwarding via VPS edge ([54de1e6e](https://github.com/underpostnet/engine/commit/54de1e6e5dddccad5c056da152cb32712ab3ba25))
33
+ - Extract forward proxy and systemd helpers into server modules ([97be08d1](https://github.com/underpostnet/engine/commit/97be08d107e825c2ff5a97382ebb9367a6ad3523))
34
+ - Implement HTTP/CONNECT forward proxy for WireGuard ([a95163df](https://github.com/underpostnet/engine/commit/a95163df2797bbfa86d3d1f422fe0afd224b72b3))
35
+ - Implement idempotent in Restart, reconnect, and reset pipeline ([65710c3b](https://github.com/underpostnet/engine/commit/65710c3bd3056b1f2cc49e3b82517d081f7f25df))
36
+ - Implement Edge Hub WireGuard and HAProxy CLI module ([2e293b87](https://github.com/underpostnet/engine/commit/2e293b87540a43489bb535e2ab731581809b1848))
37
+
38
+ ### catalog-cyberia
39
+
40
+ - Add coverall cyberia trigger script ([c8e59eed](https://github.com/underpostnet/engine/commit/c8e59eed08c113d39a99f5151d8d6b4af96fb4e9))
41
+
42
+ ### scripts
43
+
44
+ - Mark scripts as executable ([8f04cbc7](https://github.com/underpostnet/engine/commit/8f04cbc700e2bc17b917ea49450efabc766e27ed))
45
+
46
+ ### release
47
+
48
+ - Fix missing file bump version scopes ([4aa983a5](https://github.com/underpostnet/engine/commit/4aa983a5d8aea7983295ee01799c358ed1b9c2bc))
49
+
50
+ ### deploy
51
+
52
+ - Mark deploy scripts as executable ([b18151bf](https://github.com/underpostnet/engine/commit/b18151bfaa52c17b2540e0a2706b79a8850fee84))
53
+
54
+ ### hardhat
55
+
56
+ - Update hardhat npm module version to sync current project scope v3.2.90 ([8fc717b9](https://github.com/underpostnet/engine/commit/8fc717b9913c69a41c2c9e88b2b7f720a4a7cb09))
57
+ - Update undici override dependency to v6.28.0 ([fb2d2aa3](https://github.com/underpostnet/engine/commit/fb2d2aa3b502b5552212f63d9a01f23d2333b296))
58
+
59
+ ### dependabot
60
+
61
+ - Disable typescript autoupdate ([8bd76183](https://github.com/underpostnet/engine/commit/8bd7618336423a1df1d4ca77cd138aef51902d6c))
62
+
63
+ ### cli-client
64
+
65
+ - Add only ssr build workload flag option and logic ([92026a66](https://github.com/underpostnet/engine/commit/92026a66ec3c403219af62bfc5bcc78917d537ed))
66
+
67
+ ### cli-cron
68
+
69
+ - Fix cron CLI setup flag and single job execution ([84eab73d](https://github.com/underpostnet/engine/commit/84eab73d9a618244b46e699ba65b469940d1a267))
70
+
71
+ ### cli-repository
72
+
73
+ - Add getDefaultBranch resolve in switchRemote method ([04bc8743](https://github.com/underpostnet/engine/commit/04bc8743b6f4c5f9edd891276137183fa444d447))
74
+
75
+ ### cli-ssh
76
+
77
+ - Add initializeDefaultSshConfig method ([84f5f869](https://github.com/underpostnet/engine/commit/84f5f8698810596f084e632487208ea909feddfd))
78
+
79
+ ### cli-vultr
80
+
81
+ - Add Vultr Bandwidth Monitor cron job CLI Module ([22fb9249](https://github.com/underpostnet/engine/commit/22fb9249ad40ba24a8cd87da43d742b1972c4fbb))
82
+
83
+ ### cli-dns
84
+
85
+ - Add blokc/unblock ingress/egress workflow handling ([980fab35](https://github.com/underpostnet/engine/commit/980fab35aba6a279b94701550edfd765c8b422a2))
86
+
87
+ ### underpost-ingress
88
+
89
+ - Enable response compression in ingress and gateway ([7763f9da](https://github.com/underpostnet/engine/commit/7763f9da2b81128042cef2a73ca5570938dcd3f5))
90
+
91
+ ### test
92
+
93
+ - Fix missing pngjs import in object-layer test pipeline ([20c1f24d](https://github.com/underpostnet/engine/commit/20c1f24d865d5cdeb70a365c93f8c797c28fe960))
94
+ - Add WebSocket load test for cyberia-server ([e3ff2777](https://github.com/underpostnet/engine/commit/e3ff277725e33dace3ed3268e6f60299ea146f59))
95
+
96
+ ### engine-cyberia
97
+
98
+ - Remove eiri from entity default inventory ([e8f8d03c](https://github.com/underpostnet/engine/commit/e8f8d03c7e326fac012722f659def7d7a7da882c))
99
+ - Add fallback world default items staging and hot reload ([e646c430](https://github.com/underpostnet/engine/commit/e646c430d72ea7a319cf1640bd4c7505cbb40b87))
100
+ - Add playerBaseSpeed field to instance config defaults ([7cdbd23d](https://github.com/underpostnet/engine/commit/7cdbd23d255bb47e253e60f7ec0cc6c3600d5678))
101
+ - Add WebSocket connection limit env to cyberia-server ([c6f834c7](https://github.com/underpostnet/engine/commit/c6f834c7dc7bcae24d4f493a005cdb2d1b76a73d))
102
+
103
+ ### client-cyberia
104
+
105
+ - Add Fallback World Engine editor view ([cf61dfe8](https://github.com/underpostnet/engine/commit/cf61dfe8e7eec7556f5bd07e445d6759d9b432e4))
106
+ - Implement IPFS cid filters in ObjectLayerEngineViewer component ([93eb6992](https://github.com/underpostnet/engine/commit/93eb69928bf8ea6915f70b1ca4307fa582cc17b6))
107
+
108
+ ### docs
109
+
110
+ - Document moveAck reconciliation and move coalescing in Cyberia replication ([24b14ca4](https://github.com/underpostnet/engine/commit/24b14ca4ee4c9ef0ce4dc9e3135e4990ed0a8274))
111
+
112
+ ## New release v:3.2.90 (2026-08-11)
4
113
 
5
114
  ### cli-run
6
115
 
package/CLI-HELP.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ## Underpost CLI
2
2
 
3
- > underpost ci/cd cli v3.2.90
3
+ > underpost ci/cd cli v3.3.0
4
4
 
5
5
  **Usage:** `underpost [options] [command]`
6
6
 
@@ -39,6 +39,9 @@
39
39
  | [`test`](#underpost-test) | Manages and runs tests, defaulting to the current Underpost default test suite. |
40
40
  | [`monitor`](#underpost-monitor) | Manages health server monitoring for specified deployments. |
41
41
  | [`ssh`](#underpost-ssh) | Manages SSH credentials and sessions for remote access to cluster nodes or services. |
42
+ | [`wireguard`](#underpost-wireguard) | Manages the WireGuard L3 hub-and-spoke transport and the HAProxy edge gateway in front of it. |
43
+ | [`haproxy`](#underpost-haproxy) | Manages the HAProxy edge gateway over the WireGuard transport (same subsystem as `underpost wireguard`). |
44
+ | [`vultr`](#underpost-vultr) | Meters the edge VPS bandwidth against its Vultr plan quota and blocks egress before overage accrues. |
42
45
  | [`run`](#underpost-run) | Runs specified scripts using various runners. |
43
46
  | [`docker-compose`](#underpost-docker-compose) | General-purpose Docker Compose development pipeline (mirrors the Kubernetes dev stack). |
44
47
  | [`lxd`](#underpost-lxd) | Manages LXD virtual machines as K3s nodes (control plane or workers). |
@@ -106,6 +109,7 @@ Builds client assets, single replicas, and/or syncs environment ports.
106
109
  | `--merge-zip <build-prefix>` | Merge split ZIP parts back into a single ZIP file for the given build prefix |
107
110
  | `--lite-build` | Skip full build (default is full build) |
108
111
  | `--icons-build` | Build icons |
112
+ | `--ssr` | Rebuild only SSR views defined in conf.ssr.json, leaving client assets untouched |
109
113
  | `-h, --help` | display help for command |
110
114
 
111
115
  ---
@@ -227,7 +231,7 @@ Manages commits to a GitHub repository, supporting various commit types and opti
227
231
  | `--has-changes` | Prints "1" if there are staged or unstaged git changes in the repository, empty string otherwise. |
228
232
  | `--remote-url` | Prints the current git remote URL (origin) in plain text. |
229
233
  | `--switch-repo <url>` | Switches the git remote (origin) to <url> and force-pulls the target branch, overwriting the current working tree (discards local commits and tracked changes). Accepts a full URL or "owner/repo". |
230
- | `--target-branch <branch>` | Target branch for --switch-repo (default: master). |
234
+ | `--target-branch <branch>` | Target branch for --switch-repo (default: remote default branch). |
231
235
  | `-h, --help` | display help for command |
232
236
 
233
237
  ---
@@ -389,6 +393,10 @@ Displays the current public machine IP addresses.
389
393
  | `--ban-egress-clear` | Clears all banned egress IP addresses. |
390
394
  | `--ban-both-add` | Adds IP addresses to both banned ingress and egress lists. |
391
395
  | `--ban-both-remove` | Removes IP addresses from both banned ingress and egress lists. |
396
+ | `--block-all-egress` | Blocks all outbound traffic from this host (keeps established/related connections). |
397
+ | `--unblock-all-egress` | Unblocks all outbound traffic and restores default ACCEPT policy. |
398
+ | `--block-all-ingress` | Blocks all new inbound traffic to this host (keeps established/related connections). |
399
+ | `--unblock-all-ingress` | Unblocks all inbound traffic and restores default ACCEPT policy. |
392
400
  | `--mac` | Prints the MAC address of the main network interface. |
393
401
  | `-h, --help` | display help for command |
394
402
 
@@ -678,18 +686,19 @@ Manages cron jobs: execute jobs directly or generate and apply K8s CronJob manif
678
686
 
679
687
  | Argument | Description |
680
688
  | --- | --- |
681
- | `deploy-list` | A comma-separated list of deployment IDs (e.g., "default-a,default-b"). |
682
- | `job-list` | A comma-separated list of job IDs. Options: dns,backup. Defaults to all available jobs. |
689
+ | `deploy-list` | A comma-separated list of deployment IDs (e.g., "default-a,default-b"). In manifest modes its first entry is the manifest owner deploy-id. |
690
+ | `job-list` | A comma-separated list of job IDs. Options: dns,backup,vultr. Defaults to all available jobs, and restricts which jobs are generated in manifest modes. |
683
691
 
684
692
  #### Options
685
693
 
686
694
  | Option | Description |
687
695
  | --- | --- |
688
696
  | `--generate-k8s-cronjobs` | Generates Kubernetes CronJob YAML manifests from cron configuration. |
689
- | `--apply` | Applies generated K8s CronJob manifests to the cluster via kubectl. |
690
- | `--setup-start [deploy-id]` | Updates deploy-id package.json start script and generates+applies its K8s CronJob manifests. |
697
+ | `--apply` | Generates and applies K8s CronJob manifests to the cluster via kubectl (never runs jobs). |
698
+ | `--setup-start` | Updates deploy-list package.json start script and generates+applies its K8s CronJob manifests. |
691
699
  | `--namespace <namespace>` | Kubernetes namespace for the CronJob resources (default: "default"). |
692
700
  | `--image <image>` | Custom container image for the CronJob pods. |
701
+ | `--node-name <node-name>` | Pins the CronJob pods to this node via a kubernetes.io/hostname nodeSelector. |
693
702
  | `--git` | Pass --git flag to cron job execution. |
694
703
  | `--cmd <cmd>` | Optional pre-script commands to run before cron execution. |
695
704
  | `--dev` | Use local ./ base path instead of global underpost installation. |
@@ -697,7 +706,7 @@ Manages cron jobs: execute jobs directly or generate and apply K8s CronJob manif
697
706
  | `--kind` | Use kind cluster context (apply via kind-worker container). |
698
707
  | `--kubeadm` | Use kubeadm cluster context (apply directly on host). |
699
708
  | `--dry-run` | Preview cron jobs without executing them. |
700
- | `--create-job-now` | After applying manifests, immediately create a Job from each CronJob (requires --apply). |
709
+ | `--create-job-now` | Creates a Job from each CronJob on the cluster now (implies manifest mode; combine with --apply to publish first). |
701
710
  | `-h, --help` | display help for command |
702
711
 
703
712
  ---
@@ -827,6 +836,127 @@ Manages SSH credentials and sessions for remote access to cluster nodes or servi
827
836
 
828
837
  ---
829
838
 
839
+ ### underpost wireguard
840
+
841
+ Manages the WireGuard L3 hub-and-spoke transport and the HAProxy edge gateway in front of it.
842
+
843
+ **Usage:** `underpost wireguard [options]`
844
+
845
+ #### Options
846
+
847
+ | Option | Description |
848
+ | --- | --- |
849
+ | `--deploy-id <deploy-id>` | Deploy IDs whose conf.server.json/conf.instances.json define the routes. Accepts one id or a comma-separated list; defaults to "dd", every deploy in dd.router, because the edge holds one pair of map files for the whole cluster. |
850
+ | `--interface <name>` | WireGuard interface name (default: "wg0"). |
851
+ | `--wireguard-install` | Installs the wireguard-tools, haproxy and iptables host packages. |
852
+ | `--wireguard-setup` | Generates keys, builds the interface config, and applies local network rules. |
853
+ | `--server` | Configures this node as the hub endpoint accepting inbound tunnel traffic. |
854
+ | `--client` | Configures this node as a spoke endpoint maintaining an outbound tunnel. |
855
+ | `--port <port>` | WireGuard UDP listening port (default: 51820). |
856
+ | `--cidr <cidr>` | Hub interface address with prefix when used with --server (e.g. "10.0.0.1/24"); the overlay subnet a spoke routes back through the hub when used with --client (default: "10.0.0.0/24"). |
857
+ | `--peer-ip <ip>` | Tunnel address of the target spoke. Required with --client and --peer-add. |
858
+ | `--endpoint <host:port>` | Hub host and port a spoke dials. Required with --client. |
859
+ | `--public-key <key>` | Hub public key with --client; spoke public key with --peer-add. |
860
+ | `--peer-add <peer-id>` | Registers a spoke and applies it to the running hub without a restart. |
861
+ | `--peer-remove <peer-id>` | Removes a spoke from the registry and from the running hub. |
862
+ | `--allowed-ips <cidrs>` | Comma-separated CIDRs routed to the spoke (e.g. "10.0.0.2/32,192.168.10.0/24"). |
863
+ | `--hosts <hosts>` | Comma-separated hostnames bound to the spoke, overriding instance resolution. |
864
+ | `--instances <instances>` | Comma-separated conf.instances.json ids bound to the spoke. |
865
+ | `--default` | Marks the spoke as the fallback for hostnames that match no other binding. |
866
+ | `--haproxy-setup` | Installs HAProxy, publishes the current routes, and enables the daemon. |
867
+ | `--haproxy-sync` | Recompiles the SNI/Host maps from deploy config and hot-reloads HAProxy. |
868
+ | `--status` | Prints the whole edge context without changing anything: role, interface, tunnel address, public key, daemon states, peers with their bindings and link health, and the resolved routing. |
869
+ | `--build-conf` | Writes only engine-private/deploy/conf.wireguard.json and touches no host state. Combine with --wireguard-setup / --peer-add / --peer-remove to author the topology off-box; alone it normalizes and validates the existing registry. |
870
+ | `--forward-proxy-server` | Ensures the hub HTTP/CONNECT forward proxy runs as the underpost-forward-proxy systemd service, bound to the tunnel address only (default port 1080), and returns. Authenticates every request with FORWARD_PROXY_API_KEY, so spokes can reach the internet through the VPS public address. Idempotent: re-running converges on the one service and restarts it only when the unit actually changed. |
871
+ | `--forward-proxy-server-host <host>` | Address the forward proxy binds, overriding the hub tunnel address from the registry. |
872
+ | `--forward-proxy-server-port <port>` | Port the forward proxy binds (default: 1080). |
873
+ | `--ssh-forward-port <port>` | Publishes the default spoke SSH port on this public TCP port of the hub, so CI with no fixed address can reach the cluster node (e.g. 2222). "0" closes it. Stored in the registry. |
874
+ | `--wireguard-start` | Enables and starts wg-quick@<interface> and the QUIC forward. |
875
+ | `--wireguard-stop` | Tears down the interface and removes its transient packet rules. |
876
+ | `--wireguard-reset` | Removes generated configs and packet rules, keeping the key pair and registry. |
877
+ | `--wireguard-reinstall` | Full purge, package reinstall and re-key; every spoke must re-register. |
878
+ | `--dry-run` | Prints the files and commands the run would apply, without touching the host. |
879
+ | `-h, --help` | display help for command |
880
+
881
+ ---
882
+
883
+ ### underpost haproxy
884
+
885
+ Manages the HAProxy edge gateway over the WireGuard transport (same subsystem as `underpost wireguard`).
886
+
887
+ **Usage:** `underpost haproxy [options]`
888
+
889
+ #### Options
890
+
891
+ | Option | Description |
892
+ | --- | --- |
893
+ | `--deploy-id <deploy-id>` | Deploy IDs whose conf.server.json/conf.instances.json define the routes. Accepts one id or a comma-separated list; defaults to "dd", every deploy in dd.router, because the edge holds one pair of map files for the whole cluster. |
894
+ | `--interface <name>` | WireGuard interface name (default: "wg0"). |
895
+ | `--wireguard-install` | Installs the wireguard-tools, haproxy and iptables host packages. |
896
+ | `--wireguard-setup` | Generates keys, builds the interface config, and applies local network rules. |
897
+ | `--server` | Configures this node as the hub endpoint accepting inbound tunnel traffic. |
898
+ | `--client` | Configures this node as a spoke endpoint maintaining an outbound tunnel. |
899
+ | `--port <port>` | WireGuard UDP listening port (default: 51820). |
900
+ | `--cidr <cidr>` | Hub interface address with prefix when used with --server (e.g. "10.0.0.1/24"); the overlay subnet a spoke routes back through the hub when used with --client (default: "10.0.0.0/24"). |
901
+ | `--peer-ip <ip>` | Tunnel address of the target spoke. Required with --client and --peer-add. |
902
+ | `--endpoint <host:port>` | Hub host and port a spoke dials. Required with --client. |
903
+ | `--public-key <key>` | Hub public key with --client; spoke public key with --peer-add. |
904
+ | `--peer-add <peer-id>` | Registers a spoke and applies it to the running hub without a restart. |
905
+ | `--peer-remove <peer-id>` | Removes a spoke from the registry and from the running hub. |
906
+ | `--allowed-ips <cidrs>` | Comma-separated CIDRs routed to the spoke (e.g. "10.0.0.2/32,192.168.10.0/24"). |
907
+ | `--hosts <hosts>` | Comma-separated hostnames bound to the spoke, overriding instance resolution. |
908
+ | `--instances <instances>` | Comma-separated conf.instances.json ids bound to the spoke. |
909
+ | `--default` | Marks the spoke as the fallback for hostnames that match no other binding. |
910
+ | `--haproxy-setup` | Installs HAProxy, publishes the current routes, and enables the daemon. |
911
+ | `--haproxy-sync` | Recompiles the SNI/Host maps from deploy config and hot-reloads HAProxy. |
912
+ | `--status` | Prints the whole edge context without changing anything: role, interface, tunnel address, public key, daemon states, peers with their bindings and link health, and the resolved routing. |
913
+ | `--build-conf` | Writes only engine-private/deploy/conf.wireguard.json and touches no host state. Combine with --wireguard-setup / --peer-add / --peer-remove to author the topology off-box; alone it normalizes and validates the existing registry. |
914
+ | `--forward-proxy-server` | Ensures the hub HTTP/CONNECT forward proxy runs as the underpost-forward-proxy systemd service, bound to the tunnel address only (default port 1080), and returns. Authenticates every request with FORWARD_PROXY_API_KEY, so spokes can reach the internet through the VPS public address. Idempotent: re-running converges on the one service and restarts it only when the unit actually changed. |
915
+ | `--forward-proxy-server-host <host>` | Address the forward proxy binds, overriding the hub tunnel address from the registry. |
916
+ | `--forward-proxy-server-port <port>` | Port the forward proxy binds (default: 1080). |
917
+ | `--ssh-forward-port <port>` | Publishes the default spoke SSH port on this public TCP port of the hub, so CI with no fixed address can reach the cluster node (e.g. 2222). "0" closes it. Stored in the registry. |
918
+ | `--wireguard-start` | Enables and starts wg-quick@<interface> and the QUIC forward. |
919
+ | `--wireguard-stop` | Tears down the interface and removes its transient packet rules. |
920
+ | `--wireguard-reset` | Removes generated configs and packet rules, keeping the key pair and registry. |
921
+ | `--wireguard-reinstall` | Full purge, package reinstall and re-key; every spoke must re-register. |
922
+ | `--dry-run` | Prints the files and commands the run would apply, without touching the host. |
923
+ | `-h, --help` | display help for command |
924
+
925
+ ---
926
+
927
+ ### underpost vultr
928
+
929
+ Meters the edge VPS bandwidth against its Vultr plan quota and blocks egress before overage accrues.
930
+
931
+ **Usage:** `underpost vultr [options] [deploy-list]`
932
+
933
+ #### Arguments
934
+
935
+ | Argument | Description |
936
+ | --- | --- |
937
+ | `deploy-list` | A comma-separated list of deployment IDs, logged for attribution. |
938
+
939
+ #### Options
940
+
941
+ | Option | Description |
942
+ | --- | --- |
943
+ | `--instance-id <instance-id>` | Vultr instance id to meter (default: VULTR_INSTANCE_ID). |
944
+ | `--api-key <api-key>` | Vultr API key (default: VULTR_API_KEY). Prefer the environment over this flag. |
945
+ | `--threshold <ratio>` | Fraction of the plan quota that triggers the egress block; "0.80" and "80" are both accepted (default: 0.80). |
946
+ | `--metric <metric>` | "total" (incoming + outgoing, default) or "outgoing" for egress alone. |
947
+ | `--month <yyyy-mm>` | Billing month to sum (default: the current UTC month). |
948
+ | `--all-dates` | Sum every daily bucket the API returns instead of scoping to one month. |
949
+ | `--host <ip>` | Edge VPS to block (default: VULTR_VPS_IP, then DEFAULT_SSH_HOST). |
950
+ | `--user <user>` | SSH user on the edge VPS (default: VULTR_SSH_USER, then DEFAULT_SSH_USER, then "root"). |
951
+ | `--key-path <path>` | SSH private key (default: VULTR_SSH_KEY_PATH, then DEFAULT_SSH_KEY_PATH). |
952
+ | `--port <port>` | SSH port on the edge VPS (default: VULTR_SSH_PORT, then DEFAULT_SSH_PORT, then 22). |
953
+ | `--force` | Re-apply the egress block even if it was already applied for this cycle. |
954
+ | `--auto-unblock` | Restore egress automatically once consumption falls back under the threshold. |
955
+ | `--dry-run` | Reports the consumption and the action it would take, without touching the edge VPS. |
956
+ | `-h, --help` | display help for command |
957
+
958
+ ---
959
+
830
960
  ### underpost run
831
961
 
832
962
  Runs specified scripts using various runners.
@@ -837,7 +967,7 @@ Runs specified scripts using various runners.
837
967
 
838
968
  | Argument | Description |
839
969
  | --- | --- |
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. |
970
+ | `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,kubeadm-wireguard,build-cluster-deployment-manifests,monitor-ui,shared-dir,shared-dir-add-user. |
841
971
  | `path` | The input value, identifier, or path for the operation. |
842
972
 
843
973
  #### Options
@@ -887,7 +1017,7 @@ Runs specified scripts using various runners.
887
1017
  | `--conf-server-path <conf-server-path>` | Sets a custom configuration server path. |
888
1018
  | `--underpost-root <underpost-root>` | Sets a custom Underpost root path. |
889
1019
  | `--cmd-cron-jobs <cmd-cron-jobs>` | Pre-script commands to run before cron job execution. |
890
- | `--deploy-id-cron-jobs <deploy-id-cron-jobs>` | Specifies deployment IDs to synchronize cron jobs with during execution. |
1020
+ | `--deploy-id-cron-jobs <deploy-id-cron-jobs>` | Cron deploy-id to set up during sync; defaults to dd.cron, "none" skips cron setup entirely. |
891
1021
  | `--timezone <timezone>` | Sets the timezone for the runner execution. |
892
1022
  | `--kubeadm` | Sets the kubeadm cluster context for the runner execution. |
893
1023
  | `--k3s` | Sets the k3s cluster context for the runner execution. |
package/README.md CHANGED
@@ -16,7 +16,7 @@
16
16
 
17
17
  <div align="center">
18
18
 
19
- [![Node.js CI](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml) [![Test](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml) [![Downloads](https://img.shields.io/npm/dm/underpost.svg)](https://www.npmjs.com/package/underpost) [![](https://data.jsdelivr.com/v1/package/npm/underpost/badge)](https://www.jsdelivr.com/package/npm/underpost) [![Socket Badge](https://socket.dev/api/badge/npm/package/underpost/3.2.90)](https://socket.dev/npm/package/underpost/overview/3.2.90) [![Coverage Status](https://coveralls.io/repos/github/underpostnet/engine/badge.svg?branch=master)](https://coveralls.io/github/underpostnet/engine?branch=master) [![Version](https://img.shields.io/npm/v/underpost.svg)](https://www.npmjs.org/package/underpost) [![License](https://img.shields.io/npm/l/underpost.svg)](https://www.npmjs.com/package/underpost)
19
+ [![Node.js CI](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml) [![Test](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml) [![Downloads](https://img.shields.io/npm/dm/underpost.svg)](https://www.npmjs.com/package/underpost) [![](https://data.jsdelivr.com/v1/package/npm/underpost/badge)](https://www.jsdelivr.com/package/npm/underpost) [![Socket Badge](https://socket.dev/api/badge/npm/package/underpost/3.3.0)](https://socket.dev/npm/package/underpost/overview/3.3.0) [![Coverage Status](https://coveralls.io/repos/github/underpostnet/engine/badge.svg?branch=master)](https://coveralls.io/github/underpostnet/engine?branch=master) [![Version](https://img.shields.io/npm/v/underpost.svg)](https://www.npmjs.org/package/underpost) [![License](https://img.shields.io/npm/l/underpost.svg)](https://www.npmjs.com/package/underpost)
20
20
 
21
21
  </div>
22
22
 
@@ -88,7 +88,7 @@ npm run dev
88
88
  <!-- cli-index-start -->
89
89
  ## Underpost CLI
90
90
 
91
- > underpost ci/cd cli v3.2.90
91
+ > underpost ci/cd cli v3.3.0
92
92
 
93
93
  **Usage:** `underpost [options] [command]`
94
94
 
@@ -127,6 +127,9 @@ npm run dev
127
127
  | [`test`](CLI-HELP.md#underpost-test) | Manages and runs tests, defaulting to the current Underpost default test suite. |
128
128
  | [`monitor`](CLI-HELP.md#underpost-monitor) | Manages health server monitoring for specified deployments. |
129
129
  | [`ssh`](CLI-HELP.md#underpost-ssh) | Manages SSH credentials and sessions for remote access to cluster nodes or services. |
130
+ | [`wireguard`](CLI-HELP.md#underpost-wireguard) | Manages the WireGuard L3 hub-and-spoke transport and the HAProxy edge gateway in front of it. |
131
+ | [`haproxy`](CLI-HELP.md#underpost-haproxy) | Manages the HAProxy edge gateway over the WireGuard transport (same subsystem as `underpost wireguard`). |
132
+ | [`vultr`](CLI-HELP.md#underpost-vultr) | Meters the edge VPS bandwidth against its Vultr plan quota and blocks egress before overage accrues. |
130
133
  | [`run`](CLI-HELP.md#underpost-run) | Runs specified scripts using various runners. |
131
134
  | [`docker-compose`](CLI-HELP.md#underpost-docker-compose) | General-purpose Docker Compose development pipeline (mirrors the Kubernetes dev stack). |
132
135
  | [`lxd`](CLI-HELP.md#underpost-lxd) | Manages LXD virtual machines as K3s nodes (control plane or workers). |
package/bin/build.js CHANGED
@@ -15,7 +15,6 @@ import {
15
15
  } from '../src/server/conf.js';
16
16
  import { loadDeployCatalog } from '../src/server/catalog.js';
17
17
  import Underpost from '../src/index.js';
18
- import { DOCKER_SCRIPTS } from '../src/api/cyberia-server-defaults/cyberia-server-defaults.js';
19
18
 
20
19
  const baseConfPath = './engine-private/conf/dd-cron/.env.production';
21
20
  if (fs.existsSync(baseConfPath)) dotenv.config({ path: baseConfPath, override: true });
@@ -114,6 +113,9 @@ const buildDeployTemplate = async (confName) => {
114
113
 
115
114
  switch (confName) {
116
115
  case 'dd-cyberia': {
116
+ const { CyberiaDependencies, DOCKER_SCRIPTS } = await import(
117
+ `../src/api/cyberia-server-defaults/cyberia-server-defaults.js`
118
+ );
117
119
  fs.copyFileSync(`./bin/cyberia.js`, `${basePath}/bin/cyberia.js`);
118
120
  fs.copyFileSync(
119
121
  `./.github/workflows/publish.cyberia.ci.yml`,
@@ -124,7 +126,6 @@ const buildDeployTemplate = async (confName) => {
124
126
  packageJson.bin.cyberia = 'bin/index.js';
125
127
  packageJson.keywords = catalog.keywords;
126
128
  packageJson.description = catalog.description;
127
- const { CyberiaDependencies } = await import(`../src/api/cyberia-server-defaults/cyberia-server-defaults.js`);
128
129
  packageJson.dependencies = {
129
130
  underpost: '^' + Underpost.version.replace('v', ''),
130
131
  'adm-zip': '^0.6.0',
@@ -155,9 +156,10 @@ const buildDeployTemplate = async (confName) => {
155
156
  JSON.stringify(packageJson, null, 4).replaceAll('pwa-microservices-template', repoName),
156
157
  'utf8',
157
158
  );
158
-
159
- fs.copySync(`./src/cli`, `${basePath}/src/cli`);
160
- if (!fs.existsSync(`${basePath}/images`)) fs.mkdirSync(`${basePath}/images`);
159
+ if (fs.existsSync(`./deploy/${confName}`))
160
+ fs.copySync(`./deploy/${confName}`, `${basePath}/deploy/${confName}`, {
161
+ overwrite: true,
162
+ });
161
163
 
162
164
  fs.copyFileSync(`./.github/workflows/${repoName}.ci.yml`, `${basePath}/.github/workflows/${repoName}.ci.yml`);
163
165
  if (fs.existsSync(`./.github/workflows/docker-image.${repoName}.ci.yml`))
package/bin/deploy.js CHANGED
@@ -14,10 +14,10 @@ import {
14
14
  addWsConf,
15
15
  buildWsSrc,
16
16
  cloneSrcComponents,
17
- writeEnv,
18
17
  buildCliDoc,
19
18
  loadConf,
20
19
  } from '../src/server/conf.js';
20
+ import { writeEnv } from '../src/server/environment.js';
21
21
  import colors from 'colors';
22
22
  import { program } from '../src/cli/index.js';
23
23
  import { timer, getCapVariableName } from '../src/client/components/core/CommonJs.js';
@@ -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
+ }