mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-02-05 12:53:27 +01:00
Compare commits
1 Commits
github-act
...
automated/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7000d426aa |
22
CHANGELOG.md
22
CHANGELOG.md
@@ -400,28 +400,6 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
## 2026-02-05
|
## 2026-02-05
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- New: SQL-Server 2025 | Refactor SQL-Server 2022 [@MickLesk](https://github.com/MickLesk) ([#11546](https://github.com/community-scripts/ProxmoxVE/pull/11546))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- Refactor: Docker-VM (Multi-OS / Cloud-Init / Stabilization) [@MickLesk](https://github.com/MickLesk) ([#9047](https://github.com/community-scripts/ProxmoxVE/pull/9047))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- cloud-init: add interactive SSH key discovery and selection [@MickLesk](https://github.com/MickLesk) ([#11547](https://github.com/community-scripts/ProxmoxVE/pull/11547))
|
|
||||||
|
|
||||||
### 🌐 Website
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- fix(frontend): theme respective syntax highlighting [@ls-root](https://github.com/ls-root) ([#11565](https://github.com/community-scripts/ProxmoxVE/pull/11565))
|
|
||||||
|
|
||||||
## 2026-02-04
|
## 2026-02-04
|
||||||
|
|
||||||
### 🆕 New Scripts
|
### 🆕 New Scripts
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
_____ ____ __ _____ ___ ____ ___ ______
|
|
||||||
/ ___// __ \ / / / ___/___ ______ _____ _____ |__ \ / __ \__ \ / ____/
|
|
||||||
\__ \/ / / / / / \__ \/ _ \/ ___/ | / / _ \/ ___/ __/ // / / /_/ //___ \
|
|
||||||
___/ / /_/ / / /___ ___/ / __/ / | |/ / __/ / / __// /_/ / __/____/ /
|
|
||||||
/____/\___\_\/_____/ /____/\___/_/ |___/\___/_/ /____/\____/____/_____/
|
|
||||||
|
|
||||||
@@ -27,8 +27,7 @@ function update_script() {
|
|||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
msg_info "Updating SQL Server 2022"
|
msg_info "Updating ${APP} LXC"
|
||||||
rm -f /etc/profile.d/debuginfod.sh /etc/profile.d/debuginfod.csh
|
|
||||||
$STD apt update
|
$STD apt update
|
||||||
$STD apt -y upgrade
|
$STD apt -y upgrade
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: MickLesk (CanbiZ)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://www.microsoft.com/en-us/sql-server/sql-server-2025
|
|
||||||
|
|
||||||
APP="SQL Server 2025"
|
|
||||||
var_tags="${var_tags:-sql;database}"
|
|
||||||
var_cpu="${var_cpu:-2}"
|
|
||||||
var_ram="${var_ram:-2048}"
|
|
||||||
var_disk="${var_disk:-10}"
|
|
||||||
var_os="${var_os:-ubuntu}"
|
|
||||||
var_version="${var_version:-24.04}"
|
|
||||||
var_unprivileged="${var_unprivileged:-0}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
if [[ ! -d /opt/mssql ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
msg_info "Updating SQL Server 2025"
|
|
||||||
rm -f /etc/profile.d/debuginfod.sh /etc/profile.d/debuginfod.csh
|
|
||||||
$STD apt update
|
|
||||||
$STD apt -y upgrade
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following IP:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}${IP}:1433${CL}"
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "SQL Server 2025",
|
|
||||||
"slug": "sqlserver2025",
|
|
||||||
"categories": [
|
|
||||||
8
|
|
||||||
],
|
|
||||||
"date_created": "2026-02-05",
|
|
||||||
"type": "ct",
|
|
||||||
"updateable": true,
|
|
||||||
"privileged": true,
|
|
||||||
"interface_port": 1433,
|
|
||||||
"documentation": "https://learn.microsoft.com/en-us/sql/sql-server/?view=sql-server-ver17",
|
|
||||||
"website": "https://www.microsoft.com/en-us/sql-server/sql-server-2025",
|
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/microsoft-sql-server.webp",
|
|
||||||
"config_path": "",
|
|
||||||
"description": "Script to automatically set up a SQL Server 2025 installation with Ubuntu 24.04 support.",
|
|
||||||
"install_methods": [
|
|
||||||
{
|
|
||||||
"type": "default",
|
|
||||||
"script": "ct/sqlserver2025.sh",
|
|
||||||
"resources": {
|
|
||||||
"cpu": 2,
|
|
||||||
"ram": 2048,
|
|
||||||
"hdd": 10,
|
|
||||||
"os": "Ubuntu",
|
|
||||||
"version": "24.04"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default_credentials": {
|
|
||||||
"username": null,
|
|
||||||
"password": null
|
|
||||||
},
|
|
||||||
"notes": [
|
|
||||||
{
|
|
||||||
"text": "If you choose not to run the installation setup, execute: `/opt/mssql/bin/mssql-conf setup` in LXC shell.",
|
|
||||||
"type": "info"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": "You can setup the admin account 'SA' during installation",
|
|
||||||
"type": "info"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": "Make sure you disable the SA account if you intend to use this in production!",
|
|
||||||
"type": "warning"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": "Ubuntu 24.04 support requires SQL Server 2025 CU1 or later",
|
|
||||||
"type": "info"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -29,10 +29,9 @@ import { ScriptSchema } from "./_schemas/schemas";
|
|||||||
import Categories from "./_components/categories";
|
import Categories from "./_components/categories";
|
||||||
import Note from "./_components/note";
|
import Note from "./_components/note";
|
||||||
|
|
||||||
import { githubGist, nord } from "react-syntax-highlighter/dist/esm/styles/hljs";
|
import { nord } from "react-syntax-highlighter/dist/esm/styles/hljs";
|
||||||
import SyntaxHighlighter from "react-syntax-highlighter";
|
import SyntaxHighlighter from "react-syntax-highlighter";
|
||||||
import { ScriptItem } from "../scripts/_components/script-item";
|
import { ScriptItem } from "../scripts/_components/script-item";
|
||||||
import { useTheme } from "next-themes";
|
|
||||||
|
|
||||||
const initialScript: Script = {
|
const initialScript: Script = {
|
||||||
name: "",
|
name: "",
|
||||||
@@ -59,7 +58,6 @@ const initialScript: Script = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function JSONGenerator() {
|
export default function JSONGenerator() {
|
||||||
const { theme } = useTheme();
|
|
||||||
const [script, setScript] = useState<Script>(initialScript);
|
const [script, setScript] = useState<Script>(initialScript);
|
||||||
const [isCopied, setIsCopied] = useState(false);
|
const [isCopied, setIsCopied] = useState(false);
|
||||||
const [isValid, setIsValid] = useState(false);
|
const [isValid, setIsValid] = useState(false);
|
||||||
@@ -359,7 +357,7 @@ export default function JSONGenerator() {
|
|||||||
|
|
||||||
<SyntaxHighlighter
|
<SyntaxHighlighter
|
||||||
language="json"
|
language="json"
|
||||||
style={theme === "light" ? githubGist : nord}
|
style={nord}
|
||||||
className="mt-4 p-4 bg-secondary rounded shadow overflow-x-scroll"
|
className="mt-4 p-4 bg-secondary rounded shadow overflow-x-scroll"
|
||||||
>
|
>
|
||||||
{JSON.stringify(script, null, 2)}
|
{JSON.stringify(script, null, 2)}
|
||||||
|
|||||||
@@ -14,32 +14,24 @@ network_check
|
|||||||
update_os
|
update_os
|
||||||
|
|
||||||
msg_info "Installing Dependencies"
|
msg_info "Installing Dependencies"
|
||||||
$STD apt install -y coreutils
|
$STD apt install -y \
|
||||||
|
coreutils
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
msg_info "Setting up SQL Server 2022 Repository"
|
msg_info "Setup SQL Server 2022"
|
||||||
setup_deb822_repo \
|
curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc >/dev/null
|
||||||
"mssql-server-2022" \
|
curl -fsSL https://packages.microsoft.com/config/ubuntu/22.04/mssql-server-2022.list | tee /etc/apt/sources.list.d/mssql-server-2022.list >/dev/null
|
||||||
"https://packages.microsoft.com/keys/microsoft.asc" \
|
$STD apt-get update -y
|
||||||
"https://packages.microsoft.com/ubuntu/22.04/mssql-server-2022" \
|
$STD apt-get install -y mssql-server
|
||||||
"./" \
|
msg_ok "Setup Server 2022"
|
||||||
""
|
|
||||||
msg_ok "Repository configured"
|
|
||||||
|
|
||||||
msg_info "Installing SQL Server 2022"
|
|
||||||
$STD apt install -y mssql-server
|
|
||||||
msg_ok "Installed SQL Server 2022"
|
|
||||||
|
|
||||||
msg_info "Installing SQL Server Tools"
|
msg_info "Installing SQL Server Tools"
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
export ACCEPT_EULA=Y
|
export ACCEPT_EULA=Y
|
||||||
setup_deb822_repo \
|
curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | tee /etc/apt/trusted.gpg.d/microsoft.asc >/dev/null
|
||||||
"mssql-release" \
|
curl -fsSL https://packages.microsoft.com/config/ubuntu/22.04/prod.list | tee /etc/apt/sources.list.d/mssql-release.list >/dev/null
|
||||||
"https://packages.microsoft.com/keys/microsoft.asc" \
|
$STD apt-get update
|
||||||
"https://packages.microsoft.com/ubuntu/22.04/prod" \
|
$STD apt-get install -y -qq \
|
||||||
"jammy" \
|
|
||||||
"main"
|
|
||||||
$STD apt-get install -y \
|
|
||||||
mssql-tools18 \
|
mssql-tools18 \
|
||||||
unixodbc-dev
|
unixodbc-dev
|
||||||
echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >>~/.bash_profile
|
echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >>~/.bash_profile
|
||||||
@@ -57,11 +49,6 @@ msg_info "Start Service"
|
|||||||
systemctl enable -q --now mssql-server
|
systemctl enable -q --now mssql-server
|
||||||
msg_ok "Service started"
|
msg_ok "Service started"
|
||||||
|
|
||||||
msg_info "Cleaning up"
|
|
||||||
rm -f /etc/profile.d/debuginfod.sh
|
|
||||||
rm -f /etc/profile.d/debuginfod.csh
|
|
||||||
msg_ok "Cleaned up"
|
|
||||||
|
|
||||||
motd_ssh
|
motd_ssh
|
||||||
customize
|
customize
|
||||||
cleanup_lxc
|
cleanup_lxc
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: MickLesk (CanbiZ)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://www.microsoft.com/en-us/sql-server/sql-server-2025
|
|
||||||
|
|
||||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
|
||||||
color
|
|
||||||
verb_ip6
|
|
||||||
catch_errors
|
|
||||||
setting_up_container
|
|
||||||
network_check
|
|
||||||
update_os
|
|
||||||
|
|
||||||
msg_info "Installing Dependencies"
|
|
||||||
$STD apt install -y coreutils
|
|
||||||
msg_ok "Installed Dependencies"
|
|
||||||
|
|
||||||
msg_info "Setting up SQL Server 2025 Repository"
|
|
||||||
setup_deb822_repo \
|
|
||||||
"mssql-server-2025" \
|
|
||||||
"https://packages.microsoft.com/keys/microsoft.asc" \
|
|
||||||
"https://packages.microsoft.com/ubuntu/24.04/mssql-server-2025" \
|
|
||||||
"./" \
|
|
||||||
""
|
|
||||||
msg_ok "Repository configured"
|
|
||||||
|
|
||||||
msg_info "Installing SQL Server 2025"
|
|
||||||
$STD apt install -y mssql-server
|
|
||||||
msg_ok "Installed SQL Server 2025"
|
|
||||||
|
|
||||||
msg_info "Installing SQL Server Tools"
|
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
|
||||||
export ACCEPT_EULA=Y
|
|
||||||
setup_deb822_repo \
|
|
||||||
"mssql-release" \
|
|
||||||
"https://packages.microsoft.com/keys/microsoft.asc" \
|
|
||||||
"https://packages.microsoft.com/ubuntu/24.04/prod" \
|
|
||||||
"noble" \
|
|
||||||
"main"
|
|
||||||
$STD apt-get install -y \
|
|
||||||
mssql-tools18 \
|
|
||||||
unixodbc-dev
|
|
||||||
echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >>~/.bash_profile
|
|
||||||
source ~/.bash_profile
|
|
||||||
msg_ok "Installed SQL Server Tools"
|
|
||||||
|
|
||||||
read -r -p "${TAB3}Do you want to run the SQL Server setup now? (Later is also possible) <y/N>" prompt
|
|
||||||
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
|
||||||
/opt/mssql/bin/mssql-conf setup
|
|
||||||
else
|
|
||||||
msg_ok "Skipping SQL Server setup. You can run it later with '/opt/mssql/bin/mssql-conf setup'."
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Starting SQL Server Service"
|
|
||||||
systemctl enable -q --now mssql-server
|
|
||||||
msg_ok "Service started"
|
|
||||||
|
|
||||||
msg_info "Cleaning up"
|
|
||||||
rm -f /etc/profile.d/debuginfod.sh /etc/profile.d/debuginfod.csh
|
|
||||||
msg_ok "Cleaned up"
|
|
||||||
|
|
||||||
motd_ssh
|
|
||||||
customize
|
|
||||||
cleanup_lxc
|
|
||||||
@@ -28,210 +28,13 @@
|
|||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# These can be overridden before sourcing this library
|
# These can be overridden before sourcing this library
|
||||||
|
|
||||||
# Disable 'unbound variable' errors for this library (restored at end)
|
|
||||||
_OLD_SET_STATE=$(set +o | grep -E 'set -(e|u|o)')
|
|
||||||
set +u
|
|
||||||
|
|
||||||
CLOUDINIT_DEFAULT_USER="${CLOUDINIT_DEFAULT_USER:-root}"
|
CLOUDINIT_DEFAULT_USER="${CLOUDINIT_DEFAULT_USER:-root}"
|
||||||
CLOUDINIT_DNS_SERVERS="${CLOUDINIT_DNS_SERVERS:-1.1.1.1 8.8.8.8}"
|
CLOUDINIT_DNS_SERVERS="${CLOUDINIT_DNS_SERVERS:-1.1.1.1 8.8.8.8}"
|
||||||
CLOUDINIT_SEARCH_DOMAIN="${CLOUDINIT_SEARCH_DOMAIN:-local}"
|
CLOUDINIT_SEARCH_DOMAIN="${CLOUDINIT_SEARCH_DOMAIN:-local}"
|
||||||
CLOUDINIT_SSH_KEYS="${CLOUDINIT_SSH_KEYS:-}" # Empty by default - user must explicitly provide keys
|
CLOUDINIT_SSH_KEYS="${CLOUDINIT_SSH_KEYS:-/root/.ssh/authorized_keys}"
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# SECTION 2: SSH KEY DISCOVERY AND SELECTION
|
# SECTION 2: HELPER FUNCTIONS
|
||||||
# ==============================================================================
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# _ci_ssh_extract_keys_from_file - Extracts valid SSH public keys from a file
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
function _ci_ssh_extract_keys_from_file() {
|
|
||||||
local file="$1"
|
|
||||||
[[ -f "$file" && -r "$file" ]] || return 0
|
|
||||||
grep -E '^(ssh-(rsa|ed25519|dss|ecdsa)|ecdsa-sha2-)' "$file" 2>/dev/null || true
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# _ci_ssh_discover_files - Scans standard paths for SSH keys
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
function _ci_ssh_discover_files() {
|
|
||||||
local -a cand=()
|
|
||||||
shopt -s nullglob
|
|
||||||
cand+=(/root/.ssh/authorized_keys /root/.ssh/authorized_keys2)
|
|
||||||
cand+=(/root/.ssh/*.pub)
|
|
||||||
cand+=(/etc/ssh/authorized_keys /etc/ssh/authorized_keys.d/*)
|
|
||||||
shopt -u nullglob
|
|
||||||
printf '%s\0' "${cand[@]}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# _ci_ssh_build_choices - Builds whiptail checklist from SSH key files
|
|
||||||
#
|
|
||||||
# Sets: CI_SSH_CHOICES (array), CI_SSH_COUNT (int), CI_SSH_MAPFILE (path)
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
function _ci_ssh_build_choices() {
|
|
||||||
local -a files=("$@")
|
|
||||||
CI_SSH_CHOICES=()
|
|
||||||
CI_SSH_COUNT=0
|
|
||||||
CI_SSH_MAPFILE="$(mktemp)"
|
|
||||||
local id key typ fp cmt base
|
|
||||||
|
|
||||||
for f in "${files[@]}"; do
|
|
||||||
[[ -f "$f" && -r "$f" ]] || continue
|
|
||||||
base="$(basename -- "$f")"
|
|
||||||
# Skip known_hosts and private keys
|
|
||||||
case "$base" in
|
|
||||||
known_hosts | known_hosts.* | config) continue ;;
|
|
||||||
id_*) [[ "$f" != *.pub ]] && continue ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
while IFS= read -r key; do
|
|
||||||
[[ -n "$key" ]] || continue
|
|
||||||
|
|
||||||
typ=""
|
|
||||||
fp=""
|
|
||||||
cmt=""
|
|
||||||
read -r _typ _b64 _cmt <<<"$key"
|
|
||||||
typ="${_typ:-key}"
|
|
||||||
cmt="${_cmt:-}"
|
|
||||||
|
|
||||||
# Get fingerprint via ssh-keygen if available
|
|
||||||
if command -v ssh-keygen >/dev/null 2>&1; then
|
|
||||||
fp="$(printf '%s\n' "$key" | ssh-keygen -lf - 2>/dev/null | awk '{print $2}')"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Shorten long comments
|
|
||||||
[[ ${#cmt} -gt 40 ]] && cmt="${cmt:0:37}..."
|
|
||||||
|
|
||||||
CI_SSH_COUNT=$((CI_SSH_COUNT + 1))
|
|
||||||
id="K${CI_SSH_COUNT}"
|
|
||||||
echo "${id}|${key}" >>"$CI_SSH_MAPFILE"
|
|
||||||
CI_SSH_CHOICES+=("$id" "[$typ] ${fp:+$fp }${cmt:+$cmt }— ${base}" "OFF")
|
|
||||||
done < <(_ci_ssh_extract_keys_from_file "$f")
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# configure_cloudinit_ssh_keys - Interactive SSH key selection for Cloud-Init
|
|
||||||
#
|
|
||||||
# Usage: configure_cloudinit_ssh_keys
|
|
||||||
# Sets: CLOUDINIT_SSH_KEYS (path to temporary file with selected keys)
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
function configure_cloudinit_ssh_keys() {
|
|
||||||
local backtitle="Proxmox VE Helper Scripts"
|
|
||||||
local ssh_key_mode
|
|
||||||
|
|
||||||
# Create temp file for selected keys
|
|
||||||
CLOUDINIT_SSH_KEYS_TEMP="$(mktemp)"
|
|
||||||
: >"$CLOUDINIT_SSH_KEYS_TEMP"
|
|
||||||
|
|
||||||
# Discover keys and build choices
|
|
||||||
IFS=$'\0' read -r -d '' -a _def_files < <(_ci_ssh_discover_files && printf '\0')
|
|
||||||
_ci_ssh_build_choices "${_def_files[@]}"
|
|
||||||
local default_key_count="$CI_SSH_COUNT"
|
|
||||||
|
|
||||||
if [[ "$default_key_count" -gt 0 ]]; then
|
|
||||||
ssh_key_mode=$(whiptail --backtitle "$backtitle" --title "SSH KEY SOURCE" --menu \
|
|
||||||
"Provision SSH keys for Cloud-Init VM:" 14 72 4 \
|
|
||||||
"found" "Select from detected keys (${default_key_count})" \
|
|
||||||
"manual" "Paste a single public key" \
|
|
||||||
"folder" "Scan another folder (path or glob)" \
|
|
||||||
"none" "No SSH keys (password auth only)" 3>&1 1>&2 2>&3) || return 1
|
|
||||||
else
|
|
||||||
ssh_key_mode=$(whiptail --backtitle "$backtitle" --title "SSH KEY SOURCE" --menu \
|
|
||||||
"No host keys detected. Choose:" 12 72 3 \
|
|
||||||
"manual" "Paste a single public key" \
|
|
||||||
"folder" "Scan another folder (path or glob)" \
|
|
||||||
"none" "No SSH keys (password auth only)" 3>&1 1>&2 2>&3) || return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "$ssh_key_mode" in
|
|
||||||
found)
|
|
||||||
# Show checklist with individual keys
|
|
||||||
local selection
|
|
||||||
selection=$(whiptail --backtitle "$backtitle" --title "SELECT SSH KEYS" \
|
|
||||||
--checklist "Select one or more keys to import:" 20 140 10 "${CI_SSH_CHOICES[@]}" 3>&1 1>&2 2>&3) || return 1
|
|
||||||
|
|
||||||
for tag in $selection; do
|
|
||||||
tag="${tag%\"}"
|
|
||||||
tag="${tag#\"}"
|
|
||||||
local line
|
|
||||||
line=$(grep -E "^${tag}\|" "$CI_SSH_MAPFILE" | head -n1 | cut -d'|' -f2-)
|
|
||||||
[[ -n "$line" ]] && printf '%s\n' "$line" >>"$CLOUDINIT_SSH_KEYS_TEMP"
|
|
||||||
done
|
|
||||||
local imported
|
|
||||||
imported=$(wc -l <"$CLOUDINIT_SSH_KEYS_TEMP")
|
|
||||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}${imported} key(s) selected${CL}"
|
|
||||||
;;
|
|
||||||
manual)
|
|
||||||
local pubkey
|
|
||||||
pubkey=$(whiptail --backtitle "$backtitle" --title "PASTE SSH PUBLIC KEY" \
|
|
||||||
--inputbox "Paste your SSH public key (ssh-rsa, ssh-ed25519, etc.):" 10 76 3>&1 1>&2 2>&3) || return 1
|
|
||||||
if [[ -n "$pubkey" ]]; then
|
|
||||||
echo "$pubkey" >"$CLOUDINIT_SSH_KEYS_TEMP"
|
|
||||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}1 key added manually${CL}"
|
|
||||||
else
|
|
||||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}none (empty input)${CL}"
|
|
||||||
CLOUDINIT_SSH_KEYS=""
|
|
||||||
rm -f "$CLOUDINIT_SSH_KEYS_TEMP" "$CI_SSH_MAPFILE" 2>/dev/null
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
folder)
|
|
||||||
local glob_path
|
|
||||||
glob_path=$(whiptail --backtitle "$backtitle" --title "SCAN FOLDER/GLOB" \
|
|
||||||
--inputbox "Enter a folder or glob to scan (e.g. /root/.ssh/*.pub):" 10 72 3>&1 1>&2 2>&3) || return 1
|
|
||||||
if [[ -n "$glob_path" ]]; then
|
|
||||||
shopt -s nullglob
|
|
||||||
local -a _scan_files=($glob_path)
|
|
||||||
shopt -u nullglob
|
|
||||||
if [[ "${#_scan_files[@]}" -gt 0 ]]; then
|
|
||||||
_ci_ssh_build_choices "${_scan_files[@]}"
|
|
||||||
if [[ "$CI_SSH_COUNT" -gt 0 ]]; then
|
|
||||||
local folder_selection
|
|
||||||
folder_selection=$(whiptail --backtitle "$backtitle" --title "SELECT FOLDER KEYS" \
|
|
||||||
--checklist "Select key(s) to import:" 20 140 10 "${CI_SSH_CHOICES[@]}" 3>&1 1>&2 2>&3) || return 1
|
|
||||||
for tag in $folder_selection; do
|
|
||||||
tag="${tag%\"}"
|
|
||||||
tag="${tag#\"}"
|
|
||||||
local line
|
|
||||||
line=$(grep -E "^${tag}\|" "$CI_SSH_MAPFILE" | head -n1 | cut -d'|' -f2-)
|
|
||||||
[[ -n "$line" ]] && printf '%s\n' "$line" >>"$CLOUDINIT_SSH_KEYS_TEMP"
|
|
||||||
done
|
|
||||||
local imported
|
|
||||||
imported=$(wc -l <"$CLOUDINIT_SSH_KEYS_TEMP")
|
|
||||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}${imported} key(s) from folder${CL}"
|
|
||||||
else
|
|
||||||
whiptail --backtitle "$backtitle" --msgbox "No keys found in: $glob_path" 8 60
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
whiptail --backtitle "$backtitle" --msgbox "Path/glob returned no files." 8 60
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
none | *)
|
|
||||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}none (password auth only)${CL}"
|
|
||||||
CLOUDINIT_SSH_KEYS=""
|
|
||||||
rm -f "$CLOUDINIT_SSH_KEYS_TEMP" "$CI_SSH_MAPFILE" 2>/dev/null
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Cleanup mapfile
|
|
||||||
rm -f "$CI_SSH_MAPFILE" 2>/dev/null
|
|
||||||
|
|
||||||
# Set the variable for setup_cloud_init to use
|
|
||||||
if [[ -s "$CLOUDINIT_SSH_KEYS_TEMP" ]]; then
|
|
||||||
CLOUDINIT_SSH_KEYS="$CLOUDINIT_SSH_KEYS_TEMP"
|
|
||||||
else
|
|
||||||
CLOUDINIT_SSH_KEYS=""
|
|
||||||
rm -f "$CLOUDINIT_SSH_KEYS_TEMP"
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# SECTION 3: HELPER FUNCTIONS
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -341,10 +144,9 @@ function setup_cloud_init() {
|
|||||||
local cipassword=$(openssl rand -base64 16)
|
local cipassword=$(openssl rand -base64 16)
|
||||||
qm set "$vmid" --cipassword "$cipassword" >/dev/null
|
qm set "$vmid" --cipassword "$cipassword" >/dev/null
|
||||||
|
|
||||||
# Add SSH keys only if explicitly provided (not auto-imported from host)
|
# Add SSH keys if available
|
||||||
if [ -n "${CLOUDINIT_SSH_KEYS:-}" ] && [ -f "$CLOUDINIT_SSH_KEYS" ]; then
|
if [ -f "$CLOUDINIT_SSH_KEYS" ]; then
|
||||||
qm set "$vmid" --sshkeys "$CLOUDINIT_SSH_KEYS" >/dev/null 2>&1 || true
|
qm set "$vmid" --sshkeys "$CLOUDINIT_SSH_KEYS" >/dev/null 2>&1 || true
|
||||||
_ci_msg_info "SSH keys imported from: $CLOUDINIT_SSH_KEYS"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Configure network
|
# Configure network
|
||||||
@@ -657,11 +459,6 @@ export -f wait_for_cloud_init 2>/dev/null || true
|
|||||||
export -f validate_ip_cidr 2>/dev/null || true
|
export -f validate_ip_cidr 2>/dev/null || true
|
||||||
export -f validate_ip 2>/dev/null || true
|
export -f validate_ip 2>/dev/null || true
|
||||||
|
|
||||||
# Restore previous shell options if they were saved
|
|
||||||
if [ -n "${_OLD_SET_STATE:-}" ]; then
|
|
||||||
eval "$_OLD_SET_STATE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# SECTION 7: EXAMPLES & DOCUMENTATION
|
# SECTION 7: EXAMPLES & DOCUMENTATION
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|||||||
730
vm/docker-vm.sh
730
vm/docker-vm.sh
@@ -1,45 +1,71 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: thost96 (thost96) | michelroegl-brunner | MickLesk
|
# Author: thost96 (thost96) | Co-Author: michelroegl-brunner
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
|
||||||
# ==============================================================================
|
source /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func)
|
||||||
# Docker VM - Creates a Docker-ready Virtual Machine
|
|
||||||
# ==============================================================================
|
|
||||||
|
|
||||||
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/api.func) 2>/dev/null
|
function header_info() {
|
||||||
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/vm-core.func) 2>/dev/null
|
clear
|
||||||
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/cloud-init.func) 2>/dev/null || true
|
cat <<"EOF"
|
||||||
load_functions
|
____ __ _ ____ ___
|
||||||
|
/ __ \____ _____/ /_____ _____ | | / / |/ /
|
||||||
# ==============================================================================
|
/ / / / __ \/ ___/ //_/ _ \/ ___/ | | / / /|_/ /
|
||||||
# SCRIPT VARIABLES
|
/ /_/ / /_/ / /__/ ,< / __/ / | |/ / / / /
|
||||||
# ==============================================================================
|
/_____/\____/\___/_/|_|\___/_/ |___/_/ /_/
|
||||||
APP="Docker"
|
|
||||||
APP_TYPE="vm"
|
|
||||||
NSAPP="docker-vm"
|
|
||||||
var_os="debian"
|
|
||||||
var_version="13"
|
|
||||||
|
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
header_info
|
||||||
|
echo -e "\n Loading..."
|
||||||
GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//')
|
GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//')
|
||||||
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
|
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
|
||||||
METHOD=""
|
METHOD=""
|
||||||
|
NSAPP="docker-vm"
|
||||||
|
var_os="debian"
|
||||||
|
var_version="12"
|
||||||
DISK_SIZE="10G"
|
DISK_SIZE="10G"
|
||||||
USE_CLOUD_INIT="no"
|
|
||||||
OS_TYPE=""
|
|
||||||
OS_VERSION=""
|
|
||||||
THIN="discard=on,ssd=1,"
|
|
||||||
|
|
||||||
# ==============================================================================
|
YW=$(echo "\033[33m")
|
||||||
# ERROR HANDLING & CLEANUP
|
BL=$(echo "\033[36m")
|
||||||
# ==============================================================================
|
RD=$(echo "\033[01;31m")
|
||||||
|
BGN=$(echo "\033[4;92m")
|
||||||
|
GN=$(echo "\033[1;92m")
|
||||||
|
DGN=$(echo "\033[32m")
|
||||||
|
CL=$(echo "\033[m")
|
||||||
|
|
||||||
|
CL=$(echo "\033[m")
|
||||||
|
BOLD=$(echo "\033[1m")
|
||||||
|
BFR="\\r\\033[K"
|
||||||
|
HOLD=" "
|
||||||
|
TAB=" "
|
||||||
|
|
||||||
|
CM="${TAB}✔️${TAB}${CL}"
|
||||||
|
CROSS="${TAB}✖️${TAB}${CL}"
|
||||||
|
INFO="${TAB}💡${TAB}${CL}"
|
||||||
|
OS="${TAB}🖥️${TAB}${CL}"
|
||||||
|
CONTAINERTYPE="${TAB}📦${TAB}${CL}"
|
||||||
|
DISKSIZE="${TAB}💾${TAB}${CL}"
|
||||||
|
CPUCORE="${TAB}🧠${TAB}${CL}"
|
||||||
|
RAMSIZE="${TAB}🛠️${TAB}${CL}"
|
||||||
|
CONTAINERID="${TAB}🆔${TAB}${CL}"
|
||||||
|
HOSTNAME="${TAB}🏠${TAB}${CL}"
|
||||||
|
BRIDGE="${TAB}🌉${TAB}${CL}"
|
||||||
|
GATEWAY="${TAB}🌐${TAB}${CL}"
|
||||||
|
DEFAULT="${TAB}⚙️${TAB}${CL}"
|
||||||
|
MACADDRESS="${TAB}🔗${TAB}${CL}"
|
||||||
|
VLANTAG="${TAB}🏷️${TAB}${CL}"
|
||||||
|
CREATING="${TAB}🚀${TAB}${CL}"
|
||||||
|
ADVANCED="${TAB}🧩${TAB}${CL}"
|
||||||
|
CLOUD="${TAB}☁️${TAB}${CL}"
|
||||||
|
|
||||||
|
THIN="discard=on,ssd=1,"
|
||||||
set -e
|
set -e
|
||||||
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
||||||
trap cleanup EXIT
|
trap cleanup EXIT
|
||||||
trap 'post_update_to_api "failed" "INTERRUPTED"' SIGINT
|
trap 'post_update_to_api "failed" "INTERRUPTED"' SIGINT
|
||||||
trap 'post_update_to_api "failed" "TERMINATED"' SIGTERM
|
trap 'post_update_to_api "failed" "TERMINATED"' SIGTERM
|
||||||
|
|
||||||
function error_handler() {
|
function error_handler() {
|
||||||
local exit_code="$?"
|
local exit_code="$?"
|
||||||
local line_number="$1"
|
local line_number="$1"
|
||||||
@@ -50,96 +76,140 @@ function error_handler() {
|
|||||||
cleanup_vmid
|
cleanup_vmid
|
||||||
}
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
function get_valid_nextid() {
|
||||||
# OS SELECTION FUNCTIONS
|
local try_id
|
||||||
# ==============================================================================
|
try_id=$(pvesh get /cluster/nextid)
|
||||||
function select_os() {
|
while true; do
|
||||||
if OS_CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SELECT OS" --radiolist \
|
if [ -f "/etc/pve/qemu-server/${try_id}.conf" ] || [ -f "/etc/pve/lxc/${try_id}.conf" ]; then
|
||||||
"Choose Operating System for Docker VM" 14 68 4 \
|
try_id=$((try_id + 1))
|
||||||
"debian13" "Debian 13 (Trixie) - Latest" ON \
|
continue
|
||||||
"debian12" "Debian 12 (Bookworm) - Stable" OFF \
|
|
||||||
"ubuntu2404" "Ubuntu 24.04 LTS (Noble)" OFF \
|
|
||||||
"ubuntu2204" "Ubuntu 22.04 LTS (Jammy)" OFF \
|
|
||||||
3>&1 1>&2 2>&3); then
|
|
||||||
case $OS_CHOICE in
|
|
||||||
debian13)
|
|
||||||
OS_TYPE="debian"
|
|
||||||
OS_VERSION="13"
|
|
||||||
OS_CODENAME="trixie"
|
|
||||||
OS_DISPLAY="Debian 13 (Trixie)"
|
|
||||||
;;
|
|
||||||
debian12)
|
|
||||||
OS_TYPE="debian"
|
|
||||||
OS_VERSION="12"
|
|
||||||
OS_CODENAME="bookworm"
|
|
||||||
OS_DISPLAY="Debian 12 (Bookworm)"
|
|
||||||
;;
|
|
||||||
ubuntu2404)
|
|
||||||
OS_TYPE="ubuntu"
|
|
||||||
OS_VERSION="24.04"
|
|
||||||
OS_CODENAME="noble"
|
|
||||||
OS_DISPLAY="Ubuntu 24.04 LTS"
|
|
||||||
;;
|
|
||||||
ubuntu2204)
|
|
||||||
OS_TYPE="ubuntu"
|
|
||||||
OS_VERSION="22.04"
|
|
||||||
OS_CODENAME="jammy"
|
|
||||||
OS_DISPLAY="Ubuntu 22.04 LTS"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}${OS_DISPLAY}${CL}"
|
|
||||||
else
|
|
||||||
exit_script
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function select_cloud_init() {
|
|
||||||
if [ "$OS_TYPE" = "ubuntu" ]; then
|
|
||||||
USE_CLOUD_INIT="yes"
|
|
||||||
echo -e "${CLOUD:-${TAB}☁️${TAB}${CL}}${BOLD}${DGN}Cloud-Init: ${BGN}yes (Ubuntu requires Cloud-Init)${CL}"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "CLOUD-INIT" \
|
|
||||||
--yesno "Enable Cloud-Init for VM configuration?\n\nCloud-Init allows automatic configuration of:\n- User accounts and passwords\n- SSH keys\n- Network settings (DHCP/Static)\n- DNS configuration\n\nYou can also configure these settings later in Proxmox UI.\n\nNote: Debian without Cloud-Init will use nocloud image with console auto-login." 18 68); then
|
|
||||||
USE_CLOUD_INIT="yes"
|
|
||||||
echo -e "${CLOUD:-${TAB}☁️${TAB}${CL}}${BOLD}${DGN}Cloud-Init: ${BGN}yes${CL}"
|
|
||||||
else
|
|
||||||
USE_CLOUD_INIT="no"
|
|
||||||
echo -e "${CLOUD:-${TAB}☁️${TAB}${CL}}${BOLD}${DGN}Cloud-Init: ${BGN}no${CL}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function get_image_url() {
|
|
||||||
local arch=$(dpkg --print-architecture)
|
|
||||||
case $OS_TYPE in
|
|
||||||
debian)
|
|
||||||
if [ "$USE_CLOUD_INIT" = "yes" ]; then
|
|
||||||
echo "https://cloud.debian.org/images/cloud/${OS_CODENAME}/latest/debian-${OS_VERSION}-generic-${arch}.qcow2"
|
|
||||||
else
|
|
||||||
echo "https://cloud.debian.org/images/cloud/${OS_CODENAME}/latest/debian-${OS_VERSION}-nocloud-${arch}.qcow2"
|
|
||||||
fi
|
fi
|
||||||
;;
|
if lvs --noheadings -o lv_name | grep -qE "(^|[-_])${try_id}($|[-_])"; then
|
||||||
ubuntu)
|
try_id=$((try_id + 1))
|
||||||
echo "https://cloud-images.ubuntu.com/${OS_CODENAME}/current/${OS_CODENAME}-server-cloudimg-${arch}.img"
|
continue
|
||||||
;;
|
fi
|
||||||
esac
|
break
|
||||||
|
done
|
||||||
|
echo "$try_id"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
function cleanup_vmid() {
|
||||||
# SETTINGS FUNCTIONS
|
if qm status $VMID &>/dev/null; then
|
||||||
# ==============================================================================
|
qm stop $VMID &>/dev/null
|
||||||
function default_settings() {
|
qm destroy $VMID &>/dev/null
|
||||||
select_os
|
fi
|
||||||
select_cloud_init
|
}
|
||||||
|
|
||||||
|
function cleanup() {
|
||||||
|
popd >/dev/null
|
||||||
|
post_update_to_api "done" "none"
|
||||||
|
rm -rf $TEMP_DIR
|
||||||
|
}
|
||||||
|
|
||||||
|
TEMP_DIR=$(mktemp -d)
|
||||||
|
pushd $TEMP_DIR >/dev/null
|
||||||
|
if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Docker VM" --yesno "This will create a New Docker VM. Proceed?" 10 58; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
header_info && echo -e "${CROSS}${RD}User exited script${CL}\n" && exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
function msg_info() {
|
||||||
|
local msg="$1"
|
||||||
|
echo -ne "${TAB}${YW}${HOLD}${msg}${HOLD}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function msg_ok() {
|
||||||
|
local msg="$1"
|
||||||
|
echo -e "${BFR}${CM}${GN}${msg}${CL}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function msg_error() {
|
||||||
|
local msg="$1"
|
||||||
|
echo -e "${BFR}${CROSS}${RD}${msg}${CL}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_root() {
|
||||||
|
if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then
|
||||||
|
clear
|
||||||
|
msg_error "Please run this script as root."
|
||||||
|
echo -e "\nExiting..."
|
||||||
|
sleep 2
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported.
|
||||||
|
# Supported: Proxmox VE 8.0.x – 8.9.x, 9.0 and 9.1
|
||||||
|
pve_check() {
|
||||||
|
local PVE_VER
|
||||||
|
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
|
||||||
|
|
||||||
|
# Check for Proxmox VE 8.x: allow 8.0–8.9
|
||||||
|
if [[ "$PVE_VER" =~ ^8\.([0-9]+) ]]; then
|
||||||
|
local MINOR="${BASH_REMATCH[1]}"
|
||||||
|
if ((MINOR < 0 || MINOR > 9)); then
|
||||||
|
msg_error "This version of Proxmox VE is not supported."
|
||||||
|
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for Proxmox VE 9.x: allow 9.0 and 9.1
|
||||||
|
if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
|
||||||
|
local MINOR="${BASH_REMATCH[1]}"
|
||||||
|
if ((MINOR < 0 || MINOR > 1)); then
|
||||||
|
msg_error "This version of Proxmox VE is not supported."
|
||||||
|
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# All other unsupported versions
|
||||||
|
msg_error "This version of Proxmox VE is not supported."
|
||||||
|
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function arch_check() {
|
||||||
|
if [ "$(dpkg --print-architecture)" != "amd64" ]; then
|
||||||
|
echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n"
|
||||||
|
echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n"
|
||||||
|
echo -e "Exiting..."
|
||||||
|
sleep 2
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function ssh_check() {
|
||||||
|
if command -v pveversion >/dev/null 2>&1; then
|
||||||
|
if [ -n "${SSH_CLIENT:+x}" ]; then
|
||||||
|
if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then
|
||||||
|
echo "you've been warned"
|
||||||
|
else
|
||||||
|
clear
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function exit-script() {
|
||||||
|
clear
|
||||||
|
echo -e "\n${CROSS}${RD}User exited script${CL}\n"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
function default_settings() {
|
||||||
VMID=$(get_valid_nextid)
|
VMID=$(get_valid_nextid)
|
||||||
FORMAT=""
|
FORMAT=",efitype=4m"
|
||||||
MACHINE=" -machine q35"
|
MACHINE=""
|
||||||
DISK_CACHE=""
|
DISK_CACHE=""
|
||||||
DISK_SIZE="10G"
|
DISK_SIZE="10G"
|
||||||
HN="docker"
|
HN="docker"
|
||||||
CPU_TYPE=" -cpu host"
|
CPU_TYPE=""
|
||||||
CORE_COUNT="2"
|
CORE_COUNT="2"
|
||||||
RAM_SIZE="4096"
|
RAM_SIZE="4096"
|
||||||
BRG="vmbr0"
|
BRG="vmbr0"
|
||||||
@@ -148,13 +218,12 @@ function default_settings() {
|
|||||||
MTU=""
|
MTU=""
|
||||||
START_VM="yes"
|
START_VM="yes"
|
||||||
METHOD="default"
|
METHOD="default"
|
||||||
|
|
||||||
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}"
|
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}"
|
||||||
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}Q35 (Modern)${CL}"
|
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}i440fx${CL}"
|
||||||
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}"
|
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}"
|
||||||
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
|
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
|
||||||
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}"
|
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}"
|
||||||
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
|
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
|
||||||
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}"
|
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}"
|
||||||
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}${CL}"
|
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}${CL}"
|
||||||
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}${BRG}${CL}"
|
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}${BRG}${CL}"
|
||||||
@@ -162,22 +231,12 @@ function default_settings() {
|
|||||||
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}Default${CL}"
|
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}Default${CL}"
|
||||||
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}Default${CL}"
|
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}Default${CL}"
|
||||||
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
|
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
|
||||||
echo -e "${CREATING}${BOLD}${DGN}Creating a Docker VM using the above settings${CL}"
|
echo -e "${CREATING}${BOLD}${DGN}Creating a Docker VM using the above default settings${CL}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function advanced_settings() {
|
function advanced_settings() {
|
||||||
select_os
|
|
||||||
select_cloud_init
|
|
||||||
|
|
||||||
# SSH Key selection for Cloud-Init VMs
|
|
||||||
if [ "$USE_CLOUD_INIT" = "yes" ]; then
|
|
||||||
configure_cloudinit_ssh_keys || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
METHOD="advanced"
|
METHOD="advanced"
|
||||||
[ -z "${VMID:-}" ] && VMID=$(get_valid_nextid)
|
[ -z "${VMID:-}" ] && VMID=$(get_valid_nextid)
|
||||||
|
|
||||||
# VM ID
|
|
||||||
while true; do
|
while true; do
|
||||||
if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $VMID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $VMID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z "$VMID" ]; then
|
if [ -z "$VMID" ]; then
|
||||||
@@ -191,29 +250,27 @@ function advanced_settings() {
|
|||||||
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"
|
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Machine Type
|
|
||||||
if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \
|
if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \
|
||||||
"q35" "Q35 (Modern, PCIe)" ON \
|
"i440fx" "Machine i440fx" ON \
|
||||||
"i440fx" "i440fx (Legacy, PCI)" OFF \
|
"q35" "Machine q35" OFF \
|
||||||
3>&1 1>&2 2>&3); then
|
3>&1 1>&2 2>&3); then
|
||||||
if [ $MACH = q35 ]; then
|
if [ $MACH = q35 ]; then
|
||||||
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}Q35 (Modern)${CL}"
|
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
|
||||||
FORMAT=""
|
FORMAT=""
|
||||||
MACHINE=" -machine q35"
|
MACHINE=" -machine q35"
|
||||||
else
|
else
|
||||||
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}i440fx (Legacy)${CL}"
|
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
|
||||||
FORMAT=",efitype=4m"
|
FORMAT=",efitype=4m"
|
||||||
MACHINE=""
|
MACHINE=""
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Disk Size
|
|
||||||
if DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GiB (e.g., 10, 20)" 8 58 "$DISK_SIZE" --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GiB (e.g., 10, 20)" 8 58 "$DISK_SIZE" --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
DISK_SIZE=$(echo "$DISK_SIZE" | tr -d ' ')
|
DISK_SIZE=$(echo "$DISK_SIZE" | tr -d ' ')
|
||||||
if [[ "$DISK_SIZE" =~ ^[0-9]+$ ]]; then
|
if [[ "$DISK_SIZE" =~ ^[0-9]+$ ]]; then
|
||||||
@@ -223,13 +280,12 @@ function advanced_settings() {
|
|||||||
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
|
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
|
||||||
else
|
else
|
||||||
echo -e "${DISKSIZE}${BOLD}${RD}Invalid Disk Size. Please use a number (e.g., 10 or 10G).${CL}"
|
echo -e "${DISKSIZE}${BOLD}${RD}Invalid Disk Size. Please use a number (e.g., 10 or 10G).${CL}"
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Disk Cache
|
|
||||||
if DISK_CACHE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
|
if DISK_CACHE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
|
||||||
"0" "None (Default)" ON \
|
"0" "None (Default)" ON \
|
||||||
"1" "Write Through" OFF \
|
"1" "Write Through" OFF \
|
||||||
@@ -242,25 +298,24 @@ function advanced_settings() {
|
|||||||
DISK_CACHE=""
|
DISK_CACHE=""
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Hostname
|
|
||||||
if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 docker --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 docker --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z $VM_NAME ]; then
|
if [ -z $VM_NAME ]; then
|
||||||
HN="docker"
|
HN="docker"
|
||||||
|
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
|
||||||
else
|
else
|
||||||
HN=$(echo ${VM_NAME,,} | tr -d ' ')
|
HN=$(echo ${VM_NAME,,} | tr -d ' ')
|
||||||
|
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
|
||||||
fi
|
fi
|
||||||
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
|
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# CPU Model
|
|
||||||
if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
|
if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
|
||||||
"1" "Host (Recommended)" ON \
|
"0" "KVM64 (Default)" ON \
|
||||||
"0" "KVM64" OFF \
|
"1" "Host" OFF \
|
||||||
3>&1 1>&2 2>&3); then
|
3>&1 1>&2 2>&3); then
|
||||||
if [ $CPU_TYPE1 = "1" ]; then
|
if [ $CPU_TYPE1 = "1" ]; then
|
||||||
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
|
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
|
||||||
@@ -270,78 +325,80 @@ function advanced_settings() {
|
|||||||
CPU_TYPE=""
|
CPU_TYPE=""
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# CPU Cores
|
|
||||||
if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z $CORE_COUNT ]; then
|
if [ -z $CORE_COUNT ]; then
|
||||||
CORE_COUNT="2"
|
CORE_COUNT="2"
|
||||||
|
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}"
|
||||||
|
else
|
||||||
|
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}"
|
||||||
fi
|
fi
|
||||||
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}"
|
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# RAM Size
|
if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 2048 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
|
||||||
if [ -z $RAM_SIZE ]; then
|
if [ -z $RAM_SIZE ]; then
|
||||||
RAM_SIZE="4096"
|
RAM_SIZE="2048"
|
||||||
|
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}"
|
||||||
|
else
|
||||||
|
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}"
|
||||||
fi
|
fi
|
||||||
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}"
|
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Bridge
|
|
||||||
if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z $BRG ]; then
|
if [ -z $BRG ]; then
|
||||||
BRG="vmbr0"
|
BRG="vmbr0"
|
||||||
|
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
|
||||||
|
else
|
||||||
|
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
|
||||||
fi
|
fi
|
||||||
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
|
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# MAC Address
|
|
||||||
if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z $MAC1 ]; then
|
if [ -z $MAC1 ]; then
|
||||||
MAC="$GEN_MAC"
|
MAC="$GEN_MAC"
|
||||||
|
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}"
|
||||||
else
|
else
|
||||||
MAC="$MAC1"
|
MAC="$MAC1"
|
||||||
|
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}"
|
||||||
fi
|
fi
|
||||||
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}"
|
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# VLAN
|
if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan (leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
|
||||||
if [ -z $VLAN1 ]; then
|
if [ -z $VLAN1 ]; then
|
||||||
VLAN1="Default"
|
VLAN1="Default"
|
||||||
VLAN=""
|
VLAN=""
|
||||||
|
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
|
||||||
else
|
else
|
||||||
VLAN=",tag=$VLAN1"
|
VLAN=",tag=$VLAN1"
|
||||||
|
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
|
||||||
fi
|
fi
|
||||||
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
|
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# MTU
|
|
||||||
if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z $MTU1 ]; then
|
if [ -z $MTU1 ]; then
|
||||||
MTU1="Default"
|
MTU1="Default"
|
||||||
MTU=""
|
MTU=""
|
||||||
|
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
|
||||||
else
|
else
|
||||||
MTU=",mtu=$MTU1"
|
MTU=",mtu=$MTU1"
|
||||||
|
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
|
||||||
fi
|
fi
|
||||||
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
|
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Start VM
|
|
||||||
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then
|
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then
|
||||||
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
|
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
|
||||||
START_VM="yes"
|
START_VM="yes"
|
||||||
@@ -350,7 +407,6 @@ function advanced_settings() {
|
|||||||
START_VM="no"
|
START_VM="no"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Confirm
|
|
||||||
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create a Docker VM?" --no-button Do-Over 10 58); then
|
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create a Docker VM?" --no-button Do-Over 10 58); then
|
||||||
echo -e "${CREATING}${BOLD}${DGN}Creating a Docker VM using the above advanced settings${CL}"
|
echo -e "${CREATING}${BOLD}${DGN}Creating a Docker VM using the above advanced settings${CL}"
|
||||||
else
|
else
|
||||||
@@ -371,28 +427,13 @@ function start_script() {
|
|||||||
advanced_settings
|
advanced_settings
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# MAIN EXECUTION
|
|
||||||
# ==============================================================================
|
|
||||||
header_info
|
|
||||||
|
|
||||||
check_root
|
check_root
|
||||||
arch_check
|
arch_check
|
||||||
pve_check
|
pve_check
|
||||||
|
ssh_check
|
||||||
if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Docker VM" --yesno "This will create a New Docker VM. Proceed?" 10 58; then
|
|
||||||
:
|
|
||||||
else
|
|
||||||
header_info && echo -e "${CROSS}${RD}User exited script${CL}\n" && exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
start_script
|
start_script
|
||||||
post_to_api_vm
|
post_to_api_vm
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# STORAGE SELECTION
|
|
||||||
# ==============================================================================
|
|
||||||
msg_info "Validating Storage"
|
msg_info "Validating Storage"
|
||||||
while read -r line; do
|
while read -r line; do
|
||||||
TAG=$(echo $line | awk '{print $1}')
|
TAG=$(echo $line | awk '{print $1}')
|
||||||
@@ -405,7 +446,6 @@ while read -r line; do
|
|||||||
fi
|
fi
|
||||||
STORAGE_MENU+=("$TAG" "$ITEM" "OFF")
|
STORAGE_MENU+=("$TAG" "$ITEM" "OFF")
|
||||||
done < <(pvesm status -content images | awk 'NR>1')
|
done < <(pvesm status -content images | awk 'NR>1')
|
||||||
|
|
||||||
VALID=$(pvesm status -content images | awk 'NR>1')
|
VALID=$(pvesm status -content images | awk 'NR>1')
|
||||||
if [ -z "$VALID" ]; then
|
if [ -z "$VALID" ]; then
|
||||||
msg_error "Unable to detect a valid storage location."
|
msg_error "Unable to detect a valid storage location."
|
||||||
@@ -413,8 +453,6 @@ if [ -z "$VALID" ]; then
|
|||||||
elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then
|
elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then
|
||||||
STORAGE=${STORAGE_MENU[0]}
|
STORAGE=${STORAGE_MENU[0]}
|
||||||
else
|
else
|
||||||
if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
|
|
||||||
printf "\e[?25h"
|
|
||||||
while [ -z "${STORAGE:+x}" ]; do
|
while [ -z "${STORAGE:+x}" ]; do
|
||||||
STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
|
STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
|
||||||
"Which storage pool would you like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \
|
"Which storage pool would you like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \
|
||||||
@@ -424,288 +462,112 @@ else
|
|||||||
fi
|
fi
|
||||||
msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
|
msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
|
||||||
msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
|
msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
|
||||||
|
msg_info "Retrieving the URL for the Debian 12 Qcow2 Disk Image"
|
||||||
# ==============================================================================
|
URL="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-nocloud-$(dpkg --print-architecture).qcow2"
|
||||||
# PREREQUISITES
|
sleep 2
|
||||||
# ==============================================================================
|
|
||||||
if ! command -v virt-customize &>/dev/null; then
|
|
||||||
msg_info "Installing libguestfs-tools"
|
|
||||||
apt-get -qq update >/dev/null
|
|
||||||
apt-get -qq install libguestfs-tools lsb-release -y >/dev/null
|
|
||||||
apt-get -qq install dhcpcd-base -y >/dev/null 2>&1 || true
|
|
||||||
msg_ok "Installed libguestfs-tools"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# IMAGE DOWNLOAD
|
|
||||||
# ==============================================================================
|
|
||||||
msg_info "Retrieving the URL for the ${OS_DISPLAY} Qcow2 Disk Image"
|
|
||||||
URL=$(get_image_url)
|
|
||||||
CACHE_DIR="/var/lib/vz/template/cache"
|
|
||||||
CACHE_FILE="$CACHE_DIR/$(basename "$URL")"
|
|
||||||
mkdir -p "$CACHE_DIR"
|
|
||||||
msg_ok "${CL}${BL}${URL}${CL}"
|
msg_ok "${CL}${BL}${URL}${CL}"
|
||||||
|
curl -f#SL -o "$(basename "$URL")" "$URL"
|
||||||
|
echo -en "\e[1A\e[0K"
|
||||||
|
FILE=$(basename $URL)
|
||||||
|
msg_ok "Downloaded ${CL}${BL}${FILE}${CL}"
|
||||||
|
|
||||||
if [[ ! -s "$CACHE_FILE" ]]; then
|
|
||||||
curl -f#SL -o "$CACHE_FILE" "$URL"
|
|
||||||
echo -en "\e[1A\e[0K"
|
|
||||||
msg_ok "Downloaded ${CL}${BL}$(basename "$CACHE_FILE")${CL}"
|
|
||||||
else
|
|
||||||
msg_ok "Using cached image ${CL}${BL}$(basename "$CACHE_FILE")${CL}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# STORAGE TYPE DETECTION
|
|
||||||
# ==============================================================================
|
|
||||||
STORAGE_TYPE=$(pvesm status -storage "$STORAGE" | awk 'NR>1 {print $2}')
|
STORAGE_TYPE=$(pvesm status -storage "$STORAGE" | awk 'NR>1 {print $2}')
|
||||||
case $STORAGE_TYPE in
|
case $STORAGE_TYPE in
|
||||||
nfs | dir)
|
nfs | dir)
|
||||||
DISK_EXT=".qcow2"
|
DISK_EXT=".qcow2"
|
||||||
DISK_REF="$VMID/"
|
DISK_REF="$VMID/"
|
||||||
DISK_IMPORT="--format qcow2"
|
DISK_IMPORT="-format qcow2"
|
||||||
THIN=""
|
THIN=""
|
||||||
;;
|
;;
|
||||||
btrfs)
|
btrfs)
|
||||||
DISK_EXT=".raw"
|
DISK_EXT=".raw"
|
||||||
DISK_REF="$VMID/"
|
DISK_REF="$VMID/"
|
||||||
DISK_IMPORT="--format raw"
|
DISK_IMPORT="-format raw"
|
||||||
FORMAT=",efitype=4m"
|
FORMAT=",efitype=4m"
|
||||||
THIN=""
|
THIN=""
|
||||||
;;
|
;;
|
||||||
*)
|
|
||||||
DISK_EXT=""
|
|
||||||
DISK_REF=""
|
|
||||||
DISK_IMPORT="--format raw"
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
for i in {0,1}; do
|
||||||
# ==============================================================================
|
disk="DISK$i"
|
||||||
# IMAGE CUSTOMIZATION WITH DOCKER
|
eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-}
|
||||||
# ==============================================================================
|
eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk}
|
||||||
msg_info "Preparing ${OS_DISPLAY} image with Docker"
|
|
||||||
|
|
||||||
WORK_FILE=$(mktemp --suffix=.qcow2)
|
|
||||||
cp "$CACHE_FILE" "$WORK_FILE"
|
|
||||||
|
|
||||||
export LIBGUESTFS_BACKEND_SETTINGS=dns=8.8.8.8,1.1.1.1
|
|
||||||
|
|
||||||
DOCKER_PREINSTALLED="no"
|
|
||||||
|
|
||||||
# Install qemu-guest-agent and Docker during image customization
|
|
||||||
msg_info "Installing base packages in image"
|
|
||||||
if virt-customize -a "$WORK_FILE" --install qemu-guest-agent,curl,ca-certificates >/dev/null 2>&1; then
|
|
||||||
msg_ok "Installed base packages"
|
|
||||||
|
|
||||||
msg_info "Installing Docker (this may take 2-5 minutes)"
|
|
||||||
if virt-customize -q -a "$WORK_FILE" --run-command "curl -fsSL https://get.docker.com | sh" >/dev/null 2>&1 &&
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "systemctl enable docker" >/dev/null 2>&1; then
|
|
||||||
msg_ok "Installed Docker"
|
|
||||||
|
|
||||||
msg_info "Configuring Docker daemon"
|
|
||||||
# Optimize Docker daemon configuration
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "mkdir -p /etc/docker" >/dev/null 2>&1
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command 'cat > /etc/docker/daemon.json << EOF
|
|
||||||
{
|
|
||||||
"storage-driver": "overlay2",
|
|
||||||
"log-driver": "json-file",
|
|
||||||
"log-opts": {
|
|
||||||
"max-size": "10m",
|
|
||||||
"max-file": "3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF' >/dev/null 2>&1
|
|
||||||
DOCKER_PREINSTALLED="yes"
|
|
||||||
msg_ok "Configured Docker daemon"
|
|
||||||
else
|
|
||||||
msg_ok "Docker will be installed on first boot"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
msg_ok "Packages will be installed on first boot"
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Finalizing image (hostname, SSH config)"
|
|
||||||
# Set hostname and prepare for unique machine-id
|
|
||||||
virt-customize -q -a "$WORK_FILE" --hostname "${HN}" >/dev/null 2>&1
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "truncate -s 0 /etc/machine-id" >/dev/null 2>&1
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "rm -f /var/lib/dbus/machine-id" >/dev/null 2>&1
|
|
||||||
|
|
||||||
# Configure SSH for Cloud-Init
|
|
||||||
if [ "$USE_CLOUD_INIT" = "yes" ]; then
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "sed -i 's/^#*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config" >/dev/null 2>&1 || true
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config" >/dev/null 2>&1 || true
|
|
||||||
else
|
|
||||||
# Configure auto-login for nocloud images (no Cloud-Init)
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "mkdir -p /etc/systemd/system/serial-getty@ttyS0.service.d" >/dev/null 2>&1 || true
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command 'cat > /etc/systemd/system/serial-getty@ttyS0.service.d/autologin.conf << EOF
|
|
||||||
[Service]
|
|
||||||
ExecStart=
|
|
||||||
ExecStart=-/sbin/agetty --autologin root --noclear %I \$TERM
|
|
||||||
EOF' >/dev/null 2>&1 || true
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "mkdir -p /etc/systemd/system/getty@tty1.service.d" >/dev/null 2>&1 || true
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command 'cat > /etc/systemd/system/getty@tty1.service.d/autologin.conf << EOF
|
|
||||||
[Service]
|
|
||||||
ExecStart=
|
|
||||||
ExecStart=-/sbin/agetty --autologin root --noclear %I \$TERM
|
|
||||||
EOF' >/dev/null 2>&1 || true
|
|
||||||
fi
|
|
||||||
msg_ok "Finalized image"
|
|
||||||
|
|
||||||
# Create first-boot Docker install script (fallback if virt-customize failed)
|
|
||||||
if [ "$DOCKER_PREINSTALLED" = "no" ]; then
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command 'cat > /root/install-docker.sh << "DOCKERSCRIPT"
|
|
||||||
#!/bin/bash
|
|
||||||
exec > /var/log/install-docker.log 2>&1
|
|
||||||
echo "[$(date)] Starting Docker installation"
|
|
||||||
|
|
||||||
for i in {1..30}; do
|
|
||||||
ping -c 1 8.8.8.8 >/dev/null 2>&1 && break
|
|
||||||
sleep 2
|
|
||||||
done
|
done
|
||||||
|
|
||||||
apt-get update
|
if ! command -v virt-customize &>/dev/null; then
|
||||||
apt-get install -y qemu-guest-agent curl ca-certificates
|
msg_info "Installing Pre-Requisite libguestfs-tools onto Host"
|
||||||
curl -fsSL https://get.docker.com | sh
|
apt-get -qq update >/dev/null
|
||||||
systemctl enable docker
|
apt-get -qq install libguestfs-tools lsb-release -y >/dev/null
|
||||||
systemctl start docker
|
# Workaround for Proxmox VE 9.0 libguestfs issue
|
||||||
|
apt-get -qq install dhcpcd-base -y >/dev/null 2>&1 || true
|
||||||
mkdir -p /etc/docker
|
msg_ok "Installed libguestfs-tools successfully"
|
||||||
cat > /etc/docker/daemon.json << DAEMON
|
|
||||||
{
|
|
||||||
"storage-driver": "overlay2",
|
|
||||||
"log-driver": "json-file",
|
|
||||||
"log-opts": { "max-size": "10m", "max-file": "3" }
|
|
||||||
}
|
|
||||||
DAEMON
|
|
||||||
systemctl restart docker
|
|
||||||
|
|
||||||
touch /root/.docker-installed
|
|
||||||
echo "[$(date)] Docker installation completed"
|
|
||||||
DOCKERSCRIPT
|
|
||||||
chmod +x /root/install-docker.sh' >/dev/null 2>&1
|
|
||||||
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command 'cat > /etc/systemd/system/install-docker.service << "DOCKERSERVICE"
|
|
||||||
[Unit]
|
|
||||||
Description=Install Docker on First Boot
|
|
||||||
After=network-online.target
|
|
||||||
Wants=network-online.target
|
|
||||||
ConditionPathExists=!/root/.docker-installed
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
ExecStart=/root/install-docker.sh
|
|
||||||
RemainAfterExit=yes
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
DOCKERSERVICE
|
|
||||||
systemctl enable install-docker.service' >/dev/null 2>&1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Resize disk to target size
|
msg_info "Adding Docker and Docker Compose Plugin to Debian 12 Qcow2 Disk Image"
|
||||||
msg_info "Resizing disk image to ${DISK_SIZE}"
|
virt-customize -q -a "${FILE}" --install qemu-guest-agent,apt-transport-https,ca-certificates,curl,gnupg,software-properties-common,lsb-release >/dev/null &&
|
||||||
qemu-img resize "$WORK_FILE" "${DISK_SIZE}" >/dev/null 2>&1
|
virt-customize -q -a "${FILE}" --run-command "mkdir -p /etc/apt/keyrings && curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg" >/dev/null &&
|
||||||
msg_ok "Resized disk image"
|
virt-customize -q -a "${FILE}" --run-command "echo 'deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable' > /etc/apt/sources.list.d/docker.list" >/dev/null &&
|
||||||
|
virt-customize -q -a "${FILE}" --run-command "apt-get update -qq && apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin" >/dev/null &&
|
||||||
|
virt-customize -q -a "${FILE}" --run-command "systemctl enable docker" >/dev/null &&
|
||||||
|
virt-customize -q -a "${FILE}" --hostname "${HN}" >/dev/null &&
|
||||||
|
virt-customize -q -a "${FILE}" --run-command "echo -n > /etc/machine-id" >/dev/null
|
||||||
|
msg_ok "Added Docker and Docker Compose Plugin to Debian 12 Qcow2 Disk Image successfully"
|
||||||
|
|
||||||
# ==============================================================================
|
msg_info "Expanding root partition to use full disk space"
|
||||||
# VM CREATION
|
qemu-img create -f qcow2 expanded.qcow2 ${DISK_SIZE} >/dev/null 2>&1
|
||||||
# ==============================================================================
|
virt-resize --expand /dev/sda1 ${FILE} expanded.qcow2 >/dev/null 2>&1
|
||||||
msg_info "Creating Docker VM shell"
|
mv expanded.qcow2 ${FILE} >/dev/null 2>&1
|
||||||
|
msg_ok "Expanded image to full size"
|
||||||
|
|
||||||
|
msg_info "Creating a Docker VM"
|
||||||
qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \
|
qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \
|
||||||
-name $HN -tags community-script -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci >/dev/null
|
-name $HN -tags community-script -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci
|
||||||
|
pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null
|
||||||
msg_ok "Created VM shell"
|
qm importdisk $VMID ${FILE} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null
|
||||||
|
qm set $VMID \
|
||||||
# ==============================================================================
|
-efidisk0 ${DISK0_REF}${FORMAT} \
|
||||||
# DISK IMPORT
|
-scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=${DISK_SIZE} \
|
||||||
# ==============================================================================
|
-boot order=scsi0 \
|
||||||
msg_info "Importing disk into storage ($STORAGE)"
|
-serial0 socket >/dev/null
|
||||||
|
qm resize $VMID scsi0 8G >/dev/null
|
||||||
if qm disk import --help >/dev/null 2>&1; then
|
|
||||||
IMPORT_CMD=(qm disk import)
|
|
||||||
else
|
|
||||||
IMPORT_CMD=(qm importdisk)
|
|
||||||
fi
|
|
||||||
|
|
||||||
IMPORT_OUT="$("${IMPORT_CMD[@]}" "$VMID" "$WORK_FILE" "$STORAGE" ${DISK_IMPORT:-} 2>&1 || true)"
|
|
||||||
DISK_REF_IMPORTED="$(printf '%s\n' "$IMPORT_OUT" | sed -n "s/.*successfully imported disk '\([^']\+\)'.*/\1/p" | tr -d "\r\"'")"
|
|
||||||
[[ -z "$DISK_REF_IMPORTED" ]] && DISK_REF_IMPORTED="$(pvesm list "$STORAGE" | awk -v id="$VMID" '$5 ~ ("vm-"id"-disk-") {print $1":"$5}' | sort | tail -n1)"
|
|
||||||
[[ -z "$DISK_REF_IMPORTED" ]] && {
|
|
||||||
msg_error "Unable to determine imported disk reference."
|
|
||||||
echo "$IMPORT_OUT"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
msg_ok "Imported disk (${CL}${BL}${DISK_REF_IMPORTED}${CL})"
|
|
||||||
|
|
||||||
# Clean up work file
|
|
||||||
rm -f "$WORK_FILE"
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# VM CONFIGURATION
|
|
||||||
# ==============================================================================
|
|
||||||
msg_info "Attaching EFI and root disk"
|
|
||||||
|
|
||||||
qm set "$VMID" \
|
|
||||||
--efidisk0 "${STORAGE}:0,efitype=4m" \
|
|
||||||
--scsi0 "${DISK_REF_IMPORTED},${DISK_CACHE}${THIN%,}" \
|
|
||||||
--boot order=scsi0 \
|
|
||||||
--serial0 socket >/dev/null
|
|
||||||
|
|
||||||
qm set $VMID --agent enabled=1 >/dev/null
|
qm set $VMID --agent enabled=1 >/dev/null
|
||||||
|
|
||||||
msg_ok "Attached EFI and root disk"
|
DESCRIPTION=$(
|
||||||
|
cat <<EOF
|
||||||
|
<div align='center'>
|
||||||
|
<a href='https://Helper-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>
|
||||||
|
|
||||||
# Set VM description
|
<h2 style='font-size: 24px; margin: 20px 0;'>Docker VM</h2>
|
||||||
set_description
|
|
||||||
|
|
||||||
# Cloud-Init configuration
|
<p style='margin: 16px 0;'>
|
||||||
if [ "$USE_CLOUD_INIT" = "yes" ]; then
|
<a href='https://ko-fi.com/community_scripts' target='_blank' rel='noopener noreferrer'>
|
||||||
msg_info "Configuring Cloud-Init"
|
<img src='https://img.shields.io/badge/☕-Buy us a coffee-blue' alt='spend Coffee' />
|
||||||
setup_cloud_init "$VMID" "$STORAGE" "$HN" "yes"
|
</a>
|
||||||
msg_ok "Cloud-Init configured"
|
</p>
|
||||||
fi
|
|
||||||
|
|
||||||
# Start VM
|
<span style='margin: 0 10px;'>
|
||||||
|
<i class="fa fa-github fa-fw" style="color: #f5f5f5;"></i>
|
||||||
|
<a href='https://github.com/community-scripts/ProxmoxVE' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>GitHub</a>
|
||||||
|
</span>
|
||||||
|
<span style='margin: 0 10px;'>
|
||||||
|
<i class="fa fa-comments fa-fw" style="color: #f5f5f5;"></i>
|
||||||
|
<a href='https://github.com/community-scripts/ProxmoxVE/discussions' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>Discussions</a>
|
||||||
|
</span>
|
||||||
|
<span style='margin: 0 10px;'>
|
||||||
|
<i class="fa fa-exclamation-circle fa-fw" style="color: #f5f5f5;"></i>
|
||||||
|
<a href='https://github.com/community-scripts/ProxmoxVE/issues' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>Issues</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
qm set $VMID -description "$DESCRIPTION" >/dev/null
|
||||||
|
|
||||||
|
msg_ok "Created a Docker VM ${CL}${BL}(${HN})"
|
||||||
if [ "$START_VM" == "yes" ]; then
|
if [ "$START_VM" == "yes" ]; then
|
||||||
msg_info "Starting Docker VM"
|
msg_info "Starting Docker VM"
|
||||||
qm start $VMID >/dev/null 2>&1
|
qm start $VMID
|
||||||
msg_ok "Started Docker VM"
|
msg_ok "Started Docker VM"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# FINAL OUTPUT
|
|
||||||
# ==============================================================================
|
|
||||||
VM_IP=""
|
|
||||||
if [ "$START_VM" == "yes" ]; then
|
|
||||||
set +e
|
|
||||||
for i in {1..10}; do
|
|
||||||
VM_IP=$(qm guest cmd "$VMID" network-get-interfaces 2>/dev/null |
|
|
||||||
jq -r '.[] | select(.name != "lo") | ."ip-addresses"[]? | select(."ip-address-type" == "ipv4") | ."ip-address"' 2>/dev/null |
|
|
||||||
grep -v "^127\." | head -1) || true
|
|
||||||
[ -n "$VM_IP" ] && break
|
|
||||||
sleep 3
|
|
||||||
done
|
|
||||||
set -e
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "\n${INFO}${BOLD}${GN}Docker VM Configuration Summary:${CL}"
|
|
||||||
echo -e "${TAB}${DGN}VM ID: ${BGN}${VMID}${CL}"
|
|
||||||
echo -e "${TAB}${DGN}Hostname: ${BGN}${HN}${CL}"
|
|
||||||
echo -e "${TAB}${DGN}OS: ${BGN}${OS_DISPLAY}${CL}"
|
|
||||||
[ -n "$VM_IP" ] && echo -e "${TAB}${DGN}IP Address: ${BGN}${VM_IP}${CL}"
|
|
||||||
|
|
||||||
if [ "$DOCKER_PREINSTALLED" = "yes" ]; then
|
|
||||||
echo -e "${TAB}${DGN}Docker: ${BGN}Pre-installed (via get.docker.com)${CL}"
|
|
||||||
else
|
|
||||||
echo -e "${TAB}${DGN}Docker: ${BGN}Installing on first boot${CL}"
|
|
||||||
echo -e "${TAB}${YW}⚠️ Wait 2-3 minutes for installation to complete${CL}"
|
|
||||||
echo -e "${TAB}${YW}⚠️ Check progress: ${BL}cat /var/log/install-docker.log${CL}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$USE_CLOUD_INIT" = "yes" ]; then
|
|
||||||
display_cloud_init_info "$VMID" "$HN" 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
post_update_to_api "done" "none"
|
post_update_to_api "done" "none"
|
||||||
msg_ok "Completed successfully!\n"
|
msg_ok "Completed successfully!\n"
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
____ __
|
|
||||||
/ __ \____ _____/ /_____ _____
|
|
||||||
/ / / / __ \/ ___/ //_/ _ \/ ___/
|
|
||||||
/ /_/ / /_/ / /__/ ,< / __/ /
|
|
||||||
/_____/\____/\___/_/|_|\___/_/
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user