mirror of
https://github.com/vdsm/virtual-dsm.git
synced 2026-08-28 11:56:03 +00:00
feat: Check available memory before installation starts (#1353)
This commit is contained in:
+5
-13
@@ -29,10 +29,6 @@ RUN <<EOF
|
||||
procps \
|
||||
ipcalc \
|
||||
ethtool \
|
||||
python3 \
|
||||
python3-pip \
|
||||
python3-msgpack \
|
||||
python3-pysodium \
|
||||
xz-utils \
|
||||
iptables \
|
||||
iproute2 \
|
||||
@@ -48,7 +44,11 @@ RUN <<EOF
|
||||
inotify-tools \
|
||||
ca-certificates \
|
||||
netcat-openbsd \
|
||||
qemu-system-x86
|
||||
qemu-system-x86 \
|
||||
python3 \
|
||||
python3-pip \
|
||||
python3-msgpack \
|
||||
python3-pysodium
|
||||
|
||||
# Install Passt package
|
||||
wget "https://github.com/qemus/passt/releases/download/v${VERSION_PASST}/passt_${VERSION_PASST}_${TARGETARCH}.deb" -O /tmp/passt.deb -q --timeout=10
|
||||
@@ -59,14 +59,6 @@ RUN <<EOF
|
||||
# Install Python dependencies
|
||||
pip3 install --no-cache-dir --break-system-packages --root-user-action=ignore "dissect.cstruct==$VERSION_CSTRUCT"
|
||||
|
||||
# Configure QEMU
|
||||
mkdir -p /etc/qemu
|
||||
echo "allow br0" > /etc/qemu/bridge.conf
|
||||
|
||||
# Configure nginx
|
||||
unlink /etc/nginx/sites-enabled/default
|
||||
sed -i 's/^worker_processes.*/worker_processes 1;/' /etc/nginx/nginx.conf
|
||||
|
||||
# Set version file
|
||||
echo "$VERSION_ARG" > /etc/version
|
||||
|
||||
|
||||
@@ -61,6 +61,8 @@ buildArguments() {
|
||||
return 0
|
||||
}
|
||||
|
||||
finalizeMemory
|
||||
|
||||
configureMemory
|
||||
configureMonitor
|
||||
configureMachine
|
||||
|
||||
+2
-2
@@ -9,7 +9,8 @@ cd /run
|
||||
|
||||
. start.sh # Startup hook
|
||||
. utils.sh # Load functions
|
||||
. reset.sh # Initialize system
|
||||
. init.sh # Initialize system
|
||||
. memory.sh # Check memory
|
||||
. server.sh # Start webserver
|
||||
. install.sh # Run installation
|
||||
. disk.sh # Initialize disks
|
||||
@@ -18,7 +19,6 @@ cd /run
|
||||
. proc.sh # Initialize processor
|
||||
. serial.sh # Initialize serialport
|
||||
. power.sh # Configure shutdown
|
||||
. memory.sh # Check available memory
|
||||
. config.sh # Configure arguments
|
||||
. finish.sh # Finish initialization
|
||||
|
||||
|
||||
@@ -5,4 +5,7 @@ if enabled "$DEBUG"; then
|
||||
printf "QEMU arguments:\n\n %s\n\n" "${ARGS// -/$'\n -'}"
|
||||
fi
|
||||
|
||||
# Must always remain the very last command
|
||||
enableTrap
|
||||
|
||||
return 0
|
||||
|
||||
@@ -158,53 +158,6 @@ checkHost() {
|
||||
return 0
|
||||
}
|
||||
|
||||
checkRam() {
|
||||
|
||||
# Read host and container memory limits.
|
||||
getMemoryInfo
|
||||
|
||||
RAM_SPARE=500000000
|
||||
RAM_MINIMUM="${RAM_MINIMUM:-1073741824}"
|
||||
|
||||
RAM_MINIMUM=$(strip "$RAM_MINIMUM")
|
||||
RAM_MINIMUM="${RAM_MINIMUM// /}"
|
||||
RAM_MINIMUM=$(echo "${RAM_MINIMUM^^}" | sed 's/MB/M/g;s/GB/G/g;s/TB/T/g')
|
||||
numfmt --from=iec "$RAM_MINIMUM" &>/dev/null || {
|
||||
error "Invalid RAM_MINIMUM: $RAM_MINIMUM"
|
||||
exit 16
|
||||
}
|
||||
RAM_MINIMUM=$(numfmt --from=iec "$RAM_MINIMUM")
|
||||
|
||||
RAM_SIZE=$(strip "$RAM_SIZE")
|
||||
RAM_SIZE="${RAM_SIZE// /}"
|
||||
[ -z "$RAM_SIZE" ] && RAM_SIZE="2G"
|
||||
|
||||
if [[ "${RAM_SIZE,,}" != "max" && "${RAM_SIZE,,}" != "half" ]]; then
|
||||
|
||||
# Bare values below 130 are interpreted as GiB for convenience; larger bare
|
||||
# values are treated as MiB to preserve historical configurations.
|
||||
if [ -z "${RAM_SIZE//[0-9. ]}" ]; then
|
||||
[ "${RAM_SIZE%%.*}" -lt "130" ] && RAM_SIZE="${RAM_SIZE}G" || RAM_SIZE="${RAM_SIZE}M"
|
||||
fi
|
||||
|
||||
RAM_SIZE=$(echo "${RAM_SIZE^^}" | sed 's/MB/M/g;s/GB/G/g;s/TB/T/g')
|
||||
numfmt --from=iec "$RAM_SIZE" &>/dev/null || {
|
||||
error "Invalid RAM_SIZE: $RAM_SIZE"
|
||||
exit 16
|
||||
}
|
||||
|
||||
wanted=$(numfmt --from=iec "$RAM_SIZE")
|
||||
|
||||
if [ "$wanted" -lt "$RAM_MINIMUM" ]; then
|
||||
error "$(app) requires at least $(formatBytes "$RAM_MINIMUM") of RAM, but RAM_SIZE is set to $(formatBytes "$wanted")."
|
||||
exit 16
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
checkKvm() {
|
||||
|
||||
# Check KVM support
|
||||
@@ -311,7 +264,7 @@ IFS=. read -r KERNEL MINOR _ <<< "$SYS"
|
||||
checkSockets
|
||||
checkCores
|
||||
checkStorage
|
||||
checkRam
|
||||
getMemoryInfo
|
||||
|
||||
# Print system info
|
||||
SYS="${SYS/-generic/}"
|
||||
+116
-14
@@ -1,14 +1,61 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
msg="Checking memory..."
|
||||
enabled "$DEBUG" && echo "$msg"
|
||||
normalizeMemory() {
|
||||
|
||||
RAM_WARNING=""
|
||||
RAM_ALLOCATION=""
|
||||
local wanted
|
||||
|
||||
RAM_SPARE=500000000
|
||||
RAM_MINIMUM="${RAM_MINIMUM:-1073741824}"
|
||||
|
||||
RAM_MINIMUM=$(strip "$RAM_MINIMUM")
|
||||
RAM_MINIMUM="${RAM_MINIMUM// /}"
|
||||
RAM_MINIMUM=$(echo "${RAM_MINIMUM^^}" | sed 's/MB/M/g;s/GB/G/g;s/TB/T/g')
|
||||
numfmt --from=iec "$RAM_MINIMUM" &>/dev/null || {
|
||||
error "Invalid RAM_MINIMUM: $RAM_MINIMUM"
|
||||
exit 16
|
||||
}
|
||||
RAM_MINIMUM=$(numfmt --from=iec "$RAM_MINIMUM")
|
||||
|
||||
RAM_SIZE=$(strip "$RAM_SIZE")
|
||||
RAM_SIZE="${RAM_SIZE// /}"
|
||||
[ -z "$RAM_SIZE" ] && RAM_SIZE="2G"
|
||||
|
||||
if [[ "${RAM_SIZE,,}" != "max" && "${RAM_SIZE,,}" != "half" ]]; then
|
||||
|
||||
# Bare values below 130 are interpreted as GiB for convenience; larger bare
|
||||
# values are treated as MiB to preserve historical configurations.
|
||||
if [ -z "${RAM_SIZE//[0-9. ]}" ]; then
|
||||
[ "${RAM_SIZE%%.*}" -lt "130" ] && RAM_SIZE="${RAM_SIZE}G" || RAM_SIZE="${RAM_SIZE}M"
|
||||
fi
|
||||
|
||||
RAM_SIZE=$(echo "${RAM_SIZE^^}" | sed 's/MB/M/g;s/GB/G/g;s/TB/T/g')
|
||||
numfmt --from=iec "$RAM_SIZE" &>/dev/null || {
|
||||
error "Invalid RAM_SIZE: $RAM_SIZE"
|
||||
exit 16
|
||||
}
|
||||
|
||||
wanted=$(numfmt --from=iec "$RAM_SIZE")
|
||||
|
||||
if [ "$wanted" -lt "$RAM_MINIMUM" ]; then
|
||||
error "$(app) requires at least $(formatBytes "$RAM_MINIMUM") of RAM, but RAM_SIZE is set to $(formatBytes "$wanted")."
|
||||
exit 16
|
||||
fi
|
||||
|
||||
# QEMU requires a whole-number memory value, so convert decimal sizes to MiB.
|
||||
if [[ "$RAM_SIZE" == *.* ]]; then
|
||||
RAM_SIZE="$(( wanted / 1048576 ))M"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
checkConfiguredMemory() {
|
||||
|
||||
local final="$1"
|
||||
|
||||
if disabled "$RAM_CHECK" || [[ "${RAM_SIZE,,}" == "max" || "${RAM_SIZE,,}" == "half" ]]; then
|
||||
return 0
|
||||
fi
|
||||
@@ -25,7 +72,7 @@ checkConfiguredMemory() {
|
||||
# heuristic remains informational instead of rewriting RAM_SIZE.
|
||||
if [[ "${FS,,}" == "zfs" ]]; then
|
||||
|
||||
info "$msg but since ZFS is active this will be ignored."
|
||||
enabled "$final" && info "$msg but since ZFS is active this will be ignored."
|
||||
|
||||
else
|
||||
|
||||
@@ -41,9 +88,9 @@ checkConfiguredMemory() {
|
||||
local msg="your configured RAM_SIZE of ${RAM_SIZE/G/ GB} is very close to the $avail_mem of free memory available,"
|
||||
|
||||
if [[ "${FS,,}" == "zfs" ]]; then
|
||||
info "$msg but since ZFS is active this will be ignored."
|
||||
enabled "$final" && info "$msg but since ZFS is active this will be ignored."
|
||||
else
|
||||
warn "$msg please consider a lower amount."
|
||||
enabled "$final" && warn "$msg please consider a lower amount."
|
||||
fi
|
||||
|
||||
fi
|
||||
@@ -107,27 +154,82 @@ configureMaxMemory() {
|
||||
return 0
|
||||
}
|
||||
|
||||
showMemoryLimitHint() {
|
||||
|
||||
local kernel
|
||||
kernel=$(uname -r)
|
||||
|
||||
if [[ "${kernel,,}" == *-wsl2* ]]; then
|
||||
echo
|
||||
info "Docker Desktop (WSL2) is detected, follow these instructions:"
|
||||
info ""
|
||||
info "Increase the memory limit in \"%UserProfile%\\.wslconfig\" by setting \"memory=<size>\" under \"[wsl2]\"."
|
||||
info "Then run \"wsl --shutdown\" in PowerShell and restart Docker Desktop for the new limit to take effect."
|
||||
echo
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
checkMinimumMemory() {
|
||||
|
||||
local wanted
|
||||
wanted=$(numfmt --from=iec "$RAM_SIZE")
|
||||
|
||||
if [ "$wanted" -lt "$RAM_MINIMUM" ]; then
|
||||
|
||||
error "$(app) requires at least $(formatBytes "$RAM_MINIMUM") of RAM, but only $(formatBytes "$wanted") can be allocated."
|
||||
|
||||
showMemoryLimitHint
|
||||
|
||||
exit 16
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
getMemoryInfo
|
||||
checkMemoryAllocation() {
|
||||
|
||||
checkConfiguredMemory
|
||||
configureHalfMemory
|
||||
configureMaxMemory
|
||||
checkMinimumMemory
|
||||
local final="${1:-N}"
|
||||
local configured
|
||||
|
||||
[ -n "$RAM_WARNING" ] && warn "$RAM_WARNING"
|
||||
[ -n "$RAM_ALLOCATION" ] && info "Allocated $(formatBytes "$RAM_ALLOCATION") of RAM for $(app)."
|
||||
normalizeMemory
|
||||
configured="$RAM_SIZE"
|
||||
|
||||
RAM_WARNING=""
|
||||
RAM_ALLOCATION=""
|
||||
|
||||
getMemoryInfo
|
||||
checkConfiguredMemory "$final"
|
||||
|
||||
configureHalfMemory
|
||||
configureMaxMemory
|
||||
checkMinimumMemory
|
||||
|
||||
if enabled "$final"; then
|
||||
[ -n "$RAM_WARNING" ] && warn "$RAM_WARNING"
|
||||
[ -n "$RAM_ALLOCATION" ] && info "Allocated $(formatBytes "$RAM_ALLOCATION") of RAM for $(app)."
|
||||
else
|
||||
RAM_SIZE="$configured"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
checkMemoryRequirement() {
|
||||
|
||||
checkMemoryAllocation "N"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
finalizeMemory() {
|
||||
|
||||
checkMemoryAllocation "Y"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
checkMemoryRequirement
|
||||
|
||||
return 0
|
||||
|
||||
@@ -968,6 +968,17 @@ configurePasst() {
|
||||
return 0
|
||||
}
|
||||
|
||||
configureBridge() {
|
||||
|
||||
local file="/etc/qemu/bridge.conf"
|
||||
|
||||
[ -e "$file" ] && return 0
|
||||
mkdir -p "${file%/*}" || return 0
|
||||
echo "allow br0" > "$file" || return 0
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
createBridge() {
|
||||
|
||||
local gateway="$1"
|
||||
@@ -2137,6 +2148,7 @@ showHostInfo() {
|
||||
echo "❯ DNS: $nameservers"
|
||||
fi
|
||||
|
||||
enabled "$DEBUG" && echo
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -2191,6 +2203,7 @@ initializeNetwork() {
|
||||
|
||||
configureMTU
|
||||
configureMAC
|
||||
configureBridge
|
||||
|
||||
showHostInfo
|
||||
|
||||
|
||||
+16
-8
@@ -335,7 +335,7 @@ waitForShutdown() {
|
||||
return 0
|
||||
}
|
||||
|
||||
graceful_shutdown() {
|
||||
gracefulShutdown() {
|
||||
|
||||
local sig="$1"
|
||||
local pid code
|
||||
@@ -387,13 +387,21 @@ graceful_shutdown() {
|
||||
finish "$code"
|
||||
}
|
||||
|
||||
enabled "$SHUTDOWN" || return 0
|
||||
enableTrap() {
|
||||
|
||||
enabled "$SHUTDOWN" || return 0
|
||||
|
||||
# Keep Ctrl-C available to interactive users without installing an unnecessary
|
||||
# SIGINT handler for background/container execution.
|
||||
if interactive; then
|
||||
_trap gracefulShutdown SIGINT
|
||||
fi
|
||||
|
||||
_trap gracefulShutdown SIGTERM SIGHUP SIGABRT SIGQUIT
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
[ -n "${QEMU_TIMEOUT:-}" ] && TIMEOUT="$QEMU_TIMEOUT"
|
||||
|
||||
if interactive; then
|
||||
_trap graceful_shutdown SIGINT
|
||||
fi
|
||||
|
||||
_trap graceful_shutdown SIGTERM SIGHUP SIGABRT SIGQUIT
|
||||
|
||||
return 0
|
||||
|
||||
+17
-2
@@ -51,11 +51,26 @@ configureIpv6Listen() {
|
||||
return 0
|
||||
}
|
||||
|
||||
configureWebServer() {
|
||||
configureNginx() {
|
||||
|
||||
mkdir -p /etc/nginx/sites-enabled || return 1
|
||||
rm -f /etc/nginx/sites-enabled/default || return 1
|
||||
|
||||
if ! sed -i \
|
||||
-e 's/^worker_processes.*/worker_processes 1;/' \
|
||||
/etc/nginx/nginx.conf; then
|
||||
error "Failed to configure nginx!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
mkdir -p /etc/nginx/sites-enabled
|
||||
cp /etc/nginx/default.conf /etc/nginx/sites-enabled/web.conf
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
configureWebServer() {
|
||||
|
||||
configureNginx || return 1
|
||||
configureWebPorts || return 1
|
||||
configureIpv6Listen || return 1
|
||||
|
||||
|
||||
+6
-6
@@ -7,6 +7,12 @@ info () { printf "%b%s%b" "\E[1;34m❯ \E[1;36m" "${1:-}" "\E[0m\n"; }
|
||||
error () { printf "%b%s%b" "\E[1;31m❯ " "ERROR: ${1:-}" "\E[0m\n" >&2; }
|
||||
warn () { printf "%b%s%b" "\E[1;31m❯ " "Warning: ${1:-}" "\E[0m\n" >&2; }
|
||||
|
||||
app() {
|
||||
|
||||
echo "Virtual DSM"
|
||||
return 0
|
||||
}
|
||||
|
||||
readPidFile() {
|
||||
|
||||
local -n _pid="$1"
|
||||
@@ -307,12 +313,6 @@ makeDir() {
|
||||
return 0
|
||||
}
|
||||
|
||||
app() {
|
||||
|
||||
echo "Virtual DSM"
|
||||
return 0
|
||||
}
|
||||
|
||||
finiteMemoryLimit() {
|
||||
|
||||
local limit="$1"
|
||||
|
||||
Reference in New Issue
Block a user