underpost 2.89.35 → 2.89.44

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 (44) hide show
  1. package/README.md +4 -2
  2. package/bin/deploy.js +22 -15
  3. package/cli.md +23 -2
  4. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  5. package/manifests/deployment/dd-test-development/deployment.yaml +10 -6
  6. package/manifests/deployment/dd-test-development/proxy.yaml +2 -0
  7. package/manifests/deployment/kafka/deployment.yaml +0 -2
  8. package/manifests/deployment/spark/spark-pi-py.yaml +0 -1
  9. package/manifests/deployment/tensorflow/tf-gpu-test.yaml +0 -2
  10. package/manifests/envoy-service-nodeport.yaml +0 -1
  11. package/manifests/kubeadm-calico-config.yaml +10 -115
  12. package/manifests/letsencrypt-prod.yaml +0 -1
  13. package/manifests/mariadb/statefulset.yaml +1 -1
  14. package/manifests/mongodb/statefulset.yaml +11 -11
  15. package/manifests/mongodb-4.4/service-deployment.yaml +1 -3
  16. package/manifests/mysql/pv-pvc.yaml +1 -1
  17. package/manifests/mysql/statefulset.yaml +1 -1
  18. package/manifests/valkey/service.yaml +0 -1
  19. package/manifests/valkey/statefulset.yaml +2 -3
  20. package/package.json +1 -1
  21. package/scripts/device-scan.sh +43 -21
  22. package/scripts/rpmfusion-ffmpeg-setup.sh +1 -0
  23. package/src/api/user/user.model.js +10 -1
  24. package/src/cli/cluster.js +51 -26
  25. package/src/cli/deploy.js +73 -39
  26. package/src/cli/index.js +22 -1
  27. package/src/cli/monitor.js +9 -5
  28. package/src/cli/repository.js +1 -1
  29. package/src/cli/run.js +38 -21
  30. package/src/client/components/core/Logger.js +1 -1
  31. package/src/client/components/core/Modal.js +5 -0
  32. package/src/client/components/core/ObjectLayerEngineModal.js +334 -71
  33. package/src/client/components/core/ObjectLayerEngineViewer.js +170 -403
  34. package/src/client/components/core/Router.js +10 -1
  35. package/src/client/services/default/default.management.js +25 -5
  36. package/src/index.js +1 -1
  37. package/src/server/client-build.js +5 -4
  38. package/src/server/conf.js +1 -1
  39. package/src/server/start.js +1 -1
  40. package/manifests/kubelet-config.yaml +0 -65
  41. package/manifests/mongodb/backup-access.yaml +0 -16
  42. package/manifests/mongodb/backup-cronjob.yaml +0 -42
  43. package/manifests/mongodb/backup-pv-pvc.yaml +0 -22
  44. package/manifests/mongodb/configmap.yaml +0 -26
package/src/cli/index.js CHANGED
@@ -7,6 +7,8 @@ import { commitData } from '../client/components/core/CommonJs.js';
7
7
  import UnderpostLxd from './lxd.js';
8
8
  import UnderpostBaremetal from './baremetal.js';
9
9
  import UnderpostRun from './run.js';
10
+ import Dns from '../server/dns.js';
11
+ import { pbcopy } from '../server/process.js';
10
12
 
11
13
  // Load environment variables from .env file
12
14
  const underpostRootPath = getUnderpostRootPath();
@@ -129,6 +131,16 @@ program
129
131
  .description('Displays the root path of the npm installation.')
130
132
  .action(() => console.log(getNpmRootPath()));
131
133
 
134
+ program
135
+ .command('ip')
136
+ .option('--copy', 'Copies the IP addresses to the clipboard.')
137
+ .description('Displays the current public machine IP addresses.')
138
+ .action(async (options) => {
139
+ const ip = await Dns.getPublicIp();
140
+ if (options.copy) return pbcopy(ip);
141
+ return console.log(ip);
142
+ });
143
+
132
144
  // 'cluster' command: Manage Kubernetes clusters
133
145
  program
134
146
  .command('cluster')
@@ -146,7 +158,10 @@ program
146
158
  .option('--dedicated-gpu', 'Initializes the cluster with dedicated GPU base resources and environment settings.')
147
159
  .option('--info', 'Retrieves information about all deployed Kubernetes objects.')
148
160
  .option('--full', 'Initializes the cluster with all available statefulsets and services.')
