underpost 3.2.9 → 3.2.11

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 (104) hide show
  1. package/.github/workflows/npmpkg.ci.yml +1 -0
  2. package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
  3. package/.github/workflows/release.cd.yml +1 -0
  4. package/.vscode/extensions.json +9 -9
  5. package/.vscode/settings.json +20 -4
  6. package/CHANGELOG.md +195 -1
  7. package/CLI-HELP.md +92 -23
  8. package/README.md +38 -9
  9. package/bin/build.js +27 -7
  10. package/bin/build.template.js +187 -0
  11. package/bin/deploy.js +12 -2
  12. package/bin/index.js +2 -1
  13. package/bump.config.js +26 -0
  14. package/conf.js +20 -7
  15. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
  16. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
  17. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  18. package/manifests/deployment/dd-test-development/deployment.yaml +4 -2
  19. package/manifests/kind-config-dev.yaml +8 -0
  20. package/manifests/lxd/lxd-admin-profile.yaml +12 -3
  21. package/manifests/mongodb/pv-pvc.yaml +44 -8
  22. package/manifests/mongodb/statefulset.yaml +55 -68
  23. package/manifests/mongodb-4.4/headless-service.yaml +10 -0
  24. package/manifests/mongodb-4.4/kustomization.yaml +3 -1
  25. package/manifests/mongodb-4.4/mongodb-nodeport.yaml +17 -0
  26. package/manifests/mongodb-4.4/pv-pvc.yaml +10 -14
  27. package/manifests/mongodb-4.4/statefulset.yaml +79 -0
  28. package/manifests/mongodb-4.4/storage-class.yaml +9 -0
  29. package/manifests/valkey/statefulset.yaml +1 -1
  30. package/manifests/valkey/valkey-nodeport.yaml +17 -0
  31. package/package.json +27 -12
  32. package/scripts/ipxe-setup.sh +52 -49
  33. package/scripts/k3s-node-setup.sh +81 -46
  34. package/scripts/lxd-vm-setup.sh +193 -8
  35. package/scripts/maas-nat-firewalld.sh +145 -0
  36. package/src/api/core/core.router.js +19 -14
  37. package/src/api/core/core.service.js +5 -5
  38. package/src/api/default/default.router.js +22 -18
  39. package/src/api/default/default.service.js +5 -5
  40. package/src/api/document/document.router.js +28 -23
  41. package/src/api/document/document.service.js +100 -23
  42. package/src/api/file/file.router.js +19 -13
  43. package/src/api/file/file.service.js +9 -7
  44. package/src/api/test/test.router.js +17 -12
  45. package/src/api/types.js +24 -0
  46. package/src/api/user/guest.service.js +5 -4
  47. package/src/api/user/user.router.js +297 -288
  48. package/src/api/user/user.service.js +100 -35
  49. package/src/cli/baremetal.js +132 -101
  50. package/src/cli/cluster.js +700 -232
  51. package/src/cli/db.js +59 -60
  52. package/src/cli/deploy.js +216 -137
  53. package/src/cli/fs.js +13 -3
  54. package/src/cli/index.js +80 -15
  55. package/src/cli/ipfs.js +4 -6
  56. package/src/cli/kubectl.js +4 -1
  57. package/src/cli/lxd.js +1099 -223
  58. package/src/cli/monitor.js +9 -3
  59. package/src/cli/release.js +334 -140
  60. package/src/cli/repository.js +68 -23
  61. package/src/cli/run.js +191 -47
  62. package/src/cli/secrets.js +11 -2
  63. package/src/cli/test.js +9 -3
  64. package/src/client/Default.index.js +9 -3
  65. package/src/client/components/core/Auth.js +5 -0
  66. package/src/client/components/core/ClientEvents.js +76 -0
  67. package/src/client/components/core/EventBus.js +4 -0
  68. package/src/client/components/core/Modal.js +82 -41
  69. package/src/client/components/core/PanelForm.js +56 -52
  70. package/src/client/components/core/Worker.js +162 -363
  71. package/src/client/sw/core.sw.js +174 -112
  72. package/src/db/DataBaseProvider.js +115 -15
  73. package/src/db/mariadb/MariaDB.js +2 -1
  74. package/src/db/mongo/MongoBootstrap.js +657 -0
  75. package/src/db/mongo/MongooseDB.js +129 -21
  76. package/src/index.js +1 -1
  77. package/src/runtime/express/Express.js +2 -2
  78. package/src/runtime/wp/Wp.js +8 -5
  79. package/src/server/auth.js +2 -2
  80. package/src/server/client-build-docs.js +1 -1
  81. package/src/server/client-build.js +94 -129
  82. package/src/server/conf.js +81 -79
  83. package/src/server/process.js +180 -19
  84. package/src/server/proxy.js +9 -2
  85. package/src/server/runtime.js +1 -1
  86. package/src/server/start.js +16 -4
  87. package/src/server/valkey.js +2 -0
  88. package/src/ws/IoInterface.js +16 -16
  89. package/src/ws/core/channels/core.ws.chat.js +11 -11
  90. package/src/ws/core/channels/core.ws.mailer.js +29 -29
  91. package/src/ws/core/channels/core.ws.stream.js +19 -19
  92. package/src/ws/core/core.ws.connection.js +8 -8
  93. package/src/ws/core/core.ws.server.js +6 -5
  94. package/src/ws/default/channels/default.ws.main.js +10 -10
  95. package/src/ws/default/default.ws.connection.js +4 -4
  96. package/src/ws/default/default.ws.server.js +4 -3
  97. package/bin/file.js +0 -202
  98. package/bin/vs.js +0 -74
  99. package/bin/zed.js +0 -84
  100. package/src/client/ssr/email/DefaultRecoverEmail.js +0 -21
  101. package/src/client/ssr/email/DefaultVerifyEmail.js +0 -17
  102. /package/src/client/ssr/{offline → views}/Maintenance.js +0 -0
  103. /package/src/client/ssr/{offline → views}/NoNetworkConnection.js +0 -0
  104. /package/src/client/ssr/{pages → views}/Test.js +0 -0
