前言
之前在github上找来的,本来挺好用的,但是后来github的作者修改了脚本,搞的有些不好用,可能是没有修复BUG什么的,反正之前下的脚本我就暂存一份在自己博客,免得以后丢了!顺便说下,我也不知道是哪个作者了!
用法
复制以下代码,保存为templates.sh即可,拉到PVE根目录,给与执行权限,然后./templates.sh就可以操作了,爱选哪个选哪个!还有几个脚本是一次性全部下载,我也放上去!
交互式的脚本如下
#!/bin/bash
# 函数:提示用户输入网络接口和存储
prompt_for_network_and_storage() {
echo -n "请输入网络接口(例如 vmbr0,默认为 vmbr0):"
read -r vmbr
if [ -z "$vmbr" ]; then
vmbr="vmbr0"
fi
echo -n "请输入存储名称(例如 local,默认为 local):"
read -r storage
if [ -z "$storage" ]; then
storage="local"
fi
}
# 函数:显示发行版选项菜单(仅在交互模式下使用)
show_distro_menu() {
echo "====================================="
echo "欢迎使用 Proxmox VE 虚拟机模板创建脚本"
echo "====================================="
echo "请选择要创建的发行版:"
echo "1. Debian 12"
echo "2. Debian 11"
echo "3. CentOS 9 Stream"
echo "4. CentOS 8 Stream"
echo "5. Ubuntu 22.04"
echo "6. Ubuntu 24.04"
echo "7. AlmaLinux 8"
echo "8. AlmaLinux 9"
echo "9. Rocky Linux 8"
echo "10. Rocky Linux 9"
echo -n "请输入选项 (1-10):"
read -r choice
case $choice in
1)
distro="debian12"
image_url="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2"
image_file="debian-12-generic-amd64.qcow2"
vm_name="Debian-12"
;;
2)
distro="debian11"
image_url="https://cloud.debian.org/images/cloud/bullseye/latest/debian-11-generic-amd64.qcow2"
image_file="debian-11-generic-amd64.qcow2"
vm_name="Debian-11"
;;
3)
distro="centos9"
image_url="https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2"
image_file="CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2"
vm_name="CentOS-9"
;;
4)
distro="centos8"
image_url="https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-latest.x86_64.qcow2"
image_file="CentOS-Stream-GenericCloud-8-latest.x86_64.qcow2"
vm_name="CentOS-8"
;;
5)
distro="ubuntu22"
image_url="https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img"
image_file="jammy-server-cloudimg-amd64.img"
vm_name="Ubuntu-22"
;;
6)
distro="ubuntu24"
image_url="https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img"
image_file="noble-server-cloudimg-amd64.img"
vm_name="Ubuntu-24"
;;
7)
distro="alma8"
image_url="https://repo.almalinux.org/almalinux/8/cloud/x86_64/images/AlmaLinux-8-GenericCloud-latest.x86_64.qcow2"
image_file="AlmaLinux-8-GenericCloud-latest.x86_64.qcow2"
vm_name="AlmaLinux-8"
;;
8)
distro="alma9"
image_url="https://repo.almalinux.org/almalinux/9/cloud/x86_64/images/AlmaLinux-9-GenericCloud-latest.x86_64.qcow2"
image_file="AlmaLinux-9-GenericCloud-latest.x86_64.qcow2"
vm_name="AlmaLinux-9"
;;
9)
distro="rocky8"
image_url="https://download.rockylinux.org/pub/rocky/8/images/x86_64/Rocky-8-GenericCloud.latest.x86_64.qcow2"
image_file="Rocky-8-GenericCloud.latest.x86_64.qcow2"
vm_name="Rocky-8"
;;
10)
distro="rocky9"
image_url="https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2"
image_file="Rocky-9-GenericCloud.latest.x86_64.qcow2"
vm_name="Rocky-9"
;;
*)
echo "无效选项,请选择 1-10 之间的数字。"
exit 1
;;
esac
# 提示用户输入 VMID
echo -n "请输入 VMID(例如 8000):"
read -r vmid
if ! [[ "$vmid" =~ ^[0-9]+$ ]]; then
echo "VMID 必须是数字。"
exit 1
fi
}
# 函数:通过参数设置发行版和 VMID(非交互模式)
set_distro_and_vmid() {
local choice=$1
local input_vmid=$2
case $choice in
1)
distro="debian12"
image_url="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2"
image_file="debian-12-generic-amd64.qcow2"
vm_name="Debian-12"
;;
2)
distro="debian11"
image_url="https://cloud.debian.org/images/cloud/bullseye/latest/debian-11-generic-amd64.qcow2"
image_file="debian-11-generic-amd64.qcow2"
vm_name="Debian-11"
;;
3)
distro="centos9"
image_url="https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2"
image_file="CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2"
vm_name="CentOS-9"
;;
4)
distro="centos8"
image_url="https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-latest.x86_64.qcow2"
image_file="CentOS-Stream-GenericCloud-8-latest.x86_64.qcow2"
vm_name="CentOS-8"
;;
5)
distro="ubuntu22"
image_url="https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img"
image_file="jammy-server-cloudimg-amd64.img"
vm_name="Ubuntu-22"
;;
6)
distro="ubuntu24"
image_url="https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img"
image_file="noble-server-cloudimg-amd64.img"
vm_name="Ubuntu-24"
;;
7)
distro="alma8"
image_url="https://repo.almalinux.org/almalinux/8/cloud/x86_64/images/AlmaLinux-8-GenericCloud-latest.x86_64.qcow2"
image_file="AlmaLinux-8-GenericCloud-latest.x86_64.qcow2"
vm_name="AlmaLinux-8"
;;
8)
distro="alma9"
image_url="https://repo.almalinux.org/almalinux/9/cloud/x86_64/images/AlmaLinux-9-GenericCloud-latest.x86_64.qcow2"
image_file="AlmaLinux-9-GenericCloud-latest.x86_64.qcow2"
vm_name="AlmaLinux-9"
;;
9)
distro="rocky8"
image_url="https://download.rockylinux.org/pub/rocky/8/images/x86_64/Rocky-8-GenericCloud.latest.x86_64.qcow2"
image_file="Rocky-8-GenericCloud.latest.x86_64.qcow2"
vm_name="Rocky-8"
;;
10)
distro="rocky9"
image_url="https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2"
image_file="Rocky-9-GenericCloud.latest.x86_64.qcow2"
vm_name="Rocky-9"
;;
*)
echo "无效选项:$choice,请选择 1-10 之间的数字。"
exit 1
;;
esac
vmid=$input_vmid
if ! [[ "$vmid" =~ ^[0-9]+$ ]]; then
echo "VMID 必须是数字:$vmid"
exit 1
fi
}
# 函数:检查并销毁已存在的虚拟机(带确认)
destroy_existing_vm() {
local vmid=$1
if qm status $vmid >/dev/null 2>&1; then
echo "检测到 VMID $vmid 已存在,是否销毁?(输入 Y/y 确认,其他键取消)"
read -r confirm
if [[ "$confirm" != "Y" && "$confirm" != "y" ]]; then
echo "用户取消销毁操作,脚本退出。"
exit 1
fi
echo "正在销毁 VMID $vmid..."
# 停止虚拟机(如果正在运行)
qm stop $vmid 2>/dev/null
# 销毁虚拟机
qm destroy $vmid --destroy-unreferenced-disks 1 --purge 1
if [ $? -ne 0 ]; then
echo "销毁虚拟机失败:VMID $vmid"
exit 1
fi
echo "已销毁 VMID $vmid 及其未引用磁盘和作业配置。"
fi
}
# 函数:下载镜像
download_image() {
local url=$1
local file=$2
echo "正在下载 $file ..."
wget -O /tmp/$file $url
if [ $? -ne 0 ]; then
echo "下载失败:$url"
echo "请检查网络连接或镜像地址是否有效。"
exit 1
fi
}
# 函数:创建虚拟机
create_vm() {
local vmid=$1
local vm_name=$2
local vmbr=$3
echo "正在创建虚拟机 $vm_name (VMID: $vmid)..."
# 创建虚拟机时不添加默认硬盘,使用用户指定的网络接口
qm create $vmid --memory 2048 --core 2 --name $vm_name --net0 virtio,bridge=$vmbr --ide0 none
if [ $? -ne 0 ]; then
echo "创建虚拟机失败:VMID $vmid"
exit 1
fi
}
# 函数:导入磁盘
import_disk() {
local vmid=$1
local image_file=$2
local storage=$3
# 导入磁盘到用户指定的存储
echo "正在导入磁盘 /tmp/$image_file 到 $storage 存储..."
qm importdisk $vmid /tmp/$image_file $storage --format qcow2
if [ $? -ne 0 ]; then
echo "导入磁盘失败:$image_file"
exit 1
fi
# 检查导入的磁盘文件是否存在(路径可能因存储类型不同而变化)
if [ ! -f "/var/lib/vz/images/$vmid/vm-$vmid-disk-0.qcow2" ]; then
echo "警告:未在 /var/lib/vz/images/$vmid/ 找到磁盘文件,可能是存储路径不同,请手动检查。"
else
echo "磁盘文件 /var/lib/vz/images/$vmid/vm-$vmid-disk-0.qcow2 已成功生成。"
fi
}
# 函数:配置虚拟机
configure_vm() {
local vmid=$1
local storage=$2
# 设置 SCSI 控制器并挂载导入的磁盘
echo "正在挂载磁盘 $storage:$vmid/vm-$vmid-disk-0.qcow2 到 scsi0..."
qm set $vmid --scsihw virtio-scsi-pci --scsi0 $storage:$vmid/vm-$vmid-disk-0.qcow2
if [ $? -ne 0 ]; then
echo "挂载磁盘到 scsi0 失败:VMID $vmid"
# 打印存储内容以供调试
echo "当前 $storage 存储内容:"
ls -lh /var/lib/vz/images/$vmid/ 2>/dev/null || echo "无法列出存储内容,可能是存储路径不同。"
exit 1
fi
# 配置 CloudInit、启动顺序等
qm set $vmid --ide2 $storage:cloudinit
qm set $vmid --boot c --bootdisk scsi0
qm set $vmid --serial0 socket --vga serial0
}
# 函数:将虚拟机转换为模板
convert_to_template() {
local vmid=$1
echo "正在将 VMID $vmid 转换为模板..."
qm template $vmid
if [ $? -ne 0 ]; then
echo "转换为模板失败:VMID $vmid"
exit 1
fi
}
# 主函数
main() {
# 如果提供了参数(发行版选项和 VMID),则使用参数运行
if [ $# -eq 2 ]; then
set_distro_and_vmid "$1" "$2"
else
# 否则进入交互模式
show_distro_menu
fi
# 提示用户输入网络接口和存储
prompt_for_network_and_storage
# 检查并销毁已存在的虚拟机
destroy_existing_vm $vmid
# 下载镜像
download_image $image_url $image_file
# 创建虚拟机
create_vm $vmid $vm_name $vmbr
# 导入磁盘
import_disk $vmid $image_file $storage
# 配置虚拟机
configure_vm $vmid $storage
# 转换为模板
convert_to_template $vmid
# 清理临时文件
rm /tmp/$image_file
echo "====================================="
echo "虚拟机模板 $vm_name (VMID: $vmid) 创建并转换为模板完成!"
echo "====================================="
}
# 运行主函数
main "$@"
全部下载系统模版
#!/bin/bash
# 函数:提示用户输入网络接口和存储
prompt_for_network_and_storage() {
echo -n "请输入网络接口(例如 vmbr0,默认为 vmbr0):"
read -r vmbr
if [ -z "$vmbr" ]; then
vmbr="vmbr0"
fi
echo -n "请输入存储名称(例如 local,默认为 local):"
read -r storage
if [ -z "$storage" ]; then
storage="local"
fi
}
# 函数:设置发行版信息
set_distro_info() {
local choice=$1
local input_vmid=$2
case $choice in
1)
distro="debian12"
image_url="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2"
image_file="debian-12-generic-amd64.qcow2"
vm_name="Debian-12"
;;
2)
distro="debian11"
image_url="https://cloud.debian.org/images/cloud/bullseye/latest/debian-11-generic-amd64.qcow2"
image_file="debian-11-generic-amd64.qcow2"
vm_name="Debian-11"
;;
3)
distro="centos9"
image_url="https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2"
image_file="CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2"
vm_name="CentOS-9"
;;
4)
distro="centos8"
image_url="https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-latest.x86_64.qcow2"
image_file="CentOS-Stream-GenericCloud-8-latest.x86_64.qcow2"
vm_name="CentOS-8"
;;
5)
distro="ubuntu22"
image_url="https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img"
image_file="jammy-server-cloudimg-amd64.img"
vm_name="Ubuntu-22"
;;
6)
distro="ubuntu24"
image_url="https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img"
image_file="noble-server-cloudimg-amd64.img"
vm_name="Ubuntu-24"
;;
7)
distro="alma8"
image_url="https://repo.almalinux.org/almalinux/8/cloud/x86_64/images/AlmaLinux-8-GenericCloud-latest.x86_64.qcow2"
image_file="AlmaLinux-8-GenericCloud-latest.x86_64.qcow2"
vm_name="AlmaLinux-8"
;;
8)
distro="alma9"
image_url="https://repo.almalinux.org/almalinux/9/cloud/x86_64/images/AlmaLinux-9-GenericCloud-latest.x86_64.qcow2"
image_file="AlmaLinux-9-GenericCloud-latest.x86_64.qcow2"
vm_name="AlmaLinux-9"
;;
9)
distro="rocky8"
image_url="https://download.rockylinux.org/pub/rocky/8/images/x86_64/Rocky-8-GenericCloud.latest.x86_64.qcow2"
image_file="Rocky-8-GenericCloud.latest.x86_64.qcow2"
vm_name="Rocky-8"
;;
10)
distro="rocky9"
image_url="https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2"
image_file="Rocky-9-GenericCloud.latest.x86_64.qcow2"
vm_name="Rocky-9"
;;
*)
echo "无效选项:$choice,请选择 1-10 之间的数字。"
exit 1
;;
esac
vmid=$input_vmid
if ! [[ "$vmid" =~ ^[0-9]+$ ]]; then
echo "VMID 必须是数字:$vmid"
exit 1
fi
}
# 函数:检查并销毁已存在的虚拟机(自动确认销毁)
destroy_existing_vm() {
local vmid=$1
if qm status $vmid >/dev/null 2>&1; then
echo "检测到 VMID $vmid 已存在,自动销毁..."
# 停止虚拟机(如果正在运行)
qm stop $vmid 2>/dev/null
# 销毁虚拟机
qm destroy $vmid --destroy-unreferenced-disks 1 --purge 1
if [ $? -ne 0 ]; then
echo "销毁虚拟机失败:VMID $vmid"
exit 1
fi
echo "已销毁 VMID $vmid 及其未引用磁盘和作业配置。"
fi
}
# 函数:下载镜像
download_image() {
local url=$1
local file=$2
echo "正在下载 $file ..."
wget -O /tmp/$file $url
if [ $? -ne 0 ]; then
echo "下载失败:$url"
echo "请检查网络连接或镜像地址是否有效。"
exit 1
fi
}
# 函数:创建虚拟机
create_vm() {
local vmid=$1
local vm_name=$2
local vmbr=$3
echo "正在创建虚拟机 $vm_name (VMID: $vmid)..."
# 创建虚拟机时不添加默认硬盘,使用用户指定的网络接口
qm create $vmid --memory 2048 --core 2 --name $vm_name --net0 virtio,bridge=$vmbr --ide0 none
if [ $? -ne 0 ]; then
echo "创建虚拟机失败:VMID $vmid"
exit 1
fi
}
# 函数:导入磁盘
import_disk() {
local vmid=$1
local image_file=$2
local storage=$3
# 导入磁盘到用户指定的存储
echo "正在导入磁盘 /tmp/$image_file 到 $storage 存储..."
qm importdisk $vmid /tmp/$image_file $storage --format qcow2
if [ $? -ne 0 ]; then
echo "导入磁盘失败:$image_file"
exit 1
fi
# 检查导入的磁盘文件是否存在(路径可能因存储类型不同而变化)
if [ ! -f "/var/lib/vz/images/$vmid/vm-$vmid-disk-0.qcow2" ]; then
echo "警告:未在 /var/lib/vz/images/$vmid/ 找到磁盘文件,可能是存储路径不同,请手动检查。"
else
echo "磁盘文件 /var/lib/vz/images/$vmid/vm-$vmid-disk-0.qcow2 已成功生成。"
fi
}
# 函数:配置虚拟机
configure_vm() {
local vmid=$1
local storage=$2
# 设置 SCSI 控制器并挂载导入的磁盘
echo "正在挂载磁盘 $storage:$vmid/vm-$vmid-disk-0.qcow2 到 scsi0..."
qm set $vmid --scsihw virtio-scsi-pci --scsi0 $storage:$vmid/vm-$vmid-disk-0.qcow2
if [ $? -ne 0 ]; then
echo "挂载磁盘到 scsi0 失败:VMID $vmid"
# 打印存储内容以供调试
echo "当前 $storage 存储内容:"
ls -lh /var/lib/vz/images/$vmid/ 2>/dev/null || echo "无法列出存储内容,可能是存储路径不同。"
exit 1
fi
# 配置 CloudInit、启动顺序等
qm set $vmid --ide2 $storage:cloudinit
qm set $vmid --boot c --bootdisk scsi0
qm set $vmid --serial0 socket --vga serial0
}
# 函数:将虚拟机转换为模板
convert_to_template() {
local vmid=$1
echo "正在将 VMID $vmid 转换为模板..."
qm template $vmid
if [ $? -ne 0 ]; then
echo "转换为模板失败:VMID $vmid"
exit 1
fi
}
# 函数:创建单个模板
create_template() {
local distro_option=$1
local vmid=$2
local vmbr=$3
local storage=$4
# 设置发行版信息
set_distro_info $distro_option $vmid
# 检查并销毁已存在的虚拟机
destroy_existing_vm $vmid
# 下载镜像
download_image $image_url $image_file
# 创建虚拟机
create_vm $vmid $vm_name $vmbr
# 导入磁盘
import_disk $vmid $image_file $storage
# 配置虚拟机
configure_vm $vmid $storage
# 转换为模板
convert_to_template $vmid
# 清理临时文件
rm /tmp/$image_file
echo "====================================="
echo "虚拟机模板 $vm_name (VMID: $vmid) 创建并转换为模板完成!"
echo "====================================="
}
# 函数:自动创建所有模板
create_all_templates() {
local start_vmid=8000
local distro_count=10 # 总共有 10 个发行版
local current_vmid=$start_vmid
# 发行版名称(仅用于显示)
declare -A distro_names
distro_names[1]="Debian 12"
distro_names[2]="Debian 11"
distro_names[3]="CentOS 9 Stream"
distro_names[4]="CentOS 8 Stream"
distro_names[5]="Ubuntu 22.04"
distro_names[6]="Ubuntu 24.04"
distro_names[7]="AlmaLinux 8"
distro_names[8]="AlmaLinux 9"
distro_names[9]="Rocky Linux 8"
distro_names[10]="Rocky Linux 9"
for distro_option in $(seq 1 $distro_count); do
echo "====================================="
echo "正在为 ${distro_names[$distro_option]} 创建模板,VMID: $current_vmid"
echo "====================================="
# 创建模板
create_template $distro_option $current_vmid $vmbr $storage
# VMID 递增
current_vmid=$((current_vmid + 1))
done
}
# 主函数
main() {
echo "====================================="
echo "开始一键安装所有 Proxmox VE 模板"
echo "VMID 将从 8000 开始递增"
echo "====================================="
# 提示用户输入网络接口和存储
prompt_for_network_and_storage
# 创建所有模板
create_all_templates
echo "====================================="
echo "所有模板创建完成!"
echo "创建的模板 VMID 范围:8000 - $((8000 + 10 - 1))"
echo "====================================="
}
# 运行主函数
main