cyberia 3.2.9 → 3.2.12
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/.github/workflows/engine-cyberia.cd.yml +6 -0
- package/.github/workflows/npmpkg.ci.yml +1 -0
- package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
- package/.github/workflows/release.cd.yml +1 -0
- package/.vscode/extensions.json +9 -9
- package/.vscode/settings.json +20 -4
- package/CHANGELOG.md +213 -1
- package/CLI-HELP.md +92 -23
- package/README.md +190 -348
- package/bin/build.js +24 -8
- package/bin/build.template.js +187 -0
- package/bin/cyberia.js +229 -52
- package/bin/deploy.js +12 -2
- package/bin/index.js +229 -52
- package/bump.config.js +26 -0
- package/conf.js +130 -24
- package/deployment.yaml +4 -2
- package/hardhat/package-lock.json +113 -144
- package/hardhat/package.json +4 -3
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +4 -2
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +4 -2
- package/manifests/kind-config-dev.yaml +8 -0
- package/manifests/lxd/lxd-admin-profile.yaml +12 -3
- package/manifests/mongodb/pv-pvc.yaml +44 -8
- package/manifests/mongodb/statefulset.yaml +55 -68
- package/manifests/mongodb-4.4/headless-service.yaml +10 -0
- package/manifests/mongodb-4.4/kustomization.yaml +3 -1
- package/manifests/mongodb-4.4/mongodb-nodeport.yaml +17 -0
- package/manifests/mongodb-4.4/pv-pvc.yaml +10 -14
- package/manifests/mongodb-4.4/statefulset.yaml +79 -0
- package/manifests/mongodb-4.4/storage-class.yaml +9 -0
- package/manifests/valkey/statefulset.yaml +1 -1
- package/manifests/valkey/valkey-nodeport.yaml +17 -0
- package/package.json +27 -15
- package/scripts/ipxe-setup.sh +52 -49
- package/scripts/k3s-node-setup.sh +81 -46
- package/scripts/lxd-vm-setup.sh +193 -8
- package/scripts/maas-nat-firewalld.sh +145 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +38 -33
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +16 -16
- package/src/api/core/core.router.js +19 -14
- package/src/api/core/core.service.js +5 -5
- package/src/api/crypto/crypto.router.js +18 -12
- package/src/api/crypto/crypto.service.js +3 -3
- package/src/api/cyberia-action/cyberia-action.model.js +1 -1
- package/src/api/cyberia-action/cyberia-action.router.js +22 -18
- package/src/api/cyberia-action/cyberia-action.service.js +5 -5
- package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +74 -0
- package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +99 -0
- package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +98 -0
- package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +152 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +25 -20
- package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +6 -6
- package/src/api/cyberia-entity/cyberia-entity.router.js +22 -18
- package/src/api/cyberia-entity/cyberia-entity.service.js +5 -5
- package/src/api/cyberia-instance/cyberia-fallback-world.js +79 -4
- package/src/api/cyberia-instance/cyberia-instance.router.js +57 -52
- package/src/api/cyberia-instance/cyberia-instance.service.js +10 -10
- package/src/api/cyberia-instance/cyberia-world-generator.js +3 -3
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +14 -48
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +22 -18
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +5 -5
- package/src/api/cyberia-map/cyberia-map.router.js +35 -30
- package/src/api/cyberia-map/cyberia-map.service.js +7 -7
- package/src/api/cyberia-quest/cyberia-quest.model.js +1 -1
- package/src/api/cyberia-quest/cyberia-quest.router.js +22 -18
- package/src/api/cyberia-quest/cyberia-quest.service.js +5 -5
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +22 -18
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +5 -5
- package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +451 -0
- package/src/api/default/default.router.js +22 -18
- package/src/api/default/default.service.js +5 -5
- package/src/api/document/document.router.js +28 -23
- package/src/api/document/document.service.js +100 -23
- package/src/api/file/file.router.js +19 -13
- package/src/api/file/file.service.js +9 -7
- package/src/api/instance/instance.router.js +29 -24
- package/src/api/instance/instance.service.js +6 -6
- package/src/api/ipfs/ipfs.router.js +21 -16
- package/src/api/ipfs/ipfs.service.js +8 -8
- package/src/api/object-layer/object-layer.router.js +512 -507
- package/src/api/object-layer/object-layer.service.js +17 -14
- package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +22 -18
- package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +5 -5
- package/src/api/test/test.router.js +17 -12
- package/src/api/types.js +24 -0
- package/src/api/user/guest.service.js +5 -4
- package/src/api/user/user.router.js +297 -288
- package/src/api/user/user.service.js +100 -35
- package/src/cli/baremetal.js +132 -101
- package/src/cli/cluster.js +700 -232
- package/src/cli/db.js +59 -60
- package/src/cli/deploy.js +216 -137
- package/src/cli/fs.js +13 -3
- package/src/cli/index.js +80 -15
- package/src/cli/ipfs.js +4 -6
- package/src/cli/kubectl.js +4 -1
- package/src/cli/lxd.js +1099 -223
- package/src/cli/monitor.js +9 -3
- package/src/cli/release.js +334 -140
- package/src/cli/repository.js +68 -23
- package/src/cli/run.js +193 -49
- package/src/cli/secrets.js +11 -2
- package/src/cli/test.js +9 -3
- package/src/client/Default.index.js +9 -3
- package/src/client/components/core/Auth.js +5 -0
- package/src/client/components/core/ClientEvents.js +76 -0
- package/src/client/components/core/EventBus.js +4 -0
- package/src/client/components/core/Modal.js +82 -41
- package/src/client/components/core/PanelForm.js +56 -52
- package/src/client/components/core/Worker.js +162 -363
- package/src/client/components/cyberia/MapEngineCyberia.js +1 -1
- package/src/client/components/cyberia/SharedDefaultsCyberia.js +330 -0
- package/src/client/public/cyberia-docs/ARCHITECTURE.md +50 -410
- package/src/client/public/cyberia-docs/CYBERIA-CLI.md +114 -327
- package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +200 -222
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +203 -185
- package/src/client/public/cyberia-docs/CYBERIA.md +259 -0
- package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +2 -2
- package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
- package/src/client/public/cyberia-docs/UNDERPOST-PLATFORM.md +106 -0
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
- package/src/client/services/cyberia-client-hints/cyberia-client-hints.service.js +99 -0
- package/src/client/ssr/views/CyberiaServerMetrics.js +982 -0
- package/src/client/sw/core.sw.js +174 -112
- package/src/db/DataBaseProvider.js +115 -15
- package/src/db/mariadb/MariaDB.js +2 -1
- package/src/db/mongo/MongoBootstrap.js +657 -0
- package/src/db/mongo/MongooseDB.js +129 -21
- package/src/grpc/cyberia/grpc-server.js +25 -57
- package/src/index.js +1 -1
- package/src/runtime/cyberia-client/Dockerfile +24 -3
- package/src/runtime/cyberia-client/Dockerfile.dev +82 -0
- package/src/runtime/cyberia-server/Dockerfile +29 -4
- package/src/runtime/cyberia-server/Dockerfile.dev +71 -0
- package/src/runtime/express/Express.js +2 -2
- package/src/runtime/wp/Wp.js +8 -5
- package/src/server/auth.js +2 -2
- package/src/server/client-build-docs.js +1 -1
- package/src/server/client-build.js +94 -129
- package/src/server/conf.js +86 -83
- package/src/server/process.js +180 -19
- package/src/server/proxy.js +9 -2
- package/src/server/runtime.js +1 -1
- package/src/server/start.js +17 -5
- package/src/server/valkey.js +2 -0
- package/src/ws/IoInterface.js +16 -16
- package/src/ws/core/channels/core.ws.chat.js +11 -11
- package/src/ws/core/channels/core.ws.mailer.js +29 -29
- package/src/ws/core/channels/core.ws.stream.js +19 -19
- package/src/ws/core/core.ws.connection.js +8 -8
- package/src/ws/core/core.ws.server.js +6 -5
- package/src/ws/default/channels/default.ws.main.js +10 -10
- package/src/ws/default/default.ws.connection.js +4 -4
- package/src/ws/default/default.ws.server.js +4 -3
- package/bin/file.js +0 -202
- package/bin/vs.js +0 -74
- package/bin/zed.js +0 -84
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +0 -574
- package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +0 -467
- package/src/client/ssr/email/DefaultRecoverEmail.js +0 -21
- package/src/client/ssr/email/DefaultVerifyEmail.js +0 -17
- package/src/client/ssr/pages/CyberiaServerMetrics.js +0 -461
- /package/src/client/ssr/{offline → views}/Maintenance.js +0 -0
- /package/src/client/ssr/{offline → views}/NoNetworkConnection.js +0 -0
- /package/src/client/ssr/{pages → views}/Test.js +0 -0
package/scripts/ipxe-setup.sh
CHANGED
|
@@ -14,39 +14,39 @@ REBUILD=false
|
|
|
14
14
|
EMBED_SCRIPT=""
|
|
15
15
|
|
|
16
16
|
while [[ $# -gt 0 ]]; do
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
17
|
+
case $1 in
|
|
18
|
+
--rebuild)
|
|
19
|
+
REBUILD=true
|
|
20
|
+
shift # past argument
|
|
21
|
+
;;
|
|
22
|
+
--target-arch)
|
|
23
|
+
case "$2" in
|
|
24
|
+
arm64)
|
|
25
|
+
TARGET_ARCH="aarch64"
|
|
26
|
+
;;
|
|
27
|
+
amd64)
|
|
28
|
+
TARGET_ARCH="x86_64"
|
|
29
|
+
;;
|
|
30
|
+
*)
|
|
31
|
+
echo "Error: Unsupported architecture '$2'. Use 'arm64' or 'amd64'."
|
|
32
|
+
exit 1
|
|
33
|
+
;;
|
|
34
|
+
esac
|
|
35
|
+
shift # past argument
|
|
36
|
+
shift # past value
|
|
37
|
+
;;
|
|
38
|
+
--embed-script)
|
|
39
|
+
EMBED_SCRIPT="$2"
|
|
40
|
+
shift # past argument
|
|
41
|
+
shift # past value
|
|
42
|
+
;;
|
|
30
43
|
*)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
;;
|
|
38
|
-
--embed-script)
|
|
39
|
-
EMBED_SCRIPT="$2"
|
|
40
|
-
shift # past argument
|
|
41
|
-
shift # past value
|
|
42
|
-
;;
|
|
43
|
-
*)
|
|
44
|
-
if [ -z "$TARGET_DIR_ARG" ]; then
|
|
45
|
-
TARGET_DIR_ARG="$1"
|
|
46
|
-
fi
|
|
47
|
-
shift # past argument
|
|
48
|
-
;;
|
|
49
|
-
esac
|
|
44
|
+
if [ -z "$TARGET_DIR_ARG" ]; then
|
|
45
|
+
TARGET_DIR_ARG="$1"
|
|
46
|
+
fi
|
|
47
|
+
shift # past argument
|
|
48
|
+
;;
|
|
49
|
+
esac
|
|
50
50
|
done
|
|
51
51
|
|
|
52
52
|
# Use argument if provided, otherwise env var, otherwise current dir
|
|
@@ -64,7 +64,7 @@ echo "Embed Script: ${EMBED_SCRIPT:-none}"
|
|
|
64
64
|
# Determine iPXE build target based on requested architecture
|
|
65
65
|
if [ "$TARGET_ARCH" = "aarch64" ]; then
|
|
66
66
|
BUILD_TARGET="bin-arm64-efi/ipxe.efi"
|
|
67
|
-
elif [ "$TARGET_ARCH" = "x86_64" ]; then
|
|
67
|
+
elif [ "$TARGET_ARCH" = "x86_64" ]; then
|
|
68
68
|
BUILD_TARGET="bin-x86_64-efi/ipxe.efi"
|
|
69
69
|
else
|
|
70
70
|
echo "Error: Unsupported target architecture '$TARGET_ARCH'"
|
|
@@ -79,49 +79,50 @@ DO_BUILD=false
|
|
|
79
79
|
|
|
80
80
|
if [ "$REBUILD" = true ]; then
|
|
81
81
|
DO_BUILD=true
|
|
82
|
-
elif [ ! -f "$COMPILED_SRC_PATH" ]; then
|
|
82
|
+
elif [ ! -f "$COMPILED_SRC_PATH" ]; then
|
|
83
83
|
echo "Binary not found at $COMPILED_SRC_PATH. Initiating build..."
|
|
84
84
|
DO_BUILD=true
|
|
85
|
+
|
|
85
86
|
else
|
|
86
|
-
echo "Binary found at $COMPILED_SRC_PATH. Skipping build."
|
|
87
|
+
echo "Binary found at $COMPILED_SRC_PATH with matching embedded script. Skipping build."
|
|
87
88
|
fi
|
|
88
89
|
|
|
89
90
|
if [ "$DO_BUILD" = true ]; then
|
|
90
|
-
|
|
91
|
+
|
|
91
92
|
# Helper function for package manager
|
|
92
93
|
if command -v dnf &> /dev/null; then
|
|
93
94
|
PKG_MGR="dnf"
|
|
94
95
|
else
|
|
95
96
|
PKG_MGR="yum"
|
|
96
97
|
fi
|
|
97
|
-
|
|
98
|
+
|
|
98
99
|
# --- 2. Install Dependencies (RHEL/CentOS/Fedora) ---
|
|
99
100
|
echo ""
|
|
100
101
|
echo "--- Installing Build Dependencies ---"
|
|
101
102
|
echo "Requesting sudo permissions..."
|
|
102
|
-
|
|
103
|
+
|
|
103
104
|
COMMON_PKGS="git make binutils-devel xz-devel perl"
|
|
104
|
-
|
|
105
|
+
|
|
105
106
|
# Logic to determine if we need native or cross-compilers
|
|
106
107
|
if [ "$HOST_ARCH" = "$TARGET_ARCH" ]; then
|
|
107
108
|
# Native compilation
|
|
108
109
|
echo "Architecture match ($HOST_ARCH). Installing native GCC..."
|
|
109
110
|
sudo $PKG_MGR install -y $COMMON_PKGS gcc
|
|
110
111
|
CROSS_COMPILE_PREFIX=""
|
|
111
|
-
|
|
112
|
-
|
|
112
|
+
|
|
113
|
+
elif [ "$HOST_ARCH" = "x86_64" ] && [ "$TARGET_ARCH" = "aarch64" ]; then
|
|
113
114
|
# Cross-compilation: x86_64 host -> aarch64 target
|
|
114
115
|
echo "Cross-compiling for $TARGET_ARCH on $HOST_ARCH..."
|
|
115
116
|
# Note: Ensure EPEL repo is enabled on RHEL/CentOS for this package
|
|
116
117
|
sudo $PKG_MGR install -y $COMMON_PKGS gcc-aarch64-linux-gnu
|
|
117
118
|
CROSS_COMPILE_PREFIX="aarch64-linux-gnu-"
|
|
118
|
-
|
|
119
|
+
|
|
119
120
|
else
|
|
120
121
|
echo "Error: No automated path defined for Host: $HOST_ARCH -> Target: $TARGET_ARCH"
|
|
121
122
|
echo "You may need to install specific cross-compilers manually."
|
|
122
123
|
exit 1
|
|
123
124
|
fi
|
|
124
|
-
|
|
125
|
+
|
|
125
126
|
# --- 3. Clone iPXE Source ---
|
|
126
127
|
echo ""
|
|
127
128
|
echo "--- Downloading iPXE Source Code ---"
|
|
@@ -133,15 +134,15 @@ if [ "$DO_BUILD" = true ]; then
|
|
|
133
134
|
git clone https://github.com/ipxe/ipxe.git $IPXE_SRC_DIR
|
|
134
135
|
cd $IPXE_SRC_DIR
|
|
135
136
|
fi
|
|
136
|
-
|
|
137
|
+
|
|
137
138
|
# --- 4. Compile the Binary ---
|
|
138
139
|
echo ""
|
|
139
140
|
echo "--- Compiling $EFI_FILENAME for $TARGET_ARCH ---"
|
|
140
141
|
cd src
|
|
141
|
-
|
|
142
|
+
|
|
142
143
|
# Clean previous builds to ensure no arch mismatch
|
|
143
144
|
make clean
|
|
144
|
-
|
|
145
|
+
|
|
145
146
|
# Build with embedded script if provided
|
|
146
147
|
if [ -n "$EMBED_SCRIPT" ]; then
|
|
147
148
|
echo "Embedding script into iPXE binary..."
|
|
@@ -155,7 +156,7 @@ if [ "$DO_BUILD" = true ]; then
|
|
|
155
156
|
echo "Running make for target: $BUILD_TARGET..."
|
|
156
157
|
make CROSS_COMPILE=$CROSS_COMPILE_PREFIX $BUILD_TARGET
|
|
157
158
|
fi
|
|
158
|
-
|
|
159
|
+
|
|
159
160
|
if [ $? -ne 0 ]; then
|
|
160
161
|
echo "Error: Compilation failed."
|
|
161
162
|
if [ -n "$CROSS_COMPILE_PREFIX" ]; then
|
|
@@ -163,6 +164,8 @@ if [ "$DO_BUILD" = true ]; then
|
|
|
163
164
|
fi
|
|
164
165
|
exit 1
|
|
165
166
|
fi
|
|
167
|
+
|
|
168
|
+
|
|
166
169
|
fi
|
|
167
170
|
|
|
168
171
|
# --- 5. Deploy Binary ---
|
|
@@ -176,10 +179,10 @@ if [ -f "$COMPILED_SRC_PATH" ]; then
|
|
|
176
179
|
echo "Creating target directory: $TARGET_DIR"
|
|
177
180
|
mkdir -p "$TARGET_DIR"
|
|
178
181
|
fi
|
|
179
|
-
|
|
182
|
+
|
|
180
183
|
echo "Copying $COMPILED_SRC_PATH to $TARGET_DIR/$EFI_FILENAME..."
|
|
181
184
|
cp "$COMPILED_SRC_PATH" "$TARGET_DIR/$EFI_FILENAME"
|
|
182
|
-
|
|
185
|
+
|
|
183
186
|
if [ $? -eq 0 ]; then
|
|
184
187
|
echo "✓ Success!"
|
|
185
188
|
echo "---------------------------------------------------"
|
|
@@ -1,39 +1,70 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
set -
|
|
2
|
+
set -euo pipefail
|
|
3
3
|
|
|
4
4
|
# ---------------------------------------------------------------------------
|
|
5
5
|
# Underpost K3s Node Setup
|
|
6
|
+
#
|
|
7
|
+
# This script runs INSIDE an LXD VM. It assumes the host has already mirrored
|
|
8
|
+
# the project source into $ENGINE_ROOT (default /home/dd/engine) via the
|
|
9
|
+
# `underpost lxd [vm-id] --vm-init` flow in `src/cli/lxd.js`. There is no
|
|
10
|
+
# fallback to a globally installed `underpost`: every operational command
|
|
11
|
+
# resolves from the local project so the latest local changes are always what
|
|
12
|
+
# runs in the VM.
|
|
13
|
+
#
|
|
6
14
|
# Usage:
|
|
7
|
-
# --
|
|
8
|
-
# --
|
|
9
|
-
# --
|
|
10
|
-
# --
|
|
15
|
+
# --engine-root=<path> Path to the mirrored engine source (default: /home/dd/engine)
|
|
16
|
+
# --control Initialize as K3s control plane node (default)
|
|
17
|
+
# --worker Initialize as K3s worker node
|
|
18
|
+
# --control-ip=<ip> Control plane IP (required for --worker)
|
|
19
|
+
# --token=<token> K3s node token (required for --worker)
|
|
11
20
|
# ---------------------------------------------------------------------------
|
|
12
21
|
|
|
13
22
|
ROLE="control"
|
|
14
23
|
CONTROL_IP=""
|
|
15
24
|
K3S_TOKEN=""
|
|
25
|
+
ENGINE_ROOT="/home/dd/engine"
|
|
16
26
|
|
|
17
27
|
for arg in "$@"; do
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
28
|
+
case $arg in
|
|
29
|
+
--worker) ROLE="worker" ;;
|
|
30
|
+
--control) ROLE="control" ;;
|
|
31
|
+
--control-ip=*) CONTROL_IP="${arg#*=}" ;;
|
|
32
|
+
--token=*) K3S_TOKEN="${arg#*=}" ;;
|
|
33
|
+
--engine-root=*) ENGINE_ROOT="${arg#*=}" ;;
|
|
34
|
+
esac
|
|
24
35
|
done
|
|
36
|
+
|
|
37
|
+
# Fail fast if the bootstrap step did not run / left the directory empty.
|
|
38
|
+
# Split into two checks so `ls -A` only runs against a path that exists; this
|
|
39
|
+
# avoids needing an error-swallowing redirect.
|
|
40
|
+
if [ ! -d "$ENGINE_ROOT" ]; then
|
|
41
|
+
echo "ERROR: engine source directory $ENGINE_ROOT does not exist."
|
|
42
|
+
echo "The LXD [vm-id] --vm-init flow must mirror the project here before running this script."
|
|
43
|
+
exit 1
|
|
44
|
+
fi
|
|
45
|
+
if [ -z "$(ls -A "$ENGINE_ROOT")" ]; then
|
|
46
|
+
echo "ERROR: engine source directory $ENGINE_ROOT is empty."
|
|
47
|
+
echo "The LXD [vm-id] --vm-init flow must mirror the project here before running this script."
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
|
|
25
51
|
# ---------------------------------------------------------------------------
|
|
26
|
-
# NVM and Node.js
|
|
52
|
+
# NVM and Node.js — required for `node bin ...` entrypoints
|
|
27
53
|
# ---------------------------------------------------------------------------
|
|
28
|
-
echo "Installing NVM and Node.js v24.
|
|
54
|
+
echo "Installing NVM and Node.js v24.15.0..."
|
|
29
55
|
|
|
30
56
|
curl -o- https://cdn.jsdelivr.net/gh/nvm-sh/nvm@v0.40.1/install.sh | bash
|
|
31
57
|
|
|
32
58
|
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
|
|
59
|
+
# shellcheck disable=SC1090
|
|
33
60
|
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
|
34
61
|
|
|
35
62
|
nvm install 24.15.0
|
|
36
63
|
nvm use 24.15.0
|
|
64
|
+
nvm alias default 24.15.0
|
|
65
|
+
ln -sf "$(command -v node)" /usr/local/bin/node
|
|
66
|
+
ln -sf "$(command -v npm)" /usr/local/bin/npm
|
|
67
|
+
ln -sf "$(command -v npx)" /usr/local/bin/npx
|
|
37
68
|
|
|
38
69
|
echo "
|
|
39
70
|
██╗░░░██╗███╗░░██╗██████╗░███████╗██████╗░██████╗░░█████╗░░██████╗████████╗
|
|
@@ -43,47 +74,51 @@ echo "
|
|
|
43
74
|
╚██████╔╝██║░╚███║██████╔╝███████╗██║░░██║██║░░░░░╚█████╔╝██████╔╝░░░██║░░░
|
|
44
75
|
░╚═════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚═╝░░░░░░╚════╝░╚═════╝░░░░╚═╝░░░
|
|
45
76
|
|
|
46
|
-
|
|
77
|
+
Bringing up underpost VM node from $ENGINE_ROOT (role=$ROLE)
|
|
47
78
|
"
|
|
48
79
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
cd /home/dd/engine
|
|
52
|
-
|
|
53
|
-
echo "Applying host configuration..."
|
|
80
|
+
cd "$ENGINE_ROOT"
|
|
54
81
|
|
|
82
|
+
# Install JS deps and generate secrets using the local engine entrypoint only.
|
|
55
83
|
npm install
|
|
56
|
-
|
|
57
84
|
node bin run secret
|
|
58
85
|
|
|
59
|
-
node bin cluster --dev --config
|
|
60
|
-
|
|
61
86
|
if [ "$ROLE" = "control" ]; then
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
echo "
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
87
|
+
echo "Installing underpost CLI..."
|
|
88
|
+
npm install -g underpost
|
|
89
|
+
underpost --version
|
|
90
|
+
echo "Initializing K3s control plane via local engine..."
|
|
91
|
+
node bin cluster --dev --k3s
|
|
92
|
+
ln -s /usr/local/bin/k3s /bin/k3s
|
|
93
|
+
ln -s /usr/local/bin/kubectl /bin/kubectl
|
|
94
|
+
|
|
95
|
+
echo ""
|
|
96
|
+
echo "K3s control plane is ready."
|
|
97
|
+
echo "Node token (share with workers to join this cluster):"
|
|
98
|
+
sudo cat /var/lib/rancher/k3s/server/node-token
|
|
99
|
+
echo ""
|
|
100
|
+
echo "Control plane IP addresses:"
|
|
101
|
+
ip -4 addr show scope global | grep inet | awk '{print $2}' | cut -d/ -f1
|
|
102
|
+
|
|
103
|
+
elif [ "$ROLE" = "worker" ]; then
|
|
104
|
+
if [ -z "$CONTROL_IP" ] || [ -z "$K3S_TOKEN" ]; then
|
|
105
|
+
echo "ERROR: --control-ip and --token are required for worker role."
|
|
106
|
+
echo "Usage: bash k3s-node-setup.sh --worker --control-ip=<ip> --token=<token>"
|
|
107
|
+
exit 1
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
# Worker nodes still need the minimal K3s host prep even though they join via
|
|
111
|
+
# the upstream installer rather than `node bin cluster --k3s`.
|
|
112
|
+
echo "Applying minimal K3s host configuration via local engine..."
|
|
113
|
+
node bin cluster --dev --config --k3s
|
|
114
|
+
|
|
115
|
+
echo "Joining K3s cluster at https://${CONTROL_IP}:6443..."
|
|
116
|
+
curl -sfL https://get.k3s.io | \
|
|
82
117
|
K3S_URL="https://${CONTROL_IP}:6443" \
|
|
83
118
|
K3S_TOKEN="${K3S_TOKEN}" \
|
|
84
119
|
sh -s - agent
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
120
|
+
|
|
121
|
+
echo ""
|
|
122
|
+
echo "K3s worker joined https://${CONTROL_IP}:6443 successfully."
|
|
123
|
+
sudo systemctl status k3s-agent --no-pager
|
|
89
124
|
fi
|
package/scripts/lxd-vm-setup.sh
CHANGED
|
@@ -1,23 +1,208 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
1
3
|
|
|
2
|
-
|
|
4
|
+
# ---------------------------------------------------------------------------
|
|
5
|
+
# LXD VM OS base setup. Runs inside the VM via `lxc exec`. Idempotent.
|
|
6
|
+
# ---------------------------------------------------------------------------
|
|
3
7
|
|
|
4
|
-
|
|
5
|
-
|
|
8
|
+
# lxdbr0 is a plain L2 bridge: LXD runs no DHCP/DNS on it (MAAS owns
|
|
9
|
+
# provisioning), so VMs configure their NIC statically and deterministically.
|
|
10
|
+
# The host pins the gateway (10.250.250.1) on the bridge and provides NAT; no
|
|
11
|
+
# resolver listens there, so DNS must use public/MAAS resolvers, not the gateway.
|
|
12
|
+
# LXD_NET_MODE=dhcp opts back into DHCP-first for VMs on a MAAS-served segment.
|
|
13
|
+
LXD_NET_MODE="${LXD_NET_MODE:-static}"
|
|
14
|
+
LXD_FALLBACK_IPV4_CIDR="${LXD_FALLBACK_IPV4_CIDR:-10.250.250.100/24}"
|
|
15
|
+
LXD_FALLBACK_GATEWAY="${LXD_FALLBACK_GATEWAY:-10.250.250.1}"
|
|
16
|
+
LXD_FALLBACK_DNS="${LXD_FALLBACK_DNS:-1.1.1.1 8.8.8.8}"
|
|
17
|
+
ROCKY_MIRROR_HOST="${ROCKY_MIRROR_HOST:-mirrors.rockylinux.org}"
|
|
18
|
+
|
|
19
|
+
current_ipv4() {
|
|
20
|
+
ip -4 addr show "$IFACE" | awk '/inet /{print $2; exit}'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
wait_for_ipv4() {
|
|
24
|
+
local current_ip=""
|
|
25
|
+
|
|
26
|
+
for _ in $(seq 1 10); do
|
|
27
|
+
current_ip="$(current_ipv4)"
|
|
28
|
+
if [ -n "$current_ip" ]; then
|
|
29
|
+
echo "$current_ip"
|
|
30
|
+
return 0
|
|
31
|
+
fi
|
|
32
|
+
sleep 1
|
|
33
|
+
done
|
|
34
|
+
|
|
35
|
+
return 1
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
refresh_resolver_state() {
|
|
39
|
+
if command -v resolvectl >/dev/null 2>&1; then
|
|
40
|
+
sudo resolvectl flush-caches || true
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
if [ -f /run/NetworkManager/resolv.conf ]; then
|
|
44
|
+
sudo ln -sf /run/NetworkManager/resolv.conf /etc/resolv.conf || true
|
|
45
|
+
fi
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
verify_name_resolution() {
|
|
49
|
+
getent ahostsv4 "$ROCKY_MIRROR_HOST" >/dev/null 2>&1
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
retry_dnf() {
|
|
53
|
+
local attempt=1
|
|
54
|
+
local max_attempts=3
|
|
55
|
+
|
|
56
|
+
until "$@"; do
|
|
57
|
+
if [ "$attempt" -ge "$max_attempts" ]; then
|
|
58
|
+
return 1
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
echo "DNF command failed (attempt $attempt/$max_attempts): $*"
|
|
62
|
+
echo "Refreshing resolver state before retry..."
|
|
63
|
+
refresh_resolver_state
|
|
64
|
+
verify_name_resolution || true
|
|
65
|
+
attempt=$((attempt + 1))
|
|
66
|
+
done
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# k3s derives the node name from the system hostname. The Rocky image keeps
|
|
70
|
+
# "localhost.localdomain" for every VM, so without this every node would try to
|
|
71
|
+
# register under the same name — the second one is rejected ("Node password
|
|
72
|
+
# rejected, duplicate hostname"). Pin the hostname to the LXD instance name so
|
|
73
|
+
# node names are unique and deterministic (control plane labeling relies on it).
|
|
74
|
+
if [ -n "${LXD_NODE_NAME:-}" ] && [ "$(hostname)" != "$LXD_NODE_NAME" ]; then
|
|
75
|
+
echo "--- Hostname ---"
|
|
76
|
+
echo "Setting hostname to ${LXD_NODE_NAME} (k3s node name)..."
|
|
77
|
+
sudo hostnamectl set-hostname "$LXD_NODE_NAME" 2>/dev/null || sudo hostname "$LXD_NODE_NAME"
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
echo "--- Network Configuration ---"
|
|
81
|
+
|
|
82
|
+
# 1. Detect primary non-loopback interface
|
|
83
|
+
IFACE=$(ip -o link show up | awk -F': ' '$2!="lo"{print $2; exit}')
|
|
84
|
+
echo "Using network interface: ${IFACE:-none}"
|
|
85
|
+
|
|
86
|
+
if [ -z "$IFACE" ]; then
|
|
87
|
+
echo "CRITICAL ERROR: No network interface detected."
|
|
88
|
+
exit 1
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
# 2. Force NetworkManager initialization if interface lacks an IP address
|
|
92
|
+
CURRENT_IP="$(current_ipv4 || true)"
|
|
93
|
+
|
|
94
|
+
if command -v nmcli >/dev/null 2>&1 && [ -z "$CURRENT_IP" ]; then
|
|
95
|
+
echo "Inspecting NetworkManager profiles..."
|
|
96
|
+
|
|
97
|
+
# Check if a profile is tracking this device
|
|
98
|
+
NM_CON=$(nmcli -t -f NAME,DEVICE connection show | awk -F: -v iface="$IFACE" '$2==iface{print $1; exit}')
|
|
99
|
+
|
|
100
|
+
if [ -z "$NM_CON" ]; then
|
|
101
|
+
echo "No connection profile matches $IFACE. Forcing generation of profile 'k3s-net'..."
|
|
102
|
+
nmcli connection add type ethernet con-name k3s-net ifname "$IFACE"
|
|
103
|
+
NM_CON="k3s-net"
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
apply_static_ipv4() {
|
|
107
|
+
echo "Applying static LXD bridge address ${LXD_FALLBACK_IPV4_CIDR} (gw ${LXD_FALLBACK_GATEWAY}, dns ${LXD_FALLBACK_DNS})..."
|
|
108
|
+
nmcli connection modify "$NM_CON" \
|
|
109
|
+
connection.autoconnect yes \
|
|
110
|
+
connection.interface-name "$IFACE" \
|
|
111
|
+
ipv4.method manual \
|
|
112
|
+
ipv4.addresses "$LXD_FALLBACK_IPV4_CIDR" \
|
|
113
|
+
ipv4.gateway "$LXD_FALLBACK_GATEWAY" \
|
|
114
|
+
ipv4.dns "$LXD_FALLBACK_DNS" \
|
|
115
|
+
ipv4.ignore-auto-dns yes \
|
|
116
|
+
ipv6.method ignore
|
|
117
|
+
nmcli connection up "$NM_CON"
|
|
118
|
+
CURRENT_IP="$(wait_for_ipv4 || true)"
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
# Static-first: lxdbr0 has no DHCP, so a DHCP attempt only adds a ~45s
|
|
122
|
+
# activation timeout per boot. DHCP is opt-in for VMs on a MAAS-served
|
|
123
|
+
# segment (LXD_NET_MODE=dhcp), with a static fallback if no lease appears.
|
|
124
|
+
if [ "$LXD_NET_MODE" = "dhcp" ]; then
|
|
125
|
+
echo "Configuring DHCP-first NetworkManager profile '$NM_CON'..."
|
|
126
|
+
nmcli connection modify "$NM_CON" \
|
|
127
|
+
connection.autoconnect yes \
|
|
128
|
+
connection.interface-name "$IFACE" \
|
|
129
|
+
ipv4.method auto \
|
|
130
|
+
ipv4.dhcp-client-id mac \
|
|
131
|
+
ipv4.ignore-auto-dns no \
|
|
132
|
+
ipv6.method ignore
|
|
133
|
+
echo "Bringing network interface up with DHCP..."
|
|
134
|
+
nmcli connection up "$NM_CON" || echo "DHCP activation failed; static fallback will be applied."
|
|
135
|
+
CURRENT_IP="$(wait_for_ipv4 || true)"
|
|
136
|
+
if [ -z "$CURRENT_IP" ]; then
|
|
137
|
+
echo "No DHCP lease on $IFACE."
|
|
138
|
+
apply_static_ipv4
|
|
139
|
+
fi
|
|
140
|
+
else
|
|
141
|
+
echo "Configuring static NetworkManager profile '$NM_CON' for the plain LXD bridge..."
|
|
142
|
+
apply_static_ipv4
|
|
143
|
+
fi
|
|
144
|
+
fi
|
|
145
|
+
|
|
146
|
+
# 3. Give the network interface a short window to settle and lease an IP address
|
|
147
|
+
echo "Waiting for IP address allocation..."
|
|
148
|
+
CURRENT_IP="${CURRENT_IP:-$(wait_for_ipv4 || true)}"
|
|
149
|
+
if [ -n "$CURRENT_IP" ]; then
|
|
150
|
+
echo "Interface $IFACE successfully initialized with IP: $CURRENT_IP"
|
|
151
|
+
fi
|
|
152
|
+
|
|
153
|
+
# 4. Verify DNS and outbound connectivity before proceeding (Fail Closed)
|
|
154
|
+
echo "Verifying internet and DNS connectivity..."
|
|
155
|
+
refresh_resolver_state
|
|
156
|
+
if ! verify_name_resolution; then
|
|
157
|
+
echo "CRITICAL ERROR: DNS lookup failed for $ROCKY_MIRROR_HOST. Diagnostic snapshot:"
|
|
158
|
+
echo "=== /etc/resolv.conf ==="
|
|
159
|
+
cat /etc/resolv.conf || true
|
|
160
|
+
echo "=== Interface State ==="
|
|
161
|
+
ip -4 addr show "$IFACE" || true
|
|
162
|
+
echo "=== Routing Table ==="
|
|
163
|
+
ip route show || true
|
|
164
|
+
echo "=== NetworkManager Status ==="
|
|
165
|
+
nmcli device status || true
|
|
166
|
+
exit 1
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
if ! timeout 15 curl -fsSL --max-time 10 "https://${ROCKY_MIRROR_HOST}" -o /dev/null; then
|
|
170
|
+
echo "CRITICAL ERROR: Network/DNS remains unreachable. Diagnostic snapshot:"
|
|
171
|
+
echo "=== /etc/resolv.conf ==="
|
|
172
|
+
cat /etc/resolv.conf || true
|
|
173
|
+
echo "=== Interface State ==="
|
|
174
|
+
ip -4 addr show "$IFACE" || true
|
|
175
|
+
echo "=== Routing Table ==="
|
|
176
|
+
ip route show || true
|
|
177
|
+
echo "=== NetworkManager Status ==="
|
|
178
|
+
nmcli device status || true
|
|
179
|
+
exit 1
|
|
6
180
|
fi
|
|
7
181
|
|
|
182
|
+
echo "--- Disk Resizing ---"
|
|
183
|
+
if ! command -v parted >/dev/null 2>&1; then
|
|
184
|
+
sudo dnf install -y parted
|
|
185
|
+
fi
|
|
186
|
+
|
|
187
|
+
set +e
|
|
8
188
|
sudo parted /dev/sda ---pretend-input-tty <<EOF
|
|
9
189
|
unit s
|
|
10
190
|
resizepart 2 100%
|
|
11
191
|
Yes
|
|
12
192
|
quit
|
|
13
193
|
EOF
|
|
194
|
+
set -e
|
|
14
195
|
|
|
15
196
|
sudo resize2fs /dev/sda2
|
|
16
|
-
echo "Disk resized."
|
|
197
|
+
echo "Disk partition and filesystem resized successfully."
|
|
17
198
|
|
|
18
|
-
echo "
|
|
19
|
-
sudo dnf install -y
|
|
20
|
-
sudo dnf -y
|
|
199
|
+
echo "--- Package Installation ---"
|
|
200
|
+
retry_dnf sudo dnf install -y epel-release
|
|
201
|
+
retry_dnf sudo dnf install -y tar bzip2 git curl jq
|
|
202
|
+
retry_dnf sudo dnf -y update
|
|
21
203
|
|
|
22
|
-
echo "
|
|
204
|
+
echo "--- Kernel Modules for K3s ---"
|
|
23
205
|
sudo modprobe br_netfilter
|
|
206
|
+
echo "br_netfilter" | sudo tee /etc/modules-load.d/k3s-br_netfilter.conf > /dev/null
|
|
207
|
+
|
|
208
|
+
echo "Setup complete. System is ready for k3s-node-setup.sh"
|