underpost 2.8.884 → 2.8.886
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.production +3 -0
- package/.github/workflows/ghpkg.ci.yml +1 -1
- package/.github/workflows/npmpkg.ci.yml +1 -1
- package/.github/workflows/publish.ci.yml +5 -5
- package/.github/workflows/pwa-microservices-template-page.cd.yml +1 -1
- package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
- package/CHANGELOG.md +145 -1
- package/Dockerfile +1 -1
- package/README.md +5 -121
- package/bin/build.js +18 -9
- package/bin/deploy.js +102 -197
- package/bin/file.js +4 -6
- package/cli.md +16 -12
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +54 -54
- package/manifests/deployment/dd-test-development/proxy.yaml +4 -4
- package/manifests/lxd/underpost-setup.sh +5 -5
- package/package.json +3 -3
- package/scripts/ssl.sh +164 -0
- package/src/cli/baremetal.js +7 -7
- package/src/cli/cloud-init.js +1 -1
- package/src/cli/cluster.js +31 -3
- package/src/cli/cron.js +9 -1
- package/src/cli/db.js +64 -2
- package/src/cli/deploy.js +189 -4
- package/src/cli/env.js +43 -0
- package/src/cli/fs.js +96 -2
- package/src/cli/image.js +15 -0
- package/src/cli/index.js +17 -4
- package/src/cli/monitor.js +33 -2
- package/src/cli/repository.js +95 -2
- package/src/cli/run.js +315 -51
- package/src/cli/script.js +32 -0
- package/src/cli/secrets.js +34 -0
- package/src/cli/test.js +42 -1
- package/src/client/components/core/Css.js +16 -8
- package/src/client/components/core/Docs.js +5 -13
- package/src/client/components/core/Modal.js +48 -29
- package/src/client/components/core/Router.js +6 -3
- package/src/client/components/core/Worker.js +205 -118
- package/src/client/components/core/windowGetDimensions.js +229 -162
- package/src/client/components/default/MenuDefault.js +1 -0
- package/src/client.dev.js +6 -3
- package/src/db/DataBaseProvider.js +65 -12
- package/src/db/mariadb/MariaDB.js +39 -6
- package/src/db/mongo/MongooseDB.js +51 -133
- package/src/index.js +2 -2
- package/src/mailer/EmailRender.js +58 -9
- package/src/mailer/MailerProvider.js +99 -25
- package/src/runtime/express/Express.js +32 -38
- package/src/runtime/lampp/Dockerfile +1 -1
- package/src/server/auth.js +9 -28
- package/src/server/backup.js +20 -0
- package/src/server/client-build-live.js +23 -12
- package/src/server/client-build.js +136 -91
- package/src/server/client-dev-server.js +35 -8
- package/src/server/client-icons.js +19 -0
- package/src/server/conf.js +543 -80
- package/src/server/dns.js +184 -42
- package/src/server/downloader.js +65 -24
- package/src/server/object-layer.js +260 -162
- package/src/server/peer.js +3 -9
- package/src/server/proxy.js +93 -76
- package/src/server/runtime.js +15 -21
- package/src/server/ssr.js +4 -4
- package/src/server/start.js +39 -0
- package/src/server/tls.js +251 -0
- package/src/server/valkey.js +11 -10
- package/src/ws/IoInterface.js +133 -39
- package/src/ws/IoServer.js +80 -31
- package/src/ws/core/core.ws.connection.js +50 -16
- package/src/ws/core/core.ws.emit.js +47 -8
- package/src/ws/core/core.ws.server.js +62 -10
- package/manifests/maas/lxd-preseed.yaml +0 -32
- package/src/server/ssl.js +0 -108
- /package/{manifests/maas → scripts}/device-scan.sh +0 -0
- /package/{manifests/maas → scripts}/gpu-diag.sh +0 -0
- /package/{manifests/maas → scripts}/maas-setup.sh +0 -0
- /package/{manifests/maas → scripts}/nat-iptables.sh +0 -0
- /package/{manifests/maas → scripts}/nvim.sh +0 -0
- /package/{manifests/maas → scripts}/snap-clean.sh +0 -0
- /package/{manifests/maas → scripts}/ssh-cluster-info.sh +0 -0
package/src/cli/deploy.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deploy module for managing the deployment of applications and services.
|
|
3
|
+
* @module src/cli/deploy.js
|
|
4
|
+
* @namespace UnderpostDeploy
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
import {
|
|
2
8
|
buildKindPorts,
|
|
3
9
|
buildPortProxyRouter,
|
|
@@ -14,13 +20,30 @@ import fs from 'fs-extra';
|
|
|
14
20
|
import dotenv from 'dotenv';
|
|
15
21
|
import UnderpostRootEnv from './env.js';
|
|
16
22
|
import UnderpostCluster from './cluster.js';
|
|
17
|
-
import
|
|
23
|
+
import { timer } from '../client/components/core/CommonJs.js';
|
|
18
24
|
|
|
19
25
|
const logger = loggerFactory(import.meta);
|
|
20
26
|
|
|
27
|
+
/**
|
|
28
|
+
* @class UnderpostDeploy
|
|
29
|
+
* @description Manages the deployment of applications and services.
|
|
30
|
+
* This class provides a set of static methods to handle the deployment process,
|
|
31
|
+
* including resource allocation, configuration management, and Kubernetes deployment.
|
|
32
|
+
* @memberof UnderpostDeploy
|
|
33
|
+
*/
|
|
21
34
|
class UnderpostDeploy {
|
|
22
35
|
static NETWORK = {};
|
|
23
36
|
static API = {
|
|
37
|
+
/**
|
|
38
|
+
* Synchronizes deployment configurations for a list of deployments.
|
|
39
|
+
* @param {string} deployList - List of deployment IDs to synchronize.
|
|
40
|
+
* @param {object} options - Options for the synchronization process.
|
|
41
|
+
* @param {string} options.versions - Comma-separated list of versions to deploy.
|
|
42
|
+
* @param {string} options.replicas - Number of replicas for each deployment.
|
|
43
|
+
* @param {string} options.node - Node name for resource allocation.
|
|
44
|
+
* @returns {object} - Deployment data for the specified deployments.
|
|
45
|
+
* @memberof UnderpostDeploy
|
|
46
|
+
*/
|
|
24
47
|
sync(deployList, { versions, replicas, node }) {
|
|
25
48
|
const deployGroupId = 'dd.router';
|
|
26
49
|
fs.writeFileSync(`./engine-private/deploy/${deployGroupId}`, deployList, 'utf8');
|
|
@@ -43,6 +66,13 @@ class UnderpostDeploy {
|
|
|
43
66
|
deployGroupId,
|
|
44
67
|
});
|
|
45
68
|
},
|
|
69
|
+
/**
|
|
70
|
+
* Creates a router configuration for a list of deployments.
|
|
71
|
+
* @param {string} deployList - List of deployment IDs to include in the router.
|
|
72
|
+
* @param {string} env - Environment for which the router is being created.
|
|
73
|
+
* @returns {object} - Router configuration for the specified deployments.
|
|
74
|
+
* @memberof UnderpostDeploy
|
|
75
|
+
*/
|
|
46
76
|
async routerFactory(deployList, env) {
|
|
47
77
|
const initEnvPath = `./engine-private/conf/${deployList.split(',')[0]}/.env.${env}`;
|
|
48
78
|
const initEnvObj = dotenv.parse(fs.readFileSync(initEnvPath, 'utf8'));
|
|
@@ -51,6 +81,15 @@ class UnderpostDeploy {
|
|
|
51
81
|
await Config.build('proxy', deployList);
|
|
52
82
|
return buildPortProxyRouter(env === 'development' ? 80 : 443, buildProxyRouter());
|
|
53
83
|
},
|
|
84
|
+
/**
|
|
85
|
+
* Creates a YAML service configuration for a deployment.
|
|
86
|
+
* @param {string} deployId - Deployment ID for which the service is being created.
|
|
87
|
+
* @param {string} env - Environment for which the service is being created.
|
|
88
|
+
* @param {number} port - Port number for the service.
|
|
89
|
+
* @param {Array<string>} deploymentVersions - List of deployment versions.
|
|
90
|
+
* @returns {string} - YAML service configuration for the specified deployment.
|
|
91
|
+
* @memberof UnderpostDeploy
|
|
92
|
+
*/
|
|
54
93
|
deploymentYamlServiceFactory({ deployId, env, port, deploymentVersions }) {
|
|
55
94
|
return deploymentVersions
|
|
56
95
|
.map(
|
|
@@ -61,7 +100,19 @@ class UnderpostDeploy {
|
|
|
61
100
|
)
|
|
62
101
|
.join('');
|
|
63
102
|
},
|
|
103
|
+
/**
|
|
104
|
+
* Creates a YAML deployment configuration for a deployment.
|
|
105
|
+
* @param {string} deployId - Deployment ID for which the deployment is being created.
|
|
106
|
+
* @param {string} env - Environment for which the deployment is being created.
|
|
107
|
+
* @param {string} suffix - Suffix for the deployment.
|
|
108
|
+
* @param {object} resources - Resource configuration for the deployment.
|
|
109
|
+
* @param {number} replicas - Number of replicas for the deployment.
|
|
110
|
+
* @param {string} image - Docker image for the deployment.
|
|
111
|
+
* @returns {string} - YAML deployment configuration for the specified deployment.
|
|
112
|
+
* @memberof UnderpostDeploy
|
|
113
|
+
*/
|
|
64
114
|
deploymentYamlPartsFactory({ deployId, env, suffix, resources, replicas, image }) {
|
|
115
|
+
const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
|
|
65
116
|
return `apiVersion: apps/v1
|
|
66
117
|
kind: Deployment
|
|
67
118
|
metadata:
|
|
@@ -80,7 +131,7 @@ spec:
|
|
|
80
131
|
spec:
|
|
81
132
|
containers:
|
|
82
133
|
- name: ${deployId}-${env}-${suffix}
|
|
83
|
-
image: ${image ?? `localhost/rockylinux9-underpost
|
|
134
|
+
image: ${image ?? `localhost/rockylinux9-underpost:v${packageJson.version}`}
|
|
84
135
|
# resources:
|
|
85
136
|
# requests:
|
|
86
137
|
# memory: "${resources.requests.memory}"
|
|
@@ -114,6 +165,16 @@ spec:
|
|
|
114
165
|
ports:
|
|
115
166
|
{{ports}} type: LoadBalancer`;
|
|
116
167
|
},
|
|
168
|
+
/**
|
|
169
|
+
* Builds a manifest for a list of deployments.
|
|
170
|
+
* @param {string} deployList - List of deployment IDs to include in the manifest.
|
|
171
|
+
* @param {string} env - Environment for which the manifest is being built.
|
|
172
|
+
* @param {object} options - Options for the manifest build process.
|
|
173
|
+
* @param {string} options.replicas - Number of replicas for each deployment.
|
|
174
|
+
* @param {string} options.image - Docker image for the deployment.
|
|
175
|
+
* @returns {Promise<void>} - Promise that resolves when the manifest is built.
|
|
176
|
+
* @memberof UnderpostDeploy
|
|
177
|
+
*/
|
|
117
178
|
async buildManifest(deployList, env, options) {
|
|
118
179
|
const resources = UnderpostDeploy.API.resourcesFactory();
|
|
119
180
|
const replicas = options.replicas;
|
|
@@ -124,10 +185,9 @@ spec:
|
|
|
124
185
|
if (!deployId) continue;
|
|
125
186
|
const confServer = loadReplicas(
|
|
126
187
|
JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8')),
|
|
127
|
-
'proxy',
|
|
128
188
|
);
|
|
129
189
|
const router = await UnderpostDeploy.API.routerFactory(deployId, env);
|
|
130
|
-
const pathPortAssignmentData = pathPortAssignmentFactory(router, confServer);
|
|
190
|
+
const pathPortAssignmentData = await pathPortAssignmentFactory(deployId, router, confServer);
|
|
131
191
|
const { fromPort, toPort } = deployRangePortFactory(router);
|
|
132
192
|
const deploymentVersions = options.versions.split(',');
|
|
133
193
|
fs.mkdirSync(`./engine-private/conf/${deployId}/build/${env}`, { recursive: true });
|
|
@@ -208,6 +268,12 @@ spec:
|
|
|
208
268
|
}
|
|
209
269
|
}
|
|
210
270
|
},
|
|
271
|
+
/**
|
|
272
|
+
* Builds a Certificate resource for a host using cert-manager.
|
|
273
|
+
* @param {string} host - Hostname for which the certificate is being built.
|
|
274
|
+
* @returns {string} - Certificate resource YAML for the specified host.
|
|
275
|
+
* @memberof UnderpostDeploy
|
|
276
|
+
*/
|
|
211
277
|
buildCertManagerCertificate({ host }) {
|
|
212
278
|
return `
|
|
213
279
|
---
|
|
@@ -224,6 +290,12 @@ spec:
|
|
|
224
290
|
kind: ClusterIssuer
|
|
225
291
|
secretName: ${host}`;
|
|
226
292
|
},
|
|
293
|
+
/**
|
|
294
|
+
* Retrieves the current traffic status for a deployment.
|
|
295
|
+
* @param {string} deployId - Deployment ID for which the traffic status is being retrieved.
|
|
296
|
+
* @returns {string|null} - Current traffic status ('blue' or 'green') or null if not found.
|
|
297
|
+
* @memberof UnderpostDeploy
|
|
298
|
+
*/
|
|
227
299
|
getCurrentTraffic(deployId) {
|
|
228
300
|
// kubectl get deploy,sts,svc,configmap,secret -n default -o yaml --export > default.yaml
|
|
229
301
|
const hostTest = Object.keys(
|
|
@@ -232,6 +304,32 @@ spec:
|
|
|
232
304
|
const info = shellExec(`sudo kubectl get HTTPProxy/${hostTest} -o yaml`, { silent: true, stdout: true });
|
|
233
305
|
return info.match('blue') ? 'blue' : info.match('green') ? 'green' : null;
|
|
234
306
|
},
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Callback function for handling deployment options.
|
|
310
|
+
* @param {string} deployList - List of deployment IDs to include in the manifest.
|
|
311
|
+
* @param {string} env - Environment for which the manifest is being built.
|
|
312
|
+
* @param {object} options - Options for the manifest build process.
|
|
313
|
+
* @param {string} options.remove - Whether to remove the deployment.
|
|
314
|
+
* @param {string} options.infoRouter - Whether to display router information.
|
|
315
|
+
* @param {string} options.sync - Whether to synchronize the deployment.
|
|
316
|
+
* @param {string} options.buildManifest - Whether to build the manifest.
|
|
317
|
+
* @param {string} options.infoUtil - Whether to display utility information.
|
|
318
|
+
* @param {string} options.expose - Whether to expose the deployment.
|
|
319
|
+
* @param {string} options.cert - Whether to create a certificate.
|
|
320
|
+
* @param {string} options.certHosts - List of hosts for which certificates are being created.
|
|
321
|
+
* @param {string} options.versions - Comma-separated list of versions to deploy.
|
|
322
|
+
* @param {string} options.image - Docker image for the deployment.
|
|
323
|
+
* @param {string} options.traffic - Current traffic status for the deployment.
|
|
324
|
+
* @param {string} options.replicas - Number of replicas for the deployment.
|
|
325
|
+
* @param {string} options.node - Node name for resource allocation.
|
|
326
|
+
* @param {string} options.restoreHosts - Whether to restore hosts.
|
|
327
|
+
* @param {string} options.disableUpdateDeployment - Whether to disable updating the deployment.
|
|
328
|
+
* @param {string} options.infoTraffic - Whether to display traffic information.
|
|
329
|
+
* @param {string} options.etcHosts - Whether to update /etc/hosts.
|
|
330
|
+
* @returns {Promise<void>} - Promise that resolves when the callback is complete.
|
|
331
|
+
* @memberof UnderpostDeploy
|
|
332
|
+
*/
|
|
235
333
|
async callback(
|
|
236
334
|
deployList = '',
|
|
237
335
|
env = 'development',
|
|
@@ -399,6 +497,13 @@ EOF`);
|
|
|
399
497
|
` + renderHosts,
|
|
400
498
|
);
|
|
401
499
|
},
|
|
500
|
+
/**
|
|
501
|
+
* Retrieves information about a deployment.
|
|
502
|
+
* @param {string} deployId - Deployment ID for which information is being retrieved.
|
|
503
|
+
* @param {string} kindType - Type of Kubernetes resource to retrieve information for (e.g. 'pods').
|
|
504
|
+
* @returns {Array<object>} - Array of objects containing information about the deployment.
|
|
505
|
+
* @memberof UnderpostDeploy
|
|
506
|
+
*/
|
|
402
507
|
get(deployId, kindType = 'pods') {
|
|
403
508
|
const raw = shellExec(`sudo kubectl get ${kindType} --all-namespaces -o wide`, {
|
|
404
509
|
stdout: true,
|
|
@@ -430,6 +535,11 @@ EOF`);
|
|
|
430
535
|
|
|
431
536
|
return result;
|
|
432
537
|
},
|
|
538
|
+
/**
|
|
539
|
+
* Retrieves the resources factory for a deployment.
|
|
540
|
+
* @returns {object} - Object containing the resources factory for the deployment.
|
|
541
|
+
* @memberof UnderpostDeploy
|
|
542
|
+
*/
|
|
433
543
|
resourcesFactory() {
|
|
434
544
|
return {
|
|
435
545
|
requests: {
|
|
@@ -443,6 +553,14 @@ EOF`);
|
|
|
443
553
|
totalPods: UnderpostRootEnv.API.get('total-pods'),
|
|
444
554
|
};
|
|
445
555
|
},
|
|
556
|
+
/**
|
|
557
|
+
* Checks if a container file exists in a pod.
|
|
558
|
+
* @param {object} options - Options for the check.
|
|
559
|
+
* @param {string} options.podName - Name of the pod to check.
|
|
560
|
+
* @param {string} options.path - Path to the container file to check.
|
|
561
|
+
* @returns {boolean} - True if the container file exists, false otherwise.
|
|
562
|
+
* @memberof UnderpostDeploy
|
|
563
|
+
*/
|
|
446
564
|
existsContainerFile({ podName, path }) {
|
|
447
565
|
return JSON.parse(
|
|
448
566
|
shellExec(`kubectl exec ${podName} -- test -f ${path} && echo "true" || echo "false"`, {
|
|
@@ -452,6 +570,15 @@ EOF`);
|
|
|
452
570
|
}).trim(),
|
|
453
571
|
);
|
|
454
572
|
},
|
|
573
|
+
/**
|
|
574
|
+
* Checks the status of a deployment.
|
|
575
|
+
* @param {string} deployId - Deployment ID for which the status is being checked.
|
|
576
|
+
* @param {string} env - Environment for which the status is being checked.
|
|
577
|
+
* @param {string} traffic - Current traffic status for the deployment.
|
|
578
|
+
* @param {Array<string>} ignoresNames - List of pod names to ignore.
|
|
579
|
+
* @returns {object} - Object containing the status of the deployment.
|
|
580
|
+
* @memberof UnderpostDeploy
|
|
581
|
+
*/
|
|
455
582
|
checkDeploymentReadyStatus(deployId, env, traffic, ignoresNames = []) {
|
|
456
583
|
const cmd = `underpost config get container-status`;
|
|
457
584
|
const pods = UnderpostDeploy.API.get(`${deployId}-${env}-${traffic}`);
|
|
@@ -476,12 +603,25 @@ EOF`);
|
|
|
476
603
|
readyPods,
|
|
477
604
|
};
|
|
478
605
|
},
|
|
606
|
+
/**
|
|
607
|
+
* Creates a configmap for a deployment.
|
|
608
|
+
* @param {string} env - Environment for which the configmap is being created.
|
|
609
|
+
* @memberof UnderpostDeploy
|
|
610
|
+
*/
|
|
479
611
|
configMap(env) {
|
|
480
612
|
shellExec(`kubectl delete configmap underpost-config`);
|
|
481
613
|
shellExec(
|
|
482
614
|
`kubectl create configmap underpost-config --from-file=/home/dd/engine/engine-private/conf/dd-cron/.env.${env}`,
|
|
483
615
|
);
|
|
484
616
|
},
|
|
617
|
+
/**
|
|
618
|
+
* Switches the traffic for a deployment.
|
|
619
|
+
* @param {string} deployId - Deployment ID for which the traffic is being switched.
|
|
620
|
+
* @param {string} env - Environment for which the traffic is being switched.
|
|
621
|
+
* @param {string} targetTraffic - Target traffic status for the deployment.
|
|
622
|
+
* @param {number} replicas - Number of replicas for the deployment.
|
|
623
|
+
* @memberof UnderpostDeploy
|
|
624
|
+
*/
|
|
485
625
|
switchTraffic(deployId, env, targetTraffic, replicas = 1) {
|
|
486
626
|
UnderpostRootEnv.API.set(`${deployId}-${env}-traffic`, targetTraffic);
|
|
487
627
|
shellExec(
|
|
@@ -489,6 +629,11 @@ EOF`);
|
|
|
489
629
|
);
|
|
490
630
|
shellExec(`sudo kubectl apply -f ./engine-private/conf/${deployId}/build/${env}/proxy.yaml`);
|
|
491
631
|
},
|
|
632
|
+
/**
|
|
633
|
+
* Creates a hosts file for a deployment.
|
|
634
|
+
* @param {Array<string>} hosts - List of hosts to be added to the hosts file.
|
|
635
|
+
* @memberof UnderpostDeploy
|
|
636
|
+
*/
|
|
492
637
|
etcHostFactory(hosts = []) {
|
|
493
638
|
const renderHosts = `127.0.0.1 ${hosts.join(
|
|
494
639
|
' ',
|
|
@@ -498,10 +643,50 @@ EOF`);
|
|
|
498
643
|
fs.writeFileSync(`/etc/hosts`, renderHosts, 'utf8');
|
|
499
644
|
return { renderHosts };
|
|
500
645
|
},
|
|
646
|
+
/**
|
|
647
|
+
* Checks if a TLS context is valid.
|
|
648
|
+
* @param {object} options - Options for the check.
|
|
649
|
+
* @param {string} options.host - Host for which the TLS context is being checked.
|
|
650
|
+
* @param {string} options.env - Environment for which the TLS context is being checked.
|
|
651
|
+
* @param {object} options.options - Options for the TLS context check.
|
|
652
|
+
* @returns {boolean} - True if the TLS context is valid, false otherwise.
|
|
653
|
+
* @memberof UnderpostDeploy
|
|
654
|
+
*/
|
|
501
655
|
isValidTLSContext: ({ host, env, options }) =>
|
|
502
656
|
env === 'production' &&
|
|
503
657
|
options.cert === true &&
|
|
504
658
|
(!options.certHosts || options.certHosts.split(',').includes(host)),
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* Monitors the ready status of a deployment.
|
|
662
|
+
* @param {string} deployId - Deployment ID for which the ready status is being monitored.
|
|
663
|
+
* @param {string} env - Environment for which the ready status is being monitored.
|
|
664
|
+
* @param {string} targetTraffic - Target traffic status for the deployment.
|
|
665
|
+
* @param {Array<string>} ignorePods - List of pod names to ignore.
|
|
666
|
+
* @memberof UnderpostDeploy
|
|
667
|
+
*/
|
|
668
|
+
async monitorReadyRunner(deployId, env, targetTraffic, ignorePods = []) {
|
|
669
|
+
let checkStatusIteration = 0;
|
|
670
|
+
const checkStatusIterationMsDelay = 1000;
|
|
671
|
+
const iteratorTag = `[${deployId}-${env}-${targetTraffic}]`;
|
|
672
|
+
logger.info('Deployment init', { deployId, env, targetTraffic, checkStatusIterationMsDelay });
|
|
673
|
+
const minReadyOk = 3;
|
|
674
|
+
let readyOk = 0;
|
|
675
|
+
|
|
676
|
+
while (readyOk < minReadyOk) {
|
|
677
|
+
const ready = UnderpostDeploy.API.checkDeploymentReadyStatus(deployId, env, targetTraffic, ignorePods).ready;
|
|
678
|
+
if (ready === true) {
|
|
679
|
+
readyOk++;
|
|
680
|
+
logger.info(`${iteratorTag} | Deployment ready. Verification number: ${readyOk}`);
|
|
681
|
+
}
|
|
682
|
+
await timer(checkStatusIterationMsDelay);
|
|
683
|
+
checkStatusIteration++;
|
|
684
|
+
logger.info(
|
|
685
|
+
`${iteratorTag} | Deployment in progress... | Delay number check iterations: ${checkStatusIteration}`,
|
|
686
|
+
);
|
|
687
|
+
}
|
|
688
|
+
logger.info(`${iteratorTag} | Deployment ready. | Total delay number check iterations: ${checkStatusIteration}`);
|
|
689
|
+
},
|
|
505
690
|
};
|
|
506
691
|
}
|
|
507
692
|
|
package/src/cli/env.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment module for managing the environment variables of the underpost root
|
|
3
|
+
* @module src/cli/env.js
|
|
4
|
+
* @namespace UnderpostEnv
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
import { getNpmRootPath, writeEnv } from '../server/conf.js';
|
|
2
8
|
import fs from 'fs-extra';
|
|
3
9
|
import { loggerFactory } from '../server/logger.js';
|
|
@@ -7,8 +13,20 @@ dotenv.config();
|
|
|
7
13
|
|
|
8
14
|
const logger = loggerFactory(import.meta);
|
|
9
15
|
|
|
16
|
+
/**
|
|
17
|
+
* @class UnderpostEnv
|
|
18
|
+
* @description Manages the environment variables of the underpost root.
|
|
19
|
+
* @memberof UnderpostEnv
|
|
20
|
+
*/
|
|
10
21
|
class UnderpostRootEnv {
|
|
11
22
|
static API = {
|
|
23
|
+
/**
|
|
24
|
+
* @method set
|
|
25
|
+
* @description Sets an environment variable in the underpost root environment.
|
|
26
|
+
* @param {string} key - The key of the environment variable to set.
|
|
27
|
+
* @param {string} value - The value of the environment variable to set.
|
|
28
|
+
* @memberof UnderpostEnv
|
|
29
|
+
*/
|
|
12
30
|
set(key, value) {
|
|
13
31
|
const exeRootPath = `${getNpmRootPath()}/underpost`;
|
|
14
32
|
const envPath = `${exeRootPath}/.env`;
|
|
@@ -17,6 +35,12 @@ class UnderpostRootEnv {
|
|
|
17
35
|
env[key] = value;
|
|
18
36
|
writeEnv(envPath, env);
|
|
19
37
|
},
|
|
38
|
+
/**
|
|
39
|
+
* @method delete
|
|
40
|
+
* @description Deletes an environment variable from the underpost root environment.
|
|
41
|
+
* @param {string} key - The key of the environment variable to delete.
|
|
42
|
+
* @memberof UnderpostEnv
|
|
43
|
+
*/
|
|
20
44
|
delete(key) {
|
|
21
45
|
const exeRootPath = `${getNpmRootPath()}/underpost`;
|
|
22
46
|
const envPath = `${exeRootPath}/.env`;
|
|
@@ -25,6 +49,15 @@ class UnderpostRootEnv {
|
|
|
25
49
|
delete env[key];
|
|
26
50
|
writeEnv(envPath, env);
|
|
27
51
|
},
|
|
52
|
+
/**
|
|
53
|
+
* @method get
|
|
54
|
+
* @description Gets an environment variable from the underpost root environment.
|
|
55
|
+
* @param {string} key - The key of the environment variable to get.
|
|
56
|
+
* @param {string} value - The value of the environment variable to get.
|
|
57
|
+
* @param {object} options - Options for getting the environment variable.
|
|
58
|
+
* @param {boolean} [options.plain=false] - If true, returns the environment variable value as a string.
|
|
59
|
+
* @memberof UnderpostEnv
|
|
60
|
+
*/
|
|
28
61
|
get(key, value, options = { plain: false }) {
|
|
29
62
|
const exeRootPath = `${getNpmRootPath()}/underpost`;
|
|
30
63
|
const envPath = `${exeRootPath}/.env`;
|
|
@@ -36,6 +69,11 @@ class UnderpostRootEnv {
|
|
|
36
69
|
options?.plain === true ? console.log(env[key]) : logger.info(`${key}(${typeof env[key]})`, env[key]);
|
|
37
70
|
return env[key];
|
|
38
71
|
},
|
|
72
|
+
/**
|
|
73
|
+
* @method list
|
|
74
|
+
* @description Lists all environment variables in the underpost root environment.
|
|
75
|
+
* @memberof UnderpostEnv
|
|
76
|
+
*/
|
|
39
77
|
list() {
|
|
40
78
|
const exeRootPath = `${getNpmRootPath()}/underpost`;
|
|
41
79
|
const envPath = `${exeRootPath}/.env`;
|
|
@@ -47,6 +85,11 @@ class UnderpostRootEnv {
|
|
|
47
85
|
logger.info('underpost root', env);
|
|
48
86
|
return env;
|
|
49
87
|
},
|
|
88
|
+
/**
|
|
89
|
+
* @method clean
|
|
90
|
+
* @description Cleans the underpost root environment by removing the environment file.
|
|
91
|
+
* @memberof UnderpostEnv
|
|
92
|
+
*/
|
|
50
93
|
clean() {
|
|
51
94
|
const exeRootPath = `${getNpmRootPath()}/underpost`;
|
|
52
95
|
const envPath = `${exeRootPath}/.env`;
|
package/src/cli/fs.js
CHANGED
|
@@ -1,18 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File storage module for managing file operations using Cloudinary.
|
|
3
|
+
* @module src/cli/fs.js
|
|
4
|
+
* @namespace UnderpostFileStorage
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
import { v2 as cloudinary } from 'cloudinary';
|
|
2
8
|
import { loggerFactory } from '../server/logger.js';
|
|
3
9
|
import dotenv from 'dotenv';
|
|
4
10
|
import AdmZip from 'adm-zip';
|
|
5
11
|
import * as dir from 'path';
|
|
6
12
|
import fs from 'fs-extra';
|
|
7
|
-
import
|
|
13
|
+
import Downloader from '../server/downloader.js';
|
|
8
14
|
import UnderpostRepository from './repository.js';
|
|
9
15
|
import { shellExec } from '../server/process.js';
|
|
10
16
|
dotenv.config();
|
|
11
17
|
|
|
12
18
|
const logger = loggerFactory(import.meta);
|
|
13
19
|
|
|
20
|
+
/**
|
|
21
|
+
* @class UnderpostFileStorage
|
|
22
|
+
* @description Manages file storage operations using Cloudinary.
|
|
23
|
+
* This class provides a set of static methods to upload, pull, and delete files
|
|
24
|
+
* from Cloudinary, as well as manage a local storage configuration file.
|
|
25
|
+
*/
|
|
14
26
|
class UnderpostFileStorage {
|
|
15
27
|
static API = {
|
|
28
|
+
/**
|
|
29
|
+
* @method cloudinaryConfig
|
|
30
|
+
* @description Configures the Cloudinary client with environment variables.
|
|
31
|
+
* @memberof UnderpostFileStorage
|
|
32
|
+
*/
|
|
16
33
|
cloudinaryConfig() {
|
|
17
34
|
// https://console.cloudinary.com/
|
|
18
35
|
cloudinary.config({
|
|
@@ -21,6 +38,15 @@ class UnderpostFileStorage {
|
|
|
21
38
|
api_secret: process.env.CLOUDINARY_API_SECRET,
|
|
22
39
|
});
|
|
23
40
|
},
|
|
41
|
+
/**
|
|
42
|
+
* @method getStorageConf
|
|
43
|
+
* @description Retrieves the storage configuration for a specific deployment.
|
|
44
|
+
* @param {object} options - An object containing deployment-specific options.
|
|
45
|
+
* @param {string} options.deployId - The identifier for the deployment.
|
|
46
|
+
* @param {string} [options.storageFilePath] - The path to the storage configuration file.
|
|
47
|
+
* @returns {object} An object containing the storage configuration and storage file path.
|
|
48
|
+
* @memberof UnderpostFileStorage
|
|
49
|
+
*/
|
|
24
50
|
getStorageConf(options) {
|
|
25
51
|
let storage, storageConf;
|
|
26
52
|
if (options.deployId && typeof options.deployId === 'string') {
|
|
@@ -30,9 +56,31 @@ class UnderpostFileStorage {
|
|
|
30
56
|
}
|
|
31
57
|
return { storage, storageConf };
|
|
32
58
|
},
|
|
59
|
+
/**
|
|
60
|
+
* @method writeStorageConf
|
|
61
|
+
* @description Writes the storage configuration to a file.
|
|
62
|
+
* @param {object} storage - The storage configuration object.
|
|
63
|
+
* @param {string} storageConf - The path to the storage configuration file.
|
|
64
|
+
* @memberof UnderpostFileStorage
|
|
65
|
+
*/
|
|
33
66
|
writeStorageConf(storage, storageConf) {
|
|
34
67
|
if (storage) fs.writeFileSync(storageConf, JSON.stringify(storage, null, 4), 'utf8');
|
|
35
68
|
},
|
|
69
|
+
/**
|
|
70
|
+
* @method recursiveCallback
|
|
71
|
+
* @description Recursively processes files and directories based on the provided options.
|
|
72
|
+
* @param {string} path - The path to the directory to process.
|
|
73
|
+
* @param {object} [options] - An object containing options for the recursive callback.
|
|
74
|
+
* @param {boolean} [options.rm=false] - Flag to remove files and directories.
|
|
75
|
+
* @param {boolean} [options.recursive=false] - Flag to process directories recursively.
|
|
76
|
+
* @param {string} [options.deployId=''] - The identifier for the deployment.
|
|
77
|
+
* @param {boolean} [options.force=false] - Flag to force file operations.
|
|
78
|
+
* @param {boolean} [options.pull=false] - Flag to pull files from storage.
|
|
79
|
+
* @param {boolean} [options.git=false] - Flag to use Git for file operations.
|
|
80
|
+
* @param {string} [options.storageFilePath=''] - The path to the storage configuration file.
|
|
81
|
+
* @returns {Promise<void>} A promise that resolves when the recursive callback is complete.
|
|
82
|
+
* @memberof UnderpostFileStorage
|
|
83
|
+
*/
|
|
36
84
|
async recursiveCallback(
|
|
37
85
|
path,
|
|
38
86
|
options = {
|
|
@@ -84,6 +132,21 @@ class UnderpostFileStorage {
|
|
|
84
132
|
shellExec(`underpost cmt ${path} feat`);
|
|
85
133
|
}
|
|
86
134
|
},
|
|
135
|
+
/**
|
|
136
|
+
* @method callback
|
|
137
|
+
* @description Orchestrates file storage operations based on the provided options.
|
|
138
|
+
* This method handles file uploads, deletions, and recursive processing of directories.
|
|
139
|
+
* @param {string} path - The path to the file or directory to process.
|
|
140
|
+
* @param {object} [options] - An object containing options for the callback.
|
|
141
|
+
* @param {boolean} [options.rm=false] - Flag to remove files and directories.
|
|
142
|
+
* @param {boolean} [options.recursive=false] - Flag to process directories recursively.
|
|
143
|
+
* @param {string} [options.deployId=''] - The identifier for the deployment.
|
|
144
|
+
* @param {boolean} [options.force=false] - Flag to force file operations.
|
|
145
|
+
* @param {boolean} [options.pull=false] - Flag to pull files from storage.
|
|
146
|
+
* @param {boolean} [options.git=false] - Flag to use Git for file operations.
|
|
147
|
+
* @returns {Promise<void>} A promise that resolves when the callback is complete.
|
|
148
|
+
* @memberof UnderpostFileStorage
|
|
149
|
+
*/
|
|
87
150
|
async callback(
|
|
88
151
|
path,
|
|
89
152
|
options = { rm: false, recursive: false, deployId: '', force: false, pull: false, git: false },
|
|
@@ -94,6 +157,16 @@ class UnderpostFileStorage {
|
|
|
94
157
|
if (options.rm === true) return await UnderpostFileStorage.API.delete(path, options);
|
|
95
158
|
return await UnderpostFileStorage.API.upload(path, options);
|
|
96
159
|
},
|
|
160
|
+
/**
|
|
161
|
+
* @method upload
|
|
162
|
+
* @description Uploads a file to Cloudinary.
|
|
163
|
+
* @param {string} path - The path to the file to upload.
|
|
164
|
+
* @param {object} [options] - An object containing options for the upload.
|
|
165
|
+
* @param {boolean} [options.force=false] - Flag to force file operations.
|
|
166
|
+
* @param {string} [options.storageFilePath=''] - The path to the storage configuration file.
|
|
167
|
+
* @returns {Promise<object>} A promise that resolves to the upload result.
|
|
168
|
+
* @memberof UnderpostFileStorage
|
|
169
|
+
*/
|
|
97
170
|
async upload(
|
|
98
171
|
path,
|
|
99
172
|
options = { rm: false, recursive: false, deployId: '', force: false, pull: false, storageFilePath: '' },
|
|
@@ -115,6 +188,13 @@ class UnderpostFileStorage {
|
|
|
115
188
|
UnderpostFileStorage.API.writeStorageConf(storage, storageConf);
|
|
116
189
|
return uploadResult;
|
|
117
190
|
},
|
|
191
|
+
/**
|
|
192
|
+
* @method pull
|
|
193
|
+
* @description Pulls a file from Cloudinary.
|
|
194
|
+
* @param {string} path - The path to the file to pull.
|
|
195
|
+
* @returns {Promise<void>} A promise that resolves when the file is pulled.
|
|
196
|
+
* @memberof UnderpostFileStorage
|
|
197
|
+
*/
|
|
118
198
|
async pull(path) {
|
|
119
199
|
UnderpostFileStorage.API.cloudinaryConfig();
|
|
120
200
|
const folder = dir.dirname(path);
|
|
@@ -124,7 +204,7 @@ class UnderpostFileStorage {
|
|
|
124
204
|
resource_type: 'raw',
|
|
125
205
|
});
|
|
126
206
|
logger.info('download result', downloadResult);
|
|
127
|
-
await Downloader(downloadResult, path + '.zip');
|
|
207
|
+
await Downloader.downloadFile(downloadResult, path + '.zip');
|
|
128
208
|
path = UnderpostFileStorage.API.zip2File(path + '.zip');
|
|
129
209
|
fs.removeSync(path + '.zip');
|
|
130
210
|
},
|
|
@@ -138,6 +218,13 @@ class UnderpostFileStorage {
|
|
|
138
218
|
logger.info('delete result', deleteResult);
|
|
139
219
|
return deleteResult;
|
|
140
220
|
},
|
|
221
|
+
/**
|
|
222
|
+
* @method file2Zip
|
|
223
|
+
* @description Converts a file to a zip file.
|
|
224
|
+
* @param {string} path - The path to the file to convert.
|
|
225
|
+
* @returns {string} The path to the zip file.
|
|
226
|
+
* @memberof UnderpostFileStorage
|
|
227
|
+
*/
|
|
141
228
|
file2Zip(path) {
|
|
142
229
|
const zip = new AdmZip();
|
|
143
230
|
zip.addLocalFile(path, '/');
|
|
@@ -145,6 +232,13 @@ class UnderpostFileStorage {
|
|
|
145
232
|
zip.writeZip(path);
|
|
146
233
|
return path;
|
|
147
234
|
},
|
|
235
|
+
/**
|
|
236
|
+
* @method zip2File
|
|
237
|
+
* @description Converts a zip file to a file.
|
|
238
|
+
* @param {string} path - The path to the zip file to convert.
|
|
239
|
+
* @returns {string} The path to the file.
|
|
240
|
+
* @memberof UnderpostFileStorage
|
|
241
|
+
*/
|
|
148
242
|
zip2File(path) {
|
|
149
243
|
const zip = new AdmZip(path);
|
|
150
244
|
path = path.replaceAll('.zip', '');
|
package/src/cli/image.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image management module for pull, build, creation of docker images and loading them into Kubernetes clusters
|
|
3
|
+
* @module src/cli/image.js
|
|
4
|
+
* @namespace UnderpostImage
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
import fs from 'fs-extra';
|
|
2
8
|
import dotenv from 'dotenv';
|
|
3
9
|
import { loggerFactory } from '../server/logger.js';
|
|
@@ -9,6 +15,13 @@ dotenv.config();
|
|
|
9
15
|
|
|
10
16
|
const logger = loggerFactory(import.meta);
|
|
11
17
|
|
|
18
|
+
/**
|
|
19
|
+
* @class UnderpostImage
|
|
20
|
+
* @description Manages Docker image operations, including pulling, building, and loading images into Kubernetes clusters.
|
|
21
|
+
* This class provides a set of static methods to handle image operations, including pulling base images,
|
|
22
|
+
* building custom images, and loading them into specified Kubernetes clusters (Kind, Kubeadm, or K3s).
|
|
23
|
+
* @memberof UnderpostImage
|
|
24
|
+
*/
|
|
12
25
|
class UnderpostImage {
|
|
13
26
|
static API = {
|
|
14
27
|
dockerfile: {
|
|
@@ -22,6 +35,7 @@ class UnderpostImage {
|
|
|
22
35
|
* @param {boolean} [options.k3sLoad=false] - If true, load image into K3s cluster.
|
|
23
36
|
* @param {string} [options.path=false] - Path to the Dockerfile context.
|
|
24
37
|
* @param {string} [options.version=''] - Version tag for the image.
|
|
38
|
+
* @memberof UnderpostImage
|
|
25
39
|
*/
|
|
26
40
|
pullBaseImages(
|
|
27
41
|
options = {
|
|
@@ -68,6 +82,7 @@ class UnderpostImage {
|
|
|
68
82
|
* @param {boolean} [options.secrets=false] - If true, load secrets from the .env file for the build.
|
|
69
83
|
* @param {string} [options.secretsPath=''] - Custom path to the .env file for secrets.
|
|
70
84
|
* @param {boolean} [options.reset=false] - If true, perform a no-cache build.
|
|
85
|
+
* @memberof UnderpostImage
|
|
71
86
|
*/
|
|
72
87
|
build(
|
|
73
88
|
options = {
|
package/src/cli/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import dotenv from 'dotenv';
|
|
2
2
|
import { Command } from 'commander';
|
|
3
|
-
import Underpost from '../index.js';
|
|
3
|
+
import Underpost, { UnderpostRootEnv } from '../index.js';
|
|
4
4
|
import { getNpmRootPath, getUnderpostRootPath, loadConf } from '../server/conf.js';
|
|
5
5
|
import fs from 'fs-extra';
|
|
6
6
|
import { commitData } from '../client/components/core/CommonJs.js';
|
|
@@ -26,7 +26,8 @@ program
|
|
|
26
26
|
.option('--deploy-id', 'Crete deploy ID conf env files')
|
|
27
27
|
.option('--cluster', 'Create deploy ID cluster files and sync to current cluster')
|
|
28
28
|
.option('--dev', 'Sets the development cli context')
|
|
29
|
-
.
|
|
29
|
+
.option('--sub-conf <sub-conf>', 'Create sub conf env files')
|
|
30
|
+
.description('Initializes a new Underpost project, service, or configuration.')
|
|
30
31
|
.action(Underpost.repo.new);
|
|
31
32
|
|
|
32
33
|
// 'start' command: Start application servers, build pipelines, or services
|
|
@@ -86,10 +87,22 @@ program
|
|
|
86
87
|
// 'env' command: Manage environment variables
|
|
87
88
|
program
|
|
88
89
|
.command('env')
|
|
89
|
-
.argument(
|
|
90
|
+
.argument(
|
|
91
|
+
'[deploy-id]',
|
|
92
|
+
`The deployment configuration ID. Use 'clean' to restore default environment settings. User 'root' to load root env. User 'current' to get plain current deploy Id.`,
|
|
93
|
+
)
|
|
90
94
|
.argument('[env]', 'Optional: The environment to set (e.g., "production", "development"). Defaults to "production".')
|
|
95
|
+
.argument('[subConf]', 'Optional: The sub configuration to set.')
|
|
91
96
|
.description('Sets environment variables and configurations related to a specific deployment ID.')
|
|
92
|
-
.action(
|
|
97
|
+
.action((deployId, env, subConf) => {
|
|
98
|
+
if (fs.existsSync(`./engine-private/conf/${deployId}/.env.${env}`))
|
|
99
|
+
dotenv.config({ path: `./engine-private/conf/${deployId}/.env.${env}`, override: true });
|
|
100
|
+
else if (deployId === 'root') {
|
|
101
|
+
deployId = UnderpostRootEnv.API.get('DEPLOY_ID');
|
|
102
|
+
} else dotenv.config({ path: `./.env`, override: true });
|
|
103
|
+
|
|
104
|
+
loadConf(deployId, subConf);
|
|
105
|
+
});
|
|
93
106
|
|
|
94
107
|
// 'config' command: Manage Underpost configurations
|
|
95
108
|
program
|