@underpostnet/underpost 2.99.1 → 2.99.5

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 (42) hide show
  1. package/.env.development +0 -3
  2. package/.env.production +1 -3
  3. package/.env.test +0 -3
  4. package/LICENSE +1 -1
  5. package/README.md +30 -30
  6. package/baremetal/commission-workflows.json +52 -0
  7. package/bin/deploy.js +101 -47
  8. package/cli.md +47 -43
  9. package/examples/static-page/README.md +55 -378
  10. package/examples/static-page/ssr-components/CustomPage.js +1 -13
  11. package/jsconfig.json +4 -2
  12. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  13. package/manifests/deployment/dd-test-development/deployment.yaml +2 -2
  14. package/manifests/deployment/playwright/deployment.yaml +52 -0
  15. package/package.json +2 -2
  16. package/scripts/disk-devices.sh +13 -0
  17. package/scripts/rocky-pwa.sh +2 -2
  18. package/scripts/ssl.sh +12 -6
  19. package/src/api/user/user.model.js +1 -0
  20. package/src/cli/baremetal.js +576 -176
  21. package/src/cli/cloud-init.js +97 -79
  22. package/src/cli/deploy.js +6 -24
  23. package/src/cli/env.js +4 -1
  24. package/src/cli/image.js +7 -40
  25. package/src/cli/index.js +37 -7
  26. package/src/cli/repository.js +3 -1
  27. package/src/cli/run.js +109 -92
  28. package/src/cli/secrets.js +0 -34
  29. package/src/cli/static.js +0 -26
  30. package/src/cli/test.js +13 -1
  31. package/src/client/components/core/Polyhedron.js +896 -7
  32. package/src/client/components/core/Translate.js +4 -0
  33. package/src/client/services/default/default.management.js +12 -2
  34. package/src/index.js +27 -1
  35. package/src/runtime/express/Express.js +3 -3
  36. package/src/server/conf.js +6 -4
  37. package/src/server/logger.js +33 -31
  38. package/src/server/process.js +27 -2
  39. package/src/server/proxy.js +4 -6
  40. package/src/server/tls.js +30 -25
  41. package/examples/static-page/QUICK-REFERENCE.md +0 -481
  42. package/examples/static-page/STATIC-GENERATOR-GUIDE.md +0 -757
package/src/cli/run.js CHANGED
@@ -80,6 +80,11 @@ const logger = loggerFactory(import.meta);
80
80
  * @property {string} user - The user to run as.
81
81
  * @property {string} pid - The process ID.
82
82
  * @property {boolean} disablePrivateConfUpdate - Whether to disable private configuration updates.
83
+ * @property {string} monitorStatus - The monitor status option.
84
+ * @property {string} monitorStatusKindType - The monitor status kind type option.
85
+ * @property {string} monitorStatusDeltaMs - The monitor status delta in milliseconds.
86
+ * @property {string} monitorStatusMaxAttempts - The maximum number of attempts for monitor status.
87
+ * @property {boolean} logs - Whether to enable logs.
83
88
  * @memberof UnderpostRun
84
89
  */
