mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-03-24 10:53:00 +01:00
Compare commits
3 Commits
refactor/t
...
chore/upda
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76117d3b69 | ||
|
|
283e762b83 | ||
|
|
15b5542ad6 |
2
.github/workflows/close-tteck-issues.yaml
generated
vendored
2
.github/workflows/close-tteck-issues.yaml
generated
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
const message = `Hello, it looks like you are referencing the **old tteck repo**.
|
||||
|
||||
This repository is no longer used for active scripts.
|
||||
**Please update your bookmarks** and use: [https://helper-scripts.com](https://helper-scripts.com)
|
||||
**Please update your bookmarks** and use: [https://community-scripts.com](https://community-scripts.com)
|
||||
|
||||
Also make sure your Bash command starts with:
|
||||
\`\`\`bash
|
||||
|
||||
28
CHANGELOG.md
28
CHANGELOG.md
@@ -428,34 +428,6 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
## 2026-03-23
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- Alpine-Borgbackup-Server ([#13219](https://github.com/community-scripts/ProxmoxVE/pull/13219))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- NginxProxyManager: build OpenResty from source via GitHub releases [@MickLesk](https://github.com/MickLesk) ([#13134](https://github.com/community-scripts/ProxmoxVE/pull/13134))
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Tracearr: modify service restart and modify build ressources [@MickLesk](https://github.com/MickLesk) ([#13230](https://github.com/community-scripts/ProxmoxVE/pull/13230))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- Kometa: optimize config.yml sed patterns, add Quickstart integration [@MickLesk](https://github.com/MickLesk) ([#13198](https://github.com/community-scripts/ProxmoxVE/pull/13198))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- Refactor: nginxproxymanager update and OpenResty flow [@MickLesk](https://github.com/MickLesk) ([#13216](https://github.com/community-scripts/ProxmoxVE/pull/13216))
|
||||
- Refactor: PartDB [@MickLesk](https://github.com/MickLesk) ([#13229](https://github.com/community-scripts/ProxmoxVE/pull/13229))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- core: alpine - Improve network connectivity and DNS checks [@MickLesk](https://github.com/MickLesk) ([#13222](https://github.com/community-scripts/ProxmoxVE/pull/13222))
|
||||
- core: allow /31 and /32 CIDR with out-of-subnet gateway [@MickLesk](https://github.com/MickLesk) ([#13231](https://github.com/community-scripts/ProxmoxVE/pull/13231))
|
||||
|
||||
## 2026-03-22
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<p><em>A Community Legacy in Memory of @tteck</em></p>
|
||||
|
||||
<p>
|
||||
<a href="https://helper-scripts.com">
|
||||
<a href="https://community-scripts.com">
|
||||
<img src="https://img.shields.io/badge/🌐_Website-Visit-4c9b3f?style=for-the-badge&labelColor=2d3748" alt="Website" />
|
||||
</a>
|
||||
<a href="https://discord.gg/3AnUqsXnmK">
|
||||
|
||||
@@ -73,7 +73,7 @@ function update_script() {
|
||||
$STD curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/v2.23.0/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin
|
||||
$STD filebrowser config init -a '0.0.0.0'
|
||||
$STD filebrowser config set -a '0.0.0.0'
|
||||
$STD filebrowser users add admin helper-scripts.com --perm.admin
|
||||
$STD filebrowser users add admin community-scripts.com --perm.admin
|
||||
msg_ok "Installed FileBrowser"
|
||||
|
||||
msg_info "Creating Service"
|
||||
@@ -93,7 +93,7 @@ WantedBy=default.target" >$service_path
|
||||
|
||||
msg_ok "Completed successfully!\n"
|
||||
echo -e "FileBrowser should be reachable by going to the following URL.
|
||||
${BL}http://$LOCAL_IP:8080${CL} admin|helper-scripts.com\n"
|
||||
${BL}http://$LOCAL_IP:8080${CL} admin|community-scripts.com\n"
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -102,6 +102,7 @@ EOF
|
||||
msg_ok "Built OpenResty"
|
||||
fi
|
||||
|
||||
cd /root
|
||||
if [ -d /opt/certbot ]; then
|
||||
msg_info "Updating Certbot"
|
||||
$STD /opt/certbot/bin/pip install --upgrade pip setuptools wheel
|
||||
|
||||
@@ -68,7 +68,7 @@ function update_script() {
|
||||
$STD curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash
|
||||
$STD filebrowser config init -a '0.0.0.0'
|
||||
$STD filebrowser config set -a '0.0.0.0'
|
||||
$STD filebrowser users add admin helper-scripts.com --perm.admin
|
||||
$STD filebrowser users add admin community-scripts.com --perm.admin
|
||||
msg_ok "Installed FileBrowser"
|
||||
|
||||
msg_info "Creating Service"
|
||||
@@ -90,7 +90,7 @@ EOF
|
||||
|
||||
msg_ok "Completed successfully!\n"
|
||||
echo -e "FileBrowser should be reachable by going to the following URL.
|
||||
${BL}http://$LOCAL_IP:8080${CL} admin|helper-scripts.com\n"
|
||||
${BL}http://$LOCAL_IP:8080${CL} admin|community-scripts.com\n"
|
||||
exit
|
||||
fi
|
||||
if [ "$UPD" == "4" ]; then
|
||||
|
||||
@@ -50,7 +50,7 @@ function update_script() {
|
||||
/opt/semaphore/config.json
|
||||
SEM_PW=$(cat ~/semaphore.creds)
|
||||
systemctl start semaphore
|
||||
$STD semaphore user add --admin --login admin --email admin@helper-scripts.com --name Administrator --password "${SEM_PW}" --config /opt/semaphore/config.json
|
||||
$STD semaphore user add --admin --login admin --email admin@community-scripts.com --name Administrator --password "${SEM_PW}" --config /opt/semaphore/config.json
|
||||
|
||||
msg_ok "Moved from BoltDB to SQLite"
|
||||
fi
|
||||
|
||||
@@ -62,10 +62,10 @@ expect "Email address"
|
||||
send "\r"
|
||||
|
||||
expect "Password"
|
||||
send "helper-scripts.com\r"
|
||||
send "community-scripts.com\r"
|
||||
|
||||
expect "Password (again)"
|
||||
send "helper-scripts.com\r"
|
||||
send "community-scripts.com\r"
|
||||
|
||||
expect eof
|
||||
EOF
|
||||
|
||||
@@ -58,7 +58,7 @@ service:
|
||||
use_prerelease: false
|
||||
dashboard:
|
||||
icon: https://raw.githubusercontent.com/community-scripts/ProxmoxVE/refs/heads/main/misc/images/logo.png
|
||||
icon_link_to: https://helper-scripts.com/
|
||||
icon_link_to: https://community-scripts.com/
|
||||
web_url: https://github.com/community-scripts/ProxmoxVE/releases
|
||||
EOF
|
||||
msg_ok "Setup Config"
|
||||
|
||||
@@ -17,7 +17,7 @@ fetch_and_deploy_gh_release "inspircd" "inspircd/inspircd" "binary" "latest" "/o
|
||||
|
||||
msg_info "Configuring InspIRCd"
|
||||
cat <<EOF >/etc/inspircd/inspircd.conf
|
||||
<define name="networkDomain" value="helper-scripts.com">
|
||||
<define name="networkDomain" value="community-scripts.com">
|
||||
<define name="networkName" value="Proxmox VE Helper-Scripts">
|
||||
|
||||
<server
|
||||
|
||||
@@ -55,10 +55,10 @@ $STD expect <<EOF
|
||||
set timeout -1
|
||||
log_user 0
|
||||
|
||||
spawn bin/console kimai:user:create admin admin@helper-scripts.com ROLE_SUPER_ADMIN
|
||||
spawn bin/console kimai:user:create admin admin@community-scripts.com ROLE_SUPER_ADMIN
|
||||
|
||||
expect "Please enter the password:"
|
||||
send "helper-scripts.com\r"
|
||||
send "community-scripts.com\r"
|
||||
|
||||
expect eof
|
||||
EOF
|
||||
|
||||
@@ -33,7 +33,7 @@ $STD yarn config set ignore-engines true
|
||||
$STD yarn install
|
||||
$STD yarn run production
|
||||
$STD php artisan key:generate
|
||||
$STD php artisan setup:production --email=admin@helper-scripts.com --password=helper-scripts.com --force
|
||||
$STD php artisan setup:production --email=admin@community-scripts.com --password=community-scripts.com --force
|
||||
chown -R www-data:www-data /opt/monica
|
||||
chmod -R 775 /opt/monica/storage
|
||||
echo "* * * * * root php /opt/monica/artisan schedule:run >> /dev/null 2>&1" >>/etc/crontab
|
||||
|
||||
@@ -60,7 +60,7 @@ read -r -p "${TAB3}Enter your ACME Email: " ACME_EMAIL_INPUT
|
||||
yq -i "
|
||||
.services.npmplus.environment |=
|
||||
(map(select(. != \"TZ=*\" and . != \"ACME_EMAIL=*\" and . != \"INITIAL_ADMIN_EMAIL=*\" and . != \"INITIAL_ADMIN_PASSWORD=*\")) +
|
||||
[\"TZ=$TZ_INPUT\", \"ACME_EMAIL=$ACME_EMAIL_INPUT\", \"INITIAL_ADMIN_EMAIL=admin@local.com\", \"INITIAL_ADMIN_PASSWORD=helper-scripts.com\"])
|
||||
[\"TZ=$TZ_INPUT\", \"ACME_EMAIL=$ACME_EMAIL_INPUT\", \"INITIAL_ADMIN_EMAIL=admin@local.com\", \"INITIAL_ADMIN_PASSWORD=community-scripts.com\"])
|
||||
" /opt/compose.yaml
|
||||
|
||||
msg_info "Building and Starting NPMplus (Patience)"
|
||||
|
||||
@@ -99,7 +99,7 @@ PHOTOPRISM_DEBUG='false'
|
||||
PHOTOPRISM_LOG_LEVEL='info'
|
||||
|
||||
# Site Info
|
||||
PHOTOPRISM_SITE_CAPTION='https://Helper-Scripts.com'
|
||||
PHOTOPRISM_SITE_CAPTION='https://community-scripts.com'
|
||||
PHOTOPRISM_SITE_DESCRIPTION=''
|
||||
PHOTOPRISM_SITE_AUTHOR=''
|
||||
EOF
|
||||
|
||||
@@ -40,7 +40,7 @@ cat <<EOF >/opt/semaphore/config.json
|
||||
"access_key_encryption": "${SEM_KEY}"
|
||||
}
|
||||
EOF
|
||||
$STD semaphore user add --admin --login admin --email admin@helper-scripts.com --name Administrator --password "${SEM_PW}" --config /opt/semaphore/config.json
|
||||
$STD semaphore user add --admin --login admin --email admin@community-scripts.com --name Administrator --password "${SEM_PW}" --config /opt/semaphore/config.json
|
||||
echo "${SEM_PW}" >~/semaphore.creds
|
||||
msg_ok "Setup Semaphore"
|
||||
|
||||
|
||||
@@ -627,8 +627,8 @@ post_to_api() {
|
||||
|
||||
[[ "${DEV_MODE:-}" == "true" ]] && echo "[DEBUG] post_to_api() DIAGNOSTICS=$DIAGNOSTICS RANDOM_UUID=$RANDOM_UUID NSAPP=$NSAPP" >&2
|
||||
|
||||
# Set type for later status updates (respect pre-set value, e.g. "turnkey")
|
||||
TELEMETRY_TYPE="${TELEMETRY_TYPE:-lxc}"
|
||||
# Set type for later status updates
|
||||
TELEMETRY_TYPE="lxc"
|
||||
|
||||
local pve_version=""
|
||||
if command -v pveversion &>/dev/null; then
|
||||
@@ -664,7 +664,7 @@ post_to_api() {
|
||||
{
|
||||
"random_id": "${RANDOM_UUID}",
|
||||
"execution_id": "${EXECUTION_ID:-${RANDOM_UUID}}",
|
||||
"type": "${TELEMETRY_TYPE}",
|
||||
"type": "lxc",
|
||||
"nsapp": "${NSAPP:-unknown}",
|
||||
"status": "installing",
|
||||
"ct_type": ${CT_TYPE:-1},
|
||||
|
||||
@@ -5672,7 +5672,7 @@ description() {
|
||||
DESCRIPTION=$(
|
||||
cat <<EOF
|
||||
<div align='center'>
|
||||
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<a href='https://community-scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -594,7 +594,7 @@ set_description() {
|
||||
DESCRIPTION=$(
|
||||
cat <<EOF
|
||||
<div align='center'>
|
||||
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<a href='https://community-scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -165,9 +165,9 @@ function install() {
|
||||
else
|
||||
read -rp "${TAB}Set admin username [admin]: " admin_user
|
||||
admin_user=${admin_user:-admin}
|
||||
read -rsp "${TAB}Set admin password [helper-scripts.com]: " admin_pass
|
||||
read -rsp "${TAB}Set admin password [community-scripts.com]: " admin_pass
|
||||
echo ""
|
||||
admin_pass=${admin_pass:-helper-scripts.com}
|
||||
admin_pass=${admin_pass:-community-scripts.com}
|
||||
msg_ok "Configured with admin user: ${admin_user}"
|
||||
fi
|
||||
|
||||
|
||||
@@ -201,9 +201,9 @@ server:
|
||||
- neverWatchPath: "/lost+found"
|
||||
auth:
|
||||
adminUsername: admin
|
||||
adminPassword: helper-scripts.com
|
||||
adminPassword: community-scripts.com
|
||||
EOF
|
||||
msg_ok "Configured with default admin (admin / helper-scripts.com)"
|
||||
msg_ok "Configured with default admin (admin / community-scripts.com)"
|
||||
fi
|
||||
|
||||
msg_info "Creating service"
|
||||
|
||||
@@ -140,8 +140,8 @@ if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
cd /usr/local/community-scripts
|
||||
filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
||||
filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
||||
filebrowser users add admin helper-scripts.com --perm.admin --database "$DB_PATH" &>/dev/null
|
||||
msg_ok "Default authentication configured (admin:helper-scripts.com)"
|
||||
filebrowser users add admin community-scripts.com --perm.admin --database "$DB_PATH" &>/dev/null
|
||||
msg_ok "Default authentication configured (admin:community-scripts.com)"
|
||||
fi
|
||||
|
||||
msg_info "Creating service"
|
||||
|
||||
@@ -1,23 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Copyright (c) 2021-2026 tteck
|
||||
# Author: tteck (tteckster)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# License: MIT
|
||||
# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
|
||||
# Source shared libraries
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func)
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
||||
load_functions
|
||||
catch_errors
|
||||
|
||||
APP="TurnKey LXC"
|
||||
NSAPP="turnkey"
|
||||
DIAGNOSTICS="no"
|
||||
METHOD="default"
|
||||
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
|
||||
EXECUTION_ID="${RANDOM_UUID}"
|
||||
|
||||
header_info() {
|
||||
function header_info {
|
||||
clear
|
||||
cat <<"EOF"
|
||||
______ __ __ __ _ _______
|
||||
@@ -28,343 +15,281 @@ header_info() {
|
||||
EOF
|
||||
}
|
||||
|
||||
# Validate if a container ID is available (cluster-aware)
|
||||
validate_container_id() {
|
||||
set -euo pipefail
|
||||
shopt -s expand_aliases
|
||||
alias die='EXIT=$? LINE=$LINENO error_exit'
|
||||
trap die ERR
|
||||
function error_exit() {
|
||||
trap - ERR
|
||||
local DEFAULT='Unknown failure occured.'
|
||||
local REASON="\e[97m${1:-$DEFAULT}\e[39m"
|
||||
local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE"
|
||||
msg "$FLAG $REASON" 1>&2
|
||||
[ ! -z ${CTID-} ] && cleanup_ctid
|
||||
exit $EXIT
|
||||
}
|
||||
function warn() {
|
||||
local REASON="\e[97m$1\e[39m"
|
||||
local FLAG="\e[93m[WARNING]\e[39m"
|
||||
msg "$FLAG $REASON"
|
||||
}
|
||||
function info() {
|
||||
local REASON="$1"
|
||||
local FLAG="\e[36m[INFO]\e[39m"
|
||||
msg "$FLAG $REASON"
|
||||
}
|
||||
function msg() {
|
||||
local TEXT="$1"
|
||||
echo -e "$TEXT"
|
||||
}
|
||||
function validate_container_id() {
|
||||
local ctid="$1"
|
||||
[[ "$ctid" =~ ^[0-9]+$ ]] || return 1
|
||||
|
||||
# Cluster-wide check via pvesh
|
||||
if command -v pvesh &>/dev/null; then
|
||||
local cluster_ids
|
||||
cluster_ids=$(pvesh get /cluster/resources --type vm --output-format json 2>/dev/null |
|
||||
grep -oP '"vmid":\s*\K[0-9]+' 2>/dev/null || true)
|
||||
if [[ -n "$cluster_ids" ]] && echo "$cluster_ids" | grep -qw "$ctid"; then
|
||||
return 1
|
||||
fi
|
||||
# Check if ID is numeric
|
||||
if ! [[ "$ctid" =~ ^[0-9]+$ ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Local fallback
|
||||
# Check if config file exists for VM or LXC
|
||||
if [[ -f "/etc/pve/qemu-server/${ctid}.conf" ]] || [[ -f "/etc/pve/lxc/${ctid}.conf" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check all cluster nodes
|
||||
if [[ -d "/etc/pve/nodes" ]]; then
|
||||
for node_dir in /etc/pve/nodes/*/; do
|
||||
if [[ -f "${node_dir}qemu-server/${ctid}.conf" ]] || [[ -f "${node_dir}lxc/${ctid}.conf" ]]; then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Check LVM volumes
|
||||
# Check if ID is used in LVM logical volumes
|
||||
if lvs --noheadings -o lv_name 2>/dev/null | grep -qE "(^|[-_])${ctid}($|[-_])"; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
get_valid_container_id() {
|
||||
local suggested_id="${1:-$(pvesh get /cluster/nextid 2>/dev/null || echo 100)}"
|
||||
function get_valid_container_id() {
|
||||
local suggested_id="${1:-$(pvesh get /cluster/nextid)}"
|
||||
while ! validate_container_id "$suggested_id"; do
|
||||
suggested_id=$((suggested_id + 1))
|
||||
done
|
||||
echo "$suggested_id"
|
||||
}
|
||||
|
||||
cleanup_ctid() {
|
||||
if pct status "$CTID" &>/dev/null; then
|
||||
if [[ "$(pct status "$CTID" | awk '{print $2}')" == "running" ]]; then
|
||||
pct stop "$CTID"
|
||||
function cleanup_ctid() {
|
||||
if pct status $CTID &>/dev/null; then
|
||||
if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then
|
||||
pct stop $CTID
|
||||
fi
|
||||
pct destroy "$CTID"
|
||||
pct destroy $CTID
|
||||
fi
|
||||
}
|
||||
|
||||
select_storage() {
|
||||
local class="$1" content content_label
|
||||
case "$class" in
|
||||
container)
|
||||
content='rootdir'
|
||||
content_label='Container'
|
||||
;;
|
||||
template)
|
||||
content='vztmpl'
|
||||
content_label='Container template'
|
||||
;;
|
||||
*)
|
||||
msg_error "Invalid storage class '$class'"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
local -a MENU=()
|
||||
local MSG_MAX_LENGTH=0
|
||||
|
||||
while read -r line; do
|
||||
local TAG TYPE FREE ITEM OFFSET=2
|
||||
TAG=$(echo "$line" | awk '{print $1}')
|
||||
TYPE=$(echo "$line" | awk '{printf "%-10s", $2}')
|
||||
FREE=$(echo "$line" | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}')
|
||||
ITEM=" Type: $TYPE Free: $FREE "
|
||||
((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=$((${#ITEM} + OFFSET))
|
||||
MENU+=("$TAG" "$ITEM" "OFF")
|
||||
done < <(pvesm status -content "$content" | awk 'NR>1')
|
||||
|
||||
if [[ $((${#MENU[@]} / 3)) -eq 0 ]]; then
|
||||
msg_error "'$content_label' needs to be selected for at least one storage location."
|
||||
return 1
|
||||
elif [[ $((${#MENU[@]} / 3)) -eq 1 ]]; then
|
||||
printf '%s' "${MENU[0]}"
|
||||
else
|
||||
local STORAGE
|
||||
while [[ -z "${STORAGE:+x}" ]]; do
|
||||
STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
|
||||
"Which storage pool for the ${content_label,,}?\n\n" \
|
||||
16 $((MSG_MAX_LENGTH + 23)) 6 \
|
||||
"${MENU[@]}" 3>&1 1>&2 2>&3) || exit_script
|
||||
done
|
||||
printf '%s' "$STORAGE"
|
||||
fi
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# MAIN
|
||||
# ==============================================================================
|
||||
|
||||
# Cleanup on error: destroy container, report telemetry, and restart monitor
|
||||
turnkey_cleanup() {
|
||||
local exit_code=$?
|
||||
if [[ $exit_code -ne 0 ]]; then
|
||||
# Report failure to telemetry
|
||||
if [[ "${POST_TO_API_DONE:-}" == "true" && "${POST_UPDATE_DONE:-}" != "true" ]]; then
|
||||
post_update_to_api "failed" "$exit_code" 2>/dev/null || true
|
||||
fi
|
||||
# Destroy failed container
|
||||
if [[ -n "${CTID:-}" ]]; then
|
||||
cleanup_ctid 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
if [[ -f /etc/systemd/system/ping-instances.service ]]; then
|
||||
systemctl start ping-instances.service 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
trap turnkey_cleanup EXIT
|
||||
|
||||
# Stop Proxmox VE Monitor-All if running
|
||||
if systemctl is-active -q ping-instances.service; then
|
||||
systemctl stop ping-instances.service
|
||||
fi
|
||||
|
||||
pve_check
|
||||
shell_check
|
||||
root_check
|
||||
|
||||
# Read diagnostics preference (same logic as build.func diagnostics_check)
|
||||
DIAG_CONFIG="/usr/local/community-scripts/diagnostics"
|
||||
if [[ -f "$DIAG_CONFIG" ]]; then
|
||||
DIAGNOSTICS=$(awk -F '=' '/^DIAGNOSTICS/ {print $2}' "$DIAG_CONFIG") || true
|
||||
DIAGNOSTICS="${DIAGNOSTICS:-no}"
|
||||
fi
|
||||
|
||||
header_info
|
||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "TurnKey LXCs" --yesno \
|
||||
"This will allow for the creation of one of the many TurnKey LXC Containers. Proceed?" 10 68 || exit_script
|
||||
|
||||
# Update template catalog early so the menu reflects the latest available templates
|
||||
msg_info "Updating LXC template list"
|
||||
pveam update >/dev/null
|
||||
msg_ok "Updated LXC template list"
|
||||
|
||||
# Build TurnKey selection menu dynamically from available templates
|
||||
declare -A TURNKEY_TEMPLATES
|
||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "TurnKey LXCs" --yesno "This will allow for the creation of one of the many TurnKey LXC Containers. Proceed?" 10 68
|
||||
TURNKEY_MENU=()
|
||||
MSG_MAX_LENGTH=0
|
||||
while IFS=$'\t' read -r TEMPLATE_FILE TAG ITEM; do
|
||||
TURNKEY_TEMPLATES["$TAG"]="$TEMPLATE_FILE"
|
||||
while read -r TAG ITEM; do
|
||||
OFFSET=2
|
||||
((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=$((${#ITEM} + OFFSET))
|
||||
((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET
|
||||
TURNKEY_MENU+=("$TAG" "$ITEM " "OFF")
|
||||
done < <(pveam available -section turnkeylinux | awk '{
|
||||
tpl = $2
|
||||
if (match(tpl, /debian-([0-9]+)-turnkey-([^_]+)_([^_]+)_/, m)) {
|
||||
app = m[2]; deb = m[1]; ver = m[3]
|
||||
display = app
|
||||
gsub(/-/, " ", display)
|
||||
n = split(display, words, " ")
|
||||
display = ""
|
||||
for (i = 1; i <= n; i++) {
|
||||
words[i] = toupper(substr(words[i], 1, 1)) substr(words[i], 2)
|
||||
display = display (i > 1 ? " " : "") words[i]
|
||||
}
|
||||
tag = app "-" deb
|
||||
printf "%s\t%s\t%s | Debian %s | %s\n", tpl, tag, display, deb, ver
|
||||
}
|
||||
}' | sort -t$'\t' -k2,2)
|
||||
done < <(
|
||||
cat <<EOF
|
||||
ansible Ansible
|
||||
bookstack BookStack
|
||||
core Core
|
||||
faveo-helpdesk Faveo Helpdesk
|
||||
fileserver File Server
|
||||
gallery Gallery
|
||||
gameserver Game Server
|
||||
gitea Gitea
|
||||
gitlab GitLab
|
||||
invoice-ninja Invoice Ninja
|
||||
mediaserver Media Server
|
||||
nextcloud Nextcloud
|
||||
observium Observium
|
||||
odoo Odoo
|
||||
openldap OpenLDAP
|
||||
openvpn OpenVPN
|
||||
owncloud ownCloud
|
||||
phpbb phpBB
|
||||
torrentserver Torrent Server
|
||||
wireguard WireGuard
|
||||
wordpress Wordpress
|
||||
zoneminder ZoneMinder
|
||||
EOF
|
||||
)
|
||||
turnkey=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "TurnKey LXCs" --radiolist "\nSelect a TurnKey LXC to create:\n" 16 $((MSG_MAX_LENGTH + 58)) 6 "${TURNKEY_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"')
|
||||
[ -z "$turnkey" ] && {
|
||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "No TurnKey LXC Selected" --msgbox "It appears that no TurnKey LXC container was selected" 10 68
|
||||
msg "Done"
|
||||
exit
|
||||
}
|
||||
|
||||
if [[ ${#TURNKEY_MENU[@]} -eq 0 ]]; then
|
||||
msg_error "No TurnKey templates found. Check your internet connection or template repository."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
selected=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "TurnKey LXCs" --radiolist \
|
||||
"\nSelect a TurnKey LXC to create:\n" 20 $((MSG_MAX_LENGTH + 58)) 12 \
|
||||
"${TURNKEY_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit_script
|
||||
|
||||
if [[ -z "$selected" ]]; then
|
||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "No TurnKey LXC Selected" \
|
||||
--msgbox "It appears that no TurnKey LXC container was selected" 10 68
|
||||
exit_script
|
||||
fi
|
||||
|
||||
# Extract template filename and app name from selection
|
||||
TEMPLATE="${TURNKEY_TEMPLATES[$selected]}"
|
||||
turnkey="${selected%-*}"
|
||||
|
||||
# Generate random password
|
||||
# Setup script environment
|
||||
PASS="$(openssl rand -base64 8)"
|
||||
|
||||
# Prompt for Container ID
|
||||
NEXT_ID=$(pvesh get /cluster/nextid 2>/dev/null || echo 100)
|
||||
# Prompt user to confirm container ID
|
||||
while true; do
|
||||
CTID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Container ID" \
|
||||
--inputbox "Enter the container ID..." 8 40 "$NEXT_ID" 3>&1 1>&2 2>&3) || exit_script
|
||||
CTID=$(whiptail --backtitle "Container ID" --title "Choose the Container ID" --inputbox "Enter the container ID..." 8 40 $(pvesh get /cluster/nextid) 3>&1 1>&2 2>&3)
|
||||
|
||||
if [[ -z "$CTID" ]]; then
|
||||
msg_error "No Container ID selected"
|
||||
exit_script
|
||||
fi
|
||||
# Check if user cancelled
|
||||
[ -z "$CTID" ] && die "No Container ID selected"
|
||||
|
||||
# Validate Container ID
|
||||
if ! validate_container_id "$CTID"; then
|
||||
SUGGESTED_ID=$(get_valid_container_id "$CTID")
|
||||
if whiptail --backtitle "Proxmox VE Helper Scripts" --title "ID Already In Use" --yesno \
|
||||
"Container/VM ID $CTID is already in use.\n\nWould you like to use the next available ID ($SUGGESTED_ID)?" 10 58; then
|
||||
if whiptail --backtitle "Container ID" --title "ID Already In Use" --yesno "Container/VM ID $CTID is already in use.\n\nWould you like to use the next available ID ($SUGGESTED_ID)?" 10 58; then
|
||||
CTID="$SUGGESTED_ID"
|
||||
break
|
||||
fi
|
||||
# User declined, loop back to input
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Prompt for Hostname
|
||||
HOST_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Hostname" \
|
||||
--inputbox "Enter the container hostname..." 8 40 "turnkey-${turnkey}" 3>&1 1>&2 2>&3) || exit_script
|
||||
|
||||
# Container options
|
||||
PCT_OPTIONS=(
|
||||
-features keyctl=1,nesting=1
|
||||
-hostname "$HOST_NAME"
|
||||
-tags community-script
|
||||
-onboot 1
|
||||
-cores 2
|
||||
-memory 2048
|
||||
-password "$PASS"
|
||||
-net0 name=eth0,bridge=vmbr0,ip=dhcp
|
||||
-unprivileged 1
|
||||
-arch "$(dpkg --print-architecture)"
|
||||
# Prompt user to confirm Hostname
|
||||
HOST_NAME=$(whiptail --backtitle "Hostname" --title "Choose the Hostname" --inputbox "Enter the containers Hostname..." 8 40 "turnkey-${turnkey}" 3>&1 1>&2 2>&3)
|
||||
PCT_OPTIONS="
|
||||
-features keyctl=1,nesting=1
|
||||
-hostname $HOST_NAME
|
||||
-tags community-script
|
||||
-onboot 1
|
||||
-cores 2
|
||||
-memory 2048
|
||||
-password $PASS
|
||||
-net0 name=eth0,bridge=vmbr0,ip=dhcp
|
||||
-unprivileged 1
|
||||
"
|
||||
DEFAULT_PCT_OPTIONS=(
|
||||
-arch $(dpkg --print-architecture)
|
||||
)
|
||||
|
||||
# Storage selection
|
||||
TEMPLATE_STORAGE=$(select_storage template) || {
|
||||
msg_error "Failed to select template storage"
|
||||
exit 1
|
||||
}
|
||||
msg_ok "Using '${BL}${TEMPLATE_STORAGE}${CL}' for template storage"
|
||||
# Set the CONTENT and CONTENT_LABEL variables
|
||||
function select_storage() {
|
||||
local CLASS=$1
|
||||
local CONTENT
|
||||
local CONTENT_LABEL
|
||||
case $CLASS in
|
||||
container)
|
||||
CONTENT='rootdir'
|
||||
CONTENT_LABEL='Container'
|
||||
;;
|
||||
template)
|
||||
CONTENT='vztmpl'
|
||||
CONTENT_LABEL='Container template'
|
||||
;;
|
||||
*) false || die "Invalid storage class." ;;
|
||||
esac
|
||||
|
||||
CONTAINER_STORAGE=$(select_storage container) || {
|
||||
msg_error "Failed to select container storage"
|
||||
exit 1
|
||||
}
|
||||
msg_ok "Using '${BL}${CONTAINER_STORAGE}${CL}' for container storage"
|
||||
# Query all storage locations
|
||||
local -a MENU
|
||||
while read -r line; do
|
||||
local TAG=$(echo $line | awk '{print $1}')
|
||||
local TYPE=$(echo $line | awk '{printf "%-10s", $2}')
|
||||
local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}')
|
||||
local ITEM=" Type: $TYPE Free: $FREE "
|
||||
local OFFSET=2
|
||||
if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then
|
||||
local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))
|
||||
fi
|
||||
MENU+=("$TAG" "$ITEM" "OFF")
|
||||
done < <(pvesm status -content $CONTENT | awk 'NR>1')
|
||||
|
||||
# Download template if not already cached
|
||||
if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE"; then
|
||||
msg_info "Downloading LXC template"
|
||||
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null || {
|
||||
msg_error "Failed to download LXC template '${TEMPLATE}'"
|
||||
exit 1
|
||||
}
|
||||
msg_ok "Downloaded LXC template"
|
||||
# Select storage location
|
||||
if [ $((${#MENU[@]} / 3)) -eq 0 ]; then
|
||||
warn "'$CONTENT_LABEL' needs to be selected for at least one storage location."
|
||||
die "Unable to detect valid storage location."
|
||||
elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then
|
||||
printf ${MENU[0]}
|
||||
else
|
||||
local STORAGE
|
||||
while [ -z "${STORAGE:+x}" ]; do
|
||||
STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
|
||||
"Which storage pool would you like to use for the ${CONTENT_LABEL,,}?\n\n" \
|
||||
16 $(($MSG_MAX_LENGTH + 23)) 6 \
|
||||
"${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted."
|
||||
done
|
||||
printf $STORAGE
|
||||
fi
|
||||
}
|
||||
|
||||
# Get template storage
|
||||
TEMPLATE_STORAGE=$(select_storage template)
|
||||
info "Using '$TEMPLATE_STORAGE' for template storage."
|
||||
|
||||
# Get container storage
|
||||
CONTAINER_STORAGE=$(select_storage container)
|
||||
info "Using '$CONTAINER_STORAGE' for container storage."
|
||||
|
||||
# Update LXC template list
|
||||
msg "Updating LXC template list..."
|
||||
pveam update >/dev/null
|
||||
|
||||
# Get LXC template string
|
||||
mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | awk -v turnkey="${turnkey}" '$0 ~ turnkey {print $2}' | sort -t - -k 2 -V)
|
||||
[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '${turnkey}'."
|
||||
TEMPLATE="${TEMPLATES[-1]}"
|
||||
|
||||
# Download LXC template
|
||||
if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then
|
||||
msg "Downloading LXC template (Patience)..."
|
||||
pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null ||
|
||||
die "A problem occured while downloading the LXC template."
|
||||
fi
|
||||
|
||||
# Add rootfs if not specified
|
||||
[[ " ${PCT_OPTIONS[*]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs "${CONTAINER_STORAGE}:${PCT_DISK_SIZE:-8}")
|
||||
# Create variable for 'pct' options
|
||||
PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}})
|
||||
[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8})
|
||||
|
||||
# Set telemetry variables for the selected turnkey
|
||||
TELEMETRY_TYPE="turnkey"
|
||||
NSAPP="turnkey-${turnkey}"
|
||||
CT_TYPE=1
|
||||
DISK_SIZE="${PCT_DISK_SIZE:-8}"
|
||||
CORE_COUNT=2
|
||||
RAM_SIZE=2048
|
||||
var_os="turnkey"
|
||||
var_version="${turnkey}"
|
||||
# Create LXC
|
||||
msg "Creating LXC container..."
|
||||
pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null ||
|
||||
die "A problem occured while trying to create container."
|
||||
|
||||
# Report installation start to telemetry
|
||||
post_to_api
|
||||
# Save password
|
||||
echo "TurnKey ${turnkey} password: ${PASS}" >>~/turnkey-${turnkey}.creds # file is located in the Proxmox root directory
|
||||
|
||||
# Create LXC container
|
||||
msg_info "Creating LXC container"
|
||||
pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" >/dev/null || {
|
||||
msg_error "Failed to create container"
|
||||
exit 1
|
||||
}
|
||||
msg_ok "Created LXC container (ID: ${BL}${CTID}${CL})"
|
||||
|
||||
# Save credentials securely
|
||||
CREDS_FILE=~/turnkey-${turnkey}.creds
|
||||
echo "TurnKey ${turnkey} password: ${PASS}" >>"$CREDS_FILE"
|
||||
chmod 600 "$CREDS_FILE"
|
||||
|
||||
# Configure TUN device access for VPN-based turnkeys
|
||||
TUN_DEVICE_REQUIRED=("openvpn")
|
||||
# If turnkey is "OpenVPN", add access to the tun device
|
||||
TUN_DEVICE_REQUIRED=("openvpn") # Setup this way in case future turnkeys also need tun access
|
||||
if printf '%s\n' "${TUN_DEVICE_REQUIRED[@]}" | grep -qw "${turnkey}"; then
|
||||
msg_info "Configuring TUN device access for ${turnkey}"
|
||||
{
|
||||
echo "lxc.cgroup2.devices.allow: c 10:200 rwm"
|
||||
echo "lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file 0 0"
|
||||
} >>"/etc/pve/lxc/${CTID}.conf"
|
||||
msg_ok "TUN device access configured"
|
||||
info "${turnkey} requires access to /dev/net/tun on the host. Modifying the container configuration to allow this."
|
||||
echo "lxc.cgroup2.devices.allow: c 10:200 rwm" >>/etc/pve/lxc/${CTID}.conf
|
||||
echo "lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file 0 0" >>/etc/pve/lxc/${CTID}.conf
|
||||
sleep 5
|
||||
fi
|
||||
|
||||
# Start container
|
||||
msg_info "Starting LXC container"
|
||||
msg "Starting LXC Container..."
|
||||
pct start "$CTID"
|
||||
msg_ok "Started LXC container"
|
||||
sleep 10
|
||||
|
||||
# Detect container IP
|
||||
msg_info "Detecting IP address"
|
||||
# Get container IP
|
||||
set +euo pipefail # Turn off error checking
|
||||
max_attempts=5
|
||||
attempt=1
|
||||
IP=""
|
||||
for attempt in $(seq 1 5); do
|
||||
IP=$(pct exec "$CTID" -- ip -4 a show dev eth0 2>/dev/null | grep -oP 'inet \K[^/]+' || true)
|
||||
if [[ -n "$IP" ]]; then
|
||||
while [[ $attempt -le $max_attempts ]]; do
|
||||
IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+')
|
||||
if [[ -n $IP ]]; then
|
||||
break
|
||||
else
|
||||
warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..."
|
||||
sleep 5
|
||||
((attempt++))
|
||||
fi
|
||||
[[ $attempt -lt 5 ]] && sleep 5
|
||||
done
|
||||
|
||||
if [[ -z "$IP" ]]; then
|
||||
msg_warn "IP address not found after 5 attempts"
|
||||
if [[ -z $IP ]]; then
|
||||
warn "Maximum number of attempts reached. IP address not found."
|
||||
IP="NOT FOUND"
|
||||
else
|
||||
msg_ok "IP address: ${BL}${IP}${CL}"
|
||||
fi
|
||||
|
||||
# Report success to telemetry
|
||||
post_update_to_api "done" "none"
|
||||
# Start Proxmox VE Monitor-All if available
|
||||
if [[ -f /etc/systemd/system/ping-instances.service ]]; then
|
||||
systemctl start ping-instances.service
|
||||
fi
|
||||
|
||||
# Success summary
|
||||
# Success message
|
||||
header_info
|
||||
echo
|
||||
msg_ok "TurnKey ${BL}${turnkey}${CL} LXC container '${BL}${CTID}${CL}' was successfully created."
|
||||
info "LXC container '$CTID' was successfully created, and its IP address is ${IP}."
|
||||
echo
|
||||
echo -e " ${TAB}${YW}IP Address:${CL} ${BL}${IP}${CL}"
|
||||
echo -e " ${TAB}${YW}Login:${CL} ${GN}root${CL}"
|
||||
echo -e " ${TAB}${YW}Password:${CL} ${GN}${PASS}${CL}"
|
||||
info "Proceed to the LXC console to complete the setup."
|
||||
echo
|
||||
echo -e " ${TAB}Proceed to the LXC console to complete the TurnKey setup."
|
||||
echo -e " ${TAB}Credentials stored in: ${BL}~/turnkey-${turnkey}.creds${CL}"
|
||||
info "login: root"
|
||||
info "password: $PASS"
|
||||
info "(credentials also stored in the root user's root directory in the 'turnkey-${turnkey}.creds' file.)"
|
||||
echo
|
||||
|
||||
@@ -551,7 +551,7 @@ qm set $VMID \
|
||||
DESCRIPTION=$(
|
||||
cat <<EOF
|
||||
<div align='center'>
|
||||
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<a href='https://community-scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -631,7 +631,7 @@ rm -f "$WORK_FILE"
|
||||
DESCRIPTION=$(
|
||||
cat <<EOF
|
||||
<div align='center'>
|
||||
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<a href='https://community-scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -568,7 +568,7 @@ fi
|
||||
DESCRIPTION=$(
|
||||
cat <<EOF
|
||||
<div align='center'>
|
||||
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<a href='https://community-scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -639,7 +639,7 @@ msg_ok "Resized disk"
|
||||
DESCRIPTION=$(
|
||||
cat <<EOF
|
||||
<div align='center'>
|
||||
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<a href='https://community-scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -622,7 +622,7 @@ qm set $VMID \
|
||||
DESCRIPTION=$(
|
||||
cat <<EOF
|
||||
<div align='center'>
|
||||
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<a href='https://community-scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -546,7 +546,7 @@ qm set $VMID \
|
||||
DESCRIPTION=$(
|
||||
cat <<EOF
|
||||
<div align='center'>
|
||||
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<a href='https://community-scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -605,7 +605,7 @@ msg_ok "Resized disk to ${DISK_SIZE}"
|
||||
DESCRIPTION=$(
|
||||
cat <<EOF
|
||||
<div align='center'>
|
||||
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<a href='https://community-scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -750,7 +750,7 @@ qm resize $VMID scsi0 20G >/dev/null
|
||||
DESCRIPTION=$(
|
||||
cat <<EOF
|
||||
<div align='center'>
|
||||
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<a href='https://community-scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<img src='https://raw.githubusercontent.com/michelroegl-brunner/ProxmoxVE/refs/heads/develop/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -560,7 +560,7 @@ qm set $VMID \
|
||||
DESCRIPTION=$(
|
||||
cat <<EOF
|
||||
<div align='center'>
|
||||
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<a href='https://community-scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -462,7 +462,7 @@ qm set $VMID \
|
||||
DESCRIPTION=$(
|
||||
cat <<EOF
|
||||
<div align='center'>
|
||||
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<a href='https://community-scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -610,7 +610,7 @@ fi
|
||||
DESCRIPTION=$(
|
||||
cat <<EOF
|
||||
<div align='center'>
|
||||
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<a href='https://community-scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -542,7 +542,7 @@ qm set $VMID \
|
||||
DESCRIPTION=$(
|
||||
cat <<EOF
|
||||
<div align='center'>
|
||||
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<a href='https://community-scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -544,7 +544,7 @@ qm set $VMID \
|
||||
DESCRIPTION=$(
|
||||
cat <<EOF
|
||||
<div align='center'>
|
||||
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<a href='https://community-scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -543,7 +543,7 @@ qm set $VMID \
|
||||
DESCRIPTION=$(
|
||||
cat <<EOF
|
||||
<div align='center'>
|
||||
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<a href='https://community-scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -590,7 +590,7 @@ qm resize $VMID scsi0 ${DISK_SIZE} >/dev/null
|
||||
DESCRIPTION=$(
|
||||
cat <<EOF
|
||||
<div align='center'>
|
||||
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<a href='https://community-scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||
</a>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user