package/src/cli/index.js CHANGED
@@ -242,15 +242,27 @@ program
242
242
  .command('cluster')
243
243
  .argument('[pod-name]', 'Optional: Filters information by a specific pod name.')
244
244
  .option('--reset', `Deletes all clusters and prunes all related data and caches.`)
245
+ .option(
246
+ '--reset-mongodb',
247
+ `Performs a hard cleanup of only MongoDB-related resources (StatefulSet, PVCs/PVs, Secrets, ConfigMaps, caches) without restarting the whole node.`,
248
+ )
245
249
  .option('--mariadb', 'Initializes the cluster with a MariaDB statefulset.')
246
250
  .option('--mysql', 'Initializes the cluster with a MySQL statefulset.')
247
251
  .option('--mongodb', 'Initializes the cluster with a MongoDB statefulset.')
248
- .option('--mongo-db-host <host>', 'Set custom mongo db host')
252
+ .option('--service-host <host>', 'Set custom host/IP for exposed MongoDB and Valkey clients.')
249
253
  .option('--postgresql', 'Initializes the cluster with a PostgreSQL statefulset.')
250
254
  .option('--mongodb4', 'Initializes the cluster with a MongoDB 4.4 service.')
251
255
  .option('--valkey', 'Initializes the cluster with a Valkey service.')
252
256
  .option('--ipfs', 'Initializes the cluster with an ipfs-cluster statefulset.')
253
257
  .option('--contour', 'Initializes the cluster with Project Contour base HTTPProxy and Envoy.')
