Created
June 8, 2025 22:40
-
-
Save OptimusGREEN/cf974a3cef1a1afe1eee60d7ae0b09b4 to your computer and use it in GitHub Desktop.
check directory and update iso to latest version
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Linux ISO Updater Script | |
# Updates ISO files to latest minor/patch versions while preserving major versions | |
set -e | |
# Configuration | |
ISO_DIR="$(pwd)" | |
DOWNLOAD_DIR="" | |
BACKUP_DIR="" | |
DRY_RUN=false | |
VERBOSE=false | |
# Colors for output | |
RED='\033[0;31m' | |
GREEN='\033[0;32m' | |
YELLOW='\033[1;33m' | |
BLUE='\033[0;34m' | |
NC='\033[0m' # No Color | |
# Function to print colored output | |
print_status() { | |
local color=$1 | |
local message=$2 | |
echo -e "${color}${message}${NC}" | |
} | |
# Function to show usage | |
show_usage() { | |
cat << EOF | |
Usage: $0 [OPTIONS] [DIRECTORY] | |
OPTIONS: | |
-d, --dry-run Show what would be updated without downloading | |
-v, --verbose Verbose output | |
-h, --help Show this help message | |
DIRECTORY: | |
Path to directory containing ISO files (default: current directory) | |
Examples: | |
$0 # Check current directory | |
$0 /path/to/isos # Check specific directory | |
$0 --dry-run /path/to/isos # Show what would be updated | |
EOF | |
} | |
# Parse command line arguments | |
while [[ $# -gt 0 ]]; do | |
case $1 in | |
-d|--dry-run) | |
DRY_RUN=true | |
shift | |
;; | |
-v|--verbose) | |
VERBOSE=true | |
shift | |
;; | |
-h|--help) | |
show_usage | |
exit 0 | |
;; | |
-*) | |
echo "Unknown option $1" | |
show_usage | |
exit 1 | |
;; | |
*) | |
ISO_DIR="$1" | |
shift | |
;; | |
esac | |
done | |
# Set up directory paths after parsing arguments | |
DOWNLOAD_DIR="${ISO_DIR}/downloads" | |
BACKUP_DIR="${ISO_DIR}/backup" | |
# Check if directory exists | |
if [[ ! -d "$ISO_DIR" ]]; then | |
print_status $RED "Error: Directory '$ISO_DIR' does not exist" | |
exit 1 | |
fi | |
# Create necessary directories | |
mkdir -p "$DOWNLOAD_DIR" "$BACKUP_DIR" | |
# Function to extract distribution info from ISO filename | |
parse_iso_filename() { | |
local filename=$1 | |
local distro="" | |
local version="" | |
local arch="" | |
local variant="" | |
# Remove .iso extension | |
filename="${filename%.iso}" | |
# Ubuntu patterns (including variants) | |
if [[ $filename =~ ubuntu-([0-9]+\.[0-9]+)(\.[0-9]+)?-(.+)-(.+) ]]; then | |
distro="ubuntu" | |
version="${BASH_REMATCH[1]}${BASH_REMATCH[2]}" | |
variant="${BASH_REMATCH[3]}" | |
arch="${BASH_REMATCH[4]}" | |
# Ubuntu variants (mate, studio, cinnamon, etc.) | |
elif [[ $filename =~ ubuntu(mate|studio|cinnamon)-([0-9]+\.[0-9]+)(\.[0-9]+)?-(.+)-(.+) ]]; then | |
distro="ubuntu-${BASH_REMATCH[1]}" | |
version="${BASH_REMATCH[2]}${BASH_REMATCH[3]}" | |
variant="${BASH_REMATCH[4]}" | |
arch="${BASH_REMATCH[5]}" | |
# Linux Mint | |
elif [[ $filename =~ linuxmint-([0-9]+(\.[0-9]+)?)-(.+)-(.+) ]]; then | |
distro="linuxmint" | |
version="${BASH_REMATCH[1]}" | |
variant="${BASH_REMATCH[3]}" | |
arch="${BASH_REMATCH[4]}" | |
# SystemRescue | |
elif [[ $filename =~ systemrescue-([0-9]+\.[0-9]+)-(.+) ]]; then | |
distro="systemrescue" | |
version="${BASH_REMATCH[1]}" | |
variant="" | |
arch="${BASH_REMATCH[2]}" | |
# GParted Live | |
elif [[ $filename =~ gparted-live-([0-9]+\.[0-9]+\.[0-9]+)-([0-9]+)-(.+) ]]; then | |
distro="gparted" | |
version="${BASH_REMATCH[1]}-${BASH_REMATCH[2]}" | |
variant="live" | |
arch="${BASH_REMATCH[3]}" | |
# Clonezilla Live | |
elif [[ $filename =~ clonezilla-live-([0-9]+\.[0-9]+\.[0-9]+)-([0-9]+)-(.+) ]]; then | |
distro="clonezilla" | |
version="${BASH_REMATCH[1]}-${BASH_REMATCH[2]}" | |
variant="live" | |
arch="${BASH_REMATCH[3]}" | |
# Clonezilla Live (date format) | |
elif [[ $filename =~ clonezilla-live-([0-9]{8})-(.+)-(.+) ]]; then | |
distro="clonezilla" | |
version="${BASH_REMATCH[1]}" | |
variant="${BASH_REMATCH[2]}" | |
arch="${BASH_REMATCH[3]}" | |
# TrueNAS SCALE | |
elif [[ $filename =~ TrueNAS-SCALE-([0-9]+\.[0-9]+\.[0-9]+)(\.[0-9]+)? ]]; then | |
distro="truenas-scale" | |
version="${BASH_REMATCH[1]}${BASH_REMATCH[2]}" | |
variant="scale" | |
arch="amd64" | |
# Proxmox VE | |
elif [[ $filename =~ proxmox-ve_([0-9]+\.[0-9]+)-([0-9]+) ]]; then | |
distro="proxmox-ve" | |
version="${BASH_REMATCH[1]}-${BASH_REMATCH[2]}" | |
variant="ve" | |
arch="amd64" | |
# Proxmox Backup Server | |
elif [[ $filename =~ proxmox-backup-server_([0-9]+\.[0-9]+)-([0-9]+) ]]; then | |
distro="proxmox-backup" | |
version="${BASH_REMATCH[1]}-${BASH_REMATCH[2]}" | |
variant="backup-server" | |
arch="amd64" | |
# OPNsense | |
elif [[ $filename =~ OPNsense-([0-9]+\.[0-9]+)-(.+)-(.+) ]]; then | |
distro="opnsense" | |
version="${BASH_REMATCH[1]}" | |
variant="${BASH_REMATCH[2]}" | |
arch="${BASH_REMATCH[3]}" | |
# pfSense | |
elif [[ $filename =~ pfSense-CE-([0-9]+\.[0-9]+\.[0-9]+)-RELEASE-(.+) ]]; then | |
distro="pfsense" | |
version="${BASH_REMATCH[1]}" | |
variant="CE-RELEASE" | |
arch="${BASH_REMATCH[2]}" | |
# OpenMediaVault | |
elif [[ $filename =~ openmediavault_([0-9]+\.[0-9]+\.[0-9]+)-(.+) ]]; then | |
distro="openmediavault" | |
version="${BASH_REMATCH[1]}" | |
variant="" | |
arch="${BASH_REMATCH[2]}" | |
# NixOS | |
elif [[ $filename =~ latest-nixos-(.+)-(.+)-linux ]]; then | |
distro="nixos" | |
version="latest" | |
variant="${BASH_REMATCH[1]}" | |
arch="${BASH_REMATCH[2]}" | |
# YunoHost | |
elif [[ $filename =~ yunohost-(.+)-([0-9]+\.[0-9]+)-(.+)-(.+) ]]; then | |
distro="yunohost" | |
version="${BASH_REMATCH[2]}" | |
variant="${BASH_REMATCH[1]}-${BASH_REMATCH[4]}" | |
arch="${BASH_REMATCH[3]}" | |
# UmbrelOS | |
elif [[ $filename =~ umbrelos-(.+)-usb-installer-([0-9]+\.[0-9]+) ]]; then | |
distro="umbrelos" | |
version="${BASH_REMATCH[2]}" | |
variant="usb-installer" | |
arch="${BASH_REMATCH[1]}" | |
# Generic pattern for other distributions | |
elif [[ $filename =~ ([a-zA-Z]+)-([0-9]+(\.[0-9]+)*) ]]; then | |
distro="${BASH_REMATCH[1]}" | |
version="${BASH_REMATCH[2]}" | |
variant="" | |
arch="" | |
fi | |
echo "$distro|$version|$variant|$arch" | |
} | |
# Function to get major version | |
get_major_version() { | |
local version=$1 | |
echo "${version%%.*}" | |
} | |
# Function to compare versions (returns 0 if v1 < v2, 1 if v1 >= v2) | |
version_lt() { | |
local v1=$1 | |
local v2=$2 | |
# Convert versions to arrays | |
IFS='.' read -ra V1 <<< "$v1" | |
IFS='.' read -ra V2 <<< "$v2" | |
# Compare each part | |
local max_len=${#V1[@]} | |
[[ ${#V2[@]} -gt $max_len ]] && max_len=${#V2[@]} | |
for ((i=0; i<max_len; i++)); do | |
local n1=${V1[i]:-0} | |
local n2=${V2[i]:-0} | |
if [[ $n1 -lt $n2 ]]; then | |
return 0 | |
elif [[ $n1 -gt $n2 ]]; then | |
return 1 | |
fi | |
done | |
return 1 # versions are equal | |
} | |
# Function to check for Ubuntu updates | |
check_ubuntu_updates() { | |
local current_version=$1 | |
local variant=$2 | |
local arch=$3 | |
local major_version=$(get_major_version "$current_version") | |
if [[ $VERBOSE == true ]]; then | |
print_status $BLUE "Checking Ubuntu $major_version.x updates..." | |
fi | |
# Ubuntu releases page (simplified check) | |
local releases_url="http://releases.ubuntu.com/" | |
local latest_in_series="" | |
# For Ubuntu, check the specific series directory | |
local series_url="${releases_url}${major_version}/" | |
# This is a simplified version - in reality you'd parse the HTML or use API | |
# For demonstration, we'll simulate finding a newer version | |
case "$major_version" in | |
"22") | |
if [[ "$current_version" < "22.04.4" ]]; then | |
latest_in_series="22.04.4" | |
fi | |
;; | |
"20") | |
if [[ "$current_version" < "20.04.6" ]]; then | |
latest_in_series="20.04.6" | |
fi | |
;; | |
"18") | |
if [[ "$current_version" < "18.04.6" ]]; then | |
latest_in_series="18.04.6" | |
fi | |
;; | |
esac | |
echo "$latest_in_series" | |
} | |
# Function to check for Linux Mint updates | |
check_linuxmint_updates() { | |
local current_version=$1 | |
local variant=$2 | |
local arch=$3 | |
local major_version=$(get_major_version "$current_version") | |
if [[ $VERBOSE == true ]]; then | |
print_status $BLUE "Checking Linux Mint $major_version.x updates..." | |
fi | |
local latest_in_series="" | |
case "$major_version" in | |
"22") | |
if version_lt "$current_version" "22"; then | |
latest_in_series="22" | |
fi | |
;; | |
"21") | |
if version_lt "$current_version" "21.3"; then | |
latest_in_series="21.3" | |
fi | |
;; | |
esac | |
echo "$latest_in_series" | |
} | |
# Function to check for TrueNAS SCALE updates | |
check_truenas_updates() { | |
local current_version=$1 | |
local variant=$2 | |
local arch=$3 | |
local major_version=$(get_major_version "$current_version") | |
if [[ $VERBOSE == true ]]; then | |
print_status $BLUE "Checking TrueNAS SCALE $major_version.x updates..." | |
fi | |
local latest_in_series="" | |
case "$major_version" in | |
"24") | |
if version_lt "$current_version" "24.10.2"; then | |
latest_in_series="24.10.2" | |
fi | |
;; | |
"23") | |
if version_lt "$current_version" "23.10.2"; then | |
latest_in_series="23.10.2" | |
fi | |
;; | |
esac | |
echo "$latest_in_series" | |
} | |
# Function to check for Proxmox updates | |
check_proxmox_updates() { | |
local current_version=$1 | |
local variant=$2 | |
local arch=$3 | |
local distro_type=$4 | |
local major_version=$(get_major_version "$current_version") | |
if [[ $VERBOSE == true ]]; then | |
print_status $BLUE "Checking Proxmox $distro_type $major_version.x updates..." | |
fi | |
local latest_in_series="" | |
if [[ "$distro_type" == "ve" ]]; then | |
case "$major_version" in | |
"8") | |
if version_lt "$current_version" "8.4-1"; then | |
latest_in_series="8.4-1" | |
fi | |
;; | |
esac | |
elif [[ "$distro_type" == "backup" ]]; then | |
case "$major_version" in | |
"3") | |
if version_lt "$current_version" "3.4-1"; then | |
latest_in_series="3.4-1" | |
fi | |
;; | |
esac | |
fi | |
echo "$latest_in_series" | |
} | |
# Function to download ISO | |
download_iso() { | |
local distro=$1 | |
local version=$2 | |
local variant=$3 | |
local arch=$4 | |
local url=$5 | |
local filename=$6 | |
print_status $YELLOW "Downloading $filename..." | |
if [[ $DRY_RUN == true ]]; then | |
print_status $BLUE "DRY RUN: Would download from $url" | |
return 0 | |
fi | |
# Use wget or curl to download | |
if command -v wget >/dev/null 2>&1; then | |
wget -O "$DOWNLOAD_DIR/$filename" "$url" | |
elif command -v curl >/dev/null 2>&1; then | |
curl -L -o "$DOWNLOAD_DIR/$filename" "$url" | |
else | |
print_status $RED "Error: Neither wget nor curl is available" | |
return 1 | |
fi | |
return $? | |
} | |
# Function to backup old ISO | |
backup_iso() { | |
local iso_file=$1 | |
local backup_name="${iso_file%.iso}.$(date +%Y%m%d_%H%M%S).iso" | |
if [[ $DRY_RUN == true ]]; then | |
print_status $BLUE "DRY RUN: Would backup $iso_file to $BACKUP_DIR/$backup_name" | |
return 0 | |
fi | |
cp "$ISO_DIR/$iso_file" "$BACKUP_DIR/$backup_name" | |
print_status $GREEN "Backed up $iso_file" | |
} | |
# Main processing function | |
process_iso_files() { | |
local iso_count=0 | |
local update_count=0 | |
print_status $BLUE "Scanning directory: $ISO_DIR" | |
for iso_file in "$ISO_DIR"/*.iso; do | |
[[ ! -f "$iso_file" ]] && continue | |
local basename=$(basename "$iso_file") | |
iso_count=$((iso_count + 1)) | |
print_status $YELLOW "Processing: $basename" | |
# Parse ISO filename | |
local info=$(parse_iso_filename "$basename") | |
IFS='|' read -r distro version variant arch <<< "$info" | |
if [[ -z "$distro" ]]; then | |
print_status $RED " Unable to parse ISO filename format" | |
continue | |
fi | |
if [[ $VERBOSE == true ]]; then | |
print_status $BLUE " Detected: $distro $version ($variant, $arch)" | |
fi | |
# Check for updates based on distribution | |
local latest_version="" | |
case "$distro" in | |
"ubuntu"|"ubuntu-mate"|"ubuntu-studio"|"ubuntu-cinnamon") | |
latest_version=$(check_ubuntu_updates "$version" "$variant" "$arch") | |
;; | |
"linuxmint") | |
latest_version=$(check_linuxmint_updates "$version" "$variant" "$arch") | |
;; | |
"truenas-scale") | |
latest_version=$(check_truenas_updates "$version" "$variant" "$arch") | |
;; | |
"proxmox-ve") | |
latest_version=$(check_proxmox_updates "$version" "$variant" "$arch" "ve") | |
;; | |
"proxmox-backup") | |
latest_version=$(check_proxmox_updates "$version" "$variant" "$arch" "backup") | |
;; | |
"systemrescue"|"gparted"|"clonezilla"|"opnsense"|"pfsense"|"openmediavault"|"nixos"|"yunohost"|"umbrelos") | |
print_status $YELLOW " Update checking available but not implemented for $distro" | |
print_status $YELLOW " Current version: $version" | |
continue | |
;; | |
*) | |
print_status $YELLOW " Update checking not implemented for $distro" | |
continue | |
;; | |
esac | |
if [[ -n "$latest_version" ]]; then | |
print_status $GREEN " Update available: $version -> $latest_version" | |
if [[ $DRY_RUN == true ]]; then | |
print_status $BLUE " DRY RUN: Would update to $latest_version" | |
else | |
# Construct download URL (simplified) | |
local download_url="" | |
local new_filename="" | |
case "$distro" in | |
"ubuntu") | |
new_filename="ubuntu-${latest_version}-${variant}-${arch}.iso" | |
download_url="http://releases.ubuntu.com/${latest_version}/$new_filename" | |
;; | |
esac | |
if [[ -n "$download_url" ]]; then | |
backup_iso "$basename" | |
if download_iso "$distro" "$latest_version" "$variant" "$arch" "$download_url" "$new_filename"; then | |
# Move downloaded file to main directory | |
mv "$DOWNLOAD_DIR/$new_filename" "$ISO_DIR/$new_filename" | |
# Remove old file | |
rm "$ISO_DIR/$basename" | |
print_status $GREEN " Successfully updated to $latest_version" | |
update_count=$((update_count + 1)) | |
else | |
print_status $RED " Failed to download update" | |
fi | |
fi | |
fi | |
else | |
print_status $GREEN " Already up to date" | |
fi | |
echo | |
done | |
print_status $BLUE "Summary:" | |
print_status $BLUE " ISOs processed: $iso_count" | |
print_status $BLUE " Updates available: $update_count" | |
} | |
# Main execution | |
main() { | |
print_status $GREEN "Linux ISO Updater" | |
print_status $GREEN "==================" | |
echo | |
if [[ $DRY_RUN == true ]]; then | |
print_status $YELLOW "DRY RUN MODE - No files will be modified" | |
echo | |
fi | |
# Check for required tools | |
if ! command -v wget >/dev/null 2>&1 && ! command -v curl >/dev/null 2>&1; then | |
print_status $RED "Error: Either wget or curl is required" | |
exit 1 | |
fi | |
process_iso_files | |
print_status $GREEN "Done!" | |
} | |
# Run main function | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment