Update rhel8-iso-update.sh
This commit is contained in:
@@ -2,13 +2,47 @@
|
||||
|
||||
#===============================================================================
|
||||
# RHEL 8.10 Offline Update Script
|
||||
#
|
||||
# This interactive script guides administrators through applying updates
|
||||
# from a locally-mounted ISO file.
|
||||
#===============================================================================
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Interactive script for applying RHEL 8.10 updates from a local ISO file
|
||||
# in air-gapped or disconnected environments.
|
||||
#
|
||||
# SUPPORTED ISOs
|
||||
# - Full_Latest_RHEL8_x86_64_patches_*.iso (full monthly update, ~30GB)
|
||||
# - Incremental_Latest_RHEL8_X86_64_patches_*.iso (incremental update, smaller)
|
||||
#
|
||||
# USAGE
|
||||
# sudo ./rhel8-iso-update.sh
|
||||
#
|
||||
# OPTIONS
|
||||
# The script is fully interactive and will prompt for all choices.
|
||||
# No command-line arguments are required.
|
||||
#
|
||||
# FEATURES
|
||||
# - Auto-detects ISOs in /var/isos/, /media/, /mnt/, and USB drives
|
||||
# - Detects and can mount unmounted USB devices
|
||||
# - Cleans up previous update configuration before applying new updates
|
||||
# - Creates temporary repo pointing to mounted ISO
|
||||
# - Checks if reboot is required after updates
|
||||
# - Optional cleanup of ISO, mount, and repo files when finished
|
||||
#
|
||||
# PATHS USED
|
||||
# ISO Search: /var/isos/, /run/media/, /media/, /mnt/
|
||||
# Mount Point: /media/rhel-patches
|
||||
# Repo File: /etc/yum.repos.d/rhel-patches.repo
|
||||
#
|
||||
# REQUIREMENTS
|
||||
# - Root or sudo access
|
||||
# - RHEL 8.10 system
|
||||
# - Sufficient disk space (~35GB for full ISO if copying locally)
|
||||
#
|
||||
# AUTHOR
|
||||
# Cybersecurity Team
|
||||
#
|
||||
# LAST UPDATED
|
||||
# January 2026
|
||||
#
|
||||
# ISO: Full_Latest_RHEL8_x86_64_patches_2026-01-13.iso
|
||||
# Mount Point: /media/JanPatch
|
||||
# Repo File: /etc/yum.repos.d/JanPatch.repo
|
||||
#===============================================================================
|
||||
|
||||
# Colors for output
|
||||
@@ -19,10 +53,13 @@ BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Configuration
|
||||
ISO_NAME="Full_Latest_RHEL8_x86_64_patches_2026-01-13.iso"
|
||||
ISO_PATH="/var/isos/${ISO_NAME}"
|
||||
MOUNT_POINT="/media/JanPatch"
|
||||
REPO_FILE="/etc/yum.repos.d/JanPatch.repo"
|
||||
ISO_PATTERN_FULL="Full_Latest_RHEL8_x86_64_patches_*.iso"
|
||||
ISO_PATTERN_INCREMENTAL="Incremental_Latest_RHEL8_X86_64_patches_*.iso"
|
||||
ISO_NAME="" # Will be set when ISO is found/selected
|
||||
ISO_PATH="" # Will be set when ISO is found/selected
|
||||
ISO_DIR="/var/isos"
|
||||
MOUNT_POINT="/media/rhel-patches"
|
||||
REPO_FILE="/etc/yum.repos.d/rhel-patches.repo"
|
||||
|
||||
# Global variables for tracking
|
||||
FOUND_ISO_LOCATIONS=()
|
||||
@@ -87,6 +124,62 @@ check_root() {
|
||||
# ISO Detection Functions
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
check_previous_update() {
|
||||
# Check if there's a previous update still mounted/configured
|
||||
local needs_cleanup=false
|
||||
|
||||
if mountpoint -q "$MOUNT_POINT" 2>/dev/null; then
|
||||
needs_cleanup=true
|
||||
fi
|
||||
|
||||
if [[ -f "$REPO_FILE" ]]; then
|
||||
needs_cleanup=true
|
||||
fi
|
||||
|
||||
if [[ "$needs_cleanup" == true ]]; then
|
||||
print_header "Previous Update Detected"
|
||||
echo "A previous update configuration was found:"
|
||||
echo ""
|
||||
|
||||
if mountpoint -q "$MOUNT_POINT" 2>/dev/null; then
|
||||
echo " - ISO mounted at: ${MOUNT_POINT}"
|
||||
fi
|
||||
|
||||
if [[ -f "$REPO_FILE" ]]; then
|
||||
echo " - Repo file exists: ${REPO_FILE}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
if confirm_action "Would you like to clean up the previous update before continuing?"; then
|
||||
print_info "Cleaning up previous update..."
|
||||
|
||||
# Disable repo if it exists
|
||||
if [[ -f "$REPO_FILE" ]]; then
|
||||
dnf config-manager --set-disabled dvd-rhel-patches 2>/dev/null
|
||||
rm -f "$REPO_FILE"
|
||||
print_success "Removed old repo file."
|
||||
fi
|
||||
|
||||
# Unmount if mounted
|
||||
if mountpoint -q "$MOUNT_POINT" 2>/dev/null; then
|
||||
umount "$MOUNT_POINT"
|
||||
print_success "Unmounted previous ISO."
|
||||
fi
|
||||
|
||||
# Clean DNF cache
|
||||
dnf clean all &>/dev/null
|
||||
|
||||
echo ""
|
||||
print_success "Previous update cleaned up."
|
||||
else
|
||||
print_info "Keeping previous configuration. The script will overwrite as needed."
|
||||
fi
|
||||
|
||||
pause_continue
|
||||
fi
|
||||
}
|
||||
|
||||
detect_external_media() {
|
||||
# Find mounted external media (USB drives, external disks)
|
||||
# Looks in common mount locations for removable media
|
||||
@@ -96,22 +189,29 @@ detect_external_media() {
|
||||
"/run/media"
|
||||
"/media"
|
||||
"/mnt"
|
||||
"$ISO_DIR"
|
||||
)
|
||||
|
||||
print_info "Scanning for external media..."
|
||||
print_info "Scanning for RHEL patch ISOs (Full and Incremental)..."
|
||||
echo ""
|
||||
|
||||
for base_path in "${search_paths[@]}"; do
|
||||
if [[ -d "$base_path" ]]; then
|
||||
# Find the ISO file recursively in media locations
|
||||
# Find Full ISO files
|
||||
while IFS= read -r -d '' file; do
|
||||
found_locations+=("$file")
|
||||
done < <(find "$base_path" -maxdepth 3 -name "$ISO_NAME" -type f -print0 2>/dev/null)
|
||||
done < <(find "$base_path" -maxdepth 3 -name "$ISO_PATTERN_FULL" -type f -print0 2>/dev/null)
|
||||
|
||||
# Find Incremental ISO files
|
||||
while IFS= read -r -d '' file; do
|
||||
found_locations+=("$file")
|
||||
done < <(find "$base_path" -maxdepth 3 -name "$ISO_PATTERN_INCREMENTAL" -type f -print0 2>/dev/null)
|
||||
fi
|
||||
done
|
||||
|
||||
# Return results via global variable
|
||||
FOUND_ISO_LOCATIONS=("${found_locations[@]}")
|
||||
# Sort by filename (newest date typically last)
|
||||
IFS=$'\n' FOUND_ISO_LOCATIONS=($(sort -u <<< "${found_locations[*]}")); unset IFS
|
||||
}
|
||||
}
|
||||
|
||||
detect_unmounted_usb() {
|
||||
@@ -151,21 +251,25 @@ show_iso_search_menu() {
|
||||
local option_paths=()
|
||||
local count=1
|
||||
|
||||
echo "Where would you like to load the ISO from?"
|
||||
echo "Found the following RHEL patch ISO files:"
|
||||
echo ""
|
||||
|
||||
# Option: Default location if exists
|
||||
if [[ -f "$ISO_PATH" ]]; then
|
||||
echo " ${count}) Default location: ${ISO_PATH}"
|
||||
options+=("default")
|
||||
option_paths+=("$ISO_PATH")
|
||||
((count++))
|
||||
fi
|
||||
|
||||
# Options: Found on external media
|
||||
# Options: Found ISO files
|
||||
for location in "${FOUND_ISO_LOCATIONS[@]}"; do
|
||||
echo " ${count}) External media: ${location}"
|
||||
options+=("external")
|
||||
local filename=$(basename "$location")
|
||||
local dir=$(dirname "$location")
|
||||
local iso_type="Unknown"
|
||||
|
||||
# Determine ISO type
|
||||
if [[ "$filename" == Full_* ]]; then
|
||||
iso_type="Full"
|
||||
elif [[ "$filename" == Incremental_* ]]; then
|
||||
iso_type="Incremental"
|
||||
fi
|
||||
|
||||
echo " ${count}) [${iso_type}] ${filename}"
|
||||
echo " Location: ${dir}"
|
||||
options+=("found")
|
||||
option_paths+=("$location")
|
||||
((count++))
|
||||
done
|
||||
@@ -208,8 +312,9 @@ show_iso_search_menu() {
|
||||
local chosen_path="${option_paths[$idx]}"
|
||||
|
||||
case "$chosen_option" in
|
||||
"default"|"external")
|
||||
"found")
|
||||
ISO_PATH="$chosen_path"
|
||||
ISO_NAME=$(basename "$ISO_PATH")
|
||||
return 0
|
||||
;;
|
||||
"mount_usb")
|
||||
@@ -220,6 +325,7 @@ show_iso_search_menu() {
|
||||
read -p "Enter full path to ISO file: " custom_path
|
||||
if [[ -f "$custom_path" ]]; then
|
||||
ISO_PATH="$custom_path"
|
||||
ISO_NAME=$(basename "$ISO_PATH")
|
||||
return 0
|
||||
else
|
||||
print_error "File not found: ${custom_path}"
|
||||
@@ -244,27 +350,29 @@ mount_usb_device() {
|
||||
if mount "$device" "$mount_dir"; then
|
||||
print_success "Mounted ${device} to ${mount_dir}"
|
||||
|
||||
# Search for ISO on mounted device
|
||||
local found_iso=$(find "$mount_dir" -maxdepth 2 -name "$ISO_NAME" -type f 2>/dev/null | head -1)
|
||||
# Search for ISO on mounted device using both patterns
|
||||
local found_iso=$(find "$mount_dir" -maxdepth 2 \( -name "$ISO_PATTERN_FULL" -o -name "$ISO_PATTERN_INCREMENTAL" \) -type f 2>/dev/null | head -1)
|
||||
|
||||
if [[ -n "$found_iso" ]]; then
|
||||
print_success "Found ISO: ${found_iso}"
|
||||
ISO_NAME=$(basename "$found_iso")
|
||||
|
||||
if confirm_action "Copy ISO to ${ISO_PATH}? (This will take several minutes for 30GB)"; then
|
||||
if confirm_action "Copy ISO to ${ISO_DIR}/${ISO_NAME}? (This will take several minutes for large ISOs)"; then
|
||||
print_info "Copying ISO... This may take a while."
|
||||
|
||||
# Ensure target directory exists
|
||||
mkdir -p "$(dirname "$ISO_PATH")"
|
||||
mkdir -p "$ISO_DIR"
|
||||
|
||||
# Copy with progress using rsync if available, otherwise cp
|
||||
if command -v rsync &>/dev/null; then
|
||||
rsync -ah --progress "$found_iso" "$ISO_PATH"
|
||||
rsync -ah --progress "$found_iso" "${ISO_DIR}/${ISO_NAME}"
|
||||
else
|
||||
cp -v "$found_iso" "$ISO_PATH"
|
||||
cp -v "$found_iso" "${ISO_DIR}/${ISO_NAME}"
|
||||
fi
|
||||
|
||||
if [[ -f "$ISO_PATH" ]]; then
|
||||
if [[ -f "${ISO_DIR}/${ISO_NAME}" ]]; then
|
||||
print_success "ISO copied successfully."
|
||||
ISO_PATH="${ISO_DIR}/${ISO_NAME}"
|
||||
umount "$mount_dir"
|
||||
rmdir "$mount_dir"
|
||||
return 0
|
||||
@@ -279,7 +387,11 @@ mount_usb_device() {
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
print_error "ISO file not found on ${device}"
|
||||
print_error "No RHEL patch ISO found on ${device}"
|
||||
echo "Looking for files matching:"
|
||||
echo " - ${ISO_PATTERN_FULL}"
|
||||
echo " - ${ISO_PATTERN_INCREMENTAL}"
|
||||
echo ""
|
||||
echo "Files on device:"
|
||||
ls -la "$mount_dir" | head -10
|
||||
fi
|
||||
@@ -301,14 +413,17 @@ mount_usb_device() {
|
||||
show_welcome() {
|
||||
clear
|
||||
print_header "RHEL 8.10 Offline Update Script"
|
||||
echo "This script will guide you through applying updates from the ISO file:"
|
||||
echo "This script will guide you through applying updates from a patch ISO."
|
||||
echo ""
|
||||
echo " ISO File: ${ISO_NAME}"
|
||||
echo " Mount Point: ${MOUNT_POINT}"
|
||||
echo " Repo File: ${REPO_FILE}"
|
||||
echo " Supported ISOs:"
|
||||
echo " - Full: ${ISO_PATTERN_FULL}"
|
||||
echo " - Incremental: ${ISO_PATTERN_INCREMENTAL}"
|
||||
echo ""
|
||||
echo " Mount Point: ${MOUNT_POINT}"
|
||||
echo " Repo File: ${REPO_FILE}"
|
||||
echo ""
|
||||
echo "Steps this script will perform:"
|
||||
echo " 1. Verify the ISO file exists"
|
||||
echo " 1. Search for and select the ISO file"
|
||||
echo " 2. Create mount point and mount the ISO"
|
||||
echo " 3. Create the local repository configuration"
|
||||
echo " 4. Refresh the package cache"
|
||||
@@ -326,47 +441,56 @@ show_welcome() {
|
||||
|
||||
step1_verify_iso() {
|
||||
print_header "Step 1: Locate ISO File"
|
||||
print_step "1" "Searching for ISO file..."
|
||||
print_step "1" "Searching for RHEL patch ISO files..."
|
||||
|
||||
# Detect external media with ISO
|
||||
# Detect ISOs in all locations
|
||||
detect_external_media
|
||||
detect_unmounted_usb
|
||||
|
||||
# Check if ISO exists in default location
|
||||
local iso_found=false
|
||||
if [[ -f "$ISO_PATH" ]]; then
|
||||
iso_found=true
|
||||
fi
|
||||
|
||||
# Check if found on external media
|
||||
# Check if any ISOs were found
|
||||
if [[ ${#FOUND_ISO_LOCATIONS[@]} -gt 0 ]]; then
|
||||
iso_found=true
|
||||
fi
|
||||
|
||||
# Show what we found
|
||||
if [[ "$iso_found" == true ]] || [[ ${#UNMOUNTED_USB_DEVICES[@]} -gt 0 ]]; then
|
||||
|
||||
# If only one option (default location) and no USB, use it directly
|
||||
if [[ -f "$ISO_PATH" ]] && [[ ${#FOUND_ISO_LOCATIONS[@]} -eq 0 ]] && [[ ${#UNMOUNTED_USB_DEVICES[@]} -eq 0 ]]; then
|
||||
print_success "ISO file found: ${ISO_PATH}"
|
||||
# If only one ISO found, confirm and use it
|
||||
if [[ ${#FOUND_ISO_LOCATIONS[@]} -eq 1 ]] && [[ ${#UNMOUNTED_USB_DEVICES[@]} -eq 0 ]]; then
|
||||
ISO_PATH="${FOUND_ISO_LOCATIONS[0]}"
|
||||
ISO_NAME=$(basename "$ISO_PATH")
|
||||
print_success "Found ISO: ${ISO_NAME}"
|
||||
print_info "Location: $(dirname "$ISO_PATH")"
|
||||
|
||||
local size=$(du -h "$ISO_PATH" | cut -f1)
|
||||
print_info "File size: ${size}"
|
||||
|
||||
if ! confirm_action "Use this ISO?"; then
|
||||
if ! show_iso_search_menu; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# Multiple options available - show menu
|
||||
# Multiple options - show menu
|
||||
if ! show_iso_search_menu; then
|
||||
print_error "Failed to locate ISO file."
|
||||
exit 1
|
||||
fi
|
||||
print_success "Using ISO: ${ISO_PATH}"
|
||||
fi
|
||||
|
||||
print_success "Selected: ${ISO_NAME}"
|
||||
|
||||
elif [[ ${#UNMOUNTED_USB_DEVICES[@]} -gt 0 ]]; then
|
||||
# No ISOs found but unmounted USB detected
|
||||
print_info "No ISO files found, but unmounted USB devices detected."
|
||||
if ! show_iso_search_menu; then
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# Nothing found anywhere
|
||||
print_error "ISO file not found."
|
||||
print_error "No RHEL patch ISO files found."
|
||||
echo ""
|
||||
echo "The script searched for: ${ISO_NAME}"
|
||||
echo "The script searched for:"
|
||||
echo " - ${ISO_PATTERN_FULL}"
|
||||
echo " - ${ISO_PATTERN_INCREMENTAL}"
|
||||
echo ""
|
||||
echo "Locations checked:"
|
||||
echo " - ${ISO_PATH}"
|
||||
echo " - ${ISO_DIR}/"
|
||||
echo " - /run/media/*/ (mounted USB drives)"
|
||||
echo " - /media/*/"
|
||||
echo " - /mnt/*/"
|
||||
@@ -376,17 +500,15 @@ step1_verify_iso() {
|
||||
read -p "Enter full path to ISO file: " custom_path
|
||||
if [[ -f "$custom_path" ]]; then
|
||||
ISO_PATH="$custom_path"
|
||||
print_success "Using ISO: ${ISO_PATH}"
|
||||
ISO_NAME=$(basename "$ISO_PATH")
|
||||
print_success "Using ISO: ${ISO_NAME}"
|
||||
else
|
||||
print_error "File not found: ${custom_path}"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo ""
|
||||
echo "Please copy the ISO to /var/isos/ and run this script again."
|
||||
echo ""
|
||||
echo "Example from USB drive:"
|
||||
echo " cp /run/media/\$(whoami)/USBDRIVE/${ISO_NAME} /var/isos/"
|
||||
echo "Please copy the ISO to ${ISO_DIR}/ and run this script again."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
@@ -460,10 +582,10 @@ step3_create_repo() {
|
||||
fi
|
||||
|
||||
# Create the repo file
|
||||
cat > "$REPO_FILE" << 'EOF'
|
||||
cat > "$REPO_FILE" << EOF
|
||||
[dvd-rhel-patches]
|
||||
name=DVD for RHEL Patches
|
||||
baseurl=file:///media/JanPatch
|
||||
baseurl=file://${MOUNT_POINT}
|
||||
enabled=1
|
||||
gpgcheck=0
|
||||
EOF
|
||||
@@ -611,10 +733,10 @@ step8_cleanup() {
|
||||
fi
|
||||
fi
|
||||
|
||||
# Delete ISO (only if it's in /var/isos, not on USB)
|
||||
if [[ -f "/var/isos/$ISO_NAME" ]]; then
|
||||
if confirm_action "Delete the ISO file (/var/isos/${ISO_NAME})? This will free up ~30GB."; then
|
||||
rm -f "/var/isos/$ISO_NAME"
|
||||
# Delete ISO (only if it's in ISO_DIR, not on USB)
|
||||
if [[ -n "$ISO_NAME" ]] && [[ -f "${ISO_DIR}/${ISO_NAME}" ]]; then
|
||||
if confirm_action "Delete the ISO file (${ISO_DIR}/${ISO_NAME})? This will free up ~30GB."; then
|
||||
rm -f "${ISO_DIR}/${ISO_NAME}"
|
||||
print_success "ISO file deleted."
|
||||
fi
|
||||
fi
|
||||
@@ -650,6 +772,7 @@ show_complete() {
|
||||
main() {
|
||||
check_root
|
||||
show_welcome
|
||||
check_previous_update
|
||||
step1_verify_iso
|
||||
step2_mount_iso
|
||||
step3_create_repo
|
||||
@@ -662,4 +785,4 @@ main() {
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main
|
||||
main
|
||||
Reference in New Issue
Block a user