258
+ .option(
259
+ '--node-port',
260
+ 'Exposes enabled ready services (e.g. MongoDB 4.4, Valkey) to the host/public network via their NodePort Service manifest.',
261
+ )
262
+ .option(
263
+ '--node-selector <k8s-node-name>',
264
+ 'Pins the just-deployed StatefulSet (MongoDB 4.4 / Valkey) to the given Kubernetes node once it is ready (via a kubernetes.io/hostname nodeSelector).',
265
+ )
254
266
  .option('--cert-manager', "Initializes the cluster with a Let's Encrypt production ClusterIssuer.")
255
267
  .option('--dedicated-gpu', 'Initializes the cluster with dedicated GPU base resources and environment settings.')
256
268
  .option(
@@ -281,6 +293,10 @@ program
281
293
  .option('--k3s', 'Initializes the cluster using K3s (Lightweight Kubernetes).')
282
294
  .option('--hosts <hosts>', 'A comma-separated list of cluster hostnames or IP addresses.')
283
295
  .option('--remove-volume-host-paths', 'Removes specified volume host paths after execution.')
296
+ .option(
297
+ '--reset-mode <mode>',
298
+ 'Reset mode for --reset --k3s: "drain" (stop services, keep K3s installed) or "full" (uninstall + cleanup). Default: "full".',
299
+ )
284
300
  .option('--namespace <namespace>', 'Kubernetes namespace for cluster operations (defaults to "default").')
285
301
  .option('--replicas <replicas>', 'Sets a custom number of replicas for statefulset deployments.')
286
302
  .action(Underpost.cluster.init)
@@ -327,8 +343,6 @@ program
327
343
  .option('--k3s', 'Enables the k3s context for deployment operations.')
328
344
  .option('--kind', 'Enables the kind context for deployment operations.')
329
345
  .option('--git-clean', 'Runs git clean on volume mount paths before copying.')
330
- .option('--etc-hosts', 'Enables the etc-hosts context for deployment operations.')
331
- .option('--restore-hosts', 'Restores default `/etc/hosts` entries.')
332
346
  .option('--disable-update-underpost-config', 'Disables updates to Underpost configuration during deployment.')
333
347
  .option('--namespace <namespace>', 'Kubernetes namespace for deployment operations (defaults to "default").')
334
348
  .option('--kind-type <kind-type>', 'Specifies the Kind cluster type for deployment operations.')
@@ -346,6 +360,10 @@ program
346
360
  '--pull-bundle',
347
361
  'Explicitly pull the pre-built client bundle from Cloudinary inside the container. Use together with --skip-full-build.',
348
362
  )
363
+ .option(
364
+ '--image-pull-policy <policy>',
365
+ 'Override container imagePullPolicy in the generated deployment manifest (Always, IfNotPresent, Never). Defaults to Never for localhost/ images and IfNotPresent otherwise.',
366
+ )
349
367
  .description('Manages application deployments, defaulting to deploying development pods.')
350
368
  .action(Underpost.deploy.callback);
351
369
 
@@ -682,13 +700,33 @@ program
682
700
  '--pull-bundle',
683
701
  'Explicitly download the pre-built client bundle from Cloudinary inside the container (supported by: sync, template-deploy). Use together with --skip-full-build.',
684
702
  )
703
+ .option('--remove', 'Remove/teardown resources')
685
704
  .description('Runs specified scripts using various runners.')
686
705
  .action(Underpost.run.callback);
687
706
 
688
707
  program
689
708
  .command('lxd')
709
+ .argument(
710
+ '[vm-id]',
711
+ 'VM identifier shared by current-VM flags like --vm-create, --vm-delete, --vm-init, --vm-info, and --vm-test.',
712
+ )
690
713
  .option('--init', 'Initializes LXD on the current machine via preseed.')
