underpost 2.8.846 → 2.8.847

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/README.md CHANGED
@@ -39,12 +39,14 @@ template
39
39
 
40
40
 
41
41
 
42
+
43
+
42
44
 
43
45
 
44
46
  <!-- badges -->
45
47
 
46
48
 
47
- [![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.8.846)](https://socket.dev/npm/package/underpost/overview/2.8.846) [![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)
49
+ [![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.8.847)](https://socket.dev/npm/package/underpost/overview/2.8.847) [![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)
48
50
 
49
51
 
50
52
  <!-- end-badges -->
@@ -66,6 +68,8 @@ template
66
68
 
67
69
 
68
70
 
71
+
72
+
69
73
 
70
74
 
71
75
  </div>
@@ -112,7 +116,7 @@ Run dev client server
112
116
  npm run dev
113
117
  ```
114
118
  <!-- -->
115
- ## underpost ci/cd cli v2.8.846
119
+ ## underpost ci/cd cli v2.8.847
116
120
 
117
121
  ### Usage: `underpost [options] [command]`
118
122
  ```
@@ -142,6 +146,7 @@ Commands:
142
146
  fs [options] [path] Manages file storage, defaulting to file upload operations.
143
147
  test [options] [deploy-list] Manages and runs tests, defaulting to the current Underpost default test suite.
144
148
  monitor [options] <deploy-id> [env] Manages health server monitoring for specified deployments.
149
+ ssh [options] Import and start ssh server and client based on current default deployment ID.
145
150
  run [options] <runner-id> [path] Runs a script from the specified path.
146
151
  lxd [options] Manages LXD containers and virtual machines.
147
152
  baremetal [options] [workflow-id] [hostname] [ip-address] Manages baremetal server operations, including installation, database setup, commissioning, and user management.
package/bin/build.js CHANGED
@@ -53,7 +53,9 @@ if (process.argv.includes('conf')) {
53
53
  fs.removeSync(toPath);
54
54
  fs.mkdirSync(toPath, { recursive: true });
55
55
  fs.copySync(`./engine-private/conf/${_confName}`, toPath);
56
- if (fs.existsSync(`./engine-private/replica`)) {
56
+ if (process.argv.includes('remove-replica') && fs.existsSync(`../${privateRepoName}/replica`)) {
57
+ fs.removeSync(`../${privateRepoName}/replica`);
58
+ } else if (fs.existsSync(`./engine-private/replica`)) {
57
59
  const replicas = await fs.readdir(`./engine-private/replica`);
58
60
  for (const replica of replicas)
59
61
  if (replica.match(_confName))
@@ -187,4 +189,8 @@ const { DefaultConf } = await import(`../conf.${confName}.js`);
187
189
 
188
190
  fs.copyFileSync(`./.github/workflows/${repoName}.ci.yml`, `${basePath}/.github/workflows/${repoName}.ci.yml`);
189
191
  fs.copyFileSync(`./.github/workflows/${repoName}.cd.yml`, `${basePath}/.github/workflows/${repoName}.cd.yml`);
192
+
193
+ if (fs.existsSync(`./src/ws/${confName.split('-')[1]}`)) {
194
+ fs.copySync(`./src/ws/${confName.split('-')[1]}`, `${basePath}/src/ws/${confName.split('-')[1]}`);
195
+ }
190
196
  }
package/bin/deploy.js CHANGED
@@ -835,6 +835,12 @@ ${shellExec(`git log | grep Author: | sort -u`, { stdout: true }).split(`\n`).jo
835
835
  }
836
836
 
837
837
  case 'ssh': {
838
+ // only import + start
839
+ // node bin/deploy ssh root@<host> <password> import
840
+
841
+ // generate + import + start
842
+ // node bin/deploy ssh root@<host> <password>
843
+
838
844
  const host = process.argv[3] ?? `root@${await ip.public.ipv4()}`;
839
845
  const domain = host.split('@')[1];
840
846
  const user = 'root'; // host.split('@')[0];
@@ -907,7 +913,7 @@ EOF`);
907
913
  // shellExec(`sudo echo "" > ~/.ssh/known_hosts`);
908
914
 
909
915
  // ssh-copy-id -i ~/.ssh/id_rsa.pub -p <port_number> <username>@<host>
910
- shellExec(`ssh-copy-id -i ~/.ssh/id_rsa.pub -p ${port} ${host}`);
916
+ // shellExec(`ssh-copy-id -i ~/.ssh/id_rsa.pub -p ${port} ${host}`);
911
917
  // debug:
912
918
  // shellExec(`ssh -vvv ${host}`);
913
919
 
package/cli.md CHANGED
@@ -1,4 +1,4 @@
1
- ## underpost ci/cd cli v2.8.846
1
+ ## underpost ci/cd cli v2.8.847
2
2
 
3
3
  ### Usage: `underpost [options] [command]`
4
4
  ```
@@ -28,6 +28,7 @@ Commands:
28
28
  fs [options] [path] Manages file storage, defaulting to file upload operations.
29
29
  test [options] [deploy-list] Manages and runs tests, defaulting to the current Underpost default test suite.
30
30
  monitor [options] <deploy-id> [env] Manages health server monitoring for specified deployments.
31
+ ssh [options] Import and start ssh server and client based on current default deployment ID.
31
32
  run [options] <runner-id> [path] Runs a script from the specified path.
32
33
  lxd [options] Manages LXD containers and virtual machines.
33
34
  baremetal [options] [workflow-id] [hostname] [ip-address] Manages baremetal server operations, including installation, database setup, commissioning, and user management.
@@ -552,6 +553,20 @@ Options:
552
553
  ```
553
554
 
554
555
 
556
+ ### `ssh` :
557
+ ```
558
+ Usage: underpost ssh [options]
559
+
560
+ Import and start ssh server and client based on current default deployment ID.
561
+
562
+ Options:
563
+ --generate Generates new ssh credential and stores it in current private
564
+ keys file storage.
565
+ -h, --help display help for command
566
+
567
+ ```
568
+
569
+
555
570
  ### `run` :
556
571
  ```
557
572
  Usage: underpost run [options] <runner-id> [path]
@@ -58,7 +58,7 @@ services:
58
58
  cpus: '0.25'
59
59
  memory: 20M
60
60
  labels: # labels in Compose file instead of Dockerfile
61
- engine.version: '2.8.846'
61
+ engine.version: '2.8.847'
62
62
  networks:
63
63
  - load-balancer
64
64
 
@@ -17,7 +17,7 @@ spec:
17
17
  spec:
18
18
  containers:
19
19
  - name: dd-template-development-blue
20
- image: localhost/rockylinux9-underpost:v2.8.846
20
+ image: localhost/rockylinux9-underpost:v2.8.847
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-template-development-green
103
- image: localhost/rockylinux9-underpost:v2.8.846
103
+ image: localhost/rockylinux9-underpost:v2.8.847
104
104
  # resources:
105
105
  # requests:
106
106
  # memory: "124Ki"
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.8.846",
5
+ "version": "2.8.847",
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",
@@ -476,6 +476,12 @@ net.bridge.bridge-nf-call-arptables = 1
476
476
  net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`,
477
477
  { silent: true },
478
478
  );
479
+
480
+ // Increase inotify limits
481
+ shellExec(`sudo sysctl -w fs.inotify.max_user_watches=2099999999`);
482
+ shellExec(`sudo sysctl -w fs.inotify.max_user_instances=2099999999`);
483
+ shellExec(`sudo sysctl -w fs.inotify.max_queued_events=2099999999`);
484
+
479
485
  // shellExec(`sudo sysctl --system`); // Apply sysctl changes immediately
480
486
  // Apply NAT iptables rules.
481
487
  shellExec(`${underpostRoot}/manifests/maas/nat-iptables.sh`, { silent: true });
package/src/cli/deploy.js CHANGED
@@ -528,13 +528,14 @@ node bin/deploy build-full-client ${deployId}
528
528
  }).trim(),
529
529
  );
530
530
  },
531
- checkDeploymentReadyStatus(deployId, env, traffic) {
531
+ checkDeploymentReadyStatus(deployId, env, traffic, ignoresNames = []) {
532
532
  const cmd = `underpost config get container-status`;
533
533
  const pods = UnderpostDeploy.API.get(`${deployId}-${env}-${traffic}`);
534
534
  const readyPods = [];
535
535
  const notReadyPods = [];
536
536
  for (const pod of pods) {
537
537
  const { NAME } = pod;
538
+ if (ignoresNames && ignoresNames.find((t) => NAME.trim().toLowerCase().match(t.trim().toLowerCase()))) continue;
538
539
  if (
539
540
  shellExec(`sudo kubectl exec -i ${NAME} -- sh -c "${cmd}"`, { stdout: true }).match(
540
541
  `${deployId}-${env}-running-deployment`,
package/src/cli/index.js CHANGED
@@ -316,6 +316,13 @@ program
316
316
  .description('Manages health server monitoring for specified deployments.')
317
317
  .action(Underpost.monitor.callback);
318
318
 
319
+ // 'ssh' command: SSH management
320
+ program
321
+ .command('ssh')
322
+ .option('--generate', 'Generates new ssh credential and stores it in current private keys file storage.')
323
+ .description('Import and start ssh server and client based on current default deployment ID.')
324
+ .action(Underpost.ssh.callback);
325
+
319
326
  // 'run' command: Run a script
320
327
  program
321
328
  .command('run')
package/src/cli/run.js CHANGED
@@ -206,12 +206,13 @@ class UnderpostRun {
206
206
  const currentTraffic = UnderpostDeploy.API.getCurrentTraffic(deployId);
207
207
  const targetTraffic = currentTraffic === 'blue' ? 'green' : 'blue';
208
208
  const env = 'production';
209
+ const ignorePods = UnderpostDeploy.API.get(`${deployId}-${env}-${targetTraffic}`).map((p) => p.NAME);
209
210
  shellExec(`sudo kubectl rollout restart deployment/${deployId}-${env}-${targetTraffic}`);
210
211
 
211
212
  let secondsElapsed = 0;
212
213
  logger.info('Deployment init', { deployId, env, targetTraffic });
213
214
 
214
- while (!UnderpostDeploy.API.checkDeploymentReadyStatus(deployId, env, targetTraffic).ready) {
215
+ while (!UnderpostDeploy.API.checkDeploymentReadyStatus(deployId, env, targetTraffic, ignorePods).ready) {
215
216
  await timer(1000);
216
217
  secondsElapsed++;
217
218
  logger.info(`Deployment in progress, seconds elapsed: ${secondsElapsed}`);
package/src/cli/ssh.js ADDED
@@ -0,0 +1,32 @@
1
+ import { getNpmRootPath } from '../server/conf.js';
2
+ import { shellExec } from '../server/process.js';
3
+
4
+ class UnderpostSSH {
5
+ static API = {
6
+ /**
7
+ * @method callback
8
+ * @param {object} options
9
+ * @param {boolean} options.generate - Generates new ssh credential and stores it in current private keys file storage.
10
+ * @description Import and start ssh server and client based on current default deployment ID.
11
+ */
12
+ callback: async (
13
+ options = {
14
+ generate: false,
15
+ },
16
+ ) => {
17
+ // only import + start
18
+ // node bin/deploy ssh root@<host> <password> import
19
+
20
+ // generate + import + start
21
+ // node bin/deploy ssh root@<host> <password>
22
+
23
+ shellExec(
24
+ `node bin/deploy ssh root@${process.env.DEFAULT_DEPLOY_HOST} ${process.env.DEFAULT_DEPLOY_PASSWORD ?? `''`}${
25
+ options.generate === true ? '' : ' import'
26
+ }`,
27
+ );
28
+ },
29
+ };
30
+ }
31
+
32
+ export default UnderpostSSH;
@@ -17,8 +17,8 @@ const CssCommonCore = async () => {
17
17
  await AgGrid.RenderStyle();
18
18
  return html`<style>
19
19
  .top-bar-app-icon {
20
- width: 35px;
21
- height: 35px;
20
+ width: 40px;
21
+ height: 40px;
22
22
  }
23
23
  .mini-title {
24
24
  font-size: 15px;
@@ -51,7 +51,6 @@ const CssCommonCore = async () => {
51
51
  cursor: grabbing !important;
52
52
  }
53
53
  .btn-label-content {
54
- height: 100%;
55
54
  top: 15px;
56
55
  }
57
56
  .badge {
@@ -139,6 +139,71 @@ const Modal = {
139
139
  case 'slide-menu-right':
140
140
  case 'slide-menu-left':
141
141
  (async () => {
142
+ if (!options.slideMenuTopBarBannerFix) {
143
+ options.slideMenuTopBarBannerFix = async () => {
144
+ let style = html``;
145
+ if (options.barMode === 'top-bottom-bar') {
146
+ style = html`<style>
147
+ .default-slide-menu-top-bar-fix-logo-container {
148
+ width: 50px;
149
+ height: 50px;
150
+ }
151
+ .default-slide-menu-top-bar-fix-logo {
152
+ width: 40px;
153
+ height: 40px;
154
+ padding: 5px;
155
+ }
156
+ .default-slide-menu-top-bar-fix-title-container-text {
157
+ font-size: 26px;
158
+ top: 8px;
159
+ color: ${darkTheme ? '#ffffff' : '#000000'};
160
+ }
161
+ </style>`;
162
+ } else {
163
+ style = html`<style>
164
+ .default-slide-menu-top-bar-fix-logo-container {
165
+ width: 100px;
166
+ height: 100px;
167
+ }
168
+ .default-slide-menu-top-bar-fix-logo {
169
+ width: 80px;
170
+ height: 80px;
171
+ padding: 10px;
172
+ }
173
+ .default-slide-menu-top-bar-fix-title-container-text {
174
+ font-size: 30px;
175
+ top: 30px;
176
+ color: ${darkTheme ? '#ffffff' : '#000000'};
177
+ }
178
+ </style>`;
179
+ }
180
+ setTimeout(() => {
181
+ if (s(`.top-bar-app-icon`) && s(`.top-bar-app-icon`).src) {
182
+ s(`.default-slide-menu-top-bar-fix-logo`).src = s(`.top-bar-app-icon`).src;
183
+ if (s(`.top-bar-app-icon`).classList.contains('negative-color'))
184
+ s(`.default-slide-menu-top-bar-fix-logo`).classList.add('negative-color');
185
+ htmls(
186
+ `.default-slide-menu-top-bar-fix-title-container`,
187
+ html`
188
+ <div class="inl default-slide-menu-top-bar-fix-title-container-text">
189
+ ${options.RouterInstance.NameApp}
190
+ </div>
191
+ `,
192
+ );
193
+ } else
194
+ htmls(
195
+ `.default-slide-menu-top-bar-fix-logo-container`,
196
+ html`<div class="abs center">${s(`.action-btn-app-icon-render`).innerHTML}</div>`,
197
+ );
198
+ });
199
+
200
+ return html`${style}
201
+ <div class="in fll default-slide-menu-top-bar-fix-logo-container">
202
+ <img class="default-slide-menu-top-bar-fix-logo in fll" />
203
+ </div>
204
+ <div class="in fll default-slide-menu-top-bar-fix-title-container"></div>`;
205
+ };
206
+ }
142
207
  const { barConfig } = options;
143
208
  options.style = {
144
209
  position: 'absolute',
@@ -266,7 +331,9 @@ const Modal = {
266
331
  </div>
267
332
  </div>
268
333
  <div
269
- class="abs main-body-btn main-body-btn-bar-custom ${options?.slideMenuTopBarFix ? '' : 'hide'}"
334
+ class="abs main-body-btn main-body-btn-bar-custom ${options?.slideMenuTopBarBannerFix
335
+ ? ''
336
+ : 'hide'}"
270
337
  style="top: 100px; ${true || (options.mode && options.mode.match('right'))
271
338
  ? 'right'
272
339
  : 'left'}: 0px"
@@ -345,6 +412,7 @@ const Modal = {
345
412
  );
346
413
  }
347
414
  };
415
+ Modal.setTopBannerLink();
348
416
  });
349
417
 
350
418
  const inputSearchBoxId = `top-bar-search-box`;
@@ -429,12 +497,12 @@ const Modal = {
429
497
  })}
430
498
  </div>
431
499
  </div>
432
- ${options?.slideMenuTopBarFix
500
+ ${options?.slideMenuTopBarBannerFix
433
501
  ? html`<div
434
502
  class="abs modal slide-menu-top-bar-fix"
435
503
  style="height: ${options.heightTopBar}px; top: 0px"
436
504
  >
437
- ${await options.slideMenuTopBarFix()}
505
+ <a class="a-link-top-banner"> ${await options.slideMenuTopBarBannerFix()}</a>
438
506
  </div>`
439
507
  : ''}
440
508
  </div>`,
@@ -1072,11 +1140,18 @@ const Modal = {
1072
1140
  }
1073
1141
 
1074
1142
  {
1075
- ThemeEvents['action-btn-theme'] = () => {
1143
+ ThemeEvents['action-btn-theme'] = async () => {
1076
1144
  htmls(
1077
1145
  `.action-btn-theme-render`,
1078
1146
  html` ${darkTheme ? html` <i class="fas fa-moon"></i>` : html`<i class="far fa-sun"></i>`}`,
1079
1147
  );
1148
+ if (s(`.slide-menu-top-bar-fix`)) {
1149
+ htmls(
1150
+ `.slide-menu-top-bar-fix`,
1151
+ html`<a class="a-link-top-banner">${await options.slideMenuTopBarBannerFix()}</a>`,
1152
+ );
1153
+ Modal.setTopBannerLink();
1154
+ }
1080
1155
  };
1081
1156
  ThemeEvents['action-btn-theme']();
1082
1157
 
@@ -2138,6 +2213,16 @@ const Modal = {
2138
2213
  // non-fatal: keep default placement if structure not present
2139
2214
  }
2140
2215
  },
2216
+ setTopBannerLink: function () {
2217
+ if (s(`.a-link-top-banner`)) {
2218
+ s(`.a-link-top-banner`).setAttribute('href', `${location.origin}${getProxyPath()}`);
2219
+ EventsUI.onClick(`.a-link-top-banner`, (e) => {
2220
+ if (location.pathname === '/') return location.reload();
2221
+ e.preventDefault();
2222
+ s(`.action-btn-home`).click();
2223
+ });
2224
+ }
2225
+ },
2141
2226
  headerTitleHeight: 40,
2142
2227
  actionBtnCenter: function () {
2143
2228
  if (!s(`.btn-close-modal-menu`).classList.contains('hide')) {
package/src/index.js CHANGED
@@ -19,6 +19,7 @@ import UnderpostRepository from './cli/repository.js';
19
19
  import UnderpostRun from './cli/run.js';
20
20
  import UnderpostScript from './cli/script.js';
21
21
  import UnderpostSecret from './cli/secrets.js';
22
+ import UnderpostSSH from './cli/ssh.js';
22
23
  import UnderpostTest from './cli/test.js';
23
24
  import UnderpostStartUp from './server/start.js';
24
25
 
@@ -34,7 +35,7 @@ class Underpost {
34
35
  * @type {String}
35
36
  * @memberof Underpost
36
37
  */
37
- static version = 'v2.8.846';
38
+ static version = 'v2.8.847';
38
39
  /**
39
40
  * Repository cli API
40
41
  * @static
@@ -126,6 +127,13 @@ class Underpost {
126
127
  * @memberof Underpost
127
128
  */
128
129
  static monitor = UnderpostMonitor.API;
130
+ /**
131
+ * SSH cli API
132
+ * @static
133
+ * @type {UnderpostSSH.API}
134
+ * @memberof Underpost
135
+ */
136
+ static ssh = UnderpostSSH.API;
129
137
  /**
130
138
  * LXD cli API
131
139
  * @static