underpost 2.92.0 → 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.
Files changed (35) hide show
  1. package/.github/workflows/pwa-microservices-template-page.cd.yml +5 -4
  2. package/README.md +4 -5
  3. package/bin/build.js +6 -1
  4. package/bin/deploy.js +2 -69
  5. package/cli.md +99 -92
  6. package/manifests/deployment/dd-default-development/deployment.yaml +4 -4
  7. package/manifests/deployment/dd-test-development/deployment.yaml +2 -2
  8. package/package.json +1 -1
  9. package/scripts/disk-clean.sh +216 -0
  10. package/scripts/ssh-cluster-info.sh +4 -3
  11. package/src/cli/cluster.js +1 -1
  12. package/src/cli/db.js +71 -80
  13. package/src/cli/deploy.js +77 -13
  14. package/src/cli/image.js +198 -133
  15. package/src/cli/index.js +59 -81
  16. package/src/cli/lxd.js +73 -74
  17. package/src/cli/monitor.js +20 -9
  18. package/src/cli/repository.js +86 -3
  19. package/src/cli/run.js +167 -63
  20. package/src/cli/ssh.js +351 -134
  21. package/src/index.js +1 -1
  22. package/src/monitor.js +11 -1
  23. package/src/server/backup.js +1 -1
  24. package/src/server/conf.js +1 -1
  25. package/src/server/dns.js +88 -1
  26. package/src/server/process.js +6 -1
  27. package/scripts/snap-clean.sh +0 -26
  28. package/src/client/public/default/plantuml/client-conf.svg +0 -1
  29. package/src/client/public/default/plantuml/client-schema.svg +0 -1
  30. package/src/client/public/default/plantuml/cron-conf.svg +0 -1
  31. package/src/client/public/default/plantuml/cron-schema.svg +0 -1
  32. package/src/client/public/default/plantuml/server-conf.svg +0 -1
  33. package/src/client/public/default/plantuml/server-schema.svg +0 -1
  34. package/src/client/public/default/plantuml/ssr-conf.svg +0 -1
  35. package/src/client/public/default/plantuml/ssr-schema.svg +0 -1
package/src/cli/run.js CHANGED
@@ -23,7 +23,7 @@ import UnderpostDB from './db.js';
23
23
  import UnderpostRootEnv from './env.js';
24
24
  import UnderpostRepository from './repository.js';
25
25
  import os from 'os';
26
- import Underpost from '../index.js';
26
+ import Underpost, { UnderpostSSH } from '../index.js';
27
27
  import dotenv from 'dotenv';
28
28
 
29
29
  const logger = loggerFactory(import.meta);
