cyberia 3.2.22 → 3.2.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +127 -68
- package/.github/workflows/cyberia-client.cd.yml +40 -0
- package/.github/workflows/cyberia-server.cd.yml +40 -0
- package/.github/workflows/docker-image.cyberia-client.ci.yml +49 -0
- package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +48 -0
- package/.github/workflows/docker-image.cyberia-server.ci.yml +69 -0
- package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +69 -0
- package/.github/workflows/docker-image.engine-cyberia.ci.yml +52 -0
- package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +52 -0
- package/.github/workflows/engine-cyberia.cd.yml +33 -24
- package/.github/workflows/engine-cyberia.ci.yml +13 -3
- package/.github/workflows/ghpkg.ci.yml +88 -1
- package/.github/workflows/gitlab.ci.yml +1 -1
- package/.github/workflows/hardhat.ci.yml +1 -1
- package/.github/workflows/npmpkg.ci.yml +10 -7
- package/.github/workflows/publish.ci.yml +2 -2
- package/.github/workflows/publish.cyberia.ci.yml +5 -16
- package/.github/workflows/pwa-microservices-template-page.cd.yml +1 -8
- package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
- package/CHANGELOG.md +301 -1
- package/CLI-HELP.md +71 -6
- package/Dockerfile +141 -43
- package/Dockerfile.dev +143 -0
- package/Dockerfile.test +165 -0
- package/README.md +1 -1
- package/baremetal/commission-workflows.json +1 -0
- package/bin/build.js +31 -0
- package/bin/cyberia.js +1080 -184
- package/bin/deploy.js +2 -2
- package/bin/index.js +1080 -184
- package/bump.config.js +1 -0
- package/compose.env +131 -0
- package/conf.js +18 -1
- package/deployment.yaml +2 -2
- package/docker-compose.yml +316 -0
- package/hardhat/hardhat.config.js +2 -2
- package/hardhat/package-lock.json +620 -2041
- package/hardhat/package.json +7 -5
- package/hardhat/scripts/deployObjectLayerToken.js +18 -18
- package/hardhat/test/ObjectLayerToken.js +378 -274
- package/ipfs/configure-ipfs.sh +13 -0
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-cyberia-development/grpc-service.yaml +17 -0
- package/manifests/deployment/dd-cyberia-development/pv-pvc.yaml +32 -0
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/mongodb/entrypoint.sh +76 -0
- package/nginx.conf +87 -0
- package/package.json +31 -19
- package/pv-pvc.yaml +32 -0
- package/scripts/disk-clean.sh +85 -60
- package/scripts/kubeadm-node-setup.sh +317 -0
- package/scripts/rocky-kickstart.sh +877 -185
- package/scripts/rpmfusion-ffmpeg-setup.sh +26 -50
- package/scripts/test-monitor.sh +3 -5
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +43 -7
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +17 -25
- package/src/api/cyberia-action/cyberia-action.controller.js +19 -0
- package/src/api/cyberia-action/cyberia-action.model.js +21 -29
- package/src/api/cyberia-action/cyberia-action.router.js +42 -7
- package/src/api/cyberia-action/cyberia-action.service.js +20 -4
- package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +58 -57
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +37 -6
- package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +8 -2
- package/src/api/cyberia-entity/cyberia-entity.router.js +39 -7
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +74 -0
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.model.js +67 -0
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +63 -0
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +46 -0
- package/src/api/cyberia-instance/cyberia-fallback-world.js +62 -10
- package/src/api/cyberia-instance/cyberia-instance.model.js +32 -2
- package/src/api/cyberia-instance/cyberia-instance.router.js +6 -6
- package/src/api/cyberia-instance/cyberia-world-generator.js +116 -3
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +3 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +39 -7
- package/src/api/cyberia-map/cyberia-map.router.js +21 -6
- package/src/api/cyberia-quest/cyberia-quest.controller.js +38 -0
- package/src/api/cyberia-quest/cyberia-quest.router.js +47 -7
- package/src/api/cyberia-quest/cyberia-quest.service.js +59 -4
- package/src/api/cyberia-saga/cyberia-saga.controller.js +74 -0
- package/src/api/cyberia-saga/cyberia-saga.model.js +59 -0
- package/src/api/cyberia-saga/cyberia-saga.router.js +63 -0
- package/src/api/cyberia-saga/cyberia-saga.service.js +42 -0
- package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +551 -129
- package/src/api/cyberia-skill/cyberia-skill.controller.js +74 -0
- package/src/api/cyberia-skill/cyberia-skill.model.js +50 -0
- package/src/api/cyberia-skill/cyberia-skill.router.js +63 -0
- package/src/api/cyberia-skill/cyberia-skill.service.js +42 -0
- package/src/api/ipfs/ipfs.service.js +28 -15
- package/src/api/object-layer/object-layer.router.js +25 -15
- package/src/api/object-layer/object-layer.service.js +15 -20
- package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +39 -7
- package/src/cli/baremetal.js +717 -16
- package/src/cli/cluster.js +80 -5
- package/src/cli/deploy.js +127 -11
- package/src/cli/docker-compose.js +648 -0
- package/src/cli/env.js +11 -2
- package/src/cli/fs.js +75 -30
- package/src/cli/image.js +129 -51
- package/src/cli/index.js +110 -6
- package/src/cli/kickstart.js +142 -20
- package/src/cli/release.js +46 -4
- package/src/cli/repository.js +238 -33
- package/src/cli/run.js +520 -114
- package/src/cli/secrets.js +82 -48
- package/src/cli/ssh.js +234 -0
- package/src/cli/static.js +2 -2
- package/src/client/components/cyberia/ActionEngineCyberia.js +1867 -0
- package/src/client/components/cyberia/EntityEngineCyberia.js +585 -0
- package/src/client/components/cyberia/InstanceEngineCyberia.js +219 -13
- package/src/client/components/cyberia/MapEngineCyberia.js +154 -71
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +40 -63
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +34 -20
- package/src/client/components/cyberia/SharedDefaultsCyberia.js +195 -4
- package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +66 -0
- package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +8 -0
- package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +8 -0
- package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +45 -27
- package/src/client/public/cyberia-docs/CYBERIA-CLI.md +3 -3
- package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +39 -22
- package/src/client/public/cyberia-docs/CYBERIA-LORE.md +88 -0
- package/src/client/public/cyberia-docs/CYBERIA-SAGA.md +394 -0
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +8 -1
- package/src/client/public/cyberia-docs/CYBERIA.md +1 -1
- package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +5 -5
- package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
- package/src/client/services/cyberia-entity-type-default/cyberia-entity-type-default.service.js +99 -0
- package/src/client/services/cyberia-instance/cyberia-instance.management.js +2 -2
- package/src/client/services/cyberia-map/cyberia-map.management.js +2 -2
- package/src/client/services/cyberia-saga/cyberia-saga.service.js +99 -0
- package/src/client/services/cyberia-skill/cyberia-skill.service.js +99 -0
- package/src/client/services/object-layer/object-layer.management.js +6 -6
- package/src/{server → client-builder}/client-build-docs.js +15 -5
- package/src/{server → client-builder}/client-build-live.js +3 -3
- package/src/{server → client-builder}/client-build.js +25 -22
- package/src/{server → client-builder}/client-dev-server.js +3 -3
- package/src/{server → client-builder}/client-icons.js +2 -2
- package/src/{server → client-builder}/ssr.js +5 -5
- package/src/client.build.js +1 -3
- package/src/client.dev.js +1 -1
- package/src/db/mongo/MongoBootstrap.js +12 -12
- package/src/grpc/cyberia/grpc-server.js +255 -70
- package/src/index.js +12 -1
- package/src/mailer/EmailRender.js +1 -1
- package/src/{server → projects/cyberia}/atlas-sprite-sheet-generator.js +2 -2
- package/src/{server → projects/cyberia}/besu-genesis-generator.js +3 -3
- package/src/projects/cyberia/catalog-cyberia.js +81 -0
- package/src/projects/cyberia/gemini-client.js +175 -0
- package/src/projects/cyberia/generate-saga.js +2107 -0
- package/src/{server → projects/cyberia}/ipfs-client.js +2 -2
- package/src/{server → projects/cyberia}/object-layer.js +12 -108
- package/src/{server → projects/cyberia}/semantic-layer-generator-floor.js +1 -1
- package/src/{server → projects/cyberia}/semantic-layer-generator-resource.js +1 -1
- package/src/{server → projects/cyberia}/semantic-layer-generator-skin.js +1 -1
- package/src/{server → projects/cyberia}/semantic-layer-generator.js +2 -2
- package/src/{server → projects/cyberia}/shape-generator.js +2 -2
- package/src/{server → projects/underpost}/catalog-underpost.js +1 -2
- package/src/runtime/cyberia-client/Dockerfile +27 -61
- package/src/runtime/cyberia-client/Dockerfile.dev +20 -12
- package/src/runtime/cyberia-server/Dockerfile +21 -20
- package/src/runtime/cyberia-server/Dockerfile.dev +17 -8
- package/src/runtime/engine-cyberia/Dockerfile +143 -0
- package/src/runtime/engine-cyberia/Dockerfile.dev +143 -0
- package/src/runtime/engine-cyberia/Dockerfile.test +165 -0
- package/src/runtime/engine-cyberia/compose.env +131 -0
- package/src/runtime/engine-cyberia/docker-compose.yml +316 -0
- package/src/runtime/engine-cyberia/ipfs/configure-ipfs.sh +13 -0
- package/src/runtime/engine-cyberia/mongodb/entrypoint.sh +76 -0
- package/src/runtime/engine-cyberia/nginx.conf +87 -0
- package/src/runtime/express/Express.js +2 -2
- package/src/runtime/nginx/Nginx.js +250 -0
- package/src/server/catalog.js +9 -14
- package/src/server/conf.js +3 -6
- package/src/server/runtime-status.js +18 -1
- package/src/server/start.js +12 -2
- package/src/server.js +6 -2
- package/test/cyberia-instance-conf-defaults.test.js +140 -0
- package/test/deploy-monitor.test.js +26 -10
- package/test/shape-generator.test.js +7 -1
- package/typedoc.dd-cyberia.json +3 -1
- package/typedoc.json +3 -1
- /package/src/client/ssr/{Render.js → RootDocument.js} +0 -0
- /package/src/{server → client-builder}/client-formatted.js +0 -0
package/src/cli/run.js
CHANGED
|
@@ -22,7 +22,7 @@ import { actionInitLog, loggerFactory } from '../server/logger.js';
|
|
|
22
22
|
|
|
23
23
|
import fs from 'fs-extra';
|
|
24
24
|
import net from 'net';
|
|
25
|
-
import { range, setPad, timer } from '../client/components/core/CommonJs.js';
|
|
25
|
+
import { range, s4, setPad, timer } from '../client/components/core/CommonJs.js';
|
|
26
26
|
|
|
27
27
|
import os from 'os';
|
|
28
28
|
import Underpost from '../index.js';
|
|
@@ -52,10 +52,12 @@ const logger = loggerFactory(import.meta);
|
|
|
52
52
|
/**
|
|
53
53
|
* @constant DEFAULT_OPTION
|
|
54
54
|
* @description Default options for the UnderpostRun class.
|
|
55
|
+
* @typedef {Object} UnderpostRunDefaultOptions
|
|
55
56
|
* @type {Object}
|
|
56
57
|
* @property {boolean} dev - Whether to run in development mode.
|
|
57
58
|
* @property {string} podName - The name of the pod to run.
|
|
58
59
|
* @property {string} nodeName - The name of the node to run.
|
|
60
|
+
* @property {string} sshKeyPath - Private key path for node SSH operations, forwarded to volume shipping over SSH.
|
|
59
61
|
* @property {number} port - Custom port to use.
|
|
60
62
|
* @property {string} volumeHostPath - The host path for the volume.
|
|
61
63
|
* @property {string} volumeMountPath - The mount path for the volume.
|
|
@@ -127,6 +129,7 @@ const DEFAULT_OPTION = {
|
|
|
127
129
|
dev: false,
|
|
128
130
|
podName: '',
|
|
129
131
|
nodeName: '',
|
|
132
|
+
sshKeyPath: '',
|
|
130
133
|
port: 0,
|
|
131
134
|
volumeHostPath: '',
|
|
132
135
|
volumeMountPath: '',
|
|
@@ -213,7 +216,7 @@ class UnderpostRun {
|
|
|
213
216
|
* @method dev-cluster
|
|
214
217
|
* @description Resets and deploys a full development cluster including MongoDB, Valkey, exposes services, and updates `/etc/hosts` for local access.
|
|
215
218
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
216
|
-
* @param {
|
|
219
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
217
220
|
* @memberof UnderpostRun
|
|
218
221
|
*/
|
|
219
222
|
'dev-cluster': (path, options = DEFAULT_OPTION) => {
|
|
@@ -295,7 +298,7 @@ class UnderpostRun {
|
|
|
295
298
|
* @method metadata
|
|
296
299
|
* @description Generates metadata for the specified path after exposing the development cluster.
|
|
297
300
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
298
|
-
* @param {
|
|
301
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
299
302
|
* @memberof UnderpostRun
|
|
300
303
|
*/
|
|
301
304
|
metadata: async (path, options = DEFAULT_OPTION) => {
|
|
@@ -320,7 +323,7 @@ class UnderpostRun {
|
|
|
320
323
|
* @method svc-ls
|
|
321
324
|
* @description Lists systemd services and installed packages, optionally filtering by the provided path.
|
|
322
325
|
* @param {string} path - The input value, identifier, or path for the operation (used as the optional filter for services and packages).
|
|
323
|
-
* @param {
|
|
326
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
324
327
|
* @memberof UnderpostRun
|
|
325
328
|
*/
|
|
326
329
|
'svc-ls': (path, options = DEFAULT_OPTION) => {
|
|
@@ -340,7 +343,7 @@ class UnderpostRun {
|
|
|
340
343
|
* @method svc-rm
|
|
341
344
|
* @description Removes a systemd service by stopping it, disabling it, uninstalling the package, and deleting related files.
|
|
342
345
|
* @param {string} path - The input value, identifier, or path for the operation (used as the service name).
|
|
343
|
-
* @param {
|
|
346
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
344
347
|
* @memberof UnderpostRun
|
|
345
348
|
*/
|
|
346
349
|
'svc-rm': (path, options = DEFAULT_OPTION) => {
|
|
@@ -355,7 +358,7 @@ class UnderpostRun {
|
|
|
355
358
|
* @method ssh-deploy-info
|
|
356
359
|
* @description Retrieves deployment status and pod information from a remote server via SSH.
|
|
357
360
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
358
|
-
* @param {
|
|
361
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
359
362
|
* @memberof UnderpostRun
|
|
360
363
|
*/
|
|
361
364
|
'ssh-deploy-info': async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -373,11 +376,233 @@ class UnderpostRun {
|
|
|
373
376
|
);
|
|
374
377
|
},
|
|
375
378
|
|
|
379
|
+
/**
|
|
380
|
+
* @method node-move
|
|
381
|
+
* @description Abstract runner that relocates any schedulable Kubernetes workload
|
|
382
|
+
* (Deployment, StatefulSet, DaemonSet, ReplicaSet, Job, CronJob, ReplicationController)
|
|
383
|
+
* onto a target node by patching its pod-template `nodeSelector` and rolling it out.
|
|
384
|
+
* Resource-kind agnostic: it resolves the kind dynamically and applies the right
|
|
385
|
+
* patch path, so it works for `sts`, `deployment`, etc. without bespoke logic.
|
|
386
|
+
*
|
|
387
|
+
* Selection grammar via `path`:
|
|
388
|
+
* - `<kind>/<name>` -> a single resource (e.g. `deployment/dd-core-production-blue`)
|
|
389
|
+
* - `<kind>` -> every resource of that kind in the namespace (e.g. `statefulset`)
|
|
390
|
+
* - `` -> all movable workloads (deployment, statefulset, daemonset) in the namespace
|
|
391
|
+
*
|
|
392
|
+
* Placement:
|
|
393
|
+
* - default: built-in `kubernetes.io/hostname=<node>` (no node mutation required)
|
|
394
|
+
* - `--labels k=v,...`: label the target node with those pairs and use them as the
|
|
395
|
+
* nodeSelector (matches the "label node + nodeSelector" pattern), enabling reusable
|
|
396
|
+
* workload pools instead of pinning to a single hostname.
|
|
397
|
+
*
|
|
398
|
+
* Flags: `--node-name <node>` (target), `--namespace <ns>`, `--dry-run` (preview only),
|
|
399
|
+
* `--remove` (clear the nodeSelector / unpin placement).
|
|
400
|
+
*
|
|
401
|
+
* Caveats: Services/ConfigMaps and bare Pods are not schedulable controllers and are
|
|
402
|
+
* skipped (move the owning controller). StatefulSets bound to node-local PVs may stay
|
|
403
|
+
* Pending after a move until their volume is available on the target node.
|
|
404
|
+
* @param {string} path - Resource selector (`kind/name`, `kind`, or empty).
|
|
405
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
406
|
+
* @memberof UnderpostRun
|
|
407
|
+
* @returns {Array<{ref:string,kind:string,status:string,node?:string}>} Per-resource outcome.
|
|
408
|
+
*/
|
|
409
|
+
'node-move': (path = '', options = DEFAULT_OPTION) => {
|
|
410
|
+
const node = options.nodeName;
|
|
411
|
+
const ns = options.namespace || 'default';
|
|
412
|
+
const dryRun = options.dryRun === true;
|
|
413
|
+
const remove = options.remove === true;
|
|
414
|
+
|
|
415
|
+
if (!remove && !node) {
|
|
416
|
+
throw new Error('node-move requires --node-name <target-node> (or --remove to clear placement)');
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const normalizeKind = (k) =>
|
|
420
|
+
({
|
|
421
|
+
deploy: 'deployment',
|
|
422
|
+
deployments: 'deployment',
|
|
423
|
+
deployment: 'deployment',
|
|
424
|
+
sts: 'statefulset',
|
|
425
|
+
statefulsets: 'statefulset',
|
|
426
|
+
statefulset: 'statefulset',
|
|
427
|
+
ds: 'daemonset',
|
|
428
|
+
daemonsets: 'daemonset',
|
|
429
|
+
daemonset: 'daemonset',
|
|
430
|
+
rs: 'replicaset',
|
|
431
|
+
replicasets: 'replicaset',
|
|
432
|
+
replicaset: 'replicaset',
|
|
433
|
+
rc: 'replicationcontroller',
|
|
434
|
+
replicationcontroller: 'replicationcontroller',
|
|
435
|
+
job: 'job',
|
|
436
|
+
jobs: 'job',
|
|
437
|
+
cj: 'cronjob',
|
|
438
|
+
cronjob: 'cronjob',
|
|
439
|
+
cronjobs: 'cronjob',
|
|
440
|
+
po: 'pod',
|
|
441
|
+
pod: 'pod',
|
|
442
|
+
pods: 'pod',
|
|
443
|
+
svc: 'service',
|
|
444
|
+
service: 'service',
|
|
445
|
+
services: 'service',
|
|
446
|
+
})[k] || k;
|
|
447
|
+
|
|
448
|
+
// Kinds that own a pod template we can patch; rolloutKinds additionally
|
|
449
|
+
// support `kubectl rollout restart` to reschedule existing pods now.
|
|
450
|
+
const templated = [
|
|
451
|
+
'deployment',
|
|
452
|
+
'statefulset',
|
|
453
|
+
'daemonset',
|
|
454
|
+
'replicaset',
|
|
455
|
+
'job',
|
|
456
|
+
'cronjob',
|
|
457
|
+
'replicationcontroller',
|
|
458
|
+
];
|
|
459
|
+
const rolloutKinds = ['deployment', 'statefulset', 'daemonset'];
|
|
460
|
+
const templateSelectorPath = (kind) =>
|
|
461
|
+
kind === 'cronjob'
|
|
462
|
+
? ['spec', 'jobTemplate', 'spec', 'template', 'spec', 'nodeSelector']
|
|
463
|
+
: ['spec', 'template', 'spec', 'nodeSelector'];
|
|
464
|
+
|
|
465
|
+
// Resolve the desired nodeSelector. Custom --labels enables reusable pools;
|
|
466
|
+
// otherwise pin by the always-present hostname label.
|
|
467
|
+
let selector = { 'kubernetes.io/hostname': node };
|
|
468
|
+
if (!remove && options.labels) {
|
|
469
|
+
selector = {};
|
|
470
|
+
for (const pair of `${options.labels}`
|
|
471
|
+
.split(',')
|
|
472
|
+
.map((s) => s.trim())
|
|
473
|
+
.filter(Boolean)) {
|
|
474
|
+
const eq = pair.indexOf('=');
|
|
475
|
+
if (eq < 0) continue;
|
|
476
|
+
selector[pair.slice(0, eq).trim()] = pair.slice(eq + 1).trim();
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// Verify the target node exists, and apply custom labels to it if provided.
|
|
481
|
+
if (!remove) {
|
|
482
|
+
const found = shellExec(`kubectl get node ${node} -o name`, {
|
|
483
|
+
silent: true,
|
|
484
|
+
stdout: true,
|
|
485
|
+
silentOnError: true,
|
|
486
|
+
}).trim();
|
|
487
|
+
if (!found) throw new Error(`Target node not found: ${node}`);
|
|
488
|
+
if (options.labels) {
|
|
489
|
+
const labelArgs = Object.entries(selector)
|
|
490
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
491
|
+
.join(' ');
|
|
492
|
+
const labelCmd = `kubectl label node ${node} ${labelArgs} --overwrite`;
|
|
493
|
+
if (dryRun) logger.info(`[dry-run] ${labelCmd}`);
|
|
494
|
+
else shellExec(labelCmd);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
const kubectlNames = (kind) =>
|
|
499
|
+
(
|
|
500
|
+
shellExec(`kubectl get ${kind} -n ${ns} -o name`, {
|
|
501
|
+
silent: true,
|
|
502
|
+
stdout: true,
|
|
503
|
+
silentOnError: true,
|
|
504
|
+
}).trim() || ''
|
|
505
|
+
)
|
|
506
|
+
.split('\n')
|
|
507
|
+
.map((s) => s.trim())
|
|
508
|
+
.filter(Boolean);
|
|
509
|
+
|
|
510
|
+
// Build the list of "kind/name" targets from the selection grammar.
|
|
511
|
+
let targets = [];
|
|
512
|
+
if (!path) {
|
|
513
|
+
for (const kind of ['deployment', 'statefulset', 'daemonset']) targets.push(...kubectlNames(kind));
|
|
514
|
+
} else if (path.includes('/')) {
|
|
515
|
+
targets = [path];
|
|
516
|
+
} else {
|
|
517
|
+
targets = kubectlNames(path);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
if (targets.length === 0) {
|
|
521
|
+
logger.warn('node-move: no matching resources found', { path, namespace: ns });
|
|
522
|
+
return [];
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// Merge-patch body that sets (or clears, when --remove) the nodeSelector.
|
|
526
|
+
const buildPatch = (kind) => {
|
|
527
|
+
const keys = templateSelectorPath(kind);
|
|
528
|
+
let obj = remove ? null : selector;
|
|
529
|
+
for (let i = keys.length - 1; i >= 0; i--) obj = { [keys[i]]: obj };
|
|
530
|
+
return JSON.stringify(obj);
|
|
531
|
+
};
|
|
532
|
+
|
|
533
|
+
const results = [];
|
|
534
|
+
for (const ref of targets) {
|
|
535
|
+
const slash = ref.indexOf('/');
|
|
536
|
+
const rawKind = slash >= 0 ? ref.slice(0, slash) : path && !path.includes('/') ? path : '';
|
|
537
|
+
const name = slash >= 0 ? ref.slice(slash + 1) : ref;
|
|
538
|
+
const kind = normalizeKind(`${rawKind}`.split('.')[0].toLowerCase());
|
|
539
|
+
|
|
540
|
+
if (!templated.includes(kind)) {
|
|
541
|
+
logger.warn(`node-move: ${kind}/${name} is not a schedulable controller; skipping`, {
|
|
542
|
+
hint: 'move its owning controller (deployment/statefulset/daemonset) instead',
|
|
543
|
+
});
|
|
544
|
+
results.push({ ref, kind, status: 'skipped' });
|
|
545
|
+
continue;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// Idempotency: skip the patch + rollout if the resource is already where
|
|
549
|
+
// we want it. Compares the live pod-template nodeSelector against the
|
|
550
|
+
// desired placement so a repeated run does not trigger an unnecessary
|
|
551
|
+
// rollout restart.
|
|
552
|
+
const basePath = kind === 'cronjob' ? 'spec.jobTemplate.spec.template.spec' : 'spec.template.spec';
|
|
553
|
+
const jsonpath = (expr) =>
|
|
554
|
+
shellExec(`kubectl get ${kind} ${name} -n ${ns} -o jsonpath='${expr}'`, {
|
|
555
|
+
silent: true,
|
|
556
|
+
stdout: true,
|
|
557
|
+
silentOnError: true,
|
|
558
|
+
disableLog: true,
|
|
559
|
+
}).trim();
|
|
560
|
+
|
|
561
|
+
if (remove) {
|
|
562
|
+
const current = jsonpath(`{.${basePath}.nodeSelector}`);
|
|
563
|
+
if (!current || current === 'map[]') {
|
|
564
|
+
logger.info(`node-move: ${kind}/${name} already has no nodeSelector; nothing to clear`);
|
|
565
|
+
results.push({ ref, kind, status: 'already-cleared' });
|
|
566
|
+
continue;
|
|
567
|
+
}
|
|
568
|
+
} else {
|
|
569
|
+
const alreadyOnNode = Object.entries(selector).every(([k, v]) => {
|
|
570
|
+
const esc = k.replace(/\./g, '\\.');
|
|
571
|
+
return jsonpath(`{.${basePath}.nodeSelector.${esc}}`) === v;
|
|
572
|
+
});
|
|
573
|
+
if (alreadyOnNode) {
|
|
574
|
+
logger.info(`node-move: ${kind}/${name} already pinned to ${node}; skipping`, { namespace: ns });
|
|
575
|
+
results.push({ ref, kind, status: 'already-on-node', node });
|
|
576
|
+
continue;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
const patchCmd = `kubectl patch ${kind} ${name} -n ${ns} --type=merge -p '${buildPatch(kind)}'`;
|
|
581
|
+
const restartCmd = `kubectl rollout restart ${kind} ${name} -n ${ns}`;
|
|
582
|
+
if (dryRun) {
|
|
583
|
+
logger.info(`[dry-run] ${patchCmd}`);
|
|
584
|
+
if (rolloutKinds.includes(kind)) logger.info(`[dry-run] ${restartCmd}`);
|
|
585
|
+
results.push({ ref, kind, status: 'dry-run', node: remove ? undefined : node });
|
|
586
|
+
continue;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
shellExec(patchCmd);
|
|
590
|
+
if (rolloutKinds.includes(kind)) shellExec(restartCmd);
|
|
591
|
+
logger.info(remove ? `Cleared node placement: ${kind}/${name}` : `Moved ${kind}/${name} -> ${node}`, {
|
|
592
|
+
namespace: ns,
|
|
593
|
+
});
|
|
594
|
+
results.push({ ref, kind, status: remove ? 'cleared' : 'moved', node: remove ? undefined : node });
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
logger.info('node-move complete', { namespace: ns, node: remove ? null : node, count: results.length });
|
|
598
|
+
return results;
|
|
599
|
+
},
|
|
600
|
+
|
|
376
601
|
/**
|
|
377
602
|
* @method dev-hosts-expose
|
|
378
603
|
* @description Deploys a specified service in development mode with `/etc/hosts` modification for local access.
|
|
379
604
|
* @param {string} path - The input value, identifier, or path for the operation (used as the deployment ID to deploy).
|
|
380
|
-
* @param {
|
|
605
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
381
606
|
* @memberof UnderpostRun
|
|
382
607
|
*/
|
|
383
608
|
'dev-hosts-expose': (path, options = DEFAULT_OPTION) => {
|
|
@@ -390,7 +615,7 @@ class UnderpostRun {
|
|
|
390
615
|
* @method dev-hosts-restore
|
|
391
616
|
* @description Restores the `/etc/hosts` file to its original state after modifications made during development deployments.
|
|
392
617
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
393
|
-
* @param {
|
|
618
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
394
619
|
* @memberof UnderpostRun
|
|
395
620
|
*/
|
|
396
621
|
'dev-hosts-restore': (path, options = DEFAULT_OPTION) => {
|
|
@@ -401,11 +626,13 @@ class UnderpostRun {
|
|
|
401
626
|
* @method cluster-build
|
|
402
627
|
* @description Build configuration for cluster deployment.
|
|
403
628
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
404
|
-
* @param {
|
|
629
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
405
630
|
* @memberof UnderpostRun
|
|
406
631
|
*/
|
|
407
632
|
'cluster-build': (path, options = DEFAULT_OPTION) => {
|
|
408
|
-
const nodeOptions =
|
|
633
|
+
const nodeOptions =
|
|
634
|
+
(options.nodeName ? ` --node-name ${options.nodeName}` : '') +
|
|
635
|
+
(options.sshKeyPath ? ` --ssh-key-path ${options.sshKeyPath}` : '');
|
|
409
636
|
shellExec(`node bin run clean`);
|
|
410
637
|
shellExec(`node bin run --dev sync-replica template-deploy${nodeOptions}`);
|
|
411
638
|
shellExec(`node bin run sync-replica template-deploy${nodeOptions}`);
|
|
@@ -423,7 +650,7 @@ class UnderpostRun {
|
|
|
423
650
|
* and optionally triggers engine-<conf-id> CI with sync/init which in turn dispatches the CD workflow
|
|
424
651
|
* after the build chain completes (template → ghpkg → engine-<conf-id> → CD).
|
|
425
652
|
* @param {string} path - The deployment path identifier (e.g., 'sync-engine-core', 'init-engine-core', or empty for build-only).
|
|
426
|
-
* @param {
|
|
653
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
427
654
|
* @memberof UnderpostRun
|
|
428
655
|
*/
|
|
429
656
|
'template-deploy': (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -437,13 +664,10 @@ class UnderpostRun {
|
|
|
437
664
|
shellExec(`${baseCommand} run pull`);
|
|
438
665
|
shellExec(`${baseCommand} run shared-dir`);
|
|
439
666
|
|
|
440
|
-
// Capture last N commit
|
|
441
|
-
//
|
|
442
|
-
const fromN =
|
|
443
|
-
|
|
444
|
-
? parseInt(options.fromNCommit)
|
|
445
|
-
: Underpost.repo.getUnpushedCount('.').count;
|
|
446
|
-
const message = shellExec(`node bin cmt --changelog ${fromN} --changelog-no-hash`, {
|
|
667
|
+
// Capture the sanitized message from the last N commits (--from-n-commit, default 1) for
|
|
668
|
+
// propagation to pwa-microservices-template and every engine-* repo.
|
|
669
|
+
const fromN = parseInt(options.fromNCommit) > 0 ? parseInt(options.fromNCommit) : 1;
|
|
670
|
+
const sanitizedMessage = shellExec(`node bin cmt --changelog-msg --from-n-commit ${fromN} --changelog-no-hash`, {
|
|
447
671
|
silent: true,
|
|
448
672
|
stdout: true,
|
|
449
673
|
}).trim();
|
|
@@ -455,8 +679,6 @@ class UnderpostRun {
|
|
|
455
679
|
);
|
|
456
680
|
shellCd('/home/dd/engine');
|
|
457
681
|
|
|
458
|
-
const sanitizedMessage = Underpost.repo.sanitizeChangelogMessage(message);
|
|
459
|
-
|
|
460
682
|
// Push engine repo so workflow YAML changes reach GitHub
|
|
461
683
|
shellExec(`git reset`);
|
|
462
684
|
shellExec(`${baseCommand} push . ${options.force ? '-f ' : ''}${process.env.GITHUB_USERNAME}/engine`);
|
|
@@ -504,7 +726,7 @@ class UnderpostRun {
|
|
|
504
726
|
* @method template-deploy-local
|
|
505
727
|
* @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.
|
|
506
728
|
* @param {string} path - The deployment path identifier (e.g., 'sync-engine-core', 'init-engine-core', or empty for build-only).
|
|
507
|
-
* @param {
|
|
729
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
508
730
|
* @memberof UnderpostRun
|
|
509
731
|
*/
|
|
510
732
|
'template-deploy-local': async (path, options = DEFAULT_OPTION) => {
|
|
@@ -518,17 +740,12 @@ class UnderpostRun {
|
|
|
518
740
|
shellExec(`${baseCommand} run pull`);
|
|
519
741
|
shellExec(`${baseCommand} run shared-dir`);
|
|
520
742
|
|
|
521
|
-
// Capture last N
|
|
522
|
-
|
|
523
|
-
const fromN
|
|
524
|
-
options.fromNCommit && parseInt(options.fromNCommit) > 0
|
|
525
|
-
? parseInt(options.fromNCommit)
|
|
526
|
-
: Underpost.repo.getUnpushedCount('.').count;
|
|
527
|
-
const rawMessage = shellExec(`node bin cmt --changelog ${fromN} --changelog-no-hash`, {
|
|
743
|
+
// Capture the sanitized message from the last N commits (--from-n-commit, default 1).
|
|
744
|
+
const fromN = parseInt(options.fromNCommit) > 0 ? parseInt(options.fromNCommit) : 1;
|
|
745
|
+
const sanitizedMessage = shellExec(`node bin cmt --changelog-msg --from-n-commit ${fromN} --changelog-no-hash`, {
|
|
528
746
|
silent: true,
|
|
529
747
|
stdout: true,
|
|
530
748
|
}).trim();
|
|
531
|
-
const sanitizedMessage = Underpost.repo.sanitizeChangelogMessage(rawMessage);
|
|
532
749
|
|
|
533
750
|
const { triggerCmd } = path
|
|
534
751
|
? await Underpost.release.ci(path, sanitizedMessage, options)
|
|
@@ -540,15 +757,14 @@ class UnderpostRun {
|
|
|
540
757
|
* @description Dispatches the Docker image CI workflow (`docker-image[.<runtime>].ci.yml`) via `workflow_dispatch`.
|
|
541
758
|
* Repository resolution is delegated to `Underpost.repo.resolveInstanceRepo(path)`.
|
|
542
759
|
* @param {string} path - Optional runtime / workflow suffix (e.g. `cyberia-server`, `cyberia-client`).
|
|
543
|
-
* @param {
|
|
760
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
544
761
|
* @memberof UnderpostRun
|
|
545
762
|
*/
|
|
546
763
|
'docker-image': (path, options = DEFAULT_OPTION) => {
|
|
547
|
-
const repo = Underpost.repo.resolveInstanceRepo(path);
|
|
764
|
+
const repo = Underpost.repo.resolveInstanceRepo(path, options.dev);
|
|
548
765
|
Underpost.repo.dispatchWorkflow({
|
|
549
766
|
repo,
|
|
550
|
-
workflowFile: `docker-image${path ? `.${path}` : ''}.ci.yml`,
|
|
551
|
-
ref: 'master',
|
|
767
|
+
workflowFile: `docker-image${path ? `.${path}` : ''}${options.dev ? '.dev' : ''}.ci.yml`,
|
|
552
768
|
inputs: {},
|
|
553
769
|
});
|
|
554
770
|
},
|
|
@@ -556,7 +772,7 @@ class UnderpostRun {
|
|
|
556
772
|
* @method clean
|
|
557
773
|
* @description Changes directory to the provided path (defaulting to `/home/dd/engine`) and runs `node bin/deploy clean-core-repo`.
|
|
558
774
|
* @param {string} path - The input value, identifier, or path for the operation (used as the optional directory path).
|
|
559
|
-
* @param {
|
|
775
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
560
776
|
* @memberof UnderpostRun
|
|
561
777
|
*/
|
|
562
778
|
clean: (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -567,7 +783,7 @@ class UnderpostRun {
|
|
|
567
783
|
* @method pull
|
|
568
784
|
* @description Clones or pulls updates for the `engine` and `engine-private` repositories into `/home/dd/engine` and `/home/dd/engine/engine-private`.
|
|
569
785
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
570
|
-
* @param {
|
|
786
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
571
787
|
* @memberof UnderpostRun
|
|
572
788
|
*/
|
|
573
789
|
pull: (path, options = DEFAULT_OPTION) => {
|
|
@@ -594,7 +810,7 @@ class UnderpostRun {
|
|
|
594
810
|
* @method release-deploy
|
|
595
811
|
* @description Executes deployment (`underpost run deploy`) for all deployment IDs listed in `./engine-private/deploy/dd.router`.
|
|
596
812
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
597
|
-
* @param {
|
|
813
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
598
814
|
* @memberof UnderpostRun
|
|
599
815
|
*/
|
|
600
816
|
'release-deploy': (path, options = DEFAULT_OPTION) => {
|
|
@@ -610,7 +826,7 @@ class UnderpostRun {
|
|
|
610
826
|
* @method ssh-deploy
|
|
611
827
|
* @description Dispatches the corresponding CD workflow for SSH-based deployment, replacing empty commits with workflow_dispatch.
|
|
612
828
|
* @param {string} path - The deployment identifier (e.g., 'engine-core', 'sync-engine-core', 'init-engine-core').
|
|
613
|
-
* @param {
|
|
829
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
614
830
|
* @memberof UnderpostRun
|
|
615
831
|
*/
|
|
616
832
|
'ssh-deploy': (path, options = DEFAULT_OPTION) => {
|
|
@@ -625,9 +841,9 @@ class UnderpostRun {
|
|
|
625
841
|
job = 'init';
|
|
626
842
|
confId = path.replace(/^init-/, '');
|
|
627
843
|
}
|
|
628
|
-
|
|
844
|
+
const repo = Underpost.repo.resolveInstanceRepo(confId, options.dev);
|
|
629
845
|
Underpost.repo.dispatchWorkflow({
|
|
630
|
-
repo
|
|
846
|
+
repo,
|
|
631
847
|
workflowFile: `${confId}.cd.yml`,
|
|
632
848
|
ref: 'master',
|
|
633
849
|
inputs: { job },
|
|
@@ -638,7 +854,7 @@ class UnderpostRun {
|
|
|
638
854
|
* @description Opens a Visual Studio Code (VS Code) session for the specified path using `node ${underpostRoot}/bin/zed ${path}`,
|
|
639
855
|
* or installs Zed and sublime-text IDE if `path` is 'install'.
|
|
640
856
|
* @param {string} path - The input value, identifier, or path for the operation (used as the path to the directory to open in the IDE).
|
|
641
|
-
* @param {
|
|
857
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
642
858
|
* @memberof UnderpostRun
|
|
643
859
|
*/
|
|
644
860
|
ide: (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -665,7 +881,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
665
881
|
* @method crypto-policy
|
|
666
882
|
* @description Sets the system's crypto policies to `DEFAULT:SHA1` using `update-crypto-policies` command.
|
|
667
883
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
668
|
-
* @param {
|
|
884
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
669
885
|
* @memberof UnderpostRun
|
|
670
886
|
*/
|
|
671
887
|
'crypto-policy': (path, options = DEFAULT_OPTION) => {
|
|
@@ -680,7 +896,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
680
896
|
* `deployment.yaml`. Useful when you want to force `Always` so the kubelet re-pulls a mutable tag on every rollout. Example:
|
|
681
897
|
* `node bin run sync dd-core --kubeadm --image-pull-policy Always`
|
|
682
898
|
* @param {string} path - The input value, identifier, or path for the operation (used as a comma-separated string containing deploy parameters).
|
|
683
|
-
* @param {
|
|
899
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
684
900
|
* @memberof UnderpostRun
|
|
685
901
|
*/
|
|
686
902
|
sync: async (path, options = DEFAULT_OPTION) => {
|
|
@@ -701,7 +917,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
701
917
|
replicas = replicas ? replicas : defaultPath[1];
|
|
702
918
|
versions = versions ? versions.replaceAll('+', ',') : defaultPath[2];
|
|
703
919
|
image = image ? image : defaultPath[3];
|
|
704
|
-
node = node ? node : defaultPath[4];
|
|
920
|
+
node = node ? node : options.nodeName ? options.nodeName : defaultPath[4];
|
|
705
921
|
shellExec(`${baseCommand} cluster --ns-use ${options.namespace}`);
|
|
706
922
|
|
|
707
923
|
if (image && !image.startsWith('localhost'))
|
|
@@ -742,13 +958,14 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
742
958
|
const skipFullBuildFlag = options.skipFullBuild ? ' --skip-full-build' : '';
|
|
743
959
|
const pullBundleFlag = options.pullBundle ? ' --pull-bundle' : '';
|
|
744
960
|
const imagePullPolicyFlag = options.imagePullPolicy ? ` --image-pull-policy ${options.imagePullPolicy}` : '';
|
|
961
|
+
const sshKeyPathFlag = options.sshKeyPath ? ` --ssh-key-path ${options.sshKeyPath}` : '';
|
|
745
962
|
|
|
746
963
|
shellExec(
|
|
747
964
|
`${baseCommand} deploy${clusterFlag} --build-manifest --sync --info-router --replicas ${replicas} --node ${node}${
|
|
748
965
|
image ? ` --image ${image}` : ''
|
|
749
966
|
}${versions ? ` --versions ${versions}` : ''}${
|
|
750
967
|
options.namespace ? ` --namespace ${options.namespace}` : ''
|
|
751
|
-
}${timeoutFlags}${cmdString}${gitCleanFlag}${skipFullBuildFlag}${pullBundleFlag}${imagePullPolicyFlag} ${deployId} ${env}`,
|
|
968
|
+
}${timeoutFlags}${cmdString}${gitCleanFlag}${skipFullBuildFlag}${pullBundleFlag}${imagePullPolicyFlag}${sshKeyPathFlag} ${deployId} ${env}`,
|
|
752
969
|
);
|
|
753
970
|
|
|
754
971
|
if (isDeployRunnerContext(path, options)) {
|
|
@@ -757,9 +974,9 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
757
974
|
`${baseCommand} db ${deployId} ${clusterFlag}${baseClusterCommand} --repo-backup --primary-pod --git --force-clone --preserveUUID ${options.namespace ? ` --ns ${options.namespace}` : ''}`,
|
|
758
975
|
);
|
|
759
976
|
shellExec(
|
|
760
|
-
`${baseCommand} deploy${clusterFlag}${cmdString} --replicas ${replicas} --disable-update-proxy ${deployId} ${env} --versions ${versions}${
|
|
977
|
+
`${baseCommand} deploy${clusterFlag}${cmdString} --replicas ${replicas} --node ${node} --disable-update-proxy ${deployId} ${env} --versions ${versions}${
|
|
761
978
|
options.namespace ? ` --namespace ${options.namespace}` : ''
|
|
762
|
-
}${timeoutFlags}${gitCleanFlag}${imagePullPolicyFlag}`,
|
|
979
|
+
}${timeoutFlags}${gitCleanFlag}${imagePullPolicyFlag}${sshKeyPathFlag}`,
|
|
763
980
|
);
|
|
764
981
|
if (!targetTraffic)
|
|
765
982
|
targetTraffic = Underpost.deploy.getCurrentTraffic(deployId, { namespace: options.namespace });
|
|
@@ -773,7 +990,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
773
990
|
* @method stop
|
|
774
991
|
* @description Stops a deployment by deleting the corresponding Kubernetes deployment and service resources.
|
|
775
992
|
* @param {string} path - The input value, identifier, or path for the operation (used to determine which traffic to stop).
|
|
776
|
-
* @param {
|
|
993
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
777
994
|
* @memberof UnderpostRun
|
|
778
995
|
*/
|
|
779
996
|
stop: async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -797,7 +1014,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
797
1014
|
* @method ssh-deploy-stop
|
|
798
1015
|
* @description Stops a remote deployment via SSH by executing the appropriate Underpost command on the remote server.
|
|
799
1016
|
* @param {string} path - The input value, identifier, or path for the operation (used to determine which traffic to stop).
|
|
800
|
-
* @param {
|
|
1017
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
801
1018
|
* @memberof UnderpostRun
|
|
802
1019
|
*/
|
|
803
1020
|
'ssh-deploy-stop': async (path, options = DEFAULT_OPTION) => {
|
|
@@ -824,7 +1041,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
824
1041
|
* @method ssh-deploy-db-rollback
|
|
825
1042
|
* @description Performs a database rollback on remote deployment via SSH.
|
|
826
1043
|
* @param {string} path - Comma-separated deployId and optional number of commits to reset (format: "deployId,nCommits")
|
|
827
|
-
* @param {
|
|
1044
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
828
1045
|
* @param {string} options.deployId - The deployment identifier
|
|
829
1046
|
* @param {string} options.user - The SSH user for credential lookup
|
|
830
1047
|
* @param {boolean} options.dev - Development mode flag
|
|
@@ -851,7 +1068,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
851
1068
|
* @method ssh-deploy-db
|
|
852
1069
|
* @description Imports/restores a database on remote deployment via SSH.
|
|
853
1070
|
* @param {string} path - The deployment ID for database import
|
|
854
|
-
* @param {
|
|
1071
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
855
1072
|
* @param {string} options.deployId - The deployment identifier
|
|
856
1073
|
* @param {string} options.user - The SSH user for credential lookup
|
|
857
1074
|
* @param {boolean} options.dev - Development mode flag
|
|
@@ -876,7 +1093,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
876
1093
|
* @method ssh-deploy-db-status
|
|
877
1094
|
* @description Retrieves database status/stats for a deployment (or all deployments from dd.router) via SSH.
|
|
878
1095
|
* @param {string} path - Comma-separated deployId(s) or 'dd' to use the dd.router list.
|
|
879
|
-
* @param {
|
|
1096
|
+
* @param {UnderpostRunDefaultOptions} options - Runner options (uses options.deployId for SSH host lookup).
|
|
880
1097
|
* @param {string} options.deployId - Deployment identifier used for SSH config lookup.
|
|
881
1098
|
* @param {string} options.user - SSH user for credential lookup.
|
|
882
1099
|
* @param {boolean} options.dev - Development mode flag.
|
|
@@ -922,7 +1139,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
922
1139
|
* @method tz
|
|
923
1140
|
* @description Sets the system timezone using `timedatectl set-timezone` command.
|
|
924
1141
|
* @param {string} path - The input value, identifier, or path for the operation (used as the timezone string).
|
|
925
|
-
* @param {
|
|
1142
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
926
1143
|
* @memberof UnderpostRun
|
|
927
1144
|
*/
|
|
928
1145
|
tz: (path, options = DEFAULT_OPTION) => {
|
|
@@ -943,7 +1160,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
943
1160
|
* @method get-proxy
|
|
944
1161
|
* @description Retrieves and logs the HTTPProxy resources in the specified namespace using `kubectl get HTTPProxy`.
|
|
945
1162
|
* @param {string} path - The input value, identifier, or path for the operation (used as an optional filter for the HTTPProxy resources).
|
|
946
|
-
* @param {
|
|
1163
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
947
1164
|
* @memberof UnderpostRun
|
|
948
1165
|
*/
|
|
949
1166
|
'get-proxy': async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -1050,7 +1267,7 @@ EOF
|
|
|
1050
1267
|
/**
|
|
1051
1268
|
* @method instance
|
|
1052
1269
|
* @param {string} path - The input value, identifier, or path for the operation (used as a comma-separated string containing workflow parameters).
|
|
1053
|
-
* @param {
|
|
1270
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1054
1271
|
* @memberof UnderpostRun
|
|
1055
1272
|
*/
|
|
1056
1273
|
instance: async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -1119,9 +1336,16 @@ EOF
|
|
|
1119
1336
|
deployId: _deployId,
|
|
1120
1337
|
env,
|
|
1121
1338
|
version: targetTraffic,
|
|
1122
|
-
nodeName:
|
|
1339
|
+
nodeName: Underpost.deploy.resolveDeployNode({
|
|
1340
|
+
node: options.nodeName,
|
|
1341
|
+
kind: options.kind,
|
|
1342
|
+
kubeadm: options.kubeadm,
|
|
1343
|
+
k3s: options.k3s,
|
|
1344
|
+
env,
|
|
1345
|
+
}),
|
|
1123
1346
|
clusterContext: options.k3s ? 'k3s' : options.kubeadm ? 'kubeadm' : 'kind',
|
|
1124
1347
|
gitClean: options.gitClean || false,
|
|
1348
|
+
sshKeyPath: options.sshKeyPath || '',
|
|
1125
1349
|
});
|
|
1126
1350
|
// Regenerate the parent deploy's gRPC ClusterIP service pointing to the
|
|
1127
1351
|
// parent's current traffic colour and apply it before the instance pod starts so
|
|
@@ -1215,12 +1439,39 @@ EOF
|
|
|
1215
1439
|
}
|
|
1216
1440
|
},
|
|
1217
1441
|
|
|
1442
|
+
/**
|
|
1443
|
+
* @method deploy-key
|
|
1444
|
+
* @description Copies the deploy key for a specific user and deployId to a temporary location on the local machine.
|
|
1445
|
+
* @param {string} path - The input value, identifier, or path for the operation (not used in this method).
|
|
1446
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1447
|
+
* @param {string} options.user - The user for which to copy the deploy key.
|
|
1448
|
+
* @param {string} options.deployId - The deployment identifier associated with the deploy key.
|
|
1449
|
+
* @memberof UnderpostRun
|
|
1450
|
+
*/
|
|
1451
|
+
'deploy-key': (path, options = DEFAULT_OPTION) => {
|
|
1452
|
+
const prefix = 'dd-key';
|
|
1453
|
+
if (options.reset) {
|
|
1454
|
+
shellExec(`rm -rf /home/dd/tmp/${prefix}_*`);
|
|
1455
|
+
return;
|
|
1456
|
+
}
|
|
1457
|
+
if (!options.user || !options.deployId) {
|
|
1458
|
+
logger.error('Both --user and --deploy-id options are required to copy the deploy key.');
|
|
1459
|
+
return;
|
|
1460
|
+
}
|
|
1461
|
+
const targetPath = `/home/dd/tmp/${prefix}_${s4()}${s4()}`;
|
|
1462
|
+
fs.mkdirSync('/home/dd/tmp', { recursive: true });
|
|
1463
|
+
fs.copyFileSync(`./engine-private/conf/${options.deployId}/users/${options.user}/id_rsa`, targetPath);
|
|
1464
|
+
logger.info(`Copied deploy key to ${targetPath}`);
|
|
1465
|
+
if (options.copy) pbcopy(targetPath);
|
|
1466
|
+
},
|
|
1467
|
+
|
|
1218
1468
|
/**
|
|
1219
1469
|
* @method instance-build-manifest
|
|
1220
1470
|
* @description Builds a Kubernetes Deployment + Service manifest for a specific instance entry
|
|
1221
|
-
* from `conf.instances.json` and writes it to a file.
|
|
1222
|
-
*
|
|
1223
|
-
*
|
|
1471
|
+
* from `conf.instances.json` and writes it to a file. This is a purely local
|
|
1472
|
+
* artifact generator: it never probes a live cluster. Traffic colour defaults
|
|
1473
|
+
* to the canonical initial `blue` and can be overridden with `--traffic`; the
|
|
1474
|
+
* real blue/green swap is resolved at deploy time (`deploy --sync`).
|
|
1224
1475
|
*
|
|
1225
1476
|
* If `--build` is supplied the image is built from the project Dockerfile and loaded into the
|
|
1226
1477
|
* cluster before the manifest is written (kind by default; `--kubeadm` / `--k3s` override).
|
|
@@ -1231,7 +1482,7 @@ EOF
|
|
|
1231
1482
|
* `<projectPath>/manifests/<env>/deployment.yaml`.
|
|
1232
1483
|
* In production, files are also copied to `<projectPath>/Dockerfile` and
|
|
1233
1484
|
* `<projectPath>/deployment.yaml`.
|
|
1234
|
-
* @param {
|
|
1485
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1235
1486
|
* @memberof UnderpostRun
|
|
1236
1487
|
*/
|
|
1237
1488
|
'instance-build-manifest': (path, options = DEFAULT_OPTION) => {
|
|
@@ -1310,7 +1561,7 @@ EOF
|
|
|
1310
1561
|
path: projectPath,
|
|
1311
1562
|
imageName: _image,
|
|
1312
1563
|
podmanSave: true,
|
|
1313
|
-
|
|
1564
|
+
imageOutPath: projectPath,
|
|
1314
1565
|
kind: isKind,
|
|
1315
1566
|
kubeadm: !!options.kubeadm,
|
|
1316
1567
|
k3s: !!options.k3s,
|
|
@@ -1323,15 +1574,8 @@ EOF
|
|
|
1323
1574
|
});
|
|
1324
1575
|
}
|
|
1325
1576
|
|
|
1326
|
-
|
|
1327
|
-
const
|
|
1328
|
-
hostTest: _host,
|
|
1329
|
-
namespace: options.namespace,
|
|
1330
|
-
});
|
|
1331
|
-
const targetTraffic = currentTraffic ? (currentTraffic === 'blue' ? 'green' : 'blue') : 'blue';
|
|
1332
|
-
|
|
1333
|
-
// Resolve {{grpc-service-dns}} using the parent deploy's current (or default) traffic.
|
|
1334
|
-
const parentTraffic = Underpost.deploy.getCurrentTraffic(deployId, { namespace: options.namespace }) || 'blue';
|
|
1577
|
+
const targetTraffic = options.traffic || 'blue';
|
|
1578
|
+
const parentTraffic = targetTraffic;
|
|
1335
1579
|
const resolvedCmd = _cmd[env].map((c) =>
|
|
1336
1580
|
c.replaceAll(
|
|
1337
1581
|
'{{grpc-service-dns}}',
|
|
@@ -1379,11 +1623,86 @@ EOF
|
|
|
1379
1623
|
image: _image,
|
|
1380
1624
|
});
|
|
1381
1625
|
|
|
1626
|
+
// --- Sibling manifests (pv-pvc, proxy, grpc-service) ------------------
|
|
1627
|
+
// Emit the same apply-able set the parent deploy writes to build/<env>,
|
|
1628
|
+
// scoped to this instance so the project repo and engine-private ship
|
|
1629
|
+
// more than just deployment.yaml. Content matches what `run instance`
|
|
1630
|
+
// creates dynamically at deploy time (deployVolume / instance-promote /
|
|
1631
|
+
// the parent gRPC ClusterIP), so a static `kubectl apply` is equivalent.
|
|
1632
|
+
const pvDataNode = Underpost.deploy.resolveDeployNode({
|
|
1633
|
+
node: options.nodeName,
|
|
1634
|
+
kind: options.kind,
|
|
1635
|
+
kubeadm: options.kubeadm,
|
|
1636
|
+
k3s: options.k3s,
|
|
1637
|
+
env,
|
|
1638
|
+
});
|
|
1639
|
+
|
|
1640
|
+
// pv-pvc.yaml — one PV+PVC per instance volume; names mirror deployVolume.
|
|
1641
|
+
let pvPvcYaml = '';
|
|
1642
|
+
for (const volume of _volumes || []) {
|
|
1643
|
+
if (!volume.claimName) continue;
|
|
1644
|
+
const pvcId = `${volume.claimName}-${_deployId}-${env}-${targetTraffic}`;
|
|
1645
|
+
const pvId = `${volume.claimName.replace('pvc-', 'pv-')}-${_deployId}-${env}-${targetTraffic}`;
|
|
1646
|
+
pvPvcYaml += `---\n${Underpost.deploy.persistentVolumeFactory({
|
|
1647
|
+
pvcId,
|
|
1648
|
+
namespace: options.namespace,
|
|
1649
|
+
hostPath: `/home/dd/engine/volume/${pvId}`,
|
|
1650
|
+
nodeName: pvDataNode,
|
|
1651
|
+
})}\n`;
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
// proxy.yaml — HTTPProxy for the instance host (mirrors instance-promote).
|
|
1655
|
+
const proxyYaml =
|
|
1656
|
+
Underpost.deploy.baseProxyYamlFactory({ host: _host, env, options }) +
|
|
1657
|
+
Underpost.deploy.deploymentYamlServiceFactory({
|
|
1658
|
+
path: _path,
|
|
1659
|
+
port: _fromPort,
|
|
1660
|
+
deployId: _deployId,
|
|
1661
|
+
env,
|
|
1662
|
+
deploymentVersions: [targetTraffic],
|
|
1663
|
+
});
|
|
1664
|
+
|
|
1665
|
+
// grpc-service.yaml — the parent deploy's gRPC ClusterIP (shared; the
|
|
1666
|
+
// instance cmd resolves {{grpc-service-dns}} to it). Reuse the parent's
|
|
1667
|
+
// generated manifest when present rather than regenerating it here.
|
|
1668
|
+
const parentGrpcServicePath = `./engine-private/conf/${deployId}/build/${env}/grpc-service.yaml`;
|
|
1669
|
+
const grpcServiceYaml = fs.existsSync(parentGrpcServicePath)
|
|
1670
|
+
? fs.readFileSync(parentGrpcServicePath, 'utf8')
|
|
1671
|
+
: '';
|
|
1672
|
+
|
|
1673
|
+
// Write the sibling set next to deployment.yaml (project) and into the
|
|
1674
|
+
// engine-private per-instance build dir (mirrors instances/<id>/ layout).
|
|
1675
|
+
const instanceBuildDir = `./engine-private/conf/${deployId}/instances/${_id}/build/${env}`;
|
|
1676
|
+
fs.mkdirpSync(instanceBuildDir);
|
|
1677
|
+
fs.writeFileSync(`${instanceBuildDir}/deployment.yaml`, deploymentYaml, 'utf8');
|
|
1678
|
+
const siblingManifests = {
|
|
1679
|
+
'pv-pvc.yaml': pvPvcYaml,
|
|
1680
|
+
'proxy.yaml': proxyYaml,
|
|
1681
|
+
'grpc-service.yaml': grpcServiceYaml,
|
|
1682
|
+
};
|
|
1683
|
+
for (const [name, content] of Object.entries(siblingManifests)) {
|
|
1684
|
+
if (!content) continue;
|
|
1685
|
+
fs.writeFileSync(`${envManifestPath}/${name}`, content, 'utf8');
|
|
1686
|
+
fs.writeFileSync(`${instanceBuildDir}/${name}`, content, 'utf8');
|
|
1687
|
+
}
|
|
1688
|
+
logger.info('[instance-build-manifest] Sibling manifests written', {
|
|
1689
|
+
project: envManifestPath,
|
|
1690
|
+
enginePrivate: instanceBuildDir,
|
|
1691
|
+
pvPvc: !!pvPvcYaml,
|
|
1692
|
+
proxy: !!proxyYaml,
|
|
1693
|
+
grpcService: !!grpcServiceYaml,
|
|
1694
|
+
});
|
|
1695
|
+
|
|
1382
1696
|
if (env === 'production') {
|
|
1383
1697
|
if (fs.existsSync(dockerfileManifestPath)) {
|
|
1384
1698
|
fs.copyFileSync(dockerfileManifestPath, `${rootPath}/Dockerfile`);
|
|
1385
1699
|
}
|
|
1386
1700
|
fs.copyFileSync(outputPath, `${rootPath}/deployment.yaml`);
|
|
1701
|
+
// Sibling manifests alongside deployment.yaml at the project root.
|
|
1702
|
+
for (const name of ['pv-pvc.yaml', 'proxy.yaml', 'grpc-service.yaml']) {
|
|
1703
|
+
const src = `${envManifestPath}/${name}`;
|
|
1704
|
+
if (fs.existsSync(src)) fs.copyFileSync(src, `${rootPath}/${name}`);
|
|
1705
|
+
}
|
|
1387
1706
|
logger.info('[instance-build-manifest] Production artifacts copied to project root', {
|
|
1388
1707
|
rootPath,
|
|
1389
1708
|
dockerfile: `${rootPath}/Dockerfile`,
|
|
@@ -1395,6 +1714,25 @@ EOF
|
|
|
1395
1714
|
fs.copyFileSync(ciSrc, `${rootPath}/.github/workflows/docker-image.${_runtime}.ci.yml`);
|
|
1396
1715
|
logger.info(`[instance-build-manifest] CI workflow copied`, { src: ciSrc });
|
|
1397
1716
|
}
|
|
1717
|
+
|
|
1718
|
+
// Ship the development variant alongside production so the instance repo
|
|
1719
|
+
// is self-contained: the dev Dockerfile (built by the -dev CI workflow
|
|
1720
|
+
// into underpost/<runtime>-dev, consumed by the development compose
|
|
1721
|
+
// stack) and its dispatchable workflow. Both are optional — synced only
|
|
1722
|
+
// when the source-of-truth files exist in the engine repo.
|
|
1723
|
+
if (_runtime) {
|
|
1724
|
+
const devDockerfileSrc = `src/runtime/${_runtime}/Dockerfile.dev`;
|
|
1725
|
+
if (fs.existsSync(devDockerfileSrc)) {
|
|
1726
|
+
fs.copyFileSync(devDockerfileSrc, `${rootPath}/Dockerfile.dev`);
|
|
1727
|
+
logger.info('[instance-build-manifest] Dev Dockerfile copied', { src: devDockerfileSrc });
|
|
1728
|
+
}
|
|
1729
|
+
const devCiSrc = `./.github/workflows/docker-image.${_runtime}.dev.ci.yml`;
|
|
1730
|
+
if (fs.existsSync(devCiSrc)) {
|
|
1731
|
+
if (!fs.existsSync(`${rootPath}/.github/workflows`)) fs.mkdirpSync(`${rootPath}/.github/workflows`);
|
|
1732
|
+
fs.copyFileSync(devCiSrc, `${rootPath}/.github/workflows/docker-image.${_runtime}.dev.ci.yml`);
|
|
1733
|
+
logger.info(`[instance-build-manifest] Dev CI workflow copied`, { src: devCiSrc });
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1398
1736
|
}
|
|
1399
1737
|
},
|
|
1400
1738
|
|
|
@@ -1402,7 +1740,7 @@ EOF
|
|
|
1402
1740
|
* @method ls-deployments
|
|
1403
1741
|
* @description Retrieves and logs a table of Kubernetes deployments using `Underpost.deploy.get`.
|
|
1404
1742
|
* @param {string} path - The input value, identifier, or path for the operation (used as an optional deployment name filter).
|
|
1405
|
-
* @param {
|
|
1743
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1406
1744
|
* @memberof UnderpostRun
|
|
1407
1745
|
*/
|
|
1408
1746
|
'ls-deployments': async (path, options = DEFAULT_OPTION) => {
|
|
@@ -1413,7 +1751,7 @@ EOF
|
|
|
1413
1751
|
* @method host-update
|
|
1414
1752
|
* @description Executes the `rocky-setup.sh` script to update the host system configuration.
|
|
1415
1753
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
1416
|
-
* @param {
|
|
1754
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1417
1755
|
* @memberof UnderpostRun
|
|
1418
1756
|
*/
|
|
1419
1757
|
'host-update': async (path, options = DEFAULT_OPTION) => {
|
|
@@ -1429,7 +1767,7 @@ EOF
|
|
|
1429
1767
|
* the systemd cgroup driver, enables the `crio` service, and writes `/etc/crictl.yaml`
|
|
1430
1768
|
* so that `crictl` targets the CRI-O socket by default.
|
|
1431
1769
|
* @param {string} path - Unused.
|
|
1432
|
-
* @param {
|
|
1770
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow.
|
|
1433
1771
|
* @memberof UnderpostRun
|
|
1434
1772
|
*/
|
|
1435
1773
|
'install-crio': (path, options = DEFAULT_OPTION) => {
|
|
@@ -1443,8 +1781,24 @@ gpgcheck=1
|
|
|
1443
1781
|
gpgkey=https://download.opensuse.org/repositories/isv:/cri-o:/stable:/v1.33/rpm/repodata/repomd.xml.key
|
|
1444
1782
|
EOF`);
|
|
1445
1783
|
shellExec(`sudo dnf -y install cri-o`);
|
|
1446
|
-
//
|
|
1447
|
-
|
|
1784
|
+
// Add the Kubernetes repo so cri-tools (crictl CLI) is available.
|
|
1785
|
+
// The repo has exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni, so we
|
|
1786
|
+
// use --disableexcludes=kubernetes to override and install cri-tools.
|
|
1787
|
+
shellExec(`cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
|
|
1788
|
+
[kubernetes]
|
|
1789
|
+
name=Kubernetes
|
|
1790
|
+
baseurl=https://pkgs.k8s.io/core:/stable:/v1.36/rpm/
|
|
1791
|
+
enabled=1
|
|
1792
|
+
gpgcheck=1
|
|
1793
|
+
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.36/rpm/repodata/repomd.xml.key
|
|
1794
|
+
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
|
|
1795
|
+
EOF`);
|
|
1796
|
+
shellExec(`sudo yum install -y cri-tools --disableexcludes=kubernetes 2>/dev/null || {
|
|
1797
|
+
CRICTL_VERSION="v1.31.0"
|
|
1798
|
+
ARCH="amd64"
|
|
1799
|
+
log "Kubernetes repo not available, downloading crictl binary directly..."
|
|
1800
|
+
curl -sL "https://github.com/kubernetes-sigs/cri-tools/releases/download/\${CRICTL_VERSION}/crictl-\${CRICTL_VERSION}-\${ARCH}.tar.gz" | sudo tar -C /usr/local/bin -xz
|
|
1801
|
+
}`);
|
|
1448
1802
|
// Ensure CRI-O uses systemd cgroup driver (matches kubelet default)
|
|
1449
1803
|
shellExec(`sudo sed -i 's/^#\?cgroup_manager =.*/cgroup_manager = "systemd"/' /etc/crio/crio.conf`, {
|
|
1450
1804
|
silentOnError: true,
|
|
@@ -1464,7 +1818,7 @@ EOF`);
|
|
|
1464
1818
|
* @method dd-container
|
|
1465
1819
|
* @description Deploys a development or debug container tasks jobs, setting up necessary volumes and images, and running specified commands within the container.
|
|
1466
1820
|
* @param {string} path - The input value, identifier, or path for the operation (used as the command to run inside the container).
|
|
1467
|
-
* @param {
|
|
1821
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1468
1822
|
* @memberof UnderpostRun
|
|
1469
1823
|
*/
|
|
1470
1824
|
'dd-container': async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -1491,7 +1845,11 @@ EOF`);
|
|
|
1491
1845
|
}
|
|
1492
1846
|
|
|
1493
1847
|
if (!currentImage)
|
|
1494
|
-
shellExec(
|
|
1848
|
+
shellExec(
|
|
1849
|
+
`${baseCommand} image${baseClusterCommand} --pull-base --build --path ${
|
|
1850
|
+
options.dev ? '.' : options.underpostRoot
|
|
1851
|
+
} ${options.dev ? '--kind' : '--kubeadm'}`,
|
|
1852
|
+
);
|
|
1495
1853
|
// shellExec(`kubectl delete pod ${podName} --ignore-not-found`);
|
|
1496
1854
|
|
|
1497
1855
|
const payload = {
|
|
@@ -1519,7 +1877,7 @@ EOF`);
|
|
|
1519
1877
|
* @method ip-info
|
|
1520
1878
|
* @description Executes the `ip-info.sh` script to display IP-related information for the specified path.
|
|
1521
1879
|
* @param {string} path - The input value, identifier, or path for the operation (used as an argument to the script).
|
|
1522
|
-
* @param {
|
|
1880
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1523
1881
|
* @memberof UnderpostRun
|
|
1524
1882
|
*/
|
|
1525
1883
|
'ip-info': (path, options = DEFAULT_OPTION) => {
|
|
@@ -1532,7 +1890,7 @@ EOF`);
|
|
|
1532
1890
|
* @method db-client
|
|
1533
1891
|
* @description Deploys and exposes the Adminer database client application (using `adminer:4.7.6-standalone` image) on the cluster.
|
|
1534
1892
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
1535
|
-
* @param {
|
|
1893
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1536
1894
|
* @memberof UnderpostRun
|
|
1537
1895
|
*/
|
|
1538
1896
|
'db-client': async (path, options = DEFAULT_OPTION) => {
|
|
@@ -1559,7 +1917,7 @@ EOF`);
|
|
|
1559
1917
|
* @method git-conf
|
|
1560
1918
|
* @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.
|
|
1561
1919
|
* @param {string} path - The input value, identifier, or path for the operation (used as a comma-separated string: `username,email`).
|
|
1562
|
-
* @param {
|
|
1920
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1563
1921
|
* @memberof UnderpostRun
|
|
1564
1922
|
*/
|
|
1565
1923
|
'git-conf': (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -1607,7 +1965,7 @@ EOF`);
|
|
|
1607
1965
|
* TLS config, deletes stale Certificate resources, then reapplies the proxy and secret.yaml
|
|
1608
1966
|
* (cert-manager Certificate resources) for each affected deployment.
|
|
1609
1967
|
* @param {string} path - The input value, identifier, or path for the operation (used as a comma-separated string: `deployId,env,replicas`).
|
|
1610
|
-
* @param {
|
|
1968
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1611
1969
|
* @memberof UnderpostRun
|
|
1612
1970
|
*/
|
|
1613
1971
|
promote: async (path, options = DEFAULT_OPTION) => {
|
|
@@ -1661,10 +2019,31 @@ EOF`);
|
|
|
1661
2019
|
* @method metrics
|
|
1662
2020
|
* @description Deploys Prometheus and Grafana for metrics monitoring, targeting the hosts defined in the deployment configuration files.
|
|
1663
2021
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
1664
|
-
* @param {
|
|
2022
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1665
2023
|
* @memberof UnderpostRun
|
|
1666
2024
|
*/
|
|
1667
2025
|
metrics: async (path, options = DEFAULT_OPTION) => {
|
|
2026
|
+
if (path === 'server') {
|
|
2027
|
+
shellExec(
|
|
2028
|
+
`kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/high-availability-1.21+.yaml`,
|
|
2029
|
+
);
|
|
2030
|
+
await timer(2000);
|
|
2031
|
+
|
|
2032
|
+
shellExec(`kubectl patch deployment metrics-server -n kube-system \
|
|
2033
|
+
--type='json' \
|
|
2034
|
+
-p='[
|
|
2035
|
+
{
|
|
2036
|
+
"op":"add",
|
|
2037
|
+
"path":"/spec/template/spec/containers/0/args/-",
|
|
2038
|
+
"value":"--kubelet-insecure-tls"
|
|
2039
|
+
}
|
|
2040
|
+
]'`);
|
|
2041
|
+
shellExec(`kubectl scale deployment metrics-server \
|
|
2042
|
+
-n kube-system \
|
|
2043
|
+
--replicas=1`);
|
|
2044
|
+
|
|
2045
|
+
return;
|
|
2046
|
+
}
|
|
1668
2047
|
const deployList = fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8').split(',');
|
|
1669
2048
|
let hosts = [];
|
|
1670
2049
|
for (const deployId of deployList) {
|
|
@@ -1678,7 +2057,7 @@ EOF`);
|
|
|
1678
2057
|
* @method cluster
|
|
1679
2058
|
* @description Deploys a full production/development ready Kubernetes cluster environment including MongoDB, MariaDB, Valkey, Contour (Ingress), and Cert-Manager, and deploys all services.
|
|
1680
2059
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
1681
|
-
* @param {
|
|
2060
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1682
2061
|
* @memberof UnderpostRun
|
|
1683
2062
|
*/
|
|
1684
2063
|
cluster: async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -1740,7 +2119,7 @@ EOF`);
|
|
|
1740
2119
|
* @method deploy
|
|
1741
2120
|
* @description Deploys a specified service (identified by `path`) using blue/green strategy, monitors its status, and switches traffic upon readiness.
|
|
1742
2121
|
* @param {string} path - The input value, identifier, or path for the operation (used as the deployment ID to deploy).
|
|
1743
|
-
* @param {
|
|
2122
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1744
2123
|
* @memberof UnderpostRun
|
|
1745
2124
|
*/
|
|
1746
2125
|
deploy: async (path, options = DEFAULT_OPTION) => {
|
|
@@ -1765,7 +2144,7 @@ EOF`);
|
|
|
1765
2144
|
* @method disk-clean
|
|
1766
2145
|
* @description Executes the `disk-clean-sh` script to perform disk cleanup operations.
|
|
1767
2146
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
1768
|
-
* @param {
|
|
2147
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1769
2148
|
* @memberof UnderpostRun
|
|
1770
2149
|
*/
|
|
1771
2150
|
'disk-clean': async (path, options = DEFAULT_OPTION) => {
|
|
@@ -1778,7 +2157,7 @@ EOF`);
|
|
|
1778
2157
|
* @method disk-devices
|
|
1779
2158
|
* @description Executes the `disk-devices.sh` script to display information about disk devices.
|
|
1780
2159
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
1781
|
-
* @param {
|
|
2160
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1782
2161
|
* @memberof UnderpostRun
|
|
1783
2162
|
*/
|
|
1784
2163
|
'disk-devices': async (path = '/', options = DEFAULT_OPTION) => {
|
|
@@ -1791,7 +2170,7 @@ EOF`);
|
|
|
1791
2170
|
* @method disk-usage
|
|
1792
2171
|
* @description Displays disk usage statistics using the `du` command, sorted by size.
|
|
1793
2172
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
1794
|
-
* @param {
|
|
2173
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1795
2174
|
* @memberof UnderpostRun
|
|
1796
2175
|
*/
|
|
1797
2176
|
'disk-usage': async (path = '/', options = DEFAULT_OPTION) => {
|
|
@@ -1806,7 +2185,7 @@ EOF`);
|
|
|
1806
2185
|
* @method dev
|
|
1807
2186
|
* @description Starts development servers for client, API, and proxy based on provided parameters (deployId, host, path, clientHostPort).
|
|
1808
2187
|
* @param {string} path - The input value, identifier, or path for the operation (formatted as `deployId,subConf,host,path,clientHostPort`).
|
|
1809
|
-
* @param {
|
|
2188
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1810
2189
|
* @memberof UnderpostRun
|
|
1811
2190
|
*/
|
|
1812
2191
|
dev: async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -1866,7 +2245,7 @@ EOF`);
|
|
|
1866
2245
|
* @method service
|
|
1867
2246
|
* @description Deploys and exposes specific services (like `mongo-express-service`) on the cluster, updating deployment configurations and monitoring status.
|
|
1868
2247
|
* @param {string} path - The input value, identifier, or path for the operation (formatted as `deployId,serviceId,host,path,replicas,image,node`).
|
|
1869
|
-
* @param {
|
|
2248
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1870
2249
|
* @memberof UnderpostRun
|
|
1871
2250
|
*/
|
|
1872
2251
|
service: async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -1962,7 +2341,7 @@ EOF`);
|
|
|
1962
2341
|
* @method etc-hosts
|
|
1963
2342
|
* @description Generates and logs the contents for the `/etc/hosts` file based on provided hosts or deployment configurations.
|
|
1964
2343
|
* @param {string} path - The input value, identifier, or path for the operation (used as a comma-separated list of hosts).
|
|
1965
|
-
* @param {
|
|
2344
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1966
2345
|
* @memberof UnderpostRun
|
|
1967
2346
|
*/
|
|
1968
2347
|
'etc-hosts': async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -1979,7 +2358,7 @@ EOF`);
|
|
|
1979
2358
|
* @method sh
|
|
1980
2359
|
* @description Enables remote control for the Kitty terminal emulator.
|
|
1981
2360
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
1982
|
-
* @param {
|
|
2361
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
1983
2362
|
* @memberof UnderpostRun
|
|
1984
2363
|
*/
|
|
1985
2364
|
sh: async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -1999,7 +2378,7 @@ EOF`);
|
|
|
1999
2378
|
* @method log
|
|
2000
2379
|
* @description Searches and highlights keywords in a specified log file, optionally showing surrounding lines.
|
|
2001
2380
|
* @param {string} path - The input value, identifier, or path for the operation (formatted as `filePath,keywords,lines`).
|
|
2002
|
-
* @param {
|
|
2381
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2003
2382
|
* @memberof UnderpostRun
|
|
2004
2383
|
*/
|
|
2005
2384
|
log: async (path, options = DEFAULT_OPTION) => {
|
|
@@ -2016,7 +2395,7 @@ EOF`);
|
|
|
2016
2395
|
* @method ps
|
|
2017
2396
|
* @description Displays running processes that match a specified path or keyword.
|
|
2018
2397
|
* @param {string} path - The input value, identifier, or path for the operation (used as a keyword to filter processes).
|
|
2019
|
-
* @param {
|
|
2398
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2020
2399
|
* @memberof UnderpostRun
|
|
2021
2400
|
*/
|
|
2022
2401
|
ps: async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -2041,7 +2420,7 @@ EOF`);
|
|
|
2041
2420
|
* @method pid-info
|
|
2042
2421
|
* @description Displays detailed information about a process by PID, including service details, command line, executable path, working directory, environment variables, and parent process tree.
|
|
2043
2422
|
* @param {string} path - The PID of the process to inspect.
|
|
2044
|
-
* @param {
|
|
2423
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2045
2424
|
* @memberof UnderpostRun
|
|
2046
2425
|
*/
|
|
2047
2426
|
'pid-info': (path, options = DEFAULT_OPTION) => {
|
|
@@ -2081,7 +2460,7 @@ EOF`);
|
|
|
2081
2460
|
* @method background
|
|
2082
2461
|
* @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`.
|
|
2083
2462
|
* @param {string} path - The command to run in the background (e.g. 'npm run prod:container dd-cyberia-r3').
|
|
2084
|
-
* @param {
|
|
2463
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2085
2464
|
* @memberof UnderpostRun
|
|
2086
2465
|
*/
|
|
2087
2466
|
background: (path, options = DEFAULT_OPTION) => {
|
|
@@ -2101,7 +2480,7 @@ EOF`);
|
|
|
2101
2480
|
* @method ports
|
|
2102
2481
|
* @description Set on ~/.bashrc alias: ports <port> Command to list listening ports that match the given keyword.
|
|
2103
2482
|
* @param {string} path - The input value, identifier, or path for the operation (used as a keyword to filter listening ports).
|
|
2104
|
-
* @param {
|
|
2483
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2105
2484
|
* @memberof UnderpostRun
|
|
2106
2485
|
*/
|
|
2107
2486
|
ports: async (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -2113,7 +2492,7 @@ EOF`);
|
|
|
2113
2492
|
* @method deploy-test
|
|
2114
2493
|
* @description Deploys a test deployment (`dd-test`) in either development or production mode, setting up necessary secrets and starting the deployment.
|
|
2115
2494
|
* @param {string} path - The input value, identifier, or path for the operation (used as the deployment ID).
|
|
2116
|
-
* @param {
|
|
2495
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2117
2496
|
* @memberof UnderpostRun
|
|
2118
2497
|
*/
|
|
2119
2498
|
'deploy-test': async (path, options = DEFAULT_OPTION) => {
|
|
@@ -2138,7 +2517,7 @@ EOF`);
|
|
|
2138
2517
|
* @method tf-vae-test
|
|
2139
2518
|
* @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.
|
|
2140
2519
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
2141
|
-
* @param {
|
|
2520
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2142
2521
|
* @memberof UnderpostRun
|
|
2143
2522
|
*/
|
|
2144
2523
|
'tf-vae-test': async (path, options = DEFAULT_OPTION) => {
|
|
@@ -2238,7 +2617,7 @@ EOF`);
|
|
|
2238
2617
|
* @method spark-template
|
|
2239
2618
|
* @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`.
|
|
2240
2619
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
2241
|
-
* @param {
|
|
2620
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2242
2621
|
* @memberof UnderpostRun
|
|
2243
2622
|
*/
|
|
2244
2623
|
'spark-template': (path, options = DEFAULT_OPTION) => {
|
|
@@ -2266,7 +2645,7 @@ EOF`);
|
|
|
2266
2645
|
* @method pull-rocky-image
|
|
2267
2646
|
* @description Pulls the base `rockylinux:9` image from Docker Hub via Podman.
|
|
2268
2647
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
2269
|
-
* @param {
|
|
2648
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2270
2649
|
* @memberof UnderpostRun
|
|
2271
2650
|
*/
|
|
2272
2651
|
'pull-rocky-image': (path, options = DEFAULT_OPTION) => {
|
|
@@ -2276,7 +2655,7 @@ EOF`);
|
|
|
2276
2655
|
* @method rmi
|
|
2277
2656
|
* @description Forces the removal of all local Podman images (`podman rmi $(podman images -qa) --force`).
|
|
2278
2657
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
2279
|
-
* @param {
|
|
2658
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2280
2659
|
* @memberof UnderpostRun
|
|
2281
2660
|
*/
|
|
2282
2661
|
rmi: (path, options = DEFAULT_OPTION) => {
|
|
@@ -2286,7 +2665,7 @@ EOF`);
|
|
|
2286
2665
|
* @method kill
|
|
2287
2666
|
* @description Kills processes listening on the specified port(s). If the `path` contains a `+`, it treats it as a range of ports to kill.
|
|
2288
2667
|
* @param {string} path - The input value, identifier, or path for the operation (used as the port number).
|
|
2289
|
-
* @param {
|
|
2668
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2290
2669
|
* @memberof UnderpostRun
|
|
2291
2670
|
*/
|
|
2292
2671
|
kill: (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -2318,7 +2697,7 @@ EOF`);
|
|
|
2318
2697
|
* constraints (lowercase, uppercase, digit, special char, min 8 chars). Logs the plain password
|
|
2319
2698
|
* to the console or, when `--copy` is set, copies it to the clipboard via pbcopy.
|
|
2320
2699
|
* @param {string} path - Optional password length (default: 16).
|
|
2321
|
-
* @param {
|
|
2700
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow.
|
|
2322
2701
|
* @param {boolean} options.copy - When true, copies to clipboard instead of logging.
|
|
2323
2702
|
* @memberof UnderpostRun
|
|
2324
2703
|
*/
|
|
@@ -2352,7 +2731,7 @@ EOF`);
|
|
|
2352
2731
|
* @method secret
|
|
2353
2732
|
* @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.
|
|
2354
2733
|
* @param {string} path - The input value, identifier, or path for the operation (used as the optional path to the secret file).
|
|
2355
|
-
* @param {
|
|
2734
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2356
2735
|
* @memberof UnderpostRun
|
|
2357
2736
|
*/
|
|
2358
2737
|
secret: (path, options = DEFAULT_OPTION) => {
|
|
@@ -2365,7 +2744,7 @@ EOF`);
|
|
|
2365
2744
|
* @method underpost-config
|
|
2366
2745
|
* @description Calls `Underpost.deploy.configMap` to create a Kubernetes ConfigMap, defaulting to the 'production' environment.
|
|
2367
2746
|
* @param {string} path - The input value, identifier, or path for the operation (used as the optional configuration name/environment).
|
|
2368
|
-
* @param {
|
|
2747
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2369
2748
|
* @memberof UnderpostRun
|
|
2370
2749
|
*/
|
|
2371
2750
|
'underpost-config': (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -2375,7 +2754,7 @@ EOF`);
|
|
|
2375
2754
|
* @method gpu-env
|
|
2376
2755
|
* @description Sets up a dedicated GPU development environment cluster, resetting and then setting up the cluster with `--dedicated-gpu` and monitoring the pods.
|
|
2377
2756
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
2378
|
-
* @param {
|
|
2757
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2379
2758
|
* @memberof UnderpostRun
|
|
2380
2759
|
*/
|
|
2381
2760
|
'gpu-env': (path, options = DEFAULT_OPTION) => {
|
|
@@ -2388,7 +2767,7 @@ EOF`);
|
|
|
2388
2767
|
* @method tf-gpu-test
|
|
2389
2768
|
* @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`.
|
|
2390
2769
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
2391
|
-
* @param {
|
|
2770
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2392
2771
|
* @memberof UnderpostRun
|
|
2393
2772
|
*/
|
|
2394
2773
|
'tf-gpu-test': (path, options = DEFAULT_OPTION) => {
|
|
@@ -2402,7 +2781,7 @@ EOF`);
|
|
|
2402
2781
|
* @method deploy-job
|
|
2403
2782
|
* @description Creates and applies a custom Kubernetes Pod manifest (Job) for running arbitrary commands inside a container image (defaulting to a TensorFlow/NVIDIA image).
|
|
2404
2783
|
* @param {string} path - The input value, identifier, or path for the operation (used as the optional script path or job argument).
|
|
2405
|
-
* @param {
|
|
2784
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2406
2785
|
* @memberof UnderpostRun
|
|
2407
2786
|
*/
|
|
2408
2787
|
'deploy-job': async (path, options = DEFAULT_OPTION) => {
|
|
@@ -2537,7 +2916,7 @@ EOF`;
|
|
|
2537
2916
|
* Only files matching `<host>-<route>.zip.part*` or `<host>-<route>.zip` for each non-skipped route are uploaded.
|
|
2538
2917
|
* @param {string} path - Optional `fsPath.splitOption` string.
|
|
2539
2918
|
* Examples: `build` (default split 8), `build.16` (split 16 MB), `build.none-split` (no split flag).
|
|
2540
|
-
* @param {
|
|
2919
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow.
|
|
2541
2920
|
* @param {string} [options.deployId] - Override deploy ID.
|
|
2542
2921
|
* @param {boolean} [options.dev] - Use development environment; defaults to production.
|
|
2543
2922
|
* @memberof UnderpostRun
|
|
@@ -2625,7 +3004,7 @@ EOF`;
|
|
|
2625
3004
|
* so that multi-path deployments are handled correctly.
|
|
2626
3005
|
* @param {string} path - Optional comma-separated host name(s) to restrict processing (e.g. 'underpost.net' or 'a.com,b.com').
|
|
2627
3006
|
* If omitted, all hosts from `engine-private/conf/<deployId>/conf.server.json` are used.
|
|
2628
|
-
* @param {
|
|
3007
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow.
|
|
2629
3008
|
* @param {string} [options.deployId] - Deploy ID for storage lookup (defaults to 'dd-default').
|
|
2630
3009
|
* @param {boolean} [options.dev] - Use development environment; defaults to production.
|
|
2631
3010
|
* @memberof UnderpostRun
|
|
@@ -2717,7 +3096,7 @@ EOF`;
|
|
|
2717
3096
|
* @method build-cluster-deployment-manifests
|
|
2718
3097
|
* @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.
|
|
2719
3098
|
* @param {string} path - Unused.
|
|
2720
|
-
* @param {
|
|
3099
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow.
|
|
2721
3100
|
* @memberof UnderpostRun
|
|
2722
3101
|
*/
|
|
2723
3102
|
'build-cluster-deployment-manifests': (path = '', options = DEFAULT_OPTION) => {
|
|
@@ -2730,7 +3109,7 @@ EOF`;
|
|
|
2730
3109
|
* @description Installs and enables the Cockpit KVM Dashboard (cockpit, cockpit-machines, libvirt)
|
|
2731
3110
|
* and opens the cockpit firewall service. With `--remove`, closes the firewall service instead.
|
|
2732
3111
|
* @param {string} path - Unused.
|
|
2733
|
-
* @param {
|
|
3112
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow.
|
|
2734
3113
|
* `options.remove` — when true, removes the cockpit firewall rule instead of adding it.
|
|
2735
3114
|
* @memberof UnderpostRun
|
|
2736
3115
|
*/
|
|
@@ -2754,7 +3133,7 @@ EOF`;
|
|
|
2754
3133
|
* Use `reload-shared-dir` for subsequent permission repairs without recreating the group.
|
|
2755
3134
|
* @param {string} path - Target directory to set up (defaults to `/home/dd/engine`).
|
|
2756
3135
|
* Customise via the `path` argument or leave empty to use the default.
|
|
2757
|
-
* @param {
|
|
3136
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow.
|
|
2758
3137
|
* Key fields: `options.user` (default `'admin'`), `options.group` (default `'engine-dev'`).
|
|
2759
3138
|
* @memberof UnderpostRun
|
|
2760
3139
|
*/
|
|
@@ -2775,6 +3154,33 @@ EOF`;
|
|
|
2775
3154
|
|
|
2776
3155
|
logger.info(`[setup-shared-dir] Shared directory setup complete: ${dir}`);
|
|
2777
3156
|
},
|
|
3157
|
+
/**
|
|
3158
|
+
* @method shared-dir-add-user
|
|
3159
|
+
* @description Add a user to an existing shared directory without changing
|
|
3160
|
+
* file owners. Grants recursive group/ACL access so the user can read and
|
|
3161
|
+
* write throughout the shared workspace while preserving existing ownership.
|
|
3162
|
+
*
|
|
3163
|
+
* @param {string} path - Shared directory (defaults to `/home/dd/engine`).
|
|
3164
|
+
* @param {UnderpostRunDefaultOptions} options - Underpost runner options.
|
|
3165
|
+
* Key fields:
|
|
3166
|
+
* - options.user (default: 'admin')
|
|
3167
|
+
* - options.group (default: 'engine-dev')
|
|
3168
|
+
*
|
|
3169
|
+
* @memberof UnderpostRun
|
|
3170
|
+
*/ 'shared-dir-add-user': (path = '/home/dd/engine', options = DEFAULT_OPTION) => {
|
|
3171
|
+
const dir = path || '/home/dd/engine';
|
|
3172
|
+
const user = options.user || 'admin';
|
|
3173
|
+
|
|
3174
|
+
logger.info(`[shared-dir-add-user] dir=${dir} user=${user}`);
|
|
3175
|
+
|
|
3176
|
+
// Give the user direct access without changing owners or group ownership.
|
|
3177
|
+
shellExec(`sudo setfacl -R -m u:${user}:rwx ${dir}`);
|
|
3178
|
+
|
|
3179
|
+
// Make future files/directories inherit the same user ACL.
|
|
3180
|
+
shellExec(`sudo find ${dir} -type d -exec setfacl -d -m u:${user}:rwx {} \\;`);
|
|
3181
|
+
|
|
3182
|
+
logger.info(`[shared-dir-add-user] User '${user}' added to shared directory: ${dir}`);
|
|
3183
|
+
},
|
|
2778
3184
|
};
|
|
2779
3185
|
|
|
2780
3186
|
static API = {
|
|
@@ -2803,7 +3209,7 @@ EOF`;
|
|
|
2803
3209
|
* @description Executes a specified runner function from the UnderpostRun class with the provided path and options.
|
|
2804
3210
|
* @param {string} runner - The name of the runner to execute.
|
|
2805
3211
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
2806
|
-
* @param {
|
|
3212
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2807
3213
|
* @memberof UnderpostRun
|
|
2808
3214
|
* @returns {Promise<any>} The result of the runner execution.
|
|
2809
3215
|
*/
|
|
@@ -2816,7 +3222,7 @@ EOF`;
|
|
|
2816
3222
|
* @description Initiates the execution of a specified CLI command (runner) with the given input value (`path`) and processed options.
|
|
2817
3223
|
* @param {string} runner - The name of the runner to execute.
|
|
2818
3224
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
2819
|
-
* @param {
|
|
3225
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options for customizing workflow
|
|
2820
3226
|
* @memberof UnderpostRun
|
|
2821
3227
|
* @returns {Promise<any>} The result of the callback execution.
|
|
2822
3228
|
*/
|