149
- .option('--ns-use <ns-name>', 'Switches the current Kubernetes context to the specified namespace.')
161
+ .option(
162
+ '--ns-use <ns-name>',
163
+ "Switches the current Kubernetes context to the specified namespace (creates if it doesn't exist).",
164
+ )
150
165
  .option('--kubeadm', 'Initializes the cluster using kubeadm for control plane management.')
151
166
  .option('--grafana', 'Initializes the cluster with a Grafana deployment.')
152
167
  .option(
@@ -166,6 +181,7 @@ program
166
181
  .option('--k3s', 'Initializes the cluster using K3s (Lightweight Kubernetes).')
167
182
  .option('--hosts <hosts>', 'A comma-separated list of cluster hostnames or IP addresses.')
168
183
  .option('--remove-volume-host-paths', 'Removes specified volume host paths after execution.')
184
+ .option('--namespace <namespace>', 'Kubernetes namespace for cluster operations (defaults to "default").')
169
185
  .action(Underpost.cluster.init)
170
186
  .description('Manages Kubernetes clusters, defaulting to Kind cluster initialization.');
171
187
 
@@ -205,6 +221,7 @@ program
205
221
  .option('--etc-hosts', 'Enables the etc-hosts context for deployment operations.')
206
222
  .option('--restore-hosts', 'Restores default `/etc/hosts` entries.')
207
223
  .option('--disable-update-underpost-config', 'Disables updates to Underpost configuration during deployment.')
224
+ .option('--namespace <namespace>', 'Kubernetes namespace for deployment operations (defaults to "default").')
208
225
  .description('Manages application deployments, defaulting to deploying development pods.')
209
226
  .action(Underpost.deploy.callback);
210
227
 
@@ -402,6 +419,10 @@ program
402
419
  .option('--runtime-class-name <name>', 'Sets the runtime class name for the job in deploy-job.')
403
420
  .option('--image-pull-policy <policy>', 'Sets the image pull policy for the job in deploy-job.')
404
421
  .option('--api-version <version>', 'Sets the API version for the job manifest in deploy-job.')
422
+ .option(
423
+ '--labels <labels>',
424
+ 'Optional: Specifies a comma-separated list of key-value pairs for labels (e.g., "app=my-app,env=prod").',
425
+ )
405
426
  .option('--claim-name <name>', 'Optional: Specifies the claim name for volume mounting in deploy-job.')
406
427
  .option('--kind <kind-type>', 'Specifies the kind of Kubernetes resource (e.g., Job, Deployment) for deploy-job.')
407
428
  .option('--kubeadm', 'Flag to indicate Kubeadm cluster type context')
@@ -95,12 +95,13 @@ class UnderpostMonitor {
95
95
  if (traffic === 'blue') traffic = 'green';
96
96
  else traffic = 'blue';
97
97
  UnderpostRootEnv.API.set(`${deployId}-${env}-traffic`, traffic);
98
+ const namespace = options.namespace || 'default';
98
99
  shellExec(
99
100
  `node bin deploy --info-router --build-manifest --traffic ${traffic} --replicas ${
100
101
  options.replicas ? options.replicas : 1
101
- } ${deployId} ${env}`,
102
+ } --namespace ${namespace} ${deployId} ${env}`,
102
103
  );
103
- shellExec(`sudo kubectl apply -f ./engine-private/conf/${deployId}/build/${env}/proxy.yaml`);
104
+ shellExec(`sudo kubectl apply -f ./engine-private/conf/${deployId}/build/${env}/proxy.yaml -n ${namespace}`);
104
105
  };
105
106
 
106
107
  const monitor = async (reject) => {
@@ -152,12 +153,15 @@ class UnderpostMonitor {
152
153
  fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'),
153
154
  );
154
155
 
155
- UnderpostDeploy.API.configMap(env);
156
+ const namespace = options.namespace || 'default';
157
+ UnderpostDeploy.API.configMap(env, namespace);
156
158
 
157
159
  for (const host of Object.keys(confServer)) {
158
- shellExec(`sudo kubectl delete HTTPProxy ${host}`);
160
+ shellExec(`sudo kubectl delete HTTPProxy ${host} -n ${namespace} --ignore-not-found`);
159
161
  }
160
- shellExec(`sudo kubectl rollout restart deployment/${deployId}-${env}-${traffic}`);
162
+ shellExec(
163
+ `sudo kubectl rollout restart deployment/${deployId}-${env}-${traffic} -n ${namespace}`,
164
+ );
161
165
 
162
166
  switchTraffic();
163
167
  }
@@ -179,7 +179,7 @@ class UnderpostRepository {
179
179
  return;
180
180
  }
181
181
  if (options.info) return logger.info('', commitData);
182
- const _message = `${commitType}${subModule ? `(${subModule})` : ''}${process.argv.includes('!') ? '!' : ''}: ${
182
+ const _message = `${commitType}${subModule ? `(${subModule})` : ''}: ${
183
183
  commitData[commitType].emoji
184
184
  } ${message ? message : commitData[commitType].description}`;
185
185
  if (options.copy) return pbcopy(_message);
package/src/cli/run.js CHANGED
@@ -81,7 +81,7 @@ class UnderpostRun {
81
81
  volumeMountPath: '',
82
82
  imageName: '',
83
83
  containerName: '',
84
- namespace: '',
84
+ namespace: 'default',
85
85
  build: false,
86
86
  replicas: 1,
87
87
  k3s: false,
@@ -209,10 +209,10 @@ class UnderpostRun {
209
209
  * @memberof UnderpostRun
210
210
  */
211
211
  'tf-gpu-test': (path, options = UnderpostRun.DEFAULT_OPTION) => {
212
- const { underpostRoot } = options;
213
- shellExec(`kubectl delete configmap tf-gpu-test-script`);
214
- shellExec(`kubectl delete pod tf-gpu-test-pod`);
215
- shellExec(`kubectl apply -f ${underpostRoot}/manifests/deployment/tensorflow/tf-gpu-test.yaml`);
212
+ const { underpostRoot, namespace } = options;
213
+ shellExec(`kubectl delete configmap tf-gpu-test-script -n ${namespace} --ignore-not-found`);
214
+ shellExec(`kubectl delete pod tf-gpu-test-pod -n ${namespace} --ignore-not-found`);
215
+ shellExec(`kubectl apply -f ${underpostRoot}/manifests/deployment/tensorflow/tf-gpu-test.yaml -n ${namespace}`);
216
216
  },
217
217
  /**
218
218
  * @method dev-cluster
@@ -340,9 +340,10 @@ class UnderpostRun {
340
340
  * @memberof UnderpostRun
341
341
  */
342
342
  'cluster-build': (path, options = UnderpostRun.DEFAULT_OPTION) => {
343
+ const nodeOptions = options.nodeName ? ` --node-name ${options.nodeName}` : '';
343
344
  shellExec(`node bin run clean`);
344
- shellExec(`node bin run --dev sync-replica template-deploy`);
345
- shellExec(`node bin run sync-replica template-deploy`);
345
+ shellExec(`node bin run --dev sync-replica template-deploy${nodeOptions}`);
346
+ shellExec(`node bin run sync-replica template-deploy${nodeOptions}`);
346
347
  shellExec(`node bin env clean`);
347
348
  for (const deployId of fs.readFileSync('./engine-private/deploy/dd.router', 'utf8').split(','))
348
349
  shellExec(`node bin/deploy update-default-conf ${deployId.trim()}`);
@@ -509,11 +510,13 @@ class UnderpostRun {
509
510
  shellExec(
510
511
  `${baseCommand} deploy --kubeadm --build-manifest --sync --info-router --replicas ${
511
512
  replicas ? replicas : 1
512
- } --node ${node}${image ? ` --image ${image}` : ''}${versions ? ` --versions ${versions}` : ''} dd ${env}`,
513
+ } --node ${node}${image ? ` --image ${image}` : ''}${versions ? ` --versions ${versions}` : ''}${options.namespace ? ` --namespace ${options.namespace}` : ''} dd ${env}`,
513
514
  );
514
515
 
515
516
  if (isDeployRunnerContext(path, options)) {
516
- shellExec(`${baseCommand} deploy --kubeadm --disable-update-proxy ${deployId} ${env} --versions ${versions}`);
517
+ shellExec(
518
+ `${baseCommand} deploy --kubeadm --disable-update-proxy ${deployId} ${env} --versions ${versions}${options.namespace ? ` --namespace ${options.namespace}` : ''}`,
519
+ );
517
520
  if (!targetTraffic) targetTraffic = UnderpostDeploy.API.getCurrentTraffic(deployId);
518
521
  await UnderpostDeploy.API.monitorReadyRunner(deployId, env, targetTraffic);
519
522
  UnderpostDeploy.API.switchTraffic(deployId, env, targetTraffic);
@@ -618,7 +621,7 @@ class UnderpostRun {
618
621
  `docker exec -i kind-worker bash -c "chown -R 1000:1000 ${volumeHostPath} || true; chmod -R 755 ${volumeHostPath}"`,
619
622
  );
620
623
  } else {
621
- shellExec(`kubectl apply -f ${options.underpostRoot}/manifests/pv-pvc-dd.yaml`);
624
+ shellExec(`kubectl apply -f ${options.underpostRoot}/manifests/pv-pvc-dd.yaml -n ${options.namespace}`);
622
625
  }
623
626
 
624
627
  if (!currentImage)
@@ -681,7 +684,7 @@ class UnderpostRun {
681
684
  switch (path) {
682
685
  case 'tf-vae-test':
683
686
  {
684
- const nameSpace = 'default';
687
+ const nameSpace = options.namespace || 'default';
685
688
  const podName = path;
686
689
  const basePath = '/home/dd';
687
690
  const scriptPath = '/site/en/tutorials/generative/cvae.py';
@@ -763,8 +766,8 @@ class UnderpostRun {
763
766
  // For kubeadm/k3s, ensure it's available for containerd
764
767
  shellExec(`sudo crictl pull ${image}`);
765
768
 
766
- shellExec(`kubectl delete deployment adminer`);
767
- shellExec(`kubectl apply -k ${underpostRoot}/manifests/deployment/adminer/.`);
769
+ shellExec(`kubectl delete deployment adminer -n ${options.namespace} --ignore-not-found`);
770
+ shellExec(`kubectl apply -k ${underpostRoot}/manifests/deployment/adminer/. -n ${options.namespace}`);
768
771
  const successInstance = await UnderpostTest.API.statusMonitor('adminer', 'Running', 'pods', 1000, 60 * 10);
769
772
 
770
773
  if (successInstance) {
@@ -921,7 +924,7 @@ class UnderpostRun {
921
924
  const env = 'production';
922
925
  const ignorePods = UnderpostDeploy.API.get(`${deployId}-${env}-${targetTraffic}`).map((p) => p.NAME);
923
926
 
924
- shellExec(`sudo kubectl rollout restart deployment/${deployId}-${env}-${targetTraffic}`);
927
+ shellExec(`sudo kubectl rollout restart deployment/${deployId}-${env}-${targetTraffic} -n ${options.namespace}`);
925
928
 
926
929
  await UnderpostDeploy.API.monitorReadyRunner(deployId, env, targetTraffic, ignorePods);
927
930
 
@@ -1042,9 +1045,9 @@ class UnderpostRun {
1042
1045
  );
1043
1046
  switch (serviceId) {
1044
1047
  case 'mongo-express-service': {
1045
- shellExec(`kubectl delete svc mongo-express-service --ignore-not-found`);
1046
- shellExec(`kubectl delete deployment mongo-express --ignore-not-found`);
1047
- shellExec(`kubectl apply -f manifests/deployment/mongo-express/deployment.yaml`);
1048
+ shellExec(`kubectl delete svc mongo-express-service -n ${options.namespace} --ignore-not-found`);
1049
+ shellExec(`kubectl delete deployment mongo-express -n ${options.namespace} --ignore-not-found`);
1050
+ shellExec(`kubectl apply -f manifests/deployment/mongo-express/deployment.yaml -n ${options.namespace}`);
1048
1051
  podToMonitor = 'mongo-express';
1049
1052
  break;
1050
1053
  }
@@ -1143,7 +1146,11 @@ class UnderpostRun {
1143
1146
  shellExec(`${baseCommand} env ${deployId} ${env}`);
1144
1147
  for (const host of Object.keys(confServer))
1145
1148
  if (_path in confServer[host]) shellExec(`node bin/deploy build-single-replica ${deployId} ${host} ${_path}`);
1146
- const node = options.dev || !isDeployRunnerContext(path, options) ? 'kind-control-plane' : os.hostname();
1149
+ const node = options.nodeName
1150
+ ? options.nodeName
1151
+ : options.dev || !isDeployRunnerContext(path, options)
1152
+ ? 'kind-control-plane'
1153
+ : os.hostname();
1147
1154
  // deployId, replicas, versions, image, node
1148
1155
  let defaultPath = [deployId, 1, ``, ``, node];
1149
1156
  shellExec(`${baseCommand} run${options.dev === true ? ' --dev' : ''} --build sync ${defaultPath}`);
@@ -1220,6 +1227,16 @@ class UnderpostRun {
1220
1227
  const imagePullPolicy = options.imagePullPolicy || 'IfNotPresent';
1221
1228
  const hostNetwork = options.hostNetwork ? options.hostNetwork : '';
1222
1229
  const apiVersion = options.apiVersion || 'v1';
1230
+ const labels = options.labels
1231
+ ? options.labels
1232
+ .split(',')
1233
+ .map((keyValue) => {
1234
+ const [key, value] = keyValue.split('=');
1235
+ return ` ${key}: ${value}
1236
+ `;
1237
+ })
1238
+ .join('')
1239
+ : ` app: ${podName}`;
1223
1240
  if (options.volumeType === 'dev') options.volumeType = 'FileOrCreate';
1224
1241
  const volumeType =
1225
1242
  options.volumeType || (enableVolumeMount && volumeHostPath && fs.statSync(volumeHostPath).isDirectory())
@@ -1235,7 +1252,7 @@ metadata:
1235
1252
  name: ${podName}
1236
1253
  namespace: ${namespace}
1237
1254
  labels:
1238
- app: ${podName}
1255
+ ${labels}
1239
1256
  spec:
1240
1257
  restartPolicy: ${restartPolicy}
1241
1258
  ${runtimeClassName ? ` runtimeClassName: ${runtimeClassName}` : ''}
@@ -1273,13 +1290,13 @@ ${
1273
1290
  : ''
1274
1291
  }
1275
1292
  EOF`;
1276
- shellExec(`kubectl delete pod ${podName} --ignore-not-found`);
1293
+ shellExec(`kubectl delete pod ${podName} -n ${namespace} --ignore-not-found`);
1277
1294
  console.log(cmd);
1278
1295
  shellExec(cmd, { disableLog: true });
1279
1296
  const successInstance = await UnderpostTest.API.statusMonitor(podName);
1280
1297
  if (successInstance) {
1281
1298
  options.on?.init ? await options.on.init() : null;
1282
- shellExec(`kubectl logs -f ${podName}`);
1299
+ shellExec(`kubectl logs -f ${podName} -n ${namespace}`);
1283
1300
  }
1284
1301
  },
1285
1302
  };
@@ -6,7 +6,7 @@ const loggerFactory = (meta, options = { trace: false }) => {
6
6
  const logger = {
7
7
  log: function (type, args) {
8
8
  if (!window.renderPayload.dev) return;
9
- if (options.trace === true) args.push(getCurrentTrace().split('Logger.js:23')[1]);
9
+ if (options.trace === true) args.push(getCurrentTrace().split('Logger.js')[1]);
10
10
  return console[type](`[${meta}] ${new Date().toISOString()} ${type}:`, ...args);
11
11
  },
12
12
  };
@@ -87,6 +87,7 @@ const Modal = {
87
87
  onExpandUiListener: {},
88
88
  onBarUiOpen: {},
89
89
  onBarUiClose: {},
90
+ onReloadModalListener: {},
90
91
  onHome: {},
91
92
  homeModals: options.homeModals ? options.homeModals : [],
92
93
  query: options.query ? `${window.location.search}` : undefined,
@@ -121,6 +122,7 @@ const Modal = {
121
122
  top = `${windowGetH() / 2 - height / 2}px`;
122
123
  left = `${windowGetW() / 2 - width / 2}px`;
123
124
  },
125
+ ...this.Data[idModal],
124
126
  };
125
127
 
126
128
  if (options && 'mode' in options) {
@@ -1387,6 +1389,9 @@ const Modal = {
1387
1389
  if (options.zIndexSync) this.zIndexSync({ idModal });
1388
1390
 
1389
1391
  if (s(`.${idModal}`)) {
1392
+ for (const event of Object.keys(Modal.Data[idModal].onReloadModalListener))
1393
+ await Modal.Data[idModal].onReloadModalListener[event]();
1394
+
1390
1395
  s(`.btn-maximize-${idModal}`).click();
1391
1396
  return;
1392
1397
  }