@underpostnet/underpost 2.98.3 → 2.99.1
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 +1 -0
- package/.env.production +1 -0
- package/.env.test +1 -0
- package/README.md +2 -3
- package/bin/deploy.js +1 -1
- package/cli.md +113 -110
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +4 -4
- package/package.json +1 -2
- package/src/api/user/user.router.js +7 -40
- package/src/cli/baremetal.js +67 -71
- package/src/cli/cloud-init.js +11 -12
- package/src/cli/cluster.js +22 -24
- package/src/cli/db.js +43 -50
- package/src/cli/deploy.js +163 -61
- package/src/cli/env.js +20 -5
- package/src/cli/fs.js +19 -21
- package/src/cli/index.js +38 -32
- package/src/cli/lxd.js +5 -5
- package/src/cli/monitor.js +83 -88
- package/src/cli/repository.js +7 -6
- package/src/cli/run.js +498 -288
- package/src/cli/secrets.js +3 -3
- package/src/cli/ssh.js +80 -32
- package/src/cli/static.js +1 -1
- package/src/cli/test.js +6 -7
- package/src/index.js +49 -32
- package/src/runtime/express/Express.js +7 -6
- package/src/server/auth.js +6 -1
- package/src/server/backup.js +11 -1
- package/src/server/conf.js +4 -4
- package/src/{cli → server}/cron.js +56 -29
- package/src/server/dns.js +39 -31
- package/src/server/peer.js +2 -2
- package/src/server/process.js +2 -2
- package/src/server/proxy.js +8 -7
- package/src/server/runtime.js +4 -7
- package/src/server/start.js +28 -15
- package/src/ws/IoServer.js +2 -3
- package/scripts/ssh-cluster-info.sh +0 -15
- package/src/cli/script.js +0 -85
- package/src/monitor.js +0 -34
package/src/cli/run.js
CHANGED
|
@@ -4,30 +4,138 @@
|
|
|
4
4
|
* @namespace UnderpostRun
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { daemonProcess, getTerminalPid, openTerminal,
|
|
7
|
+
import { daemonProcess, getTerminalPid, openTerminal, shellCd, shellExec } from '../server/process.js';
|
|
8
8
|
import {
|
|
9
9
|
awaitDeployMonitor,
|
|
10
10
|
buildKindPorts,
|
|
11
11
|
Config,
|
|
12
12
|
getNpmRootPath,
|
|
13
|
-
getUnderpostRootPath,
|
|
14
13
|
isDeployRunnerContext,
|
|
15
14
|
writeEnv,
|
|
16
15
|
} from '../server/conf.js';
|
|
17
16
|
import { actionInitLog, loggerFactory } from '../server/logger.js';
|
|
18
|
-
|
|
17
|
+
|
|
19
18
|
import fs from 'fs-extra';
|
|
20
19
|
import { range, setPad, timer } from '../client/components/core/CommonJs.js';
|
|
21
|
-
|
|
22
|
-
import UnderpostDB from './db.js';
|
|
23
|
-
import UnderpostRootEnv from './env.js';
|
|
24
|
-
import UnderpostRepository from './repository.js';
|
|
20
|
+
|
|
25
21
|
import os from 'os';
|
|
26
|
-
import Underpost
|
|
22
|
+
import Underpost from '../index.js';
|
|
27
23
|
import dotenv from 'dotenv';
|
|
28
24
|
|
|
29
25
|
const logger = loggerFactory(import.meta);
|
|
30
26
|
|
|
27
|
+
/**
|
|
28
|
+
* @constant DEFAULT_OPTION
|
|
29
|
+
* @description Default options for the UnderpostRun class.
|
|
30
|
+
* @type {Object}
|
|
31
|
+
* @property {boolean} dev - Whether to run in development mode.
|
|
32
|
+
* @property {string} podName - The name of the pod to run.
|
|
33
|
+
* @property {string} nodeName - The name of the node to run.
|
|
34
|
+
* @property {number} port - Custom port to use.
|
|
35
|
+
* @property {boolean} etcHosts - Whether to modify /etc/hosts.
|
|
36
|
+
* @property {string} volumeHostPath - The host path for the volume.
|
|
37
|
+
* @property {string} volumeMountPath - The mount path for the volume.
|
|
38
|
+
* @property {string} imageName - The name of the image to run.
|
|
39
|
+
* @property {string} containerName - The name of the container to run.
|
|
40
|
+
* @property {string} namespace - The namespace to run in.
|
|
41
|
+
* @property {string} timeoutResponse - The response timeout duration.
|
|
42
|
+
* @property {string} timeoutIdle - The idle timeout duration.
|
|
43
|
+
* @property {string} retryCount - The number of retries.
|
|
44
|
+
* @property {string} retryPerTryTimeout - The timeout duration per retry.
|
|
45
|
+
* @property {boolean} build - Whether to build the image.
|
|
46
|
+
* @property {number} replicas - The number of replicas to run.
|
|
47
|
+
* @property {boolean} force - Whether to force the operation.
|
|
48
|
+
* @property {boolean} reset - Whether to reset the operation.
|
|
49
|
+
* @property {boolean} tls - Whether to use TLS.
|
|
50
|
+
* @property {string} cmd - The command to run in the container.
|
|
51
|
+
* @property {string} tty - The TTY option for the container.
|
|
52
|
+
* @property {string} stdin - The stdin option for the container.
|
|
53
|
+
* @property {string} restartPolicy - The restart policy for the container.
|
|
54
|
+
* @property {string} runtimeClassName - The runtime class name for the container.
|
|
55
|
+
* @property {string} imagePullPolicy - The image pull policy for the container.
|
|
56
|
+
* @property {string} apiVersion - The API version for the container.
|
|
57
|
+
* @property {string} claimName - The claim name for the volume.
|
|
58
|
+
* @property {string} kindType - The kind of resource to create.
|
|
59
|
+
* @property {boolean} terminal - Whether to open a terminal.
|
|
60
|
+
* @property {number} devProxyPortOffset - The port offset for the development proxy.
|
|
61
|
+
* @property {boolean} hostNetwork - Whether to use host networking.
|
|
62
|
+
* @property {string} requestsMemory - The memory request for the container.
|
|
63
|
+
* @property {string} requestsCpu - The CPU request for the container.
|
|
64
|
+
* @property {string} limitsMemory - The memory limit for the container.
|
|
65
|
+
* @property {string} limitsCpu - The CPU limit for the container.
|
|
66
|
+
* @property {string} resourceTemplateId - The resource template ID.
|
|
67
|
+
* @property {boolean} expose - Whether to expose the service.
|
|
68
|
+
* @property {boolean} etcHosts - Whether to modify /etc/hosts.
|
|
69
|
+
* @property {string} confServerPath - The configuration server path.
|
|
70
|
+
* @property {string} underpostRoot - The root path of the Underpost installation.
|
|
71
|
+
* @property {string} cronJobs - The cron jobs to run.
|
|
72
|
+
* @property {string} timezone - The timezone to set.
|
|
73
|
+
* @property {boolean} kubeadm - Whether to run in kubeadm mode.
|
|
74
|
+
* @property {boolean} kind - Whether to run in kind mode.
|
|
75
|
+
* @property {boolean} k3s - Whether to run in k3s mode.
|
|
76
|
+
* @property {string} logType - The type of log to generate.
|
|
77
|
+
* @property {string} hosts - The hosts to use.
|
|
78
|
+
* @property {string} deployId - The deployment ID.
|
|
79
|
+
* @property {string} instanceId - The instance ID.
|
|
80
|
+
* @property {string} user - The user to run as.
|
|
81
|
+
* @property {string} pid - The process ID.
|
|
82
|
+
* @property {boolean} disablePrivateConfUpdate - Whether to disable private configuration updates.
|
|
83
|
+
* @memberof UnderpostRun
|
|
84
|
+
*/
|
|
85
|
+
const DEFAULT_OPTION = {
|
|
86
|
+
dev: false,
|
|
87
|
+
podName: '',
|
|
88
|
+
nodeName: '',
|
|
89
|
+
port: 0,
|
|
90
|
+
volumeHostPath: '',
|
|
91
|
+
volumeMountPath: '',
|
|
92
|
+
imageName: '',
|
|
93
|
+
containerName: '',
|
|
94
|
+
namespace: 'default',
|
|
95
|
+
timeoutResponse: '',
|
|
96
|
+
timeoutIdle: '',
|
|
97
|
+
retryCount: '',
|
|
98
|
+
retryPerTryTimeout: '',
|
|
99
|
+
build: false,
|
|
100
|
+
replicas: 1,
|
|
101
|
+
force: false,
|
|
102
|
+
reset: false,
|
|
103
|
+
tls: false,
|
|
104
|
+
cmd: '',
|
|
105
|
+
tty: '',
|
|
106
|
+
stdin: '',
|
|
107
|
+
restartPolicy: '',
|
|
108
|
+
runtimeClassName: '',
|
|
109
|
+
imagePullPolicy: '',
|
|
110
|
+
apiVersion: '',
|
|
111
|
+
claimName: '',
|
|
112
|
+
kindType: '',
|
|
113
|
+
terminal: false,
|
|
114
|
+
devProxyPortOffset: 0,
|
|
115
|
+
hostNetwork: false,
|
|
116
|
+
requestsMemory: '',
|
|
117
|
+
requestsCpu: '',
|
|
118
|
+
limitsMemory: '',
|
|
119
|
+
limitsCpu: '',
|
|
120
|
+
resourceTemplateId: '',
|
|
121
|
+
expose: false,
|
|
122
|
+
etcHosts: false,
|
|
123
|
+
confServerPath: '',
|
|
124
|
+
underpostRoot: '',
|
|
125
|
+
cronJobs: '',
|
|
126
|
+
timezone: '',
|
|
127
|
+
kubeadm: false,
|
|
128
|
+
kind: false,
|
|
129
|
+
k3s: false,
|
|
130
|
+
logType: '',
|
|
131
|
+
hosts: '',
|
|
132
|
+
deployId: '',
|
|
133
|
+
instanceId: '',
|
|
134
|
+
user: '',
|
|
135
|
+
pid: '',
|
|
136
|
+
disablePrivateConfUpdate: false,
|
|
137
|
+
};
|
|
138
|
+
|
|
31
139
|
/**
|
|
32
140
|
* @class UnderpostRun
|
|
33
141
|
* @description Manages the execution of various CLI commands and operations.
|
|
@@ -38,107 +146,6 @@ const logger = loggerFactory(import.meta);
|
|
|
38
146
|
* @memberof UnderpostRun
|
|
39
147
|
*/
|
|
40
148
|
class UnderpostRun {
|
|
41
|
-
/**
|
|
42
|
-
* @static
|
|
43
|
-
* @description Default options for the UnderpostRun class.
|
|
44
|
-
* @type {Object}
|
|
45
|
-
* @property {boolean} dev - Whether to run in development mode.
|
|
46
|
-
* @property {string} podName - The name of the pod to run.
|
|
47
|
-
* @property {string} nodeName - The name of the node to run.
|
|
48
|
-
* @property {number} port - Custom port to use.
|
|
49
|
-
* @property {boolean} etcHosts - Whether to modify /etc/hosts.
|
|
50
|
-
* @property {string} volumeHostPath - The host path for the volume.
|
|
51
|
-
* @property {string} volumeMountPath - The mount path for the volume.
|
|
52
|
-
* @property {string} imageName - The name of the image to run.
|
|
53
|
-
* @property {string} containerName - The name of the container to run.
|
|
54
|
-
* @property {string} namespace - The namespace to run in.
|
|
55
|
-
* @property {boolean} build - Whether to build the image.
|
|
56
|
-
* @property {number} replicas - The number of replicas to run.
|
|
57
|
-
* @property {boolean} force - Whether to force the operation.
|
|
58
|
-
* @property {boolean} reset - Whether to reset the operation.
|
|
59
|
-
* @property {boolean} tls - Whether to use TLS.
|
|
60
|
-
* @property {string} cmd - The command to run in the container.
|
|
61
|
-
* @property {string} tty - The TTY option for the container.
|
|
62
|
-
* @property {string} stdin - The stdin option for the container.
|
|
63
|
-
* @property {string} restartPolicy - The restart policy for the container.
|
|
64
|
-
* @property {string} runtimeClassName - The runtime class name for the container.
|
|
65
|
-
* @property {string} imagePullPolicy - The image pull policy for the container.
|
|
66
|
-
* @property {string} apiVersion - The API version for the container.
|
|
67
|
-
* @property {string} claimName - The claim name for the volume.
|
|
68
|
-
* @property {string} kindType - The kind of resource to create.
|
|
69
|
-
* @property {boolean} terminal - Whether to open a terminal.
|
|
70
|
-
* @property {number} devProxyPortOffset - The port offset for the development proxy.
|
|
71
|
-
* @property {boolean} hostNetwork - Whether to use host networking.
|
|
72
|
-
* @property {string} requestsMemory - The memory request for the container.
|
|
73
|
-
* @property {string} requestsCpu - The CPU request for the container.
|
|
74
|
-
* @property {string} limitsMemory - The memory limit for the container.
|
|
75
|
-
* @property {string} limitsCpu - The CPU limit for the container.
|
|
76
|
-
* @property {string} resourceTemplateId - The resource template ID.
|
|
77
|
-
* @property {boolean} expose - Whether to expose the service.
|
|
78
|
-
* @property {boolean} etcHosts - Whether to modify /etc/hosts.
|
|
79
|
-
* @property {string} confServerPath - The configuration server path.
|
|
80
|
-
* @property {string} underpostRoot - The root path of the Underpost installation.
|
|
81
|
-
* @property {string} cronJobs - The cron jobs to run.
|
|
82
|
-
* @property {string} timezone - The timezone to set.
|
|
83
|
-
* @property {boolean} kubeadm - Whether to run in kubeadm mode.
|
|
84
|
-
* @property {boolean} kind - Whether to run in kind mode.
|
|
85
|
-
* @property {boolean} k3s - Whether to run in k3s mode.
|
|
86
|
-
* @property {string} logType - The type of log to generate.
|
|
87
|
-
* @property {string} hosts - The hosts to use.
|
|
88
|
-
* @property {string} deployId - The deployment ID.
|
|
89
|
-
* @property {string} instanceId - The instance ID.
|
|
90
|
-
* @property {string} user - The user to run as.
|
|
91
|
-
* @property {string} pid - The process ID.
|
|
92
|
-
* @memberof UnderpostRun
|
|
93
|
-
*/
|
|
94
|
-
static DEFAULT_OPTION = {
|
|
95
|
-
dev: false,
|
|
96
|
-
podName: '',
|
|
97
|
-
nodeName: '',
|
|
98
|
-
port: 0,
|
|
99
|
-
volumeHostPath: '',
|
|
100
|
-
volumeMountPath: '',
|
|
101
|
-
imageName: '',
|
|
102
|
-
containerName: '',
|
|
103
|
-
namespace: 'default',
|
|
104
|
-
build: false,
|
|
105
|
-
replicas: 1,
|
|
106
|
-
force: false,
|
|
107
|
-
reset: false,
|
|
108
|
-
tls: false,
|
|
109
|
-
cmd: '',
|
|
110
|
-
tty: '',
|
|
111
|
-
stdin: '',
|
|
112
|
-
restartPolicy: '',
|
|
113
|
-
runtimeClassName: '',
|
|
114
|
-
imagePullPolicy: '',
|
|
115
|
-
apiVersion: '',
|
|
116
|
-
claimName: '',
|
|
117
|
-
kindType: '',
|
|
118
|
-
terminal: false,
|
|
119
|
-
devProxyPortOffset: 0,
|
|
120
|
-
hostNetwork: false,
|
|
121
|
-
requestsMemory: '',
|
|
122
|
-
requestsCpu: '',
|
|
123
|
-
limitsMemory: '',
|
|
124
|
-
limitsCpu: '',
|
|
125
|
-
resourceTemplateId: '',
|
|
126
|
-
expose: false,
|
|
127
|
-
etcHosts: false,
|
|
128
|
-
confServerPath: '',
|
|
129
|
-
underpostRoot: '',
|
|
130
|
-
cronJobs: '',
|
|
131
|
-
timezone: '',
|
|
132
|
-
kubeadm: false,
|
|
133
|
-
kind: false,
|
|
134
|
-
k3s: false,
|
|
135
|
-
logType: '',
|
|
136
|
-
hosts: '',
|
|
137
|
-
deployId: '',
|
|
138
|
-
instanceId: '',
|
|
139
|
-
user: '',
|
|
140
|
-
pid: '',
|
|
141
|
-
};
|
|
142
149
|
/**
|
|
143
150
|
* @static
|
|
144
151
|
* @description Collection of runners for executing specific commands.
|
|
@@ -153,7 +160,7 @@ class UnderpostRun {
|
|
|
153
160
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
154
161
|
* @memberof UnderpostRun
|
|
155
162
|
*/
|
|
156
|
-
'dev-cluster': (path, options =
|
|
163
|
+
'dev-cluster': (path, options = DEFAULT_OPTION) => {
|
|
157
164
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
158
165
|
const mongoHosts = ['mongodb-0.mongodb-service'];
|
|
159
166
|
if (!options.expose) {
|
|
@@ -172,7 +179,7 @@ class UnderpostRun {
|
|
|
172
179
|
// Detect MongoDB primary pod using centralized method
|
|
173
180
|
let primaryMongoHost = 'mongodb-0.mongodb-service';
|
|
174
181
|
try {
|
|
175
|
-
const primaryPodName =
|
|
182
|
+
const primaryPodName = Underpost.db.getMongoPrimaryPodName({
|
|
176
183
|
namespace: options.namespace,
|
|
177
184
|
podName: 'mongodb-0',
|
|
178
185
|
});
|
|
@@ -189,7 +196,7 @@ class UnderpostRun {
|
|
|
189
196
|
});
|
|
190
197
|
}
|
|
191
198
|
|
|
192
|
-
const hostListenResult =
|
|
199
|
+
const hostListenResult = Underpost.deploy.etcHostFactory([primaryMongoHost]);
|
|
193
200
|
logger.info(hostListenResult.renderHosts);
|
|
194
201
|
}
|
|
195
202
|
},
|
|
@@ -201,7 +208,7 @@ class UnderpostRun {
|
|
|
201
208
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
202
209
|
* @memberof UnderpostRun
|
|
203
210
|
*/
|
|
204
|
-
metadata: async (path, options =
|
|
211
|
+
metadata: async (path, options = DEFAULT_OPTION) => {
|
|
205
212
|
const ports = '6379,27017';
|
|
206
213
|
shellExec(`node bin run kill '${ports}'`);
|
|
207
214
|
shellExec(`node bin run dev-cluster --dev --expose --namespace ${options.namespace}`, { async: true });
|
|
@@ -219,7 +226,7 @@ class UnderpostRun {
|
|
|
219
226
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
220
227
|
* @memberof UnderpostRun
|
|
221
228
|
*/
|
|
222
|
-
'svc-ls': (path, options =
|
|
229
|
+
'svc-ls': (path, options = DEFAULT_OPTION) => {
|
|
223
230
|
const log = shellExec(`systemctl list-units --type=service${path ? ` | grep ${path}` : ''}`, {
|
|
224
231
|
silent: true,
|
|
225
232
|
stdout: true,
|
|
@@ -239,7 +246,7 @@ class UnderpostRun {
|
|
|
239
246
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
240
247
|
* @memberof UnderpostRun
|
|
241
248
|
*/
|
|
242
|
-
'svc-rm': (path, options =
|
|
249
|
+
'svc-rm': (path, options = DEFAULT_OPTION) => {
|
|
243
250
|
shellExec(`sudo systemctl stop ${path}`);
|
|
244
251
|
shellExec(`sudo systemctl disable --now ${path}`);
|
|
245
252
|
shellExec(`sudo dnf remove -y ${path}*`);
|
|
@@ -248,17 +255,25 @@ class UnderpostRun {
|
|
|
248
255
|
},
|
|
249
256
|
|
|
250
257
|
/**
|
|
251
|
-
* @method ssh-
|
|
252
|
-
* @description
|
|
258
|
+
* @method ssh-deploy-info
|
|
259
|
+
* @description Retrieves deployment status and pod information from a remote server via SSH.
|
|
253
260
|
* @param {string} path - The input value, identifier, or path for the operation.
|
|
254
261
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
255
262
|
* @memberof UnderpostRun
|
|
256
263
|
*/
|
|
257
|
-
'ssh-
|
|
258
|
-
const
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
264
|
+
'ssh-deploy-info': async (path = '', options = DEFAULT_OPTION) => {
|
|
265
|
+
const env = options.dev ? 'development' : 'production';
|
|
266
|
+
await Underpost.ssh.sshRemoteRunner(
|
|
267
|
+
`node bin deploy ${path ? path : 'dd'} ${env} --status && kubectl get pods -A`,
|
|
268
|
+
{
|
|
269
|
+
deployId: options.deployId,
|
|
270
|
+
user: options.user,
|
|
271
|
+
dev: options.dev,
|
|
272
|
+
remote: true,
|
|
273
|
+
useSudo: true,
|
|
274
|
+
cd: '/home/dd/engine',
|
|
275
|
+
},
|
|
276
|
+
);
|
|
262
277
|
},
|
|
263
278
|
|
|
264
279
|
/**
|
|
@@ -268,7 +283,7 @@ class UnderpostRun {
|
|
|
268
283
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
269
284
|
* @memberof UnderpostRun
|
|
270
285
|
*/
|
|
271
|
-
'dev-hosts-expose': (path, options =
|
|
286
|
+
'dev-hosts-expose': (path, options = DEFAULT_OPTION) => {
|
|
272
287
|
shellExec(
|
|
273
288
|
`node bin deploy ${path} development --disable-update-deployment --disable-update-proxy --kubeadm --etc-hosts`,
|
|
274
289
|
);
|
|
@@ -281,7 +296,7 @@ class UnderpostRun {
|
|
|
281
296
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
282
297
|
* @memberof UnderpostRun
|
|
283
298
|
*/
|
|
284
|
-
'dev-hosts-restore': (path, options =
|
|
299
|
+
'dev-hosts-restore': (path, options = DEFAULT_OPTION) => {
|
|
285
300
|
shellExec(`node bin deploy --restore-hosts`);
|
|
286
301
|
},
|
|
287
302
|
|
|
@@ -292,7 +307,7 @@ class UnderpostRun {
|
|
|
292
307
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
293
308
|
* @memberof UnderpostRun
|
|
294
309
|
*/
|
|
295
|
-
'cluster-build': (path, options =
|
|
310
|
+
'cluster-build': (path, options = DEFAULT_OPTION) => {
|
|
296
311
|
const nodeOptions = options.nodeName ? ` --node-name ${options.nodeName}` : '';
|
|
297
312
|
shellExec(`node bin run clean`);
|
|
298
313
|
shellExec(`node bin run --dev sync-replica template-deploy${nodeOptions}`);
|
|
@@ -312,16 +327,20 @@ class UnderpostRun {
|
|
|
312
327
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
313
328
|
* @memberof UnderpostRun
|
|
314
329
|
*/
|
|
315
|
-
'template-deploy': (path = '', options =
|
|
330
|
+
'template-deploy': (path = '', options = DEFAULT_OPTION) => {
|
|
316
331
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
317
332
|
shellExec(`${baseCommand} run clean`);
|
|
318
333
|
shellExec(
|
|
319
|
-
`${baseCommand} push ./engine-private ${options.force ? '-f ' : ''}${
|
|
334
|
+
`${baseCommand} push ./engine-private ${options.force ? '-f ' : ''}${
|
|
335
|
+
process.env.GITHUB_USERNAME
|
|
336
|
+
}/engine-private`,
|
|
320
337
|
);
|
|
321
338
|
shellCd('/home/dd/engine');
|
|
322
339
|
shellExec(`git reset`);
|
|
323
340
|
shellExec(
|
|
324
|
-
`${baseCommand} cmt . --empty ci package-pwa-microservices-template${
|
|
341
|
+
`${baseCommand} cmt . --empty ci package-pwa-microservices-template${
|
|
342
|
+
path.startsWith('sync') ? `-${path}` : ''
|
|
343
|
+
}`,
|
|
325
344
|
);
|
|
326
345
|
shellExec(`${baseCommand} push . ${options.force ? '-f ' : ''}${process.env.GITHUB_USERNAME}/engine`);
|
|
327
346
|
},
|
|
@@ -333,10 +352,12 @@ class UnderpostRun {
|
|
|
333
352
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
334
353
|
* @memberof UnderpostRun
|
|
335
354
|
*/
|
|
336
|
-
'template-deploy-image': (path, options =
|
|
355
|
+
'template-deploy-image': (path, options = DEFAULT_OPTION) => {
|
|
337
356
|
// const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
338
357
|
shellExec(
|
|
339
|
-
`cd /home/dd/engine && git reset && underpost cmt . --empty ci docker-image 'underpost-engine:${
|
|
358
|
+
`cd /home/dd/engine && git reset && underpost cmt . --empty ci docker-image 'underpost-engine:${
|
|
359
|
+
Underpost.version
|
|
360
|
+
}' && underpost push . ${options.force ? '-f ' : ''}${process.env.GITHUB_USERNAME}/engine`,
|
|
340
361
|
);
|
|
341
362
|
},
|
|
342
363
|
/**
|
|
@@ -346,7 +367,7 @@ class UnderpostRun {
|
|
|
346
367
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
347
368
|
* @memberof UnderpostRun
|
|
348
369
|
*/
|
|
349
|
-
clean: (path = '', options =
|
|
370
|
+
clean: (path = '', options = DEFAULT_OPTION) => {
|
|
350
371
|
Underpost.repo.clean({ paths: path ? path.split(',') : ['/home/dd/engine', '/home/dd/engine/engine-private'] });
|
|
351
372
|
},
|
|
352
373
|
/**
|
|
@@ -356,7 +377,7 @@ class UnderpostRun {
|
|
|
356
377
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
357
378
|
* @memberof UnderpostRun
|
|
358
379
|
*/
|
|
359
|
-
pull: (path, options =
|
|
380
|
+
pull: (path, options = DEFAULT_OPTION) => {
|
|
360
381
|
if (!fs.existsSync(`/home/dd`) || !fs.existsSync(`/home/dd/engine`)) {
|
|
361
382
|
fs.mkdirSync(`/home/dd`, { recursive: true });
|
|
362
383
|
shellExec(`cd /home/dd && underpost clone ${process.env.GITHUB_USERNAME}/engine`, {
|
|
@@ -387,7 +408,7 @@ class UnderpostRun {
|
|
|
387
408
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
388
409
|
* @memberof UnderpostRun
|
|
389
410
|
*/
|
|
390
|
-
'release-deploy': (path, options =
|
|
411
|
+
'release-deploy': (path, options = DEFAULT_OPTION) => {
|
|
391
412
|
actionInitLog();
|
|
392
413
|
shellExec(`underpost --version`);
|
|
393
414
|
shellCd(`/home/dd/engine`);
|
|
@@ -403,7 +424,7 @@ class UnderpostRun {
|
|
|
403
424
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
404
425
|
* @memberof UnderpostRun
|
|
405
426
|
*/
|
|
406
|
-
'ssh-deploy': (path, options =
|
|
427
|
+
'ssh-deploy': (path, options = DEFAULT_OPTION) => {
|
|
407
428
|
actionInitLog();
|
|
408
429
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
409
430
|
shellCd('/home/dd/engine');
|
|
@@ -419,7 +440,7 @@ class UnderpostRun {
|
|
|
419
440
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
420
441
|
* @memberof UnderpostRun
|
|
421
442
|
*/
|
|
422
|
-
ide: (path, options =
|
|
443
|
+
ide: (path, options = DEFAULT_OPTION) => {
|
|
423
444
|
const { underpostRoot } = options;
|
|
424
445
|
if (path === 'install') {
|
|
425
446
|
shellExec(`sudo curl -f https://zed.dev/install.sh | sh`);
|
|
@@ -429,6 +450,16 @@ class UnderpostRun {
|
|
|
429
450
|
shellExec(`sudo dnf install -y sublime-text`);
|
|
430
451
|
} else shellExec(`node ${underpostRoot}/bin/zed ${path}`);
|
|
431
452
|
},
|
|
453
|
+
/**
|
|
454
|
+
* @method crypto-policy
|
|
455
|
+
* @description Sets the system's crypto policies to `DEFAULT:SHA1` using `update-crypto-policies` command.
|
|
456
|
+
* @param {string} path - The input value, identifier, or path for the operation.
|
|
457
|
+
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
458
|
+
* @memberof UnderpostRun
|
|
459
|
+
*/
|
|
460
|
+
'crypto-policy': (path, options = DEFAULT_OPTION) => {
|
|
461
|
+
shellExec(`sudo update-crypto-policies --set DEFAULT:SHA1`);
|
|
462
|
+
},
|
|
432
463
|
/**
|
|
433
464
|
* @method sync
|
|
434
465
|
* @description Cleans up, and then runs a deployment synchronization command (`underpost deploy --kubeadm --build-manifest --sync...`) using parameters parsed from `path` (deployId, replicas, versions, image, node).
|
|
@@ -436,7 +467,7 @@ class UnderpostRun {
|
|
|
436
467
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
437
468
|
* @memberof UnderpostRun
|
|
438
469
|
*/
|
|
439
|
-
sync: async (path, options =
|
|
470
|
+
sync: async (path, options = DEFAULT_OPTION) => {
|
|
440
471
|
// Dev usage: node bin run --dev --build sync dd-default
|
|
441
472
|
const env = options.dev ? 'development' : 'production';
|
|
442
473
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
@@ -456,42 +487,45 @@ class UnderpostRun {
|
|
|
456
487
|
node = node ? node : defaultPath[4];
|
|
457
488
|
shellExec(`${baseCommand} cluster --ns-use ${options.namespace}`);
|
|
458
489
|
if (isDeployRunnerContext(path, options)) {
|
|
459
|
-
|
|
460
|
-
|
|
490
|
+
if (!options.disablePrivateConfUpdate) {
|
|
491
|
+
const { validVersion } = Underpost.repo.privateConfUpdate(deployId);
|
|
492
|
+
if (!validVersion) throw new Error('Version mismatch');
|
|
493
|
+
}
|
|
461
494
|
if (options.timezone !== 'none') shellExec(`${baseCommand} run${baseClusterCommand} tz`);
|
|
462
495
|
if (options.cronJobs !== 'none') shellExec(`${baseCommand} run${baseClusterCommand} cron`);
|
|
463
496
|
}
|
|
464
497
|
|
|
465
498
|
const currentTraffic = isDeployRunnerContext(path, options)
|
|
466
|
-
?
|
|
499
|
+
? Underpost.deploy.getCurrentTraffic(deployId, { namespace: options.namespace })
|
|
467
500
|
: '';
|
|
468
501
|
let targetTraffic = currentTraffic ? (currentTraffic === 'blue' ? 'green' : 'blue') : 'green';
|
|
469
|
-
if (targetTraffic) versions = targetTraffic;
|
|
502
|
+
if (targetTraffic) versions = versions ? versions : targetTraffic;
|
|
503
|
+
|
|
504
|
+
const timeoutFlags = Underpost.deploy.timeoutFlagsFactory(options);
|
|
505
|
+
const cmdString = options.cmd
|
|
506
|
+
? ' --cmd ' + (options.cmd.find((c) => c.match('"')) ? '"' + options.cmd + '"' : "'" + options.cmd + "'")
|
|
507
|
+
: '';
|
|
470
508
|
|
|
471
509
|
shellExec(
|
|
472
|
-
`${baseCommand} deploy --kubeadm --build-manifest --sync --info-router --replicas ${
|
|
473
|
-
|
|
474
|
-
}
|
|
510
|
+
`${baseCommand} deploy --kubeadm --build-manifest --sync --info-router --replicas ${replicas} --node ${node}${
|
|
511
|
+
image ? ` --image ${image}` : ''
|
|
512
|
+
}${versions ? ` --versions ${versions}` : ''}${
|
|
513
|
+
options.namespace ? ` --namespace ${options.namespace}` : ''
|
|
514
|
+
}${timeoutFlags}${cmdString} dd ${env}`,
|
|
475
515
|
);
|
|
476
516
|
|
|
477
517
|
if (isDeployRunnerContext(path, options)) {
|
|
478
|
-
const cmdString = options.cmd
|
|
479
|
-
? ` --cmd ${options.cmd.find((c) => c.match('"')) ? `"${options.cmd}"` : `'${options.cmd}'`}`
|
|
480
|
-
: '';
|
|
481
518
|
shellExec(
|
|
482
|
-
`${baseCommand} deploy --kubeadm${cmdString} --replicas ${
|
|
483
|
-
|
|
484
|
-
}
|
|
519
|
+
`${baseCommand} deploy --kubeadm${cmdString} --replicas ${replicas} --disable-update-proxy ${deployId} ${env} --versions ${versions}${
|
|
520
|
+
options.namespace ? ` --namespace ${options.namespace}` : ''
|
|
521
|
+
}${timeoutFlags}`,
|
|
485
522
|
);
|
|
486
523
|
if (!targetTraffic)
|
|
487
|
-
targetTraffic =
|
|
488
|
-
await
|
|
489
|
-
|
|
524
|
+
targetTraffic = Underpost.deploy.getCurrentTraffic(deployId, { namespace: options.namespace });
|
|
525
|
+
await Underpost.deploy.monitorReadyRunner(deployId, env, targetTraffic, [], options.namespace, 'underpost');
|
|
526
|
+
Underpost.deploy.switchTraffic(deployId, env, targetTraffic, replicas, options.namespace, options);
|
|
490
527
|
} else
|
|
491
|
-
logger.info(
|
|
492
|
-
'current traffic',
|
|
493
|
-
UnderpostDeploy.API.getCurrentTraffic(deployId, { namespace: options.namespace }),
|
|
494
|
-
);
|
|
528
|
+
logger.info('current traffic', Underpost.deploy.getCurrentTraffic(deployId, { namespace: options.namespace }));
|
|
495
529
|
},
|
|
496
530
|
|
|
497
531
|
/**
|
|
@@ -501,8 +535,8 @@ class UnderpostRun {
|
|
|
501
535
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
502
536
|
* @memberof UnderpostRun
|
|
503
537
|
*/
|
|
504
|
-
stop: async (path = '', options =
|
|
505
|
-
let currentTraffic =
|
|
538
|
+
stop: async (path = '', options = DEFAULT_OPTION) => {
|
|
539
|
+
let currentTraffic = Underpost.deploy.getCurrentTraffic(options.deployId, {
|
|
506
540
|
namespace: options.namespace,
|
|
507
541
|
hostTest: options.hosts,
|
|
508
542
|
});
|
|
@@ -510,7 +544,9 @@ class UnderpostRun {
|
|
|
510
544
|
|
|
511
545
|
if (!path.match('current')) currentTraffic === 'blue' ? (currentTraffic = 'green') : (currentTraffic = 'blue');
|
|
512
546
|
const [_deployId] = path.split(',');
|
|
513
|
-
const deploymentId = `${_deployId ? _deployId : options.deployId}${
|
|
547
|
+
const deploymentId = `${_deployId ? _deployId : options.deployId}${
|
|
548
|
+
options.instanceId ? `-${options.instanceId}` : ''
|
|
549
|
+
}-${env}-${currentTraffic}`;
|
|
514
550
|
|
|
515
551
|
shellExec(`kubectl delete deployment ${deploymentId} -n ${options.namespace}`);
|
|
516
552
|
shellExec(`kubectl delete svc ${deploymentId}-service -n ${options.namespace}`);
|
|
@@ -523,30 +559,122 @@ class UnderpostRun {
|
|
|
523
559
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
524
560
|
* @memberof UnderpostRun
|
|
525
561
|
*/
|
|
526
|
-
'ssh-deploy-stop': async (path, options =
|
|
527
|
-
const env = options.dev ? 'development' : 'production';
|
|
562
|
+
'ssh-deploy-stop': async (path, options = DEFAULT_OPTION) => {
|
|
528
563
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
529
564
|
const baseClusterCommand = options.dev ? ' --dev' : '';
|
|
530
|
-
await UnderpostSSH.API.setDefautlSshCredentials(options);
|
|
531
|
-
shellExec(`#!/usr/bin/env bash
|
|
532
|
-
set -euo pipefail
|
|
533
565
|
|
|
534
|
-
|
|
535
|
-
REMOTE_HOST=$(node bin config get --plain DEFAULT_SSH_HOST)
|
|
536
|
-
REMOTE_PORT=$(node bin config get --plain DEFAULT_SSH_PORT)
|
|
537
|
-
SSH_KEY=$(node bin config get --plain DEFAULT_SSH_KEY_PATH)
|
|
538
|
-
|
|
539
|
-
chmod 600 "$SSH_KEY"
|
|
540
|
-
|
|
541
|
-
ssh -i "$SSH_KEY" -o BatchMode=yes "$REMOTE_USER@$REMOTE_HOST" -p $REMOTE_PORT sh <<EOF
|
|
542
|
-
cd /home/dd/engine
|
|
543
|
-
sudo -n -- /bin/bash -lc "${[
|
|
566
|
+
const remoteCommand = [
|
|
544
567
|
`${baseCommand} run${baseClusterCommand} stop${path ? ` ${path}` : ''}`,
|
|
545
568
|
` --deploy-id ${options.deployId}${options.instanceId ? ` --instance-id ${options.instanceId}` : ''}`,
|
|
546
569
|
` --namespace ${options.namespace}${options.hosts ? ` --hosts ${options.hosts}` : ''}`,
|
|
547
|
-
].join('')
|
|
548
|
-
|
|
549
|
-
|
|
570
|
+
].join('');
|
|
571
|
+
|
|
572
|
+
await Underpost.ssh.sshRemoteRunner(remoteCommand, {
|
|
573
|
+
deployId: options.deployId,
|
|
574
|
+
user: options.user,
|
|
575
|
+
dev: options.dev,
|
|
576
|
+
remote: true,
|
|
577
|
+
useSudo: true,
|
|
578
|
+
cd: '/home/dd/engine',
|
|
579
|
+
});
|
|
580
|
+
},
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* @method ssh-deploy-db-rollback
|
|
584
|
+
* @description Performs a database rollback on remote deployment via SSH.
|
|
585
|
+
* @param {string} path - Comma-separated deployId and optional number of commits to reset (format: "deployId,nCommits")
|
|
586
|
+
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
587
|
+
* @param {string} options.deployId - The deployment identifier
|
|
588
|
+
* @param {string} options.user - The SSH user for credential lookup
|
|
589
|
+
* @param {boolean} options.dev - Development mode flag
|
|
590
|
+
* @memberof UnderpostRun
|
|
591
|
+
*/
|
|
592
|
+
'ssh-deploy-db-rollback': async (path = '', options = DEFAULT_OPTION) => {
|
|
593
|
+
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
594
|
+
let [deployId, nCommitsReset] = path.split(',');
|
|
595
|
+
if (!nCommitsReset) nCommitsReset = 1;
|
|
596
|
+
|
|
597
|
+
const remoteCommand = `${baseCommand} db ${deployId} --git --kubeadm --primary-pod --force-clone --macro-rollback-export ${nCommitsReset}${options.namespace ? ` --ns ${options.namespace}` : ''}`;
|
|
598
|
+
|
|
599
|
+
await Underpost.ssh.sshRemoteRunner(remoteCommand, {
|
|
600
|
+
deployId: options.deployId,
|
|
601
|
+
user: options.user,
|
|
602
|
+
dev: options.dev,
|
|
603
|
+
remote: true,
|
|
604
|
+
useSudo: true,
|
|
605
|
+
cd: '/home/dd/engine',
|
|
606
|
+
});
|
|
607
|
+
},
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* @method ssh-deploy-db
|
|
611
|
+
* @description Imports/restores a database on remote deployment via SSH.
|
|
612
|
+
* @param {string} path - The deployment ID for database import
|
|
613
|
+
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
614
|
+
* @param {string} options.deployId - The deployment identifier
|
|
615
|
+
* @param {string} options.user - The SSH user for credential lookup
|
|
616
|
+
* @param {boolean} options.dev - Development mode flag
|
|
617
|
+
* @memberof UnderpostRun
|
|
618
|
+
*/
|
|
619
|
+
'ssh-deploy-db': async (path, options = DEFAULT_OPTION) => {
|
|
620
|
+
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
621
|
+
|
|
622
|
+
const remoteCommand = `${baseCommand} db ${path} --import --drop --preserveUUID --git --kubeadm --primary-pod --force-clone${options.namespace ? ` --ns ${options.namespace}` : ''}`;
|
|
623
|
+
|
|
624
|
+
await Underpost.ssh.sshRemoteRunner(remoteCommand, {
|
|
625
|
+
deployId: options.deployId,
|
|
626
|
+
user: options.user,
|
|
627
|
+
dev: options.dev,
|
|
628
|
+
remote: true,
|
|
629
|
+
useSudo: true,
|
|
630
|
+
cd: '/home/dd/engine',
|
|
631
|
+
});
|
|
632
|
+
},
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* @method ssh-deploy-db-status
|
|
636
|
+
* @description Retrieves database status/stats for a deployment (or all deployments from dd.router) via SSH.
|
|
637
|
+
* @param {string} path - Comma-separated deployId(s) or 'dd' to use the dd.router list.
|
|
638
|
+
* @param {Object} options - Runner options (uses options.deployId for SSH host lookup).
|
|
639
|
+
* @param {string} options.deployId - Deployment identifier used for SSH config lookup.
|
|
640
|
+
* @param {string} options.user - SSH user for credential lookup.
|
|
641
|
+
* @param {boolean} options.dev - Development mode flag.
|
|
642
|
+
* @param {string} [options.namespace] - Kubernetes namespace to pass to the db check.
|
|
643
|
+
* @memberof UnderpostRun
|
|
644
|
+
*/
|
|
645
|
+
'ssh-deploy-db-status': async (path = '', options = DEFAULT_OPTION) => {
|
|
646
|
+
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
647
|
+
|
|
648
|
+
let deployList = [];
|
|
649
|
+
if (!path || path === 'dd') {
|
|
650
|
+
if (!fs.existsSync('./engine-private/deploy/dd.router')) {
|
|
651
|
+
logger.warn('dd.router not found; nothing to run');
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
deployList = fs
|
|
655
|
+
.readFileSync('./engine-private/deploy/dd.router', 'utf8')
|
|
656
|
+
.split(',')
|
|
657
|
+
.map((d) => d.trim())
|
|
658
|
+
.filter(Boolean);
|
|
659
|
+
} else {
|
|
660
|
+
deployList = path
|
|
661
|
+
.split(',')
|
|
662
|
+
.map((d) => d.trim())
|
|
663
|
+
.filter(Boolean);
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
for (const deployId of deployList) {
|
|
667
|
+
const remoteCommand = `${baseCommand} db ${deployId} --stats --kubeadm --primary-pod${options.namespace ? ` --ns ${options.namespace}` : ''}`;
|
|
668
|
+
|
|
669
|
+
await Underpost.ssh.sshRemoteRunner(remoteCommand, {
|
|
670
|
+
deployId: options.deployId,
|
|
671
|
+
user: options.user,
|
|
672
|
+
dev: options.dev,
|
|
673
|
+
remote: true,
|
|
674
|
+
useSudo: true,
|
|
675
|
+
cd: '/home/dd/engine',
|
|
676
|
+
});
|
|
677
|
+
}
|
|
550
678
|
},
|
|
551
679
|
|
|
552
680
|
/**
|
|
@@ -556,14 +684,14 @@ EOF
|
|
|
556
684
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
557
685
|
* @memberof UnderpostRun
|
|
558
686
|
*/
|
|
559
|
-
tz: (path, options =
|
|
687
|
+
tz: (path, options = DEFAULT_OPTION) => {
|
|
560
688
|
const tz =
|
|
561
689
|
options.timezone && options.timezone !== 'none'
|
|
562
690
|
? options.timezone
|
|
563
691
|
: path
|
|
564
692
|
? path
|
|
565
|
-
:
|
|
566
|
-
?
|
|
693
|
+
: Underpost.env.get('TIME_ZONE', undefined, { disableLog: true })
|
|
694
|
+
? Underpost.env.get('TIME_ZONE')
|
|
567
695
|
: process.env.TIME_ZONE
|
|
568
696
|
? process.env.TIME_ZONE
|
|
569
697
|
: 'America/New_York';
|
|
@@ -577,7 +705,7 @@ EOF
|
|
|
577
705
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
578
706
|
* @memberof UnderpostRun
|
|
579
707
|
*/
|
|
580
|
-
cron: (path, options =
|
|
708
|
+
cron: (path, options = DEFAULT_OPTION) => {
|
|
581
709
|
const env = options.dev ? 'development' : 'production';
|
|
582
710
|
shellExec(`node bin env ${path ? path : 'dd-cron'} ${env}`);
|
|
583
711
|
shellExec(`npm start`);
|
|
@@ -591,7 +719,7 @@ EOF
|
|
|
591
719
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
592
720
|
* @memberof UnderpostRun
|
|
593
721
|
*/
|
|
594
|
-
'get-proxy': async (path = '', options =
|
|
722
|
+
'get-proxy': async (path = '', options = DEFAULT_OPTION) => {
|
|
595
723
|
console.log(
|
|
596
724
|
shellExec(`kubectl get HTTPProxy -n ${options.namespace} ${path} -o yaml`, {
|
|
597
725
|
silent: true,
|
|
@@ -608,7 +736,7 @@ EOF
|
|
|
608
736
|
);
|
|
609
737
|
},
|
|
610
738
|
|
|
611
|
-
'instance-promote': async (path, options =
|
|
739
|
+
'instance-promote': async (path, options = DEFAULT_OPTION) => {
|
|
612
740
|
const env = options.dev ? 'development' : 'production';
|
|
613
741
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
614
742
|
const baseClusterCommand = options.dev ? ' --dev' : '';
|
|
@@ -630,14 +758,14 @@ EOF
|
|
|
630
758
|
} = instance;
|
|
631
759
|
if (id !== _id) continue;
|
|
632
760
|
const _deployId = `${deployId}-${_id}`;
|
|
633
|
-
const currentTraffic =
|
|
761
|
+
const currentTraffic = Underpost.deploy.getCurrentTraffic(_deployId, {
|
|
634
762
|
hostTest: _host,
|
|
635
763
|
namespace: options.namespace,
|
|
636
764
|
});
|
|
637
765
|
const targetTraffic = currentTraffic ? (currentTraffic === 'blue' ? 'green' : 'blue') : 'blue';
|
|
638
766
|
let proxyYaml =
|
|
639
|
-
|
|
640
|
-
|
|
767
|
+
Underpost.deploy.baseProxyYamlFactory({ host: _host, env: options.tls ? 'production' : env, options }) +
|
|
768
|
+
Underpost.deploy.deploymentYamlServiceFactory({
|
|
641
769
|
path: _path,
|
|
642
770
|
port: _fromPort,
|
|
643
771
|
// serviceId: deployId,
|
|
@@ -648,7 +776,7 @@ EOF
|
|
|
648
776
|
});
|
|
649
777
|
if (options.tls) {
|
|
650
778
|
shellExec(`sudo kubectl delete Certificate ${_host} -n ${options.namespace} --ignore-not-found`);
|
|
651
|
-
proxyYaml +=
|
|
779
|
+
proxyYaml += Underpost.deploy.buildCertManagerCertificate({ ...options, host: _host });
|
|
652
780
|
}
|
|
653
781
|
// console.log(proxyYaml);
|
|
654
782
|
shellExec(`kubectl delete HTTPProxy ${_host} --namespace ${options.namespace} --ignore-not-found`);
|
|
@@ -668,7 +796,7 @@ EOF
|
|
|
668
796
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
669
797
|
* @memberof UnderpostRun
|
|
670
798
|
*/
|
|
671
|
-
instance: async (path = '', options =
|
|
799
|
+
instance: async (path = '', options = DEFAULT_OPTION) => {
|
|
672
800
|
const env = options.dev ? 'development' : 'production';
|
|
673
801
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
674
802
|
const baseClusterCommand = options.dev ? ' --dev' : '';
|
|
@@ -706,20 +834,20 @@ EOF
|
|
|
706
834
|
shellExec(`sudo kind load docker-image ${_image}`);
|
|
707
835
|
}
|
|
708
836
|
|
|
709
|
-
const currentTraffic =
|
|
837
|
+
const currentTraffic = Underpost.deploy.getCurrentTraffic(_deployId, {
|
|
710
838
|
hostTest: _host,
|
|
711
839
|
namespace: options.namespace,
|
|
712
840
|
});
|
|
713
841
|
|
|
714
842
|
const targetTraffic = currentTraffic ? (currentTraffic === 'blue' ? 'green' : 'blue') : 'blue';
|
|
715
843
|
const podId = `${_deployId}-${env}-${targetTraffic}`;
|
|
716
|
-
const ignorePods =
|
|
717
|
-
|
|
844
|
+
const ignorePods = Underpost.deploy.get(podId, 'pods', options.namespace).map((p) => p.NAME);
|
|
845
|
+
Underpost.deploy.configMap(env, options.namespace);
|
|
718
846
|
shellExec(`kubectl delete service ${podId}-service --namespace ${options.namespace} --ignore-not-found`);
|
|
719
847
|
shellExec(`kubectl delete deployment ${podId} --namespace ${options.namespace} --ignore-not-found`);
|
|
720
848
|
for (const _volume of _volumes)
|
|
721
849
|
if (_volume.claimName)
|
|
722
|
-
|
|
850
|
+
Underpost.deploy.deployVolume(_volume, {
|
|
723
851
|
namespace: options.namespace,
|
|
724
852
|
deployId: _deployId,
|
|
725
853
|
env,
|
|
@@ -727,17 +855,19 @@ EOF
|
|
|
727
855
|
nodeName: options.nodeName,
|
|
728
856
|
});
|
|
729
857
|
let deploymentYaml = `---
|
|
730
|
-
${
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
858
|
+
${Underpost.deploy
|
|
859
|
+
.deploymentYamlPartsFactory({
|
|
860
|
+
deployId: _deployId,
|
|
861
|
+
env,
|
|
862
|
+
suffix: targetTraffic,
|
|
863
|
+
resources: Underpost.deploy.resourcesFactory(options),
|
|
864
|
+
replicas,
|
|
865
|
+
image: _image,
|
|
866
|
+
namespace: options.namespace,
|
|
867
|
+
volumes: _volumes,
|
|
868
|
+
cmd: _cmd[env],
|
|
869
|
+
})
|
|
870
|
+
.replace('{{ports}}', buildKindPorts(_fromPort, _toPort))}
|
|
741
871
|
`;
|
|
742
872
|
// console.log(deploymentYaml);
|
|
743
873
|
shellExec(
|
|
@@ -747,7 +877,7 @@ EOF
|
|
|
747
877
|
`,
|
|
748
878
|
{ disableLog: true },
|
|
749
879
|
);
|
|
750
|
-
const { ready, readyPods } = await
|
|
880
|
+
const { ready, readyPods } = await Underpost.deploy.monitorReadyRunner(
|
|
751
881
|
_deployId,
|
|
752
882
|
env,
|
|
753
883
|
targetTraffic,
|
|
@@ -768,20 +898,20 @@ EOF
|
|
|
768
898
|
);
|
|
769
899
|
}
|
|
770
900
|
if (options.etcHosts) {
|
|
771
|
-
const hostListenResult =
|
|
901
|
+
const hostListenResult = Underpost.deploy.etcHostFactory(etcHosts);
|
|
772
902
|
logger.info(hostListenResult.renderHosts);
|
|
773
903
|
}
|
|
774
904
|
},
|
|
775
905
|
|
|
776
906
|
/**
|
|
777
907
|
* @method ls-deployments
|
|
778
|
-
* @description Retrieves and logs a table of Kubernetes deployments using `
|
|
908
|
+
* @description Retrieves and logs a table of Kubernetes deployments using `Underpost.deploy.get`.
|
|
779
909
|
* @param {string} path - The input value, identifier, or path for the operation (used as an optional deployment name filter).
|
|
780
910
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
781
911
|
* @memberof UnderpostRun
|
|
782
912
|
*/
|
|
783
|
-
'ls-deployments': async (path, options =
|
|
784
|
-
console.table(await
|
|
913
|
+
'ls-deployments': async (path, options = DEFAULT_OPTION) => {
|
|
914
|
+
console.table(await Underpost.deploy.get(path, 'deployments', options.namespace));
|
|
785
915
|
},
|
|
786
916
|
|
|
787
917
|
/**
|
|
@@ -791,7 +921,7 @@ EOF
|
|
|
791
921
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
792
922
|
* @memberof UnderpostRun
|
|
793
923
|
*/
|
|
794
|
-
'host-update': async (path, options =
|
|
924
|
+
'host-update': async (path, options = DEFAULT_OPTION) => {
|
|
795
925
|
// const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
796
926
|
shellExec(`chmod +x ${options.underpostRoot}/scripts/rocky-setup.sh`);
|
|
797
927
|
shellExec(`${options.underpostRoot}/scripts/rocky-setup.sh${options.dev ? ' --install-dev' : ``}`);
|
|
@@ -804,14 +934,14 @@ EOF
|
|
|
804
934
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
805
935
|
* @memberof UnderpostRun
|
|
806
936
|
*/
|
|
807
|
-
'dd-container': async (path = '', options =
|
|
937
|
+
'dd-container': async (path = '', options = DEFAULT_OPTION) => {
|
|
808
938
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
809
939
|
const baseClusterCommand = options.dev ? ' --dev' : '';
|
|
810
940
|
const currentImage = options.imageName
|
|
811
941
|
? options.imageName
|
|
812
|
-
:
|
|
813
|
-
(
|
|
814
|
-
|
|
942
|
+
: Underpost.deploy
|
|
943
|
+
.getCurrentLoadedImages(options.nodeName ? options.nodeName : 'kind-worker', false)
|
|
944
|
+
.find((o) => o.IMAGE.match('underpost'));
|
|
815
945
|
const podName = options.podName || `underpost-dev-container`;
|
|
816
946
|
const volumeHostPath = options.claimName || '/home/dd';
|
|
817
947
|
const claimName = options.claimName || `pvc-dd`;
|
|
@@ -851,7 +981,7 @@ EOF
|
|
|
851
981
|
args: [daemonProcess(path ? path : `cd /home/dd/engine && npm install && npm run test`)],
|
|
852
982
|
};
|
|
853
983
|
|
|
854
|
-
await
|
|
984
|
+
await Underpost.run.RUNNERS['deploy-job'](path, payload);
|
|
855
985
|
},
|
|
856
986
|
|
|
857
987
|
/**
|
|
@@ -861,7 +991,7 @@ EOF
|
|
|
861
991
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
862
992
|
* @memberof UnderpostRun
|
|
863
993
|
*/
|
|
864
|
-
'ip-info': (path, options =
|
|
994
|
+
'ip-info': (path, options = DEFAULT_OPTION) => {
|
|
865
995
|
const { underpostRoot } = options;
|
|
866
996
|
shellExec(`chmod +x ${underpostRoot}/scripts/ip-info.sh`);
|
|
867
997
|
shellExec(`${underpostRoot}/scripts/ip-info.sh ${path}`);
|
|
@@ -874,12 +1004,12 @@ EOF
|
|
|
874
1004
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
875
1005
|
* @memberof UnderpostRun
|
|
876
1006
|
*/
|
|
877
|
-
monitor: (path, options =
|
|
1007
|
+
monitor: (path, options = DEFAULT_OPTION) => {
|
|
878
1008
|
const pid = getTerminalPid();
|
|
879
1009
|
logger.info('monitor pid', pid);
|
|
880
1010
|
const checkPath = '/await';
|
|
881
1011
|
const _monitor = async () => {
|
|
882
|
-
const result =
|
|
1012
|
+
const result = Underpost.deploy.existsContainerFile({ podName: path, path: checkPath });
|
|
883
1013
|
logger.info('monitor', result);
|
|
884
1014
|
if (result === true) {
|
|
885
1015
|
switch (path) {
|
|
@@ -916,7 +1046,7 @@ EOF
|
|
|
916
1046
|
const checkPath = `/latent_space_plot.png`;
|
|
917
1047
|
const outsPaths = [];
|
|
918
1048
|
logger.info('monitor', checkPath);
|
|
919
|
-
while (!
|
|
1049
|
+
while (!Underpost.deploy.existsContainerFile({ podName, path: `/home/dd/docs${checkPath}` }))
|
|
920
1050
|
await timer(1000);
|
|
921
1051
|
|
|
922
1052
|
{
|
|
@@ -954,7 +1084,7 @@ EOF
|
|
|
954
1084
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
955
1085
|
* @memberof UnderpostRun
|
|
956
1086
|
*/
|
|
957
|
-
'db-client': async (path, options =
|
|
1087
|
+
'db-client': async (path, options = DEFAULT_OPTION) => {
|
|
958
1088
|
const { underpostRoot } = options;
|
|
959
1089
|
|
|
960
1090
|
const image = 'adminer:4.7.6-standalone';
|
|
@@ -969,7 +1099,7 @@ EOF
|
|
|
969
1099
|
|
|
970
1100
|
shellExec(`kubectl delete deployment adminer -n ${options.namespace} --ignore-not-found`);
|
|
971
1101
|
shellExec(`kubectl apply -k ${underpostRoot}/manifests/deployment/adminer/. -n ${options.namespace}`);
|
|
972
|
-
const successInstance = await
|
|
1102
|
+
const successInstance = await Underpost.test.statusMonitor('adminer', 'Running', 'pods', 1000, 60 * 10);
|
|
973
1103
|
|
|
974
1104
|
if (successInstance) {
|
|
975
1105
|
shellExec(`underpost deploy --expose adminer --namespace ${options.namespace}`);
|
|
@@ -983,16 +1113,16 @@ EOF
|
|
|
983
1113
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
984
1114
|
* @memberof UnderpostRun
|
|
985
1115
|
*/
|
|
986
|
-
'git-conf': (path = '', options =
|
|
987
|
-
const defaultUsername =
|
|
988
|
-
const defaultEmail =
|
|
1116
|
+
'git-conf': (path = '', options = DEFAULT_OPTION) => {
|
|
1117
|
+
const defaultUsername = Underpost.env.get('GITHUB_USERNAME');
|
|
1118
|
+
const defaultEmail = Underpost.env.get('GITHUB_EMAIL');
|
|
989
1119
|
const validPath = path && path.split(',').length;
|
|
990
1120
|
const [username, email] = validPath ? path.split(',') : [defaultUsername, defaultEmail];
|
|
991
1121
|
if (validPath) {
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
1122
|
+
Underpost.env.set('GITHUB_USERNAME', username);
|
|
1123
|
+
Underpost.env.set('GITHUB_EMAIL', email);
|
|
1124
|
+
Underpost.env.get('GITHUB_USERNAME');
|
|
1125
|
+
Underpost.env.get('GITHUB_EMAIL');
|
|
996
1126
|
}
|
|
997
1127
|
shellExec(
|
|
998
1128
|
`git config --global credential.helper "" && ` +
|
|
@@ -1022,20 +1152,27 @@ EOF
|
|
|
1022
1152
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1023
1153
|
* @memberof UnderpostRun
|
|
1024
1154
|
*/
|
|
1025
|
-
promote: async (path, options =
|
|
1155
|
+
promote: async (path, options = DEFAULT_OPTION) => {
|
|
1026
1156
|
let [inputDeployId, inputEnv, inputReplicas] = path.split(',');
|
|
1027
1157
|
if (!inputEnv) inputEnv = 'production';
|
|
1028
1158
|
if (!inputReplicas) inputReplicas = 1;
|
|
1029
1159
|
if (inputDeployId === 'dd') {
|
|
1030
1160
|
for (const deployId of fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8').split(',')) {
|
|
1031
|
-
const currentTraffic =
|
|
1161
|
+
const currentTraffic = Underpost.deploy.getCurrentTraffic(deployId, { namespace: options.namespace });
|
|
1032
1162
|
const targetTraffic = currentTraffic === 'blue' ? 'green' : 'blue';
|
|
1033
|
-
|
|
1163
|
+
Underpost.deploy.switchTraffic(deployId, inputEnv, targetTraffic, inputReplicas, options.namespace, options);
|
|
1034
1164
|
}
|
|
1035
1165
|
} else {
|
|
1036
|
-
const currentTraffic =
|
|
1166
|
+
const currentTraffic = Underpost.deploy.getCurrentTraffic(inputDeployId, { namespace: options.namespace });
|
|
1037
1167
|
const targetTraffic = currentTraffic === 'blue' ? 'green' : 'blue';
|
|
1038
|
-
|
|
1168
|
+
Underpost.deploy.switchTraffic(
|
|
1169
|
+
inputDeployId,
|
|
1170
|
+
inputEnv,
|
|
1171
|
+
targetTraffic,
|
|
1172
|
+
inputReplicas,
|
|
1173
|
+
options.namespace,
|
|
1174
|
+
options,
|
|
1175
|
+
);
|
|
1039
1176
|
}
|
|
1040
1177
|
},
|
|
1041
1178
|
/**
|
|
@@ -1045,7 +1182,7 @@ EOF
|
|
|
1045
1182
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1046
1183
|
* @memberof UnderpostRun
|
|
1047
1184
|
*/
|
|
1048
|
-
metrics: async (path, options =
|
|
1185
|
+
metrics: async (path, options = DEFAULT_OPTION) => {
|
|
1049
1186
|
const deployList = fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8').split(',');
|
|
1050
1187
|
let hosts = [];
|
|
1051
1188
|
for (const deployId of deployList) {
|
|
@@ -1062,7 +1199,7 @@ EOF
|
|
|
1062
1199
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1063
1200
|
* @memberof UnderpostRun
|
|
1064
1201
|
*/
|
|
1065
|
-
cluster: async (path = '', options =
|
|
1202
|
+
cluster: async (path = '', options = DEFAULT_OPTION) => {
|
|
1066
1203
|
const { underpostRoot } = options;
|
|
1067
1204
|
const env = options.dev ? 'development' : 'production';
|
|
1068
1205
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
@@ -1097,7 +1234,9 @@ EOF
|
|
|
1097
1234
|
}
|
|
1098
1235
|
await timer(5000);
|
|
1099
1236
|
for (const deployId of deployList) {
|
|
1100
|
-
shellExec(
|
|
1237
|
+
shellExec(
|
|
1238
|
+
`${baseCommand} db ${deployId} --import --git --drop --preserveUUID --primary-pod${options.namespace ? ` --ns ${options.namespace}` : ''}`,
|
|
1239
|
+
);
|
|
1101
1240
|
}
|
|
1102
1241
|
await timer(5000);
|
|
1103
1242
|
shellExec(`${baseCommand} cluster${baseClusterCommand} --${clusterType} --pull-image --valkey`);
|
|
@@ -1111,7 +1250,7 @@ EOF
|
|
|
1111
1250
|
shellExec(
|
|
1112
1251
|
`${baseCommand} deploy ${deployId} ${env} --${clusterType}${env === 'production' ? ' --cert' : ''}${
|
|
1113
1252
|
env === 'development' ? ' --etc-hosts' : ''
|
|
1114
|
-
}`,
|
|
1253
|
+
}${options.namespace ? ` --namespace ${options.namespace}` : ''}`,
|
|
1115
1254
|
);
|
|
1116
1255
|
}
|
|
1117
1256
|
},
|
|
@@ -1122,20 +1261,20 @@ EOF
|
|
|
1122
1261
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1123
1262
|
* @memberof UnderpostRun
|
|
1124
1263
|
*/
|
|
1125
|
-
deploy: async (path, options =
|
|
1264
|
+
deploy: async (path, options = DEFAULT_OPTION) => {
|
|
1126
1265
|
const deployId = path;
|
|
1127
|
-
const { validVersion } =
|
|
1266
|
+
const { validVersion } = Underpost.repo.privateConfUpdate(deployId);
|
|
1128
1267
|
if (!validVersion) throw new Error('Version mismatch');
|
|
1129
|
-
const currentTraffic =
|
|
1268
|
+
const currentTraffic = Underpost.deploy.getCurrentTraffic(deployId, { namespace: options.namespace });
|
|
1130
1269
|
const targetTraffic = currentTraffic === 'blue' ? 'green' : 'blue';
|
|
1131
|
-
const env = 'production';
|
|
1132
|
-
const ignorePods =
|
|
1133
|
-
(
|
|
1134
|
-
|
|
1270
|
+
const env = options.dev ? 'development' : 'production';
|
|
1271
|
+
const ignorePods = Underpost.deploy
|
|
1272
|
+
.get(`${deployId}-${env}-${targetTraffic}`, 'pods', options.namespace)
|
|
1273
|
+
.map((p) => p.NAME);
|
|
1135
1274
|
|
|
1136
1275
|
shellExec(`sudo kubectl rollout restart deployment/${deployId}-${env}-${targetTraffic} -n ${options.namespace}`);
|
|
1137
1276
|
|
|
1138
|
-
await
|
|
1277
|
+
await Underpost.deploy.monitorReadyRunner(
|
|
1139
1278
|
deployId,
|
|
1140
1279
|
env,
|
|
1141
1280
|
targetTraffic,
|
|
@@ -1144,7 +1283,7 @@ EOF
|
|
|
1144
1283
|
'underpost',
|
|
1145
1284
|
);
|
|
1146
1285
|
|
|
1147
|
-
|
|
1286
|
+
Underpost.deploy.switchTraffic(deployId, env, targetTraffic, options.replicas, options.namespace, options);
|
|
1148
1287
|
},
|
|
1149
1288
|
|
|
1150
1289
|
/**
|
|
@@ -1154,7 +1293,7 @@ EOF
|
|
|
1154
1293
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1155
1294
|
* @memberof UnderpostRun
|
|
1156
1295
|
*/
|
|
1157
|
-
'disk-clean': async (path, options =
|
|
1296
|
+
'disk-clean': async (path, options = DEFAULT_OPTION) => {
|
|
1158
1297
|
const { underpostRoot } = options;
|
|
1159
1298
|
shellExec(`chmod +x ${underpostRoot}/scripts/disk-clean.sh`);
|
|
1160
1299
|
shellExec(`./scripts/disk-clean.sh`);
|
|
@@ -1167,7 +1306,7 @@ EOF
|
|
|
1167
1306
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1168
1307
|
* @memberof UnderpostRun
|
|
1169
1308
|
*/
|
|
1170
|
-
'disk-usage': async (path = '/', options =
|
|
1309
|
+
'disk-usage': async (path = '/', options = DEFAULT_OPTION) => {
|
|
1171
1310
|
if (!path) path = '/';
|
|
1172
1311
|
logger.info('Mount filesystem');
|
|
1173
1312
|
shellExec(`df -h${path === '/' ? '' : ` ${path}`}`);
|
|
@@ -1182,7 +1321,7 @@ EOF
|
|
|
1182
1321
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1183
1322
|
* @memberof UnderpostRun
|
|
1184
1323
|
*/
|
|
1185
|
-
dev: async (path = '', options =
|
|
1324
|
+
dev: async (path = '', options = DEFAULT_OPTION) => {
|
|
1186
1325
|
let [deployId, subConf, host, _path, clientHostPort] = path.split(',');
|
|
1187
1326
|
if (options.confServerPath) {
|
|
1188
1327
|
const confServer = JSON.parse(fs.readFileSync(options.confServerPath, 'utf8'));
|
|
@@ -1216,7 +1355,9 @@ EOF
|
|
|
1216
1355
|
}
|
|
1217
1356
|
shellExec(`node bin run dev-cluster --expose --namespace ${options.namespace}`, { async: true });
|
|
1218
1357
|
{
|
|
1219
|
-
const cmd = `npm run dev-api ${deployId} ${subConf} ${host} ${_path} ${clientHostPort}${
|
|
1358
|
+
const cmd = `npm run dev-api ${deployId} ${subConf} ${host} ${_path} ${clientHostPort}${
|
|
1359
|
+
options.tls ? ' tls' : ''
|
|
1360
|
+
}`;
|
|
1220
1361
|
options.terminal ? openTerminal(cmd) : shellExec(cmd, { async: true });
|
|
1221
1362
|
}
|
|
1222
1363
|
await awaitDeployMonitor(true);
|
|
@@ -1239,7 +1380,7 @@ EOF
|
|
|
1239
1380
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1240
1381
|
* @memberof UnderpostRun
|
|
1241
1382
|
*/
|
|
1242
|
-
service: async (path = '', options =
|
|
1383
|
+
service: async (path = '', options = DEFAULT_OPTION) => {
|
|
1243
1384
|
const env = options.dev ? 'development' : 'production';
|
|
1244
1385
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
1245
1386
|
const baseClusterCommand = options.dev ? ' --dev' : '';
|
|
@@ -1304,25 +1445,49 @@ EOF
|
|
|
1304
1445
|
break;
|
|
1305
1446
|
}
|
|
1306
1447
|
}
|
|
1307
|
-
const success = await
|
|
1448
|
+
const success = await Underpost.test.statusMonitor(podToMonitor);
|
|
1308
1449
|
if (success) {
|
|
1309
|
-
const versions =
|
|
1450
|
+
const versions = Underpost.deploy.getCurrentTraffic(deployId, { namespace: options.namespace }) || 'blue';
|
|
1310
1451
|
if (!node) node = os.hostname();
|
|
1452
|
+
const timeoutFlags = Underpost.deploy.timeoutFlagsFactory(options);
|
|
1311
1453
|
shellExec(
|
|
1312
|
-
`${baseCommand} deploy${options.dev ? '' : ' --kubeadm'}${
|
|
1313
|
-
|
|
1314
|
-
} --
|
|
1454
|
+
`${baseCommand} deploy${options.dev ? '' : ' --kubeadm'}${
|
|
1455
|
+
options.devProxyPortOffset ? ' --disable-deployment-proxy' : ''
|
|
1456
|
+
} --build-manifest --sync --info-router --replicas ${replicas} --node ${node}${
|
|
1457
|
+
image ? ` --image ${image}` : ''
|
|
1458
|
+
}${versions ? ` --versions ${versions}` : ''}${timeoutFlags} dd ${env}`,
|
|
1315
1459
|
);
|
|
1316
1460
|
shellExec(
|
|
1317
|
-
`${baseCommand} deploy${options.dev ? '' : ' --kubeadm'}${
|
|
1461
|
+
`${baseCommand} deploy${options.dev ? '' : ' --kubeadm'}${
|
|
1462
|
+
options.devProxyPortOffset ? ' --disable-deployment-proxy' : ''
|
|
1463
|
+
} --disable-update-deployment ${deployId} ${env} --versions ${versions}`,
|
|
1318
1464
|
);
|
|
1319
1465
|
} else logger.error(`Service pod ${podToMonitor} failed to start in time.`);
|
|
1320
1466
|
if (options.etcHosts === true) {
|
|
1321
|
-
const hostListenResult =
|
|
1467
|
+
const hostListenResult = Underpost.deploy.etcHostFactory([host]);
|
|
1322
1468
|
logger.info(hostListenResult.renderHosts);
|
|
1323
1469
|
}
|
|
1324
1470
|
},
|
|
1325
1471
|
|
|
1472
|
+
/**
|
|
1473
|
+
* @method etc-hosts
|
|
1474
|
+
* @description Generates and logs the contents for the `/etc/hosts` file based on provided hosts or deployment configurations.
|
|
1475
|
+
* @param {string} path - The input value, identifier, or path for the operation (used as a comma-separated list of hosts).
|
|
1476
|
+
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1477
|
+
* @memberof UnderpostRun
|
|
1478
|
+
*/
|
|
1479
|
+
'etc-hosts': async (path = '', options = DEFAULT_OPTION) => {
|
|
1480
|
+
const hosts = path ? path.split(',') : [];
|
|
1481
|
+
if (options.deployId) {
|
|
1482
|
+
const confServer = JSON.parse(
|
|
1483
|
+
fs.readFileSync(`./engine-private/conf/${options.deployId}/conf.server.json`, 'utf8'),
|
|
1484
|
+
);
|
|
1485
|
+
hosts.push(...Object.keys(confServer));
|
|
1486
|
+
}
|
|
1487
|
+
const hostListenResult = Underpost.deploy.etcHostFactory(hosts);
|
|
1488
|
+
logger.info(hostListenResult.renderHosts);
|
|
1489
|
+
},
|
|
1490
|
+
|
|
1326
1491
|
/**
|
|
1327
1492
|
* @method sh
|
|
1328
1493
|
* @description Enables remote control for the Kitty terminal emulator.
|
|
@@ -1330,11 +1495,13 @@ EOF
|
|
|
1330
1495
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1331
1496
|
* @memberof UnderpostRun
|
|
1332
1497
|
*/
|
|
1333
|
-
sh: async (path = '', options =
|
|
1498
|
+
sh: async (path = '', options = DEFAULT_OPTION) => {
|
|
1334
1499
|
let [operator, arg0, arg1] = path.split(',');
|
|
1335
1500
|
if (operator == 'copy') {
|
|
1336
1501
|
shellExec(
|
|
1337
|
-
`kitty @ get-text ${arg0 === 'all' ? '--match all' : '--self'} --extent all${
|
|
1502
|
+
`kitty @ get-text ${arg0 === 'all' ? '--match all' : '--self'} --extent all${
|
|
1503
|
+
arg1 === 'ansi' ? ' --ansi yes' : ''
|
|
1504
|
+
} | kitty +kitten clipboard`,
|
|
1338
1505
|
);
|
|
1339
1506
|
return;
|
|
1340
1507
|
}
|
|
@@ -1348,7 +1515,7 @@ EOF
|
|
|
1348
1515
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1349
1516
|
* @memberof UnderpostRun
|
|
1350
1517
|
*/
|
|
1351
|
-
log: async (path, options =
|
|
1518
|
+
log: async (path, options = DEFAULT_OPTION) => {
|
|
1352
1519
|
const [filePath, keywords, lines] = path.split(',');
|
|
1353
1520
|
let result = shellExec(`grep -i -E ${lines ? `-C ${lines} ` : ''}'${keywords}' ${filePath}`, {
|
|
1354
1521
|
stdout: true,
|
|
@@ -1365,12 +1532,22 @@ EOF
|
|
|
1365
1532
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1366
1533
|
* @memberof UnderpostRun
|
|
1367
1534
|
*/
|
|
1368
|
-
ps: async (path = '', options =
|
|
1369
|
-
const out = shellExec(
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1535
|
+
ps: async (path = '', options = DEFAULT_OPTION) => {
|
|
1536
|
+
const out = shellExec(
|
|
1537
|
+
path.startsWith('top-consumers')
|
|
1538
|
+
? `ps -eo pid,%cpu,%mem,rss,cmd --sort=-%cpu | head -n ${path.split(',')[1] || 15}`
|
|
1539
|
+
: path
|
|
1540
|
+
? `(ps -eo pid,%cpu,%mem,rss,cmd -ww | head -n1; ps -eo pid,%cpu,%mem,rss,cmd -ww | tail -n +2 | grep -F ${path})`
|
|
1541
|
+
: `ps -eo pid,%cpu,%mem,rss,cmd -ww`,
|
|
1542
|
+
{
|
|
1543
|
+
stdout: true,
|
|
1544
|
+
silent: true,
|
|
1545
|
+
},
|
|
1546
|
+
);
|
|
1547
|
+
|
|
1548
|
+
console.log(
|
|
1549
|
+
path ? out.replaceAll(path.split(',')[2] || path, (path.split(',')[2] || path).bgYellow.black.bold) : out,
|
|
1550
|
+
);
|
|
1374
1551
|
},
|
|
1375
1552
|
|
|
1376
1553
|
/**
|
|
@@ -1380,7 +1557,7 @@ EOF
|
|
|
1380
1557
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1381
1558
|
* @memberof UnderpostRun
|
|
1382
1559
|
*/
|
|
1383
|
-
ptls: async (path = '', options =
|
|
1560
|
+
ptls: async (path = '', options = DEFAULT_OPTION) => {
|
|
1384
1561
|
shellExec(`chmod +x ${options.underpostRoot}/scripts/ports-ls.sh`);
|
|
1385
1562
|
shellExec(`${options.underpostRoot}/scripts/ports-ls.sh`);
|
|
1386
1563
|
},
|
|
@@ -1391,7 +1568,7 @@ EOF
|
|
|
1391
1568
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1392
1569
|
* @memberof UnderpostRun
|
|
1393
1570
|
*/
|
|
1394
|
-
'release-cmt': async (path, options =
|
|
1571
|
+
'release-cmt': async (path, options = DEFAULT_OPTION) => {
|
|
1395
1572
|
shellExec(`underpost run pull`);
|
|
1396
1573
|
shellExec(`underpost run secret`);
|
|
1397
1574
|
shellCd(`/home/dd/engine`);
|
|
@@ -1406,7 +1583,7 @@ EOF
|
|
|
1406
1583
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1407
1584
|
* @memberof UnderpostRun
|
|
1408
1585
|
*/
|
|
1409
|
-
'deploy-test': async (path, options =
|
|
1586
|
+
'deploy-test': async (path, options = DEFAULT_OPTION) => {
|
|
1410
1587
|
// Note: use recomendation empty deploy cluster: node bin --dev cluster
|
|
1411
1588
|
const env = options.dev ? 'development' : 'production';
|
|
1412
1589
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
@@ -1431,7 +1608,7 @@ EOF
|
|
|
1431
1608
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1432
1609
|
* @memberof UnderpostRun
|
|
1433
1610
|
*/
|
|
1434
|
-
'sync-replica': async (path, options =
|
|
1611
|
+
'sync-replica': async (path, options = DEFAULT_OPTION) => {
|
|
1435
1612
|
const env = options.dev ? 'development' : 'production';
|
|
1436
1613
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
1437
1614
|
|
|
@@ -1462,10 +1639,10 @@ EOF
|
|
|
1462
1639
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1463
1640
|
* @memberof UnderpostRun
|
|
1464
1641
|
*/
|
|
1465
|
-
'tf-vae-test': async (path, options =
|
|
1642
|
+
'tf-vae-test': async (path, options = DEFAULT_OPTION) => {
|
|
1466
1643
|
const { underpostRoot } = options;
|
|
1467
1644
|
const podName = 'tf-vae-test';
|
|
1468
|
-
await
|
|
1645
|
+
await Underpost.run.CALL('deploy-job', '', {
|
|
1469
1646
|
podName,
|
|
1470
1647
|
// volumeMountPath: '/custom_images',
|
|
1471
1648
|
// volumeHostPath: '/home/dd/engine/src/client/public/cyberia/assets/skin',
|
|
@@ -1503,7 +1680,7 @@ EOF
|
|
|
1503
1680
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1504
1681
|
* @memberof UnderpostRun
|
|
1505
1682
|
*/
|
|
1506
|
-
'spark-template': (path, options =
|
|
1683
|
+
'spark-template': (path, options = DEFAULT_OPTION) => {
|
|
1507
1684
|
const dir = '/home/dd/spark-template';
|
|
1508
1685
|
shellExec(`sudo rm -rf ${dir}`);
|
|
1509
1686
|
shellCd('/home/dd');
|
|
@@ -1530,7 +1707,7 @@ EOF
|
|
|
1530
1707
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1531
1708
|
* @memberof UnderpostRun
|
|
1532
1709
|
*/
|
|
1533
|
-
rmi: (path, options =
|
|
1710
|
+
rmi: (path, options = DEFAULT_OPTION) => {
|
|
1534
1711
|
shellExec(`podman rmi $(podman images -qa) --force`);
|
|
1535
1712
|
},
|
|
1536
1713
|
/**
|
|
@@ -1540,7 +1717,7 @@ EOF
|
|
|
1540
1717
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1541
1718
|
* @memberof UnderpostRun
|
|
1542
1719
|
*/
|
|
1543
|
-
kill: (path = '', options =
|
|
1720
|
+
kill: (path = '', options = DEFAULT_OPTION) => {
|
|
1544
1721
|
if (options.pid) return shellExec(`sudo kill -9 ${options.pid}`);
|
|
1545
1722
|
for (const _path of path.split(',')) {
|
|
1546
1723
|
if (_path.split('+')[1]) {
|
|
@@ -1559,7 +1736,7 @@ EOF
|
|
|
1559
1736
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1560
1737
|
* @memberof UnderpostRun
|
|
1561
1738
|
*/
|
|
1562
|
-
secret: (path, options =
|
|
1739
|
+
secret: (path, options = DEFAULT_OPTION) => {
|
|
1563
1740
|
const secretPath = path ? path : `/home/dd/engine/engine-private/conf/dd-cron/.env.production`;
|
|
1564
1741
|
const command = options.dev
|
|
1565
1742
|
? `node bin secret underpost --create-from-file ${secretPath}`
|
|
@@ -1568,13 +1745,13 @@ EOF
|
|
|
1568
1745
|
},
|
|
1569
1746
|
/**
|
|
1570
1747
|
* @method underpost-config
|
|
1571
|
-
* @description Calls `
|
|
1748
|
+
* @description Calls `Underpost.deploy.configMap` to create a Kubernetes ConfigMap, defaulting to the 'production' environment.
|
|
1572
1749
|
* @param {string} path - The input value, identifier, or path for the operation (used as the optional configuration name/environment).
|
|
1573
1750
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1574
1751
|
* @memberof UnderpostRun
|
|
1575
1752
|
*/
|
|
1576
|
-
'underpost-config': (path = '', options =
|
|
1577
|
-
|
|
1753
|
+
'underpost-config': (path = '', options = DEFAULT_OPTION) => {
|
|
1754
|
+
Underpost.deploy.configMap(path ? path : 'production', options.namespace);
|
|
1578
1755
|
},
|
|
1579
1756
|
/**
|
|
1580
1757
|
* @method gpu-env
|
|
@@ -1583,7 +1760,7 @@ EOF
|
|
|
1583
1760
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1584
1761
|
* @memberof UnderpostRun
|
|
1585
1762
|
*/
|
|
1586
|
-
'gpu-env': (path, options =
|
|
1763
|
+
'gpu-env': (path, options = DEFAULT_OPTION) => {
|
|
1587
1764
|
shellExec(
|
|
1588
1765
|
`node bin cluster --dev --reset && node bin cluster --dev --dedicated-gpu --kubeadm && kubectl get pods --all-namespaces -o wide -w`,
|
|
1589
1766
|
);
|
|
@@ -1595,7 +1772,7 @@ EOF
|
|
|
1595
1772
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1596
1773
|
* @memberof UnderpostRun
|
|
1597
1774
|
*/
|
|
1598
|
-
'tf-gpu-test': (path, options =
|
|
1775
|
+
'tf-gpu-test': (path, options = DEFAULT_OPTION) => {
|
|
1599
1776
|
const { underpostRoot, namespace } = options;
|
|
1600
1777
|
shellExec(`kubectl delete configmap tf-gpu-test-script -n ${namespace} --ignore-not-found`);
|
|
1601
1778
|
shellExec(`kubectl delete pod tf-gpu-test-pod -n ${namespace} --ignore-not-found`);
|
|
@@ -1609,7 +1786,7 @@ EOF
|
|
|
1609
1786
|
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1610
1787
|
* @memberof UnderpostRun
|
|
1611
1788
|
*/
|
|
1612
|
-
'deploy-job': async (path, options =
|
|
1789
|
+
'deploy-job': async (path, options = DEFAULT_OPTION) => {
|
|
1613
1790
|
const podName = options.podName || 'deploy-job';
|
|
1614
1791
|
const volumeName = `${podName}-volume`;
|
|
1615
1792
|
if (typeof options.args === 'string') options.args = options.args.split(',');
|
|
@@ -1646,7 +1823,7 @@ EOF
|
|
|
1646
1823
|
? 'Directory'
|
|
1647
1824
|
: 'File';
|
|
1648
1825
|
|
|
1649
|
-
const envs =
|
|
1826
|
+
const envs = Underpost.env.list();
|
|
1650
1827
|
|
|
1651
1828
|
const cmd = `kubectl apply -f - <<EOF
|
|
1652
1829
|
apiVersion: ${apiVersion}
|
|
@@ -1689,14 +1866,14 @@ ${Object.keys(envs)
|
|
|
1689
1866
|
.join('\n')}`}
|
|
1690
1867
|
${
|
|
1691
1868
|
enableVolumeMount
|
|
1692
|
-
?
|
|
1869
|
+
? Underpost.deploy.volumeFactory([{ volumeMountPath, volumeName, volumeHostPath, volumeType, claimName }]).render
|
|
1693
1870
|
: ''
|
|
1694
1871
|
}
|
|
1695
1872
|
EOF`;
|
|
1696
1873
|
shellExec(`kubectl delete pod ${podName} -n ${namespace} --ignore-not-found`);
|
|
1697
1874
|
console.log(cmd);
|
|
1698
1875
|
shellExec(cmd, { disableLog: true });
|
|
1699
|
-
const successInstance = await
|
|
1876
|
+
const successInstance = await Underpost.test.statusMonitor(podName);
|
|
1700
1877
|
if (successInstance) {
|
|
1701
1878
|
options.on?.init ? await options.on.init() : null;
|
|
1702
1879
|
shellExec(`kubectl logs -f ${podName} -n ${namespace}`);
|
|
@@ -1705,6 +1882,39 @@ EOF`;
|
|
|
1705
1882
|
};
|
|
1706
1883
|
|
|
1707
1884
|
static API = {
|
|
1885
|
+
/**
|
|
1886
|
+
* @method DEFAULT_OPTION
|
|
1887
|
+
* @description The default options for Underpost runners, including development mode, namespace, replicas, and underpost root path.
|
|
1888
|
+
* @memberof UnderpostRun
|
|
1889
|
+
* @static
|
|
1890
|
+
* @returns {Object} The default options object.
|
|
1891
|
+
*/
|
|
1892
|
+
get DEFAULT_OPTION() {
|
|
1893
|
+
return DEFAULT_OPTION;
|
|
1894
|
+
},
|
|
1895
|
+
/**
|
|
1896
|
+
* @method RUNNERS
|
|
1897
|
+
* @description Retrieves the list of available runner IDs from the UnderpostRun class.
|
|
1898
|
+
* @memberof UnderpostRun
|
|
1899
|
+
* @returns {string[]} An array of runner IDs.
|
|
1900
|
+
*/
|
|
1901
|
+
get RUNNERS() {
|
|
1902
|
+
return Object.keys(UnderpostRun.RUNNERS);
|
|
1903
|
+
},
|
|
1904
|
+
|
|
1905
|
+
/**
|
|
1906
|
+
* @method CALL
|
|
1907
|
+
* @description Executes a specified runner function from the UnderpostRun class with the provided path and options.
|
|
1908
|
+
* @param {string} runner - The name of the runner to execute.
|
|
1909
|
+
* @param {string} path - The input value, identifier, or path for the operation.
|
|
1910
|
+
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1911
|
+
* @memberof UnderpostRun
|
|
1912
|
+
* @returns {Promise<any>} The result of the runner execution.
|
|
1913
|
+
*/
|
|
1914
|
+
async CALL(runner = '', path = '', options = DEFAULT_OPTION) {
|
|
1915
|
+
return await UnderpostRun.RUNNERS[runner](path, options);
|
|
1916
|
+
},
|
|
1917
|
+
|
|
1708
1918
|
/**
|
|
1709
1919
|
* @method callback
|
|
1710
1920
|
* @description Initiates the execution of a specified CLI command (runner) with the given input value (`path`) and processed options.
|
|
@@ -1714,7 +1924,7 @@ EOF`;
|
|
|
1714
1924
|
* @memberof UnderpostRun
|
|
1715
1925
|
* @returns {Promise<any>} The result of the callback execution.
|
|
1716
1926
|
*/
|
|
1717
|
-
async callback(runner, path, options =
|
|
1927
|
+
async callback(runner, path, options = DEFAULT_OPTION) {
|
|
1718
1928
|
try {
|
|
1719
1929
|
const npmRoot = getNpmRootPath();
|
|
1720
1930
|
const underpostRoot = options?.dev === true ? '.' : `${npmRoot}/underpost`;
|
|
@@ -1726,8 +1936,8 @@ EOF`;
|
|
|
1726
1936
|
options.replicas = 1;
|
|
1727
1937
|
options.npmRoot = npmRoot;
|
|
1728
1938
|
logger.info('callback', { path, options });
|
|
1729
|
-
if (!(runner
|
|
1730
|
-
const result = await
|
|
1939
|
+
if (!Underpost.run.RUNNERS.includes(runner)) throw new Error(`Runner not found: ${runner}`);
|
|
1940
|
+
const result = await Underpost.run.CALL(runner, path, options);
|
|
1731
1941
|
return result;
|
|
1732
1942
|
} catch (error) {
|
|
1733
1943
|
console.log(error);
|