@@ -54,8 +54,6 @@ class UnderpostRun {
54
54
  * @property {string} namespace - The namespace to run in.
55
55
  * @property {boolean} build - Whether to build the image.
56
56
  * @property {number} replicas - The number of replicas to run.
57
- * @property {boolean} k3s - Whether to run in k3s mode.
58
- * @property {boolean} kubeadm - Whether to run in kubeadm mode.
59
57
  * @property {boolean} force - Whether to force the operation.
60
58
  * @property {boolean} reset - Whether to reset the operation.
61
59
  * @property {boolean} tls - Whether to use TLS.
@@ -66,7 +64,7 @@ class UnderpostRun {
66
64
  * @property {string} imagePullPolicy - The image pull policy for the container.
67
65
  * @property {string} apiVersion - The API version for the container.
68
66
  * @property {string} claimName - The claim name for the volume.
69
- * @property {string} kind - The kind of resource to create.
67
+ * @property {string} kindType - The kind of resource to create.
70
68
  * @property {boolean} terminal - Whether to open a terminal.
71
69
  * @property {number} devProxyPortOffset - The port offset for the development proxy.
72
70
  * @property {boolean} hostNetwork - Whether to use host networking.
@@ -79,6 +77,16 @@ class UnderpostRun {
79
77
  * @property {boolean} etcHosts - Whether to modify /etc/hosts.
80
78
  * @property {string} confServerPath - The configuration server path.
81
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.
82
90
  * @memberof UnderpostRun
83
91
  */
84
92
  static DEFAULT_OPTION = {
@@ -93,8 +101,6 @@ class UnderpostRun {
93
101
  namespace: 'default',
94
102
  build: false,
95
103
  replicas: 1,
96
- k3s: false,
97
- kubeadm: false,
98
104
  force: false,
99
105
  reset: false,
100
106
  tls: false,
@@ -105,7 +111,7 @@ class UnderpostRun {
105
111
  imagePullPolicy: '',
106
112
  apiVersion: '',
107
113
  claimName: '',
108
- kind: '',
114
+ kindType: '',
109
115
  terminal: false,
110
116
  devProxyPortOffset: 0,
111
117
  hostNetwork: false,
@@ -118,6 +124,16 @@ class UnderpostRun {
118
124
  etcHosts: false,
119
125
  confServerPath: '',
120
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: '',
121
137
  };
122
138
  /**
123
139
  * @static
@@ -337,8 +353,9 @@ class UnderpostRun {
337
353
  * @param {Object} options - The default underpost runner options for customizing workflow
338
354
  * @memberof UnderpostRun
339
355
  */
340
- 'ssh-cluster-info': (path, options = UnderpostRun.DEFAULT_OPTION) => {
356
+ 'ssh-cluster-info': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
341
357
  const { underpostRoot } = options;
358
+ if (options.deployId && options.user) await UnderpostSSH.API.setDefautlSshCredentials(options);
342
359
  shellExec(`chmod +x ${underpostRoot}/scripts/ssh-cluster-info.sh`);
343
360
  shellExec(`${underpostRoot}/scripts/ssh-cluster-info.sh`);
344
361
  },
@@ -381,7 +398,7 @@ class UnderpostRun {
381
398
  shellExec(`node bin run sync-replica template-deploy${nodeOptions}`);
382
399
  shellExec(`node bin env clean`);
383
400
  for (const deployId of fs.readFileSync('./engine-private/deploy/dd.router', 'utf8').split(','))
384
- shellExec(`node bin/deploy update-default-conf ${deployId.trim()}`);
401
+ shellExec(`node bin new --default-conf --deploy-id ${deployId.trim()}`);
385
402
  if (path === 'cmt') {
386
403
  shellExec(`git add . && underpost cmt . build cluster-build`);
387
404
  shellExec(`cd engine-private && git add . && underpost cmt . build cluster-build`);
@@ -526,7 +543,7 @@ class UnderpostRun {
526
543
  const baseClusterCommand = options.dev ? ' --dev' : '';
527
544
  const defaultPath = [
528
545
  'dd-default',
529
- 1,
546
+ options.replicas,
530
547
  ``,
531
548
  ``,
532
549
  options.dev || !isDeployRunnerContext(path, options) ? 'kind-control-plane' : os.hostname(),
@@ -541,8 +558,8 @@ class UnderpostRun {
541
558
  if (isDeployRunnerContext(path, options)) {
542
559
  const { validVersion } = UnderpostRepository.API.privateConfUpdate(deployId);
543
560
  if (!validVersion) throw new Error('Version mismatch');
544
- shellExec(`${baseCommand} run${baseClusterCommand} tz`);
545
- 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`);
546
563
  }
547
564
 
548
565
  const currentTraffic = isDeployRunnerContext(path, options)
@@ -553,7 +570,7 @@ class UnderpostRun {
553
570
 
554
571
  shellExec(
555
572
  `${baseCommand} deploy --kubeadm --build-manifest --sync --info-router --replicas ${
556
- replicas ? replicas : 1
573
+ replicas
557
574
  } --node ${node}${image ? ` --image ${image}` : ''}${versions ? ` --versions ${versions}` : ''}${options.namespace ? ` --namespace ${options.namespace}` : ''} dd ${env}`,
558
575
  );
559
576
 
@@ -563,8 +580,8 @@ class UnderpostRun {
563
580
  );
564
581
  if (!targetTraffic)
565
582
  targetTraffic = UnderpostDeploy.API.getCurrentTraffic(deployId, { namespace: options.namespace });
566
- await UnderpostDeploy.API.monitorReadyRunner(deployId, env, targetTraffic);
567
- 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);
568
585
  } else
569
586
  logger.info(
570
587
  'current traffic',
@@ -572,6 +589,61 @@ class UnderpostRun {
572
589
  );
573
590
  },
574
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
+
575
647
  /**
576
648
  * @method tz
577
649
  * @description Sets the system timezone using `timedatectl set-timezone` command.
@@ -580,13 +652,16 @@ class UnderpostRun {
580
652
  * @memberof UnderpostRun
581
653
  */
582
654
  tz: (path, options = UnderpostRun.DEFAULT_OPTION) => {
583
- const tz = path
584
- ? path
585
- : UnderpostRootEnv.API.get('TIME_ZONE', undefined, { disableLog: true })
586
- ? UnderpostRootEnv.API.get('TIME_ZONE')
587
- : process.env.TIME_ZONE
588
- ? process.env.TIME_ZONE
589
- : 'America/New_York';
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';
590
665
  shellExec(`sudo timedatectl set-timezone ${tz}`);
591
666
  },
592
667
 
@@ -652,6 +727,7 @@ class UnderpostRun {
652
727
  const _deployId = `${deployId}-${_id}`;
653
728
  const currentTraffic = UnderpostDeploy.API.getCurrentTraffic(_deployId, {
654
729
  hostTest: _host,
730
+ namespace: options.namespace,
655
731
  });
656
732
  const targetTraffic = currentTraffic ? (currentTraffic === 'blue' ? 'green' : 'blue') : 'blue';
657
733
  let proxyYaml =
@@ -691,7 +767,8 @@ EOF
691
767
  const env = options.dev ? 'development' : 'production';
692
768
  const baseCommand = options.dev ? 'node bin' : 'underpost';
693
769
  const baseClusterCommand = options.dev ? ' --dev' : '';
694
- let [deployId, id, replicas = 1] = path.split(',');
770
+ let [deployId, id, replicas] = path.split(',');
771
+ if (!replicas) replicas = options.replicas;
695
772
  const confInstances = JSON.parse(
696
773
  fs.readFileSync(`./engine-private/conf/${deployId}/conf.instances.json`, 'utf8'),
697
774
  );
@@ -726,11 +803,12 @@ EOF
726
803
 
727
804
  const currentTraffic = UnderpostDeploy.API.getCurrentTraffic(_deployId, {
728
805
  hostTest: _host,
806
+ namespace: options.namespace,
729
807
  });
730
808
 
731
809
  const targetTraffic = currentTraffic ? (currentTraffic === 'blue' ? 'green' : 'blue') : 'blue';
732
810
  const podId = `${_deployId}-${env}-${targetTraffic}`;
733
- const ignorePods = UnderpostDeploy.API.get(podId).map((p) => p.NAME);
811
+ const ignorePods = UnderpostDeploy.API.get(podId, 'pods', options.namespace).map((p) => p.NAME);
734
812
  UnderpostDeploy.API.configMap(env, options.namespace);
735
813
  shellExec(`kubectl delete service ${podId}-service --namespace ${options.namespace} --ignore-not-found`);
736
814
  shellExec(`kubectl delete deployment ${podId} --namespace ${options.namespace} --ignore-not-found`);
@@ -769,6 +847,8 @@ EOF
769
847
  env,
770
848
  targetTraffic,
771
849
  ignorePods,
850
+ options.namespace,
851
+ options.logType,
772
852
  );
773
853
 
774
854
  if (!ready) {
@@ -798,21 +878,6 @@ EOF
798
878
  'ls-deployments': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
799
879
  console.table(await UnderpostDeploy.API.get(path, 'deployments', options.namespace));
800
880
  },
801
- /**
802
- * @method ls-images
803
- * @description Retrieves and logs a table of currently loaded Docker images in the 'kind-worker' node using `UnderpostDeploy.API.getCurrentLoadedImages`.
804
- * @param {string} path - The input value, identifier, or path for the operation.
805
- * @param {Object} options - The default underpost runner options for customizing workflow
806
- * @memberof UnderpostRun
807
- */
808
- 'ls-images': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
809
- console.table(
810
- UnderpostDeploy.API.getCurrentLoadedImages(
811
- options.nodeName ? options.nodeName : 'kind-worker',
812
- path === 'spec' ? true : false,
813
- ),
814
- );
815
- },
816
881
 
817
882
  /**
818
883
  * @method host-update
@@ -858,9 +923,7 @@ EOF
858
923
  }
859
924
 
860
925
  if (!currentImage)
861
- shellExec(
862
- `${baseCommand} dockerfile-pull-base-images${baseClusterCommand} ${options.dev ? '--kind-load' : '--kubeadm-load'}`,
863
- );
926
+ shellExec(`${baseCommand} image${baseClusterCommand} --pull-base ${options.dev ? '--kind' : '--kubeadm'}`);
864
927
  // shellExec(`kubectl delete pod ${podName} --ignore-not-found`);
865
928
 
866
929
  const payload = {
@@ -917,7 +980,7 @@ EOF
917
980
  switch (path) {
918
981
  case 'tf-vae-test':
919
982
  {
920
- const nameSpace = options.namespace || 'default';
983
+ const nameSpace = options.namespace;
921
984
  const podName = path;
922
985
  const basePath = '/home/dd';
923
986
  const scriptPath = '/site/en/tutorials/generative/cvae.py';
@@ -1062,12 +1125,12 @@ EOF
1062
1125
  for (const deployId of fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8').split(',')) {
1063
1126
  const currentTraffic = UnderpostDeploy.API.getCurrentTraffic(deployId, { namespace: options.namespace });
1064
1127
  const targetTraffic = currentTraffic === 'blue' ? 'green' : 'blue';
1065
- UnderpostDeploy.API.switchTraffic(deployId, inputEnv, targetTraffic, inputReplicas);
1128
+ UnderpostDeploy.API.switchTraffic(deployId, inputEnv, targetTraffic, inputReplicas, options.namespace);
1066
1129
  }
1067
1130
  } else {
1068
1131
  const currentTraffic = UnderpostDeploy.API.getCurrentTraffic(inputDeployId, { namespace: options.namespace });
1069
1132
  const targetTraffic = currentTraffic === 'blue' ? 'green' : 'blue';
1070
- UnderpostDeploy.API.switchTraffic(inputDeployId, inputEnv, targetTraffic, inputReplicas);
1133
+ UnderpostDeploy.API.switchTraffic(inputDeployId, inputEnv, targetTraffic, inputReplicas, options.namespace);
1071
1134
  }
1072
1135
  },
1073
1136
  /**
@@ -1098,44 +1161,45 @@ EOF
1098
1161
  const env = options.dev ? 'development' : 'production';
1099
1162
  const baseCommand = options.dev ? 'node bin' : 'underpost';
1100
1163
  const baseClusterCommand = options.dev ? ' --dev' : '';
1164
+ const clusterType = options.k3s ? 'k3s' : 'kubeadm';
1101
1165
  shellCd(`/home/dd/engine`);
1102
1166
  shellExec(`${baseCommand} cluster${baseClusterCommand} --reset`);
1103
1167
  await timer(5000);
1104
- shellExec(`${baseCommand} cluster${baseClusterCommand} --kubeadm`);
1168
+ shellExec(`${baseCommand} cluster${baseClusterCommand} --${clusterType}`);
1105
1169
  await timer(5000);
1106
1170
  let [runtimeImage, deployList] = path.split(',')
1107
1171
  ? path.split(',')
1108
- : ['lampp', fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8').replaceAll(',', '+')];
1172
+ : ['express', fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8').replaceAll(',', '+')];
1109
1173
  shellExec(
1110
- `${baseCommand} dockerfile-pull-base-images${baseClusterCommand}${
1111
- runtimeImage ? ` --path /home/dd/engine/src/runtime/${runtimeImage}` : ''
1112
- } --kubeadm-load`,
1174
+ `${baseCommand} image${baseClusterCommand}${
1175
+ runtimeImage ? ` --pull-base --path /home/dd/engine/src/runtime/${runtimeImage}` : ''
1176
+ } --${clusterType}`,
1113
1177
  );
1114
1178
  if (!deployList) {
1115
1179
  deployList = [];
1116
1180
  logger.warn('No deploy list provided');
1117
1181
  } else deployList = deployList.split('+');
1118
1182
  await timer(5000);
1119
- shellExec(`${baseCommand} cluster${baseClusterCommand} --kubeadm --pull-image --mongodb`);
1183
+ shellExec(`${baseCommand} cluster${baseClusterCommand} --${clusterType} --pull-image --mongodb`);
1120
1184
  if (runtimeImage === 'lampp') {
1121
1185
  await timer(5000);
1122
- shellExec(`${baseCommand} cluster${baseClusterCommand} --kubeadm --pull-image --mariadb`);
1186
+ shellExec(`${baseCommand} cluster${baseClusterCommand} --${clusterType} --pull-image --mariadb`);
1123
1187
  }
1124
1188
  await timer(5000);
1125
1189
  for (const deployId of deployList) {
1126
1190
  shellExec(`${baseCommand} db ${deployId} --import --git`);
1127
1191
  }
1128
1192
  await timer(5000);
1129
- shellExec(`${baseCommand} cluster${baseClusterCommand} --kubeadm --pull-image --valkey`);
1193
+ shellExec(`${baseCommand} cluster${baseClusterCommand} --${clusterType} --pull-image --valkey`);
1130
1194
  await timer(5000);
1131
- shellExec(`${baseCommand} cluster${baseClusterCommand} --kubeadm --contour`);
1195
+ shellExec(`${baseCommand} cluster${baseClusterCommand} --${clusterType} --contour`);
1132
1196
  if (env === 'production') {
1133
1197
  await timer(5000);
1134
- shellExec(`${baseCommand} cluster${baseClusterCommand} --kubeadm --cert-manager`);
1198
+ shellExec(`${baseCommand} cluster${baseClusterCommand} --${clusterType} --cert-manager`);
1135
1199
  }
1136
1200
  for (const deployId of deployList) {
1137
1201
  shellExec(
1138
- `${baseCommand} deploy ${deployId} ${env} --kubeadm${env === 'production' ? ' --cert' : ''}${
1202
+ `${baseCommand} deploy ${deployId} ${env} --${clusterType}${env === 'production' ? ' --cert' : ''}${
1139
1203
  env === 'development' ? ' --etc-hosts' : ''
1140
1204
  }`,
1141
1205
  );
@@ -1155,13 +1219,50 @@ EOF
1155
1219
  const currentTraffic = UnderpostDeploy.API.getCurrentTraffic(deployId, { namespace: options.namespace });
1156
1220
  const targetTraffic = currentTraffic === 'blue' ? 'green' : 'blue';
1157
1221
  const env = 'production';
1158
- const ignorePods = UnderpostDeploy.API.get(`${deployId}-${env}-${targetTraffic}`).map((p) => p.NAME);
1222
+ const ignorePods = UnderpostDeploy.API.get(`${deployId}-${env}-${targetTraffic}`, 'pods', options.namespace).map(
1223
+ (p) => p.NAME,
1224
+ );
1159
1225
 
1160
1226
  shellExec(`sudo kubectl rollout restart deployment/${deployId}-${env}-${targetTraffic} -n ${options.namespace}`);
1161
1227
 
1162
- await UnderpostDeploy.API.monitorReadyRunner(deployId, env, targetTraffic, ignorePods);
1228
+ await UnderpostDeploy.API.monitorReadyRunner(
1229
+ deployId,
1230
+ env,
1231
+ targetTraffic,
1232
+ ignorePods,
1233
+ options.namespace,
1234
+ 'underpost',
1235
+ );
1236
+
1237
+ UnderpostDeploy.API.switchTraffic(deployId, env, targetTraffic, options.replicas, options.namespace);
1238
+ },
1163
1239
 
1164
- UnderpostDeploy.API.switchTraffic(deployId, env, targetTraffic);
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`);
1165
1266
  },
1166
1267
 
1167
1268
  /**
@@ -1234,6 +1335,7 @@ EOF
1234
1335
  const baseClusterCommand = options.dev ? ' --dev' : '';
1235
1336
  shellCd(`/home/dd/engine`);
1236
1337
  let [deployId, serviceId, host, _path, replicas, image, node] = path.split(',');
1338
+ if (!replicas) replicas = options.replicas;
1237
1339
  // const confClient = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.client.json`, 'utf8'));
1238
1340
  const confServer = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'));
1239
1341
  // const confSSR = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.ssr.json`, 'utf8'));
@@ -1298,7 +1400,7 @@ EOF
1298
1400
  if (!node) node = os.hostname();
1299
1401
  shellExec(
1300
1402
  `${baseCommand} deploy${options.dev ? '' : ' --kubeadm'}${options.devProxyPortOffset ? ' --disable-deployment-proxy' : ''} --build-manifest --sync --info-router --replicas ${
1301
- replicas ? replicas : 1
1403
+ replicas
1302
1404
  } --node ${node}${image ? ` --image ${image}` : ''}${versions ? ` --versions ${versions}` : ''} dd ${env}`,
1303
1405
  );
1304
1406
  shellExec(
@@ -1358,7 +1460,7 @@ EOF
1358
1460
  shellExec(`underpost run secret`);
1359
1461
  shellCd(`/home/dd/engine`);
1360
1462
  shellExec(`underpost cmt --empty . ci engine ' New engine release $(underpost --version)'`);
1361
- shellExec(`underpost push . ${process.env.GITHUB_USERNAME}/engine`);
1463
+ shellExec(`underpost push . ${process.env.GITHUB_USERNAME}/engine`, { silent: true });
1362
1464
  },
1363
1465
 
1364
1466
  /**
@@ -1456,7 +1558,7 @@ EOF
1456
1558
  const tty = options.tty ? 'true' : 'false';
1457
1559
  const stdin = options.stdin ? 'true' : 'false';
1458
1560
  const restartPolicy = options.restartPolicy || 'Never';
1459
- const kind = options.kind || 'Pod';
1561
+ const kindType = options.kindType || 'Pod';
1460
1562
  const imagePullPolicy = options.imagePullPolicy || 'IfNotPresent';
1461
1563
  const hostNetwork = options.hostNetwork ? options.hostNetwork : '';
1462
1564
  const apiVersion = options.apiVersion || 'v1';
@@ -1480,7 +1582,7 @@ EOF
1480
1582
 
1481
1583
  const cmd = `kubectl apply -f - <<EOF
1482
1584
  apiVersion: ${apiVersion}
1483
- kind: ${kind}
1585
+ kind: ${kindType}
1484
1586
  metadata:
1485
1587
  name: ${podName}
1486
1588
  namespace: ${namespace}
@@ -1552,6 +1654,8 @@ EOF`;
1552
1654
  if (options.args) options.args = options.args.split(',');
1553
1655
  if (!options.underpostRoot) options.underpostRoot = underpostRoot;
1554
1656
  if (!options.namespace) options.namespace = 'default';
1657
+ if (options.replicas === '' || options.replicas === null || options.replicas === undefined)
1658
+ options.replicas = 1;
1555
1659
  options.npmRoot = npmRoot;
1556
1660
  logger.info('callback', { path, options });
1557
1661
  if (!(runner in UnderpostRun.RUNNERS)) throw new Error(`Runner not found: ${runner}`);