underpost 2.8.885 → 2.8.886
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.production +3 -0
- package/.github/workflows/ghpkg.ci.yml +1 -1
- package/.github/workflows/npmpkg.ci.yml +1 -1
- package/.github/workflows/publish.ci.yml +5 -5
- package/.github/workflows/pwa-microservices-template-page.cd.yml +1 -1
- package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
- package/CHANGELOG.md +145 -1
- package/Dockerfile +1 -1
- package/README.md +3 -3
- package/bin/build.js +18 -9
- package/bin/deploy.js +93 -187
- package/cli.md +2 -2
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +54 -54
- package/manifests/deployment/dd-test-development/proxy.yaml +4 -4
- package/manifests/lxd/underpost-setup.sh +5 -5
- package/package.json +3 -3
- package/scripts/ssl.sh +164 -0
- package/src/cli/baremetal.js +7 -7
- package/src/cli/cloud-init.js +1 -1
- package/src/cli/cluster.js +10 -3
- package/src/cli/cron.js +1 -1
- package/src/cli/db.js +1 -1
- package/src/cli/deploy.js +33 -1
- package/src/cli/fs.js +2 -2
- package/src/cli/image.js +7 -0
- package/src/cli/monitor.js +33 -1
- package/src/cli/run.js +315 -51
- package/src/cli/script.js +32 -0
- package/src/cli/secrets.js +34 -0
- package/src/cli/test.js +42 -1
- package/src/client/components/core/Css.js +0 -8
- package/src/client/components/core/windowGetDimensions.js +229 -162
- package/src/index.js +2 -2
- package/src/mailer/MailerProvider.js +1 -0
- package/src/runtime/express/Express.js +12 -4
- package/src/runtime/lampp/Dockerfile +1 -1
- package/src/server/backup.js +20 -0
- package/src/server/client-build-live.js +12 -10
- package/src/server/client-build.js +136 -91
- package/src/server/client-dev-server.js +16 -2
- package/src/server/client-icons.js +19 -0
- package/src/server/conf.js +470 -60
- package/src/server/dns.js +184 -42
- package/src/server/downloader.js +65 -24
- package/src/server/object-layer.js +260 -162
- package/src/server/peer.js +2 -8
- package/src/server/proxy.js +93 -76
- package/src/server/runtime.js +15 -16
- package/src/server/ssr.js +4 -4
- package/src/server/tls.js +251 -0
- package/src/server/valkey.js +11 -10
- package/src/ws/IoInterface.js +2 -1
- package/src/ws/IoServer.js +2 -1
- package/src/ws/core/core.ws.connection.js +1 -1
- package/src/ws/core/core.ws.emit.js +1 -1
- package/src/ws/core/core.ws.server.js +1 -1
- package/manifests/maas/lxd-preseed.yaml +0 -32
- package/src/server/ssl.js +0 -108
- /package/{manifests/maas → scripts}/device-scan.sh +0 -0
- /package/{manifests/maas → scripts}/gpu-diag.sh +0 -0
- /package/{manifests/maas → scripts}/maas-setup.sh +0 -0
- /package/{manifests/maas → scripts}/nat-iptables.sh +0 -0
- /package/{manifests/maas → scripts}/nvim.sh +0 -0
- /package/{manifests/maas → scripts}/snap-clean.sh +0 -0
- /package/{manifests/maas → scripts}/ssh-cluster-info.sh +0 -0
package/scripts/ssl.sh
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# RHEL / Rocky Linux — Generate local TLS cert + fullchain (cert + root CA) using mkcert
|
|
3
|
+
# Usage:
|
|
4
|
+
# ./generate-local-ssl-fullchain.sh /path/to/target "localhost 127.0.0.1 ::1"
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
IFS=$'\n\t'
|
|
8
|
+
|
|
9
|
+
err() { echo "[ERROR] $*" >&2; }
|
|
10
|
+
info() { echo "[INFO] $*"; }
|
|
11
|
+
|
|
12
|
+
print_usage() {
|
|
13
|
+
cat <<'EOF'
|
|
14
|
+
Usage: $0 TARGET_DIR "domain1 domain2 ..."
|
|
15
|
+
Example: $0 /etc/ssl/local "localhost 127.0.0.1 ::1"
|
|
16
|
+
|
|
17
|
+
Outputs created in TARGET_DIR:
|
|
18
|
+
- <name>.pem : leaf/server certificate
|
|
19
|
+
- <name>-key.pem : private key
|
|
20
|
+
- <name>-fullchain.pem: certificate followed by root CA (use for servers needing full chain)
|
|
21
|
+
- rootCA.pem : local root CA (if OpenSSL fallback used or copied from mkcert CAROOT)
|
|
22
|
+
EOF
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if [[ ${1-} == "-h" || ${1-} == "--help" ]]; then
|
|
26
|
+
print_usage; exit 0; fi
|
|
27
|
+
|
|
28
|
+
TARGET_DIR="${1-}"
|
|
29
|
+
DOMAINS="${2-}"
|
|
30
|
+
|
|
31
|
+
if [[ -z "$TARGET_DIR" ]]; then read -rp "Target directory to store certificates (absolute path): " TARGET_DIR; fi
|
|
32
|
+
if [[ -z "$DOMAINS" ]]; then read -rp "Space-separated domains/IPs to include (e.g. 'localhost 127.0.0.1 api.myapp.test'): " DOMAINS; fi
|
|
33
|
+
|
|
34
|
+
TARGET_DIR="$(realpath -m "$TARGET_DIR")"
|
|
35
|
+
mkdir -p "$TARGET_DIR"
|
|
36
|
+
IFS=' ' read -r -a DOMAIN_ARR <<< "$DOMAINS"
|
|
37
|
+
if [[ ${#DOMAIN_ARR[@]} -eq 0 ]]; then err "No domains provided. Exiting."; exit 1; fi
|
|
38
|
+
|
|
39
|
+
NAME_SAFE="${DOMAIN_ARR[0]//[^a-zA-Z0-9_.-]/_}"
|
|
40
|
+
CERT_FILE="$TARGET_DIR/${NAME_SAFE}.pem"
|
|
41
|
+
KEY_FILE="$TARGET_DIR/${NAME_SAFE}-key.pem"
|
|
42
|
+
FULLCHAIN_FILE="$TARGET_DIR/${NAME_SAFE}-fullchain.pem"
|
|
43
|
+
ROOT_PEM="$TARGET_DIR/rootCA.pem"
|
|
44
|
+
|
|
45
|
+
info "Target dir: $TARGET_DIR"
|
|
46
|
+
info "Domains: ${DOMAIN_ARR[*]}"
|
|
47
|
+
info "Outputs: $CERT_FILE, $KEY_FILE, $FULLCHAIN_FILE, $ROOT_PEM"
|
|
48
|
+
|
|
49
|
+
# Install prerequisites
|
|
50
|
+
if ! command -v dnf >/dev/null 2>&1; then err "dnf not found. This script expects RHEL/Rocky with dnf."; exit 1; fi
|
|
51
|
+
sudo dnf install -y curl nss-tools ca-certificates || true
|
|
52
|
+
|
|
53
|
+
# Download and install mkcert binary (no 'go install')
|
|
54
|
+
download_mkcert_binary() {
|
|
55
|
+
UNAME_M=$(uname -m)
|
|
56
|
+
case "$UNAME_M" in
|
|
57
|
+
x86_64|amd64) ARCH_STR='linux-amd64' ;;
|
|
58
|
+
aarch64|arm64) ARCH_STR='linux-arm64' ;;
|
|
59
|
+
*) ARCH_STR='linux-amd64' ;;
|
|
60
|
+
esac
|
|
61
|
+
info "Searching mkcert release for $ARCH_STR"
|
|
62
|
+
ASSET_URL=$(curl -sS "https://api.github.com/repos/FiloSottile/mkcert/releases/latest" | \
|
|
63
|
+
grep -E '"browser_download_url":' | grep -i "$ARCH_STR" | head -n1 | sed -E 's/.*"(https:[^"]+)".*/\1/' || true)
|
|
64
|
+
if [[ -z "$ASSET_URL" ]]; then
|
|
65
|
+
ASSET_URL=$(curl -sS "https://api.github.com/repos/FiloSottile/mkcert/releases/latest" | \
|
|
66
|
+
grep -E '"browser_download_url":' | grep -i 'linux' | grep -i 'amd64' | head -n1 | sed -E 's/.*"(https:[^"]+)".*/\1/' || true)
|
|
67
|
+
fi
|
|
68
|
+
if [[ -z "$ASSET_URL" ]]; then err "Could not find mkcert asset for your arch"; return 1; fi
|
|
69
|
+
TMP_BIN="$(mktemp -u /tmp/mkcert.XXXXXX)"
|
|
70
|
+
if curl -fSL -o "$TMP_BIN" "$ASSET_URL"; then
|
|
71
|
+
sudo mv "$TMP_BIN" /usr/local/bin/mkcert
|
|
72
|
+
sudo chmod +x /usr/local/bin/mkcert
|
|
73
|
+
info "mkcert installed to /usr/local/bin/mkcert"
|
|
74
|
+
return 0
|
|
75
|
+
fi
|
|
76
|
+
return 1
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
use_mkcert() {
|
|
80
|
+
if ! command -v mkcert >/dev/null 2>&1; then
|
|
81
|
+
info "mkcert not found — attempting to download/install binary"
|
|
82
|
+
download_mkcert_binary || return 1
|
|
83
|
+
fi
|
|
84
|
+
MKCERT_BIN="$(command -v mkcert || echo /usr/local/bin/mkcert)"
|
|
85
|
+
info "Running mkcert -install as sudo (if necessary)"
|
|
86
|
+
if ! sudo "$MKCERT_BIN" -install >/dev/null 2>&1; then
|
|
87
|
+
if ! "$MKCERT_BIN" -install >/dev/null 2>&1; then
|
|
88
|
+
err "mkcert -install failed"; return 1
|
|
89
|
+
fi
|
|
90
|
+
fi
|
|
91
|
+
MK_ARGS=()
|
|
92
|
+
for d in "${DOMAIN_ARR[@]}"; do MK_ARGS+=("$d"); done
|
|
93
|
+
info "Generating cert+key with mkcert"
|
|
94
|
+
if ! "$MKCERT_BIN" -cert-file "$CERT_FILE" -key-file "$KEY_FILE" "${MK_ARGS[@]}"; then err "mkcert failed to generate"; return 1; fi
|
|
95
|
+
# copy root CA from mkcert CAROOT into TARGET_DIR
|
|
96
|
+
if ROOT_FROM_MKCERT="$($MKCERT_BIN -CAROOT 2>/dev/null || true)"; then
|
|
97
|
+
if [[ -f "$ROOT_FROM_MKCERT/rootCA.pem" ]]; then
|
|
98
|
+
cp "$ROOT_FROM_MKCERT/rootCA.pem" "$ROOT_PEM"
|
|
99
|
+
info "Copied mkcert root CA to $ROOT_PEM"
|
|
100
|
+
fi
|
|
101
|
+
fi
|
|
102
|
+
# create fullchain (cert followed by root CA)
|
|
103
|
+
if [[ -f "$ROOT_PEM" ]]; then
|
|
104
|
+
cat "$CERT_FILE" "$ROOT_PEM" > "$FULLCHAIN_FILE"
|
|
105
|
+
info "Created fullchain: $FULLCHAIN_FILE"
|
|
106
|
+
else
|
|
107
|
+
cp "$CERT_FILE" "$FULLCHAIN_FILE"
|
|
108
|
+
info "No root CA found to append; fullchain contains only leaf cert: $FULLCHAIN_FILE"
|
|
109
|
+
fi
|
|
110
|
+
return 0
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
use_openssl() {
|
|
114
|
+
command -v openssl >/dev/null 2>&1 || { err "openssl required"; return 1; }
|
|
115
|
+
ROOT_KEY="$TARGET_DIR/rootCA.key"
|
|
116
|
+
if [[ ! -f "$ROOT_KEY" || ! -f "$ROOT_PEM" ]]; then
|
|
117
|
+
openssl genrsa -out "$ROOT_KEY" 4096
|
|
118
|
+
openssl req -x509 -new -nodes -key "$ROOT_KEY" -sha256 -days 3650 -out "$ROOT_PEM" -subj "/CN=Local Development Root CA"
|
|
119
|
+
fi
|
|
120
|
+
CSR_KEY="$TARGET_DIR/${NAME_SAFE}.key"
|
|
121
|
+
CSR_PEM="$TARGET_DIR/${NAME_SAFE}.csr"
|
|
122
|
+
openssl genrsa -out "$CSR_KEY" 2048
|
|
123
|
+
openssl req -new -key "$CSR_KEY" -out "$CSR_PEM" -subj "/CN=${DOMAIN_ARR[0]}"
|
|
124
|
+
V3EXT="$TARGET_DIR/v3.ext"
|
|
125
|
+
printf 'authorityKeyIdentifier=keyid,issuer\nbasicConstraints=CA:FALSE\nkeyUsage = digitalSignature, keyEncipherment\nsubjectAltName = @alt_names\n\n[alt_names]\n' > "$V3EXT"
|
|
126
|
+
DNS=1; IP=1
|
|
127
|
+
for d in "${DOMAIN_ARR[@]}"; do
|
|
128
|
+
if [[ "$d" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] || [[ "$d" == *":"* ]]; then
|
|
129
|
+
printf 'IP.%d = %s\n' "$IP" "$d" >> "$V3EXT"; IP=$((IP+1))
|
|
130
|
+
else
|
|
131
|
+
printf 'DNS.%d = %s\n' "$DNS" "$d" >> "$V3EXT"; DNS=$((DNS+1))
|
|
132
|
+
fi
|
|
133
|
+
done
|
|
134
|
+
if openssl x509 -req -in "$CSR_PEM" -CA "$ROOT_PEM" -CAkey "$ROOT_KEY" -CAcreateserial -out "$CERT_FILE" -days 825 -sha256 -extfile "$V3EXT"; then
|
|
135
|
+
mv -f "$CSR_KEY" "$KEY_FILE"
|
|
136
|
+
# create fullchain: leaf + root
|
|
137
|
+
cat "$CERT_FILE" "$ROOT_PEM" > "$FULLCHAIN_FILE"
|
|
138
|
+
sudo cp "$ROOT_PEM" /etc/pki/ca-trust/source/anchors/ || true
|
|
139
|
+
sudo update-ca-trust extract || true
|
|
140
|
+
if command -v certutil >/dev/null 2>&1; then
|
|
141
|
+
mkdir -p "$HOME/.pki/nssdb"
|
|
142
|
+
certutil -d sql:$HOME/.pki/nssdb -A -t "CT,C,C" -n "Local Dev Root CA" -i "$ROOT_PEM" || true
|
|
143
|
+
fi
|
|
144
|
+
info "OpenSSL created cert, key and fullchain"
|
|
145
|
+
return 0
|
|
146
|
+
fi
|
|
147
|
+
err "OpenSSL failed to create certificate"
|
|
148
|
+
return 1
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
# main
|
|
152
|
+
if use_mkcert; then
|
|
153
|
+
info "Done: created cert, key, fullchain and root CA in $TARGET_DIR"
|
|
154
|
+
exit 0
|
|
155
|
+
else
|
|
156
|
+
info "mkcert flow failed — trying OpenSSL fallback"
|
|
157
|
+
if use_openssl; then
|
|
158
|
+
info "Done: created cert, key, fullchain and root CA in $TARGET_DIR"
|
|
159
|
+
exit 0
|
|
160
|
+
fi
|
|
161
|
+
fi
|
|
162
|
+
|
|
163
|
+
err "Failed to create certificates with mkcert or OpenSSL"
|
|
164
|
+
exit 2
|
package/src/cli/baremetal.js
CHANGED
|
@@ -11,7 +11,7 @@ import dotenv from 'dotenv';
|
|
|
11
11
|
import { loggerFactory } from '../server/logger.js';
|
|
12
12
|
import { getLocalIPv4Address } from '../server/dns.js';
|
|
13
13
|
import fs from 'fs-extra';
|
|
14
|
-
import
|
|
14
|
+
import Downloader from '../server/downloader.js';
|
|
15
15
|
import UnderpostCloudInit from './cloud-init.js';
|
|
16
16
|
import { s4, timer } from '../client/components/core/CommonJs.js';
|
|
17
17
|
|
|
@@ -153,10 +153,10 @@ class UnderpostBaremetal {
|
|
|
153
153
|
// Handle control server installation.
|
|
154
154
|
if (options.controlServerInstall === true) {
|
|
155
155
|
// Ensure scripts are executable and then run them.
|
|
156
|
-
shellExec(`chmod +x ${underpostRoot}/
|
|
157
|
-
shellExec(`chmod +x ${underpostRoot}/
|
|
158
|
-
shellExec(`${underpostRoot}/
|
|
159
|
-
shellExec(`${underpostRoot}/
|
|
156
|
+
shellExec(`chmod +x ${underpostRoot}/scripts/maas-setup.sh`);
|
|
157
|
+
shellExec(`chmod +x ${underpostRoot}/scripts/nat-iptables.sh`);
|
|
158
|
+
shellExec(`${underpostRoot}/scripts/maas-setup.sh`);
|
|
159
|
+
shellExec(`${underpostRoot}/scripts/nat-iptables.sh`);
|
|
160
160
|
return;
|
|
161
161
|
}
|
|
162
162
|
|
|
@@ -349,7 +349,7 @@ class UnderpostBaremetal {
|
|
|
349
349
|
const name = url.split('/').pop().replace('.zip', '');
|
|
350
350
|
const path = `../${name}`;
|
|
351
351
|
if (!fs.existsSync(path)) {
|
|
352
|
-
await Downloader(url, `../${name}.zip`); // Download firmware if not exists.
|
|
352
|
+
await Downloader.downloadFile(url, `../${name}.zip`); // Download firmware if not exists.
|
|
353
353
|
shellExec(`cd .. && mkdir ${name} && cd ${name} && unzip ../${name}.zip`); // Unzip firmware.
|
|
354
354
|
}
|
|
355
355
|
shellExec(`sudo cp -a ${path}/* ${tftpRootPath}`); // Copy firmware files to TFTP root.
|
|
@@ -530,7 +530,7 @@ menuentry '${menuentryStr}' {
|
|
|
530
530
|
if (options.cloudInitUpdate === true) return;
|
|
531
531
|
|
|
532
532
|
// Apply NAT iptables rules.
|
|
533
|
-
shellExec(`${underpostRoot}/
|
|
533
|
+
shellExec(`${underpostRoot}/scripts/nat-iptables.sh`, { silent: true });
|
|
534
534
|
|
|
535
535
|
// Wait for MAC address assignment.
|
|
536
536
|
logger.info('Waiting for MAC assignment...');
|
package/src/cli/cloud-init.js
CHANGED
|
@@ -182,7 +182,7 @@ cut -d: -f1 /etc/passwd`,
|
|
|
182
182
|
|
|
183
183
|
// Copy the device scan script from manifests.
|
|
184
184
|
logger.info('Build', `${nfsHostToolsPath}/device_scan.sh`);
|
|
185
|
-
fs.copySync(`${underpostRoot}/
|
|
185
|
+
fs.copySync(`${underpostRoot}/scripts/device-scan.sh`, `${nfsHostToolsPath}/device_scan.sh`);
|
|
186
186
|
|
|
187
187
|
// Build and write the config path script.
|
|
188
188
|
logger.info('Build', `${nfsHostToolsPath}/config-path.sh`);
|
package/src/cli/cluster.js
CHANGED
|
@@ -15,6 +15,13 @@ import fs from 'fs-extra';
|
|
|
15
15
|
|
|
16
16
|
const logger = loggerFactory(import.meta);
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* @class UnderpostCluster
|
|
20
|
+
* @description Manages Kubernetes cluster initialization, configuration, and component deployment.
|
|
21
|
+
* This class provides a set of static methods to handle cluster initialization, configuration,
|
|
22
|
+
* and optional component deployments.
|
|
23
|
+
* @memberof UnderpostCluster
|
|
24
|
+
*/
|
|
18
25
|
class UnderpostCluster {
|
|
19
26
|
static API = {
|
|
20
27
|
/**
|
|
@@ -520,7 +527,7 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`,
|
|
|
520
527
|
|
|
521
528
|
// shellExec(`sudo sysctl --system`); // Apply sysctl changes immediately
|
|
522
529
|
// Apply NAT iptables rules.
|
|
523
|
-
shellExec(`${underpostRoot}/
|
|
530
|
+
shellExec(`${underpostRoot}/scripts/nat-iptables.sh`, { silent: true });
|
|
524
531
|
|
|
525
532
|
// Disable firewalld (common cause of network issues in Kubernetes)
|
|
526
533
|
shellExec(`sudo systemctl stop firewalld || true`); // Stop if running
|
|
@@ -663,8 +670,8 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`,
|
|
|
663
670
|
shellExec('sudo iptables -F || true');
|
|
664
671
|
shellExec('sudo iptables -t nat -F || true');
|
|
665
672
|
// Restore iptables rules
|
|
666
|
-
shellExec(`chmod +x ${options.underpostRoot}/
|
|
667
|
-
shellExec(`${options.underpostRoot}/
|
|
673
|
+
shellExec(`chmod +x ${options.underpostRoot}/scripts/nat-iptables.sh`);
|
|
674
|
+
shellExec(`${options.underpostRoot}/scripts/nat-iptables.sh`, { silent: true });
|
|
668
675
|
shellExec('sudo ip link del cni0 || true');
|
|
669
676
|
shellExec('sudo ip link del flannel.1 || true');
|
|
670
677
|
|
package/src/cli/cron.js
CHANGED
package/src/cli/db.js
CHANGED
|
@@ -274,7 +274,7 @@ class UnderpostDB {
|
|
|
274
274
|
JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8')),
|
|
275
275
|
);
|
|
276
276
|
const router = await UnderpostDeploy.API.routerFactory(deployId, env);
|
|
277
|
-
const pathPortAssignmentData = pathPortAssignmentFactory(router, confServer);
|
|
277
|
+
const pathPortAssignmentData = await pathPortAssignmentFactory(deployId, router, confServer);
|
|
278
278
|
|
|
279
279
|
for (const host of Object.keys(confServer)) {
|
|
280
280
|
for (const { path, port } of pathPortAssignmentData[host]) {
|
package/src/cli/deploy.js
CHANGED
|
@@ -20,6 +20,7 @@ import fs from 'fs-extra';
|
|
|
20
20
|
import dotenv from 'dotenv';
|
|
21
21
|
import UnderpostRootEnv from './env.js';
|
|
22
22
|
import UnderpostCluster from './cluster.js';
|
|
23
|
+
import { timer } from '../client/components/core/CommonJs.js';
|
|
23
24
|
|
|
24
25
|
const logger = loggerFactory(import.meta);
|
|
25
26
|
|
|
@@ -186,7 +187,7 @@ spec:
|
|
|
186
187
|
JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8')),
|
|
187
188
|
);
|
|
188
189
|
const router = await UnderpostDeploy.API.routerFactory(deployId, env);
|
|
189
|
-
const pathPortAssignmentData = pathPortAssignmentFactory(router, confServer);
|
|
190
|
+
const pathPortAssignmentData = await pathPortAssignmentFactory(deployId, router, confServer);
|
|
190
191
|
const { fromPort, toPort } = deployRangePortFactory(router);
|
|
191
192
|
const deploymentVersions = options.versions.split(',');
|
|
192
193
|
fs.mkdirSync(`./engine-private/conf/${deployId}/build/${env}`, { recursive: true });
|
|
@@ -655,6 +656,37 @@ EOF`);
|
|
|
655
656
|
env === 'production' &&
|
|
656
657
|
options.cert === true &&
|
|
657
658
|
(!options.certHosts || options.certHosts.split(',').includes(host)),
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* Monitors the ready status of a deployment.
|
|
662
|
+
* @param {string} deployId - Deployment ID for which the ready status is being monitored.
|
|
663
|
+
* @param {string} env - Environment for which the ready status is being monitored.
|
|
664
|
+
* @param {string} targetTraffic - Target traffic status for the deployment.
|
|
665
|
+
* @param {Array<string>} ignorePods - List of pod names to ignore.
|
|
666
|
+
* @memberof UnderpostDeploy
|
|
667
|
+
*/
|
|
668
|
+
async monitorReadyRunner(deployId, env, targetTraffic, ignorePods = []) {
|
|
669
|
+
let checkStatusIteration = 0;
|
|
670
|
+
const checkStatusIterationMsDelay = 1000;
|
|
671
|
+
const iteratorTag = `[${deployId}-${env}-${targetTraffic}]`;
|
|
672
|
+
logger.info('Deployment init', { deployId, env, targetTraffic, checkStatusIterationMsDelay });
|
|
673
|
+
const minReadyOk = 3;
|
|
674
|
+
let readyOk = 0;
|
|
675
|
+
|
|
676
|
+
while (readyOk < minReadyOk) {
|
|
677
|
+
const ready = UnderpostDeploy.API.checkDeploymentReadyStatus(deployId, env, targetTraffic, ignorePods).ready;
|
|
678
|
+
if (ready === true) {
|
|
679
|
+
readyOk++;
|
|
680
|
+
logger.info(`${iteratorTag} | Deployment ready. Verification number: ${readyOk}`);
|
|
681
|
+
}
|
|
682
|
+
await timer(checkStatusIterationMsDelay);
|
|
683
|
+
checkStatusIteration++;
|
|
684
|
+
logger.info(
|
|
685
|
+
`${iteratorTag} | Deployment in progress... | Delay number check iterations: ${checkStatusIteration}`,
|
|
686
|
+
);
|
|
687
|
+
}
|
|
688
|
+
logger.info(`${iteratorTag} | Deployment ready. | Total delay number check iterations: ${checkStatusIteration}`);
|
|
689
|
+
},
|
|
658
690
|
};
|
|
659
691
|
}
|
|
660
692
|
|
package/src/cli/fs.js
CHANGED
|
@@ -10,7 +10,7 @@ import dotenv from 'dotenv';
|
|
|
10
10
|
import AdmZip from 'adm-zip';
|
|
11
11
|
import * as dir from 'path';
|
|
12
12
|
import fs from 'fs-extra';
|
|
13
|
-
import
|
|
13
|
+
import Downloader from '../server/downloader.js';
|
|
14
14
|
import UnderpostRepository from './repository.js';
|
|
15
15
|
import { shellExec } from '../server/process.js';
|
|
16
16
|
dotenv.config();
|
|
@@ -204,7 +204,7 @@ class UnderpostFileStorage {
|
|
|
204
204
|
resource_type: 'raw',
|
|
205
205
|
});
|
|
206
206
|
logger.info('download result', downloadResult);
|
|
207
|
-
await Downloader(downloadResult, path + '.zip');
|
|
207
|
+
await Downloader.downloadFile(downloadResult, path + '.zip');
|
|
208
208
|
path = UnderpostFileStorage.API.zip2File(path + '.zip');
|
|
209
209
|
fs.removeSync(path + '.zip');
|
|
210
210
|
},
|
package/src/cli/image.js
CHANGED
|
@@ -15,6 +15,13 @@ dotenv.config();
|
|
|
15
15
|
|
|
16
16
|
const logger = loggerFactory(import.meta);
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* @class UnderpostImage
|
|
20
|
+
* @description Manages Docker image operations, including pulling, building, and loading images into Kubernetes clusters.
|
|
21
|
+
* This class provides a set of static methods to handle image operations, including pulling base images,
|
|
22
|
+
* building custom images, and loading them into specified Kubernetes clusters (Kind, Kubeadm, or K3s).
|
|
23
|
+
* @memberof UnderpostImage
|
|
24
|
+
*/
|
|
18
25
|
class UnderpostImage {
|
|
19
26
|
static API = {
|
|
20
27
|
dockerfile: {
|
package/src/cli/monitor.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monitor module for managing the monitoring of deployments and services.
|
|
3
|
+
* @module src/cli/monitor.js
|
|
4
|
+
* @namespace UnderpostMonitor
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
import { loadReplicas, pathPortAssignmentFactory } from '../server/conf.js';
|
|
2
8
|
import { loggerFactory } from '../server/logger.js';
|
|
3
9
|
import UnderpostDeploy from './deploy.js';
|
|
@@ -9,8 +15,34 @@ import { isInternetConnection } from '../server/dns.js';
|
|
|
9
15
|
|
|
10
16
|
const logger = loggerFactory(import.meta);
|
|
11
17
|
|
|
18
|
+
/**
|
|
19
|
+
* @class UnderpostMonitor
|
|
20
|
+
* @description Manages deployment monitoring and health checks.
|
|
21
|
+
* This class provides a set of static methods to monitor and manage
|
|
22
|
+
* deployment health, including checking server status, handling traffic
|
|
23
|
+
* switching, and orchestrating monitoring workflows.
|
|
24
|
+
* @memberof UnderpostMonitor
|
|
25
|
+
*/
|
|
12
26
|
class UnderpostMonitor {
|
|
13
27
|
static API = {
|
|
28
|
+
/**
|
|
29
|
+
* @method callback
|
|
30
|
+
* @description Initiates a deployment monitoring workflow based on the provided options.
|
|
31
|
+
* This method orchestrates the monitoring process for a specific deployment, handling
|
|
32
|
+
* traffic switching, error accumulation, and optional Git integration for version control.
|
|
33
|
+
* @param {string} deployId - The identifier for the deployment to monitor.
|
|
34
|
+
* @param {string} [env='development'] - The environment for the deployment (e.g., 'development', 'production').
|
|
35
|
+
* @param {object} [options] - An object containing boolean flags for various operations.
|
|
36
|
+
* @param {boolean} [options.now=false] - Perform a single health check immediately.
|
|
37
|
+
* @param {boolean} [options.single=false] - Perform a single health check and exit.
|
|
38
|
+
* @param {string} [options.msInterval=''] - Interval in milliseconds for periodic health checks.
|
|
39
|
+
* @param {string} [options.type=''] - Type of deployment (e.g., 'blue-green', 'remote').
|
|
40
|
+
* @param {string} [options.replicas=''] - Number of replicas for the deployment.
|
|
41
|
+
* @param {boolean} [options.sync=false] - Synchronize traffic switching with the deployment.
|
|
42
|
+
* @param {object} [commanderOptions] - Options passed from the command line interface.
|
|
43
|
+
* @param {object} [auxRouter] - Optional router configuration for the deployment.
|
|
44
|
+
* @memberof UnderpostMonitor
|
|
45
|
+
*/
|
|
14
46
|
async callback(
|
|
15
47
|
deployId,
|
|
16
48
|
env = 'development',
|
|
@@ -36,7 +68,7 @@ class UnderpostMonitor {
|
|
|
36
68
|
JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8')),
|
|
37
69
|
);
|
|
38
70
|
|
|
39
|
-
const pathPortAssignmentData = pathPortAssignmentFactory(router, confServer);
|
|
71
|
+
const pathPortAssignmentData = await pathPortAssignmentFactory(deployId, router, confServer);
|
|
40
72
|
|
|
41
73
|
let errorPayloads = [];
|
|
42
74
|
if (options.sync === true) {
|