mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2025-12-21 22:46:25 +01:00
Compare commits
7 Commits
fix/zabbix
...
fix/amd-gp
| Author | SHA1 | Date | |
|---|---|---|---|
| 10de0f7e4a | |||
| e1f2814f81 | |||
| 0271dddfd5 | |||
| 5a263b5036 | |||
| 60635feeab | |||
| 7261ffe8a2 | |||
| 44ea7cecb8 |
@ -20,6 +20,7 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- zabbix: fix repo url after change [@MickLesk](https://github.com/MickLesk) ([#10042](https://github.com/community-scripts/ProxmoxVE/pull/10042))
|
||||||
- Fix: mariadb repo in update_scripts [@MickLesk](https://github.com/MickLesk) ([#10034](https://github.com/community-scripts/ProxmoxVE/pull/10034))
|
- Fix: mariadb repo in update_scripts [@MickLesk](https://github.com/MickLesk) ([#10034](https://github.com/community-scripts/ProxmoxVE/pull/10034))
|
||||||
- 2fauth: update PHP version from 8.3 to 8.4 in update_script [@MickLesk](https://github.com/MickLesk) ([#10035](https://github.com/community-scripts/ProxmoxVE/pull/10035))
|
- 2fauth: update PHP version from 8.3 to 8.4 in update_script [@MickLesk](https://github.com/MickLesk) ([#10035](https://github.com/community-scripts/ProxmoxVE/pull/10035))
|
||||||
- pdm: add rsyslog to fix /dev/log Connection refused errors [@MickLesk](https://github.com/MickLesk) ([#10018](https://github.com/community-scripts/ProxmoxVE/pull/10018))
|
- pdm: add rsyslog to fix /dev/log Connection refused errors [@MickLesk](https://github.com/MickLesk) ([#10018](https://github.com/community-scripts/ProxmoxVE/pull/10018))
|
||||||
@ -31,6 +32,7 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
- #### ✨ New Features
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- core: IP-Range-Scan Support (app.vars / default.vars) [@MickLesk](https://github.com/MickLesk) ([#10038](https://github.com/community-scripts/ProxmoxVE/pull/10038))
|
||||||
- tools.func: add optional enabled parameter to setup_deb822_repo [@MickLesk](https://github.com/MickLesk) ([#10017](https://github.com/community-scripts/ProxmoxVE/pull/10017))
|
- tools.func: add optional enabled parameter to setup_deb822_repo [@MickLesk](https://github.com/MickLesk) ([#10017](https://github.com/community-scripts/ProxmoxVE/pull/10017))
|
||||||
- core: map Etc/* timezones to 'host' for pct compatibility [@MickLesk](https://github.com/MickLesk) ([#10020](https://github.com/community-scripts/ProxmoxVE/pull/10020))
|
- core: map Etc/* timezones to 'host' for pct compatibility [@MickLesk](https://github.com/MickLesk) ([#10020](https://github.com/community-scripts/ProxmoxVE/pull/10020))
|
||||||
|
|
||||||
|
|||||||
@ -434,12 +434,24 @@ var_unprivileged=1 # 0=privileged, 1=unprivileged
|
|||||||
#### Network
|
#### Network
|
||||||
```bash
|
```bash
|
||||||
var_brg=vmbr0 # Bridge interface
|
var_brg=vmbr0 # Bridge interface
|
||||||
var_net=veth # Network driver
|
var_net=dhcp # dhcp, static IP/CIDR, or IP range (see below)
|
||||||
var_gateway=192.168.1.1 # Default gateway
|
var_gateway=192.168.1.1 # Default gateway (required for static IP)
|
||||||
var_mtu=1500 # MTU size
|
var_mtu=1500 # MTU size
|
||||||
var_vlan=100 # VLAN ID
|
var_vlan=100 # VLAN ID
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### IP Range Scanning
|
||||||
|
|
||||||
|
You can specify an IP range instead of a static IP. The system will ping each IP in the range and automatically assign the first free IP:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Format: START_IP/CIDR-END_IP/CIDR
|
||||||
|
var_net=192.168.1.100/24-192.168.1.200/24
|
||||||
|
var_gateway=192.168.1.1
|
||||||
|
```
|
||||||
|
|
||||||
|
This is useful for automated deployments where you want static IPs but don't want to track which IPs are already in use.
|
||||||
|
|
||||||
#### System
|
#### System
|
||||||
```bash
|
```bash
|
||||||
var_hostname=pihole # Container name
|
var_hostname=pihole # Container name
|
||||||
|
|||||||
@ -122,6 +122,31 @@ var_verbose=no \
|
|||||||
echo "✓ Container deployed successfully"
|
echo "✓ Container deployed successfully"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Using IP Range Scan for Automatic IP Assignment
|
||||||
|
|
||||||
|
Instead of manually specifying static IPs, you can define an IP range. The system will automatically ping each IP and assign the first free one:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# deploy-with-ip-scan.sh - Auto-assign first free IP from range
|
||||||
|
|
||||||
|
var_unprivileged=1 \
|
||||||
|
var_cpu=4 \
|
||||||
|
var_ram=4096 \
|
||||||
|
var_hostname=web-server \
|
||||||
|
var_net=192.168.1.100/24-192.168.1.150/24 \
|
||||||
|
var_gateway=192.168.1.1 \
|
||||||
|
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/debian.sh)"
|
||||||
|
|
||||||
|
# The script will:
|
||||||
|
# 1. Ping 192.168.1.100 - if responds, skip
|
||||||
|
# 2. Ping 192.168.1.101 - if responds, skip
|
||||||
|
# 3. Continue until first IP that doesn't respond
|
||||||
|
# 4. Assign that IP to the container
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note**: IP range format is `START_IP/CIDR-END_IP/CIDR`. Both sides must include the same CIDR notation.
|
||||||
|
|
||||||
### Using App Defaults
|
### Using App Defaults
|
||||||
|
|
||||||
**Step 1: Create defaults once (interactive)**
|
**Step 1: Create defaults once (interactive)**
|
||||||
|
|||||||
144
misc/build.func
144
misc/build.func
@ -291,6 +291,90 @@ find_host_ssh_keys() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# SECTION 3B: IP RANGE SCANNING
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# ip_to_int() / int_to_ip()
|
||||||
|
#
|
||||||
|
# - Converts IP address to integer and vice versa for range iteration
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
ip_to_int() {
|
||||||
|
local IFS=.
|
||||||
|
read -r i1 i2 i3 i4 <<<"$1"
|
||||||
|
echo $(((i1 << 24) + (i2 << 16) + (i3 << 8) + i4))
|
||||||
|
}
|
||||||
|
|
||||||
|
int_to_ip() {
|
||||||
|
local ip=$1
|
||||||
|
echo "$(((ip >> 24) & 0xFF)).$(((ip >> 16) & 0xFF)).$(((ip >> 8) & 0xFF)).$((ip & 0xFF))"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# resolve_ip_from_range()
|
||||||
|
#
|
||||||
|
# - Takes an IP range in format "10.0.0.1/24-10.0.0.10/24"
|
||||||
|
# - Pings each IP in the range to find the first available one
|
||||||
|
# - Returns the first free IP with CIDR notation
|
||||||
|
# - Sets NET_RESOLVED to the resolved IP or empty on failure
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
resolve_ip_from_range() {
|
||||||
|
local range="$1"
|
||||||
|
local ip_cidr_regex='^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/([0-9]{1,2})$'
|
||||||
|
local ip_start ip_end
|
||||||
|
|
||||||
|
# Parse range: "10.0.0.1/24-10.0.0.10/24"
|
||||||
|
ip_start="${range%%-*}"
|
||||||
|
ip_end="${range##*-}"
|
||||||
|
|
||||||
|
if [[ ! "$ip_start" =~ $ip_cidr_regex ]] || [[ ! "$ip_end" =~ $ip_cidr_regex ]]; then
|
||||||
|
NET_RESOLVED=""
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local ip1="${ip_start%%/*}"
|
||||||
|
local ip2="${ip_end%%/*}"
|
||||||
|
local cidr="${ip_start##*/}"
|
||||||
|
|
||||||
|
local start_int=$(ip_to_int "$ip1")
|
||||||
|
local end_int=$(ip_to_int "$ip2")
|
||||||
|
|
||||||
|
for ((ip_int = start_int; ip_int <= end_int; ip_int++)); do
|
||||||
|
local ip=$(int_to_ip $ip_int)
|
||||||
|
msg_info "Checking IP: $ip"
|
||||||
|
if ! ping -c 1 -W 1 "$ip" >/dev/null 2>&1; then
|
||||||
|
NET_RESOLVED="$ip/$cidr"
|
||||||
|
msg_ok "Found free IP: ${BGN}$NET_RESOLVED${CL}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
NET_RESOLVED=""
|
||||||
|
msg_error "No free IP found in range $range"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# is_ip_range()
|
||||||
|
#
|
||||||
|
# - Checks if a string is an IP range (contains - and looks like IP/CIDR)
|
||||||
|
# - Returns 0 if it's a range, 1 otherwise
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
is_ip_range() {
|
||||||
|
local value="$1"
|
||||||
|
local ip_start ip_end
|
||||||
|
if [[ "$value" == *-* ]] && [[ "$value" != "dhcp" ]]; then
|
||||||
|
local ip_cidr_regex='^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/([0-9]{1,2})$'
|
||||||
|
ip_start="${value%%-*}"
|
||||||
|
ip_end="${value##*-}"
|
||||||
|
if [[ "$ip_start" =~ $ip_cidr_regex ]] && [[ "$ip_end" =~ $ip_cidr_regex ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# SECTION 4: STORAGE & RESOURCE MANAGEMENT
|
# SECTION 4: STORAGE & RESOURCE MANAGEMENT
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@ -403,6 +487,18 @@ base_settings() {
|
|||||||
HN=${var_hostname:-$NSAPP}
|
HN=${var_hostname:-$NSAPP}
|
||||||
BRG=${var_brg:-"vmbr0"}
|
BRG=${var_brg:-"vmbr0"}
|
||||||
NET=${var_net:-"dhcp"}
|
NET=${var_net:-"dhcp"}
|
||||||
|
|
||||||
|
# Resolve IP range if NET contains a range (e.g., 192.168.1.100/24-192.168.1.200/24)
|
||||||
|
if is_ip_range "$NET"; then
|
||||||
|
msg_info "Scanning IP range: $NET"
|
||||||
|
if resolve_ip_from_range "$NET"; then
|
||||||
|
NET="$NET_RESOLVED"
|
||||||
|
else
|
||||||
|
msg_error "Could not find free IP in range. Falling back to DHCP."
|
||||||
|
NET="dhcp"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
IPV6_METHOD=${var_ipv6_method:-"none"}
|
IPV6_METHOD=${var_ipv6_method:-"none"}
|
||||||
IPV6_STATIC=${var_ipv6_static:-""}
|
IPV6_STATIC=${var_ipv6_static:-""}
|
||||||
GATE=${var_gateway:-""}
|
GATE=${var_gateway:-""}
|
||||||
@ -492,6 +588,12 @@ load_vars_file() {
|
|||||||
[[ "$var_key" != var_* ]] && continue
|
[[ "$var_key" != var_* ]] && continue
|
||||||
_is_whitelisted "$var_key" || continue
|
_is_whitelisted "$var_key" || continue
|
||||||
|
|
||||||
|
# Strip inline comments (anything after unquoted #)
|
||||||
|
# Only strip if not inside quotes
|
||||||
|
if [[ ! "$var_val" =~ ^[\"\'] ]]; then
|
||||||
|
var_val="${var_val%%#*}"
|
||||||
|
fi
|
||||||
|
|
||||||
# Strip quotes
|
# Strip quotes
|
||||||
if [[ "$var_val" =~ ^\"(.*)\"$ ]]; then
|
if [[ "$var_val" =~ ^\"(.*)\"$ ]]; then
|
||||||
var_val="${BASH_REMATCH[1]}"
|
var_val="${BASH_REMATCH[1]}"
|
||||||
@ -499,6 +601,9 @@ load_vars_file() {
|
|||||||
var_val="${BASH_REMATCH[1]}"
|
var_val="${BASH_REMATCH[1]}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Trim trailing whitespace
|
||||||
|
var_val="${var_val%"${var_val##*[![:space:]]}"}"
|
||||||
|
|
||||||
# Set variable: force mode overrides existing, otherwise only set if empty
|
# Set variable: force mode overrides existing, otherwise only set if empty
|
||||||
if [[ "$force" == "yes" ]]; then
|
if [[ "$force" == "yes" ]]; then
|
||||||
export "${var_key}=${var_val}"
|
export "${var_key}=${var_val}"
|
||||||
@ -1324,9 +1429,10 @@ advanced_settings() {
|
|||||||
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
|
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
|
||||||
--title "IPv4 CONFIGURATION" \
|
--title "IPv4 CONFIGURATION" \
|
||||||
--ok-button "Next" --cancel-button "Back" \
|
--ok-button "Next" --cancel-button "Back" \
|
||||||
--menu "\nSelect IPv4 Address Assignment:" 14 60 2 \
|
--menu "\nSelect IPv4 Address Assignment:" 16 65 3 \
|
||||||
"dhcp" "Automatic (DHCP, recommended)" \
|
"dhcp" "Automatic (DHCP, recommended)" \
|
||||||
"static" "Static (manual entry)" \
|
"static" "Static (manual entry)" \
|
||||||
|
"range" "IP Range Scan (find first free IP)" \
|
||||||
3>&1 1>&2 2>&3); then
|
3>&1 1>&2 2>&3); then
|
||||||
|
|
||||||
if [[ "$result" == "static" ]]; then
|
if [[ "$result" == "static" ]]; then
|
||||||
@ -1357,6 +1463,42 @@ advanced_settings() {
|
|||||||
whiptail --msgbox "Invalid IPv4 CIDR format.\nExample: 192.168.1.100/24" 8 58
|
whiptail --msgbox "Invalid IPv4 CIDR format.\nExample: 192.168.1.100/24" 8 58
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
elif [[ "$result" == "range" ]]; then
|
||||||
|
# IP Range Scan
|
||||||
|
local ip_range
|
||||||
|
if ip_range=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
|
||||||
|
--title "IP RANGE SCAN" \
|
||||||
|
--ok-button "Scan" --cancel-button "Back" \
|
||||||
|
--inputbox "\nEnter IP range to scan for free address\n(e.g. 192.168.1.100/24-192.168.1.200/24)" 12 65 "" \
|
||||||
|
3>&1 1>&2 2>&3); then
|
||||||
|
if is_ip_range "$ip_range"; then
|
||||||
|
# Exit whiptail screen temporarily to show scan progress
|
||||||
|
clear
|
||||||
|
header_info
|
||||||
|
echo -e "${INFO}${BOLD}${DGN}Scanning IP range for free address...${CL}\n"
|
||||||
|
if resolve_ip_from_range "$ip_range"; then
|
||||||
|
# Get gateway
|
||||||
|
local gateway_ip
|
||||||
|
if gateway_ip=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
|
||||||
|
--title "GATEWAY IP" \
|
||||||
|
--ok-button "Next" --cancel-button "Back" \
|
||||||
|
--inputbox "\nFound free IP: $NET_RESOLVED\n\nEnter Gateway IP address" 12 58 "" \
|
||||||
|
3>&1 1>&2 2>&3); then
|
||||||
|
if [[ "$gateway_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
||||||
|
_net="$NET_RESOLVED"
|
||||||
|
_gate=",gw=$gateway_ip"
|
||||||
|
((STEP++))
|
||||||
|
else
|
||||||
|
whiptail --msgbox "Invalid Gateway IP format." 8 58
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
whiptail --msgbox "No free IP found in the specified range.\nAll IPs responded to ping." 10 58
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
whiptail --msgbox "Invalid IP range format.\n\nExample: 192.168.1.100/24-192.168.1.200/24" 10 58
|
||||||
|
fi
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
_net="dhcp"
|
_net="dhcp"
|
||||||
_gate=""
|
_gate=""
|
||||||
|
|||||||
@ -1460,19 +1460,19 @@ check_for_gh_release() {
|
|||||||
|
|
||||||
# Try /latest endpoint for non-pinned versions (most efficient)
|
# Try /latest endpoint for non-pinned versions (most efficient)
|
||||||
local releases_json=""
|
local releases_json=""
|
||||||
|
|
||||||
if [[ -z "$pinned_version_in" ]]; then
|
if [[ -z "$pinned_version_in" ]]; then
|
||||||
releases_json=$(curl -fsSL --max-time 20 \
|
releases_json=$(curl -fsSL --max-time 20 \
|
||||||
-H 'Accept: application/vnd.github+json' \
|
-H 'Accept: application/vnd.github+json' \
|
||||||
-H 'X-GitHub-Api-Version: 2022-11-28' \
|
-H 'X-GitHub-Api-Version: 2022-11-28' \
|
||||||
"https://api.github.com/repos/${source}/releases/latest" 2>/dev/null)
|
"https://api.github.com/repos/${source}/releases/latest" 2>/dev/null)
|
||||||
|
|
||||||
if [[ $? -eq 0 ]] && [[ -n "$releases_json" ]]; then
|
if [[ $? -eq 0 ]] && [[ -n "$releases_json" ]]; then
|
||||||
# Wrap single release in array for consistent processing
|
# Wrap single release in array for consistent processing
|
||||||
releases_json="[$releases_json]"
|
releases_json="[$releases_json]"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If no releases yet (pinned version OR /latest failed), fetch up to 100
|
# If no releases yet (pinned version OR /latest failed), fetch up to 100
|
||||||
if [[ -z "$releases_json" ]]; then
|
if [[ -z "$releases_json" ]]; then
|
||||||
# Fetch releases and exclude drafts/prereleases
|
# Fetch releases and exclude drafts/prereleases
|
||||||
@ -2644,10 +2644,50 @@ function setup_hwaccel() {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# For AMD CPUs without discrete GPU (APUs)
|
# For AMD GPUs, firmware-amd-graphics is needed but requires non-free repositories
|
||||||
if [[ "$cpu_vendor" == "AuthenticAMD" && -n "$gpu_vendor" ]]; then
|
if [[ "$os_id" == "debian" ]]; then
|
||||||
$STD apt -y install libdrm-amdgpu1 firmware-amd-graphics || true
|
# Add non-free-firmware repository if not already present
|
||||||
|
if [[ ! -f /etc/apt/sources.list.d/non-free-firmware.sources ]]; then
|
||||||
|
if [[ "$os_codename" == "bookworm" ]]; then
|
||||||
|
cat <<EOF >/etc/apt/sources.list.d/non-free-firmware.sources
|
||||||
|
Types: deb
|
||||||
|
URIs: http://deb.debian.org/debian
|
||||||
|
Suites: bookworm bookworm-updates
|
||||||
|
Components: non-free-firmware
|
||||||
|
|
||||||
|
Types: deb
|
||||||
|
URIs: http://deb.debian.org/debian-security
|
||||||
|
Suites: bookworm-security
|
||||||
|
Components: non-free-firmware
|
||||||
|
EOF
|
||||||
|
elif [[ "$os_codename" == "trixie" || "$os_codename" == "sid" ]]; then
|
||||||
|
cat <<EOF >/etc/apt/sources.list.d/non-free-firmware.sources
|
||||||
|
Types: deb
|
||||||
|
URIs: http://deb.debian.org/debian
|
||||||
|
Suites: trixie trixie-updates
|
||||||
|
Components: non-free-firmware
|
||||||
|
|
||||||
|
Types: deb
|
||||||
|
URIs: http://deb.debian.org/debian-security
|
||||||
|
Suites: trixie-security
|
||||||
|
Components: non-free-firmware
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
$STD apt update
|
||||||
|
fi
|
||||||
|
elif [[ "$os_id" == "ubuntu" ]]; then
|
||||||
|
# For Ubuntu, ensure multiverse and restricted are enabled (usually default)
|
||||||
|
# firmware-amd-graphics is in multiverse/restricted
|
||||||
|
if ! grep -qE '^deb.*multiverse' /etc/apt/sources.list /etc/apt/sources.list.d/*.list 2>/dev/null; then
|
||||||
|
$STD add-apt-repository -y multiverse
|
||||||
|
$STD apt update
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Now install AMD firmware and libdrm for both Debian and Ubuntu
|
||||||
|
$STD apt -y install libdrm-amdgpu1 firmware-amd-graphics || {
|
||||||
|
msg_warn "Failed to install AMD firmware - may need manual installation"
|
||||||
|
}
|
||||||
;;
|
;;
|
||||||
NVIDIA)
|
NVIDIA)
|
||||||
# NVIDIA needs manual driver setup - skip for now
|
# NVIDIA needs manual driver setup - skip for now
|
||||||
|
|||||||
Reference in New Issue
Block a user