diff --git a/CHANGELOG.md b/CHANGELOG.md index b490191..98bc483 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # 更新日志 +2023.08.03 + +- 尝试增加了IPV6的支持,暂时只是支持了IPV6网关的设置,暂时未适配一键开设,明日适配 +- 简化IPV4和IPV6地址的查询,避免重复查询 +- 修复可能的grub更新错误 +- 网络配置文件备份修改顺序,避免重复备份 +- 增加已修改过的文件的备份 +- KVM虚拟机增加centos8-stream镜像源 + 2023.08.02 - 更新KVM虚拟机镜像源,支持更多系统 diff --git a/README.md b/README.md index 5cab7c3..0e64f79 100644 --- a/README.md +++ b/README.md @@ -13,14 +13,10 @@ ## 更新 -2023.08.03 +2023.08.04 -- 尝试增加了IPV6的支持,暂时只是支持了IPV6网关的设置,暂时未适配一键开设,明日适配 -- 简化IPV4和IPV6地址的查询,避免重复查询 -- 修复可能的grub更新错误 -- 网络配置文件备份修改顺序,避免重复备份 -- 增加已修改过的文件的备份 -- KVM虚拟机增加centos8-stream镜像源 +- 开设独立IPV4地址的虚拟机时,尝试增加自动附加IPV6地址的功能 +- 增加一键开设纯IPV6虚拟机、纯IPV6容器的脚本 [更新日志](CHANGELOG.md) diff --git a/back/old_fuction.sh b/back/old_fuction.sh index a63182c..27d8697 100644 --- a/back/old_fuction.sh +++ b/back/old_fuction.sh @@ -119,4 +119,19 @@ check_interface(){ # 提取物理网卡名字 interface_1=$(lshw -C network | awk '/logical name:/{print $3}' | sed -n '1p') interface_2=$(lshw -C network | awk '/logical name:/{print $3}' | sed -n '2p') -check_interface \ No newline at end of file +check_interface + +first_digit=${CTID:0:1} +second_digit=${CTID:1:1} +third_digit=${CTID:2:1} +if [ $first_digit -le 2 ]; then + if [ $second_digit -eq 0 ]; then + num=$third_digit + else + num=$second_digit$third_digit + fi +else + num=$((first_digit - 2))$second_digit$third_digit +fi + +user_ip="172.16.1.${num}" \ No newline at end of file diff --git a/scripts/buildct.sh b/scripts/buildct.sh index f1bb63c..3167f3a 100644 --- a/scripts/buildct.sh +++ b/scripts/buildct.sh @@ -1,7 +1,7 @@ #!/bin/bash # from # https://github.com/spiritLHLS/pve -# 2023.07.31 +# 2023.08.04 # ./buildct.sh CTID 密码 CPU核数 内存 硬盘 SSH端口 80端口 443端口 外网端口起 外网端口止 系统 存储盘 @@ -195,6 +195,27 @@ if [ $first_digit -le 2 ]; then else num=$((first_digit - 2))$second_digit$third_digit fi +# 检测IPV6相关的信息 +if [ -f /usr/local/bin/pve_check_ipv6 ]; then + ipv6_address=$(cat /usr/local/bin/pve_check_ipv6) + IFS="/" read -ra parts <<< "$ipv6_address" + part_1="${parts[0]}" + part_2="${parts[1]}" + IFS=":" read -ra part_1_parts <<< "$part_1" + part_1_last="${part_1_parts[-1]}" + if [ "$part_1_last" = "$vm_num" ]; then + ipv6_address="" + else + part_1_head=$(echo "$part_1" | awk -F':' 'BEGIN {OFS=":"} {last=""; for (i=1; i /etc/iptables/rules.v4 service netfilter-persistent restart -echo "$CTID $password $core $memory $disk $sshn $web1_port $web2_port $port_first $port_last $system_ori $storage" >> "ct${CTID}" + # 容器的相关信息将会存储到对应的容器的NOTE中,可在WEB端查看 -data=$(echo " CTID root密码-password CPU核数-CPU 内存-memory 硬盘-disk SSH端口 80端口 443端口 外网端口起-port-start 外网端口止-port-end 系统-system 存储盘-storage") +if [ -z "$ipv6_address" ] || [ -z "$ipv6_prefixlen" ] || [ -z "$ipv6_gateway" ] || [ "$ipv6_prefixlen" -gt 112 ]; then + echo "$CTID $password $core $memory $disk $sshn $web1_port $web2_port $port_first $port_last $system_ori $storage" >> "ct${CTID}" + data=$(echo " CTID root密码-password CPU核数-CPU 内存-memory 硬盘-disk SSH端口 80端口 443端口 外网端口起-port-start 外网端口止-port-end 系统-system 存储盘-storage") +else + echo "$CTID $password $core $memory $disk $sshn $web1_port $web2_port $port_first $port_last $system_ori $storage $ipv6_address" >> "ct${CTID}" + data=$(echo " CTID root密码-password CPU核数-CPU 内存-memory 硬盘-disk SSH端口 80端口 443端口 外网端口起-port-start 外网端口止-port-end 系统-system 存储盘-storage 外网IPV6-ipv6") +fi values=$(cat "ct${CTID}") IFS=' ' read -ra data_array <<< "$data" IFS=' ' read -ra values_array <<< "$values" diff --git a/scripts/buildct_onlyv6.sh b/scripts/buildct_onlyv6.sh new file mode 100644 index 0000000..eb6f535 --- /dev/null +++ b/scripts/buildct_onlyv6.sh @@ -0,0 +1,244 @@ +#!/bin/bash +# from +# https://github.com/spiritLHLS/pve +# 2023.08.04 +# ./buildct_onlyv6.sh CTID 密码 CPU核数 内存 硬盘 系统 存储盘 +# ./buildct_onlyv6.sh 102 1234567 1 512 5 debian11 local + +# 用颜色输出信息 +_red() { echo -e "\033[31m\033[01m$@\033[0m"; } +_green() { echo -e "\033[32m\033[01m$@\033[0m"; } +_yellow() { echo -e "\033[33m\033[01m$@\033[0m"; } +_blue() { echo -e "\033[36m\033[01m$@\033[0m"; } +reading(){ read -rp "$(_green "$1")" "$2"; } +utf8_locale=$(locale -a 2>/dev/null | grep -i -m 1 -E "UTF-8|utf8") +if [[ -z "$utf8_locale" ]]; then + echo "No UTF-8 locale found" +else + export LC_ALL="$utf8_locale" + export LANG="$utf8_locale" + export LANGUAGE="$utf8_locale" + echo "Locale set to $utf8_locale" +fi + +get_system_arch() { + local sysarch="$(uname -m)" + if [ "${sysarch}" = "unknown" ] || [ "${sysarch}" = "" ]; then + local sysarch="$(arch)" + fi + # 根据架构信息设置系统位数并下载文件,其余 * 包括了 x86_64 + case "${sysarch}" in + "i386" | "i686" | "x86_64") + system_arch="x86" + ;; + "armv7l" | "armv8" | "armv8l" | "aarch64") + system_arch="arch" + ;; + *) + system_arch="" + ;; + esac +} + +check_china(){ + _yellow "IP area being detected ......" + if [[ -z "${CN}" ]]; then + if [[ $(curl -m 6 -s https://ipapi.co/json | grep 'China') != "" ]]; then + _yellow "根据ipapi.co提供的信息,当前IP可能在中国,使用中国镜像下载" + CN=true + else + if [[ $? -ne 0 ]]; then + if [[ $(curl -m 6 -s cip.cc) =~ "中国" ]]; then + _yellow "根据cip.cc提供的信息,当前IP可能在中国,使用中国镜像下载" + CN=true + fi + fi + fi + fi +} + +get_system_arch +if [ -z "${system_arch}" ] || [ ! -v system_arch ]; then + _red "This script can only run on machines under x86_64 or arm architecture." + exit 1 +fi +cd /root >/dev/null 2>&1 +CTID="${1:-102}" +password="${2:-123456}" +core="${3:-1}" +memory="${4:-512}" +disk="${5:-5}" +system_ori="${6:-debian11}" +storage="${7:-local}" +rm -rf "ct$name" +en_system=$(echo "$system_ori" | sed 's/[0-9]*//g') +num_system=$(echo "$system_ori" | sed 's/[a-zA-Z]*//g') +system="$en_system-$num_system" +if [ "$system_arch" = "arch" ]; then + if [ "$en_system" = "ubuntu" ]; then + case "$system_ori" in + ubuntu14) + version="trusty" + ;; + ubuntu16) + version="xenial" + ;; + ubuntu18) + version="bionic" + ;; + ubuntu20) + version="focal" + ;; + ubuntu22) + version="jammy" + ;; + *) + echo "Unsupported Ubuntu version." + exit 1 + ;; + esac + elif [ "$en_system" = "debian" ]; then + case "$system_ori" in + debian6) + version="squeeze" + ;; + debian7) + version="wheezy" + ;; + debian8) + version="jessie" + ;; + debian9) + version="stretch" + ;; + debian10) + version="buster" + ;; + debian11) + version="bullseye" + ;; + debian12) + version="bookworm" + ;; + *) + echo "Unsupported Debian version." + exit 1 + ;; + esac + else + version=${num_system} + fi + check_china + if [[ -z "${CN}" || "${CN}" != true ]]; then + curl -o "/var/lib/vz/template/cache/${en_system}-arm64-${version}-cloud.tar.xz" "https://jenkins.linuxcontainers.org/view/LXC/job/image-${en_system}/architecture=arm64,release=${version},variant=cloud/lastSuccessfulBuild/artifact/rootfs.tar.xz" + else + # https://mirror.tuna.tsinghua.edu.cn/lxc-images/images/ + URL="https://mirror.tuna.tsinghua.edu.cn/lxc-images/images/${en_system}/${version}/arm64/cloud/" + HTML=$(curl -s "$URL") + folder_links_dates=$(echo "$HTML" | grep -oE '([^<]+)' | sed -E 's/([^<]+)/\1 \2/') + sorted_links=$(echo "$folder_links_dates" | sort -k2 -r) + latest_folder_link=$(echo "$sorted_links" | head -n 1 | awk '{print $1}') + latest_folder_url="${URL}${latest_folder_link}" + curl -o "/var/lib/vz/template/cache/${en_system}-arm64-${version}-cloud.tar.xz" "${latest_folder_url}/rootfs.tar.xz" + fi +else + system_name=$(pveam available --section system | grep "$system" | awk '{print $2}' | head -n1) + if ! pveam available --section system | grep "$system" > /dev/null; then + _red "No such system" + exit + else + _green "Use $system_name" + fi + pveam download local $system_name +fi + +check_cdn() { + local o_url=$1 + for cdn_url in "${cdn_urls[@]}"; do + if curl -sL -k "$cdn_url$o_url" --max-time 6 | grep -q "success" > /dev/null 2>&1; then + export cdn_success_url="$cdn_url" + return + fi + sleep 0.5 + done + export cdn_success_url="" +} + +check_cdn_file() { + check_cdn "https://raw.githubusercontent.com/spiritLHLS/ecs/main/back/test" + if [ -n "$cdn_success_url" ]; then + _yellow "CDN available, using CDN" + else + _yellow "No CDN available, no use CDN" + fi +} + +cdn_urls=("https://cdn.spiritlhl.workers.dev/" "https://cdn3.spiritlhl.net/" "https://cdn1.spiritlhl.net/" "https://ghproxy.com/" "https://cdn2.spiritlhl.net/") +check_cdn_file + +# 检测IPV6相关的信息 +if [ -f /usr/local/bin/pve_check_ipv6 ]; then + ipv6_address=$(cat /usr/local/bin/pve_check_ipv6) + IFS="/" read -ra parts <<< "$ipv6_address" + part_1="${parts[0]}" + part_2="${parts[1]}" + IFS=":" read -ra part_1_parts <<< "$part_1" + part_1_last="${part_1_parts[-1]}" + if [ "$part_1_last" = "$vm_num" ]; then + ipv6_address="" + else + part_1_head=$(echo "$part_1" | awk -F':' 'BEGIN {OFS=":"} {last=""; for (i=1; i> "ct${CTID}" +# 容器的相关信息将会存储到对应的容器的NOTE中,可在WEB端查看 +data=$(echo " CTID root密码-password CPU核数-CPU 内存-memory 硬盘-disk 系统-system 存储盘-storage 外网IPV6-ipv6") +values=$(cat "ct${CTID}") +IFS=' ' read -ra data_array <<< "$data" +IFS=' ' read -ra values_array <<< "$values" +length=${#data_array[@]} +for ((i=0; i<$length; i++)) +do + echo "${data_array[$i]} ${values_array[$i]}" + echo "" +done > "/tmp/temp${CTID}.txt" +sed -i 's/^/# /' "/tmp/temp${CTID}.txt" +cat "/etc/pve/lxc/${CTID}.conf" >> "/tmp/temp${CTID}.txt" +cp "/tmp/temp${CTID}.txt" "/etc/pve/lxc/${CTID}.conf" +rm -rf "/tmp/temp${CTID}.txt" +cat "ct${CTID}" diff --git a/scripts/buildvm.sh b/scripts/buildvm.sh index a24a402..288f208 100644 --- a/scripts/buildvm.sh +++ b/scripts/buildvm.sh @@ -1,7 +1,7 @@ #!/bin/bash # from # https://github.com/spiritLHLS/pve -# 2023.08.03 +# 2023.08.04 # ./buildvm.sh VMID 用户名 密码 CPU核数 内存 硬盘 SSH端口 80端口 443端口 外网端口起 外网端口止 系统 存储盘 @@ -192,7 +192,27 @@ elif [ "$system_arch" = "arch" ]; then curl -L -o "$file_path" "$url" fi fi - +# 检测IPV6相关的信息 +if [ -f /usr/local/bin/pve_check_ipv6 ]; then + ipv6_address=$(cat /usr/local/bin/pve_check_ipv6) + IFS="/" read -ra parts <<< "$ipv6_address" + part_1="${parts[0]}" + part_2="${parts[1]}" + IFS=":" read -ra part_1_parts <<< "$part_1" + part_1_last="${part_1_parts[-1]}" + if [ "$part_1_last" = "$vm_num" ]; then + ipv6_address="" + else + part_1_head=$(echo "$part_1" | awk -F':' 'BEGIN {OFS=":"} {last=""; for (i=1; i /etc/iptables/rules.v4 service netfilter-persistent restart -echo "$vm_num $user $password $core $memory $disk $sshn $web1_port $web2_port $port_first $port_last $system $storage" >> "vm${vm_num}" + # 虚拟机的相关信息将会存储到对应的虚拟机的NOTE中,可在WEB端查看 -data=$(echo " VMID 用户名-username 密码-password CPU核数-CPU 内存-memory 硬盘-disk SSH端口 80端口 443端口 外网端口起-port-start 外网端口止-port-end 系统-system 存储盘-storage") +if [ -z "$ipv6_address" ] || [ -z "$ipv6_prefixlen" ] || [ -z "$ipv6_gateway" ] || [ "$ipv6_prefixlen" -gt 112 ]; then + echo "$vm_num $user $password $core $memory $disk $sshn $web1_port $web2_port $port_first $port_last $system $storage" >> "vm${vm_num}" + data=$(echo " VMID 用户名-username 密码-password CPU核数-CPU 内存-memory 硬盘-disk SSH端口 80端口 443端口 外网端口起-port-start 外网端口止-port-end 系统-system 存储盘-storage") +else + echo "$vm_num $user $password $core $memory $disk $sshn $web1_port $web2_port $port_first $port_last $system $storage $ipv6_address" >> "vm${vm_num}" + data=$(echo " VMID 用户名-username 密码-password CPU核数-CPU 内存-memory 硬盘-disk SSH端口 80端口 443端口 外网端口起-port-start 外网端口止-port-end 系统-system 存储盘-storage 外网IPV6-ipv6") +fi values=$(cat "vm${vm_num}") IFS=' ' read -ra data_array <<< "$data" IFS=' ' read -ra values_array <<< "$values" diff --git a/scripts/buildvm_extraip.sh b/scripts/buildvm_extraip.sh index 4607a24..f26087b 100644 --- a/scripts/buildvm_extraip.sh +++ b/scripts/buildvm_extraip.sh @@ -1,10 +1,8 @@ #!/bin/bash # from # https://github.com/spiritLHLS/pve -# 2023.08.03 +# 2023.08.04 # 自动选择要绑定的IPV4地址 - - # ./buildvm_extraip.sh VMID 用户名 密码 CPU核数 内存 硬盘 系统 存储盘 # ./buildvm_extraip.sh 152 test1 1234567 1 512 5 debian11 local @@ -189,20 +187,27 @@ elif [ "$system_arch" = "arch" ]; then curl -L -o "$file_path" "$url" fi fi - -first_digit=${vm_num:0:1} -second_digit=${vm_num:1:1} -third_digit=${vm_num:2:1} -if [ $first_digit -le 2 ]; then - if [ $second_digit -eq 0 ]; then - num=$third_digit +# 检测IPV6相关的信息 +if [ -f /usr/local/bin/pve_check_ipv6 ]; then + ipv6_address=$(cat /usr/local/bin/pve_check_ipv6) + IFS="/" read -ra parts <<< "$ipv6_address" + part_1="${parts[0]}" + part_2="${parts[1]}" + IFS=":" read -ra part_1_parts <<< "$part_1" + part_1_last="${part_1_parts[-1]}" + if [ "$part_1_last" = "$vm_num" ]; then + ipv6_address="" else - num=$second_digit$third_digit + part_1_head=$(echo "$part_1" | awk -F':' 'BEGIN {OFS=":"} {last=""; for (i=1; i /dev/null 2>&1; then apt-get install -y lshw @@ -286,10 +291,13 @@ qm set $vm_num --memory $memory qm set $vm_num --ide2 ${storage}:cloudinit qm set $vm_num --nameserver 8.8.8.8 qm set $vm_num --searchdomain 8.8.4.4 -qm set $vm_num --ipconfig0 ip=${user_ip}/${user_ip_range},gw=${gateway} +if [ -z "$ipv6_address" ] || [ -z "$ipv6_prefixlen" ] || [ -z "$ipv6_gateway" ] || [ "$ipv6_prefixlen" -gt 112 ]; then + qm set $vm_num --ipconfig0 ip=${user_ip}/${user_ip_range},gw=${gateway} +else + qm set $vm_num --ipconfig0 ip=${user_ip}/${user_ip_range},gw=${gateway} --ipconfig1 ip=${ipv6_address}/${ipv6_prefixlen},gw=${ipv6_gateway} +fi qm set $vm_num --cipassword $password --ciuser $user sleep 5 -# qm set $vm_num --agent 1 qm resize $vm_num scsi0 ${disk}G if [ $? -ne 0 ]; then if [[ $disk =~ ^[0-9]+G$ ]]; then @@ -300,9 +308,14 @@ if [ $? -ne 0 ]; then fi qm start $vm_num -echo "$vm_num $user $password $core $memory $disk $system $storage $user_ip" >> "vm${vm_num}" # 虚拟机的相关信息将会存储到对应的虚拟机的NOTE中,可在WEB端查看 -data=$(echo " VMID 用户名-username 密码-password CPU核数-CPU 内存-memory 硬盘-disk 系统-system 存储盘-storage 外网IP地址-ipv4") +if [ -z "$ipv6_address" ] || [ -z "$ipv6_prefixlen" ] || [ -z "$ipv6_gateway" ] || [ "$ipv6_prefixlen" -gt 112 ]; then + echo "$vm_num $user $password $core $memory $disk $system $storage $user_ip" >> "vm${vm_num}" + data=$(echo " VMID 用户名-username 密码-password CPU核数-CPU 内存-memory 硬盘-disk 系统-system 存储盘-storage 外网IP地址-ipv4") +else + echo "$vm_num $user $password $core $memory $disk $system $storage $user_ip $ipv6_address" >> "vm${vm_num}" + data=$(echo " VMID 用户名-username 密码-password CPU核数-CPU 内存-memory 硬盘-disk 系统-system 存储盘-storage 外网IPV4-ipv4 外网IPV6-ipv6") +fi values=$(cat "vm${vm_num}") IFS=' ' read -ra data_array <<< "$data" IFS=' ' read -ra values_array <<< "$values" diff --git a/scripts/buildvm_manual_ip.sh b/scripts/buildvm_manual_ip.sh index cc55187..03b1644 100644 --- a/scripts/buildvm_manual_ip.sh +++ b/scripts/buildvm_manual_ip.sh @@ -1,7 +1,7 @@ #!/bin/bash # from # https://github.com/spiritLHLS/pve -# 2023.08.03 +# 2023.08.04 # 手动指定要绑定的IPV4地址 @@ -217,20 +217,6 @@ elif [ "$system_arch" = "arch" ]; then curl -L -o "$file_path" "$url" fi fi - -first_digit=${vm_num:0:1} -second_digit=${vm_num:1:1} -third_digit=${vm_num:2:1} -if [ $first_digit -le 2 ]; then - if [ $second_digit -eq 0 ]; then - num=$third_digit - else - num=$second_digit$third_digit - fi -else - num=$((first_digit - 2))$second_digit$third_digit -fi - # 查询信息 if ! command -v lshw > /dev/null 2>&1; then apt-get install -y lshw @@ -267,6 +253,27 @@ if [ -z "$user_ip_range" ]; then fi _green "The current IP to which the VM will be bound is: ${user_ip}" _green "当前虚拟机将绑定的IP为:${user_ip}" +# 检测IPV6相关的信息 +if [ -f /usr/local/bin/pve_check_ipv6 ]; then + ipv6_address=$(cat /usr/local/bin/pve_check_ipv6) + IFS="/" read -ra parts <<< "$ipv6_address" + part_1="${parts[0]}" + part_2="${parts[1]}" + IFS=":" read -ra part_1_parts <<< "$part_1" + part_1_last="${part_1_parts[-1]}" + if [ "$part_1_last" = "$vm_num" ]; then + ipv6_address="" + else + part_1_head=$(echo "$part_1" | awk -F':' 'BEGIN {OFS=":"} {last=""; for (i=1; i> "vm${vm_num}" # 虚拟机的相关信息将会存储到对应的虚拟机的NOTE中,可在WEB端查看 -data=$(echo " VMID 用户名-username 密码-password CPU核数-CPU 内存-memory 硬盘-disk 系统-system 存储盘-storage 外网IP地址-ipv4") +if [ -z "$ipv6_address" ] || [ -z "$ipv6_prefixlen" ] || [ -z "$ipv6_gateway" ] || [ "$ipv6_prefixlen" -gt 112 ]; then + echo "$vm_num $user $password $core $memory $disk $system $storage $user_ip" >> "vm${vm_num}" + data=$(echo " VMID 用户名-username 密码-password CPU核数-CPU 内存-memory 硬盘-disk 系统-system 存储盘-storage 外网IP地址-ipv4") +else + echo "$vm_num $user $password $core $memory $disk $system $storage $user_ip $ipv6_address" >> "vm${vm_num}" + data=$(echo " VMID 用户名-username 密码-password CPU核数-CPU 内存-memory 硬盘-disk 系统-system 存储盘-storage 外网IPV4-ipv4 外网IPV6-ipv6") +fi values=$(cat "vm${vm_num}") IFS=' ' read -ra data_array <<< "$data" IFS=' ' read -ra values_array <<< "$values" length=${#data_array[@]} for ((i=0; i<$length; i++)) do - echo "${data_array[$i]} ${values_array[$i]}" - echo "" + echo "${data_array[$i]} ${values_array[$i]}" + echo "" done > "/tmp/temp${vm_num}.txt" sed -i 's/^/# /' "/tmp/temp${vm_num}.txt" cat "/etc/pve/qemu-server/${vm_num}.conf" >> "/tmp/temp${vm_num}.txt" diff --git a/scripts/buildvm_onlyv6.sh b/scripts/buildvm_onlyv6.sh new file mode 100644 index 0000000..bcf315d --- /dev/null +++ b/scripts/buildvm_onlyv6.sh @@ -0,0 +1,257 @@ +#!/bin/bash +# from +# https://github.com/spiritLHLS/pve +# 2023.08.04 +# 自动选择要绑定的IPV6地址 +# ./buildvm_onlyv6.sh VMID 用户名 密码 CPU核数 内存 硬盘 系统 存储盘 +# ./buildvm_onlyv6.sh 152 test1 1234567 1 512 5 debian11 local + +cd /root >/dev/null 2>&1 +# 创建NAT的虚拟机 +vm_num="${1:-102}" +user="${2:-test}" +password="${3:-123456}" +core="${4:-1}" +memory="${5:-512}" +disk="${6:-5}" +system="${7:-ubuntu22}" +storage="${8:-local}" +rm -rf "vm$name" + +_red() { echo -e "\033[31m\033[01m$@\033[0m"; } +_green() { echo -e "\033[32m\033[01m$@\033[0m"; } +_yellow() { echo -e "\033[33m\033[01m$@\033[0m"; } +_blue() { echo -e "\033[36m\033[01m$@\033[0m"; } +reading(){ read -rp "$(_green "$1")" "$2"; } +utf8_locale=$(locale -a 2>/dev/null | grep -i -m 1 -E "utf8|UTF-8") +if [[ -z "$utf8_locale" ]]; then + _yellow "No UTF-8 locale found" +else + export LC_ALL="$utf8_locale" + export LANG="$utf8_locale" + export LANGUAGE="$utf8_locale" + _green "Locale set to $utf8_locale" +fi + +get_system_arch() { + local sysarch="$(uname -m)" + if [ "${sysarch}" = "unknown" ] || [ "${sysarch}" = "" ]; then + local sysarch="$(arch)" + fi + # 根据架构信息设置系统位数并下载文件,其余 * 包括了 x86_64 + case "${sysarch}" in + "i386" | "i686" | "x86_64") + system_arch="x86" + ;; + "armv7l" | "armv8" | "armv8l" | "aarch64") + system_arch="arch" + ;; + *) + system_arch="" + ;; + esac +} + +check_cdn() { + local o_url=$1 + for cdn_url in "${cdn_urls[@]}"; do + if curl -sL -k "$cdn_url$o_url" --max-time 6 | grep -q "success" > /dev/null 2>&1; then + export cdn_success_url="$cdn_url" + return + fi + sleep 0.5 + done + export cdn_success_url="" +} + +check_cdn_file() { + check_cdn "https://raw.githubusercontent.com/spiritLHLS/ecs/main/back/test" + if [ -n "$cdn_success_url" ]; then + _yellow "CDN available, using CDN" + else + _yellow "No CDN available, no use CDN" + fi +} + +cdn_urls=("https://cdn.spiritlhl.workers.dev/" "https://cdn3.spiritlhl.net/" "https://cdn1.spiritlhl.net/" "https://ghproxy.com/" "https://cdn2.spiritlhl.net/") +if [ ! -d "qcow" ]; then + mkdir qcow +fi +get_system_arch +if [ -z "${system_arch}" ] || [ ! -v system_arch ]; then + _red "This script can only run on machines under x86_64 or arm architecture." + exit 1 +fi +if [ "$system_arch" = "x86" ]; then + file_path="" + systems=( + "debian10" + "debian11" + "debian12" + "ubuntu18" + "ubuntu20" + "ubuntu22" + "centos7" + "archlinux" + "almalinux8" + "fedora33" + "fedora34" + "opensuse-leap-15" + "alpinelinux_edge" + "alpinelinux_stable" + "rockylinux8" + "centos8-stream" + ) + for sys in ${systems[@]}; do + if [[ "$system" == "$sys" ]]; then + file_path="/root/qcow/${system}.qcow2" + break + fi + done + if [[ -z "$file_path" ]]; then + _red "Unable to install corresponding system, please check https://github.com/oneclickvirt/kvm_images/ for supported system images " + _red "无法安装对应系统,请查看 https://github.com/oneclickvirt/kvm_images/ 支持的系统镜像 " + exit 1 + fi + if [ ! -f "$file_path" ]; then + check_cdn_file + ver="" + v20=("fedora34" "almalinux8" "debian11" "debian12" "ubuntu18" "ubuntu20" "ubuntu22" "centos7" "alpinelinux_edge" "alpinelinux_stable" "rockylinux8") + v11=("ubuntu18" "ubuntu20" "ubuntu22" "debian10" "debian11") + v10=("almalinux8" "archlinux" "fedora33" "opensuse-leap-15" "ubuntu18" "ubuntu20" "ubuntu22" "debian10" "debian11") + ver_list=(v20 v11 v10) + ver_name_list=("v2.0" "v1.1" "v1.0") + for ver in "${ver_list[@]}"; do + array_name="${ver}[@]" + array=("${!array_name}") + if [[ " ${array[*]} " == *" $system "* ]]; then + index=$(echo ${ver_list[*]} | tr -s ' ' '\n' | grep -n "$ver" | cut -d':' -f1) + ver="${ver_name_list[$((index-1))]}" + break + fi + done + if [[ "$system" == "centos8-stream" ]]; then + url="https://git.ilolicon.dev/Ella-Alinda/images/raw/branch/main/centos8-stream.qcow2" + curl -Lk -o "$file_path" "$url" + else + if [[ -n "$ver" ]]; then + url="${cdn_success_url}https://github.com/oneclickvirt/kvm_images/releases/download/${ver}/${system}.qcow2" + curl -Lk -o "$file_path" "$url" + else + _red "Unable to install corresponding system, please check https://github.com/oneclickvirt/kvm_images/ for supported system images " + _red "无法安装对应系统,请查看 https://github.com/oneclickvirt/kvm_images/ 支持的系统镜像 " + exit 1 + fi + fi + fi +elif [ "$system_arch" = "arch" ]; then + systems=("ubuntu14" "ubuntu16" "ubuntu18" "ubuntu20" "ubuntu22") + for sys in ${systems[@]}; do + if [[ "$system" == "$sys" ]]; then + file_path="/root/qcow/${system}.img" + break + fi + done + if [[ -z "$file_path" ]]; then + # https://www.debian.org/mirror/list + _red "Unable to install corresponding system, please check http://cloud-images.ubuntu.com for supported system images " + _red "无法安装对应系统,请查看 http://cloud-images.ubuntu.com 支持的系统镜像 " + exit 1 + fi + if [ -n "$file_path" ] && [ -f "$file_path" ]; then + case "$system" in + ubuntu14) + version="trusty" + ;; + ubuntu16) + version="xenial" + ;; + ubuntu18) + version="bionic" + ;; + ubuntu20) + version="focal" + ;; + ubuntu22) + version="jammy" + ;; + *) + echo "Unsupported Ubuntu version." + exit 1 + ;; + esac + url="http://cloud-images.ubuntu.com/${version}/current/${version}-server-cloudimg-arm64.img" + curl -L -o "$file_path" "$url" + fi +fi +# 检测IPV6相关的信息 +if [ -f /usr/local/bin/pve_check_ipv6 ]; then + ipv6_address=$(cat /usr/local/bin/pve_check_ipv6) + IFS="/" read -ra parts <<< "$ipv6_address" + part_1="${parts[0]}" + part_2="${parts[1]}" + IFS=":" read -ra part_1_parts <<< "$part_1" + part_1_last="${part_1_parts[-1]}" + if [ "$part_1_last" = "$vm_num" ]; then + ipv6_address="" + else + part_1_head=$(echo "$part_1" | awk -F':' 'BEGIN {OFS=":"} {last=""; for (i=1; i> "vm${vm_num}" +# 虚拟机的相关信息将会存储到对应的虚拟机的NOTE中,可在WEB端查看 +data=$(echo " VMID 用户名-username 密码-password CPU核数-CPU 内存-memory 硬盘-disk 系统-system 存储盘-storage 外网IPV6-ipv6") +values=$(cat "vm${vm_num}") +IFS=' ' read -ra data_array <<< "$data" +IFS=' ' read -ra values_array <<< "$values" +length=${#data_array[@]} +for ((i=0; i<$length; i++)) +do + echo "${data_array[$i]} ${values_array[$i]}" + echo "" +done > "/tmp/temp${vm_num}.txt" +sed -i 's/^/# /' "/tmp/temp${vm_num}.txt" +cat "/etc/pve/qemu-server/${vm_num}.conf" >> "/tmp/temp${vm_num}.txt" +cp "/tmp/temp${vm_num}.txt" "/etc/pve/qemu-server/${vm_num}.conf" +rm -rf "/tmp/temp${vm_num}.txt" +cat "vm${vm_num}"