diff --git a/pve2/root/utilities/iommu.sh b/pve2/root/utilities/iommu.sh new file mode 100644 index 0000000..d83bba2 --- /dev/null +++ b/pve2/root/utilities/iommu.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +shopt -s nullglob +lastgroup="" +for g in `find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V`; do + for d in $g/devices/*; do + if [ "${g##*/}" != "$lastgroup" ]; then + echo -en "Group ${g##*/}:\t" + else + echo -en "\t\t" + fi + lastgroup=${g##*/} + lspci -nms ${d##*/} | awk -F'"' '{printf "[%s:%s]", $4, $6}' + if [[ -e "$d"/reset ]]; then echo -en " [R] "; else echo -en " "; fi + + lspci -mms ${d##*/} | awk -F'"' '{printf "%s %-40s %s\n", $1, $2, $6}' + for u in ${d}/usb*/; do + bus=$(cat "${u}/busnum") + lsusb -s $bus: | \ + awk '{gsub(/:/,"",$4); printf "%s|%s %s %s %s|", $6, $1, $2, $3, $4; for(i=7;i<=NF;i++){printf "%s ", $i}; printf "\n"}' | \ + awk -F'|' '{printf "USB:\t\t[%s]\t\t %-40s %s\n", $1, $2, $3}' + done + done +done + diff --git a/pve2/root/utilities/kernel-clean.sh b/pve2/root/utilities/kernel-clean.sh new file mode 100644 index 0000000..058ed24 --- /dev/null +++ b/pve2/root/utilities/kernel-clean.sh @@ -0,0 +1,120 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + __ __ __ ________ + / //_/__ _________ ___ / / / ____/ /__ ____ _____ + / ,< / _ \/ ___/ __ \/ _ \/ / / / / / _ \/ __ `/ __ \ + / /| / __/ / / / / / __/ / / /___/ / __/ /_/ / / / / +/_/ |_\___/_/ /_/ /_/\___/_/ \____/_/\___/\__,_/_/ /_/ + +EOF +} + +# Color variables for output +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}" + +# Functions for logging messages +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +# Detect current kernel +current_kernel=$(uname -r) + +# Detect all installed kernels except the current one +available_kernels=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print $2}' | grep -v "$current_kernel" | sort -V) + +header_info + +# If no old kernels are available, exit with a message +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 + +# Prepare kernel options for selection +KERNEL_MENU=() +while read -r TAG ITEM; do + OFFSET=2 + MSG_MAX_LENGTH=$((MSG_MAX_LENGTH < ${#ITEM} + OFFSET ? ${#ITEM} + OFFSET : MSG_MAX_LENGTH)) + KERNEL_MENU+=("$TAG" "$ITEM " "OFF") +done < <(echo "$available_kernels") + +# Display checklist to select kernels for removal +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 + +# Exit if no kernel was selected +[ -z "$remove_kernels" ] && { + whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Kernel Selected" \ + --msgbox "It appears no kernel was selected." 10 68 + echo "Exiting..." + sleep 2 + clear + exit +} + +# Confirm removal +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Remove Kernels" \ + --yesno "Would you like to remove the $(echo $remove_kernels | awk '{print NF}') selected kernels?" 10 68 || exit + +# Process kernel removal +msg_info "Removing ${RD}$(echo $remove_kernels | awk '{print NF}') ${YW}old kernels${CL}" +for kernel in $remove_kernels; do + if [[ $kernel == *"-signed" ]]; then + # Handle signed kernels with dependencies + touch /please-remove-proxmox-ve # Temporarily bypass Proxmox warnings + if sudo apt-get purge -y "$kernel" >/dev/null 2>&1; then + msg_ok "Removed kernel: $kernel" + else + msg_info "Failed to remove kernel: $kernel. Check dependencies or manual removal." + fi + rm -f /please-remove-proxmox-ve # Clean up bypass file + else + # Standard kernel removal + if sudo apt-get purge -y "$kernel" >/dev/null 2>&1; then + msg_ok "Removed kernel: $kernel" + else + msg_info "Failed to remove kernel: $kernel. Check dependencies or manual removal." + fi + fi + sleep 1 +done + +# Update GRUB configuration +msg_info "Updating GRUB" +if /usr/sbin/update-grub >/dev/null 2>&1; then + msg_ok "GRUB updated successfully" +else + msg_info "Failed to update GRUB" +fi + +# Completion message +msg_info "Exiting" +sleep 2 +msg_ok "Finished" diff --git a/pve2/root/utilities/kernel-pin.sh b/pve2/root/utilities/kernel-pin.sh new file mode 100644 index 0000000..cd4891c --- /dev/null +++ b/pve2/root/utilities/kernel-pin.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/community-scripts/ProxmoxVE/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/pve2/root/utilities/update-lxcs.sh b/pve2/root/utilities/update-lxcs.sh new file mode 100644 index 0000000..36892a9 --- /dev/null +++ b/pve2/root/utilities/update-lxcs.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/community-scripts/ProxmoxVE/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 ""