underpost 2.90.4 → 2.95.1
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/pwa-microservices-template-page.cd.yml +5 -4
- package/.github/workflows/release.cd.yml +7 -7
- package/README.md +7 -8
- package/bin/build.js +6 -1
- package/bin/deploy.js +2 -196
- package/cli.md +154 -80
- package/manifests/deployment/dd-default-development/deployment.yaml +4 -4
- package/manifests/deployment/dd-test-development/deployment.yaml +2 -2
- package/package.json +1 -1
- package/scripts/disk-clean.sh +216 -0
- package/scripts/rocky-setup.sh +1 -0
- package/scripts/ssh-cluster-info.sh +4 -3
- package/src/cli/cluster.js +1 -1
- package/src/cli/db.js +1143 -201
- package/src/cli/deploy.js +93 -24
- package/src/cli/env.js +2 -2
- package/src/cli/image.js +198 -133
- package/src/cli/index.js +111 -44
- package/src/cli/lxd.js +73 -74
- package/src/cli/monitor.js +20 -9
- package/src/cli/repository.js +212 -5
- package/src/cli/run.js +207 -74
- package/src/cli/ssh.js +642 -14
- package/src/client/components/core/CommonJs.js +0 -1
- package/src/db/mongo/MongooseDB.js +5 -1
- package/src/index.js +1 -1
- package/src/monitor.js +11 -1
- package/src/server/backup.js +1 -1
- package/src/server/conf.js +1 -1
- package/src/server/dns.js +242 -1
- package/src/server/process.js +6 -1
- package/src/server/start.js +2 -0
- package/scripts/snap-clean.sh +0 -26
- package/src/client/public/default/plantuml/client-conf.svg +0 -1
- package/src/client/public/default/plantuml/client-schema.svg +0 -1
- package/src/client/public/default/plantuml/cron-conf.svg +0 -1
- package/src/client/public/default/plantuml/cron-schema.svg +0 -1
- package/src/client/public/default/plantuml/server-conf.svg +0 -1
- package/src/client/public/default/plantuml/server-schema.svg +0 -1
- package/src/client/public/default/plantuml/ssr-conf.svg +0 -1
- package/src/client/public/default/plantuml/ssr-schema.svg +0 -1
package/src/cli/run.js
CHANGED
|
@@ -19,10 +19,11 @@ import UnderpostTest from './test.js';
|
|
|
19
19
|
import fs from 'fs-extra';
|
|
20
20
|
import { range, setPad, timer } from '../client/components/core/CommonJs.js';
|
|
21
21
|
import UnderpostDeploy from './deploy.js';
|
|
22
|
+
import UnderpostDB from './db.js';
|
|
22
23
|
import UnderpostRootEnv from './env.js';
|
|
23
24
|
import UnderpostRepository from './repository.js';
|
|
24
25
|
import os from 'os';
|
|
25
|
-
import Underpost from '../index.js';
|
|
26
|
+
import Underpost, { UnderpostSSH } from '../index.js';
|
|
26
27
|
import dotenv from 'dotenv';
|
|
27
28
|
|
|
28
29
|
const logger = loggerFactory(import.meta);
|
|
@@ -53,8 +54,6 @@ class UnderpostRun {
|
|
|
53
54
|
* @property {string} namespace - The namespace to run in.
|
|
54
55
|
* @property {boolean} build - Whether to build the image.
|
|
55
56
|
* @property {number} replicas - The number of replicas to run.
|
|
56
|
-
* @property {boolean} k3s - Whether to run in k3s mode.
|
|
57
|
-
* @property {boolean} kubeadm - Whether to run in kubeadm mode.
|
|
58
57
|
* @property {boolean} force - Whether to force the operation.
|
|
59
58
|
* @property {boolean} reset - Whether to reset the operation.
|
|
60
59
|
* @property {boolean} tls - Whether to use TLS.
|
|
@@ -65,7 +64,7 @@ class UnderpostRun {
|
|
|
65
64
|
* @property {string} imagePullPolicy - The image pull policy for the container.
|
|
66
65
|
* @property {string} apiVersion - The API version for the container.
|
|
67
66
|
* @property {string} claimName - The claim name for the volume.
|
|
68
|
-
* @property {string}
|
|
67
|
+
* @property {string} kindType - The kind of resource to create.
|
|
69
68
|
* @property {boolean} terminal - Whether to open a terminal.
|
|
70
69
|
* @property {number} devProxyPortOffset - The port offset for the development proxy.
|
|
71
70
|
* @property {boolean} hostNetwork - Whether to use host networking.
|
|
@@ -78,6 +77,16 @@ class UnderpostRun {
|
|
|
78
77
|
* @property {boolean} etcHosts - Whether to modify /etc/hosts.
|
|
79
78
|
* @property {string} confServerPath - The configuration server path.
|
|
80
79
|
* @property {string} underpostRoot - The root path of the Underpost installation.
|
|
80
|
+
* @property {string} cronJobs - The cron jobs to run.
|
|
81
|
+
* @property {string} timezone - The timezone to set.
|
|
82
|
+
* @property {boolean} kubeadm - Whether to run in kubeadm mode.
|
|
83
|
+
* @property {boolean} kind - Whether to run in kind mode.
|
|
84
|
+
* @property {boolean} k3s - Whether to run in k3s mode.
|
|
85
|
+
* @property {string} logType - The type of log to generate.
|
|
86
|
+
* @property {string} hosts - The hosts to use.
|
|
87
|
+
* @property {string} deployId - The deployment ID.
|
|
88
|
+
* @property {string} instanceId - The instance ID.
|
|
89
|
+
* @property {string} user - The user to run as.
|
|
81
90
|
* @memberof UnderpostRun
|
|
82
91
|
*/
|
|
83
92
|
static DEFAULT_OPTION = {
|
|
@@ -92,8 +101,6 @@ class UnderpostRun {
|
|
|
92
101
|
namespace: 'default',
|
|
93
102
|
build: false,
|
|
94
103
|
replicas: 1,
|
|
95
|
-
k3s: false,
|
|
96
|
-
kubeadm: false,
|
|
97
104
|
force: false,
|
|
98
105
|
reset: false,
|
|
99
106
|
tls: false,
|
|
@@ -104,7 +111,7 @@ class UnderpostRun {
|
|
|
104
111
|
imagePullPolicy: '',
|
|
105
112
|
apiVersion: '',
|
|
106
113
|
claimName: '',
|
|
107
|
-
|
|
114
|
+
kindType: '',
|
|
108
115
|
terminal: false,
|
|
109
116
|
devProxyPortOffset: 0,
|
|
110
117
|
hostNetwork: false,
|
|
@@ -117,6 +124,16 @@ class UnderpostRun {
|
|
|
117
124
|
etcHosts: false,
|
|
118
125
|
confServerPath: '',
|
|
119
126
|
underpostRoot: '',
|
|
127
|
+
cronJobs: '',
|
|
128
|
+
timezone: '',
|
|
129
|
+
kubeadm: false,
|
|
130
|
+
kind: false,
|
|
131
|
+
k3s: false,
|
|
132
|
+
logType: '',
|
|
133
|
+
hosts: '',
|
|
134
|
+
deployId: '',
|
|
135
|
+
instanceId: '',
|
|
136
|
+
user: '',
|
|
120
137
|
};
|
|
121
138
|
/**
|
|
122
139
|
* @static
|
|
@@ -250,10 +267,29 @@ class UnderpostRun {
|
|
|
250
267
|
);
|
|
251
268
|
shellExec(`${baseCommand} cluster${options.dev ? ' --dev' : ''} --valkey --pull-image`);
|
|
252
269
|
}
|
|
253
|
-
|
|
254
|
-
shellExec(`${baseCommand} deploy --expose --disable-update-underpost-config valkey`, { async: true });
|
|
270
|
+
|
|
255
271
|
{
|
|
256
|
-
|
|
272
|
+
// Detect MongoDB primary pod using centralized method
|
|
273
|
+
let primaryMongoHost = 'mongodb-0.mongodb-service';
|
|
274
|
+
try {
|
|
275
|
+
const primaryPodName = UnderpostDB.API.getMongoPrimaryPodName({
|
|
276
|
+
namespace: options.namespace,
|
|
277
|
+
podName: 'mongodb-0',
|
|
278
|
+
});
|
|
279
|
+
// shellExec(`${baseCommand} deploy --expose --disable-update-underpost-config mongo`, { async: true });
|
|
280
|
+
shellExec(`kubectl port-forward -n ${options.namespace} pod/${primaryPodName} 27017:27017`, { async: true });
|
|
281
|
+
shellExec(
|
|
282
|
+
`${baseCommand} deploy --expose --namespace ${options.namespace} --disable-update-underpost-config valkey`,
|
|
283
|
+
{ async: true },
|
|
284
|
+
);
|
|
285
|
+
} catch (error) {
|
|
286
|
+
logger.warn('Failed to detect MongoDB primary pod, using default', {
|
|
287
|
+
error: error.message,
|
|
288
|
+
default: primaryMongoHost,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const hostListenResult = UnderpostDeploy.API.etcHostFactory([primaryMongoHost]);
|
|
257
293
|
logger.info(hostListenResult.renderHosts);
|
|
258
294
|
}
|
|
259
295
|
},
|
|
@@ -268,7 +304,7 @@ class UnderpostRun {
|
|
|
268
304
|
metadata: async (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
269
305
|
const ports = '6379,27017';
|
|
270
306
|
shellExec(`node bin run kill '${ports}'`);
|
|
271
|
-
shellExec(`node bin run dev-cluster --dev --expose`, { async: true });
|
|
307
|
+
shellExec(`node bin run dev-cluster --dev --expose --namespace ${options.namespace}`, { async: true });
|
|
272
308
|
console.log('Loading fordward services...');
|
|
273
309
|
await timer(5000);
|
|
274
310
|
shellExec(`node bin metadata --generate ${path}`);
|
|
@@ -317,8 +353,9 @@ class UnderpostRun {
|
|
|
317
353
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
318
354
|
* @memberof UnderpostRun
|
|
319
355
|
*/
|
|
320
|
-
'ssh-cluster-info': (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
356
|
+
'ssh-cluster-info': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
321
357
|
const { underpostRoot } = options;
|
|
358
|
+
if (options.deployId && options.user) await UnderpostSSH.API.setDefautlSshCredentials(options);
|
|
322
359
|
shellExec(`chmod +x ${underpostRoot}/scripts/ssh-cluster-info.sh`);
|
|
323
360
|
shellExec(`${underpostRoot}/scripts/ssh-cluster-info.sh`);
|
|
324
361
|
},
|
|
@@ -361,7 +398,7 @@ class UnderpostRun {
|
|
|
361
398
|
shellExec(`node bin run sync-replica template-deploy${nodeOptions}`);
|
|
362
399
|
shellExec(`node bin env clean`);
|
|
363
400
|
for (const deployId of fs.readFileSync('./engine-private/deploy/dd.router', 'utf8').split(','))
|
|
364
|
-
shellExec(`node bin
|
|
401
|
+
shellExec(`node bin new --default-conf --deploy-id ${deployId.trim()}`);
|
|
365
402
|
if (path === 'cmt') {
|
|
366
403
|
shellExec(`git add . && underpost cmt . build cluster-build`);
|
|
367
404
|
shellExec(`cd engine-private && git add . && underpost cmt . build cluster-build`);
|
|
@@ -408,8 +445,8 @@ class UnderpostRun {
|
|
|
408
445
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
409
446
|
* @memberof UnderpostRun
|
|
410
447
|
*/
|
|
411
|
-
clean: (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
412
|
-
shellCd(path
|
|
448
|
+
clean: (path = '', options = UnderpostRun.DEFAULT_OPTION) => {
|
|
449
|
+
shellCd(path ? path : `/home/dd/engine`);
|
|
413
450
|
shellExec(`node bin/deploy clean-core-repo`);
|
|
414
451
|
},
|
|
415
452
|
/**
|
|
@@ -422,16 +459,25 @@ class UnderpostRun {
|
|
|
422
459
|
pull: (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
423
460
|
if (!fs.existsSync(`/home/dd`) || !fs.existsSync(`/home/dd/engine`)) {
|
|
424
461
|
fs.mkdirSync(`/home/dd`, { recursive: true });
|
|
425
|
-
shellExec(`cd /home/dd && underpost clone ${process.env.GITHUB_USERNAME}/engine
|
|
462
|
+
shellExec(`cd /home/dd && underpost clone ${process.env.GITHUB_USERNAME}/engine`, {
|
|
463
|
+
silent: true,
|
|
464
|
+
});
|
|
426
465
|
} else {
|
|
427
466
|
shellExec(`underpost run clean`);
|
|
428
|
-
shellExec(`cd /home/dd/engine && underpost pull . ${process.env.GITHUB_USERNAME}/engine
|
|
467
|
+
shellExec(`cd /home/dd/engine && underpost pull . ${process.env.GITHUB_USERNAME}/engine`, {
|
|
468
|
+
silent: true,
|
|
469
|
+
});
|
|
429
470
|
}
|
|
430
471
|
if (!fs.existsSync(`/home/dd/engine/engine-private`))
|
|
431
|
-
shellExec(`cd /home/dd/engine && underpost clone ${process.env.GITHUB_USERNAME}/engine-private
|
|
472
|
+
shellExec(`cd /home/dd/engine && underpost clone ${process.env.GITHUB_USERNAME}/engine-private`, {
|
|
473
|
+
silent: true,
|
|
474
|
+
});
|
|
432
475
|
else
|
|
433
476
|
shellExec(
|
|
434
477
|
`cd /home/dd/engine/engine-private && underpost pull . ${process.env.GITHUB_USERNAME}/engine-private`,
|
|
478
|
+
{
|
|
479
|
+
silent: true,
|
|
480
|
+
},
|
|
435
481
|
);
|
|
436
482
|
},
|
|
437
483
|
/**
|
|
@@ -497,7 +543,7 @@ class UnderpostRun {
|
|
|
497
543
|
const baseClusterCommand = options.dev ? ' --dev' : '';
|
|
498
544
|
const defaultPath = [
|
|
499
545
|
'dd-default',
|
|
500
|
-
|
|
546
|
+
options.replicas,
|
|
501
547
|
``,
|
|
502
548
|
``,
|
|
503
549
|
options.dev || !isDeployRunnerContext(path, options) ? 'kind-control-plane' : os.hostname(),
|
|
@@ -512,8 +558,8 @@ class UnderpostRun {
|
|
|
512
558
|
if (isDeployRunnerContext(path, options)) {
|
|
513
559
|
const { validVersion } = UnderpostRepository.API.privateConfUpdate(deployId);
|
|
514
560
|
if (!validVersion) throw new Error('Version mismatch');
|
|
515
|
-
shellExec(`${baseCommand} run${baseClusterCommand} tz`);
|
|
516
|
-
shellExec(`${baseCommand} run${baseClusterCommand} cron`);
|
|
561
|
+
if (options.timezone !== 'none') shellExec(`${baseCommand} run${baseClusterCommand} tz`);
|
|
562
|
+
if (options.cronJobs !== 'none') shellExec(`${baseCommand} run${baseClusterCommand} cron`);
|
|
517
563
|
}
|
|
518
564
|
|
|
519
565
|
const currentTraffic = isDeployRunnerContext(path, options)
|
|
@@ -524,7 +570,7 @@ class UnderpostRun {
|
|
|
524
570
|
|
|
525
571
|
shellExec(
|
|
526
572
|
`${baseCommand} deploy --kubeadm --build-manifest --sync --info-router --replicas ${
|
|
527
|
-
replicas
|
|
573
|
+
replicas
|
|
528
574
|
} --node ${node}${image ? ` --image ${image}` : ''}${versions ? ` --versions ${versions}` : ''}${options.namespace ? ` --namespace ${options.namespace}` : ''} dd ${env}`,
|
|
529
575
|
);
|
|
530
576
|
|
|
@@ -534,8 +580,8 @@ class UnderpostRun {
|
|
|
534
580
|
);
|
|
535
581
|
if (!targetTraffic)
|
|
536
582
|
targetTraffic = UnderpostDeploy.API.getCurrentTraffic(deployId, { namespace: options.namespace });
|
|
537
|
-
await UnderpostDeploy.API.monitorReadyRunner(deployId, env, targetTraffic);
|
|
538
|
-
UnderpostDeploy.API.switchTraffic(deployId, env, targetTraffic);
|
|
583
|
+
await UnderpostDeploy.API.monitorReadyRunner(deployId, env, targetTraffic, [], options.namespace, 'underpost');
|
|
584
|
+
UnderpostDeploy.API.switchTraffic(deployId, env, targetTraffic, replicas, options.namespace);
|
|
539
585
|
} else
|
|
540
586
|
logger.info(
|
|
541
587
|
'current traffic',
|
|
@@ -543,6 +589,61 @@ class UnderpostRun {
|
|
|
543
589
|
);
|
|
544
590
|
},
|
|
545
591
|
|
|
592
|
+
/**
|
|
593
|
+
* @method stop
|
|
594
|
+
* @description Stops a deployment by deleting the corresponding Kubernetes deployment and service resources.
|
|
595
|
+
* @param {string} path - The input value, identifier, or path for the operation (used to determine which traffic to stop).
|
|
596
|
+
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
597
|
+
* @memberof UnderpostRun
|
|
598
|
+
*/
|
|
599
|
+
stop: async (path = '', options = UnderpostRun.DEFAULT_OPTION) => {
|
|
600
|
+
let currentTraffic = UnderpostDeploy.API.getCurrentTraffic(options.deployId, {
|
|
601
|
+
namespace: options.namespace,
|
|
602
|
+
hostTest: options.hosts,
|
|
603
|
+
});
|
|
604
|
+
const env = options.dev ? 'development' : 'production';
|
|
605
|
+
|
|
606
|
+
if (!path.match('current')) currentTraffic === 'blue' ? (currentTraffic = 'green') : (currentTraffic = 'blue');
|
|
607
|
+
const [_deployId] = path.split(',');
|
|
608
|
+
const deploymentId = `${_deployId ? _deployId : options.deployId}${options.instanceId ? `-${options.instanceId}` : ''}-${env}-${currentTraffic}`;
|
|
609
|
+
|
|
610
|
+
shellExec(`kubectl delete deployment ${deploymentId} -n ${options.namespace}`);
|
|
611
|
+
shellExec(`kubectl delete svc ${deploymentId}-service -n ${options.namespace}`);
|
|
612
|
+
},
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* @method ssh-deploy-stop
|
|
616
|
+
* @description Stops a remote deployment via SSH by executing the appropriate Underpost command on the remote server.
|
|
617
|
+
* @param {string} path - The input value, identifier, or path for the operation (used to determine which traffic to stop).
|
|
618
|
+
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
619
|
+
* @memberof UnderpostRun
|
|
620
|
+
*/
|
|
621
|
+
'ssh-deploy-stop': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
622
|
+
const env = options.dev ? 'development' : 'production';
|
|
623
|
+
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
624
|
+
const baseClusterCommand = options.dev ? ' --dev' : '';
|
|
625
|
+
await UnderpostSSH.API.setDefautlSshCredentials(options);
|
|
626
|
+
shellExec(`#!/usr/bin/env bash
|
|
627
|
+
set -euo pipefail
|
|
628
|
+
|
|
629
|
+
REMOTE_USER=$(node bin config get --plain DEFAULT_SSH_USER)
|
|
630
|
+
REMOTE_HOST=$(node bin config get --plain DEFAULT_SSH_HOST)
|
|
631
|
+
REMOTE_PORT=$(node bin config get --plain DEFAULT_SSH_PORT)
|
|
632
|
+
SSH_KEY=$(node bin config get --plain DEFAULT_SSH_KEY_PATH)
|
|
633
|
+
|
|
634
|
+
chmod 600 "$SSH_KEY"
|
|
635
|
+
|
|
636
|
+
ssh -i "$SSH_KEY" -o BatchMode=yes "$REMOTE_USER@$REMOTE_HOST" -p $REMOTE_PORT sh <<EOF
|
|
637
|
+
cd /home/dd/engine
|
|
638
|
+
sudo -n -- /bin/bash -lc "${[
|
|
639
|
+
`${baseCommand} run${baseClusterCommand} stop${path ? ` ${path}` : ''}`,
|
|
640
|
+
` --deploy-id ${options.deployId}${options.instanceId ? ` --instance-id ${options.instanceId}` : ''}`,
|
|
641
|
+
` --namespace ${options.namespace}`,
|
|
642
|
+
].join('')}"
|
|
643
|
+
EOF
|
|
644
|
+
`);
|
|
645
|
+
},
|
|
646
|
+
|
|
546
647
|
/**
|
|
547
648
|
* @method tz
|
|
548
649
|
* @description Sets the system timezone using `timedatectl set-timezone` command.
|
|
@@ -551,13 +652,16 @@ class UnderpostRun {
|
|
|
551
652
|
* @memberof UnderpostRun
|
|
552
653
|
*/
|
|
553
654
|
tz: (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
554
|
-
const tz =
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
655
|
+
const tz =
|
|
656
|
+
options.timezone && options.timezone !== 'none'
|
|
657
|
+
? options.timezone
|
|
658
|
+
: path
|
|
659
|
+
? path
|
|
660
|
+
: UnderpostRootEnv.API.get('TIME_ZONE', undefined, { disableLog: true })
|
|
661
|
+
? UnderpostRootEnv.API.get('TIME_ZONE')
|
|
662
|
+
: process.env.TIME_ZONE
|
|
663
|
+
? process.env.TIME_ZONE
|
|
664
|
+
: 'America/New_York';
|
|
561
665
|
shellExec(`sudo timedatectl set-timezone ${tz}`);
|
|
562
666
|
},
|
|
563
667
|
|
|
@@ -623,6 +727,7 @@ class UnderpostRun {
|
|
|
623
727
|
const _deployId = `${deployId}-${_id}`;
|
|
624
728
|
const currentTraffic = UnderpostDeploy.API.getCurrentTraffic(_deployId, {
|
|
625
729
|
hostTest: _host,
|
|
730
|
+
namespace: options.namespace,
|
|
626
731
|
});
|
|
627
732
|
const targetTraffic = currentTraffic ? (currentTraffic === 'blue' ? 'green' : 'blue') : 'blue';
|
|
628
733
|
let proxyYaml =
|
|
@@ -662,7 +767,8 @@ EOF
|
|
|
662
767
|
const env = options.dev ? 'development' : 'production';
|
|
663
768
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
664
769
|
const baseClusterCommand = options.dev ? ' --dev' : '';
|
|
665
|
-
let [deployId, id, replicas
|
|
770
|
+
let [deployId, id, replicas] = path.split(',');
|
|
771
|
+
if (!replicas) replicas = options.replicas;
|
|
666
772
|
const confInstances = JSON.parse(
|
|
667
773
|
fs.readFileSync(`./engine-private/conf/${deployId}/conf.instances.json`, 'utf8'),
|
|
668
774
|
);
|
|
@@ -697,11 +803,12 @@ EOF
|
|
|
697
803
|
|
|
698
804
|
const currentTraffic = UnderpostDeploy.API.getCurrentTraffic(_deployId, {
|
|
699
805
|
hostTest: _host,
|
|
806
|
+
namespace: options.namespace,
|
|
700
807
|
});
|
|
701
808
|
|
|
702
809
|
const targetTraffic = currentTraffic ? (currentTraffic === 'blue' ? 'green' : 'blue') : 'blue';
|
|
703
810
|
const podId = `${_deployId}-${env}-${targetTraffic}`;
|
|
704
|
-
const ignorePods = UnderpostDeploy.API.get(podId).map((p) => p.NAME);
|
|
811
|
+
const ignorePods = UnderpostDeploy.API.get(podId, 'pods', options.namespace).map((p) => p.NAME);
|
|
705
812
|
UnderpostDeploy.API.configMap(env, options.namespace);
|
|
706
813
|
shellExec(`kubectl delete service ${podId}-service --namespace ${options.namespace} --ignore-not-found`);
|
|
707
814
|
shellExec(`kubectl delete deployment ${podId} --namespace ${options.namespace} --ignore-not-found`);
|
|
@@ -740,6 +847,8 @@ EOF
|
|
|
740
847
|
env,
|
|
741
848
|
targetTraffic,
|
|
742
849
|
ignorePods,
|
|
850
|
+
options.namespace,
|
|
851
|
+
options.logType,
|
|
743
852
|
);
|
|
744
853
|
|
|
745
854
|
if (!ready) {
|
|
@@ -769,21 +878,6 @@ EOF
|
|
|
769
878
|
'ls-deployments': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
770
879
|
console.table(await UnderpostDeploy.API.get(path, 'deployments', options.namespace));
|
|
771
880
|
},
|
|
772
|
-
/**
|
|
773
|
-
* @method ls-images
|
|
774
|
-
* @description Retrieves and logs a table of currently loaded Docker images in the 'kind-worker' node using `UnderpostDeploy.API.getCurrentLoadedImages`.
|
|
775
|
-
* @param {string} path - The input value, identifier, or path for the operation.
|
|
776
|
-
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
777
|
-
* @memberof UnderpostRun
|
|
778
|
-
*/
|
|
779
|
-
'ls-images': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
780
|
-
console.table(
|
|
781
|
-
UnderpostDeploy.API.getCurrentLoadedImages(
|
|
782
|
-
options.nodeName ? options.nodeName : 'kind-worker',
|
|
783
|
-
path === 'spec' ? true : false,
|
|
784
|
-
),
|
|
785
|
-
);
|
|
786
|
-
},
|
|
787
881
|
|
|
788
882
|
/**
|
|
789
883
|
* @method host-update
|
|
@@ -829,9 +923,7 @@ EOF
|
|
|
829
923
|
}
|
|
830
924
|
|
|
831
925
|
if (!currentImage)
|
|
832
|
-
shellExec(
|
|
833
|
-
`${baseCommand} dockerfile-pull-base-images${baseClusterCommand} ${options.dev ? '--kind-load' : '--kubeadm-load'}`,
|
|
834
|
-
);
|
|
926
|
+
shellExec(`${baseCommand} image${baseClusterCommand} --pull-base ${options.dev ? '--kind' : '--kubeadm'}`);
|
|
835
927
|
// shellExec(`kubectl delete pod ${podName} --ignore-not-found`);
|
|
836
928
|
|
|
837
929
|
const payload = {
|
|
@@ -888,7 +980,7 @@ EOF
|
|
|
888
980
|
switch (path) {
|
|
889
981
|
case 'tf-vae-test':
|
|
890
982
|
{
|
|
891
|
-
const nameSpace = options.namespace
|
|
983
|
+
const nameSpace = options.namespace;
|
|
892
984
|
const podName = path;
|
|
893
985
|
const basePath = '/home/dd';
|
|
894
986
|
const scriptPath = '/site/en/tutorials/generative/cvae.py';
|
|
@@ -975,7 +1067,7 @@ EOF
|
|
|
975
1067
|
const successInstance = await UnderpostTest.API.statusMonitor('adminer', 'Running', 'pods', 1000, 60 * 10);
|
|
976
1068
|
|
|
977
1069
|
if (successInstance) {
|
|
978
|
-
shellExec(`underpost deploy --expose adminer`);
|
|
1070
|
+
shellExec(`underpost deploy --expose adminer --namespace ${options.namespace}`);
|
|
979
1071
|
}
|
|
980
1072
|
},
|
|
981
1073
|
|
|
@@ -1033,12 +1125,12 @@ EOF
|
|
|
1033
1125
|
for (const deployId of fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8').split(',')) {
|
|
1034
1126
|
const currentTraffic = UnderpostDeploy.API.getCurrentTraffic(deployId, { namespace: options.namespace });
|
|
1035
1127
|
const targetTraffic = currentTraffic === 'blue' ? 'green' : 'blue';
|
|
1036
|
-
UnderpostDeploy.API.switchTraffic(deployId, inputEnv, targetTraffic, inputReplicas);
|
|
1128
|
+
UnderpostDeploy.API.switchTraffic(deployId, inputEnv, targetTraffic, inputReplicas, options.namespace);
|
|
1037
1129
|
}
|
|
1038
1130
|
} else {
|
|
1039
1131
|
const currentTraffic = UnderpostDeploy.API.getCurrentTraffic(inputDeployId, { namespace: options.namespace });
|
|
1040
1132
|
const targetTraffic = currentTraffic === 'blue' ? 'green' : 'blue';
|
|
1041
|
-
UnderpostDeploy.API.switchTraffic(inputDeployId, inputEnv, targetTraffic, inputReplicas);
|
|
1133
|
+
UnderpostDeploy.API.switchTraffic(inputDeployId, inputEnv, targetTraffic, inputReplicas, options.namespace);
|
|
1042
1134
|
}
|
|
1043
1135
|
},
|
|
1044
1136
|
/**
|
|
@@ -1069,44 +1161,45 @@ EOF
|
|
|
1069
1161
|
const env = options.dev ? 'development' : 'production';
|
|
1070
1162
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
1071
1163
|
const baseClusterCommand = options.dev ? ' --dev' : '';
|
|
1164
|
+
const clusterType = options.k3s ? 'k3s' : 'kubeadm';
|
|
1072
1165
|
shellCd(`/home/dd/engine`);
|
|
1073
1166
|
shellExec(`${baseCommand} cluster${baseClusterCommand} --reset`);
|
|
1074
1167
|
await timer(5000);
|
|
1075
|
-
shellExec(`${baseCommand} cluster${baseClusterCommand}
|
|
1168
|
+
shellExec(`${baseCommand} cluster${baseClusterCommand} --${clusterType}`);
|
|
1076
1169
|
await timer(5000);
|
|
1077
1170
|
let [runtimeImage, deployList] = path.split(',')
|
|
1078
1171
|
? path.split(',')
|
|
1079
|
-
: ['
|
|
1172
|
+
: ['express', fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8').replaceAll(',', '+')];
|
|
1080
1173
|
shellExec(
|
|
1081
|
-
`${baseCommand}
|
|
1082
|
-
runtimeImage ? ` --path /home/dd/engine/src/runtime/${runtimeImage}` : ''
|
|
1083
|
-
}
|
|
1174
|
+
`${baseCommand} image${baseClusterCommand}${
|
|
1175
|
+
runtimeImage ? ` --pull-base --path /home/dd/engine/src/runtime/${runtimeImage}` : ''
|
|
1176
|
+
} --${clusterType}`,
|
|
1084
1177
|
);
|
|
1085
1178
|
if (!deployList) {
|
|
1086
1179
|
deployList = [];
|
|
1087
1180
|
logger.warn('No deploy list provided');
|
|
1088
1181
|
} else deployList = deployList.split('+');
|
|
1089
1182
|
await timer(5000);
|
|
1090
|
-
shellExec(`${baseCommand} cluster${baseClusterCommand}
|
|
1183
|
+
shellExec(`${baseCommand} cluster${baseClusterCommand} --${clusterType} --pull-image --mongodb`);
|
|
1091
1184
|
if (runtimeImage === 'lampp') {
|
|
1092
1185
|
await timer(5000);
|
|
1093
|
-
shellExec(`${baseCommand} cluster${baseClusterCommand}
|
|
1186
|
+
shellExec(`${baseCommand} cluster${baseClusterCommand} --${clusterType} --pull-image --mariadb`);
|
|
1094
1187
|
}
|
|
1095
1188
|
await timer(5000);
|
|
1096
1189
|
for (const deployId of deployList) {
|
|
1097
1190
|
shellExec(`${baseCommand} db ${deployId} --import --git`);
|
|
1098
1191
|
}
|
|
1099
1192
|
await timer(5000);
|
|
1100
|
-
shellExec(`${baseCommand} cluster${baseClusterCommand}
|
|
1193
|
+
shellExec(`${baseCommand} cluster${baseClusterCommand} --${clusterType} --pull-image --valkey`);
|
|
1101
1194
|
await timer(5000);
|
|
1102
|
-
shellExec(`${baseCommand} cluster${baseClusterCommand}
|
|
1195
|
+
shellExec(`${baseCommand} cluster${baseClusterCommand} --${clusterType} --contour`);
|
|
1103
1196
|
if (env === 'production') {
|
|
1104
1197
|
await timer(5000);
|
|
1105
|
-
shellExec(`${baseCommand} cluster${baseClusterCommand}
|
|
1198
|
+
shellExec(`${baseCommand} cluster${baseClusterCommand} --${clusterType} --cert-manager`);
|
|
1106
1199
|
}
|
|
1107
1200
|
for (const deployId of deployList) {
|
|
1108
1201
|
shellExec(
|
|
1109
|
-
`${baseCommand} deploy ${deployId} ${env}
|
|
1202
|
+
`${baseCommand} deploy ${deployId} ${env} --${clusterType}${env === 'production' ? ' --cert' : ''}${
|
|
1110
1203
|
env === 'development' ? ' --etc-hosts' : ''
|
|
1111
1204
|
}`,
|
|
1112
1205
|
);
|
|
@@ -1126,13 +1219,50 @@ EOF
|
|
|
1126
1219
|
const currentTraffic = UnderpostDeploy.API.getCurrentTraffic(deployId, { namespace: options.namespace });
|
|
1127
1220
|
const targetTraffic = currentTraffic === 'blue' ? 'green' : 'blue';
|
|
1128
1221
|
const env = 'production';
|
|
1129
|
-
const ignorePods = UnderpostDeploy.API.get(`${deployId}-${env}-${targetTraffic}
|
|
1222
|
+
const ignorePods = UnderpostDeploy.API.get(`${deployId}-${env}-${targetTraffic}`, 'pods', options.namespace).map(
|
|
1223
|
+
(p) => p.NAME,
|
|
1224
|
+
);
|
|
1130
1225
|
|
|
1131
1226
|
shellExec(`sudo kubectl rollout restart deployment/${deployId}-${env}-${targetTraffic} -n ${options.namespace}`);
|
|
1132
1227
|
|
|
1133
|
-
await UnderpostDeploy.API.monitorReadyRunner(
|
|
1228
|
+
await UnderpostDeploy.API.monitorReadyRunner(
|
|
1229
|
+
deployId,
|
|
1230
|
+
env,
|
|
1231
|
+
targetTraffic,
|
|
1232
|
+
ignorePods,
|
|
1233
|
+
options.namespace,
|
|
1234
|
+
'underpost',
|
|
1235
|
+
);
|
|
1134
1236
|
|
|
1135
|
-
UnderpostDeploy.API.switchTraffic(deployId, env, targetTraffic);
|
|
1237
|
+
UnderpostDeploy.API.switchTraffic(deployId, env, targetTraffic, options.replicas, options.namespace);
|
|
1238
|
+
},
|
|
1239
|
+
|
|
1240
|
+
/**
|
|
1241
|
+
* @method disk-clean
|
|
1242
|
+
* @description Executes the `disk-clean-sh` script to perform disk cleanup operations.
|
|
1243
|
+
* @param {string} path - The input value, identifier, or path for the operation.
|
|
1244
|
+
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1245
|
+
* @memberof UnderpostRun
|
|
1246
|
+
*/
|
|
1247
|
+
'disk-clean': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
1248
|
+
const { underpostRoot } = options;
|
|
1249
|
+
shellExec(`chmod +x ${underpostRoot}/scripts/disk-clean.sh`);
|
|
1250
|
+
shellExec(`./scripts/disk-clean.sh --yes --aggressive`);
|
|
1251
|
+
},
|
|
1252
|
+
|
|
1253
|
+
/**
|
|
1254
|
+
* @method disk-usage
|
|
1255
|
+
* @description Displays disk usage statistics using the `du` command, sorted by size.
|
|
1256
|
+
* @param {string} path - The input value, identifier, or path for the operation.
|
|
1257
|
+
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1258
|
+
* @memberof UnderpostRun
|
|
1259
|
+
*/
|
|
1260
|
+
'disk-usage': async (path = '/', options = UnderpostRun.DEFAULT_OPTION) => {
|
|
1261
|
+
if (!path) path = '/';
|
|
1262
|
+
logger.info('Mount filesystem');
|
|
1263
|
+
shellExec(`df -h${path === '/' ? '' : ` ${path}`}`);
|
|
1264
|
+
logger.info('Files disks usage');
|
|
1265
|
+
shellExec(`du -xh ${path} --max-depth=1 | sort -h`);
|
|
1136
1266
|
},
|
|
1137
1267
|
|
|
1138
1268
|
/**
|
|
@@ -1174,7 +1304,7 @@ EOF
|
|
|
1174
1304
|
envObj.DEV_PROXY_PORT_OFFSET = options.devProxyPortOffset;
|
|
1175
1305
|
writeEnv(envPath, envObj);
|
|
1176
1306
|
}
|
|
1177
|
-
shellExec(`node bin run dev-cluster --expose`, { async: true });
|
|
1307
|
+
shellExec(`node bin run dev-cluster --expose --namespace ${options.namespace}`, { async: true });
|
|
1178
1308
|
{
|
|
1179
1309
|
const cmd = `npm run dev-api ${deployId} ${subConf} ${host} ${_path} ${clientHostPort}${options.tls ? ' tls' : ''}`;
|
|
1180
1310
|
options.terminal ? openTerminal(cmd) : shellExec(cmd, { async: true });
|
|
@@ -1205,6 +1335,7 @@ EOF
|
|
|
1205
1335
|
const baseClusterCommand = options.dev ? ' --dev' : '';
|
|
1206
1336
|
shellCd(`/home/dd/engine`);
|
|
1207
1337
|
let [deployId, serviceId, host, _path, replicas, image, node] = path.split(',');
|
|
1338
|
+
if (!replicas) replicas = options.replicas;
|
|
1208
1339
|
// const confClient = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.client.json`, 'utf8'));
|
|
1209
1340
|
const confServer = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'));
|
|
1210
1341
|
// const confSSR = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.ssr.json`, 'utf8'));
|
|
@@ -1269,7 +1400,7 @@ EOF
|
|
|
1269
1400
|
if (!node) node = os.hostname();
|
|
1270
1401
|
shellExec(
|
|
1271
1402
|
`${baseCommand} deploy${options.dev ? '' : ' --kubeadm'}${options.devProxyPortOffset ? ' --disable-deployment-proxy' : ''} --build-manifest --sync --info-router --replicas ${
|
|
1272
|
-
replicas
|
|
1403
|
+
replicas
|
|
1273
1404
|
} --node ${node}${image ? ` --image ${image}` : ''}${versions ? ` --versions ${versions}` : ''} dd ${env}`,
|
|
1274
1405
|
);
|
|
1275
1406
|
shellExec(
|
|
@@ -1329,7 +1460,7 @@ EOF
|
|
|
1329
1460
|
shellExec(`underpost run secret`);
|
|
1330
1461
|
shellCd(`/home/dd/engine`);
|
|
1331
1462
|
shellExec(`underpost cmt --empty . ci engine ' New engine release $(underpost --version)'`);
|
|
1332
|
-
shellExec(`underpost push . ${process.env.GITHUB_USERNAME}/engine
|
|
1463
|
+
shellExec(`underpost push . ${process.env.GITHUB_USERNAME}/engine`, { silent: true });
|
|
1333
1464
|
},
|
|
1334
1465
|
|
|
1335
1466
|
/**
|
|
@@ -1427,7 +1558,7 @@ EOF
|
|
|
1427
1558
|
const tty = options.tty ? 'true' : 'false';
|
|
1428
1559
|
const stdin = options.stdin ? 'true' : 'false';
|
|
1429
1560
|
const restartPolicy = options.restartPolicy || 'Never';
|
|
1430
|
-
const
|
|
1561
|
+
const kindType = options.kindType || 'Pod';
|
|
1431
1562
|
const imagePullPolicy = options.imagePullPolicy || 'IfNotPresent';
|
|
1432
1563
|
const hostNetwork = options.hostNetwork ? options.hostNetwork : '';
|
|
1433
1564
|
const apiVersion = options.apiVersion || 'v1';
|
|
@@ -1451,7 +1582,7 @@ EOF
|
|
|
1451
1582
|
|
|
1452
1583
|
const cmd = `kubectl apply -f - <<EOF
|
|
1453
1584
|
apiVersion: ${apiVersion}
|
|
1454
|
-
kind: ${
|
|
1585
|
+
kind: ${kindType}
|
|
1455
1586
|
metadata:
|
|
1456
1587
|
name: ${podName}
|
|
1457
1588
|
namespace: ${namespace}
|
|
@@ -1523,6 +1654,8 @@ EOF`;
|
|
|
1523
1654
|
if (options.args) options.args = options.args.split(',');
|
|
1524
1655
|
if (!options.underpostRoot) options.underpostRoot = underpostRoot;
|
|
1525
1656
|
if (!options.namespace) options.namespace = 'default';
|
|
1657
|
+
if (options.replicas === '' || options.replicas === null || options.replicas === undefined)
|
|
1658
|
+
options.replicas = 1;
|
|
1526
1659
|
options.npmRoot = npmRoot;
|
|
1527
1660
|
logger.info('callback', { path, options });
|
|
1528
1661
|
if (!(runner in UnderpostRun.RUNNERS)) throw new Error(`Runner not found: ${runner}`);
|