underpost 2.85.0 → 2.85.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env.development CHANGED
@@ -42,4 +42,5 @@ RPI4_MAC_ADDRESS=changethis
42
42
  NVIDIA_API_KEY=changethis
43
43
  DEFAULT_ADMIN_EMAIL=admin@default.net
44
44
  DEFAULT_ADMIN_PASSWORD=changethis
45
- BASE_API=api
45
+ BASE_API=api
46
+ DEV_PROXY_PORT_OFFSET=200
package/.env.production CHANGED
@@ -51,4 +51,5 @@ NPM_USER=changethis
51
51
  NPM_PASSWORD=changethis
52
52
  BASE_API=api
53
53
  CERTBOT_LIVE_PATH=changethis
54
- CERTBOT_LIVE_PATH_WINDOWS=changethis
54
+ CERTBOT_LIVE_PATH_WINDOWS=changethis
55
+ DEV_PROXY_PORT_OFFSET=200
package/.env.test CHANGED
@@ -42,4 +42,5 @@ RPI4_MAC_ADDRESS=changethis
42
42
  NVIDIA_API_KEY=changethis
43
43
  DEFAULT_ADMIN_EMAIL=admin@default.net
44
44
  DEFAULT_ADMIN_PASSWORD=changethis
45
- BASE_API=api
45
+ BASE_API=api
46
+ DEV_PROXY_PORT_OFFSET=200
@@ -28,18 +28,9 @@ jobs:
28
28
  script: |
29
29
  set -e
30
30
  echo "Starting remote release deploy"
31
- cd /home/dd/engine
32
- npm install -g underpost
33
- underpost run secret
34
31
  underpost run pull
35
32
  underpost run secret
