underpost 2.8.884 → 2.8.886
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.production +3 -0
- package/.github/workflows/ghpkg.ci.yml +1 -1
- package/.github/workflows/npmpkg.ci.yml +1 -1
- package/.github/workflows/publish.ci.yml +5 -5
- package/.github/workflows/pwa-microservices-template-page.cd.yml +1 -1
- package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
- package/CHANGELOG.md +145 -1
- package/Dockerfile +1 -1
- package/README.md +5 -121
- package/bin/build.js +18 -9
- package/bin/deploy.js +102 -197
- package/bin/file.js +4 -6
- package/cli.md +16 -12
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +54 -54
- package/manifests/deployment/dd-test-development/proxy.yaml +4 -4
- package/manifests/lxd/underpost-setup.sh +5 -5
- package/package.json +3 -3
- package/scripts/ssl.sh +164 -0
- package/src/cli/baremetal.js +7 -7
- package/src/cli/cloud-init.js +1 -1
- package/src/cli/cluster.js +31 -3
- package/src/cli/cron.js +9 -1
- package/src/cli/db.js +64 -2
- package/src/cli/deploy.js +189 -4
- package/src/cli/env.js +43 -0
- package/src/cli/fs.js +96 -2
- package/src/cli/image.js +15 -0
- package/src/cli/index.js +17 -4
- package/src/cli/monitor.js +33 -2
- package/src/cli/repository.js +95 -2
- package/src/cli/run.js +315 -51
- package/src/cli/script.js +32 -0
- package/src/cli/secrets.js +34 -0
- package/src/cli/test.js +42 -1
- package/src/client/components/core/Css.js +16 -8
- package/src/client/components/core/Docs.js +5 -13
- package/src/client/components/core/Modal.js +48 -29
- package/src/client/components/core/Router.js +6 -3
- package/src/client/components/core/Worker.js +205 -118
- package/src/client/components/core/windowGetDimensions.js +229 -162
- package/src/client/components/default/MenuDefault.js +1 -0
- package/src/client.dev.js +6 -3
- package/src/db/DataBaseProvider.js +65 -12
- package/src/db/mariadb/MariaDB.js +39 -6
- package/src/db/mongo/MongooseDB.js +51 -133
- package/src/index.js +2 -2
- package/src/mailer/EmailRender.js +58 -9
- package/src/mailer/MailerProvider.js +99 -25
- package/src/runtime/express/Express.js +32 -38
- package/src/runtime/lampp/Dockerfile +1 -1
- package/src/server/auth.js +9 -28
- package/src/server/backup.js +20 -0
- package/src/server/client-build-live.js +23 -12
- package/src/server/client-build.js +136 -91
- package/src/server/client-dev-server.js +35 -8
- package/src/server/client-icons.js +19 -0
- package/src/server/conf.js +543 -80
- package/src/server/dns.js +184 -42
- package/src/server/downloader.js +65 -24
- package/src/server/object-layer.js +260 -162
- package/src/server/peer.js +3 -9
- package/src/server/proxy.js +93 -76
- package/src/server/runtime.js +15 -21
- package/src/server/ssr.js +4 -4
- package/src/server/start.js +39 -0
- package/src/server/tls.js +251 -0
- package/src/server/valkey.js +11 -10
- package/src/ws/IoInterface.js +133 -39
- package/src/ws/IoServer.js +80 -31
- package/src/ws/core/core.ws.connection.js +50 -16
- package/src/ws/core/core.ws.emit.js +47 -8
- package/src/ws/core/core.ws.server.js +62 -10
- package/manifests/maas/lxd-preseed.yaml +0 -32
- package/src/server/ssl.js +0 -108
- /package/{manifests/maas → scripts}/device-scan.sh +0 -0
- /package/{manifests/maas → scripts}/gpu-diag.sh +0 -0
- /package/{manifests/maas → scripts}/maas-setup.sh +0 -0
- /package/{manifests/maas → scripts}/nat-iptables.sh +0 -0
- /package/{manifests/maas → scripts}/nvim.sh +0 -0
- /package/{manifests/maas → scripts}/snap-clean.sh +0 -0
- /package/{manifests/maas → scripts}/ssh-cluster-info.sh +0 -0
|
@@ -13,7 +13,7 @@ spec:
|
|
|
13
13
|
enableWebsockets: true
|
|
14
14
|
services:
|
|
15
15
|
- name: dd-test-development-blue-service
|
|
16
|
-
port:
|
|
16
|
+
port: 4041
|
|
17
17
|
weight: 100
|
|
18
18
|
|
|
19
19
|
- conditions:
|
|
@@ -21,7 +21,7 @@ spec:
|
|
|
21
21
|
enableWebsockets: true
|
|
22
22
|
services:
|
|
23
23
|
- name: dd-test-development-blue-service
|
|
24
|
-
port:
|
|
24
|
+
port: 4042
|
|
25
25
|
weight: 100
|
|
26
26
|
|
|
27
27
|
---
|
|
@@ -38,7 +38,7 @@ spec:
|
|
|
38
38
|
enableWebsockets: true
|
|
39
39
|
services:
|
|
40
40
|
- name: dd-test-development-blue-service
|
|
41
|
-
port:
|
|
41
|
+
port: 4043
|
|
42
42
|
weight: 100
|
|
43
43
|
|
|
44
44
|
- conditions:
|
|
@@ -46,6 +46,6 @@ spec:
|
|
|
46
46
|
enableWebsockets: true
|
|
47
47
|
services:
|
|
48
48
|
- name: dd-test-development-blue-service
|
|
49
|
-
port:
|
|
49
|
+
port: 4044
|
|
50
50
|
weight: 100
|
|
51
51
|
|
|
@@ -39,15 +39,15 @@ sudo dnf install -y tar bzip2 git epel-release
|
|
|
39
39
|
sudo dnf -y update
|
|
40
40
|
|
|
41
41
|
# --- NVM and Node.js Installation ---
|
|
42
|
-
echo "Installing NVM and Node.js
|
|
42
|
+
echo "Installing NVM and Node.js v24.10.0..."
|
|
43
43
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
|
|
44
44
|
|
|
45
45
|
# Load nvm for the current session
|
|
46
46
|
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
|
|
47
47
|
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
|
48
48
|
|
|
49
|
-
nvm install
|
|
50
|
-
nvm use
|
|
49
|
+
nvm install 24.10.0
|
|
50
|
+
nvm use 24.10.0
|
|
51
51
|
|
|
52
52
|
echo "
|
|
53
53
|
██╗░░░██╗███╗░░██╗██████╗░███████╗██████╗░██████╗░░█████╗░░██████╗████████╗
|
|
@@ -65,9 +65,9 @@ npm install -g underpost
|
|
|
65
65
|
|
|
66
66
|
# Ensure underpost executable is in PATH and has execute permissions
|
|
67
67
|
# Adjusting this for global npm install which usually handles permissions
|
|
68
|
-
# If you still face issues, ensure /root/.nvm/versions/node/
|
|
68
|
+
# If you still face issues, ensure /root/.nvm/versions/node/v24.10.0/bin is in your PATH
|
|
69
69
|
# For global installs, it's usually handled automatically.
|
|
70
|
-
# chmod +x /root/.nvm/versions/node/
|
|
70
|
+
# chmod +x /root/.nvm/versions/node/v24.10.0/bin/underpost # This might not be necessary for global npm installs
|
|
71
71
|
|
|
72
72
|
# --- Kernel Module for Bridge Filtering ---
|
|
73
73
|
# This is crucial for Kubernetes networking (CNI)
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"type": "module",
|
|
3
3
|
"main": "src/index.js",
|
|
4
4
|
"name": "underpost",
|
|
5
|
-
"version": "2.8.
|
|
5
|
+
"version": "2.8.886",
|
|
6
6
|
"description": "pwa api rest template",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"start": "env-cmd -f .env.production node --max-old-space-size=8192 src/server",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"http-proxy-middleware": "^2.0.6",
|
|
81
81
|
"ignore-walk": "^6.0.4",
|
|
82
82
|
"iovalkey": "^0.2.1",
|
|
83
|
-
"jimp": "^
|
|
83
|
+
"jimp": "^1.6.0",
|
|
84
84
|
"json-colorizer": "^2.2.2",
|
|
85
85
|
"jsonwebtoken": "^9.0.2",
|
|
86
86
|
"mariadb": "^3.2.2",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"mocha": "^10.8.2",
|
|
89
89
|
"mongoose": "^8.9.5",
|
|
90
90
|
"morgan": "^1.10.0",
|
|
91
|
-
"nodemailer": "^
|
|
91
|
+
"nodemailer": "^7.0.9",
|
|
92
92
|
"nodemon": "^3.0.1",
|
|
93
93
|
"peer": "^1.0.2",
|
|
94
94
|
"peerjs": "^1.5.2",
|
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
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cluster module for managing Kubernetes cluster initialization, configuration, and component deployment.
|
|
3
|
+
* @module src/cli/cluster.js
|
|
4
|
+
* @namespace UnderpostCluster
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
import { getNpmRootPath } from '../server/conf.js';
|
|
2
8
|
import { loggerFactory } from '../server/logger.js';
|
|
3
9
|
import { shellExec } from '../server/process.js';
|
|
@@ -9,6 +15,13 @@ import fs from 'fs-extra';
|
|
|
9
15
|
|
|
10
16
|
const logger = loggerFactory(import.meta);
|
|
11
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
|
+
*/
|
|
12
25
|
class UnderpostCluster {
|
|
13
26
|
static API = {
|
|
14
27
|
/**
|
|
@@ -45,6 +58,7 @@ class UnderpostCluster {
|
|
|
45
58
|
* @param {boolean} [options.config=false] - Apply general host configuration (SELinux, containerd, sysctl, firewalld).
|
|
46
59
|
* @param {boolean} [options.worker=false] - Configure as a worker node (for Kubeadm or K3s join).
|
|
47
60
|
* @param {boolean} [options.chown=false] - Set up kubectl configuration for the current user.
|
|
61
|
+
* @memberof UnderpostCluster
|
|
48
62
|
*/
|
|
49
63
|
async init(
|
|
50
64
|
podName,
|
|
@@ -460,6 +474,7 @@ EOF
|
|
|
460
474
|
* are applied for a healthy Kubernetes environment. It explicitly avoids
|
|
461
475
|
* iptables flushing commands to prevent conflicts with Kubernetes' own network management.
|
|
462
476
|
* @param {string} underpostRoot - The root directory of the underpost project.
|
|
477
|
+
* @memberof UnderpostCluster
|
|
463
478
|
*/
|
|
464
479
|
config(options = { underpostRoot: '.' }) {
|
|
465
480
|
const { underpostRoot } = options;
|
|
@@ -512,7 +527,7 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`,
|
|
|
512
527
|
|
|
513
528
|
// shellExec(`sudo sysctl --system`); // Apply sysctl changes immediately
|
|
514
529
|
// Apply NAT iptables rules.
|
|
515
|
-
shellExec(`${underpostRoot}/
|
|
530
|
+
shellExec(`${underpostRoot}/scripts/nat-iptables.sh`, { silent: true });
|
|
516
531
|
|
|
517
532
|
// Disable firewalld (common cause of network issues in Kubernetes)
|
|
518
533
|
shellExec(`sudo systemctl stop firewalld || true`); // Stop if running
|
|
@@ -523,6 +538,7 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`,
|
|
|
523
538
|
* @method chown
|
|
524
539
|
* @description Sets up kubectl configuration for the current user based on the cluster type.
|
|
525
540
|
* @param {string} clusterType - The type of Kubernetes cluster ('kubeadm', 'k3s', or 'kind').
|
|
541
|
+
* @memberof UnderpostCluster
|
|
526
542
|
*/
|
|
527
543
|
chown(clusterType) {
|
|
528
544
|
console.log(`Setting up kubectl configuration for ${clusterType} cluster...`);
|
|
@@ -559,6 +575,7 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`,
|
|
|
559
575
|
* in coredns) by restoring SELinux security contexts and safely cleaning up cluster artifacts.
|
|
560
576
|
* @param {object} [options] - Configuration options for the reset.
|
|
561
577
|
* @param {string} [options.underpostRoot] - The root path of the underpost project.
|
|
578
|
+
* @memberof UnderpostCluster
|
|
562
579
|
*/
|
|
563
580
|
async safeReset(options = { underpostRoot: '.' }) {
|
|
564
581
|
logger.info('Starting a safe and comprehensive reset of Kubernetes and container environments...');
|
|
@@ -653,8 +670,8 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`,
|
|
|
653
670
|
shellExec('sudo iptables -F || true');
|
|
654
671
|
shellExec('sudo iptables -t nat -F || true');
|
|
655
672
|
// Restore iptables rules
|
|
656
|
-
shellExec(`chmod +x ${options.underpostRoot}/
|
|
657
|
-
shellExec(`${options.underpostRoot}/
|
|
673
|
+
shellExec(`chmod +x ${options.underpostRoot}/scripts/nat-iptables.sh`);
|
|
674
|
+
shellExec(`${options.underpostRoot}/scripts/nat-iptables.sh`, { silent: true });
|
|
658
675
|
shellExec('sudo ip link del cni0 || true');
|
|
659
676
|
shellExec('sudo ip link del flannel.1 || true');
|
|
660
677
|
|
|
@@ -672,6 +689,13 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`,
|
|
|
672
689
|
}
|
|
673
690
|
},
|
|
674
691
|
|
|
692
|
+
/**
|
|
693
|
+
* @method getResourcesCapacity
|
|
694
|
+
* @description Retrieves the capacity of resources (CPU and memory) for a specific node in the cluster.
|
|
695
|
+
* @param {string} [node=os.hostname()] - The node to query. Defaults to the current host.
|
|
696
|
+
* @returns {object} An object containing the CPU and memory capacity of the node.
|
|
697
|
+
* @memberof UnderpostCluster
|
|
698
|
+
*/
|
|
675
699
|
getResourcesCapacity(node) {
|
|
676
700
|
const resources = {};
|
|
677
701
|
const nodeName = node ?? os.hostname();
|
|
@@ -698,9 +722,11 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`,
|
|
|
698
722
|
|
|
699
723
|
return resources;
|
|
700
724
|
},
|
|
725
|
+
|
|
701
726
|
/**
|
|
702
727
|
* @method initHost
|
|
703
728
|
* @description Installs essential host-level prerequisites for Kubernetes (Docker, Podman, Kind, Kubeadm, Helm).
|
|
729
|
+
* @memberof UnderpostCluster
|
|
704
730
|
*/
|
|
705
731
|
initHost() {
|
|
706
732
|
const archData = UnderpostBaremetal.API.getHostArch();
|
|
@@ -738,10 +764,12 @@ EOF`);
|
|
|
738
764
|
shellExec(`sudo rm -rf get_helm.sh`);
|
|
739
765
|
console.log('Host prerequisites installed successfully.');
|
|
740
766
|
},
|
|
767
|
+
|
|
741
768
|
/**
|
|
742
769
|
* @method uninstallHost
|
|
743
770
|
* @description Uninstalls all host components installed by initHost.
|
|
744
771
|
* This includes Docker, Podman, Kind, Kubeadm, Kubelet, Kubectl, and Helm.
|
|
772
|
+
* @memberof UnderpostCluster
|
|
745
773
|
*/
|
|
746
774
|
uninstallHost() {
|
|
747
775
|
console.log('Uninstalling host components: Docker, Podman, Kind, Kubeadm, Kubelet, Kubectl, Helm.');
|
package/src/cli/cron.js
CHANGED
|
@@ -17,7 +17,7 @@ const logger = loggerFactory(import.meta);
|
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* UnderpostCron main module methods
|
|
20
|
-
* @class
|
|
20
|
+
* @class UnderpostCron
|
|
21
21
|
* @memberof UnderpostCron
|
|
22
22
|
*/
|
|
23
23
|
class UnderpostCron {
|
|
@@ -71,6 +71,14 @@ class UnderpostCron {
|
|
|
71
71
|
if (UnderpostCron.JOB[jobId]) await UnderpostCron.JOB[jobId].callback(deployList, options);
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Get the related deploy id for the given job id
|
|
77
|
+
* @static
|
|
78
|
+
* @param {String} jobId - The job id
|
|
79
|
+
* @return {String} The related deploy id
|
|
80
|
+
* @memberof UnderpostCron
|
|
81
|
+
*/
|
|
74
82
|
getRelatedDeployId(jobId) {
|
|
75
83
|
switch (jobId) {
|
|
76
84
|
case 'dns':
|
package/src/cli/db.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UnderpostDB CLI index module
|
|
3
|
+
* @module src/cli/db.js
|
|
4
|
+
* @namespace UnderpostDB
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
import { mergeFile, splitFileFactory } from '../server/conf.js';
|
|
2
8
|
import { loggerFactory } from '../server/logger.js';
|
|
3
9
|
import { shellExec } from '../server/process.js';
|
|
@@ -9,8 +15,36 @@ import { loadReplicas, pathPortAssignmentFactory } from '../server/conf.js';
|
|
|
9
15
|
|
|
10
16
|
const logger = loggerFactory(import.meta);
|
|
11
17
|
|
|
18
|
+
/**
|
|
19
|
+
* @class UnderpostDB
|
|
20
|
+
* @description Manages database operations and backups.
|
|
21
|
+
* This class provides a set of static methods to handle database operations,
|
|
22
|
+
* including importing and exporting data, managing database backups, and
|
|
23
|
+
* handling database connections for different providers (e.g., MariaDB, MongoDB).
|
|
24
|
+
* @memberof UnderpostDB
|
|
25
|
+
*/
|
|
12
26
|
class UnderpostDB {
|
|
13
27
|
static API = {
|
|
28
|
+
/**
|
|
29
|
+
* @method callback
|
|
30
|
+
* @description Initiates a database backup workflow based on the provided options.
|
|
31
|
+
* This method orchestrates the backup process for multiple deployments, handling
|
|
32
|
+
* database connections, backup storage, and optional Git integration for version control.
|
|
33
|
+
* @param {string} [deployList='default'] - List of deployment IDs to include in the backup.
|
|
34
|
+
* @param {object} [options] - An object containing boolean flags for various operations.
|
|
35
|
+
* @param {boolean} [options.import=false] - Flag to import data from a backup.
|
|
36
|
+
* @param {boolean} [options.export=false] - Flag to export data to a backup.
|
|
37
|
+
* @param {string} [options.podName=false] - The name of the Kubernetes pod to use for database operations.
|
|
38
|
+
* @param {string} [options.ns=false] - The namespace to use for database operations.
|
|
39
|
+
* @param {string} [options.collections=''] - Comma-separated list of collections to include in the backup.
|
|
40
|
+
* @param {string} [options.outPath=''] - Output path for the backup file.
|
|
41
|
+
* @param {boolean} [options.drop=false] - Flag to drop the database before importing.
|
|
42
|
+
* @param {boolean} [options.preserveUUID=false] - Flag to preserve UUIDs during import.
|
|
43
|
+
* @param {boolean} [options.git=false] - Flag to enable Git integration for version control.
|
|
44
|
+
* @param {string} [options.hosts=''] - Comma-separated list of hosts to include in the backup.
|
|
45
|
+
* @param {string} [options.paths=''] - Comma-separated list of paths to include in the backup.
|
|
46
|
+
* @memberof UnderpostDB
|
|
47
|
+
*/
|
|
14
48
|
async callback(
|
|
15
49
|
deployList = 'default',
|
|
16
50
|
options = {
|
|
@@ -200,6 +234,17 @@ class UnderpostDB {
|
|
|
200
234
|
}
|
|
201
235
|
}
|
|
202
236
|
},
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* @method clusterMetadataFactory
|
|
240
|
+
* @description Creates a cluster metadata object for the specified deployment.
|
|
241
|
+
* This method loads database configuration and initializes a cluster metadata object
|
|
242
|
+
* using the provided deployment ID, host, and path.
|
|
243
|
+
* @param {string} [deployId=process.env.DEFAULT_DEPLOY_ID] - The deployment ID to use.
|
|
244
|
+
* @param {string} [host=process.env.DEFAULT_DEPLOY_HOST] - The host to use.
|
|
245
|
+
* @param {string} [path=process.env.DEFAULT_DEPLOY_PATH] - The path to use.
|
|
246
|
+
* @memberof UnderpostDB
|
|
247
|
+
*/
|
|
203
248
|
async clusterMetadataFactory(
|
|
204
249
|
deployId = process.env.DEFAULT_DEPLOY_ID,
|
|
205
250
|
host = process.env.DEFAULT_DEPLOY_HOST,
|
|
@@ -227,10 +272,9 @@ class UnderpostDB {
|
|
|
227
272
|
if (!deployId) continue;
|
|
228
273
|
const confServer = loadReplicas(
|
|
229
274
|
JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8')),
|
|
230
|
-
'proxy',
|
|
231
275
|
);
|
|
232
276
|
const router = await UnderpostDeploy.API.routerFactory(deployId, env);
|
|
233
|
-
const pathPortAssignmentData = pathPortAssignmentFactory(router, confServer);
|
|
277
|
+
const pathPortAssignmentData = await pathPortAssignmentFactory(deployId, router, confServer);
|
|
234
278
|
|
|
235
279
|
for (const host of Object.keys(confServer)) {
|
|
236
280
|
for (const { path, port } of pathPortAssignmentData[host]) {
|
|
@@ -298,6 +342,24 @@ class UnderpostDB {
|
|
|
298
342
|
}
|
|
299
343
|
await DataBaseProvider.instance[`${host}${path}`].mongoose.close();
|
|
300
344
|
},
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* @method clusterMetadataBackupCallback
|
|
348
|
+
* @description Handles the backup of cluster metadata for the specified deployment.
|
|
349
|
+
* This method orchestrates the backup process for cluster metadata, including
|
|
350
|
+
* instances and crons, and handles optional Git integration for version control.
|
|
351
|
+
* @param {string} [deployId=process.env.DEFAULT_DEPLOY_ID] - The deployment ID to use.
|
|
352
|
+
* @param {string} [host=process.env.DEFAULT_DEPLOY_HOST] - The host to use.
|
|
353
|
+
* @param {string} [path=process.env.DEFAULT_DEPLOY_PATH] - The path to use.
|
|
354
|
+
* @param {object} [options] - An object containing boolean flags for various operations.
|
|
355
|
+
* @param {boolean} [options.generate=false] - Flag to generate cluster metadata.
|
|
356
|
+
* @param {boolean} [options.itc=false] - Flag to enable Git integration for version control.
|
|
357
|
+
* @param {boolean} [options.import=false] - Flag to import data from a backup.
|
|
358
|
+
* @param {boolean} [options.export=false] - Flag to export data to a backup.
|
|
359
|
+
* @param {boolean} [options.instances=false] - Flag to backup instances.
|
|
360
|
+
* @param {boolean} [options.crons=false] - Flag to backup crons.
|
|
361
|
+
* @memberof UnderpostDB
|
|
362
|
+
*/
|
|
301
363
|
clusterMetadataBackupCallback(
|
|
302
364
|
deployId = process.env.DEFAULT_DEPLOY_ID,
|
|
303
365
|
host = process.env.DEFAULT_DEPLOY_HOST,
|