underpost 3.2.30 → 3.2.80
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/ghpkg.ci.yml +87 -0
- package/.github/workflows/npmpkg.ci.yml +9 -6
- package/.github/workflows/publish.ci.yml +3 -3
- package/.github/workflows/pwa-microservices-template-page.cd.yml +0 -7
- package/.github/workflows/release.cd.yml +1 -1
- package/CHANGELOG.md +1230 -971
- package/CLI-HELP.md +14 -6
- package/README.md +3 -3
- package/bin/build.js +40 -4
- package/bin/deploy.js +2 -2
- package/bump.config.js +1 -0
- package/docker-compose.yml +26 -26
- 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-default-development/deployment.yaml +2 -2
- package/package.json +15 -15
- package/scripts/disk-clean.sh +85 -60
- package/scripts/test-monitor.sh +1 -1
- package/src/api/core/core.controller.js +4 -65
- package/src/api/core/core.router.js +8 -14
- package/src/api/default/default.controller.js +2 -70
- package/src/api/default/default.router.js +7 -17
- package/src/api/document/document.controller.js +5 -77
- package/src/api/document/document.router.js +9 -13
- package/src/api/file/file.controller.js +9 -53
- package/src/api/file/file.router.js +14 -6
- package/src/api/test/test.controller.js +8 -53
- package/src/api/test/test.router.js +1 -4
- package/src/cli/cluster.js +104 -11
- package/src/cli/db.js +4 -2
- package/src/cli/deploy.js +60 -11
- package/src/cli/docker-compose.js +212 -1
- package/src/cli/fs.js +45 -25
- package/src/cli/image.js +147 -51
- package/src/cli/index.js +26 -6
- package/src/cli/release.js +50 -4
- package/src/cli/repository.js +98 -24
- package/src/cli/run.js +380 -178
- package/src/cli/secrets.js +75 -46
- package/src/cli/ssh.js +30 -11
- package/src/client/components/core/Modal.js +38 -4
- package/src/index.js +1 -1
- package/src/server/catalog.js +2 -0
- package/src/server/conf.js +163 -3
- package/src/server/downloader.js +3 -3
- package/src/server/middlewares.js +152 -0
package/src/cli/run.js
CHANGED
|
@@ -14,7 +14,9 @@ import {
|
|
|
14
14
|
etcHostFactory,
|
|
15
15
|
getNpmRootPath,
|
|
16
16
|
isDeployRunnerContext,
|
|
17
|
+
loadConfInstances,
|
|
17
18
|
loadConfServerJson,
|
|
19
|
+
selectConfInstances,
|
|
18
20
|
loadReplicas,
|
|
19
21
|
writeEnv,
|
|
20
22
|
} from '../server/conf.js';
|
|
@@ -22,7 +24,7 @@ import { actionInitLog, loggerFactory } from '../server/logger.js';
|
|
|
22
24
|
|
|
23
25
|
import fs from 'fs-extra';
|
|
24
26
|
import net from 'net';
|
|
25
|
-
import { range, setPad, timer } from '../client/components/core/CommonJs.js';
|
|
27
|
+
import { range, s4, setPad, timer } from '../client/components/core/CommonJs.js';
|
|
26
28
|
|
|
27
29
|
import os from 'os';
|
|
28
30
|
import Underpost from '../index.js';
|
|
@@ -49,9 +51,36 @@ const waitForPort = (port, host = '127.0.0.1', { maxAttempts = 30, interval = 20
|
|
|
49
51
|
|
|
50
52
|
const logger = loggerFactory(import.meta);
|
|
51
53
|
|
|
54
|
+
/**
|
|
55
|
+
* @method instanceProxyRoutesFactory
|
|
56
|
+
* @description Renders the HTTPProxy route block for every instance sharing a host.
|
|
57
|
+
* Routes are emitted longest-prefix first so a specific instance path (`/FOREST`)
|
|
58
|
+
* is never shadowed by the default instance's catch-all (`/`).
|
|
59
|
+
* @param {string} deployId - Parent deployment identifier.
|
|
60
|
+
* @param {Array<object>} instances - Expanded instance entries bound to one host.
|
|
61
|
+
* @param {string} env - `development` | `production`.
|
|
62
|
+
* @param {Object<string,string>} trafficById - Instance id → traffic colour.
|
|
63
|
+
* @returns {string} Concatenated route YAML.
|
|
64
|
+
*/
|
|
65
|
+
const instanceProxyRoutesFactory = ({ deployId, instances, env, trafficById }) =>
|
|
66
|
+
[...instances]
|
|
67
|
+
.sort((a, b) => (b.path || '/').length - (a.path || '/').length)
|
|
68
|
+
.map((instance) =>
|
|
69
|
+
Underpost.deploy.deploymentYamlServiceFactory({
|
|
70
|
+
path: instance.path,
|
|
71
|
+
port: env === 'development' && instance.fromDebugPort ? instance.fromDebugPort : instance.fromPort,
|
|
72
|
+
deployId: `${deployId}-${instance.id}`,
|
|
73
|
+
env,
|
|
74
|
+
deploymentVersions: [trafficById[instance.id] || 'blue'],
|
|
75
|
+
pathRewritePolicy: instance.pathRewritePolicy,
|
|
76
|
+
}),
|
|
77
|
+
)
|
|
78
|
+
.join('');
|
|
79
|
+
|
|
52
80
|
/**
|
|
53
81
|
* @constant DEFAULT_OPTION
|
|
54
82
|
* @description Default options for the UnderpostRun class.
|
|
83
|
+
* @typedef {Object} UnderpostRunDefaultOptions
|
|
55
84
|
* @type {Object}
|
|
56
85
|
* @property {boolean} dev - Whether to run in development mode.
|
|
57
86
|
* @property {string} podName - The name of the pod to run.
|
|
@@ -122,6 +151,7 @@ const logger = loggerFactory(import.meta);
|
|
|
122
151
|
* @property {boolean} pullBundle - Whether to pull the bundle before running. Use together with --skip-full-build to skip the local build entirely (supported by: sync, template-deploy).
|
|
123
152
|
* @property {boolean} remove - Whether to remove/teardown resources instead of creating them (e.g. delete-expose for k3s proxy devices in dev-cluster).
|
|
124
153
|
* @property {boolean} test - Whether to enable test/generic-purpose mode (e.g. use self-signed TLS instead of cert-manager).
|
|
154
|
+
* @property {string} branch - The Git branch to use for operations (e.g., for template-deploy, ssh-deploy).
|
|
125
155
|
* @memberof UnderpostRun
|
|
126
156
|
*/
|
|
127
157
|
const DEFAULT_OPTION = {
|
|
@@ -192,6 +222,7 @@ const DEFAULT_OPTION = {
|
|
|
192
222
|
pullBundle: false,
|
|
193
223
|
remove: false,
|
|
194
224
|
test: false,
|
|
225
|
+
branch: '',
|
|
195
226
|
};
|
|
196
227
|
|
|
197
228
|
/**
|
|
@@ -215,7 +246,7 @@ class UnderpostRun {
|
|
|
215
246
|
* @method dev-cluster
|
|
216
247
|
* @description Resets and deploys a full development cluster including MongoDB, Valkey, exposes services, and updates `/etc/hosts` for local access.
|
|
217
248
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
218
|
-
* @param {
|
|
249
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
219
250
|
* @memberof UnderpostRun
|
|
220
251
|
*/
|
|
221
252
|
'dev-cluster': (path, options = DEFAULT_OPTION) => {
|
|
@@ -297,7 +328,7 @@ class UnderpostRun {
|
|
|
297
328
|
* @method metadata
|
|
298
329
|
* @description Generates metadata for the specified path after exposing the development cluster.
|
|
299
330
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
300
|
-
* @param {
|
|
331
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
301
332
|
* @memberof UnderpostRun
|
|
302
333
|
*/
|
|
303
334
|
metadata: async (path, options = DEFAULT_OPTION) => {
|
|
@@ -322,7 +353,7 @@ class UnderpostRun {
|
|
|
322
353
|
* @method svc-ls
|
|
323
354
|
* @description Lists systemd services and installed packages, optionally filtering by the provided path.
|
|
324
355
|
* @param {string} path - The input value, identifier, or path for the operation (used as the optional filter for services and packages).
|
|
325
|
-
* @param {
|
|
356
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
326
357
|
* @memberof UnderpostRun
|
|
327
358
|
*/
|
|
328
359
|
'svc-ls': (path, options = DEFAULT_OPTION) => {
|
|
@@ -342,7 +373,7 @@ class UnderpostRun {
|
|
|
342
373
|
* @method svc-rm
|
|
343
374
|
* @description Removes a systemd service by stopping it, disabling it, uninstalling the package, and deleting related files.
|
|
344
375
|
* @param {string} path - The input value, identifier, or path for the operation (used as the service name).
|
|
345
|
-
* @param {
|
|
376
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
346
377
|
* @memberof UnderpostRun
|
|
347
378
|
*/
|
|
348
379
|
'svc-rm': (path, options = DEFAULT_OPTION) => {
|
|
@@ -357,7 +388,7 @@ class UnderpostRun {
|
|
|
357
388
|
* @method ssh-deploy-info
|
|
358
389
|
* @description Retrieves deployment status and pod information from a remote server via SSH.
|
|
359
390
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
360
|
-
* @param {
|
|
391
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
361
392
|
* @memberof UnderpostRun
|
|
362
393
|
*/
|
|
363
394
|
'ssh-deploy-info': async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -401,7 +432,7 @@ class UnderpostRun {
|
|
|
401
432
|
* skipped (move the owning controller). StatefulSets bound to node-local PVs may stay
|
|
402
433
|
* Pending after a move until their volume is available on the target node.
|
|
403
434
|
* @param {string} path - Resource selector (`kind/name`, `kind`, or empty).
|
|
404
|
-
* @param {
|
|
435
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
405
436
|
* @memberof UnderpostRun
|
|
406
437
|
* @returns {Array<{ref:string,kind:string,status:string,node?:string}>} Per-resource outcome.
|
|
407
438
|
*/
|
|
@@ -601,7 +632,7 @@ class UnderpostRun {
|
|
|
601
632
|
* @method dev-hosts-expose
|
|
602
633
|
* @description Deploys a specified service in development mode with `/etc/hosts` modification for local access.
|
|
603
634
|
* @param {string} path - The input value, identifier, or path for the operation (used as the deployment ID to deploy).
|
|
604
|
-
* @param {
|
|
635
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
605
636
|
* @memberof UnderpostRun
|
|
606
637
|
*/
|
|
607
638
|
'dev-hosts-expose': (path, options = DEFAULT_OPTION) => {
|
|
@@ -614,7 +645,7 @@ class UnderpostRun {
|
|
|
614
645
|
* @method dev-hosts-restore
|
|
615
646
|
* @description Restores the `/etc/hosts` file to its original state after modifications made during development deployments.
|
|
616
647
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
617
|
-
* @param {
|
|
648
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
618
649
|
* @memberof UnderpostRun
|
|
619
650
|
*/
|
|
620
651
|
'dev-hosts-restore': (path, options = DEFAULT_OPTION) => {
|
|
@@ -625,7 +656,7 @@ class UnderpostRun {
|
|
|
625
656
|
* @method cluster-build
|
|
626
657
|
* @description Build configuration for cluster deployment.
|
|
627
658
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
628
|
-
* @param {
|
|
659
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
629
660
|
* @memberof UnderpostRun
|
|
630
661
|
*/
|
|
631
662
|
'cluster-build': (path, options = DEFAULT_OPTION) => {
|
|
@@ -649,7 +680,7 @@ class UnderpostRun {
|
|
|
649
680
|
* and optionally triggers engine-<conf-id> CI with sync/init which in turn dispatches the CD workflow
|
|
650
681
|
* after the build chain completes (template → ghpkg → engine-<conf-id> → CD).
|
|
651
682
|
* @param {string} path - The deployment path identifier (e.g., 'sync-engine-core', 'init-engine-core', or empty for build-only).
|
|
652
|
-
* @param {
|
|
683
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
653
684
|
* @memberof UnderpostRun
|
|
654
685
|
*/
|
|
655
686
|
'template-deploy': (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -663,13 +694,10 @@ class UnderpostRun {
|
|
|
663
694
|
shellExec(`${baseCommand} run pull`);
|
|
664
695
|
shellExec(`${baseCommand} run shared-dir`);
|
|
665
696
|
|
|
666
|
-
// Capture last N commit
|
|
667
|
-
//
|
|
668
|
-
const fromN =
|
|
669
|
-
|
|
670
|
-
? parseInt(options.fromNCommit)
|
|
671
|
-
: Underpost.repo.getUnpushedCount('.').count;
|
|
672
|
-
const message = shellExec(`node bin cmt --changelog ${fromN} --changelog-no-hash`, {
|
|
697
|
+
// Capture the sanitized message from the last N commits (--from-n-commit, default 1) for
|
|
698
|
+
// propagation to pwa-microservices-template and every engine-* repo.
|
|
699
|
+
const fromN = parseInt(options.fromNCommit) > 0 ? parseInt(options.fromNCommit) : 1;
|
|
700
|
+
const sanitizedMessage = shellExec(`node bin cmt --changelog-msg --from-n-commit ${fromN} --changelog-no-hash`, {
|
|
673
701
|
silent: true,
|
|
674
702
|
stdout: true,
|
|
675
703
|
}).trim();
|
|
@@ -681,8 +709,6 @@ class UnderpostRun {
|
|
|
681
709
|
);
|
|
682
710
|
shellCd('/home/dd/engine');
|
|
683
711
|
|
|
684
|
-
const sanitizedMessage = Underpost.repo.sanitizeChangelogMessage(message);
|
|
685
|
-
|
|
686
712
|
// Push engine repo so workflow YAML changes reach GitHub
|
|
687
713
|
shellExec(`git reset`);
|
|
688
714
|
shellExec(`${baseCommand} push . ${options.force ? '-f ' : ''}${process.env.GITHUB_USERNAME}/engine`);
|
|
@@ -718,10 +744,11 @@ class UnderpostRun {
|
|
|
718
744
|
if (deployConfId) inputs.deploy_conf_id = deployConfId;
|
|
719
745
|
if (deployType) inputs.deploy_type = deployType;
|
|
720
746
|
|
|
747
|
+
// Omit `ref` so dispatchWorkflow auto-detects the repo's default branch
|
|
748
|
+
// (a fork may default to `main` rather than the monorepo's `master`).
|
|
721
749
|
Underpost.repo.dispatchWorkflow({
|
|
722
750
|
repo,
|
|
723
751
|
workflowFile: 'npmpkg.ci.yml',
|
|
724
|
-
ref: 'master',
|
|
725
752
|
inputs,
|
|
726
753
|
});
|
|
727
754
|
},
|
|
@@ -730,7 +757,7 @@ class UnderpostRun {
|
|
|
730
757
|
* @method template-deploy-local
|
|
731
758
|
* @description Similar to `template-deploy` but runs the workflow locally without dispatching GitHub Actions. It pulls the latest changes, pushes to GitHub, builds the template, and optionally triggers a local release with CI push.
|
|
732
759
|
* @param {string} path - The deployment path identifier (e.g., 'sync-engine-core', 'init-engine-core', or empty for build-only).
|
|
733
|
-
* @param {
|
|
760
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
734
761
|
* @memberof UnderpostRun
|
|
735
762
|
*/
|
|
736
763
|
'template-deploy-local': async (path, options = DEFAULT_OPTION) => {
|
|
@@ -744,17 +771,12 @@ class UnderpostRun {
|
|
|
744
771
|
shellExec(`${baseCommand} run pull`);
|
|
745
772
|
shellExec(`${baseCommand} run shared-dir`);
|
|
746
773
|
|
|
747
|
-
// Capture last N
|
|
748
|
-
|
|
749
|
-
const fromN
|
|
750
|
-
options.fromNCommit && parseInt(options.fromNCommit) > 0
|
|
751
|
-
? parseInt(options.fromNCommit)
|
|
752
|
-
: Underpost.repo.getUnpushedCount('.').count;
|
|
753
|
-
const rawMessage = shellExec(`node bin cmt --changelog ${fromN} --changelog-no-hash`, {
|
|
774
|
+
// Capture the sanitized message from the last N commits (--from-n-commit, default 1).
|
|
775
|
+
const fromN = parseInt(options.fromNCommit) > 0 ? parseInt(options.fromNCommit) : 1;
|
|
776
|
+
const sanitizedMessage = shellExec(`node bin cmt --changelog-msg --from-n-commit ${fromN} --changelog-no-hash`, {
|
|
754
777
|
silent: true,
|
|
755
778
|
stdout: true,
|
|
756
779
|
}).trim();
|
|
757
|
-
const sanitizedMessage = Underpost.repo.sanitizeChangelogMessage(rawMessage);
|
|
758
780
|
|
|
759
781
|
const { triggerCmd } = path
|
|
760
782
|
? await Underpost.release.ci(path, sanitizedMessage, options)
|
|
@@ -766,15 +788,14 @@ class UnderpostRun {
|
|
|
766
788
|
* @description Dispatches the Docker image CI workflow (`docker-image[.<runtime>].ci.yml`) via `workflow_dispatch`.
|
|
767
789
|
* Repository resolution is delegated to `Underpost.repo.resolveInstanceRepo(path)`.
|
|
768
790
|
* @param {string} path - Optional runtime / workflow suffix (e.g. `cyberia-server`, `cyberia-client`).
|
|
769
|
-
* @param {
|
|
791
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
770
792
|
* @memberof UnderpostRun
|
|
771
793
|
*/
|
|
772
794
|
'docker-image': (path, options = DEFAULT_OPTION) => {
|
|
773
|
-
const repo = Underpost.repo.resolveInstanceRepo(path);
|
|
795
|
+
const repo = Underpost.repo.resolveInstanceRepo(path, !options.test);
|
|
774
796
|
Underpost.repo.dispatchWorkflow({
|
|
775
797
|
repo,
|
|
776
|
-
workflowFile: `docker-image${path ? `.${path}` : ''}.ci.yml`,
|
|
777
|
-
ref: 'master',
|
|
798
|
+
workflowFile: `docker-image${path ? `.${path}` : ''}${options.dev ? '.dev' : ''}.ci.yml`,
|
|
778
799
|
inputs: {},
|
|
779
800
|
});
|
|
780
801
|
},
|
|
@@ -782,7 +803,7 @@ class UnderpostRun {
|
|
|
782
803
|
* @method clean
|
|
783
804
|
* @description Changes directory to the provided path (defaulting to `/home/dd/engine`) and runs `node bin/deploy clean-core-repo`.
|
|
784
805
|
* @param {string} path - The input value, identifier, or path for the operation (used as the optional directory path).
|
|
785
|
-
* @param {
|
|
806
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
786
807
|
* @memberof UnderpostRun
|
|
787
808
|
*/
|
|
788
809
|
clean: (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -793,7 +814,7 @@ class UnderpostRun {
|
|
|
793
814
|
* @method pull
|
|
794
815
|
* @description Clones or pulls updates for the `engine` and `engine-private` repositories into `/home/dd/engine` and `/home/dd/engine/engine-private`.
|
|
795
816
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
796
|
-
* @param {
|
|
817
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
797
818
|
* @memberof UnderpostRun
|
|
798
819
|
*/
|
|
799
820
|
pull: (path, options = DEFAULT_OPTION) => {
|
|
@@ -820,7 +841,7 @@ class UnderpostRun {
|
|
|
820
841
|
* @method release-deploy
|
|
821
842
|
* @description Executes deployment (`underpost run deploy`) for all deployment IDs listed in `./engine-private/deploy/dd.router`.
|
|
822
843
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
823
|
-
* @param {
|
|
844
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
824
845
|
* @memberof UnderpostRun
|
|
825
846
|
*/
|
|
826
847
|
'release-deploy': (path, options = DEFAULT_OPTION) => {
|
|
@@ -836,7 +857,7 @@ class UnderpostRun {
|
|
|
836
857
|
* @method ssh-deploy
|
|
837
858
|
* @description Dispatches the corresponding CD workflow for SSH-based deployment, replacing empty commits with workflow_dispatch.
|
|
838
859
|
* @param {string} path - The deployment identifier (e.g., 'engine-core', 'sync-engine-core', 'init-engine-core').
|
|
839
|
-
* @param {
|
|
860
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
840
861
|
* @memberof UnderpostRun
|
|
841
862
|
*/
|
|
842
863
|
'ssh-deploy': (path, options = DEFAULT_OPTION) => {
|
|
@@ -851,11 +872,13 @@ class UnderpostRun {
|
|
|
851
872
|
job = 'init';
|
|
852
873
|
confId = path.replace(/^init-/, '');
|
|
853
874
|
}
|
|
854
|
-
|
|
875
|
+
const repo = Underpost.repo.resolveInstanceRepo(confId, !options.test);
|
|
876
|
+
// Omit `ref` so dispatchWorkflow auto-detects the target repo's default
|
|
877
|
+
// branch (getDefaultBranch): the monorepo is `master` but instance repos
|
|
878
|
+
// like engine-cyberia default to `main` — hardcoding either 422s.
|
|
855
879
|
Underpost.repo.dispatchWorkflow({
|
|
856
|
-
repo
|
|
880
|
+
repo,
|
|
857
881
|
workflowFile: `${confId}.cd.yml`,
|
|
858
|
-
ref: 'master',
|
|
859
882
|
inputs: { job },
|
|
860
883
|
});
|
|
861
884
|
},
|
|
@@ -864,7 +887,7 @@ class UnderpostRun {
|
|
|
864
887
|
* @description Opens a Visual Studio Code (VS Code) session for the specified path using `node ${underpostRoot}/bin/zed ${path}`,
|
|
865
888
|
* or installs Zed and sublime-text IDE if `path` is 'install'.
|
|
866
889
|
* @param {string} path - The input value, identifier, or path for the operation (used as the path to the directory to open in the IDE).
|
|
867
|
-
* @param {
|
|
890
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
868
891
|
* @memberof UnderpostRun
|
|
869
892
|
*/
|
|
870
893
|
ide: (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -891,7 +914,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
891
914
|
* @method crypto-policy
|
|
892
915
|
* @description Sets the system's crypto policies to `DEFAULT:SHA1` using `update-crypto-policies` command.
|
|
893
916
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
894
|
-
* @param {
|
|
917
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
895
918
|
* @memberof UnderpostRun
|
|
896
919
|
*/
|
|
897
920
|
'crypto-policy': (path, options = DEFAULT_OPTION) => {
|
|
@@ -906,7 +929,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
906
929
|
* `deployment.yaml`. Useful when you want to force `Always` so the kubelet re-pulls a mutable tag on every rollout. Example:
|
|
907
930
|
* `node bin run sync dd-core --kubeadm --image-pull-policy Always`
|
|
908
931
|
* @param {string} path - The input value, identifier, or path for the operation (used as a comma-separated string containing deploy parameters).
|
|
909
|
-
* @param {
|
|
932
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
910
933
|
* @memberof UnderpostRun
|
|
911
934
|
*/
|
|
912
935
|
sync: async (path, options = DEFAULT_OPTION) => {
|
|
@@ -1000,7 +1023,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
1000
1023
|
* @method stop
|
|
1001
1024
|
* @description Stops a deployment by deleting the corresponding Kubernetes deployment and service resources.
|
|
1002
1025
|
* @param {string} path - The input value, identifier, or path for the operation (used to determine which traffic to stop).
|
|
1003
|
-
* @param {
|
|
1026
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1004
1027
|
* @memberof UnderpostRun
|
|
1005
1028
|
*/
|
|
1006
1029
|
stop: async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -1024,7 +1047,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
1024
1047
|
* @method ssh-deploy-stop
|
|
1025
1048
|
* @description Stops a remote deployment via SSH by executing the appropriate Underpost command on the remote server.
|
|
1026
1049
|
* @param {string} path - The input value, identifier, or path for the operation (used to determine which traffic to stop).
|
|
1027
|
-
* @param {
|
|
1050
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1028
1051
|
* @memberof UnderpostRun
|
|
1029
1052
|
*/
|
|
1030
1053
|
'ssh-deploy-stop': async (path, options = DEFAULT_OPTION) => {
|
|
@@ -1051,7 +1074,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
1051
1074
|
* @method ssh-deploy-db-rollback
|
|
1052
1075
|
* @description Performs a database rollback on remote deployment via SSH.
|
|
1053
1076
|
* @param {string} path - Comma-separated deployId and optional number of commits to reset (format: "deployId,nCommits")
|
|
1054
|
-
* @param {
|
|
1077
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1055
1078
|
* @param {string} options.deployId - The deployment identifier
|
|
1056
1079
|
* @param {string} options.user - The SSH user for credential lookup
|
|
1057
1080
|
* @param {boolean} options.dev - Development mode flag
|
|
@@ -1078,7 +1101,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
1078
1101
|
* @method ssh-deploy-db
|
|
1079
1102
|
* @description Imports/restores a database on remote deployment via SSH.
|
|
1080
1103
|
* @param {string} path - The deployment ID for database import
|
|
1081
|
-
* @param {
|
|
1104
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1082
1105
|
* @param {string} options.deployId - The deployment identifier
|
|
1083
1106
|
* @param {string} options.user - The SSH user for credential lookup
|
|
1084
1107
|
* @param {boolean} options.dev - Development mode flag
|
|
@@ -1103,7 +1126,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
1103
1126
|
* @method ssh-deploy-db-status
|
|
1104
1127
|
* @description Retrieves database status/stats for a deployment (or all deployments from dd.router) via SSH.
|
|
1105
1128
|
* @param {string} path - Comma-separated deployId(s) or 'dd' to use the dd.router list.
|
|
1106
|
-
* @param {
|
|
1129
|
+
* @param {UnderpostRunDefaultOptions} options - Runner options (uses options.deployId for SSH host lookup).
|
|
1107
1130
|
* @param {string} options.deployId - Deployment identifier used for SSH config lookup.
|
|
1108
1131
|
* @param {string} options.user - SSH user for credential lookup.
|
|
1109
1132
|
* @param {boolean} options.dev - Development mode flag.
|
|
@@ -1149,7 +1172,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
1149
1172
|
* @method tz
|
|
1150
1173
|
* @description Sets the system timezone using `timedatectl set-timezone` command.
|
|
1151
1174
|
* @param {string} path - The input value, identifier, or path for the operation (used as the timezone string).
|
|
1152
|
-
* @param {
|
|
1175
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1153
1176
|
* @memberof UnderpostRun
|
|
1154
1177
|
*/
|
|
1155
1178
|
tz: (path, options = DEFAULT_OPTION) => {
|
|
@@ -1170,7 +1193,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
1170
1193
|
* @method get-proxy
|
|
1171
1194
|
* @description Retrieves and logs the HTTPProxy resources in the specified namespace using `kubectl get HTTPProxy`.
|
|
1172
1195
|
* @param {string} path - The input value, identifier, or path for the operation (used as an optional filter for the HTTPProxy resources).
|
|
1173
|
-
* @param {
|
|
1196
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1174
1197
|
* @memberof UnderpostRun
|
|
1175
1198
|
*/
|
|
1176
1199
|
'get-proxy': async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -1192,66 +1215,54 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
1192
1215
|
|
|
1193
1216
|
'instance-promote': async (path, options = DEFAULT_OPTION) => {
|
|
1194
1217
|
const env = options.dev ? 'development' : 'production';
|
|
1195
|
-
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
1196
|
-
const baseClusterCommand = options.dev ? ' --dev' : '';
|
|
1197
1218
|
let [deployId, id] = path.split(',');
|
|
1198
|
-
const confInstances =
|
|
1199
|
-
|
|
1200
|
-
);
|
|
1219
|
+
const confInstances = loadConfInstances(deployId);
|
|
1220
|
+
const promoted = selectConfInstances(confInstances, id);
|
|
1201
1221
|
let promotedTraffic = '';
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
metadata: _metadata,
|
|
1215
|
-
} = instance;
|
|
1216
|
-
if (id !== _id) continue;
|
|
1217
|
-
const _deployId = `${deployId}-${_id}`;
|
|
1218
|
-
// Use debug ports in development when defined, fall back to production ports.
|
|
1219
|
-
if (env === 'development' && _fromDebugPort) _fromPort = _fromDebugPort;
|
|
1220
|
-
if (env === 'development' && _toDebugPort) _toPort = _toDebugPort;
|
|
1221
|
-
const currentTraffic = Underpost.deploy.getCurrentTraffic(_deployId, {
|
|
1222
|
-
hostTest: _host,
|
|
1222
|
+
|
|
1223
|
+
// A Contour HTTPProxy is named after its host, so every instance sharing a
|
|
1224
|
+
// host shares one object. Rebuilding it from the promoted instance alone
|
|
1225
|
+
// would drop its siblings' routes, so each host is rendered from the full
|
|
1226
|
+
// set: promoted instances flip colour, the rest keep their live colour.
|
|
1227
|
+
const promotedIds = new Set(promoted.map((instance) => instance.id));
|
|
1228
|
+
const hosts = [...new Set(promoted.map((instance) => instance.host))];
|
|
1229
|
+
const affected = confInstances.filter((instance) => hosts.includes(instance.host));
|
|
1230
|
+
const trafficById = {};
|
|
1231
|
+
for (const instance of affected) {
|
|
1232
|
+
const currentTraffic = Underpost.deploy.getCurrentTraffic(`${deployId}-${instance.id}`, {
|
|
1233
|
+
hostTest: instance.host,
|
|
1223
1234
|
namespace: options.namespace,
|
|
1235
|
+
env,
|
|
1224
1236
|
});
|
|
1225
|
-
|
|
1226
|
-
|
|
1237
|
+
if (!promotedIds.has(instance.id)) {
|
|
1238
|
+
trafficById[instance.id] = currentTraffic || 'blue';
|
|
1239
|
+
continue;
|
|
1240
|
+
}
|
|
1241
|
+
trafficById[instance.id] = currentTraffic ? (currentTraffic === 'blue' ? 'green' : 'blue') : 'blue';
|
|
1242
|
+
promotedTraffic = trafficById[instance.id];
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
for (const host of hosts) {
|
|
1246
|
+
const hostInstances = affected.filter((instance) => instance.host === host);
|
|
1227
1247
|
let proxyYaml =
|
|
1228
|
-
Underpost.deploy.baseProxyYamlFactory({ host
|
|
1229
|
-
|
|
1230
|
-
path: _path,
|
|
1231
|
-
port: _fromPort,
|
|
1232
|
-
// serviceId: deployId,
|
|
1233
|
-
deployId: _deployId,
|
|
1234
|
-
env,
|
|
1235
|
-
deploymentVersions: [targetTraffic],
|
|
1236
|
-
// pathRewritePolicy,
|
|
1237
|
-
});
|
|
1248
|
+
Underpost.deploy.baseProxyYamlFactory({ host, env: options.tls ? 'production' : env, options }) +
|
|
1249
|
+
instanceProxyRoutesFactory({ deployId, instances: hostInstances, env, trafficById });
|
|
1238
1250
|
if (options.tls) {
|
|
1239
1251
|
if (options.test) {
|
|
1240
|
-
const sslDir = `./engine-private/ssl/${
|
|
1241
|
-
const nameSafe =
|
|
1252
|
+
const sslDir = `./engine-private/ssl/${host}`;
|
|
1253
|
+
const nameSafe = host.replace(/[^a-zA-Z0-9_.-]/g, '_');
|
|
1242
1254
|
fs.mkdirpSync(sslDir);
|
|
1243
|
-
shellExec(`bash ./scripts/ssl.sh "${sslDir}" "${
|
|
1244
|
-
shellExec(`kubectl delete secret ${
|
|
1255
|
+
shellExec(`bash ./scripts/ssl.sh "${sslDir}" "${host}"`);
|
|
1256
|
+
shellExec(`kubectl delete secret ${host} -n ${options.namespace} --ignore-not-found`);
|
|
1245
1257
|
shellExec(
|
|
1246
|
-
`kubectl create secret tls ${
|
|
1258
|
+
`kubectl create secret tls ${host} --cert="${sslDir}/${nameSafe}.pem" --key="${sslDir}/${nameSafe}-key.pem" -n ${options.namespace}`,
|
|
1247
1259
|
);
|
|
1248
1260
|
} else {
|
|
1249
|
-
shellExec(`sudo kubectl delete Certificate ${
|
|
1250
|
-
proxyYaml += Underpost.deploy.buildCertManagerCertificate({ ...options, host
|
|
1261
|
+
shellExec(`sudo kubectl delete Certificate ${host} -n ${options.namespace} --ignore-not-found`);
|
|
1262
|
+
proxyYaml += Underpost.deploy.buildCertManagerCertificate({ ...options, host });
|
|
1251
1263
|
}
|
|
1252
1264
|
}
|
|
1253
|
-
|
|
1254
|
-
shellExec(`kubectl delete HTTPProxy ${_host} --namespace ${options.namespace} --ignore-not-found`);
|
|
1265
|
+
shellExec(`kubectl delete HTTPProxy ${host} --namespace ${options.namespace} --ignore-not-found`);
|
|
1255
1266
|
shellExec(
|
|
1256
1267
|
`kubectl apply -f - -n ${options.namespace} <<EOF
|
|
1257
1268
|
${proxyYaml}
|
|
@@ -1277,7 +1288,7 @@ EOF
|
|
|
1277
1288
|
/**
|
|
1278
1289
|
* @method instance
|
|
1279
1290
|
* @param {string} path - The input value, identifier, or path for the operation (used as a comma-separated string containing workflow parameters).
|
|
1280
|
-
* @param {
|
|
1291
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1281
1292
|
* @memberof UnderpostRun
|
|
1282
1293
|
*/
|
|
1283
1294
|
instance: async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -1286,9 +1297,7 @@ EOF
|
|
|
1286
1297
|
const baseClusterCommand = options.dev ? ' --dev' : '';
|
|
1287
1298
|
let [deployId, id, replicas] = path.split(',');
|
|
1288
1299
|
if (!replicas) replicas = options.replicas;
|
|
1289
|
-
const confInstances =
|
|
1290
|
-
fs.readFileSync(`./engine-private/conf/${deployId}/conf.instances.json`, 'utf8'),
|
|
1291
|
-
);
|
|
1300
|
+
const confInstances = selectConfInstances(loadConfInstances(deployId), id);
|
|
1292
1301
|
const etcHosts = [];
|
|
1293
1302
|
for (const instance of confInstances) {
|
|
1294
1303
|
let {
|
|
@@ -1307,7 +1316,6 @@ EOF
|
|
|
1307
1316
|
readinessProbe: _readinessProbe,
|
|
1308
1317
|
livenessProbe: _livenessProbe,
|
|
1309
1318
|
} = instance;
|
|
1310
|
-
if (id !== _id) continue;
|
|
1311
1319
|
const _deployId = `${deployId}-${_id}`;
|
|
1312
1320
|
// Use debug ports in development when defined, fall back to production ports.
|
|
1313
1321
|
if (env === 'development' && _fromDebugPort) _fromPort = _fromDebugPort;
|
|
@@ -1331,6 +1339,7 @@ EOF
|
|
|
1331
1339
|
const currentTraffic = Underpost.deploy.getCurrentTraffic(_deployId, {
|
|
1332
1340
|
hostTest: _host,
|
|
1333
1341
|
namespace: options.namespace,
|
|
1342
|
+
env,
|
|
1334
1343
|
});
|
|
1335
1344
|
|
|
1336
1345
|
const targetTraffic = currentTraffic ? (currentTraffic === 'blue' ? 'green' : 'blue') : 'blue';
|
|
@@ -1436,25 +1445,54 @@ EOF
|
|
|
1436
1445
|
logger.error(`Deployment ${deployId} did not become ready in time.`);
|
|
1437
1446
|
return;
|
|
1438
1447
|
}
|
|
1439
|
-
shellExec(
|
|
1440
|
-
`${baseCommand} run${baseClusterCommand} --namespace ${options.namespace}` +
|
|
1441
|
-
`${options.nodeName ? ` --node-name ${options.nodeName}` : ''}` +
|
|
1442
|
-
`${options.tls ? ` --tls ${options.test ? '--test' : ''}` : ''}` +
|
|
1443
|
-
` instance-promote '${path}'`,
|
|
1444
|
-
);
|
|
1445
1448
|
}
|
|
1449
|
+
// Promote (switch the HTTPProxy to the new colour) ONLY after EVERY
|
|
1450
|
+
// instance in the family is deployed and ready — never per-instance inside
|
|
1451
|
+
// the loop. A per-variant switch would flip server.cyberiaonline.com to the
|
|
1452
|
+
// default's new deployment while -forest/-test are still being created,
|
|
1453
|
+
// pointing routes at services that don't exist yet. instance-promote
|
|
1454
|
+
// rebuilds the whole host proxy (all variant routes) in one shot, so a
|
|
1455
|
+
// single call with the family id promotes the family atomically.
|
|
1456
|
+
if (!options.expose) await UnderpostRun.RUNNERS['instance-promote'](`${deployId},${id}`, options);
|
|
1446
1457
|
if (options.etcHosts) {
|
|
1447
1458
|
const hostListenResult = etcHostFactory(etcHosts);
|
|
1448
1459
|
logger.info(hostListenResult.renderHosts);
|
|
1449
1460
|
}
|
|
1450
1461
|
},
|
|
1451
1462
|
|
|
1463
|
+
/**
|
|
1464
|
+
* @method deploy-key
|
|
1465
|
+
* @description Copies the deploy key for a specific user and deployId to a temporary location on the local machine.
|
|
1466
|
+
* @param {string} path - The input value, identifier, or path for the operation (not used in this method).
|
|
1467
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1468
|
+
* @param {string} options.user - The user for which to copy the deploy key.
|
|
1469
|
+
* @param {string} options.deployId - The deployment identifier associated with the deploy key.
|
|
1470
|
+
* @memberof UnderpostRun
|
|
1471
|
+
*/
|
|
1472
|
+
'deploy-key': (path, options = DEFAULT_OPTION) => {
|
|
1473
|
+
const prefix = 'dd-key';
|
|
1474
|
+
if (options.reset) {
|
|
1475
|
+
shellExec(`rm -rf /home/dd/tmp/${prefix}_*`);
|
|
1476
|
+
return;
|
|
1477
|
+
}
|
|
1478
|
+
if (!options.user || !options.deployId) {
|
|
1479
|
+
logger.error('Both --user and --deploy-id options are required to copy the deploy key.');
|
|
1480
|
+
return;
|
|
1481
|
+
}
|
|
1482
|
+
const targetPath = `/home/dd/tmp/${prefix}_${s4()}${s4()}`;
|
|
1483
|
+
fs.mkdirSync('/home/dd/tmp', { recursive: true });
|
|
1484
|
+
fs.copyFileSync(`./engine-private/conf/${options.deployId}/users/${options.user}/id_rsa`, targetPath);
|
|
1485
|
+
logger.info(`Copied deploy key to ${targetPath}`);
|
|
1486
|
+
if (options.copy) pbcopy(targetPath);
|
|
1487
|
+
},
|
|
1488
|
+
|
|
1452
1489
|
/**
|
|
1453
1490
|
* @method instance-build-manifest
|
|
1454
1491
|
* @description Builds a Kubernetes Deployment + Service manifest for a specific instance entry
|
|
1455
|
-
* from `conf.instances.json` and writes it to a file.
|
|
1456
|
-
*
|
|
1457
|
-
*
|
|
1492
|
+
* from `conf.instances.json` and writes it to a file. This is a purely local
|
|
1493
|
+
* artifact generator: it never probes a live cluster. Traffic colour defaults
|
|
1494
|
+
* to the canonical initial `blue` and can be overridden with `--traffic`; the
|
|
1495
|
+
* real blue/green swap is resolved at deploy time (`deploy --sync`).
|
|
1458
1496
|
*
|
|
1459
1497
|
* If `--build` is supplied the image is built from the project Dockerfile and loaded into the
|
|
1460
1498
|
* cluster before the manifest is written (kind by default; `--kubeadm` / `--k3s` override).
|
|
@@ -1465,33 +1503,49 @@ EOF
|
|
|
1465
1503
|
* `<projectPath>/manifests/<env>/deployment.yaml`.
|
|
1466
1504
|
* In production, files are also copied to `<projectPath>/Dockerfile` and
|
|
1467
1505
|
* `<projectPath>/deployment.yaml`.
|
|
1468
|
-
* @param {
|
|
1506
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1469
1507
|
* @memberof UnderpostRun
|
|
1470
1508
|
*/
|
|
1471
1509
|
'instance-build-manifest': (path, options = DEFAULT_OPTION) => {
|
|
1472
1510
|
const env = options.dev ? 'development' : 'production';
|
|
1473
1511
|
let [deployId, id, projectPath] = path.split(',');
|
|
1474
1512
|
const rootPath = projectPath ? projectPath : '.';
|
|
1513
|
+
|
|
1514
|
+
const confInstances = loadConfInstances(deployId);
|
|
1515
|
+
// Targeting a template id builds every world in the family. The fan-out
|
|
1516
|
+
// re-enters this runner with `instanceOnly` because the default world
|
|
1517
|
+
// keeps the template id verbatim — without it, selecting `mmo-server`
|
|
1518
|
+
// would match the family again and recurse forever. Only that default
|
|
1519
|
+
// world publishes to the project root, so the repo keeps exactly one
|
|
1520
|
+
// canonical Dockerfile/deployment.yaml pair.
|
|
1521
|
+
const selected = options.instanceOnly
|
|
1522
|
+
? confInstances.filter((instance) => instance.id === id)
|
|
1523
|
+
: selectConfInstances(confInstances, id);
|
|
1524
|
+
if (selected.length === 0) {
|
|
1525
|
+
logger.error(`Instance with id '${id}' not found in conf.instances.json for deployId '${deployId}'`);
|
|
1526
|
+
return;
|
|
1527
|
+
}
|
|
1528
|
+
if (!options.instanceOnly && (selected.length > 1 || selected[0].id !== id)) {
|
|
1529
|
+
for (const instance of selected)
|
|
1530
|
+
UnderpostRun.RUNNERS['instance-build-manifest'](
|
|
1531
|
+
[deployId, instance.id, projectPath].filter((v) => v !== undefined).join(','),
|
|
1532
|
+
{ ...options, instanceOnly: true },
|
|
1533
|
+
);
|
|
1534
|
+
return;
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1475
1537
|
const envManifestPath = `${rootPath}/manifests/deployments/${id}-${env}`;
|
|
1476
1538
|
const outputPath = `${envManifestPath}/deployment.yaml`;
|
|
1477
1539
|
const dockerfileManifestPath = `${envManifestPath}/Dockerfile`;
|
|
1478
1540
|
|
|
1479
1541
|
fs.mkdirpSync(envManifestPath);
|
|
1480
1542
|
|
|
1481
|
-
const
|
|
1482
|
-
|
|
1483
|
-
);
|
|
1484
|
-
|
|
1485
|
-
const instance = confInstances.find((i) => i.id === id);
|
|
1486
|
-
if (!instance) {
|
|
1487
|
-
logger.error(`Instance with id '${id}' not found in conf.instances.json for deployId '${deployId}'`);
|
|
1488
|
-
return;
|
|
1489
|
-
}
|
|
1543
|
+
const instance = selected[0];
|
|
1544
|
+
const isDefaultInstance = instance.id === instance.templateId || !instance.templateId;
|
|
1490
1545
|
|
|
1491
1546
|
let {
|
|
1492
1547
|
id: _id,
|
|
1493
1548
|
host: _host,
|
|
1494
|
-
path: _path,
|
|
1495
1549
|
image: _image,
|
|
1496
1550
|
fromPort: _fromPort,
|
|
1497
1551
|
toPort: _toPort,
|
|
@@ -1544,7 +1598,7 @@ EOF
|
|
|
1544
1598
|
path: projectPath,
|
|
1545
1599
|
imageName: _image,
|
|
1546
1600
|
podmanSave: true,
|
|
1547
|
-
|
|
1601
|
+
imageOutPath: projectPath,
|
|
1548
1602
|
kind: isKind,
|
|
1549
1603
|
kubeadm: !!options.kubeadm,
|
|
1550
1604
|
k3s: !!options.k3s,
|
|
@@ -1557,15 +1611,8 @@ EOF
|
|
|
1557
1611
|
});
|
|
1558
1612
|
}
|
|
1559
1613
|
|
|
1560
|
-
|
|
1561
|
-
const
|
|
1562
|
-
hostTest: _host,
|
|
1563
|
-
namespace: options.namespace,
|
|
1564
|
-
});
|
|
1565
|
-
const targetTraffic = currentTraffic ? (currentTraffic === 'blue' ? 'green' : 'blue') : 'blue';
|
|
1566
|
-
|
|
1567
|
-
// Resolve {{grpc-service-dns}} using the parent deploy's current (or default) traffic.
|
|
1568
|
-
const parentTraffic = Underpost.deploy.getCurrentTraffic(deployId, { namespace: options.namespace }) || 'blue';
|
|
1614
|
+
const targetTraffic = options.traffic || 'blue';
|
|
1615
|
+
const parentTraffic = targetTraffic;
|
|
1569
1616
|
const resolvedCmd = _cmd[env].map((c) =>
|
|
1570
1617
|
c.replaceAll(
|
|
1571
1618
|
'{{grpc-service-dns}}',
|
|
@@ -1613,11 +1660,122 @@ EOF
|
|
|
1613
1660
|
image: _image,
|
|
1614
1661
|
});
|
|
1615
1662
|
|
|
1616
|
-
|
|
1663
|
+
// --- Sibling manifests (pv-pvc, proxy, grpc-service) ------------------
|
|
1664
|
+
// Emit the same apply-able set the parent deploy writes to build/<env>,
|
|
1665
|
+
// scoped to this instance so the project repo and engine-private ship
|
|
1666
|
+
// more than just deployment.yaml. Content matches what `run instance`
|
|
1667
|
+
// creates dynamically at deploy time (deployVolume / instance-promote /
|
|
1668
|
+
// the parent gRPC ClusterIP), so a static `kubectl apply` is equivalent.
|
|
1669
|
+
const pvDataNode = Underpost.deploy.resolveDeployNode({
|
|
1670
|
+
node: options.nodeName,
|
|
1671
|
+
kind: options.kind,
|
|
1672
|
+
kubeadm: options.kubeadm,
|
|
1673
|
+
k3s: options.k3s,
|
|
1674
|
+
env,
|
|
1675
|
+
});
|
|
1676
|
+
|
|
1677
|
+
// pv-pvc.yaml — one PV+PVC per instance volume; names mirror deployVolume.
|
|
1678
|
+
let pvPvcYaml = '';
|
|
1679
|
+
for (const volume of _volumes || []) {
|
|
1680
|
+
if (!volume.claimName) continue;
|
|
1681
|
+
const pvcId = `${volume.claimName}-${_deployId}-${env}-${targetTraffic}`;
|
|
1682
|
+
const pvId = `${volume.claimName.replace('pvc-', 'pv-')}-${_deployId}-${env}-${targetTraffic}`;
|
|
1683
|
+
pvPvcYaml += `---\n${Underpost.deploy.persistentVolumeFactory({
|
|
1684
|
+
pvcId,
|
|
1685
|
+
namespace: options.namespace,
|
|
1686
|
+
hostPath: `/home/dd/engine/volume/${pvId}`,
|
|
1687
|
+
nodeName: pvDataNode,
|
|
1688
|
+
})}\n`;
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1691
|
+
// proxy.yaml — this instance's OWN route only (its sub-path → its own
|
|
1692
|
+
// service), so each variant's build dir carries a distinct, instance-scoped
|
|
1693
|
+
// fragment rather than an identical copy of the whole host proxy. The
|
|
1694
|
+
// complete host HTTPProxy — every variant's route aggregated onto the one
|
|
1695
|
+
// fqdn, each pointing at its live colour — is assembled and applied by
|
|
1696
|
+
// `instance-promote` at deploy time, and only once EVERY variant is ready.
|
|
1697
|
+
const proxyYaml =
|
|
1698
|
+
Underpost.deploy.baseProxyYamlFactory({ host: _host, env, options }) +
|
|
1699
|
+
instanceProxyRoutesFactory({
|
|
1700
|
+
deployId,
|
|
1701
|
+
instances: [instance],
|
|
1702
|
+
env,
|
|
1703
|
+
trafficById: { [instance.id]: targetTraffic },
|
|
1704
|
+
});
|
|
1705
|
+
|
|
1706
|
+
// grpc-service.yaml — the parent deploy's gRPC ClusterIP (shared; the
|
|
1707
|
+
// instance cmd resolves {{grpc-service-dns}} to it). Reuse the parent's
|
|
1708
|
+
// generated manifest when present rather than regenerating it here.
|
|
1709
|
+
const parentGrpcServicePath = `./engine-private/conf/${deployId}/build/${env}/grpc-service.yaml`;
|
|
1710
|
+
const grpcServiceYaml = fs.existsSync(parentGrpcServicePath)
|
|
1711
|
+
? fs.readFileSync(parentGrpcServicePath, 'utf8')
|
|
1712
|
+
: '';
|
|
1713
|
+
|
|
1714
|
+
// Write the sibling set next to deployment.yaml (project) and into the
|
|
1715
|
+
// engine-private per-instance build dir (mirrors instances/<id>/ layout).
|
|
1716
|
+
const instanceBuildDir = `./engine-private/conf/${deployId}/instances/${_id}/build/${env}`;
|
|
1717
|
+
fs.mkdirpSync(instanceBuildDir);
|
|
1718
|
+
fs.writeFileSync(`${instanceBuildDir}/deployment.yaml`, deploymentYaml, 'utf8');
|
|
1719
|
+
const siblingManifests = {
|
|
1720
|
+
'pv-pvc.yaml': pvPvcYaml,
|
|
1721
|
+
'proxy.yaml': proxyYaml,
|
|
1722
|
+
'grpc-service.yaml': grpcServiceYaml,
|
|
1723
|
+
};
|
|
1724
|
+
for (const [name, content] of Object.entries(siblingManifests)) {
|
|
1725
|
+
if (!content) continue;
|
|
1726
|
+
fs.writeFileSync(`${envManifestPath}/${name}`, content, 'utf8');
|
|
1727
|
+
fs.writeFileSync(`${instanceBuildDir}/${name}`, content, 'utf8');
|
|
1728
|
+
}
|
|
1729
|
+
logger.info('[instance-build-manifest] Sibling manifests written', {
|
|
1730
|
+
project: envManifestPath,
|
|
1731
|
+
enginePrivate: instanceBuildDir,
|
|
1732
|
+
pvPvc: !!pvPvcYaml,
|
|
1733
|
+
proxy: !!proxyYaml,
|
|
1734
|
+
grpcService: !!grpcServiceYaml,
|
|
1735
|
+
});
|
|
1736
|
+
|
|
1737
|
+
// --- Per-instance env files -----------------------------------------
|
|
1738
|
+
// Each env file is seeded from the template instance's env file for the
|
|
1739
|
+
// same mode so operator-owned keys (API keys, memory limits, service URLs)
|
|
1740
|
+
// are inherited verbatim; only the keys the instance declares under
|
|
1741
|
+
// `multiInstance.env` — plus the derived container id — are (re)written.
|
|
1742
|
+
//
|
|
1743
|
+
// A derived instance's env dir is generated in full: both development.env
|
|
1744
|
+
// and production.env are written on every build, so a deploy in either
|
|
1745
|
+
// environment always finds the env file its `cmd` sources, no matter which
|
|
1746
|
+
// mode this build ran. The default/template instance owns the committed
|
|
1747
|
+
// source files, so only its current-mode file is idempotently refreshed.
|
|
1748
|
+
if (instance.templateId) {
|
|
1749
|
+
const instanceEnvDir = `./engine-private/conf/${deployId}/instances/${_id}/env`;
|
|
1750
|
+
fs.mkdirpSync(instanceEnvDir);
|
|
1751
|
+
const envsToWrite = isDefaultInstance ? [env] : ['development', 'production'];
|
|
1752
|
+
for (const targetEnv of envsToWrite) {
|
|
1753
|
+
const templateEnvPath = `./engine-private/conf/${deployId}/instances/${instance.templateId}/env/${targetEnv}.env`;
|
|
1754
|
+
const baseEnv = fs.existsSync(templateEnvPath) ? dotenv.parse(fs.readFileSync(templateEnvPath, 'utf8')) : {};
|
|
1755
|
+
writeEnv(`${instanceEnvDir}/${targetEnv}.env`, {
|
|
1756
|
+
...baseEnv,
|
|
1757
|
+
...(instance.instanceEnv?.[targetEnv] || {}),
|
|
1758
|
+
CONTAINER_DEPLOY_ID: `${_deployId}-${targetEnv}`,
|
|
1759
|
+
});
|
|
1760
|
+
}
|
|
1761
|
+
logger.info('[instance-build-manifest] Instance env written', {
|
|
1762
|
+
dir: instanceEnvDir,
|
|
1763
|
+
instanceCode: instance.instanceCode,
|
|
1764
|
+
envs: envsToWrite,
|
|
1765
|
+
keys: Object.keys(instance.instanceEnv?.[env] || {}),
|
|
1766
|
+
});
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
if (env === 'production' && isDefaultInstance) {
|
|
1617
1770
|
if (fs.existsSync(dockerfileManifestPath)) {
|
|
1618
1771
|
fs.copyFileSync(dockerfileManifestPath, `${rootPath}/Dockerfile`);
|
|
1619
1772
|
}
|
|
1620
1773
|
fs.copyFileSync(outputPath, `${rootPath}/deployment.yaml`);
|
|
1774
|
+
// Sibling manifests alongside deployment.yaml at the project root.
|
|
1775
|
+
for (const name of ['pv-pvc.yaml', 'proxy.yaml', 'grpc-service.yaml']) {
|
|
1776
|
+
const src = `${envManifestPath}/${name}`;
|
|
1777
|
+
if (fs.existsSync(src)) fs.copyFileSync(src, `${rootPath}/${name}`);
|
|
1778
|
+
}
|
|
1621
1779
|
logger.info('[instance-build-manifest] Production artifacts copied to project root', {
|
|
1622
1780
|
rootPath,
|
|
1623
1781
|
dockerfile: `${rootPath}/Dockerfile`,
|
|
@@ -1629,6 +1787,25 @@ EOF
|
|
|
1629
1787
|
fs.copyFileSync(ciSrc, `${rootPath}/.github/workflows/docker-image.${_runtime}.ci.yml`);
|
|
1630
1788
|
logger.info(`[instance-build-manifest] CI workflow copied`, { src: ciSrc });
|
|
1631
1789
|
}
|
|
1790
|
+
|
|
1791
|
+
// Ship the development variant alongside production so the instance repo
|
|
1792
|
+
// is self-contained: the dev Dockerfile (built by the -dev CI workflow
|
|
1793
|
+
// into underpost/<runtime>-dev, consumed by the development compose
|
|
1794
|
+
// stack) and its dispatchable workflow. Both are optional — synced only
|
|
1795
|
+
// when the source-of-truth files exist in the engine repo.
|
|
1796
|
+
if (_runtime) {
|
|
1797
|
+
const devDockerfileSrc = `src/runtime/${_runtime}/Dockerfile.dev`;
|
|
1798
|
+
if (fs.existsSync(devDockerfileSrc)) {
|
|
1799
|
+
fs.copyFileSync(devDockerfileSrc, `${rootPath}/Dockerfile.dev`);
|
|
1800
|
+
logger.info('[instance-build-manifest] Dev Dockerfile copied', { src: devDockerfileSrc });
|
|
1801
|
+
}
|
|
1802
|
+
const devCiSrc = `./.github/workflows/docker-image.${_runtime}.dev.ci.yml`;
|
|
1803
|
+
if (fs.existsSync(devCiSrc)) {
|
|
1804
|
+
if (!fs.existsSync(`${rootPath}/.github/workflows`)) fs.mkdirpSync(`${rootPath}/.github/workflows`);
|
|
1805
|
+
fs.copyFileSync(devCiSrc, `${rootPath}/.github/workflows/docker-image.${_runtime}.dev.ci.yml`);
|
|
1806
|
+
logger.info(`[instance-build-manifest] Dev CI workflow copied`, { src: devCiSrc });
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1632
1809
|
}
|
|
1633
1810
|
},
|
|
1634
1811
|
|
|
@@ -1636,7 +1813,7 @@ EOF
|
|
|
1636
1813
|
* @method ls-deployments
|
|
1637
1814
|
* @description Retrieves and logs a table of Kubernetes deployments using `Underpost.deploy.get`.
|
|
1638
1815
|
* @param {string} path - The input value, identifier, or path for the operation (used as an optional deployment name filter).
|
|
1639
|
-
* @param {
|
|
1816
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1640
1817
|
* @memberof UnderpostRun
|
|
1641
1818
|
*/
|
|
1642
1819
|
'ls-deployments': async (path, options = DEFAULT_OPTION) => {
|
|
@@ -1647,7 +1824,7 @@ EOF
|
|
|
1647
1824
|
* @method host-update
|
|
1648
1825
|
* @description Executes the `rocky-setup.sh` script to update the host system configuration.
|
|
1649
1826
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
1650
|
-
* @param {
|
|
1827
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1651
1828
|
* @memberof UnderpostRun
|
|
1652
1829
|
*/
|
|
1653
1830
|
'host-update': async (path, options = DEFAULT_OPTION) => {
|
|
@@ -1663,7 +1840,7 @@ EOF
|
|
|
1663
1840
|
* the systemd cgroup driver, enables the `crio` service, and writes `/etc/crictl.yaml`
|
|
1664
1841
|
* so that `crictl` targets the CRI-O socket by default.
|
|
1665
1842
|
* @param {string} path - Unused.
|
|
1666
|
-
* @param {
|
|
1843
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow.
|
|
1667
1844
|
* @memberof UnderpostRun
|
|
1668
1845
|
*/
|
|
1669
1846
|
'install-crio': (path, options = DEFAULT_OPTION) => {
|
|
@@ -1714,7 +1891,7 @@ EOF`);
|
|
|
1714
1891
|
* @method dd-container
|
|
1715
1892
|
* @description Deploys a development or debug container tasks jobs, setting up necessary volumes and images, and running specified commands within the container.
|
|
1716
1893
|
* @param {string} path - The input value, identifier, or path for the operation (used as the command to run inside the container).
|
|
1717
|
-
* @param {
|
|
1894
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1718
1895
|
* @memberof UnderpostRun
|
|
1719
1896
|
*/
|
|
1720
1897
|
'dd-container': async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -1741,7 +1918,11 @@ EOF`);
|
|
|
1741
1918
|
}
|
|
1742
1919
|
|
|
1743
1920
|
if (!currentImage)
|
|
1744
|
-
shellExec(
|
|
1921
|
+
shellExec(
|
|
1922
|
+
`${baseCommand} image${baseClusterCommand} --pull-base --build --path ${
|
|
1923
|
+
options.dev ? '.' : options.underpostRoot
|
|
1924
|
+
} ${options.dev ? '--kind' : '--kubeadm'}`,
|
|
1925
|
+
);
|
|
1745
1926
|
// shellExec(`kubectl delete pod ${podName} --ignore-not-found`);
|
|
1746
1927
|
|
|
1747
1928
|
const payload = {
|
|
@@ -1769,7 +1950,7 @@ EOF`);
|
|
|
1769
1950
|
* @method ip-info
|
|
1770
1951
|
* @description Executes the `ip-info.sh` script to display IP-related information for the specified path.
|
|
1771
1952
|
* @param {string} path - The input value, identifier, or path for the operation (used as an argument to the script).
|
|
1772
|
-
* @param {
|
|
1953
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1773
1954
|
* @memberof UnderpostRun
|
|
1774
1955
|
*/
|
|
1775
1956
|
'ip-info': (path, options = DEFAULT_OPTION) => {
|
|
@@ -1782,7 +1963,7 @@ EOF`);
|
|
|
1782
1963
|
* @method db-client
|
|
1783
1964
|
* @description Deploys and exposes the Adminer database client application (using `adminer:4.7.6-standalone` image) on the cluster.
|
|
1784
1965
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
1785
|
-
* @param {
|
|
1966
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1786
1967
|
* @memberof UnderpostRun
|
|
1787
1968
|
*/
|
|
1788
1969
|
'db-client': async (path, options = DEFAULT_OPTION) => {
|
|
@@ -1809,7 +1990,7 @@ EOF`);
|
|
|
1809
1990
|
* @method git-conf
|
|
1810
1991
|
* @description Configures Git global and local user name and email settings based on the provided `path` (formatted as `username,email`), or defaults to environment variables.
|
|
1811
1992
|
* @param {string} path - The input value, identifier, or path for the operation (used as a comma-separated string: `username,email`).
|
|
1812
|
-
* @param {
|
|
1993
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1813
1994
|
* @memberof UnderpostRun
|
|
1814
1995
|
*/
|
|
1815
1996
|
'git-conf': (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -1857,7 +2038,7 @@ EOF`);
|
|
|
1857
2038
|
* TLS config, deletes stale Certificate resources, then reapplies the proxy and secret.yaml
|
|
1858
2039
|
* (cert-manager Certificate resources) for each affected deployment.
|
|
1859
2040
|
* @param {string} path - The input value, identifier, or path for the operation (used as a comma-separated string: `deployId,env,replicas`).
|
|
1860
|
-
* @param {
|
|
2041
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1861
2042
|
* @memberof UnderpostRun
|
|
1862
2043
|
*/
|
|
1863
2044
|
promote: async (path, options = DEFAULT_OPTION) => {
|
|
@@ -1911,10 +2092,31 @@ EOF`);
|
|
|
1911
2092
|
* @method metrics
|
|
1912
2093
|
* @description Deploys Prometheus and Grafana for metrics monitoring, targeting the hosts defined in the deployment configuration files.
|
|
1913
2094
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
1914
|
-
* @param {
|
|
2095
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1915
2096
|
* @memberof UnderpostRun
|
|
1916
2097
|
*/
|
|
1917
2098
|
metrics: async (path, options = DEFAULT_OPTION) => {
|
|
2099
|
+
if (path === 'server') {
|
|
2100
|
+
shellExec(
|
|
2101
|
+
`kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/high-availability-1.21+.yaml`,
|
|
2102
|
+
);
|
|
2103
|
+
await timer(2000);
|
|
2104
|
+
|
|
2105
|
+
shellExec(`kubectl patch deployment metrics-server -n kube-system \
|
|
2106
|
+
--type='json' \
|
|
2107
|
+
-p='[
|
|
2108
|
+
{
|
|
2109
|
+
"op":"add",
|
|
2110
|
+
"path":"/spec/template/spec/containers/0/args/-",
|
|
2111
|
+
"value":"--kubelet-insecure-tls"
|
|
2112
|
+
}
|
|
2113
|
+
]'`);
|
|
2114
|
+
shellExec(`kubectl scale deployment metrics-server \
|
|
2115
|
+
-n kube-system \
|
|
2116
|
+
--replicas=1`);
|
|
2117
|
+
|
|
2118
|
+
return;
|
|
2119
|
+
}
|
|
1918
2120
|
const deployList = fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8').split(',');
|
|
1919
2121
|
let hosts = [];
|
|
1920
2122
|
for (const deployId of deployList) {
|
|
@@ -1928,7 +2130,7 @@ EOF`);
|
|
|
1928
2130
|
* @method cluster
|
|
1929
2131
|
* @description Deploys a full production/development ready Kubernetes cluster environment including MongoDB, MariaDB, Valkey, Contour (Ingress), and Cert-Manager, and deploys all services.
|
|
1930
2132
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
1931
|
-
* @param {
|
|
2133
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1932
2134
|
* @memberof UnderpostRun
|
|
1933
2135
|
*/
|
|
1934
2136
|
cluster: async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -1990,7 +2192,7 @@ EOF`);
|
|
|
1990
2192
|
* @method deploy
|
|
1991
2193
|
* @description Deploys a specified service (identified by `path`) using blue/green strategy, monitors its status, and switches traffic upon readiness.
|
|
1992
2194
|
* @param {string} path - The input value, identifier, or path for the operation (used as the deployment ID to deploy).
|
|
1993
|
-
* @param {
|
|
2195
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1994
2196
|
* @memberof UnderpostRun
|
|
1995
2197
|
*/
|
|
1996
2198
|
deploy: async (path, options = DEFAULT_OPTION) => {
|
|
@@ -2015,7 +2217,7 @@ EOF`);
|
|
|
2015
2217
|
* @method disk-clean
|
|
2016
2218
|
* @description Executes the `disk-clean-sh` script to perform disk cleanup operations.
|
|
2017
2219
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
2018
|
-
* @param {
|
|
2220
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2019
2221
|
* @memberof UnderpostRun
|
|
2020
2222
|
*/
|
|
2021
2223
|
'disk-clean': async (path, options = DEFAULT_OPTION) => {
|
|
@@ -2028,7 +2230,7 @@ EOF`);
|
|
|
2028
2230
|
* @method disk-devices
|
|
2029
2231
|
* @description Executes the `disk-devices.sh` script to display information about disk devices.
|
|
2030
2232
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
2031
|
-
* @param {
|
|
2233
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2032
2234
|
* @memberof UnderpostRun
|
|
2033
2235
|
*/
|
|
2034
2236
|
'disk-devices': async (path = '/', options = DEFAULT_OPTION) => {
|
|
@@ -2041,7 +2243,7 @@ EOF`);
|
|
|
2041
2243
|
* @method disk-usage
|
|
2042
2244
|
* @description Displays disk usage statistics using the `du` command, sorted by size.
|
|
2043
2245
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
2044
|
-
* @param {
|
|
2246
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2045
2247
|
* @memberof UnderpostRun
|
|
2046
2248
|
*/
|
|
2047
2249
|
'disk-usage': async (path = '/', options = DEFAULT_OPTION) => {
|
|
@@ -2056,7 +2258,7 @@ EOF`);
|
|
|
2056
2258
|
* @method dev
|
|
2057
2259
|
* @description Starts development servers for client, API, and proxy based on provided parameters (deployId, host, path, clientHostPort).
|
|
2058
2260
|
* @param {string} path - The input value, identifier, or path for the operation (formatted as `deployId,subConf,host,path,clientHostPort`).
|
|
2059
|
-
* @param {
|
|
2261
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2060
2262
|
* @memberof UnderpostRun
|
|
2061
2263
|
*/
|
|
2062
2264
|
dev: async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -2116,7 +2318,7 @@ EOF`);
|
|
|
2116
2318
|
* @method service
|
|
2117
2319
|
* @description Deploys and exposes specific services (like `mongo-express-service`) on the cluster, updating deployment configurations and monitoring status.
|
|
2118
2320
|
* @param {string} path - The input value, identifier, or path for the operation (formatted as `deployId,serviceId,host,path,replicas,image,node`).
|
|
2119
|
-
* @param {
|
|
2321
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2120
2322
|
* @memberof UnderpostRun
|
|
2121
2323
|
*/
|
|
2122
2324
|
service: async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -2212,7 +2414,7 @@ EOF`);
|
|
|
2212
2414
|
* @method etc-hosts
|
|
2213
2415
|
* @description Generates and logs the contents for the `/etc/hosts` file based on provided hosts or deployment configurations.
|
|
2214
2416
|
* @param {string} path - The input value, identifier, or path for the operation (used as a comma-separated list of hosts).
|
|
2215
|
-
* @param {
|
|
2417
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2216
2418
|
* @memberof UnderpostRun
|
|
2217
2419
|
*/
|
|
2218
2420
|
'etc-hosts': async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -2229,7 +2431,7 @@ EOF`);
|
|
|
2229
2431
|
* @method sh
|
|
2230
2432
|
* @description Enables remote control for the Kitty terminal emulator.
|
|
2231
2433
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
2232
|
-
* @param {
|
|
2434
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2233
2435
|
* @memberof UnderpostRun
|
|
2234
2436
|
*/
|
|
2235
2437
|
sh: async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -2249,7 +2451,7 @@ EOF`);
|
|
|
2249
2451
|
* @method log
|
|
2250
2452
|
* @description Searches and highlights keywords in a specified log file, optionally showing surrounding lines.
|
|
2251
2453
|
* @param {string} path - The input value, identifier, or path for the operation (formatted as `filePath,keywords,lines`).
|
|
2252
|
-
* @param {
|
|
2454
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2253
2455
|
* @memberof UnderpostRun
|
|
2254
2456
|
*/
|
|
2255
2457
|
log: async (path, options = DEFAULT_OPTION) => {
|
|
@@ -2266,7 +2468,7 @@ EOF`);
|
|
|
2266
2468
|
* @method ps
|
|
2267
2469
|
* @description Displays running processes that match a specified path or keyword.
|
|
2268
2470
|
* @param {string} path - The input value, identifier, or path for the operation (used as a keyword to filter processes).
|
|
2269
|
-
* @param {
|
|
2471
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2270
2472
|
* @memberof UnderpostRun
|
|
2271
2473
|
*/
|
|
2272
2474
|
ps: async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -2291,7 +2493,7 @@ EOF`);
|
|
|
2291
2493
|
* @method pid-info
|
|
2292
2494
|
* @description Displays detailed information about a process by PID, including service details, command line, executable path, working directory, environment variables, and parent process tree.
|
|
2293
2495
|
* @param {string} path - The PID of the process to inspect.
|
|
2294
|
-
* @param {
|
|
2496
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2295
2497
|
* @memberof UnderpostRun
|
|
2296
2498
|
*/
|
|
2297
2499
|
'pid-info': (path, options = DEFAULT_OPTION) => {
|
|
@@ -2331,7 +2533,7 @@ EOF`);
|
|
|
2331
2533
|
* @method background
|
|
2332
2534
|
* @description Runs a custom command in the background using nohup, logging output to `/var/log/<id>.log` and saving the PID to `/var/run/<id>.pid`.
|
|
2333
2535
|
* @param {string} path - The command to run in the background (e.g. 'npm run prod:container dd-cyberia-r3').
|
|
2334
|
-
* @param {
|
|
2536
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2335
2537
|
* @memberof UnderpostRun
|
|
2336
2538
|
*/
|
|
2337
2539
|
background: (path, options = DEFAULT_OPTION) => {
|
|
@@ -2351,7 +2553,7 @@ EOF`);
|
|
|
2351
2553
|
* @method ports
|
|
2352
2554
|
* @description Set on ~/.bashrc alias: ports <port> Command to list listening ports that match the given keyword.
|
|
2353
2555
|
* @param {string} path - The input value, identifier, or path for the operation (used as a keyword to filter listening ports).
|
|
2354
|
-
* @param {
|
|
2556
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2355
2557
|
* @memberof UnderpostRun
|
|
2356
2558
|
*/
|
|
2357
2559
|
ports: async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -2363,7 +2565,7 @@ EOF`);
|
|
|
2363
2565
|
* @method deploy-test
|
|
2364
2566
|
* @description Deploys a test deployment (`dd-test`) in either development or production mode, setting up necessary secrets and starting the deployment.
|
|
2365
2567
|
* @param {string} path - The input value, identifier, or path for the operation (used as the deployment ID).
|
|
2366
|
-
* @param {
|
|
2568
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2367
2569
|
* @memberof UnderpostRun
|
|
2368
2570
|
*/
|
|
2369
2571
|
'deploy-test': async (path, options = DEFAULT_OPTION) => {
|
|
@@ -2388,7 +2590,7 @@ EOF`);
|
|
|
2388
2590
|
* @method tf-vae-test
|
|
2389
2591
|
* @description Creates and runs a job pod (`tf-vae-test`) that installs TensorFlow dependencies, clones the TensorFlow docs, and runs the CVAE tutorial script, with a terminal monitor attached.
|
|
2390
2592
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
2391
|
-
* @param {
|
|
2593
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2392
2594
|
* @memberof UnderpostRun
|
|
2393
2595
|
*/
|
|
2394
2596
|
'tf-vae-test': async (path, options = DEFAULT_OPTION) => {
|
|
@@ -2488,7 +2690,7 @@ EOF`);
|
|
|
2488
2690
|
* @method spark-template
|
|
2489
2691
|
* @description Creates a new Spark template project using `sbt new` in `/home/dd/spark-template`, initializes a Git repository, and runs `replace_params.sh` and `build.sh`.
|
|
2490
2692
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
2491
|
-
* @param {
|
|
2693
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2492
2694
|
* @memberof UnderpostRun
|
|
2493
2695
|
*/
|
|
2494
2696
|
'spark-template': (path, options = DEFAULT_OPTION) => {
|
|
@@ -2516,7 +2718,7 @@ EOF`);
|
|
|
2516
2718
|
* @method pull-rocky-image
|
|
2517
2719
|
* @description Pulls the base `rockylinux:9` image from Docker Hub via Podman.
|
|
2518
2720
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
2519
|
-
* @param {
|
|
2721
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2520
2722
|
* @memberof UnderpostRun
|
|
2521
2723
|
*/
|
|
2522
2724
|
'pull-rocky-image': (path, options = DEFAULT_OPTION) => {
|
|
@@ -2526,7 +2728,7 @@ EOF`);
|
|
|
2526
2728
|
* @method rmi
|
|
2527
2729
|
* @description Forces the removal of all local Podman images (`podman rmi $(podman images -qa) --force`).
|
|
2528
2730
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
2529
|
-
* @param {
|
|
2731
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2530
2732
|
* @memberof UnderpostRun
|
|
2531
2733
|
*/
|
|
2532
2734
|
rmi: (path, options = DEFAULT_OPTION) => {
|
|
@@ -2536,7 +2738,7 @@ EOF`);
|
|
|
2536
2738
|
* @method kill
|
|
2537
2739
|
* @description Kills processes listening on the specified port(s). If the `path` contains a `+`, it treats it as a range of ports to kill.
|
|
2538
2740
|
* @param {string} path - The input value, identifier, or path for the operation (used as the port number).
|
|
2539
|
-
* @param {
|
|
2741
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2540
2742
|
* @memberof UnderpostRun
|
|
2541
2743
|
*/
|
|
2542
2744
|
kill: (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -2568,7 +2770,7 @@ EOF`);
|
|
|
2568
2770
|
* constraints (lowercase, uppercase, digit, special char, min 8 chars). Logs the plain password
|
|
2569
2771
|
* to the console or, when `--copy` is set, copies it to the clipboard via pbcopy.
|
|
2570
2772
|
* @param {string} path - Optional password length (default: 16).
|
|
2571
|
-
* @param {
|
|
2773
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow.
|
|
2572
2774
|
* @param {boolean} options.copy - When true, copies to clipboard instead of logging.
|
|
2573
2775
|
* @memberof UnderpostRun
|
|
2574
2776
|
*/
|
|
@@ -2602,7 +2804,7 @@ EOF`);
|
|
|
2602
2804
|
* @method secret
|
|
2603
2805
|
* @description Creates an Underpost secret named 'underpost' from a file, defaulting to `/home/dd/engine/engine-private/conf/dd-cron/.env.production` if no path is provided.
|
|
2604
2806
|
* @param {string} path - The input value, identifier, or path for the operation (used as the optional path to the secret file).
|
|
2605
|
-
* @param {
|
|
2807
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2606
2808
|
* @memberof UnderpostRun
|
|
2607
2809
|
*/
|
|
2608
2810
|
secret: (path, options = DEFAULT_OPTION) => {
|
|
@@ -2615,7 +2817,7 @@ EOF`);
|
|
|
2615
2817
|
* @method underpost-config
|
|
2616
2818
|
* @description Calls `Underpost.deploy.configMap` to create a Kubernetes ConfigMap, defaulting to the 'production' environment.
|
|
2617
2819
|
* @param {string} path - The input value, identifier, or path for the operation (used as the optional configuration name/environment).
|
|
2618
|
-
* @param {
|
|
2820
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2619
2821
|
* @memberof UnderpostRun
|
|
2620
2822
|
*/
|
|
2621
2823
|
'underpost-config': (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -2625,7 +2827,7 @@ EOF`);
|
|
|
2625
2827
|
* @method gpu-env
|
|
2626
2828
|
* @description Sets up a dedicated GPU development environment cluster, resetting and then setting up the cluster with `--dedicated-gpu` and monitoring the pods.
|
|
2627
2829
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
2628
|
-
* @param {
|
|
2830
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2629
2831
|
* @memberof UnderpostRun
|
|
2630
2832
|
*/
|
|
2631
2833
|
'gpu-env': (path, options = DEFAULT_OPTION) => {
|
|
@@ -2638,7 +2840,7 @@ EOF`);
|
|
|
2638
2840
|
* @method tf-gpu-test
|
|
2639
2841
|
* @description Deletes existing `tf-gpu-test-script` ConfigMap and `tf-gpu-test-pod`, and applies the test manifest from `manifests/deployment/tensorflow/tf-gpu-test.yaml`.
|
|
2640
2842
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
2641
|
-
* @param {
|
|
2843
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2642
2844
|
* @memberof UnderpostRun
|
|
2643
2845
|
*/
|
|
2644
2846
|
'tf-gpu-test': (path, options = DEFAULT_OPTION) => {
|
|
@@ -2652,7 +2854,7 @@ EOF`);
|
|
|
2652
2854
|
* @method deploy-job
|
|
2653
2855
|
* @description Creates and applies a custom Kubernetes Pod manifest (Job) for running arbitrary commands inside a container image (defaulting to a TensorFlow/NVIDIA image).
|
|
2654
2856
|
* @param {string} path - The input value, identifier, or path for the operation (used as the optional script path or job argument).
|
|
2655
|
-
* @param {
|
|
2857
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2656
2858
|
* @memberof UnderpostRun
|
|
2657
2859
|
*/
|
|
2658
2860
|
'deploy-job': async (path, options = DEFAULT_OPTION) => {
|
|
@@ -2787,7 +2989,7 @@ EOF`;
|
|
|
2787
2989
|
* Only files matching `<host>-<route>.zip.part*` or `<host>-<route>.zip` for each non-skipped route are uploaded.
|
|
2788
2990
|
* @param {string} path - Optional `fsPath.splitOption` string.
|
|
2789
2991
|
* Examples: `build` (default split 8), `build.16` (split 16 MB), `build.none-split` (no split flag).
|
|
2790
|
-
* @param {
|
|
2992
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow.
|
|
2791
2993
|
* @param {string} [options.deployId] - Override deploy ID.
|
|
2792
2994
|
* @param {boolean} [options.dev] - Use development environment; defaults to production.
|
|
2793
2995
|
* @memberof UnderpostRun
|
|
@@ -2875,7 +3077,7 @@ EOF`;
|
|
|
2875
3077
|
* so that multi-path deployments are handled correctly.
|
|
2876
3078
|
* @param {string} path - Optional comma-separated host name(s) to restrict processing (e.g. 'underpost.net' or 'a.com,b.com').
|
|
2877
3079
|
* If omitted, all hosts from `engine-private/conf/<deployId>/conf.server.json` are used.
|
|
2878
|
-
* @param {
|
|
3080
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow.
|
|
2879
3081
|
* @param {string} [options.deployId] - Deploy ID for storage lookup (defaults to 'dd-default').
|
|
2880
3082
|
* @param {boolean} [options.dev] - Use development environment; defaults to production.
|
|
2881
3083
|
* @memberof UnderpostRun
|
|
@@ -2967,7 +3169,7 @@ EOF`;
|
|
|
2967
3169
|
* @method build-cluster-deployment-manifests
|
|
2968
3170
|
* @description Builds deployment manifests for both production and development environments using `node bin deploy --build-manifest`, syncing them, and setting replicas to 1 for the `dd` deployment.
|
|
2969
3171
|
* @param {string} path - Unused.
|
|
2970
|
-
* @param {
|
|
3172
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow.
|
|
2971
3173
|
* @memberof UnderpostRun
|
|
2972
3174
|
*/
|
|
2973
3175
|
'build-cluster-deployment-manifests': (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -2980,7 +3182,7 @@ EOF`;
|
|
|
2980
3182
|
* @description Installs and enables the Cockpit KVM Dashboard (cockpit, cockpit-machines, libvirt)
|
|
2981
3183
|
* and opens the cockpit firewall service. With `--remove`, closes the firewall service instead.
|
|
2982
3184
|
* @param {string} path - Unused.
|
|
2983
|
-
* @param {
|
|
3185
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow.
|
|
2984
3186
|
* `options.remove` — when true, removes the cockpit firewall rule instead of adding it.
|
|
2985
3187
|
* @memberof UnderpostRun
|
|
2986
3188
|
*/
|
|
@@ -3004,7 +3206,7 @@ EOF`;
|
|
|
3004
3206
|
* Use `reload-shared-dir` for subsequent permission repairs without recreating the group.
|
|
3005
3207
|
* @param {string} path - Target directory to set up (defaults to `/home/dd/engine`).
|
|
3006
3208
|
* Customise via the `path` argument or leave empty to use the default.
|
|
3007
|
-
* @param {
|
|
3209
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow.
|
|
3008
3210
|
* Key fields: `options.user` (default `'admin'`), `options.group` (default `'engine-dev'`).
|
|
3009
3211
|
* @memberof UnderpostRun
|
|
3010
3212
|
*/
|
|
@@ -3032,7 +3234,7 @@ EOF`;
|
|
|
3032
3234
|
* write throughout the shared workspace while preserving existing ownership.
|
|
3033
3235
|
*
|
|
3034
3236
|
* @param {string} path - Shared directory (defaults to `/home/dd/engine`).
|
|
3035
|
-
* @param {
|
|
3237
|
+
* @param {UnderpostRunDefaultOptions} options - Underpost runner options.
|
|
3036
3238
|
* Key fields:
|
|
3037
3239
|
* - options.user (default: 'admin')
|
|
3038
3240
|
* - options.group (default: 'engine-dev')
|
|
@@ -3080,7 +3282,7 @@ EOF`;
|
|
|
3080
3282
|
* @description Executes a specified runner function from the UnderpostRun class with the provided path and options.
|
|
3081
3283
|
* @param {string} runner - The name of the runner to execute.
|
|
3082
3284
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
3083
|
-
* @param {
|
|
3285
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
3084
3286
|
* @memberof UnderpostRun
|
|
3085
3287
|
* @returns {Promise<any>} The result of the runner execution.
|
|
3086
3288
|
*/
|
|
@@ -3093,7 +3295,7 @@ EOF`;
|
|
|
3093
3295
|
* @description Initiates the execution of a specified CLI command (runner) with the given input value (`path`) and processed options.
|
|
3094
3296
|
* @param {string} runner - The name of the runner to execute.
|
|
3095
3297
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
3096
|
-
* @param {
|
|
3298
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
3097
3299
|
* @memberof UnderpostRun
|
|
3098
3300
|
* @returns {Promise<any>} The result of the callback execution.
|
|
3099
3301
|
*/
|