underpost 3.2.8 → 3.2.10
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/.github/workflows/npmpkg.ci.yml +1 -0
- package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
- package/.github/workflows/release.cd.yml +1 -0
- package/.vscode/settings.json +10 -5
- package/CHANGELOG.md +223 -2
- package/CLI-HELP.md +36 -7
- package/README.md +38 -9
- package/bin/build.js +27 -11
- package/bin/deploy.js +20 -21
- package/bin/file.js +32 -13
- package/bin/index.js +2 -1
- package/bin/vs.js +1 -1
- package/bump.config.js +26 -0
- package/conf.js +20 -4
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +2 -2
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +2 -2
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +4 -2
- package/manifests/kind-config-dev.yaml +8 -0
- package/manifests/mongodb/pv-pvc.yaml +44 -8
- package/manifests/mongodb/statefulset.yaml +55 -68
- package/package.json +40 -25
- package/scripts/k3s-node-setup.sh +30 -11
- package/scripts/nat-iptables.sh +103 -18
- package/src/api/core/core.router.js +19 -14
- package/src/api/core/core.service.js +5 -5
- package/src/api/default/default.router.js +22 -18
- package/src/api/default/default.service.js +5 -5
- package/src/api/document/document.router.js +28 -23
- package/src/api/document/document.service.js +100 -23
- package/src/api/file/file.router.js +19 -13
- package/src/api/file/file.service.js +9 -7
- package/src/api/test/test.router.js +17 -12
- package/src/api/types.js +24 -0
- package/src/api/user/guest.service.js +5 -4
- package/src/api/user/user.router.js +297 -288
- package/src/api/user/user.service.js +100 -35
- package/src/cli/baremetal.js +20 -11
- package/src/cli/cluster.js +243 -55
- package/src/cli/db.js +106 -62
- package/src/cli/deploy.js +297 -154
- package/src/cli/fs.js +19 -3
- package/src/cli/index.js +37 -9
- package/src/cli/ipfs.js +4 -6
- package/src/cli/kubectl.js +4 -1
- package/src/cli/lxd.js +217 -135
- package/src/cli/release.js +289 -131
- package/src/cli/repository.js +91 -34
- package/src/cli/run.js +297 -56
- package/src/cli/test.js +9 -3
- package/src/client/Default.index.js +9 -3
- package/src/client/components/core/Auth.js +19 -5
- package/src/client/components/core/Docs.js +6 -34
- package/src/client/components/core/FileExplorer.js +6 -6
- package/src/client/components/core/Modal.js +65 -2
- package/src/client/components/core/PanelForm.js +56 -52
- package/src/client/components/core/Recover.js +4 -4
- package/src/client/components/core/Worker.js +170 -350
- package/src/client/services/default/default.management.js +20 -25
- package/src/client/services/user/guest.service.js +10 -3
- package/src/client/sw/core.sw.js +174 -112
- package/src/db/DataBaseProvider.js +120 -20
- package/src/db/mongo/MongoBootstrap.js +587 -0
- package/src/db/mongo/MongooseDB.js +126 -22
- package/src/index.js +1 -1
- package/src/runtime/express/Express.js +2 -2
- package/src/runtime/wp/Wp.js +8 -5
- package/src/server/auth.js +2 -2
- package/src/server/client-build-docs.js +1 -1
- package/src/server/client-build.js +94 -129
- package/src/server/conf.js +20 -65
- package/src/server/data-query.js +32 -20
- package/src/server/dns.js +22 -0
- package/src/server/process.js +180 -19
- package/src/server/runtime.js +1 -1
- package/src/server/start.js +26 -7
- package/src/server/valkey.js +9 -2
- package/src/ws/IoInterface.js +16 -16
- package/src/ws/core/channels/core.ws.chat.js +11 -11
- package/src/ws/core/channels/core.ws.mailer.js +29 -29
- package/src/ws/core/channels/core.ws.stream.js +19 -19
- package/src/ws/core/core.ws.connection.js +8 -8
- package/src/ws/core/core.ws.server.js +6 -5
- package/src/ws/default/channels/default.ws.main.js +10 -10
- package/src/ws/default/default.ws.connection.js +4 -4
- package/src/ws/default/default.ws.server.js +4 -3
- package/typedoc.json +10 -1
- package/src/client/ssr/email/DefaultRecoverEmail.js +0 -21
- package/src/client/ssr/email/DefaultVerifyEmail.js +0 -17
- /package/src/client/ssr/{offline → views}/Maintenance.js +0 -0
- /package/src/client/ssr/{offline → views}/NoNetworkConnection.js +0 -0
- /package/src/client/ssr/{pages → views}/Test.js +0 -0
package/src/cli/fs.js
CHANGED
|
@@ -150,8 +150,14 @@ class UnderpostFileStorage {
|
|
|
150
150
|
} else pullSkipCount++;
|
|
151
151
|
}
|
|
152
152
|
if (pullSkipCount > 0) logger.warn(`Pull skipped ${pullSkipCount} files that already exist`);
|
|
153
|
-
|
|
154
|
-
|
|
153
|
+
// Only run git init/commit when the caller explicitly requests git tracking (--git flag).
|
|
154
|
+
// For bundle pulls into ./build the git step is unwanted and would error on a non-repo path.
|
|
155
|
+
if (options.git === true) {
|
|
156
|
+
Underpost.repo.initLocalRepo({ path });
|
|
157
|
+
shellExec(`cd ${path} && git add . && git commit -m "Base pull state"`, {
|
|
158
|
+
silentOnError: true
|
|
159
|
+
});
|
|
160
|
+
}
|
|
155
161
|
} else {
|
|
156
162
|
const files =
|
|
157
163
|
options.git === true ? Underpost.repo.getChangedFiles(path) : await fs.readdir(path, { recursive: true });
|
|
@@ -203,11 +209,13 @@ class UnderpostFileStorage {
|
|
|
203
209
|
* @description Uploads a file to Cloudinary.
|
|
204
210
|
* @param {string} path - The path to the file to upload.
|
|
205
211
|
* @param {object} [options] - An object containing options for the upload.
|
|
206
|
-
* @param {
|
|
212
|
+
* @param {string} [options.deployId=''] - The identifier for the deployment (used to locate the storage config file).
|
|
213
|
+
* @param {boolean} [options.force=false] - Flag to force file operations (overwrites existing remote asset).
|
|
207
214
|
* @param {string} [options.storageFilePath=''] - The path to the storage configuration file.
|
|
208
215
|
* @returns {Promise<object>} A promise that resolves to the upload result.
|
|
209
216
|
* @memberof UnderpostFileStorage
|
|
210
217
|
*/
|
|
218
|
+
|
|
211
219
|
async upload(
|
|
212
220
|
path,
|
|
213
221
|
options = { rm: false, recursive: false, deployId: '', force: false, pull: false, storageFilePath: '' },
|
|
@@ -235,6 +243,7 @@ class UnderpostFileStorage {
|
|
|
235
243
|
* @param {string} path - The path to the file to pull.
|
|
236
244
|
* @param {object} [options] - Pull options.
|
|
237
245
|
* @param {boolean} [options.omitUnzip=false] - If true, do not extract zip and keep downloaded zip file.
|
|
246
|
+
* @param {boolean} [options.force=false] - If true, re-download even if the local zip already exists.
|
|
238
247
|
* @returns {Promise<void>} A promise that resolves when the file is pulled.
|
|
239
248
|
* @memberof UnderpostFileStorage
|
|
240
249
|
*/
|
|
@@ -264,6 +273,13 @@ class UnderpostFileStorage {
|
|
|
264
273
|
path = Underpost.fs.zip2File(zipPath);
|
|
265
274
|
fs.removeSync(`${path}.zip`);
|
|
266
275
|
},
|
|
276
|
+
/**
|
|
277
|
+
* @method delete
|
|
278
|
+
* @description Deletes a file from Cloudinary by its public ID.
|
|
279
|
+
* @param {string} path - The path (public ID) of the file to delete.
|
|
280
|
+
* @returns {Promise<object>} A promise that resolves to the Cloudinary delete result.
|
|
281
|
+
* @memberof UnderpostFileStorage
|
|
282
|
+
*/
|
|
267
283
|
async delete(path) {
|
|
268
284
|
Underpost.fs.cloudinaryConfig();
|
|
269
285
|
const deleteResult = await cloudinary.api
|
package/src/cli/index.js
CHANGED
|
@@ -66,6 +66,10 @@ program
|
|
|
66
66
|
.option('--underpost-quickly-install', 'Uses Underpost Quickly Install for dependency installation.')
|
|
67
67
|
.option('--skip-pull-base', 'Skips cloning repositories, uses current workspace code directly.')
|
|
68
68
|
.option('--skip-full-build', 'Skips the full client bundle build during deployment.')
|
|
69
|
+
.option(
|
|
70
|
+
'--pull-bundle',
|
|
71
|
+
'Downloads the pre-built client bundle from Cloudinary via pull-bundle before starting. Use together with --skip-full-build to skip the local build entirely.',
|
|
72
|
+
)
|
|
69
73
|
.action(Underpost.start.callback)
|
|
70
74
|
.description('Initiates application servers, build pipelines, or other defined services based on the deployment ID.');
|
|
71
75
|
|
|
@@ -230,6 +234,7 @@ program
|
|
|
230
234
|
.option('--ban-egress-clear', 'Clears all banned egress IP addresses.')
|
|
231
235
|
.option('--ban-both-add', 'Adds IP addresses to both banned ingress and egress lists.')
|
|
232
236
|
.option('--ban-both-remove', 'Removes IP addresses from both banned ingress and egress lists.')
|
|
237
|
+
.option('--mac', 'Prints the MAC address of the main network interface.')
|
|
233
238
|
.description('Displays the current public machine IP addresses.')
|
|
234
239
|
.action(Underpost.dns.ipDispatcher);
|
|
235
240
|
|
|
@@ -237,6 +242,7 @@ program
|
|
|
237
242
|
.command('cluster')
|
|
238
243
|
.argument('[pod-name]', 'Optional: Filters information by a specific pod name.')
|
|
239
244
|
.option('--reset', `Deletes all clusters and prunes all related data and caches.`)
|
|
245
|
+
.option('--reset-mongodb', `Performs a hard cleanup of only MongoDB-related resources (StatefulSet, PVCs/PVs, Secrets, ConfigMaps, caches) without restarting the whole node.`)
|
|
240
246
|
.option('--mariadb', 'Initializes the cluster with a MariaDB statefulset.')
|
|
241
247
|
.option('--mysql', 'Initializes the cluster with a MySQL statefulset.')
|
|
242
248
|
.option('--mongodb', 'Initializes the cluster with a MongoDB statefulset.')
|
|
@@ -333,6 +339,18 @@ program
|
|
|
333
339
|
'Sets the local:remote port to expose when --expose is active (overrides auto-detected service port).',
|
|
334
340
|
)
|
|
335
341
|
.option('--cmd <cmd>', 'Custom initialization command for deployment (comma-separated commands).')
|
|
342
|
+
.option(
|
|
343
|
+
'--skip-full-build',
|
|
344
|
+
'Skip client bundle rebuild; container will pull pre-built bundle via pull-bundle instead.',
|
|
345
|
+
)
|
|
346
|
+
.option(
|
|
347
|
+
'--pull-bundle',
|
|
348
|
+
'Explicitly pull the pre-built client bundle from Cloudinary inside the container. Use together with --skip-full-build.',
|
|
349
|
+
)
|
|
350
|
+
.option(
|
|
351
|
+
'--image-pull-policy <policy>',
|
|
352
|
+
'Override container imagePullPolicy in the generated deployment manifest (Always, IfNotPresent, Never). Defaults to Never for localhost/ images and IfNotPresent otherwise.',
|
|
353
|
+
)
|
|
336
354
|
.description('Manages application deployments, defaulting to deploying development pods.')
|
|
337
355
|
.action(Underpost.deploy.callback);
|
|
338
356
|
|
|
@@ -657,17 +675,25 @@ program
|
|
|
657
675
|
.option(
|
|
658
676
|
'--host-aliases <host-aliases>',
|
|
659
677
|
'Adds entries to the Pod /etc/hosts via hostAliases. ' +
|
|
660
|
-
|
|
661
|
-
|
|
678
|
+
'Format: semicolon-separated entries of "ip=hostname1,hostname2" ' +
|
|
679
|
+
'(e.g., "127.0.0.1=foo.local,bar.local;10.1.2.3=foo.remote,bar.remote").',
|
|
662
680
|
)
|
|
663
681
|
.option('--copy', 'Copies the runner output to the clipboard (supported by: generate-pass, template-deploy-local).')
|
|
682
|
+
.option(
|
|
683
|
+
'--skip-full-build',
|
|
684
|
+
'Skip client bundle rebuild; triggers pull-bundle in container startup (supported by: sync, template-deploy).',
|
|
685
|
+
)
|
|
686
|
+
.option(
|
|
687
|
+
'--pull-bundle',
|
|
688
|
+
'Explicitly download the pre-built client bundle from Cloudinary inside the container (supported by: sync, template-deploy). Use together with --skip-full-build.',
|
|
689
|
+
)
|
|
664
690
|
.description('Runs specified scripts using various runners.')
|
|
665
691
|
.action(Underpost.run.callback);
|
|
666
692
|
|
|
667
693
|
program
|
|
668
694
|
.command('lxd')
|
|
669
695
|
.option('--init', 'Initializes LXD on the current machine via preseed.')
|
|
670
|
-
.option('--reset', '
|
|
696
|
+
.option('--reset', 'SAFE complete reset: cleans all VMs (proxy devices first), profiles, networks, then removes LXD snap.')
|
|
671
697
|
.option('--install', 'Installs the LXD snap.')
|
|
672
698
|
.option('--dev', 'Use local paths instead of the global npm installation.')
|
|
673
699
|
.option('--create-virtual-network', 'Creates the lxdbr0 bridge network.')
|
|
@@ -676,7 +702,7 @@ program
|
|
|
676
702
|
.option('--control', 'Initialize the target VM as a K3s control plane node.')
|
|
677
703
|
.option('--worker', 'Initialize the target VM as a K3s worker node.')
|
|
678
704
|
.option('--create-vm <vm-name>', 'Copy the LXC launch command for a new K3s VM to the clipboard.')
|
|
679
|
-
.option('--delete-vm <vm-name>', '
|
|
705
|
+
.option('--delete-vm <vm-name>', 'SAFELY stop and delete VM (removes proxy devices first, then stops, then deletes). Safe to re-run.')
|
|
680
706
|
.option('--init-vm <vm-name>', 'Run k3s-node-setup.sh on the specified VM (use with --control or --worker).')
|
|
681
707
|
.option('--info-vm <vm-name>', 'Display full configuration and status for the specified VM.')
|
|
682
708
|
.option('--test <vm-name>', 'Run connectivity and health checks on the specified VM.')
|
|
@@ -684,13 +710,11 @@ program
|
|
|
684
710
|
.option(
|
|
685
711
|
'--join-node <nodes>',
|
|
686
712
|
'Join a K3s worker to a control plane. Standalone format: "workerName,controlName". ' +
|
|
687
|
-
|
|
713
|
+
'When used with --init-vm --worker, provide just the control node name for auto-join.',
|
|
688
714
|
)
|
|
689
715
|
.option('--expose <vm-name:ports>', 'Proxy host ports to a VM (e.g., "k3s-control:80,443").')
|
|
690
716
|
.option('--delete-expose <vm-name:ports>', 'Remove proxied ports from a VM (e.g., "k3s-control:80,443").')
|
|
691
|
-
.option('--
|
|
692
|
-
.option('--vm-id <vm-name>', 'Target VM name for workflow execution.')
|
|
693
|
-
.option('--deploy-id <deploy-id>', 'Deployment ID context for workflow execution.')
|
|
717
|
+
.option('--bootstrap-engine <vm-name>', 'Replicate /home/dd/engine source into the VM after init completes.')
|
|
694
718
|
.option('--namespace <namespace>', 'Kubernetes namespace context (defaults to "default").')
|
|
695
719
|
.description('Manages LXD virtual machines as K3s nodes (control plane or workers).')
|
|
696
720
|
.action(Underpost.lxd.callback);
|
|
@@ -793,7 +817,7 @@ program
|
|
|
793
817
|
.option(
|
|
794
818
|
'--ci-push <deploy-id>',
|
|
795
819
|
'Local equivalent of engine-*.ci.yml: builds dd-{deploy-id} and pushes to the engine-{deploy-id} repository. ' +
|
|
796
|
-
|
|
820
|
+
'Accepts the suffix (e.g., "cyberia"), "dd-cyberia", or "engine-cyberia".',
|
|
797
821
|
)
|
|
798
822
|
.option(
|
|
799
823
|
'--message <message>',
|
|
@@ -803,6 +827,10 @@ program
|
|
|
803
827
|
'--pwa-build',
|
|
804
828
|
'Runs the pwa-microservices-template update flow: always re-clones, syncs engine sources, installs, builds, and pushes.',
|
|
805
829
|
)
|
|
830
|
+
.option(
|
|
831
|
+
'--dry-run',
|
|
832
|
+
'For --build: previews version-bump changes (per-file substitution counts) without writing files or running downstream commands.',
|
|
833
|
+
)
|
|
806
834
|
.description('Release orchestrator for building new versions and deploying releases of the Underpost CLI.')
|
|
807
835
|
.action(async (version, options) => {
|
|
808
836
|
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
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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}`);
|
package/src/cli/kubectl.js
CHANGED
|
@@ -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
|