From 03c1644b3a138b6fec6dbac5ce518fcb22fb9a65 Mon Sep 17 00:00:00 2001 From: Mapleawaa Date: Fri, 17 Oct 2025 21:00:17 +0800 Subject: [PATCH] feat: Add various Proxmox VE helper scripts for monitoring, installation, and configuration - Introduced `monitor-all.sh` for monitoring and restarting LXC and VM instances based on ping status. - Added `netdata.sh` for installing and uninstalling NetData on Proxmox VE. - Created `post-pbs-install.sh` for post-installation routines specific to Proxmox Backup Server. - Developed `post-pve-install.sh` for post-installation routines specific to Proxmox VE. - Implemented `scaling-governor.sh` to manage CPU scaling governors and set crontab for persistence. - Added `update-lxcs.sh` for updating LXC containers with options to exclude specific containers. --- PVE-Tools.sh | 305 +++++++++++++++++++++++++++++++++++++- Tools/.gitkeep | 2 + Tools/README.md | 81 ++++++++++ Tools/clean-lxcs.sh | 77 ++++++++++ Tools/cron-update-lxcs.sh | 56 +++++++ Tools/fstrim.sh | 78 ++++++++++ Tools/host-backup.sh | 79 ++++++++++ Tools/kernel-clean.sh | 75 ++++++++++ Tools/kernel-pin.sh | 70 +++++++++ Tools/microcode.sh | 125 ++++++++++++++++ Tools/monitor-all.sh | 163 ++++++++++++++++++++ Tools/netdata.sh | 122 +++++++++++++++ Tools/post-pbs-install.sh | 184 +++++++++++++++++++++++ Tools/post-pve-install.sh | 242 ++++++++++++++++++++++++++++++ Tools/scaling-governor.sh | 58 ++++++++ Tools/update-lxcs.sh | 112 ++++++++++++++ UPDATE | 28 +--- 17 files changed, 1832 insertions(+), 25 deletions(-) create mode 100644 Tools/.gitkeep create mode 100644 Tools/README.md create mode 100644 Tools/clean-lxcs.sh create mode 100644 Tools/cron-update-lxcs.sh create mode 100644 Tools/fstrim.sh create mode 100644 Tools/host-backup.sh create mode 100644 Tools/kernel-clean.sh create mode 100644 Tools/kernel-pin.sh create mode 100644 Tools/microcode.sh create mode 100644 Tools/monitor-all.sh create mode 100644 Tools/netdata.sh create mode 100644 Tools/post-pbs-install.sh create mode 100644 Tools/post-pve-install.sh create mode 100644 Tools/scaling-governor.sh create mode 100644 Tools/update-lxcs.sh diff --git a/PVE-Tools.sh b/PVE-Tools.sh index bff95ee..a48c526 100644 --- a/PVE-Tools.sh +++ b/PVE-Tools.sh @@ -1917,6 +1917,303 @@ remove_ceph() { } #---------PVE一键卸载ceph----------- +#---------第三方小工具管理----------- +# 小工具配置 +TOOLS_DIR="./Tools" +TOOLS_SOURCE_URL="https://github.com/tteck/Proxmox/raw/main/misc" +TOOLS_AUTHOR="tteck" +TOOLS_REPO="https://github.com/tteck/Proxmox" + +# 小工具列表(名称|描述) +declare -A TOOLS_LIST=( + ["post-pbs-install.sh"]="PBS 安装后配置|Post PBS Installation Setup" + ["post-pve-install.sh"]="PVE 安装后配置|Post PVE Installation Setup" + ["scaling-governor.sh"]="CPU 调频策略配置|CPU Scaling Governor Setup" + ["cron-update-lxcs.sh"]="定时更新 LXC 容器|Cron Update LXC Containers" + ["host-backup.sh"]="主机备份工具|Host Backup Tool" + ["kernel-clean.sh"]="内核清理工具|Kernel Cleanup Tool" + ["kernel-pin.sh"]="内核版本固定|Kernel Version Pin" + ["clean-lxcs.sh"]="清理 LXC 容器|Clean LXC Containers" + ["fstrim.sh"]="SSD Trim 优化|SSD Trim Optimization" + ["update-lxcs.sh"]="更新 LXC 容器|Update LXC Containers" + ["monitor-all.sh"]="全局监控工具|Monitor All Services" + ["netdata.sh"]="Netdata 监控安装|Netdata Monitoring Setup" + ["microcode.sh"]="CPU 微码更新|CPU Microcode Update" +) + +# 检查并创建工具目录 +check_tools_directory() { + if [[ ! -d "$TOOLS_DIR" ]]; then + log_info "创建工具目录: $TOOLS_DIR" + mkdir -p "$TOOLS_DIR" + fi +} + +# 下载所有小工具 +download_tools() { + log_step "开始下载第三方小工具集..." + check_tools_directory + + echo + log_info "工具来源: ${CYAN}$TOOLS_AUTHOR${NC} - $TOOLS_REPO" + log_info "下载位置: ${CYAN}$TOOLS_DIR${NC}" + echo + + local total=${#TOOLS_LIST[@]} + local current=0 + local success=0 + local failed=0 + + for tool_name in "${!TOOLS_LIST[@]}"; do + current=$((current + 1)) + local tool_url="$TOOLS_SOURCE_URL/$tool_name" + local tool_path="$TOOLS_DIR/$tool_name" + + # 显示进度 + show_progress_bar $current $total "下载: $tool_name" + + # 使用 curl 下载(带进度和超时) + if command -v curl &> /dev/null; then + if curl -fsSL --connect-timeout 10 --max-time 60 \ + -o "$tool_path" "$tool_url" 2>/dev/null; then + chmod +x "$tool_path" + success=$((success + 1)) + else + failed=$((failed + 1)) + log_warn "下载失败: $tool_name" + fi + else + # 备用 wget + if wget -q -O "$tool_path" "$tool_url" 2>/dev/null; then + chmod +x "$tool_path" + success=$((success + 1)) + else + failed=$((failed + 1)) + log_warn "下载失败: $tool_name" + fi + fi + done + + echo # 进度条后换行 + echo + + if [[ $success -eq $total ]]; then + log_success "所有工具下载完成!成功: $success/$total" + elif [[ $success -gt 0 ]]; then + log_warn "部分工具下载完成。成功: $success, 失败: $failed" + else + log_error "工具下载失败!请检查网络连接" + return 1 + fi + + log_info "工具已保存到: ${CYAN}$(cd "$TOOLS_DIR" && pwd)${NC}" + return 0 +} + +# 检查工具是否已下载 +check_tools_downloaded() { + if [[ ! -d "$TOOLS_DIR" ]] || [[ $(ls -1 "$TOOLS_DIR"/*.sh 2>/dev/null | wc -l) -eq 0 ]]; then + return 1 + fi + return 0 +} + +# 显示已下载的工具列表 +list_downloaded_tools() { + log_info "已下载的工具:" + echo + + local index=1 + for tool_name in "${!TOOLS_LIST[@]}"; do + local tool_path="$TOOLS_DIR/$tool_name" + local desc_full="${TOOLS_LIST[$tool_name]}" + local desc_cn=$(echo "$desc_full" | cut -d'|' -f1) + local desc_en=$(echo "$desc_full" | cut -d'|' -f2) + + if [[ -f "$tool_path" ]]; then + printf " ${GREEN}%-2s${NC}. %-30s ${CYAN}%s${NC}\n" "$index" "$desc_cn" "($desc_en)" + printf " ${YELLOW}文件:${NC} %s\n" "$tool_name" + else + printf " ${RED}%-2s${NC}. %-30s ${RED}(未下载)${NC}\n" "$index" "$desc_cn" + fi + + index=$((index + 1)) + echo + done +} + +# 执行小工具 +run_tool() { + local tool_name="$1" + local tool_path="$TOOLS_DIR/$tool_name" + + if [[ ! -f "$tool_path" ]]; then + log_error "工具不存在: $tool_name" + return 1 + fi + + if [[ ! -x "$tool_path" ]]; then + log_warn "工具不可执行,尝试添加执行权限..." + chmod +x "$tool_path" + fi + + local desc_full="${TOOLS_LIST[$tool_name]}" + local desc_cn=$(echo "$desc_full" | cut -d'|' -f1) + + echo + log_step "准备执行工具: ${GREEN}$desc_cn${NC}" + log_info "工具文件: ${CYAN}$tool_name${NC}" + log_info "工具路径: ${CYAN}$tool_path${NC}" + echo + + echo "${UI_BORDER}" + log_warn "注意事项:" + echo " 1. 此工具来自第三方项目: $TOOLS_AUTHOR" + echo " 2. 工具执行可能修改系统配置" + echo " 3. 建议先了解工具功能再使用" + echo " 4. 项目地址: $TOOLS_REPO" + echo "${UI_DIVIDER}" + + read -p "确认执行此工具吗?(y/N): " confirm + if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then + log_info "已取消工具执行" + return 0 + fi + + echo + log_step "开始执行工具..." + echo "${UI_BORDER}" + + # 记录执行日志 + log_info "工具执行开始: $tool_name ($(date '+%Y-%m-%d %H:%M:%S'))" + + # 执行工具并捕获输出 + if bash "$tool_path"; then + echo "${UI_BORDER}" + log_success "工具执行完成: $desc_cn" + log_info "工具执行结束: $tool_name ($(date '+%Y-%m-%d %H:%M:%S'))" + else + echo "${UI_BORDER}" + log_error "工具执行失败: $desc_cn" + log_error "工具执行失败: $tool_name (退出码: $?)" + fi +} + +# 小工具选择菜单 +tools_selection_menu() { + while true; do + clear + show_banner + show_menu_header "第三方小工具管理" + + echo " 工具来源: ${CYAN}$TOOLS_AUTHOR${NC}" + echo " 项目地址: ${BLUE}$TOOLS_REPO${NC}" + echo "${UI_DIVIDER}" + + # 显示工具列表 + local index=1 + local -a tool_names=() + + for tool_name in $(echo "${!TOOLS_LIST[@]}" | tr ' ' '\n' | sort); do + tool_names[$index]=$tool_name + local desc_full="${TOOLS_LIST[$tool_name]}" + local desc_cn=$(echo "$desc_full" | cut -d'|' -f1) + local tool_path="$TOOLS_DIR/$tool_name" + + if [[ -f "$tool_path" ]]; then + show_menu_option "$index" "$desc_cn ${GREEN}✓${NC}" + else + show_menu_option "$index" "$desc_cn ${RED}✗${NC}" + fi + + index=$((index + 1)) + done + + echo "${UI_DIVIDER}" + show_menu_option "r" "重新下载所有工具" + show_menu_option "l" "列出工具详情" + show_menu_option "0" "返回主菜单" + show_menu_footer + echo + + read -p "请选择工具 [0-${#TOOLS_LIST[@]}] 或 [r/l]: " choice + echo + + case $choice in + 0) + break + ;; + r) + download_tools + pause_function + ;; + l) + list_downloaded_tools + pause_function + ;; + [1-9]|[1-9][0-9]) + if [[ $choice -le ${#TOOLS_LIST[@]} ]] && [[ -n "${tool_names[$choice]}" ]]; then + run_tool "${tool_names[$choice]}" + else + log_error "无效选择" + fi + pause_function + ;; + *) + log_error "无效选择,请重新输入" + pause_function + ;; + esac + done +} + +# 第三方工具主入口 +third_party_tools_menu() { + # 检查是否已下载工具 + if ! check_tools_downloaded; then + clear + show_banner + show_menu_header "第三方小工具管理" + + echo " 检测到您还未下载第三方工具集" + echo + log_info "工具来源: ${CYAN}$TOOLS_AUTHOR${NC}" + log_info "项目地址: ${BLUE}$TOOLS_REPO${NC}" + log_info "工具数量: ${GREEN}${#TOOLS_LIST[@]}${NC} 个" + echo + echo " 这些工具包括:" + echo " • PVE/PBS 安装后配置" + echo " • CPU 调频策略管理" + echo " • LXC 容器管理" + echo " • 内核管理工具" + echo " • 系统监控工具" + echo " • 等等..." + echo + echo "${UI_DIVIDER}" + + read -p "是否立即下载工具集?(Y/n): " download_confirm + download_confirm=${download_confirm:-Y} + + if [[ "$download_confirm" == "Y" || "$download_confirm" == "y" ]]; then + echo + download_tools + pause_function + + # 下载成功后进入工具菜单 + if check_tools_downloaded; then + tools_selection_menu + fi + else + log_info "已取消下载" + return 0 + fi + else + # 已下载,直接进入工具菜单 + tools_selection_menu + fi +} +#---------第三方小工具管理----------- + # PVE8 to PVE9 升级功能 pve8_to_pve9_upgrade() { log_step "开始 PVE 8.x 升级到 PVE 9.x" @@ -2191,13 +2488,14 @@ show_menu() { show_menu_option "11" "Ceph管理 (存储相关配置)" show_menu_option "12" "内核管理 (内核切换/更新/清理)" show_menu_option "13" "PVE8 升级到 PVE9 (PVE8专用)" + show_menu_option "14" "第三方工具集 (tteck社区工具)" echo show_menu_option "0" "退出脚本" show_menu_option "520" "给作者点个Star吧,谢谢喵~" show_menu_footer echo echo "小贴士:新装系统推荐选择 7 进行一键配置" - echo -n "请输入您的选择 [0-13, 520]: " + echo -n "请输入您的选择 [0-14, 520]: " } # 一键配置 @@ -2634,6 +2932,9 @@ main() { 13) pve8_to_pve9_upgrade ;; + 14) + third_party_tools_menu + ;; 520) echo "项目地址:https://github.com/Mapleawaa/PVE-Tools-9" echo "有你真好~" @@ -2645,7 +2946,7 @@ main() { ;; *) log_error "哎呀,这个选项不存在呢" - log_warn "请输入 0-13 之间的数字" + log_warn "请输入 0-14 之间的数字" ;; esac diff --git a/Tools/.gitkeep b/Tools/.gitkeep new file mode 100644 index 0000000..81bf37b --- /dev/null +++ b/Tools/.gitkeep @@ -0,0 +1,2 @@ +# This directory stores third-party tools from tteck/Proxmox +# Tools will be downloaded when user first access the tools menu diff --git a/Tools/README.md b/Tools/README.md new file mode 100644 index 0000000..b3f3805 --- /dev/null +++ b/Tools/README.md @@ -0,0 +1,81 @@ +# PVE Tools - 第三方工具集 + +这个目录包含来自 **tteck** 社区的第三方 Proxmox 管理工具。 + +## 工具来源 + +- **作者**: tteck +- **项目地址**: https://github.com/tteck/Proxmox +- **许可证**: MIT License + +## 工具列表 + +### 系统配置工具 +- **post-pbs-install.sh** - Proxmox Backup Server 安装后配置 +- **post-pve-install.sh** - Proxmox VE 安装后配置 +- **scaling-governor.sh** - CPU 调频策略配置工具 +- **microcode.sh** - CPU 微码更新工具 + +### 容器管理工具 +- **update-lxcs.sh** - 批量更新 LXC 容器 +- **cron-update-lxcs.sh** - 定时自动更新 LXC 容器 +- **clean-lxcs.sh** - 清理 LXC 容器缓存和日志 + +### 系统维护工具 +- **host-backup.sh** - Proxmox 主机配置备份工具 +- **kernel-clean.sh** - 清理旧内核版本 +- **kernel-pin.sh** - 固定内核版本防止自动更新 +- **fstrim.sh** - SSD Trim 优化工具 + +### 监控工具 +- **monitor-all.sh** - 系统全局监控工具 +- **netdata.sh** - Netdata 实时监控系统安装 + +## 使用方法 + +### 通过 PVE-Tools.sh 主脚本使用(推荐) + +1. 运行 PVE-Tools.sh 主脚本 +2. 选择菜单选项 `14` - 第三方工具集 +3. 首次使用会提示下载所有工具 +4. 下载完成后选择需要的工具执行 + +### 直接运行工具(高级用户) + +```bash +cd Tools +bash post-pve-install.sh +``` + +## 注意事项 + +⚠️ **重要提示**: + +1. 这些工具由第三方社区维护,非 PVE-Tools-9 项目原创 +2. 工具执行前会显示确认提示,请仔细阅读 +3. 某些工具会修改系统配置,建议先了解工具功能 +4. 所有工具执行都会记录到 `/var/log/pve-tools.log` + +## 工具特性 + +- ✅ 自动下载管理 +- ✅ 执行权限自动设置 +- ✅ 执行日志记录 +- ✅ 中英文双语描述 +- ✅ 安全确认机制 + +## 更新工具集 + +在工具菜单中选择 `r` 选项可以重新下载所有工具到最新版本。 + +## 致谢 + +感谢 **tteck** 为 Proxmox 社区贡献的优秀工具! + +如需了解更多工具详情,请访问原项目: +https://github.com/tteck/Proxmox + +--- + +**PVE-Tools-9 项目** +项目地址: https://github.com/Mapleawaa/PVE-Tools-9 diff --git a/Tools/clean-lxcs.sh b/Tools/clean-lxcs.sh new file mode 100644 index 0000000..17f4fe7 --- /dev/null +++ b/Tools/clean-lxcs.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info() { + clear + cat <<"EOF" + ________ __ _ ________ + / ____/ /__ ____ _____ / / | |/ / ____/ + / / / / _ \/ __ `/ __ \ / / | / / +/ /___/ / __/ /_/ / / / / / /___/ / /___ +\____/_/\___/\__,_/_/ /_/ /_____/_/|_\____/ + +EOF +} +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +CM='\xE2\x9C\x94\033' +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +header_info +echo "Loading..." +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Clean logs, cache and update apt lists on selected LXC Containers. Proceed?" 10 58 || exit +NODE=$(hostname) +EXCLUDE_MENU=() +MSG_MAX_LENGTH=0 +while read -r TAG ITEM; do + OFFSET=2 + ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET + EXCLUDE_MENU+=("$TAG" "$ITEM " "OFF") +done < <(pct list | awk 'NR>1') +excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --checklist "\nSelect containers to skip from cleaning:\n" \ + 16 $((MSG_MAX_LENGTH + 23)) 6 "${EXCLUDE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + +function clean_container() { + container=$1 + header_info + name=$(pct exec "$container" hostname) + echo -e "${BL}[Info]${GN} Cleaning ${name} ${CL} \n" + pct exec $container -- bash -c "apt-get -y --purge autoremove && apt-get -y autoclean && bash <(curl -fsSL https://github.com/tteck/Proxmox/raw/main/misc/clean.sh) && rm -rf /var/lib/apt/lists/* && apt-get update" +} +for container in $(pct list | awk '{if(NR>1) print $1}'); do + if [[ " ${excluded_containers[@]} " =~ " $container " ]]; then + header_info + echo -e "${BL}[Info]${GN} Skipping ${BL}$container${CL}" + sleep 1 + else + os=$(pct config "$container" | awk '/^ostype/ {print $2}') + if [ "$os" != "debian" ] && [ "$os" != "ubuntu" ]; then + header_info + echo -e "${BL}[Info]${GN} Skipping ${name} ${RD}$container is not Debian or Ubuntu ${CL} \n" + sleep 1 + continue + fi + + status=$(pct status $container) + template=$(pct config $container | grep -q "template:" && echo "true" || echo "false") + if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then + echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n" + pct start $container + echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n" + sleep 5 + clean_container $container + echo -e "${BL}[Info]${GN} Shutting down${BL} $container ${CL} \n" + pct shutdown $container & + elif [ "$status" == "status: running" ]; then + clean_container $container + fi + fi +done + +wait +header_info +echo -e "${GN} Finished, Selected Containers Cleaned. ${CL} \n" diff --git a/Tools/cron-update-lxcs.sh b/Tools/cron-update-lxcs.sh new file mode 100644 index 0000000..97fb4e6 --- /dev/null +++ b/Tools/cron-update-lxcs.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/cron-update-lxcs.sh)" + +clear +cat <<"EOF" + ______ __ __ __ __ __ _ ________ + / ____/________ ____ / / / /___ ____/ /___ _/ /____ / / | |/ / ____/____ + / / / ___/ __ \/ __ \ / / / / __ \/ __ / __ `/ __/ _ \ / / | / / / ___/ +/ /___/ / / /_/ / / / / / /_/ / /_/ / /_/ / /_/ / /_/ __/ / /___/ / /___(__ ) +\____/_/ \____/_/ /_/ \____/ .___/\__,_/\__,_/\__/\___/ /_____/_/|_\____/____/ + /_/ +EOF + +add() { + while true; do + read -p "This script will add a crontab schedule that updates all LXCs every Sunday at midnight. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac + done + sh -c '(crontab -l -u root 2>/dev/null; echo "0 0 * * 0 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /bin/bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh)\" >>/var/log/update-lxcs-cron.log 2>/dev/null") | crontab -u root -' + clear + echo -e "\n To view Cron Update LXCs logs: cat /var/log/update-lxcs-cron.log" +} + +remove() { + (crontab -l | grep -v "github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh") | crontab - + rm -rf /var/log/update-lxcs-cron.log + echo "Removed Crontab Schedule from Proxmox VE" +} + +OPTIONS=(Add "Add Crontab Schedule" + Remove "Remove Crontab Schedule") + +CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Cron Update LXCs" --menu "Select an option:" 10 58 2 \ + "${OPTIONS[@]}" 3>&1 1>&2 2>&3) + +case $CHOICE in +"Add") + add + ;; +"Remove") + remove + ;; +*) + echo "Exiting..." + exit 0 + ;; +esac diff --git a/Tools/fstrim.sh b/Tools/fstrim.sh new file mode 100644 index 0000000..5c0e2ae --- /dev/null +++ b/Tools/fstrim.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info() { + clear + cat <<"EOF" + _______ __ __ ______ _ + / ____(_) /__ _______ _______/ /____ ____ ___ /_ __/____(_)___ ___ + / /_ / / / _ \/ ___/ / / / ___/ __/ _ \/ __ `__ \ / / / ___/ / __ `__ \ + / __/ / / / __(__ ) /_/ (__ ) /_/ __/ / / / / / / / / / / / / / / / / +/_/ /_/_/\___/____/\__, /____/\__/\___/_/ /_/ /_/ /_/ /_/ /_/_/ /_/ /_/ + /____/ +EOF +} +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +CM='\xE2\x9C\x94\033' +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +header_info +echo "Loading..." + +ROOT_FS=$(df -Th "/" | awk 'NR==2 {print $2}') +if [ "$ROOT_FS" != "ext4" ]; then + echo "Root filesystem is not ext4. Exiting script." + exit 1 +fi + +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Filesystem Trim" --yesno "The LXC containers will undergo the fstrim command. Proceed?" 10 58 || exit +NODE=$(hostname) +EXCLUDE_MENU=() +MSG_MAX_LENGTH=0 +while read -r TAG ITEM; do + OFFSET=2 + ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET + EXCLUDE_MENU+=("$TAG" "$ITEM " "OFF") +done < <(pct list | awk 'NR>1') +excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --checklist "\nSelect containers to skip from trimming:\n" \ + 16 $((MSG_MAX_LENGTH + 23)) 6 "${EXCLUDE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + +function trim_container() { + local container=$1 + header_info + echo -e "${BL}[Info]${GN} Trimming ${BL}$container${CL} \n" + local before_trim=$(lvs | awk -F '[[:space:]]+' 'NR>1 && (/Data%|'"vm-$container"'/) {gsub(/%/, "", $7); print $7}') + echo -e "${RD}Data before trim $before_trim%${CL}" + pct fstrim $container + local after_trim=$(lvs | awk -F '[[:space:]]+' 'NR>1 && (/Data%|'"vm-$container"'/) {gsub(/%/, "", $7); print $7}') + echo -e "${GN}Data after trim $after_trim%${CL}" + sleep 1.5 +} + + + +for container in $(pct list | awk '{if(NR>1) print $1}'); do + if [[ " ${excluded_containers[@]} " =~ " $container " ]]; then + header_info + echo -e "${BL}[Info]${GN} Skipping ${BL}$container${CL}" + sleep 1 + else + template=$(pct config $container | grep -q "template:" && echo "true" || echo "false") + if [ "$template" == "true" ]; then + header_info + echo -e "${BL}[Info]${GN} Skipping ${container} ${RD}$container is a template ${CL} \n" + sleep 1 + continue + fi + trim_container $container + fi +done + +wait +header_info +echo -e "${GN} Finished, LXC Containers Trimmed. ${CL} \n" diff --git a/Tools/host-backup.sh b/Tools/host-backup.sh new file mode 100644 index 0000000..31b67bf --- /dev/null +++ b/Tools/host-backup.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + __ __ __ ___ __ + / // /__ ___ / /_ / _ )___ _____/ /____ _____ + / _ / _ \(_-&1 1>&2 2>&3) || return + + # Default to /root/ if no input + BACKUP_PATH="${BACKUP_PATH:-/root/}" + + # Get directory to work in from user + DIR=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nDefaults to /etc/\ne.g. /root/, /var/lib/pve-cluster/ etc." 11 68 --title "Directory to work in:" 3>&1 1>&2 2>&3) || return + + # Default to /etc/ if no input + DIR="${DIR:-/etc/}" + + DIR_DASH=$(echo "$DIR" | tr '/' '-') + BACKUP_FILE="$(hostname)${DIR_DASH}backup" + + # Build a list of directories for backup + local CTID_MENU=() + while read -r dir; do + CTID_MENU+=("$(basename "$dir")" "$dir " "OFF") + done < <(ls -d "${DIR}"*) + + # Allow the user to select directories + local HOST_BACKUP + while [ -z "${HOST_BACKUP:+x}" ]; do + HOST_BACKUP=$(whiptail --backtitle "Proxmox VE Host Backup" --title "Working in the ${DIR} directory " --checklist \ + "\nSelect what files/directories to backup:\n" 16 $(((${#DIRNAME} + 2) + 88)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || return + + for selected_dir in ${HOST_BACKUP//\"/}; do + selected_directories+=("${DIR}$selected_dir") + done + done + + # Perform the backup + header_info + echo -e "This will create a backup in\e[1;33m $BACKUP_PATH \e[0mfor these files and directories\e[1;33m ${selected_directories[*]} \e[0m" + read -p "Press ENTER to continue..." + header_info + echo "Working..." + tar -czf "$BACKUP_PATH$BACKUP_FILE-$(date +%Y_%m_%d).tar.gz" --absolute-names "${selected_directories[@]}" + header_info + echo -e "\nFinished" + echo -e "\e[1;33m \nA backup is rendered ineffective when it remains stored on the host.\n \e[0m" + sleep 2 +} + +# Main script execution loop +while true; do + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE Host Backup" --yesno "This will create backups for particular files and directories located within a designated directory. Proceed?" 10 88); then + perform_backup + else + break + fi +done diff --git a/Tools/kernel-clean.sh b/Tools/kernel-clean.sh new file mode 100644 index 0000000..ca31cc2 --- /dev/null +++ b/Tools/kernel-clean.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + __ __ __ ________ + / //_/__ _________ ___ / / / ____/ /__ ____ _____ + / ,< / _ \/ ___/ __ \/ _ \/ / / / / / _ \/ __ `/ __ \ + / /| / __/ / / / / / __/ / / /___/ / __/ /_/ / / / / +/_/ |_\___/_/ /_/ /_/\___/_/ \____/_/\___/\__,_/_/ /_/ + +EOF +} +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +current_kernel=$(uname -r) +available_kernels=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print $2}' | grep -v "$current_kernel" | sort -V) +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE Kernel Clean" --yesno "This will Clean Unused Kernel Images, USE AT YOUR OWN RISK. Proceed?" 10 68 || exit +if [ -z "$available_kernels" ]; then + whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Old Kernels" --msgbox "It appears there are no old Kernels on your system. \nCurrent kernel ($current_kernel)." 10 68 + echo "Exiting..." + sleep 2 + clear + exit +fi + KERNEL_MENU=() + MSG_MAX_LENGTH=0 +while read -r TAG ITEM; do + OFFSET=2 + ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET + KERNEL_MENU+=("$TAG" "$ITEM " "OFF") +done < <(echo "$available_kernels") + +remove_kernels=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current Kernel $current_kernel" --checklist "\nSelect Kernels to remove:\n" 16 $((MSG_MAX_LENGTH + 58)) 6 "${KERNEL_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit +[ -z "$remove_kernels" ] && { + whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Kernel Selected" --msgbox "It appears that no Kernel was selected" 10 68 + echo "Exiting..." + sleep 2 + clear + exit +} +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Remove Kernels" --yesno "Would you like to remove the $(echo $remove_kernels | awk '{print NF}') previously selected Kernels?" 10 68 || exit + +msg_info "Removing ${CL}${RD}$(echo $remove_kernels | awk '{print NF}') ${CL}${YW}old Kernels${CL}" +/usr/bin/apt purge -y $remove_kernels >/dev/null 2>&1 +msg_ok "Successfully Removed Kernels" + +msg_info "Updating GRUB" +/usr/sbin/update-grub >/dev/null 2>&1 +msg_ok "Successfully Updated GRUB" +msg_info "Exiting" +sleep 2 +msg_ok "Finished" diff --git a/Tools/kernel-pin.sh b/Tools/kernel-pin.sh new file mode 100644 index 0000000..a2a15ed --- /dev/null +++ b/Tools/kernel-pin.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + __ __ __ ____ _ + / //_/__ _________ ___ / / / __ \(_)___ + / ,< / _ \/ ___/ __ \/ _ \/ / / /_/ / / __ \ + / /| / __/ / / / / / __/ / / ____/ / / / / +/_/ |_\___/_/ /_/ /_/\___/_/ /_/ /_/_/ /_/ + +EOF +} +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +current_kernel=$(uname -r) +available_kernels=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print substr($2, 16, length($2)-22)}') +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE Kernel Pin" --yesno "This will Pin/Unpin Kernel Images, Proceed?" 10 68 || exit + + KERNEL_MENU=() + MSG_MAX_LENGTH=0 +while read -r TAG ITEM; do + OFFSET=2 + ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET + KERNEL_MENU+=("$TAG" "$ITEM " "OFF") +done < <(echo "$available_kernels") + +pin_kernel=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current Kernel $current_kernel" --radiolist "\nSelect Kernel to pin:\nCancel to Unpin any Kernel" 16 $((MSG_MAX_LENGTH + 58)) 6 "${KERNEL_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit +[ -z "$pin_kernel" ] && { + whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Kernel Selected" --msgbox "It appears that no Kernel was selected\nUnpinning any pinned Kernel" 10 68 + msg_info "Unpinning any Kernel" + proxmox-boot-tool kernel unpin &>/dev/null + msg_ok "Unpinned any Kernel\n" + proxmox-boot-tool kernel list + echo "" + msg_ok "Finished\n" + echo -e "${RD} REBOOT${CL}" + exit +} +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE Kernel Pin" --yesno "Would you like to pin the $pin_kernel Kernel?" 10 68 || exit + +msg_info "Pinning $pin_kernel" +proxmox-boot-tool kernel pin $pin_kernel &>/dev/null +msg_ok "Successfully Pinned $pin_kernel\n" +proxmox-boot-tool kernel list +echo "" +msg_ok "Finished\n" +echo -e "${RD} REBOOT${CL}" diff --git a/Tools/microcode.sh b/Tools/microcode.sh new file mode 100644 index 0000000..44ad9b5 --- /dev/null +++ b/Tools/microcode.sh @@ -0,0 +1,125 @@ +#!/usr/bin/env bash +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + ____ __ ____ __ + / __ \_________ ________ ______________ _____ / |/ (_)_____________ _________ ____/ /__ + / /_/ / ___/ __ \/ ___/ _ \/ ___/ ___/ __ \/ ___/ / /|_/ / / ___/ ___/ __ \/ ___/ __ \/ __ / _ \ + / ____/ / / /_/ / /__/ __(__ |__ ) /_/ / / / / / / / /__/ / / /_/ / /__/ /_/ / /_/ / __/ +/_/ /_/ \____/\___/\___/____/____/\____/_/ /_/ /_/_/\___/_/ \____/\___/\____/\__,_/\___/ + +EOF +} + +RD=$(echo "\033[01;31m") +YW=$(echo "\033[33m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" + +msg_info() { echo -ne " ${HOLD} ${YW}$1..."; } +msg_ok() { echo -e "${BFR} ${CM} ${GN}$1${CL}"; } +msg_error() { echo -e "${BFR} ${CROSS} ${RD}$1${CL}"; } + +header_info +current_microcode=$(journalctl -k | grep -i 'microcode: Current revision:' | grep -oP 'Current revision: \K0x[0-9a-f]+') +[ -z "$current_microcode" ] && current_microcode="Not found." + +intel() { + if ! dpkg -s iucode-tool >/dev/null 2>&1; then + msg_info "Installing iucode-tool (Intel microcode updater)" + apt-get install -y iucode-tool &>/dev/null + msg_ok "Installed iucode-tool" + else + msg_ok "Intel iucode-tool is already installed" + sleep 1 + fi + + intel_microcode=$(curl -fsSL "https://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode//" | grep -o 'href="[^"]*amd64.deb"' | sed 's/href="//;s/"//') + [ -z "$intel_microcode" ] && { whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Microcode Found" --msgbox "It appears there were no microcode packages found\n Try again later." 10 68; msg_info "Exiting"; sleep 1; msg_ok "Done"; exit; } + + MICROCODE_MENU=() + MSG_MAX_LENGTH=0 + + while read -r TAG ITEM; do + OFFSET=2 + (( ${#ITEM} + OFFSET > MSG_MAX_LENGTH )) && MSG_MAX_LENGTH=${#ITEM}+OFFSET + MICROCODE_MENU+=("$TAG" "$ITEM " "OFF") + done < <(echo "$intel_microcode") + + microcode=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current Microcode revision:${current_microcode}" --radiolist "\nSelect a microcode package to install:\n" 16 $((MSG_MAX_LENGTH + 58)) 6 "${MICROCODE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + + [ -z "$microcode" ] && { whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Microcode Selected" --msgbox "It appears that no microcode packages were selected" 10 68; msg_info "Exiting"; sleep 1; msg_ok "Done"; exit; } + + msg_info "Downloading the Intel Processor Microcode Package $microcode" + wget -q http://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/$microcode + msg_ok "Downloaded the Intel Processor Microcode Package $microcode" + + msg_info "Installing $microcode (Patience)" + dpkg -i $microcode &>/dev/null + msg_ok "Installed $microcode" + + msg_info "Cleaning up" + rm $microcode + msg_ok "Cleaned" + echo -e "\nIn order to apply the changes, a system reboot will be necessary.\n" +} + +amd() { + amd_microcode=$(curl -fsSL "https://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode///" | grep -o 'href="[^"]*amd64.deb"' | sed 's/href="//;s/"//') + + [ -z "$amd_microcode" ] && { whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Microcode Found" --msgbox "It appears there were no microcode packages found\n Try again later." 10 68; msg_info "Exiting"; sleep 1; msg_ok "Done"; exit; } + + MICROCODE_MENU=() + MSG_MAX_LENGTH=0 + + while read -r TAG ITEM; do + OFFSET=2 + (( ${#ITEM} + OFFSET > MSG_MAX_LENGTH )) && MSG_MAX_LENGTH=${#ITEM}+OFFSET + MICROCODE_MENU+=("$TAG" "$ITEM " "OFF") + done < <(echo "$amd_microcode") + + microcode=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current Microcode revision:${current_microcode}" --radiolist "\nSelect a microcode package to install:\n" 16 $((MSG_MAX_LENGTH + 58)) 6 "${MICROCODE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + + [ -z "$microcode" ] && { whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Microcode Selected" --msgbox "It appears that no microcode packages were selected" 10 68; msg_info "Exiting"; sleep 1; msg_ok "Done"; exit; } + + msg_info "Downloading the AMD Processor Microcode Package $microcode" + wget -q https://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/$microcode + msg_ok "Downloaded the AMD Processor Microcode Package $microcode" + + msg_info "Installing $microcode (Patience)" + dpkg -i $microcode &>/dev/null + msg_ok "Installed $microcode" + + msg_info "Cleaning up" + rm $microcode + msg_ok "Cleaned" + echo -e "\nIn order to apply the changes, a system reboot will be necessary.\n" +} + +if ! command -v pveversion >/dev/null 2>&1; then header_info; msg_error "No PVE Detected!"; exit; fi + +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE Processor Microcode" --yesno "This will check for CPU microcode packages with the option to install. Proceed?" 10 58 || exit + +msg_info "Checking CPU Vendor" +cpu=$(lscpu | grep -oP 'Vendor ID:\s*\K\S+' | head -n 1) +if [ "$cpu" == "GenuineIntel" ]; then + msg_ok "${cpu} was detected" + sleep 1 + intel +elif [ "$cpu" == "AuthenticAMD" ]; then + msg_ok "${cpu} was detected" + sleep 1 + amd +else + msg_error "${cpu} is not supported" + exit +fi diff --git a/Tools/monitor-all.sh b/Tools/monitor-all.sh new file mode 100644 index 0000000..79bf0df --- /dev/null +++ b/Tools/monitor-all.sh @@ -0,0 +1,163 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +clear +cat <<"EOF" + __ ___ _ __ ___ ____ + / |/ /___ ____ (_) /_____ _____ / | / / / + / /|_/ / __ \/ __ \/ / __/ __ \/ ___/ / /| | / / / + / / / / /_/ / / / / / /_/ /_/ / / / ___ |/ / / +/_/ /_/\____/_/ /_/_/\__/\____/_/ /_/ |_/_/_/ + +EOF + +add() { +while true; do + read -p "This script will add Monitor All to Proxmox VE. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac +done + +echo '#!/usr/bin/env bash +# Read excluded instances from command line arguments +excluded_instances=("$@") +echo "Excluded instances: ${excluded_instances[@]}" + +while true; do + + for instance in $(pct list | awk '\''{if(NR>1) print $1}'\''; qm list | awk '\''{if(NR>1) print $1}'\''); do + # Skip excluded instances + if [[ " ${excluded_instances[@]} " =~ " ${instance} " ]]; then + echo "Skipping $instance because it is excluded" + continue + fi + + # Determine the type of the instance (container or virtual machine) + if pct status $instance >/dev/null 2>&1; then + # It is a container + config_cmd="pct config" + IP=$(pct exec $instance ip a s dev eth0 | awk '\''/inet / {print $2}'\'' | cut -d/ -f1) + else + # It is a virtual machine + config_cmd="qm config" + IP=$(qm guest cmd $instance network-get-interfaces | egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -E "192\.|10\." | head -n 1) + fi + + # Skip instances based on onboot and templates + onboot=$($config_cmd $instance | grep -q "onboot: 0" || ( ! $config_cmd $instance | grep -q "onboot" ) && echo "true" || echo "false") + template=$($config_cmd $instance | grep template | grep -q "template:" && echo "true" || echo "false") + + if [ "$onboot" == "true" ]; then + echo "Skipping $instance because it is set not to boot" + continue + elif [ "$template" == "true" ]; then + echo "Skipping $instance because it is a template" + continue + fi + + # Ping the instance + if ! ping -c 1 $IP >/dev/null 2>&1; then + # If the instance can not be pinged, stop and start it + if pct status $instance >/dev/null 2>&1; then + # It is a container + echo "$(date): CT $instance is not responding, restarting..." + pct stop $instance >/dev/null 2>&1 + sleep 5 + pct start $instance >/dev/null 2>&1 + else + # It is a virtual machine + if qm status $instance | grep -q "status: running"; then + echo "$(date): VM $instance is not responding, restarting..." + qm stop $instance >/dev/null 2>&1 + sleep 5 + else + echo "$(date): VM $instance is not running, starting..." + fi + qm start $instance >/dev/null 2>&1 + fi + fi + done + + # Wait for 5 minutes. (Edit to your needs) + echo "$(date): Pausing for 5 minutes..." + sleep 300 +done >/var/log/ping-instances.log 2>&1' >/usr/local/bin/ping-instances.sh +touch /var/log/ping-instances.log +# Change file permissions to executable +chmod +x /usr/local/bin/ping-instances.sh +cat </etc/systemd/system/ping-instances.timer +[Unit] +Description=Delay ping-instances.service by 5 minutes + +[Timer] +OnBootSec=300 +OnUnitActiveSec=300 + +[Install] +WantedBy=timers.target +EOF + +# Create ping-instances.service +cat </etc/systemd/system/ping-instances.service +[Unit] +Description=Ping instances every 5 minutes and restarts if necessary +After=ping-instances.timer +Requires=ping-instances.timer +[Service] +Type=simple +# To specify which CT/VM should be excluded, add the CT/VM ID at the end of the line where ExecStart=/usr/local/bin/ping-instances.sh is specified. +# For example: ExecStart=/usr/local/bin/ping-instances.sh 100 102 +# Virtual machines without the QEMU guest agent installed must be excluded. + +ExecStart=/usr/local/bin/ping-instances.sh +Restart=always +StandardOutput=file:/var/log/ping-instances.log +StandardError=file:/var/log/ping-instances.log + +[Install] +WantedBy=multi-user.target +EOF + +# Reload daemon, enable and start ping-instances.service +systemctl daemon-reload +systemctl enable -q --now ping-instances.timer +systemctl enable -q --now ping-instances.service +clear +echo -e "\n To view Monitor All logs: cat /var/log/ping-instances.log" +} + +remove() { + systemctl disable -q --now ping-instances.timer + systemctl disable -q --now ping-instances.service + rm /etc/systemd/system/ping-instances.service /etc/systemd/system/ping-instances.timer /usr/local/bin/ping-instances.sh /var/log/ping-instances.log + echo "Removed Monitor All from Proxmox VE" +} + +# Define options for the whiptail menu +OPTIONS=(Add "Add Monitor-All to Proxmox VE" \ + Remove "Remove Monitor-All from Proxmox VE") + +# Show the whiptail menu and save the user's choice +CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Monitor-All for Proxmox VE" --menu "Select an option:" 10 58 2 \ + "${OPTIONS[@]}" 3>&1 1>&2 2>&3) + +# Check the user's choice and perform the corresponding action +case $CHOICE in + "Add") + add + ;; + "Remove") + remove + ;; + *) + echo "Exiting..." + exit 0 + ;; +esac diff --git a/Tools/netdata.sh b/Tools/netdata.sh new file mode 100644 index 0000000..885cd42 --- /dev/null +++ b/Tools/netdata.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + _ __ __ ____ __ + / | / /__ / /_/ __ \____ _/ /_____ _ + / |/ / _ \/ __/ / / / __ `/ __/ __ `/ + / /| / __/ /_/ /_/ / /_/ / /_/ /_/ / +/_/ |_/\___/\__/_____/\__,_/\__/\__,_/ + +EOF +} + +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +silent() { "$@" >/dev/null 2>&1; } +set -e +header_info +echo "Loading..." +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +install() { + header_info + while true; do + read -p "Are you sure you want to install NetData on Proxmox VE host. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac + done + header_info + read -r -p "Verbose mode? " prompt + if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + STD="" + else + STD="silent" + fi + header_info + + msg_info "Setting up repository" + wget -q https://repo.netdata.cloud/repos/repoconfig/debian/bookworm/netdata-repo_2-2+debian12_all.deb + $STD dpkg -i netdata-repo_2-2+debian12_all.deb + rm -rf netdata-repo_2-2+debian12_all.deb + msg_ok "Set up repository" + + msg_info "Installing Netdata" + $STD apt-get update + $STD apt-get install -y netdata + msg_ok "Installed Netdata" + msg_ok "Completed Successfully!\n" + echo -e "\n Netdata should be reachable at${BL} http://$(hostname -I | awk '{print $1}'):19999 ${CL}\n" +} + +uninstall() { + header_info + read -r -p "Verbose mode? " prompt + if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + STD="" + else + STD="silent" + fi + header_info + + msg_info "Uninstalling Netdata" + systemctl stop netdata + rm -rf /var/log/netdata /var/lib/netdata /var/cache/netdata /etc/netdata/go.d + rm -rf /etc/apt/trusted.gpg.d/netdata-archive-keyring.gpg /etc/apt/sources.list.d/netdata.list + $STD apt-get remove --purge -y netdata netdata-repo + systemctl daemon-reload + $STD apt autoremove -y + $STD userdel netdata + msg_ok "Uninstalled Netdata" + msg_ok "Completed Successfully!\n" +} + +if ! pveversion | grep -Eq "pve-manager/(8\.[0-9])"; then + echo -e "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 8.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi + +OPTIONS=(Install "Install NetData on Proxmox VE" \ + Uninstall "Uninstall NetData from Proxmox VE") + +CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "NetData" --menu "Select an option:" 10 58 2 \ + "${OPTIONS[@]}" 3>&1 1>&2 2>&3) + +case $CHOICE in + "Install") + install + ;; + "Uninstall") + uninstall + ;; + *) + echo "Exiting..." + exit 0 + ;; +esac diff --git a/Tools/post-pbs-install.sh b/Tools/post-pbs-install.sh new file mode 100644 index 0000000..550626b --- /dev/null +++ b/Tools/post-pbs-install.sh @@ -0,0 +1,184 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +header_info() { + clear + cat <<"EOF" + ____ ____ _____ ____ __ ____ __ ____ + / __ \/ __ ) ___/ / __ \____ _____/ /_ / _/___ _____/ /_____ _/ / / + / /_/ / __ \__ \ / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ `/ / / + / ____/ /_/ /__/ / / ____/ /_/ (__ ) /_ _/ // / / (__ ) /_/ /_/ / / / +/_/ /_____/____/ /_/ \____/____/\__/ /___/_/ /_/____/\__/\__,_/_/_/ + +EOF +} + +RD=$(echo "\033[01;31m") +YW=$(echo "\033[33m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" + +set -euo pipefail +shopt -s inherit_errexit nullglob + +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + + +start_routines() { + header_info + VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PBS SOURCES" --menu "This will set the correct sources to update and install Proxmox Backup Server.\n \nChange to Proxmox Backup Server sources?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Changing to Proxmox Backup Server Sources" + cat </etc/apt/sources.list +deb http://deb.debian.org/debian ${VERSION} main contrib +deb http://deb.debian.org/debian ${VERSION}-updates main contrib +deb http://security.debian.org/debian-security ${VERSION}-security main contrib +EOF + msg_ok "Changed to Proxmox Backup Server Sources" + ;; + no) + msg_error "Selected no to Correcting Proxmox Backup Server Sources" + ;; + esac + + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PBS-ENTERPRISE" --menu "The 'pbs-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pbs-enterprise' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Disabling 'pbs-enterprise' repository" + cat </etc/apt/sources.list.d/pbs-enterprise.list +# deb https://enterprise.proxmox.com/debian/pbs ${VERSION} pbs-enterprise +EOF + msg_ok "Disabled 'pbs-enterprise' repository" + ;; + no) + msg_error "Selected no to Disabling 'pbs-enterprise' repository" + ;; + esac + + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PBS-NO-SUBSCRIPTION" --menu "The 'pbs-no-subscription' repository provides access to all of the open-source components of Proxmox Backup Server.\n \nEnable 'pbs-no-subscription' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Enabling 'pbs-no-subscription' repository" + cat </etc/apt/sources.list.d/pbs-install-repo.list +deb http://download.proxmox.com/debian/pbs ${VERSION} pbs-no-subscription +EOF + msg_ok "Enabled 'pbs-no-subscription' repository" + ;; + no) + msg_error "Selected no to Enabling 'pbs-no-subscription' repository" + ;; + esac + + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PBS TEST" --menu "The 'pbstest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pbstest' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Adding 'pbstest' repository and set disabled" + cat </etc/apt/sources.list.d/pbstest-for-beta.list +# deb http://download.proxmox.com/debian/pbs ${VERSION} pbstest +EOF + msg_ok "Added 'pbstest' repository" + ;; + no) + msg_error "Selected no to Adding 'pbstest' repository" + ;; + esac + + if [[ ! -f /etc/apt/apt.conf.d/no-nag-script ]]; then + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUBSCRIPTION NAG" --menu "This will disable the nag message reminding you to purchase a subscription every time you log in to the web interface.\n \nDisable subscription nag?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 + msg_info "Disabling subscription nag" + echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script + apt --reinstall install proxmox-widget-toolkit &>/dev/null + msg_ok "Disabled subscription nag (Delete browser cache)" + ;; + no) + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 + msg_error "Selected no to Disabling subscription nag" + ;; + esac + fi + + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "UPDATE" --menu "\nUpdate Proxmox Backup Server now?" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Updating Proxmox Backup Server (Patience)" + apt-get update &>/dev/null + apt-get -y dist-upgrade &>/dev/null + msg_ok "Updated Proxmox Backup Server" + ;; + no) + msg_error "Selected no to Updating Proxmox Backup Server" + ;; + esac + + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "REBOOT" --menu "\nReboot Proxmox Backup Server now? (recommended)" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Rebooting Proxmox Backup Server" + sleep 2 + msg_ok "Completed Post Install Routines" + reboot + ;; + no) + msg_error "Selected no to Rebooting Proxmox Backup Server (Reboot recommended)" + msg_ok "Completed Post Install Routines" + ;; + esac +} + +header_info +echo -e "\nThis script will Perform Post Install Routines.\n" +while true; do + read -p "Start the Proxmox Backup Server Post Install Script (y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) clear; exit ;; + *) echo "Please answer yes or no." ;; + esac +done + +if command -v pveversion >/dev/null 2>&1; then + echo -e "\n🛑 PVE Detected, Wrong Script!\n" + exit 1 +fi + +start_routines diff --git a/Tools/post-pve-install.sh b/Tools/post-pve-install.sh new file mode 100644 index 0000000..f142b85 --- /dev/null +++ b/Tools/post-pve-install.sh @@ -0,0 +1,242 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +header_info() { + clear + cat <<"EOF" + ____ _ ________ ____ __ ____ __ ____ + / __ \ | / / ____/ / __ \____ _____/ /_ / _/___ _____/ /_____ _/ / / + / /_/ / | / / __/ / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ `/ / / + / ____/| |/ / /___ / ____/ /_/ (__ ) /_ _/ // / / (__ ) /_/ /_/ / / / +/_/ |___/_____/ /_/ \____/____/\__/ /___/_/ /_/____/\__/\__,_/_/_/ + +EOF +} + +RD=$(echo "\033[01;31m") +YW=$(echo "\033[33m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" + +set -euo pipefail +shopt -s inherit_errexit nullglob + +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +start_routines() { + header_info + + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SOURCES" --menu "The package manager will use the correct sources to update and install packages on your Proxmox VE server.\n \nCorrect Proxmox VE sources?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Correcting Proxmox VE Sources" + cat </etc/apt/sources.list +deb http://deb.debian.org/debian bookworm main contrib +deb http://deb.debian.org/debian bookworm-updates main contrib +deb http://security.debian.org/debian-security bookworm-security main contrib +EOF +echo 'APT::Get::Update::SourceListWarnings::NonFreeFirmware "false";' >/etc/apt/apt.conf.d/no-bookworm-firmware.conf + msg_ok "Corrected Proxmox VE Sources" + ;; + no) + msg_error "Selected no to Correcting Proxmox VE Sources" + ;; + esac + + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PVE-ENTERPRISE" --menu "The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pve-enterprise' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Disabling 'pve-enterprise' repository" + cat </etc/apt/sources.list.d/pve-enterprise.list +# deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise +EOF + msg_ok "Disabled 'pve-enterprise' repository" + ;; + no) + msg_error "Selected no to Disabling 'pve-enterprise' repository" + ;; + esac + + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PVE-NO-SUBSCRIPTION" --menu "The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE.\n \nEnable 'pve-no-subscription' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Enabling 'pve-no-subscription' repository" + cat </etc/apt/sources.list.d/pve-install-repo.list +deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription +EOF + msg_ok "Enabled 'pve-no-subscription' repository" + ;; + no) + msg_error "Selected no to Enabling 'pve-no-subscription' repository" + ;; + esac + + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories (initially disabled).\n \nCorrect 'ceph package sources?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Correcting 'ceph package repositories'" + cat </etc/apt/sources.list.d/ceph.list +# deb https://enterprise.proxmox.com/debian/ceph-quincy bookworm enterprise +# deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription +# deb https://enterprise.proxmox.com/debian/ceph-reef bookworm enterprise +# deb http://download.proxmox.com/debian/ceph-reef bookworm no-subscription +EOF + msg_ok "Corrected 'ceph package repositories'" + ;; + no) + msg_error "Selected no to Correcting 'ceph package repositories'" + ;; + esac + + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PVETEST" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pvetest' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Adding 'pvetest' repository and set disabled" + cat </etc/apt/sources.list.d/pvetest-for-beta.list +# deb http://download.proxmox.com/debian/pve bookworm pvetest +EOF + msg_ok "Added 'pvetest' repository" + ;; + no) + msg_error "Selected no to Adding 'pvetest' repository" + ;; + esac + + if [[ ! -f /etc/apt/apt.conf.d/no-nag-script ]]; then + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUBSCRIPTION NAG" --menu "This will disable the nag message reminding you to purchase a subscription every time you log in to the web interface.\n \nDisable subscription nag?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 + msg_info "Disabling subscription nag" + echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/.*data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script + apt --reinstall install proxmox-widget-toolkit &>/dev/null + msg_ok "Disabled subscription nag (Delete browser cache)" + ;; + no) + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 + msg_error "Selected no to Disabling subscription nag" + ;; + esac + fi + + if ! systemctl is-active --quiet pve-ha-lrm; then + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "HIGH AVAILABILITY" --menu "Enable high availability?" 10 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Enabling high availability" + systemctl enable -q --now pve-ha-lrm + systemctl enable -q --now pve-ha-crm + systemctl enable -q --now corosync + msg_ok "Enabled high availability" + ;; + no) + msg_error "Selected no to Enabling high availability" + ;; + esac + fi + + if systemctl is-active --quiet pve-ha-lrm; then + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "HIGH AVAILABILITY" --menu "If you plan to utilize a single node instead of a clustered environment, you can disable unnecessary high availability (HA) services, thus reclaiming system resources.\n\nIf HA becomes necessary at a later stage, the services can be re-enabled.\n\nDisable high availability?" 18 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Disabling high availability" + systemctl disable -q --now pve-ha-lrm + systemctl disable -q --now pve-ha-crm + systemctl disable -q --now corosync + msg_ok "Disabled high availability" + ;; + no) + msg_error "Selected no to Disabling high availability" + ;; + esac + fi + + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "UPDATE" --menu "\nUpdate Proxmox VE now?" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Updating Proxmox VE (Patience)" + apt-get update &>/dev/null + apt-get -y dist-upgrade &>/dev/null + msg_ok "Updated Proxmox VE" + ;; + no) + msg_error "Selected no to Updating Proxmox VE" + ;; + esac + + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "REBOOT" --menu "\nReboot Proxmox VE now? (recommended)" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Rebooting Proxmox VE" + sleep 2 + msg_ok "Completed Post Install Routines" + reboot + ;; + no) + msg_error "Selected no to Rebooting Proxmox VE (Reboot recommended)" + msg_ok "Completed Post Install Routines" + ;; + esac +} + +header_info +echo -e "\nThis script will Perform Post Install Routines.\n" +while true; do + read -p "Start the Proxmox VE Post Install Script (y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) clear; exit ;; + *) echo "Please answer yes or no." ;; + esac +done + +if ! pveversion | grep -Eq "pve-manager/8.[0-2]"; then + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires Proxmox Virtual Environment Version 8.0 or later." + echo -e "Exiting..." + sleep 2 + exit +fi + +start_routines diff --git a/Tools/scaling-governor.sh b/Tools/scaling-governor.sh new file mode 100644 index 0000000..3523ab2 --- /dev/null +++ b/Tools/scaling-governor.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +set -e +header_info() { +clear +cat < MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET + GOVERNORS_MENU+=("$TAG" "$ITEM " "OFF") +done < <(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors | tr ' ' '\n' | grep -v "$current_governor") +scaling_governor=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current CPU Scaling Governor is set to $current_governor" --checklist "\nSelect the Scaling Governor to use:\n" 16 $((MSG_MAX_LENGTH + 58)) 6 "${GOVERNORS_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit +[ -z "$scaling_governor" ] && { + whiptail --backtitle "Proxmox VE Helper Scripts" --title "No CPU Scaling Governor Selected" --msgbox "It appears that no CPU Scaling Governor was selected" 10 68 + clear + exit +} +echo "${scaling_governor}" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor >/dev/null +current_governor=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor) +whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Current CPU Scaling Governor" "\nCurrent CPU Scaling Governor has been set to $current_governor\n" 10 60 +CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU Scaling Governor" --menu "This will establish a crontab to maintain the CPU Scaling Governor configuration across reboots.\n \nSetup a crontab?" 14 68 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + +case $CHOICE in + yes) + set +e + NEW_CRONTAB_COMMAND="(sleep 60 && echo \"$current_governor\" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor)" + EXISTING_CRONTAB=$(crontab -l 2>/dev/null) + if [[ -n "$EXISTING_CRONTAB" ]]; then + TEMP_CRONTAB_FILE=$(mktemp) + echo "$EXISTING_CRONTAB" | grep -v "@reboot (sleep 60 && echo*" > "$TEMP_CRONTAB_FILE" + crontab "$TEMP_CRONTAB_FILE" + rm "$TEMP_CRONTAB_FILE" + fi + (crontab -l 2>/dev/null; echo "@reboot $NEW_CRONTAB_COMMAND") | crontab - + echo -e "\nCrontab Set (use 'crontab -e' to check)" + ;; + no) + echo -e "\n\033[31mNOTE: Settings return to default after reboot\033[m\n" + ;; +esac +echo -e "Current CPU Scaling Governor is set to \033[36m$current_governor\033[m\n" diff --git a/Tools/update-lxcs.sh b/Tools/update-lxcs.sh new file mode 100644 index 0000000..c4ea80f --- /dev/null +++ b/Tools/update-lxcs.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + __ __ __ __ __ _ ________ + / / / /___ ____/ /___ _/ /____ / / | |/ / ____/ + / / / / __ \/ __ / __ `/ __/ _ \ / / | / / +/ /_/ / /_/ / /_/ / /_/ / /_/ __/ / /___/ / /___ +\____/ .___/\__,_/\__,_/\__/\___/ /_____/_/|_\____/ + /_/ + +EOF +} +set -eEuo pipefail +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +CM='\xE2\x9C\x94\033' +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +header_info +echo "Loading..." +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Update LXC Containers. Proceed?" 10 58 || exit +NODE=$(hostname) +EXCLUDE_MENU=() +MSG_MAX_LENGTH=0 +while read -r TAG ITEM; do + OFFSET=2 + ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET + EXCLUDE_MENU+=("$TAG" "$ITEM " "OFF") +done < <(pct list | awk 'NR>1') +excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --checklist "\nSelect containers to skip from updates:\n" 16 $((MSG_MAX_LENGTH + 23)) 6 "${EXCLUDE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + +function needs_reboot() { + local container=$1 + local os=$(pct config "$container" | awk '/^ostype/ {print $2}') + local reboot_required_file="/var/run/reboot-required.pkgs" + if [ -f "$reboot_required_file" ]; then + if [[ "$os" == "ubuntu" || "$os" == "debian" ]]; then + if pct exec "$container" -- [ -s "$reboot_required_file" ]; then + return 0 + fi + fi + fi + return 1 +} + +function update_container() { + container=$1 + header_info + name=$(pct exec "$container" hostname) + os=$(pct config "$container" | awk '/^ostype/ {print $2}') + if [[ "$os" == "ubuntu" || "$os" == "debian" || "$os" == "fedora" ]]; then + disk_info=$(pct exec "$container" df /boot | awk 'NR==2{gsub("%","",$5); printf "%s %.1fG %.1fG %.1fG", $5, $3/1024/1024, $2/1024/1024, $4/1024/1024 }') + read -ra disk_info_array <<<"$disk_info" + echo -e "${BL}[Info]${GN} Updating ${BL}$container${CL} : ${GN}$name${CL} - ${YW}Boot Disk: ${disk_info_array[0]}% full [${disk_info_array[1]}/${disk_info_array[2]} used, ${disk_info_array[3]} free]${CL}\n" + else + echo -e "${BL}[Info]${GN} Updating ${BL}$container${CL} : ${GN}$name${CL} - ${YW}[No disk info for ${os}]${CL}\n" + fi + case "$os" in + alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; + archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm" ;; + fedora | rocky | centos | alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;; + ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -yq dist-upgrade 2>&1; rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED" ;; + opensuse) pct exec "$container" -- bash -c "zypper ref && zypper --non-interactive dup" ;; + esac +} + +containers_needing_reboot=() +header_info +for container in $(pct list | awk '{if(NR>1) print $1}'); do + if [[ " ${excluded_containers[@]} " =~ " $container " ]]; then + header_info + echo -e "${BL}[Info]${GN} Skipping ${BL}$container${CL}" + sleep 1 + else + status=$(pct status $container) + template=$(pct config $container | grep -q "template:" && echo "true" || echo "false") + if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then + echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n" + pct start $container + echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n" + sleep 5 + update_container $container + echo -e "${BL}[Info]${GN} Shutting down${BL} $container ${CL} \n" + pct shutdown $container & + elif [ "$status" == "status: running" ]; then + update_container $container + fi + if pct exec "$container" -- [ -e "/var/run/reboot-required" ]; then + # Get the container's hostname and add it to the list + container_hostname=$(pct exec "$container" hostname) + containers_needing_reboot+=("$container ($container_hostname)") + fi + fi +done +wait +header_info +echo -e "${GN}The process is complete, and the containers have been successfully updated.${CL}\n" +if [ "${#containers_needing_reboot[@]}" -gt 0 ]; then + echo -e "${RD}The following containers require a reboot:${CL}" + for container_name in "${containers_needing_reboot[@]}"; do + echo "$container_name" + done +fi +echo "" diff --git a/UPDATE b/UPDATE index 46661d1..92cc570 100644 --- a/UPDATE +++ b/UPDATE @@ -1,23 +1,5 @@ -1. 界面优化 - - 修复颜色代码显示问题,使用 echo -e 替代 printf - - 简化所有UI边框元素为普通虚线 - - 移除颜色格式化,使用纯文本显示 - -2. 内核安装增强 - - 改进 install_kernel 函数,支持完整包名和版本号两种格式 - - 增强依赖检测和用户引导 - -3. 菜单重构 - - 合并温度监控选项到专用子菜单 - - 合并Ceph相关选项到专用子菜单 - - 重新编号主菜单选项(1-13) - - 更新所有对应的case语句 - -4. 自定义温度监控 - - 实现交互式菜单系统,支持详细传感器配置 - - 添加多种监控选项(CPU频率、温度、功耗、磁盘信息等) - - 实现依赖检查和预设配置方案 - -5. 代码一致性 - - 统一纯文本格式化 - - 保持功能完整性的同时简化视觉元素 +1. 新增模块 + - 新增第三方 Proxmox 管理工具。 +2. 日常维护 + - 修复已知 Bug 若干。 + - 优化系统性能。 \ No newline at end of file