85
90
  const DEFAULT_OPTION = {
@@ -134,6 +139,11 @@ const DEFAULT_OPTION = {
134
139
  user: '',
135
140
  pid: '',
136
141
  disablePrivateConfUpdate: false,
142
+ monitorStatus: '',
143
+ monitorStatusKindType: '',
144
+ monitorStatusDeltaMs: '',
145
+ monitorStatusMaxAttempts: '',
146
+ logs: false,
137
147
  };
138
148
 
139
149
  /**
@@ -997,86 +1007,6 @@ EOF
997
1007
  shellExec(`${underpostRoot}/scripts/ip-info.sh ${path}`);
998
1008
  },
999
1009
 
1000
- /**
1001
- * @method monitor
1002
- * @description Monitors a specific pod (identified by `path`) for the existence of a file (`/await`), and performs conditional actions (like file copying and opening Firefox) when the file is removed.
1003
- * @param {string} path - The input value, identifier, or path for the operation (used as the name of the pod to monitor).
1004
- * @param {Object} options - The default underpost runner options for customizing workflow
1005
- * @memberof UnderpostRun
1006
- */
1007
- monitor: (path, options = DEFAULT_OPTION) => {
1008
- const pid = getTerminalPid();
1009
- logger.info('monitor pid', pid);
1010
- const checkPath = '/await';
1011
- const _monitor = async () => {
1012
- const result = Underpost.deploy.existsContainerFile({ podName: path, path: checkPath });
1013
- logger.info('monitor', result);
1014
- if (result === true) {
1015
- switch (path) {
1016
- case 'tf-vae-test':
1017
- {
1018
- const nameSpace = options.namespace;
1019
- const podName = path;
1020
- const basePath = '/home/dd';
1021
- const scriptPath = '/site/en/tutorials/generative/cvae.py';
1022
- // shellExec(
1023
- // `sudo kubectl cp ${nameSpace}/${podName}:${basePath}/docs${scriptPath} ${basePath}/lab/src/${scriptPath
1024
- // .split('/')
1025
- // .pop()}`,
1026
- // );
1027
- // const file = fs.readFileSync(`${basePath}/lab/src/${scriptPath.split('/').pop()}`, 'utf8');
1028
- // fs.writeFileSync(
1029
- // `${basePath}/lab/src/${scriptPath.split('/').pop()}`,
1030
- // file.replace(
1031
- // `import time`,
1032
- // `import time
1033
- // print('=== SCRIPT UPDATE TEST ===')`,
1034
- // ),
1035
- // 'utf8',
1036
- // );
1037
- shellExec(
1038
- `sudo kubectl cp ${basePath}/lab/src/${scriptPath
1039
- .split('/')
1040
- .pop()} ${nameSpace}/${podName}:${basePath}/docs${scriptPath}`,
1041
- );
1042
- // shellExec(`sudo kubectl exec -i ${podName} -- sh -c "ipython ${basePath}/docs${scriptPath}"`);
1043
- shellExec(`sudo kubectl exec -i ${podName} -- sh -c "rm -rf ${checkPath}"`);
1044
-
1045
- {
1046
- const checkPath = `/latent_space_plot.png`;
1047
- const outsPaths = [];
1048
- logger.info('monitor', checkPath);
1049
- while (!Underpost.deploy.existsContainerFile({ podName, path: `/home/dd/docs${checkPath}` }))
1050
- await timer(1000);
1051
-
1052
- {
1053
- const toPath = `${basePath}/lab${checkPath}`;
1054
- outsPaths.push(toPath);
1055
- shellExec(`sudo kubectl cp ${nameSpace}/${podName}:${basePath}/docs${checkPath} ${toPath}`);
1056
- }
1057
-
1058
- for (let i of range(1, 10)) {
1059
- i = `/image_at_epoch_${setPad(i, '0', 4)}.png`;
1060
- const toPath = `${basePath}/lab/${i}`;
1061
- outsPaths.push(toPath);
1062
- shellExec(`sudo kubectl cp ${nameSpace}/${podName}:${basePath}/docs${i} ${toPath}`);
1063
- }
1064
- openTerminal(`firefox ${outsPaths.join(' ')}`, { single: true });
1065
- }
1066
- shellExec(`sudo kill -9 ${pid}`);
1067
- }
1068
- break;
1069
-
1070
- default:
1071
- break;
1072
- }
1073
- return;
1074
- }
1075
- await timer(1000);
1076
- _monitor();
1077
- };
1078
- _monitor();
1079
- },
1080
1010
  /**
1081
1011
  * @method db-client
1082
1012
  * @description Deploys and exposes the Adminer database client application (using `adminer:4.7.6-standalone` image) on the cluster.
@@ -1134,15 +1064,20 @@ EOF
1134
1064
  `git config user.email '${email}' && ` +
1135
1065
  `git config credential.interactive always &&` +
1136
1066
  `git config pull.rebase false`,
1067
+ {
1068
+ disableLog: true,
1069
+ silent: true,
1070
+ },
1137
1071
  );
1138
1072
 
1139
- console.log(
1140
- shellExec(`git config list`, { silent: true, stdout: true })
1141
- .replaceAll('user.email', 'user.email'.yellow)
1142
- .replaceAll(username, username.green)
1143
- .replaceAll('user.name', 'user.name'.yellow)
1144
- .replaceAll(email, email.green),
1145
- );
1073
+ if (options.logs)
1074
+ console.log(
1075
+ shellExec(`git config list`, { silent: true, stdout: true })
1076
+ .replaceAll('user.email', 'user.email'.yellow)
1077
+ .replaceAll(username, username.green)
1078
+ .replaceAll('user.name', 'user.name'.yellow)
1079
+ .replaceAll(email, email.green),
1080
+ );
1146
1081
  },
1147
1082
 
1148
1083
  /**
@@ -1299,6 +1234,19 @@ EOF
1299
1234
  shellExec(`./scripts/disk-clean.sh`);
1300
1235
  },
1301
1236
 
1237
+ /**
1238
+ * @method disk-devices
1239
+ * @description Executes the `disk-devices.sh` script to display information about disk devices.
1240
+ * @param {string} path - The input value, identifier, or path for the operation.
1241
+ * @param {Object} options - The default underpost runner options for customizing workflow
1242
+ * @memberof UnderpostRun
1243
+ */
1244
+ 'disk-devices': async (path = '/', options = DEFAULT_OPTION) => {
1245
+ const { underpostRoot } = options;
1246
+ shellExec(`chmod +x ${underpostRoot}/scripts/disk-devices.sh`);
1247
+ shellExec(`${underpostRoot}/scripts/disk-devices.sh`);
1248
+ },
1249
+
1302
1250
  /**
1303
1251
  * @method disk-usage
1304
1252
  * @description Displays disk usage statistics using the `du` command, sorted by size.
@@ -1370,7 +1318,11 @@ EOF
1370
1318
  });
1371
1319
  }
1372
1320
  await awaitDeployMonitor(true);
1373
- shellExec(`npm run dev-proxy ${deployId} ${subConf} ${host} ${_path}${options.tls ? ' tls' : ''}`);
1321
+ shellExec(
1322
+ `./node_modules/.bin/env-cmd -f .env.development node src/proxy proxy ${deployId} ${subConf} ${host} ${_path}${
1323
+ options.tls ? ' tls' : ''
1324
+ }`,
1325
+ );
1374
1326
  },
1375
1327
 
1376
1328
  /**
@@ -1640,15 +1592,74 @@ EOF
1640
1592
  * @memberof UnderpostRun
1641
1593
  */
1642
1594
  'tf-vae-test': async (path, options = DEFAULT_OPTION) => {
1643
- const { underpostRoot } = options;
1644
1595
  const podName = 'tf-vae-test';
1645
1596
  await Underpost.run.CALL('deploy-job', '', {
1597
+ logs: options.logs,
1646
1598
  podName,
1647
1599
  // volumeMountPath: '/custom_images',
1648
1600
  // volumeHostPath: '/home/dd/engine/src/client/public/cyberia/assets/skin',
1649
1601
  on: {
1650
1602
  init: async () => {
1651
- openTerminal(`node bin run --dev monitor ${podName}`);
1603
+ // const pid = getTerminalPid();
1604
+ // shellExec(`sudo kill -9 ${pid}`);
1605
+ (async () => {
1606
+ const nameSpace = options.namespace;
1607
+ const basePath = '/home/dd';
1608
+ const scriptPath = '/site/en/tutorials/generative/cvae.py';
1609
+
1610
+ const { close } = await (async () => {
1611
+ const checkAwaitPath = '/await';
1612
+ while (!Underpost.deploy.existsContainerFile({ podName, path: checkAwaitPath })) {
1613
+ logger.info('monitor', checkAwaitPath);
1614
+ await timer(1000);
1615
+ }
1616
+
1617
+ return {
1618
+ close: () => shellExec(`sudo kubectl exec -i ${podName} -- sh -c "rm -rf ${checkAwaitPath}"`),
1619
+ };
1620
+ })();
1621
+
1622
+ const localScriptPath = `${basePath}/lab/src/${scriptPath.split('/').pop()}`;
1623
+ if (!fs.existsSync(localScriptPath)) {
1624
+ throw new Error(`Local override script not found: ${localScriptPath}`);
1625
+ }
1626
+
1627
+ shellExec(`sudo kubectl cp ${localScriptPath} ${nameSpace}/${podName}:${basePath}/docs${scriptPath}`);
1628
+
1629
+ close();
1630
+
1631
+ {
1632
+ const checkPath = `/latent_space_plot.png`;
1633
+ const outsPaths = [];
1634
+ const labDir = `${basePath}/lab`;
1635
+
1636
+ logger.info('monitor', checkPath);
1637
+ {
1638
+ const checkAwaitPath = `/home/dd/docs${checkPath}`;
1639
+ while (!Underpost.deploy.existsContainerFile({ podName, path: checkAwaitPath })) {
1640
+ logger.info('waiting for', checkAwaitPath);
1641
+ await timer(1000);
1642
+ }
1643
+ }
1644
+
1645
+ {
1646
+ const toPath = `${labDir}${checkPath}`;
1647
+ outsPaths.push(toPath);
1648
+ shellExec(`sudo kubectl cp ${nameSpace}/${podName}:${basePath}/docs${checkPath} ${toPath}`);
1649
+ }
1650
+
1651
+ for (let i of range(1, 10)) {
1652
+ const fileName = `image_at_epoch_${setPad(i, '0', 4)}.png`;
1653
+ const fromPath = `/${fileName}`;
1654
+ const toPath = `${labDir}/${fileName}`;
1655
+ outsPaths.push(toPath);
1656
+ shellExec(`sudo kubectl cp ${nameSpace}/${podName}:${basePath}/docs${fromPath} ${toPath}`);
1657
+ }
1658
+
1659
+ openTerminal(`firefox ${outsPaths.join(' ')}`, { single: true });
1660
+ process.exit(0);
1661
+ }
1662
+ })();
1652
1663
  },
1653
1664
  },
1654
1665
  args: [
@@ -1873,10 +1884,16 @@ EOF`;
1873
1884
  shellExec(`kubectl delete pod ${podName} -n ${namespace} --ignore-not-found`);
1874
1885
  console.log(cmd);
1875
1886
  shellExec(cmd, { disableLog: true });
1876
- const successInstance = await Underpost.test.statusMonitor(podName);
1887
+ const successInstance = await Underpost.test.statusMonitor(
1888
+ podName,
1889
+ options.monitorStatus || 'Running',
1890
+ options.monitorStatusKindType || 'pods',
1891
+ options.monitorStatusDeltaMs || 1000,
1892
+ options.monitorStatusMaxAttempts || 600,
1893
+ );
1877
1894
  if (successInstance) {
1878
1895
  options.on?.init ? await options.on.init() : null;
1879
- shellExec(`kubectl logs -f ${podName} -n ${namespace}`);
1896
+ if (options.logs) shellExec(`kubectl logs -f ${podName} -n ${namespace}`, { async: true });
1880
1897
  }
1881
1898
  },
1882
1899
  };
@@ -18,40 +18,6 @@ dotenv.config();
18
18
  */
19
19
  class UnderpostSecret {
20
20
  static API = {
21
- /**
22
- * @method docker
23
- * @description Manages the secrets of the application.
24
- * @memberof UnderpostSecret
25
- */
26
- docker: {
27
- /**
28
- * @method init
29
- * @description Initializes the docker secrets.
30
- * @memberof UnderpostSecret
31
- */
32
- init() {
33
- shellExec(`docker swarm init`);
34
- },
35
- /**
36
- * @method createFromEnvFile
37
- * @description Creates a secret from an env file.
38
- * @param {string} envPath - The path to the env file.
39
- * @memberof UnderpostSecret
40
- */
41
- createFromEnvFile(envPath) {
42
- const envObj = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
43
- for (const key of Object.keys(envObj)) {
44
- Underpost.secret.docker.set(key, envObj[key]);
45
- }
46
- },
47
- set(key, value) {
48
- shellExec(`docker secret rm ${key}`);
49
- shellExec(`echo "${value}" | docker secret create ${key} -`);
50
- },
51
- list() {
52
- shellExec(`docker secret ls`);
53
- },
54
- },
55
21
  /**
56
22
  * @method underpost
57
23
  * @description Manages the secrets of the application.
package/src/cli/static.js CHANGED
@@ -68,11 +68,8 @@ const logger = loggerFactory(import.meta);
68
68
  * @property {string} [page=''] - SSR component path to render
69
69
  * @property {string} [title='Home'] - Page title (deprecated: use metadata.title)
70
70
  * @property {string} [outputPath='.'] - Output file path
71
- * @property {string} [deployId=''] - Deployment identifier
72
- * @property {string} [buildHost=''] - Build host URL
73
71
  * @property {string} [buildPath='/'] - Build path
74
72
  * @property {string} [env='production'] - Environment (development/production)
75
- * @property {boolean} [build=false] - Whether to trigger build
76
73
  * @property {boolean} [dev=false] - Development mode flag
77
74
  * @property {boolean} [minify=true] - Minify HTML output
78
75
  * @property {MetadataOptions} [metadata={}] - Comprehensive metadata options
@@ -95,11 +92,8 @@ const DefaultStaticGenerationOptions = {
95
92
  page: '',
96
93
  title: '',
97
94
  outputPath: '',
98
- deployId: '',
99
- buildHost: '',
100
95
  buildPath: '/',
101
96
  env: 'production',
102
- build: false,
103
97
  dev: false,
104
98
  minify: true,
105
99
  metadata: {},
@@ -385,11 +379,8 @@ class UnderpostStatic {
385
379
  * @param {string} [options.page] - Path to the SSR component to render
386
380
  * @param {string} [options.title] - Page title (deprecated: use metadata.title)
387
381
  * @param {string} [options.outputPath] - Output file path
388
- * @param {string} [options.deployId] - Deployment identifier
389
- * @param {string} [options.buildHost] - Build host URL
390
382
  * @param {string} [options.buildPath='/'] - Build path
391
383
  * @param {string} [options.env='production'] - Environment (development/production)
392
- * @param {boolean} [options.build=false] - Whether to trigger build
393
384
  * @param {boolean} [options.minify=true] - Minify HTML output
394
385
  * @param {MetadataOptions} [options.metadata={}] - Comprehensive metadata options
395
386
  * @param {Object} [options.scripts={}] - Script injection options
@@ -601,23 +592,6 @@ class UnderpostStatic {
601
592
  throw error;
602
593
  }
603
594
  }
604
-
605
- // Trigger build if requested
606
- if (options.deployId && options.build) {
607
- try {
608
- logger.info(`Triggering build for deployment: ${options.deployId}`);
609
-
610
- shellExec(`underpost env ${options.deployId} ${options.env}`);
611
- shellExec(
612
- `npm run build ${options.deployId}${options.buildHost ? ` ${options.buildHost} ${options.buildPath}` : ``}`,
613
- );
614
-
615
- logger.info('Build completed successfully');
616
- } catch (error) {
617
- logger.error(`Build error: ${error.message}`);
618
- throw error;
619
- }
620
- }
621
595
  },
622
596
 
623
597
  /**
package/src/cli/test.js CHANGED
@@ -59,7 +59,19 @@ class UnderpostTest {
59
59
  * @param {number} options.maxAttempts - The maximum number of attempts.
60
60
  * @memberof UnderpostTest
61
61
  */
62
- async callback(deployList = '', options = { itc: false, sh: false, logs: false }) {
62
+ async callback(
63
+ deployList = '',
64
+ options = {
65
+ itc: false,
66
+ sh: false,
67
+ logs: false,
68
+ podName: '',
69
+ podStatus: '',
70
+ kindType: '',
71
+ deltaMs: 1000,
72
+ maxAttempts: 60 * 5,
73
+ },
74
+ ) {
63
75
  if (
64
76
  options.podName &&
65
77
  typeof options.podName === 'string' &&