36
- node bin run git-conf
37
- node bin run template-deploy-image
38
- underpost config set GITHUB_USERNAME underpostnet
39
- mkdir -p /home/dd
40
- sudo rm -rf /home/dd/engine
41
- cd /home/dd
42
- underpost clone underpostnet/engine
43
- cd engine
44
- npm install
45
- node bin run ssh-deploy sync-engine-test
33
+ cd /home/dd/engine
34
+ node bin run --dev git-conf admin@underpost.net,underpostnet
35
+ node bin run --dev template-deploy-image
36
+ node bin run --dev ssh-deploy sync-engine-test
@@ -1,4 +1,26 @@
1
1
  [
2
+ {
3
+ "context": "Editor",
4
+ "bindings": {
5
+ "ctrl-c": "editor::Copy",
6
+ "ctrl-x": "editor::Cut",
7
+ "ctrl-v": "editor::Paste",
8
+ "ctrl-shift-c": "editor::CopyAndTrim",
9
+ "ctrl-shift-v": "editor::Paste",
10
+ "cmd-c": "editor::Copy",
11
+ "cmd-x": "editor::Cut",
12
+ "cmd-v": "editor::Paste"
13
+ }
14
+ },
15
+ {
16
+ "context": "Terminal",
17
+ "bindings": {
18
+ "ctrl-shift-c": "terminal::Copy",
19
+ "ctrl-shift-v": "terminal::Paste",
20
+ "cmd-shift-c": "terminal::Copy",
21
+ "cmd-shift-v": "terminal::Paste"
22
+ }
23
+ },
2
24
  {
3
25
  "context": "Editor && edit_prediction",
4
26
  "bindings": {
package/Dockerfile CHANGED
@@ -34,7 +34,9 @@ RUN npm --version
34
34
  RUN npm install -g underpost
35
35
  RUN underpost --version
36
36
 
37
- # Set working directory
37
+ # Create working directory
38
+ RUN mkdir /home/dd
39
+ VOLUME /home/dd
38
40
  WORKDIR /home/dd
39
41
 
40
42
  # Expose necessary ports
package/README.md CHANGED
@@ -18,7 +18,7 @@
18
18
 
19
19
  <!-- badges -->
20
20
 
21
- [![Node.js CI](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml) [![Test](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/coverall.yml) [![Downloads](https://img.shields.io/npm/dm/underpost.svg)](https://www.npmjs.com/package/underpost) [![Socket Badge](https://socket.dev/api/badge/npm/package/underpost/2.85.0)](https://socket.dev/npm/package/underpost/overview/2.85.0) [![Coverage Status](https://coveralls.io/repos/github/underpostnet/engine/badge.svg?branch=master)](https://coveralls.io/github/underpostnet/engine?branch=master) [![Version](https://img.shields.io/npm/v/underpost.svg)](https://www.npmjs.org/package/underpost) [![License](https://img.shields.io/npm/l/underpost.svg)](https://www.npmjs.com/package/underpost)
21
+ [![Node.js CI](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml) [![Test](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/coverall.yml) [![Downloads](https://img.shields.io/npm/dm/underpost.svg)](https://www.npmjs.com/package/underpost) [![Socket Badge](https://socket.dev/api/badge/npm/package/underpost/2.85.7)](https://socket.dev/npm/package/underpost/overview/2.85.7) [![Coverage Status](https://coveralls.io/repos/github/underpostnet/engine/badge.svg?branch=master)](https://coveralls.io/github/underpostnet/engine?branch=master) [![Version](https://img.shields.io/npm/v/underpost.svg)](https://www.npmjs.org/package/underpost) [![License](https://img.shields.io/npm/l/underpost.svg)](https://www.npmjs.com/package/underpost)
22
22
 
23
23
  <!-- end-badges -->
24
24
 
@@ -66,7 +66,7 @@ Run dev client server
66
66
  npm run dev
67
67
  ```
68
68
  <!-- -->
69
- ## underpost ci/cd cli v2.85.0
69
+ ## underpost ci/cd cli v2.85.7
70
70
 
71
71
  ### Usage: `underpost [options] [command]`
72
72
  ```
@@ -75,7 +75,7 @@ npm run dev
75
75
  -h, --help display help for command
76
76
 
77
77
  Commands:
78
- new [options] <app-name> Initializes a new Underpost project, service, or configuration.
78
+ new [options] [app-name] Initializes a new Underpost project, service, or configuration.
79
79
  start [options] <deploy-id> [env] Initiates application servers, build pipelines, or other defined services based on the deployment ID.
80
80
  clone [options] <uri> Clones a specified GitHub repository into the current directory.
81
81
  pull [options] <path> <uri> Pulls the latest changes from a specified GitHub repository.
package/bin/deploy.js CHANGED
@@ -380,6 +380,7 @@ try {
380
380
  }
381
381
 
382
382
  case 'version-build': {
383
+ dotenv.config({ path: `./engine-private/conf/dd-cron/.env.production`, override: true });
383
384
  shellCd(`/home/dd/engine`);
384
385
  shellExec(`node bin/deploy clean-core-repo`);
385
386
  shellExec(`node bin pull . ${process.env.GITHUB_USERNAME}/engine`);
@@ -493,6 +494,7 @@ try {
493
494
  }
494
495
 
495
496
  case 'version-deploy': {
497
+ dotenv.config({ path: `./engine-private/conf/dd-cron/.env.production`, override: true });
496
498
  shellExec(
497
499
  `underpost secret underpost --create-from-file /home/dd/engine/engine-private/conf/dd-cron/.env.production`,
498
500
  );
@@ -1302,8 +1304,8 @@ nvidia/gpu-operator \
1302
1304
 
1303
1305
  case 'tls': {
1304
1306
  fs.mkdirSync(`./engine-private/ssl/localhost`, { recursive: true });
1305
- const targetDir = `./engine-private/ssl/localhost`;
1306
- const domains = ['localhost', '127.0.0.1', '::1'];
1307
+ const targetDir = `./engine-private/ssl/${process.argv[3] ? process.argv[3] : 'localhost'}`;
1308
+ const domains = ['localhost', '127.0.0.1', '::1'].concat(process.argv[3] ? process.argv[3] : []);
1307
1309
  shellExec(`chmod +x ./scripts/ssl.sh`);
1308
1310
  shellExec(`./scripts/ssl.sh ${targetDir} "${domains.join(' ')}"`);
1309
1311
  break;
package/bin/file.js CHANGED
@@ -11,9 +11,12 @@ import {
11
11
  import { shellCd, shellExec } from '../src/server/process.js';
12
12
  import walk from 'ignore-walk';
13
13
  import { validateTemplatePath } from '../src/server/conf.js';
14
+ import dotenv from 'dotenv';
14
15
 
15
16
  const logger = loggerFactory(import.meta);
16
17
 
18
+ dotenv.config({ path: `./engine-private/conf/dd-cron/.env.production`, override: true });
19
+
17
20
  logger.info('argv', process.argv);
18
21
 
19
22
  let [exe, dir, type] = process.argv;
@@ -69,6 +72,7 @@ try {
69
72
  }
70
73
 
71
74
  for (const copyPath of result) {
75
+ if (copyPath === 'NaN') continue;
72
76
  const folder = getDirname(`${toPath}/${copyPath}`);
73
77
  const absolutePath = `${rawPath}/${copyPath}`;
74
78
 
package/bin/vs.js CHANGED
@@ -4,11 +4,11 @@ import { loggerFactory } from '../src/server/logger.js';
4
4
 
5
5
  const logger = loggerFactory(import.meta);
6
6
 
7
- // const vsCodeRootPath = '/root/.vscode-root';
8
- // const vsProgram = 'code';
7
+ const vsCodeRootPath = '/root/.vscode-root';
8
+ const vsProgram = 'code';
9
9
 
10
- const vsCodeRootPath = '/root/.windsurf';
11
- const vsProgram = 'windsurf';
10
+ // const vsCodeRootPath = '/root/.windsurf';
11
+ // const vsProgram = 'windsurf';
12
12
 
13
13
  switch (process.argv[2]) {
14
14
  case 'info': {
package/bin/zed.js CHANGED
@@ -1,11 +1,14 @@
1
1
  import { shellExec } from '../src/server/process.js';
2
2
  import fs from 'fs-extra';
3
3
  import { loggerFactory } from '../src/server/logger.js';
4
+ import { getUnderpostRootPath } from '../src/server/conf.js';
4
5
 
5
6
  const logger = loggerFactory(import.meta);
7
+ const underpostRoot = getUnderpostRootPath();
6
8
 
7
- fs.copyFileSync(`./.vscode/zed.settings.json`, `/root/.config/zed/settings.json`);
8
- fs.copyFileSync(`./.vscode/zed.keymap.json`, `/root/.config/zed/keymap.json`);
9
+ if (!fs.existsSync('/root/.config/zed')) fs.mkdirSync('/root/.config/zed', { recursive: true });
10
+ fs.copyFileSync(`${underpostRoot}/.vscode/zed.settings.json`, `/root/.config/zed/settings.json`);
11
+ fs.copyFileSync(`${underpostRoot}/.vscode/zed.keymap.json`, `/root/.config/zed/keymap.json`);
9
12
 
10
13
  shellExec(`ZED_ALLOW_ROOT=true zed ${process.argv[2] ? process.argv[2] : '.'}`);
11
14
 
package/cli.md CHANGED
@@ -1,4 +1,4 @@
1
- ## underpost ci/cd cli v2.85.0
1
+ ## underpost ci/cd cli v2.85.7
2
2
 
3
3
  ### Usage: `underpost [options] [command]`
4
4
  ```
@@ -7,7 +7,7 @@
7
7
  -h, --help display help for command
8
8
 
9
9
  Commands:
10
- new [options] <app-name> Initializes a new Underpost project, service, or configuration.
10
+ new [options] [app-name] Initializes a new Underpost project, service, or configuration.
11
11
  start [options] <deploy-id> [env] Initiates application servers, build pipelines, or other defined services based on the deployment ID.
12
12
  clone [options] <uri> Clones a specified GitHub repository into the current directory.
13
13
  pull [options] <path> <uri> Pulls the latest changes from a specified GitHub repository.
@@ -42,20 +42,20 @@ Commands:
42
42
 
43
43
  ### `new` :
44
44
  ```
45
- Usage: underpost new [options] <app-name>
45
+ Usage: underpost new [options] [app-name]
46
46
 
47
47
  Initializes a new Underpost project, service, or configuration.
48
48
 
49
49
  Arguments:
50
- app-name The name or deploy-id of the application to create.
50
+ app-name The name of the new project.
51
51
 
52
52
  Options:
53
- --deploy-id Crete deploy ID conf env files
54
- --cluster Create deploy ID cluster files and sync to current
55
- cluster
56
- --dev Sets the development cli context
57
- --sub-conf <sub-conf> Create sub conf env files
58
- -h, --help display help for command
53
+ --deploy-id <deploy-id> Crete deploy ID conf env files
54
+ --sub-conf <sub-conf> Create sub conf env files
55
+ --cluster Create deploy ID cluster files and sync to current
56
+ cluster
57
+ --dev Sets the development cli context
58
+ -h, --help display help for command
59
59
 
60
60
  ```
61
61
 
@@ -623,7 +623,7 @@ Options:
623
623
  Runs a script from the specified path.
624
624
 
625
625
  Arguments:
626
- runner-id The runner ID to run. Options: spark-template, rmi, kill, secret, underpost-config, gpu-env, tf-gpu-test, dev-cluster, ssh-cluster-info, dev-hosts-expose, dev-hosts-restore, cyberia-ide, engine-ide, cluster-build, template-deploy, template-deploy-image, clean, pull, release-deploy, ssh-deploy, ide, sync, ls-deployments, host-update, monitor, db-client, git-conf, promote, metrics, cluster, deploy, sync-replica, tf-vae-test, deploy-job.
626
+ runner-id The runner ID to run. Options: spark-template, rmi, kill, secret, underpost-config, gpu-env, tf-gpu-test, dev-cluster, ssh-cluster-info, dev-hosts-expose, dev-hosts-restore, cyberia-ide, engine-ide, cluster-build, template-deploy, template-deploy-image, clean, pull, release-deploy, ssh-deploy, ide, sync, ls-deployments, ls-images, host-update, dev-container, monitor, db-client, git-conf, promote, metrics, cluster, deploy, dev, service, release-cmt, sync-replica, tf-vae-test, deploy-job.
627
627
  path The absolute or relative directory path where the script is located.
628
628
 
629
629
  Options:
@@ -642,6 +642,10 @@ Options:
642
642
  --kubeadm Flag to indicate Kubeadm cluster type context
643
643
  --k3s Flag to indicate K3s cluster type context
644
644
  --force Forces operation, overriding any warnings or conflicts.
645
+ --tls Enables TLS for the runner execution.
646
+ --reset Resets the runner state before execution.
647
+ --terminal Enables terminal mode for interactive script execution.
648
+ --dev-proxy-port-offset <port-offset> Sets a custom port offset for development proxy.
645
649
  -h, --help display help for command
646
650
 
647
651
  ```
@@ -17,7 +17,7 @@ spec:
17
17
  spec:
18
18
  containers:
19
19
  - name: dd-default-development-blue
20
- image: localhost/rockylinux9-underpost:v2.85.0
20
+ image: localhost/rockylinux9-underpost:v2.85.7
21
21
  # resources:
22
22
  # requests:
23
23
  # memory: "124Ki"
@@ -100,7 +100,7 @@ spec:
100
100
  spec:
101
101
  containers:
102
102
  - name: dd-default-development-green
103
- image: localhost/rockylinux9-underpost:v2.85.0
103
+ image: localhost/rockylinux9-underpost:v2.85.7
104
104
  # resources:
105
105
  # requests:
106
106
  # memory: "124Ki"
@@ -17,7 +17,7 @@ spec:
17
17
  spec:
18
18
  containers:
19
19
  - name: dd-test-development-blue
20
- image: localhost/rockylinux9-underpost:v2.85.0
20
+ image: localhost/rockylinux9-underpost:v2.85.7
21
21
  # resources:
22
22
  # requests:
23
23
  # memory: "96294Ki"
@@ -104,7 +104,7 @@ spec:
104
104
  spec:
105
105
  containers:
106
106
  - name: dd-test-development-green
107
- image: localhost/rockylinux9-underpost:v2.85.0
107
+ image: localhost/rockylinux9-underpost:v2.85.7
108
108
  # resources:
109
109
  # requests:
110
110
  # memory: "96294Ki"
@@ -30,6 +30,8 @@ spec:
30
30
  # secretKeyRef:
31
31
  # name: mongodb-secret
32
32
  # key: password
33
+ - name: ME_CONFIG_SITE_BASEURL
34
+ value: '/mongo/'
33
35
  - name: ME_CONFIG_BASICAUTH_USERNAME
34
36
  valueFrom:
35
37
  secretKeyRef:
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "type": "module",
3
3
  "main": "src/index.js",
4
4
  "name": "underpost",
5
- "version": "2.85.0",
5
+ "version": "2.85.7",
6
6
  "description": "pwa api rest template",
7
7
  "scripts": {
8
8
  "start": "env-cmd -f .env.production node --max-old-space-size=8192 src/server",
@@ -15,7 +15,7 @@
15
15
  "monitor": "pm2 start src/monitor.js --name monitor -- dd production",
16
16
  "dev-api": "env-cmd -f .env.development nodemon --watch src --ignore src/client src/api",
17
17
  "dev-client": "env-cmd -f .env.development node src/client.dev",
18
- "proxy": "node src/proxy proxy",
18
+ "dev-proxy": "env-cmd -f .env.development node src/proxy proxy",
19
19
  "docs": "jsdoc -c jsdoc.json",
20
20
  "install-global": "npm install -g pm2 && npm install -g jsdoc && npm install -g prettier && npm install -g env-cmd",
21
21
  "install-test": "npm install -g mocha && npm install -g c8 && npm install -g coveralls",
@@ -76,9 +76,9 @@ class UnderpostBaremetal {
76
76
  const underpostRoot = options?.dev === true ? '.' : `${npmRoot}/underpost`;
77
77
 
78
78
  // Set default values if not provided.
79
- workflowId = workflowId ?? 'rpi4mb';
80
- hostname = hostname ?? workflowId;
81
- ipAddress = ipAddress ?? '192.168.1.192';
79
+ workflowId = workflowId ? workflowId : 'rpi4mb';
80
+ hostname = hostname ? hostname : workflowId;
81
+ ipAddress = ipAddress ? ipAddress : '192.168.1.192';
82
82
 
83
83
  // Set default MAC address
84
84
  let macAddress = '00:00:00:00:00:00';
package/src/cli/deploy.js CHANGED
@@ -80,26 +80,33 @@ class UnderpostDeploy {
80
80
  process.env.PORT = initEnvObj.PORT;
81
81
  process.env.NODE_ENV = env;
82
82
  await Config.build('proxy', deployList);
83
- return buildPortProxyRouter(env === 'development' ? 80 : 443, buildProxyRouter());
83
+ return buildPortProxyRouter({ port: env === 'development' ? 80 : 443, proxyRouter: buildProxyRouter() });
84
84
  },
85
85
  /**
86
86
  * Creates a YAML service configuration for a deployment.
87
87
  * @param {string} deployId - Deployment ID for which the service is being created.
88
+ * @param {string} path - Path for which the service is being created.
88
89
  * @param {string} env - Environment for which the service is being created.
89
90
  * @param {number} port - Port number for the service.
90
91
  * @param {Array<string>} deploymentVersions - List of deployment versions.
91
92
  * @returns {string} - YAML service configuration for the specified deployment.
93
+ * @param {string} [serviceId] - Custom service name (optional).
92
94
  * @memberof UnderpostDeploy
93
95
  */
94
- deploymentYamlServiceFactory({ deployId, env, port, deploymentVersions }) {
95
- return deploymentVersions
96
- .map(
97
- (version, i) => ` - name: ${deployId}-${env}-${version}-service
96
+ deploymentYamlServiceFactory({ deployId, path, env, port, deploymentVersions, serviceId }) {
97
+ return `
98
+ - conditions:
99
+ - prefix: ${path}
100
+ enableWebsockets: true
101
+ services:
102
+ ${deploymentVersions
103
+ .map(
104
+ (version, i) => ` - name: ${serviceId ? serviceId : `${deployId}-${env}-${version}-service`}
98
105
  port: ${port}
99
106
  weight: ${i === 0 ? 100 : 0}
100
107
  `,
101
- )
102
- .join('');
108
+ )
109
+ .join('')}`;
103
110
  },
104
111
  /**
105
112
  * Creates a YAML deployment configuration for a deployment.
@@ -214,6 +221,9 @@ ${UnderpostDeploy.API.deploymentYamlPartsFactory({
214
221
 
215
222
  let proxyYaml = '';
216
223
  let secretYaml = '';
224
+ const customServices = fs.existsSync(`./engine-private/conf/${deployId}/conf.services.json`)
225
+ ? JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.services.json`))
226
+ : [];
217
227
 
218
228
  for (const host of Object.keys(confServer)) {
219
229
  if (env === 'production') secretYaml += UnderpostDeploy.API.buildCertManagerCertificate({ host });
@@ -236,20 +246,33 @@ spec:
236
246
  secretName: ${host}`
237
247
  }
238
248
  routes:`;
249
+ const deploymentVersions =
250
+ options.traffic && typeof options.traffic === 'string' ? options.traffic.split(',') : ['blue'];
239
251
  for (const conditionObj of pathPortAssignment) {
240
252
  const { path, port } = conditionObj;
241
- proxyYaml += `
242
- - conditions:
243
- - prefix: ${path}
244
- enableWebsockets: true
245
- services:
246
- ${UnderpostDeploy.API.deploymentYamlServiceFactory({
247
- deployId,
248
- env,
249
- port,
250
- deploymentVersions:
251
- options.traffic && typeof options.traffic === 'string' ? options.traffic.split(',') : ['blue'],
252
- })}`;
253
+ proxyYaml += UnderpostDeploy.API.deploymentYamlServiceFactory({
254
+ path,
255
+ deployId,
256
+ env,
257
+ port,
258
+ deploymentVersions,
259
+ });
260
+ }
261
+ for (const customService of customServices) {
262
+ const { path: _path, port, serviceId, host: _host } = customService;
263
+ if (host === _host) {
264
+ switch (serviceId) {
265
+ case 'mongo-express-service': {
266
+ proxyYaml += UnderpostDeploy.API.deploymentYamlServiceFactory({
267
+ path: _path,
268
+ port,
269
+ serviceId,
270
+ deploymentVersions,
271
+ });
272
+ break;
273
+ }
274
+ }
275
+ }
253
276
  }
254
277
  }
255
278
  const yamlPath = `./engine-private/conf/${deployId}/build/${env}/proxy.yaml`;
@@ -579,6 +602,23 @@ EOF`);
579
602
  * @memberof UnderpostDeploy
580
603
  */
581
604
  existsContainerFile({ podName, path }) {
605
+ if (podName === 'kind-worker') {
606
+ const isFile = JSON.parse(
607
+ shellExec(`docker exec ${podName} sh -c 'test -f "$1" && echo true || echo false' sh ${path}`, {
608
+ stdout: true,
609
+ disableLog: true,
610
+ silent: true,
611
+ }).trim(),
612
+ );
613
+ const isFolder = JSON.parse(
614
+ shellExec(`docker exec ${podName} sh -c 'test -d "$1" && echo true || echo false' sh ${path}`, {
615
+ stdout: true,
616
+ disableLog: true,
617
+ silent: true,
618
+ }).trim(),
619
+ );
620
+ return isFolder || isFile;
621
+ }
582
622
  return JSON.parse(
583
623
  shellExec(`kubectl exec ${podName} -- test -f ${path} && echo "true" || echo "false"`, {
584
624
  stdout: true,
@@ -649,15 +689,37 @@ EOF`);
649
689
  /**
650
690
  * Creates a hosts file for a deployment.
651
691
  * @param {Array<string>} hosts - List of hosts to be added to the hosts file.
692
+ * @param {object} options - Options for the hosts file creation.
693
+ * @param {boolean} options.append - Whether to append to the existing hosts file.
694
+ * @returns {object} - Object containing the rendered hosts file.
652
695
  * @memberof UnderpostDeploy
653
696
  */
654
- etcHostFactory(hosts = []) {
697
+ etcHostFactory(hosts = [], options = { append: false }) {
698
+ hosts = hosts.map((host) => {
699
+ try {
700
+ if (!host.startsWith('http')) host = `http://${host}`;
701
+ const hostname = new URL(host).hostname;
702
+ logger.info('Hostname extract valid', { host, hostname });
703
+ return hostname;
704
+ } catch (e) {
705
+ logger.warn('No hostname extract valid', host);
706
+ return host;
707
+ }
708
+ });
655
709
  const renderHosts = `127.0.0.1 ${hosts.join(
656
710
  ' ',
657
711
  )} localhost localhost.localdomain localhost4 localhost4.localdomain4
658
712
  ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6`;
659
713
 
660
- fs.writeFileSync(`/etc/hosts`, renderHosts, 'utf8');
714
+ if (options && options.append && fs.existsSync(`/etc/hosts`)) {
715
+ fs.writeFileSync(
716
+ `/etc/hosts`,
717
+ fs.readFileSync(`/etc/hosts`, 'utf8') +
718
+ `
719
+ ${renderHosts}`,
720
+ 'utf8',
721
+ );
722
+ } else fs.writeFileSync(`/etc/hosts`, renderHosts, 'utf8');
661
723
  return { renderHosts };
662
724
  },
663
725
  /**
@@ -704,6 +766,61 @@ EOF`);
704
766
  }
705
767
  logger.info(`${iteratorTag} | Deployment ready. | Total delay number check iterations: ${checkStatusIteration}`);
706
768
  },
769
+
770
+ /**
771
+ * Retrieves the currently loaded images in the Kubernetes cluster.
772
+ * @returns {Array<object>} - Array of objects containing pod names and their corresponding images.
773
+ * @memberof UnderpostDeploy
774
+ */
775
+ getCurrentLoadedImages(node = 'kind-worker', specContainers = false) {
776
+ if (specContainers) {
777
+ const raw = shellExec(
778
+ `kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{"\\n"}{.metadata.name}{":\\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}'`,
779
+ {
780
+ stdout: true,
781
+ silent: true,
782
+ },
783
+ );
784
+ return raw
785
+ .split(`\n`)
786
+ .map((lines) => ({
787
+ pod: lines.split('\t')[0].replaceAll(':', '').trim(),
788
+ image: lines.split('\t')[1] ? lines.split('\t')[1].replaceAll(',', '').trim() : null,
789
+ }))
790
+ .filter((o) => o.image);
791
+ }
792
+ if (node === 'kind-worker') {
793
+ const raw = shellExec(`docker exec -i ${node} crictl images`, {
794
+ stdout: true,
795
+ silent: true,
796
+ });
797
+
798
+ const heads = raw
799
+ .split(`\n`)[0]
800
+ .split(' ')
801
+ .filter((_r) => _r.trim());
802
+
803
+ const pods = raw
804
+ .split(`\n`)
805
+ .filter((r) => !r.match('IMAGE'))
806
+ .map((r) => r.split(' ').filter((_r) => _r.trim()));
807
+
808
+ const result = [];
809
+
810
+ for (const row of pods) {
811
+ if (row.length === 0) continue;
812
+ const pod = {};
813
+ let index = -1;
814
+ for (const head of heads) {
815
+ if (head in pod) continue;
816
+ index++;
817
+ pod[head] = row[index];
818
+ }
819
+ result.push(pod);
820
+ }
821
+ return result;
822
+ }
823
+ },
707
824
  };
708
825
  }
709
826
 
package/src/cli/image.js CHANGED
@@ -53,7 +53,7 @@ class UnderpostImage {
53
53
  const baseCommand = options.dev ? 'node bin' : 'underpost';
54
54
  const baseCommandOption = options.dev ? ' --dev' : '';
55
55
  const IMAGE_NAME = `rockylinux9-underpost`;
56
- const IMAGE_NAME_FULL = `${IMAGE_NAME}:${options.version ?? Underpost.version}`;
56
+ const IMAGE_NAME_FULL = `${IMAGE_NAME}:${options.version ? options.version : Underpost.version}`;
57
57
  let LOAD_TYPE = '';
58
58
  if (options.kindLoad === true) {
59
59
  LOAD_TYPE = `--kind-load`;
@@ -105,7 +105,7 @@ class UnderpostImage {
105
105
  dev: false,
106
106
  },
107
107
  ) {
108
- const {
108
+ let {
109
109
  path,
110
110
  imageName,
111
111
  imagePath,
@@ -119,6 +119,7 @@ class UnderpostImage {
119
119
  reset,
120
120
  dev,
121
121
  } = options;
122
+ if (!path) path = '.';
122
123
  const podManImg = `localhost/${imageName}`;
123
124
  if (imagePath && typeof imagePath === 'string' && !fs.existsSync(imagePath))
124
125
  fs.mkdirSync(imagePath, { recursive: true });
package/src/cli/index.js CHANGED
@@ -22,11 +22,11 @@ program.name('underpost').description(`underpost ci/cd cli ${Underpost.version}`
22
22
  // 'new' command: Create a new project
23
23
  program
24
24
  .command('new')
25
- .argument('<app-name>', 'The name or deploy-id of the application to create.')
26
- .option('--deploy-id', 'Crete deploy ID conf env files')
25
+ .argument('[app-name]', 'The name of the new project.')
26
+ .option('--deploy-id <deploy-id>', 'Crete deploy ID conf env files')
27
+ .option('--sub-conf <sub-conf>', 'Create sub conf env files')
27
28
  .option('--cluster', 'Create deploy ID cluster files and sync to current cluster')
28
29
  .option('--dev', 'Sets the development cli context')
29
- .option('--sub-conf <sub-conf>', 'Create sub conf env files')
30
30
  .description('Initializes a new Underpost project, service, or configuration.')
31
31
  .action(Underpost.repo.new);
32
32
 
@@ -389,6 +389,10 @@ program
389
389
  .option('--kubeadm', 'Flag to indicate Kubeadm cluster type context')
390
390
  .option('--k3s', 'Flag to indicate K3s cluster type context')
391
391
  .option('--force', 'Forces operation, overriding any warnings or conflicts.')
392
+ .option('--tls', 'Enables TLS for the runner execution.')
393
+ .option('--reset', 'Resets the runner state before execution.')
394
+ .option('--terminal', 'Enables terminal mode for interactive script execution.')
395
+ .option('--dev-proxy-port-offset <port-offset>', 'Sets a custom port offset for development proxy.')
392
396
  .description('Runs a script from the specified path.')
393
397
  .action(UnderpostRun.API.callback);
394
398