691
- .option('--reset', 'Removes the LXD snap and purges all data.')
714
+ .option(
715
+ '--reset',
716
+ 'Host-safe reset: removes proxy devices, stops/deletes VMs, drops admin-profile and lxdbr0. Does NOT touch the LXD snap or storage pools.',
717
+ )
718
+ .option(
719
+ '--purge',
720
+ 'DESTRUCTIVE: gracefully shuts down the LXD daemon (60s timeout), then removes the LXD snap. Combine with --reset to wipe per-VM state first. Safe replacement for the prior aggressive teardown.',
721
+ )
722
+ .option(
723
+ '--shutdown',
724
+ 'Pre-host-reboot procedure: gracefully stops every VM and the LXD daemon. Run BEFORE any reboot/poweroff to keep the host bootable.',
725
+ )
726
+ .option(
727
+ '--restore',
728
+ 'Symmetric to --shutdown: starts the LXD daemon, waits for it to be responsive, then starts every VM. VMs created via admin-profile have boot.autostart=false, so this is the explicit "bring the lab back up" command.',
729
+ )
692
730
  .option('--install', 'Installs the LXD snap.')
693
731
  .option('--dev', 'Use local paths instead of the global npm installation.')
694
732
  .option('--create-virtual-network', 'Creates the lxdbr0 bridge network.')
@@ -696,25 +734,48 @@ program
696
734
  .option('--create-admin-profile', 'Creates the admin-profile for VM management.')
697
735
  .option('--control', 'Initialize the target VM as a K3s control plane node.')
698
736
  .option('--worker', 'Initialize the target VM as a K3s worker node.')
699
- .option('--create-vm <vm-name>', 'Copy the LXC launch command for a new K3s VM to the clipboard.')
700
- .option('--delete-vm <vm-name>', 'Stop and delete the specified VM.')
701
- .option('--init-vm <vm-name>', 'Run k3s-node-setup.sh on the specified VM (use with --control or --worker).')
702
- .option('--info-vm <vm-name>', 'Display full configuration and status for the specified VM.')
703
- .option('--test <vm-name>', 'Run connectivity and health checks on the specified VM.')
704
- .option('--root-size <gb-size>', 'Root disk size in GiB for --create-vm (default: 32).')
737
+ .option('--vm-create', 'Copy the LXC launch command for the command argument [vm-id] to the clipboard.')
738
+ .option(
739
+ '--vm-delete',
740
+ 'SAFELY stop and delete the command argument [vm-id] (removes proxy devices first, then stops, then deletes). Safe to re-run.',
741
+ )
742
+ .option(
743
+ '--vm-init',
744
+ 'Bring the command argument [vm-id] up as a K3s node end-to-end: OS base setup, mirror /home/dd/engine into the VM, then K3s role install via the local engine (use with --control or --worker).',
745
+ )
746
+ .option('--vm-info', 'Display full configuration and status for the command argument [vm-id].')
747
+ .option('--vm-test', 'Run connectivity and health checks on the command argument [vm-id].')
748
+ .option(
749
+ '--vm-sync-engine',
750
+ 'Re-copy the host engine source into the command argument [vm-id], overriding whatever is currently there (equivalent to the engine-bootstrap step of --vm-init in isolation).',
751
+ )
752
+ .option('--root-size <gb-size>', 'Root disk size in GiB for --vm-create (default: 32).')
705
753
  .option(
706
754
  '--join-node <nodes>',
707
755
  'Join a K3s worker to a control plane. Standalone format: "workerName,controlName". ' +
708
- 'When used with --init-vm --worker, provide just the control node name for auto-join.',
756
+ 'When used with --vm-init --worker, provide just the control node name for auto-join.',
709
757
  )
710
758
  .option('--expose <vm-name:ports>', 'Proxy host ports to a VM (e.g., "k3s-control:80,443").')
759
+ .option(
760
+ '--node-port <port>',
761
+ 'Customizes the VM-side (connect) port for --expose, so the host listens on the given port but proxies to this NodePort inside the VM (e.g. expose host 27017 -> VM NodePort 32017).',
762
+ )
711
763
  .option('--delete-expose <vm-name:ports>', 'Remove proxied ports from a VM (e.g., "k3s-control:80,443").')
