@underpostnet/underpost 2.98.3 → 2.99.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -3
- package/bin/deploy.js +1 -1
- package/cli.md +109 -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 +162 -60
- package/src/cli/env.js +20 -5
- package/src/cli/fs.js +19 -21
- package/src/cli/index.js +35 -32
- package/src/cli/lxd.js +5 -5
- package/src/cli/monitor.js +66 -88
- package/src/cli/repository.js +7 -6
- package/src/cli/run.js +369 -261
- package/src/cli/secrets.js +3 -3
- package/src/cli/ssh.js +31 -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/src/cli/script.js +0 -85
- package/src/monitor.js +0 -34
package/src/cli/index.js
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import dotenv from 'dotenv';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
|
|
2
4
|
import { Command } from 'commander';
|
|
3
|
-
import Underpost, { UnderpostRootEnv } from '../index.js';
|
|
4
5
|
import { getNpmRootPath, getUnderpostRootPath, loadConf } from '../server/conf.js';
|
|
5
|
-
import fs from 'fs-extra';
|
|
6
6
|
import { commitData } from '../client/components/core/CommonJs.js';
|
|
7
|
-
|
|
8
|
-
import
|
|
9
|
-
import UnderpostRun from './run.js';
|
|
10
|
-
import Dns from '../server/dns.js';
|
|
11
|
-
import UnderpostStatic from './static.js';
|
|
7
|
+
|
|
8
|
+
import Underpost from '../index.js';
|
|
12
9
|
|
|
13
10
|
const underpostRootPath = getUnderpostRootPath();
|
|
11
|
+
|
|
14
12
|
fs.existsSync(`${underpostRootPath}/.env`)
|
|
15
13
|
? dotenv.config({ path: `${underpostRootPath}/.env`, override: true })
|
|
16
14
|
: dotenv.config();
|
|
@@ -108,9 +106,8 @@ program
|
|
|
108
106
|
if (fs.existsSync(`./engine-private/conf/${deployId}/.env.${env}`))
|
|
109
107
|
dotenv.config({ path: `./engine-private/conf/${deployId}/.env.${env}`, override: true });
|
|
110
108
|
else if (deployId === 'root') {
|
|
111
|
-
deployId =
|
|
109
|
+
deployId = Underpost.env.get('DEPLOY_ID');
|
|
112
110
|
} else dotenv.config({ path: `./.env`, override: true });
|
|
113
|
-
|
|
114
111
|
loadConf(deployId, subConf);
|
|
115
112
|
});
|
|
116
113
|
|
|
@@ -157,7 +154,7 @@ program
|
|
|
157
154
|
.option('--dev', 'Sets the development cli context')
|
|
158
155
|
|
|
159
156
|
.description(`Manages static build of page, bundles, and documentation with comprehensive customization options.`)
|
|
160
|
-
.action(
|
|
157
|
+
.action(Underpost.static.callback);
|
|
161
158
|
|
|
162
159
|
program
|
|
163
160
|
.command('config')
|
|
@@ -166,6 +163,8 @@ program
|
|
|
166
163
|
.argument('[value]', 'Optional: The value to set for the configuration key.')
|
|
167
164
|
.option('--plain', 'Prints the configuration value in plain text.')
|
|
168
165
|
.option('--filter <keyword>', 'Filters the list by matching key or value (only for list operation).')
|
|
166
|
+
.option('--deploy-id <deploy-id>', 'Sets the deployment configuration ID for the operation context.')
|
|
167
|
+
.option('--build', 'Sets the build context for the operation.')
|
|
169
168
|
.description(`Manages Underpost configurations using various operators.`)
|
|
170
169
|
.action((...args) => Underpost.env[args[0]](args[1], args[2], args[3]));
|
|
171
170
|
|
|
@@ -190,7 +189,7 @@ program
|
|
|
190
189
|
.option('--ban-both-add', 'Adds IP addresses to both banned ingress and egress lists.')
|
|
191
190
|
.option('--ban-both-remove', 'Removes IP addresses from both banned ingress and egress lists.')
|
|
192
191
|
.description('Displays the current public machine IP addresses.')
|
|
193
|
-
.action(
|
|
192
|
+
.action(Underpost.dns.ipDispatcher);
|
|
194
193
|
|
|
195
194
|
program
|
|
196
195
|
.command('cluster')
|
|
@@ -262,6 +261,13 @@ program
|
|
|
262
261
|
.option('--image <image>', 'Sets a custom image for deployments.')
|
|
263
262
|
.option('--versions <deployment-versions>', 'A comma-separated list of custom deployment versions.')
|
|
264
263
|
.option('--traffic <traffic-versions>', 'A comma-separated list of custom deployment traffic weights.')
|
|
264
|
+
.option(
|
|
265
|
+
'--timeout-response <duration>',
|
|
266
|
+
'Sets HTTPProxy per-route response timeout (e.g., "1s", "300ms", "infinity").',
|
|
267
|
+
)
|
|
268
|
+
.option('--timeout-idle <duration>', 'Sets HTTPProxy per-route idle timeout (e.g., "10s", "infinity").')
|
|
269
|
+
.option('--retry-count <count>', 'Sets HTTPProxy per-route retry count (e.g., 3).')
|
|
270
|
+
.option('--retry-per-try-timeout <duration>', 'Sets HTTPProxy retry per-try timeout (e.g., "150ms").')
|
|
265
271
|
.option('--disable-update-deployment', 'Disables updates to deployments.')
|
|
266
272
|
.option('--disable-update-proxy', 'Disables updates to proxies.')
|
|
267
273
|
.option('--disable-deployment-proxy', 'Disables proxies of deployments.')
|
|
@@ -393,28 +399,12 @@ program
|
|
|
393
399
|
.description('Manages cluster metadata operations, including import and export.')
|
|
394
400
|
.action(Underpost.db.clusterMetadataBackupCallback);
|
|
395
401
|
|
|
396
|
-
program
|
|
397
|
-
.command('script')
|
|
398
|
-
.argument('operator', `The script operation to perform. Options: ${Object.keys(Underpost.script).join(', ')}.`)
|
|
399
|
-
.argument('<script-name>', 'The name of the script to execute.')
|
|
400
|
-
.argument('[script-value]', 'Optional: A literal command or a path to a script file.')
|
|
401
|
-
.option('--itc', 'Executes the script within the container execution context.')
|
|
402
|
-
.option('--itc-path', 'Specifies container path options for script execution.')
|
|
403
|
-
.option('--ns <ns-name>', 'Optional: Specifies the namespace context for script execution.')
|
|
404
|
-
.option('--pod-name <pod-name>', 'Optional: Specifies the pod name for script execution.')
|
|
405
|
-
.description(
|
|
406
|
-
'Supports a variety of built-in Underpost global scripts, their preset lifecycle events, and arbitrary custom scripts.',
|
|
407
|
-
)
|
|
408
|
-
.action((...args) => Underpost.script[args[0]](args[1], args[2], args[3]));
|
|
409
|
-
|
|
410
402
|
program
|
|
411
403
|
.command('cron')
|
|
412
404
|
.argument('[deploy-list]', 'A comma-separated list of deployment IDs (e.g., "default-a,default-b").')
|
|
413
405
|
.argument(
|
|
414
406
|
'[job-list]',
|
|
415
|
-
`A comma-separated list of job IDs. Options: ${
|
|
416
|
-
', ',
|
|
417
|
-
)}. Defaults to all available jobs.`,
|
|
407
|
+
`A comma-separated list of job IDs. Options: ${Underpost.cron.getJobsIDs()}. Defaults to all available jobs.`,
|
|
418
408
|
)
|
|
419
409
|
.option('--init-pm2-cronjobs', 'Initializes PM2 cron jobs from configuration for the specified deployment IDs.')
|
|
420
410
|
.option('--git', 'Uploads cron job configurations to GitHub.')
|
|
@@ -461,6 +451,11 @@ program
|
|
|
461
451
|
.option('--type <type>', 'Sets a custom monitor type.')
|
|
462
452
|
.option('--sync', 'Synchronizes with current proxy deployments and traffic configurations.')
|
|
463
453
|
.option('--namespace <namespace>', 'Sets the Kubernetes namespace for the deployment. Defaults to "default".')
|
|
454
|
+
.option('--timeout-response <duration>', 'Sets HTTPProxy per-route response timeout (e.g., "5s").')
|
|
455
|
+
.option('--timeout-idle <duration>', 'Sets HTTPProxy per-route idle timeout (e.g., "10s", "infinity").')
|
|
456
|
+
.option('--retry-count <count>', 'Sets HTTPProxy per-route retry count (e.g., 3).')
|
|
457
|
+
.option('--retry-per-try-timeout <duration>', 'Sets HTTPProxy retry per-try timeout (e.g., "150ms").')
|
|
458
|
+
.option('--disable-private-conf-update', 'Disables updates to private configuration during execution.')
|
|
464
459
|
.description('Manages health server monitoring for specified deployments.')
|
|
465
460
|
.action(Underpost.monitor.callback);
|
|
466
461
|
|
|
@@ -491,7 +486,7 @@ program
|
|
|
491
486
|
|
|
492
487
|
program
|
|
493
488
|
.command('run')
|
|
494
|
-
.argument('<runner-id>', `The runner ID to run. Options: ${
|
|
489
|
+
.argument('<runner-id>', `The runner ID to run. Options: ${Underpost.run.RUNNERS}.`)
|
|
495
490
|
.argument('[path]', 'The input value, identifier, or path for the operation.')
|
|
496
491
|
.option('--cmd <command-list>', 'Comma-separated list of commands to execute.')
|
|
497
492
|
.option('--args <args-array>', 'Array of arguments to pass to the command.')
|
|
@@ -551,8 +546,16 @@ program
|
|
|
551
546
|
.option('--hosts <hosts>', 'Comma-separated list of hosts for the runner execution.')
|
|
552
547
|
.option('--instance-id <instance-id>', 'Sets instance id context for the runner execution.')
|
|
553
548
|
.option('--pid <process-id>', 'Sets process id context for the runner execution.')
|
|
549
|
+
.option(
|
|
550
|
+
'--timeout-response <duration>',
|
|
551
|
+
'Sets HTTPProxy per-route response timeout (e.g., "1s", "300ms", "infinity").',
|
|
552
|
+
)
|
|
553
|
+
.option('--timeout-idle <duration>', 'Sets HTTPProxy per-route idle timeout (e.g., "10s", "infinity").')
|
|
554
|
+
.option('--retry-count <count>', 'Sets HTTPProxy per-route retry count (e.g., 3).')
|
|
555
|
+
.option('--retry-per-try-timeout <duration>', 'Sets HTTPProxy retry per-try timeout (e.g., "150ms").')
|
|
556
|
+
.option('--disable-private-conf-update', 'Disables updates to private configuration during execution.')
|
|
554
557
|
.description('Runs specified scripts using various runners.')
|
|
555
|
-
.action(
|
|
558
|
+
.action(Underpost.run.callback);
|
|
556
559
|
|
|
557
560
|
program
|
|
558
561
|
.command('lxd')
|
|
@@ -587,7 +590,7 @@ program
|
|
|
587
590
|
.option('--deploy-id <deploy-id>', 'Sets the deployment ID context for LXD operations.')
|
|
588
591
|
.option('--namespace <namespace>', 'Kubernetes namespace for LXD operations (defaults to "default").')
|
|
589
592
|
.description('Manages LXD containers and virtual machines.')
|
|
590
|
-
.action(
|
|
593
|
+
.action(Underpost.lxd.callback);
|
|
591
594
|
|
|
592
595
|
program
|
|
593
596
|
.command('baremetal [workflow-id] [ip-address] [hostname] [ip-file-server] [ip-config] [netmask] [dns-server]')
|
|
@@ -652,6 +655,6 @@ program
|
|
|
652
655
|
.description(
|
|
653
656
|
'Manages baremetal server operations, including installation, database setup, commissioning, and user management.',
|
|
654
657
|
)
|
|
655
|
-
.action(
|
|
658
|
+
.action(Underpost.baremetal.callback);
|
|
656
659
|
|
|
657
660
|
export { program };
|
package/src/cli/lxd.js
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { getNpmRootPath } from '../server/conf.js';
|
|
8
|
-
import { getLocalIPv4Address } from '../server/dns.js';
|
|
9
8
|
import { pbcopy, shellExec } from '../server/process.js';
|
|
10
9
|
import fs from 'fs-extra';
|
|
11
10
|
import { loggerFactory } from '../server/logger.js';
|
|
11
|
+
import Underpost from '../index.js';
|
|
12
12
|
|
|
13
13
|
const logger = loggerFactory(import.meta);
|
|
14
14
|
|
|
@@ -83,7 +83,7 @@ class UnderpostLxd {
|
|
|
83
83
|
shellExec(`sudo systemctl status snap.lxd.daemon`);
|
|
84
84
|
const lxdPressedContent = fs
|
|
85
85
|
.readFileSync(`${underpostRoot}/manifests/lxd/lxd-preseed.yaml`, 'utf8')
|
|
86
|
-
.replaceAll(`127.0.0.1`, getLocalIPv4Address());
|
|
86
|
+
.replaceAll(`127.0.0.1`, Underpost.dns.getLocalIPv4Address());
|
|
87
87
|
shellExec(`echo "${lxdPressedContent}" | lxd init --preseed`);
|
|
88
88
|
shellExec(`lxc cluster list`);
|
|
89
89
|
}
|
|
@@ -129,7 +129,7 @@ ipv6.address=none`);
|
|
|
129
129
|
// Default to kubeadm if not K3s
|
|
130
130
|
flag = ' -s -- --kubeadm';
|
|
131
131
|
}
|
|
132
|
-
await
|
|
132
|
+
await Underpost.lxd.runWorkflow({
|
|
133
133
|
workflowId: 'engine',
|
|
134
134
|
vmName: options.initVm,
|
|
135
135
|
});
|
|
@@ -147,7 +147,7 @@ ipv6.address=none`);
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
if (options.workflowId) {
|
|
150
|
-
await
|
|
150
|
+
await Underpost.lxd.runWorkflow({
|
|
151
151
|
workflowId: options.workflowId,
|
|
152
152
|
vmName: options.vmId,
|
|
153
153
|
deployId: options.deployId,
|
|
@@ -201,7 +201,7 @@ ipv6.address=none`);
|
|
|
201
201
|
const [vmName, ports] = options.expose.split(':');
|
|
202
202
|
console.log({ vmName, ports });
|
|
203
203
|
const protocols = ['tcp']; // udp
|
|
204
|
-
const hostIp = getLocalIPv4Address();
|
|
204
|
+
const hostIp = Underpost.dns.getLocalIPv4Address();
|
|
205
205
|
const vmIp = shellExec(
|
|
206
206
|
`lxc list ${vmName} --format json | jq -r '.[0].state.network.enp5s0.addresses[] | select(.family=="inet") | .address'`,
|
|
207
207
|
{ stdout: true },
|
package/src/cli/monitor.js
CHANGED
|
@@ -6,12 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
import { loadReplicas, pathPortAssignmentFactory } from '../server/conf.js';
|
|
8
8
|
import { loggerFactory } from '../server/logger.js';
|
|
9
|
-
import UnderpostDeploy from './deploy.js';
|
|
10
9
|
import axios from 'axios';
|
|
11
|
-
import UnderpostRootEnv from './env.js';
|
|
12
10
|
import fs from 'fs-extra';
|
|
13
11
|
import { shellExec } from '../server/process.js';
|
|
14
|
-
import
|
|
12
|
+
import Underpost from '../index.js';
|
|
15
13
|
|
|
16
14
|
const logger = loggerFactory(import.meta);
|
|
17
15
|
|
|
@@ -40,6 +38,10 @@ class UnderpostMonitor {
|
|
|
40
38
|
* @param {string} [options.replicas='1'] - Number of replicas for the deployment. Defaults to 1.
|
|
41
39
|
* @param {boolean} [options.sync=false] - Synchronize traffic switching with the deployment.
|
|
42
40
|
* @param {string} [options.namespace='default'] - Kubernetes namespace for the deployment. Defaults to 'default'.
|
|
41
|
+
* @param {string} [options.timeoutResponse=''] - Timeout for server response checks.
|
|
42
|
+
* @param {string} [options.timeoutIdle=''] - Timeout for idle connections.
|
|
43
|
+
* @param {string} [options.retryCount=''] - Number of retry attempts for health checks.
|
|
44
|
+
* @param {string} [options.retryPerTryTimeout=''] - Timeout per retry attempt.
|
|
43
45
|
* @param {object} [commanderOptions] - Options passed from the command line interface.
|
|
44
46
|
* @param {object} [auxRouter] - Optional router configuration for the deployment.
|
|
45
47
|
* @memberof UnderpostMonitor
|
|
@@ -55,6 +57,10 @@ class UnderpostMonitor {
|
|
|
55
57
|
replicas: '1',
|
|
56
58
|
sync: false,
|
|
57
59
|
namespace: 'default',
|
|
60
|
+
timeoutResponse: '',
|
|
61
|
+
timeoutIdle: '',
|
|
62
|
+
retryCount: '',
|
|
63
|
+
retryPerTryTimeout: '',
|
|
58
64
|
},
|
|
59
65
|
commanderOptions,
|
|
60
66
|
auxRouter,
|
|
@@ -63,17 +69,17 @@ class UnderpostMonitor {
|
|
|
63
69
|
if (!options.replicas) options.replicas = '1';
|
|
64
70
|
if (deployId === 'dd' && fs.existsSync(`./engine-private/deploy/dd.router`)) {
|
|
65
71
|
for (const _deployId of fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8').split(','))
|
|
66
|
-
|
|
72
|
+
Underpost.monitor.callback(
|
|
67
73
|
_deployId.trim(),
|
|
68
74
|
env,
|
|
69
75
|
options,
|
|
70
76
|
commanderOptions,
|
|
71
|
-
await
|
|
77
|
+
await Underpost.deploy.routerFactory(_deployId, env),
|
|
72
78
|
);
|
|
73
79
|
return;
|
|
74
80
|
}
|
|
75
81
|
|
|
76
|
-
const router = auxRouter ?? (await
|
|
82
|
+
const router = auxRouter ?? (await Underpost.deploy.routerFactory(deployId, env));
|
|
77
83
|
|
|
78
84
|
const confServer = loadReplicas(
|
|
79
85
|
deployId,
|
|
@@ -84,10 +90,10 @@ class UnderpostMonitor {
|
|
|
84
90
|
|
|
85
91
|
let errorPayloads = [];
|
|
86
92
|
if (options.sync === true) {
|
|
87
|
-
const currentTraffic =
|
|
88
|
-
if (currentTraffic)
|
|
93
|
+
const currentTraffic = Underpost.deploy.getCurrentTraffic(deployId, { namespace: options.namespace });
|
|
94
|
+
if (currentTraffic) Underpost.env.set(`${deployId}-${env}-traffic`, currentTraffic);
|
|
89
95
|
}
|
|
90
|
-
let traffic =
|
|
96
|
+
let traffic = Underpost.env.get(`${deployId}-${env}-traffic`) ?? 'blue';
|
|
91
97
|
const maxAttempts = parseInt(
|
|
92
98
|
Object.keys(pathPortAssignmentData)
|
|
93
99
|
.map((host) => pathPortAssignmentData[host].length)
|
|
@@ -102,22 +108,15 @@ class UnderpostMonitor {
|
|
|
102
108
|
traffic,
|
|
103
109
|
});
|
|
104
110
|
|
|
105
|
-
const switchTraffic = () => {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
`node bin deploy --info-router --build-manifest --traffic ${traffic} --replicas ${
|
|
112
|
-
options.replicas
|
|
113
|
-
} --namespace ${namespace} ${deployId} ${env}`,
|
|
114
|
-
);
|
|
115
|
-
shellExec(`sudo kubectl apply -f ./engine-private/conf/${deployId}/build/${env}/proxy.yaml -n ${namespace}`);
|
|
111
|
+
const switchTraffic = (targetTraffic) => {
|
|
112
|
+
const nextTraffic = targetTraffic ?? (traffic === 'blue' ? 'green' : 'blue');
|
|
113
|
+
// Delegate traffic switching to centralized deploy implementation so behavior is consistent
|
|
114
|
+
Underpost.deploy.switchTraffic(deployId, env, nextTraffic, options.replicas, options.namespace, options);
|
|
115
|
+
// Keep local traffic in sync with the environment
|
|
116
|
+
traffic = nextTraffic;
|
|
116
117
|
};
|
|
117
118
|
|
|
118
119
|
const monitor = async (reject) => {
|
|
119
|
-
if (UnderpostRootEnv.API.get(`monitor-init-callback-script`))
|
|
120
|
-
shellExec(UnderpostRootEnv.API.get(`monitor-init-callback-script`));
|
|
121
120
|
const currentTimestamp = new Date().getTime();
|
|
122
121
|
errorPayloads = errorPayloads.filter((e) => currentTimestamp - e.timestamp < 60 * 1000 * 5);
|
|
123
122
|
logger.info(`[${deployId}-${env}] Check server health`);
|
|
@@ -125,19 +124,12 @@ class UnderpostMonitor {
|
|
|
125
124
|
for (const instance of pathPortAssignmentData[host]) {
|
|
126
125
|
const { port, path } = instance;
|
|
127
126
|
if (path.match('peer') || path.match('socket')) continue;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
urlTest = `https://${host}${path}`;
|
|
133
|
-
break;
|
|
134
|
-
|
|
135
|
-
default:
|
|
136
|
-
break;
|
|
127
|
+
const urlTest = `http${env === 'development' ? '' : 's'}://${host}${path}`;
|
|
128
|
+
if (env === 'development') {
|
|
129
|
+
const { renderHosts } = Underpost.deploy.etcHostFactory([host]);
|
|
130
|
+
logger.info('renderHosts', renderHosts);
|
|
137
131
|
}
|
|
138
|
-
// logger.info('Test instance', urlTest);
|
|
139
132
|
await axios.get(urlTest, { timeout: 10000 }).catch((error) => {
|
|
140
|
-
// console.log(error);
|
|
141
133
|
const errorPayload = {
|
|
142
134
|
urlTest,
|
|
143
135
|
host,
|
|
@@ -152,39 +144,29 @@ class UnderpostMonitor {
|
|
|
152
144
|
if (errorPayload.status !== 404) {
|
|
153
145
|
errorPayloads.push(errorPayload);
|
|
154
146
|
if (errorPayloads.length >= maxAttempts) {
|
|
155
|
-
const message = JSON.stringify(errorPayloads, null, 4);
|
|
156
147
|
logger.error(
|
|
157
148
|
`Deployment ${deployId} ${env} has been reached max attempts error payloads`,
|
|
158
149
|
errorPayloads,
|
|
159
150
|
);
|
|
160
151
|
switch (options.type) {
|
|
161
152
|
case 'blue-green':
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
const namespace = options.namespace;
|
|
168
|
-
UnderpostDeploy.API.configMap(env, namespace);
|
|
153
|
+
default: {
|
|
154
|
+
const confServer = JSON.parse(
|
|
155
|
+
fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'),
|
|
156
|
+
);
|
|
169
157
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
shellExec(
|
|
174
|
-
`sudo kubectl rollout restart deployment/${deployId}-${env}-${traffic} -n ${namespace}`,
|
|
175
|
-
);
|
|
158
|
+
const namespace = options.namespace;
|
|
159
|
+
Underpost.deploy.configMap(env, namespace);
|
|
176
160
|
|
|
177
|
-
|
|
161
|
+
for (const host of Object.keys(confServer)) {
|
|
162
|
+
shellExec(`sudo kubectl delete HTTPProxy ${host} -n ${namespace} --ignore-not-found`);
|
|
178
163
|
}
|
|
164
|
+
shellExec(
|
|
165
|
+
`sudo kubectl rollout restart deployment/${deployId}-${env}-${traffic} -n ${namespace}`,
|
|
166
|
+
);
|
|
179
167
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
case 'remote':
|
|
183
|
-
break;
|
|
184
|
-
|
|
185
|
-
default:
|
|
186
|
-
if (reject) reject(message);
|
|
187
|
-
else throw new Error(message);
|
|
168
|
+
switchTraffic();
|
|
169
|
+
}
|
|
188
170
|
}
|
|
189
171
|
errorPayloads = [];
|
|
190
172
|
}
|
|
@@ -201,24 +183,29 @@ class UnderpostMonitor {
|
|
|
201
183
|
let monitorTrafficName;
|
|
202
184
|
let monitorPodName;
|
|
203
185
|
const monitorCallBack = (resolve, reject) => {
|
|
204
|
-
|
|
186
|
+
if (env === 'development') {
|
|
187
|
+
const { renderHosts } = Underpost.deploy.etcHostFactory([]);
|
|
188
|
+
logger.info('renderHosts', renderHosts);
|
|
189
|
+
}
|
|
190
|
+
const envMsTimeout = Underpost.env.get(`${deployId}-${env}-monitor-ms`);
|
|
205
191
|
setTimeout(
|
|
206
192
|
async () => {
|
|
207
|
-
const isOnline = await isInternetConnection();
|
|
193
|
+
const isOnline = await Underpost.dns.isInternetConnection();
|
|
208
194
|
if (!isOnline) {
|
|
209
195
|
logger.warn('No internet connection');
|
|
210
196
|
monitorCallBack(resolve, reject);
|
|
211
197
|
return;
|
|
212
198
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
199
|
+
if (!options.now)
|
|
200
|
+
switch (options.type) {
|
|
201
|
+
case 'blue-green':
|
|
202
|
+
default: {
|
|
216
203
|
if (monitorTrafficName !== traffic) {
|
|
217
204
|
monitorTrafficName = undefined;
|
|
218
205
|
monitorPodName = undefined;
|
|
219
206
|
}
|
|
220
207
|
const checkDeploymentReadyStatus = async () => {
|
|
221
|
-
const { ready, notReadyPods, readyPods } = await
|
|
208
|
+
const { ready, notReadyPods, readyPods } = await Underpost.deploy.checkDeploymentReadyStatus(
|
|
222
209
|
deployId,
|
|
223
210
|
env,
|
|
224
211
|
traffic,
|
|
@@ -236,33 +223,24 @@ class UnderpostMonitor {
|
|
|
236
223
|
return;
|
|
237
224
|
}
|
|
238
225
|
}
|
|
239
|
-
|
|
240
|
-
break;
|
|
241
|
-
|
|
242
|
-
default:
|
|
243
|
-
break;
|
|
244
|
-
}
|
|
245
|
-
for (const monitorStatus of [
|
|
246
|
-
{ key: `monitor-input`, value: UnderpostRootEnv.API.get(`monitor-input`) },
|
|
247
|
-
{
|
|
248
|
-
key: `${deployId}-${env}-monitor-input`,
|
|
249
|
-
value: UnderpostRootEnv.API.get(`${deployId}-${env}-monitor-input`),
|
|
250
|
-
},
|
|
251
|
-
])
|
|
252
|
-
switch (monitorStatus.value) {
|
|
253
|
-
case 'pause':
|
|
254
|
-
monitorCallBack(resolve, reject);
|
|
255
|
-
return;
|
|
256
|
-
case 'restart':
|
|
257
|
-
UnderpostRootEnv.API.delete(monitorStatus.key);
|
|
258
|
-
return reject();
|
|
259
|
-
case 'stop':
|
|
260
|
-
UnderpostRootEnv.API.delete(monitorStatus.key);
|
|
261
|
-
return resolve();
|
|
262
|
-
case 'blue-green-switch':
|
|
263
|
-
UnderpostRootEnv.API.delete(monitorStatus.key);
|
|
264
|
-
switchTraffic();
|
|
265
226
|
}
|
|
227
|
+
const monitorKey = `${deployId}-${env}-monitor-input`;
|
|
228
|
+
const monitorValue = Underpost.env.get(monitorKey);
|
|
229
|
+
switch (monitorValue) {
|
|
230
|
+
case 'pause':
|
|
231
|
+
monitorCallBack(resolve, reject);
|
|
232
|
+
return;
|
|
233
|
+
case 'restart':
|
|
234
|
+
case 'stop':
|
|
235
|
+
case 'blue-green-switch':
|
|
236
|
+
Underpost.env.delete(monitorKey);
|
|
237
|
+
case 'restart':
|
|
238
|
+
return reject();
|
|
239
|
+
case 'stop':
|
|
240
|
+
return resolve();
|
|
241
|
+
case 'blue-green-switch':
|
|
242
|
+
switchTraffic();
|
|
243
|
+
}
|
|
266
244
|
await monitor(reject);
|
|
267
245
|
monitorCallBack(resolve, reject);
|
|
268
246
|
return;
|
package/src/cli/repository.js
CHANGED
|
@@ -12,6 +12,7 @@ import fs from 'fs-extra';
|
|
|
12
12
|
import { getNpmRootPath } from '../server/conf.js';
|
|
13
13
|
import { Config } from '../server/conf.js';
|
|
14
14
|
import { DefaultConf } from '../../conf.js';
|
|
15
|
+
import Underpost from '../index.js';
|
|
15
16
|
|
|
16
17
|
dotenv.config();
|
|
17
18
|
|
|
@@ -134,8 +135,8 @@ class UnderpostRepository {
|
|
|
134
135
|
}
|
|
135
136
|
if (options.lastMsg) {
|
|
136
137
|
if (options.copy) {
|
|
137
|
-
pbcopy(
|
|
138
|
-
} else console.log(
|
|
138
|
+
pbcopy(Underpost.repo.getLastCommitMsg(options.lastMsg - 1));
|
|
139
|
+
} else console.log(Underpost.repo.getLastCommitMsg(options.lastMsg - 1));
|
|
139
140
|
return;
|
|
140
141
|
}
|
|
141
142
|
if (options.diff) {
|
|
@@ -145,7 +146,7 @@ class UnderpostRepository {
|
|
|
145
146
|
return;
|
|
146
147
|
}
|
|
147
148
|
if (options.log) {
|
|
148
|
-
const history =
|
|
149
|
+
const history = Underpost.repo.getHistory(options.log);
|
|
149
150
|
const chainCmd = history
|
|
150
151
|
.reverse()
|
|
151
152
|
.map((commitData, i) => `${i === 0 ? '' : ' && '}git ${diffCmd} ${commitData.hash}`)
|
|
@@ -174,7 +175,7 @@ class UnderpostRepository {
|
|
|
174
175
|
return;
|
|
175
176
|
}
|
|
176
177
|
if (commitType === 'reset') {
|
|
177
|
-
if (options.copy) pbcopy(
|
|
178
|
+
if (options.copy) pbcopy(Underpost.repo.getLastCommitMsg());
|
|
178
179
|
shellExec(`cd ${repoPath} && git reset --soft HEAD~${isNaN(parseInt(subModule)) ? 1 : parseInt(subModule)}`);
|
|
179
180
|
return;
|
|
180
181
|
}
|
|
@@ -283,7 +284,7 @@ class UnderpostRepository {
|
|
|
283
284
|
|
|
284
285
|
// Handle defaultConf operation
|
|
285
286
|
if (options.defaultConf) {
|
|
286
|
-
|
|
287
|
+
Underpost.repo.updateDefaultConf(options);
|
|
287
288
|
return resolve(true);
|
|
288
289
|
}
|
|
289
290
|
|
|
@@ -439,7 +440,7 @@ class UnderpostRepository {
|
|
|
439
440
|
const commandUntrack = `cd ${path} && git ls-files --others --exclude-standard`;
|
|
440
441
|
const diffOutput = shellExec(command, { stdout: true, silent: true });
|
|
441
442
|
const diffUntrackOutput = shellExec(commandUntrack, { stdout: true, silent: true });
|
|
442
|
-
const deleteFiles =
|
|
443
|
+
const deleteFiles = Underpost.repo.getDeleteFiles(path);
|
|
443
444
|
return diffOutput
|
|
444
445
|
.toString()
|
|
445
446
|
.split('\n')
|