712
- .option('--workflow-id <workflow-id>', 'Workflow ID to execute via runWorkflow.')
713
- .option('--vm-id <vm-name>', 'Target VM name for workflow execution.')
714
- .option('--deploy-id <deploy-id>', 'Deployment ID context for workflow execution.')
764
+ .option(
765
+ '--copy',
766
+ 'For two-phase flows that surface a command for the user to execute (e.g. --create-admin-profile phase 1), copy the command to the clipboard instead of printing it to the terminal.',
767
+ )
715
768
  .option('--namespace <namespace>', 'Kubernetes namespace context (defaults to "default").')
769
+ .option(
770
+ '--maas-project <project>',
771
+ 'LXD project managed by MAAS (e.g. "k3s-cluster"). When set, all lxc commands target this project so MAAS enumerates the VMs in its machines UI.',
772
+ )
773
+ .option(
774
+ '--move-to-project',
775
+ 'Stop the [vm-id] VM in the default project, move it to --maas-project, then start it so MAAS picks it up. Requires --maas-project.',
776
+ )
716
777
  .description('Manages LXD virtual machines as K3s nodes (control plane or workers).')
717
- .action(Underpost.lxd.callback);
778
+ .action((vmId, options) => Underpost.lxd.callback(vmId, options));
718
779
 
719
780
  program
720
781
  .command('baremetal [workflow-id]')
@@ -824,6 +885,10 @@ program
824
885
  '--pwa-build',
825
886
  'Runs the pwa-microservices-template update flow: always re-clones, syncs engine sources, installs, builds, and pushes.',
826
887
  )
888
+ .option(
889
+ '--dry-run',
890
+ 'For --build: previews version-bump changes (per-file substitution counts) without writing files or running downstream commands.',
891
+ )
827
892
  .description('Release orchestrator for building new versions and deploying releases of the Underpost CLI.')
828
893
  .action(async (version, options) => {
829
894
  if (options.build) return Underpost.release.build(version, options);
package/src/cli/ipfs.js CHANGED
@@ -131,12 +131,10 @@ class UnderpostIPFS {
131
131
  // Apply UDP buffer sysctl on every Kind node so QUIC (used by IPFS) can reach the
132
132
  // recommended 7.5 MB buffer size. Kind nodes are containers and do NOT inherit the
133
133
  // host sysctl values, so this must be set via docker exec on each node directly.
134
- if (!options.kubeadm && !options.k3s) {
135
- logger.info('Applying UDP buffer sysctl on Kind nodes');
136
- shellExec(
137
- `for node in $(kind get nodes); do docker exec $node sysctl -w net.core.rmem_max=7500000 net.core.wmem_max=7500000; done`,
138
- );
139
- }
134
+ shellExec(
135
+ `sudo sysctl -w net.core.rmem_max=7500000
136
+ sudo sysctl -w net.core.wmem_max=7500000`,
137
+ );
140
138
 
141
139
  shellExec(`kubectl apply -f ${underpostRoot}/manifests/ipfs/storage-class.yaml`);
142
140
  shellExec(`kubectl apply -k ${underpostRoot}/manifests/ipfs -n ${options.namespace}`);
@@ -47,9 +47,12 @@ class UnderpostKubectl {
47
47
  * @memberof UnderpostKubectl
48
48
  */
49
49
  get(deployId, kindType = 'pods', namespace = '') {
50
+ // Existence-check style: a missing kubectl context, a non-existent
51
+ // namespace, or no pods matching the filter must return an empty
52
+ // list (not throw). silentOnError keeps the legacy contract.
50
53
  const raw = shellExec(
51
54
  `sudo kubectl get ${kindType}${namespace ? ` -n ${namespace}` : ` --all-namespaces`} -o wide`,
52
- { stdout: true, disableLog: true, silent: true },
55
+ { stdout: true, disableLog: true, silent: true, silentOnError: true },
53
56
  );
54
57
 
55
58
  const heads = raw