Last active
May 13, 2025 04:28
-
-
Save S4tyendra/7152fb0a6f66e5436bbe6ab24296f9bd to your computer and use it in GitHub Desktop.
Update ubuntu systems automatically
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 | |
| set -eo pipefail | |
| # --- Banner --- | |
| echo "======================================" | |
| echo "π Automated Ubuntu LTS Upgrade Tool" | |
| echo "======================================" | |
| # --- Check for sudo/root --- | |
| if [[ "$EUID" -ne 0 ]]; then | |
| echo "β Error: This script requires root privileges" | |
| echo "π Please run with: sudo $0" | |
| exit 1 | |
| fi | |
| # --- Pre-upgrade checks --- | |
| echo "π Performing pre-upgrade checks..." | |
| # Check disk space (require at least 5GB free) | |
| FREE_SPACE=$(df -BG / | awk 'NR==2 {print $4}' | tr -d 'G') | |
| if [[ "${FREE_SPACE%.*}" -lt 5 ]]; then | |
| echo "β Error: Insufficient disk space (${FREE_SPACE}GB). At least 5GB recommended." | |
| exit 1 | |
| fi | |
| # Create timestamp for files | |
| TIMESTAMP=$(date +%Y%m%d-%H%M%S) | |
| BACKUP_DIR="/root/pre-upgrade-backup-${TIMESTAMP}" | |
| LOG_FILE="/var/log/system-upgrade-${TIMESTAMP}.log" | |
| PACKAGE_LIST="${BACKUP_DIR}/installed-packages.txt" | |
| PACKAGE_SELECTIONS="${BACKUP_DIR}/package-selections.txt" | |
| REPO_BACKUP_DIR="${BACKUP_DIR}/sources.list.d" | |
| APT_KEYS_BACKUP="${BACKUP_DIR}/apt-trusted-keys.gpg" | |
| APT_KEYRINGS_DIR="${BACKUP_DIR}/keyrings" | |
| # Create backup directories | |
| mkdir -p "$BACKUP_DIR" "$REPO_BACKUP_DIR" "$APT_KEYRINGS_DIR" | |
| # --- Save installed packages --- | |
| echo "π¦ Saving list of installed packages..." | tee -a "$LOG_FILE" | |
| apt-mark showmanual > "$PACKAGE_LIST" | |
| dpkg --get-selections > "$PACKAGE_SELECTIONS" | |
| echo "π Package lists saved to:" | tee -a "$LOG_FILE" | |
| echo " - $PACKAGE_LIST (manually installed packages)" | tee -a "$LOG_FILE" | |
| echo " - $PACKAGE_SELECTIONS (all package selections)" | tee -a "$LOG_FILE" | |
| # --- Backup repositories --- | |
| echo "π Backing up repository configurations..." | tee -a "$LOG_FILE" | |
| # Copy main sources.list | |
| cp /etc/apt/sources.list "${BACKUP_DIR}/sources.list.original" | |
| # Copy all repository files from sources.list.d | |
| cp -r /etc/apt/sources.list.d/* "$REPO_BACKUP_DIR" 2>/dev/null || true | |
| # Backup trusted keys | |
| cp /etc/apt/trusted.gpg "$APT_KEYS_BACKUP" 2>/dev/null || true | |
| cp -r /etc/apt/trusted.gpg.d/* "$APT_KEYS_BACKUP.d" 2>/dev/null || mkdir -p "$APT_KEYS_BACKUP.d" | |
| # Backup keyrings directory if it exists | |
| cp -r /etc/apt/keyrings/* "$APT_KEYRINGS_DIR" 2>/dev/null || true | |
| # Save PPA information if add-apt-repository is available | |
| if command -v add-apt-repository > /dev/null; then | |
| add-apt-repository --list > "${BACKUP_DIR}/ppa-list.txt" 2>/dev/null || true | |
| fi | |
| echo "π¦ Repository configurations backed up to $REPO_BACKUP_DIR" | tee -a "$LOG_FILE" | |
| # Create recovery script | |
| RECOVERY_SCRIPT="${BACKUP_DIR}/restore-packages.sh" | |
| cat > "$RECOVERY_SCRIPT" << 'EOL' | |
| #!/bin/bash | |
| set -e | |
| if [[ "$EUID" -ne 0 ]]; then | |
| echo "β Please run as root or with sudo." | |
| exit 1 | |
| fi | |
| SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" | |
| PACKAGE_LIST="${SCRIPT_DIR}/installed-packages.txt" | |
| PACKAGE_SELECTIONS="${SCRIPT_DIR}/package-selections.txt" | |
| SOURCES_ORIGINAL="${SCRIPT_DIR}/sources.list.original" | |
| SOURCES_BACKUP_DIR="${SCRIPT_DIR}/sources.list.d" | |
| APT_KEYS_BACKUP="${SCRIPT_DIR}/apt-trusted-keys.gpg" | |
| APT_KEYRINGS_BACKUP="${SCRIPT_DIR}/keyrings" | |
| if [[ ! -f "$PACKAGE_LIST" || ! -f "$PACKAGE_SELECTIONS" ]]; then | |
| echo "β Package lists not found in ${SCRIPT_DIR}" | |
| exit 1 | |
| fi | |
| # --- Restore repositories (optional) --- | |
| echo "π Would you like to restore your original repository sources? (y/n)" | |
| read -r RESTORE_REPOS | |
| if [[ "$RESTORE_REPOS" == "y" || "$RESTORE_REPOS" == "Y" ]]; then | |
| echo "π Restoring repository configurations..." | |
| # Backup current sources just in case | |
| CURRENT_BACKUP="/etc/apt/sources.list.before-restore" | |
| echo "π¦ Backing up current sources.list to $CURRENT_BACKUP" | |
| cp /etc/apt/sources.list "$CURRENT_BACKUP" | |
| # Restore main sources file | |
| if [[ -f "$SOURCES_ORIGINAL" ]]; then | |
| echo "π Restoring main sources.list..." | |
| cp "$SOURCES_ORIGINAL" /etc/apt/sources.list | |
| fi | |
| # Restore additional sources | |
| if [[ -d "$SOURCES_BACKUP_DIR" && -n "$(ls -A "$SOURCES_BACKUP_DIR" 2>/dev/null)" ]]; then | |
| echo "π Restoring sources.list.d directory..." | |
| cp -r "$SOURCES_BACKUP_DIR"/* /etc/apt/sources.list.d/ 2>/dev/null || true | |
| fi | |
| # Restore trusted keys | |
| if [[ -f "$APT_KEYS_BACKUP" ]]; then | |
| echo "π Restoring trusted APT keys..." | |
| cp "$APT_KEYS_BACKUP" /etc/apt/trusted.gpg 2>/dev/null || true | |
| fi | |
| # Restore keyrings | |
| if [[ -d "$APT_KEYRINGS_BACKUP" && -n "$(ls -A "$APT_KEYRINGS_BACKUP" 2>/dev/null)" ]]; then | |
| echo "π Restoring APT keyrings..." | |
| mkdir -p /etc/apt/keyrings | |
| cp -r "$APT_KEYRINGS_BACKUP"/* /etc/apt/keyrings/ 2>/dev/null || true | |
| fi | |
| echo "β Repository configurations restored!" | |
| fi | |
| echo "π Updating package lists..." | |
| apt update || { | |
| echo "β οΈ APT update failed. Please check your sources.list and try again." | |
| echo "π You can view your backed up sources in $SCRIPT_DIR" | |
| exit 1 | |
| } | |
| apt install openssh-server -y || { | |
| echo "β οΈ SSH Server installation failed!." | |
| } | |
| echo "π¦ Reinstalling packages from list..." | |
| xargs apt install -y < "$PACKAGE_LIST" || true | |
| echo "π Restoring package selections..." | |
| dpkg --set-selections < "$PACKAGE_SELECTIONS" | |
| apt-get dselect-upgrade -y || true | |
| echo "β Package restoration completed!" | |
| echo "π Note: Some packages may not have been restored if they're no longer available" | |
| echo " in the repositories or are incompatible with the new Ubuntu release." | |
| EOL | |
| chmod +x "$RECOVERY_SCRIPT" | |
| echo "π Recovery script created at $RECOVERY_SCRIPT" | tee -a "$LOG_FILE" | |
| # --- Package management --- | |
| echo "π Updating package lists..." | tee -a "$LOG_FILE" | |
| apt update >> "$LOG_FILE" 2>&1 || { echo "β Failed to update package lists"; exit 1; } | |
| echo "π¦ Upgrading existing packages..." | tee -a "$LOG_FILE" | |
| apt upgrade -y >> "$LOG_FILE" 2>&1 || { echo "β Failed to upgrade packages"; exit 1; } | |
| echo "βοΈ Performing distribution upgrade..." | tee -a "$LOG_FILE" | |
| apt dist-upgrade -y >> "$LOG_FILE" 2>&1 || { echo "β Failed to perform distribution upgrade"; exit 1; } | |
| echo "π§Ή Cleaning up unnecessary packages..." | tee -a "$LOG_FILE" | |
| apt autoremove --purge -y >> "$LOG_FILE" 2>&1 | |
| apt clean >> "$LOG_FILE" 2>&1 | |
| # --- Prepare for release upgrade --- | |
| echo "π οΈ Installing and configuring upgrade tools..." | tee -a "$LOG_FILE" | |
| apt install -y update-manager-core >> "$LOG_FILE" 2>&1 || { echo "β Failed to install update-manager-core"; exit 1; } | |
| # Configure for LTS releases only | |
| echo "π Setting release upgrade policy to LTS..." | tee -a "$LOG_FILE" | |
| sed -i 's/^Prompt=.*/Prompt=lts/' /etc/update-manager/release-upgrades | |
| # --- Backup important configuration --- | |
| echo "πΎ Creating backup of critical system files..." | tee -a "$LOG_FILE" | |
| cp -a /etc/fstab /etc/network /etc/ssh "$BACKUP_DIR" 2>/dev/null || true | |
| echo "π System configuration backup stored in $BACKUP_DIR" | tee -a "$LOG_FILE" | |
| # --- Execute release upgrade --- | |
| echo "π Starting non-interactive upgrade to latest LTS..." | tee -a "$LOG_FILE" | |
| echo "β³ This may take a while. Please be patient." | |
| export DEBIAN_FRONTEND=noninteractive | |
| do-release-upgrade -f DistUpgradeViewNonInteractive >> "$LOG_FILE" 2>&1 || { | |
| echo "β οΈ Release upgrade process exited with status $?" | |
| echo "π Check $LOG_FILE for details" | |
| echo "π¦ If needed, restore packages using $RECOVERY_SCRIPT" | |
| echo "β οΈ Manual intervention may be required!" | |
| exit 1 | |
| } | |
| # --- Final cleanup and reboot --- | |
| echo "π§Ή Performing final system cleanup..." | tee -a "$LOG_FILE" | |
| apt autoremove --purge -y >> "$LOG_FILE" 2>&1 | |
| apt clean >> "$LOG_FILE" 2>&1 | |
| echo "β Upgrade process completed successfully!" | tee -a "$LOG_FILE" | |
| echo "π Summary:" | tee -a "$LOG_FILE" | |
| echo " - System upgraded to latest LTS release" | tee -a "$LOG_FILE" | |
| echo " - Logs available at: $LOG_FILE" | tee -a "$LOG_FILE" | |
| echo " - Backup saved to: $BACKUP_DIR" | tee -a "$LOG_FILE" | |
| echo " - Package lists backed up and can be restored with: $RECOVERY_SCRIPT" | tee -a "$LOG_FILE" | |
| echo " - Repository sources backed up to: $REPO_BACKUP_DIR" | tee -a "$LOG_FILE" | |
| # Schedule reboot with countdown | |
| echo "π System will reboot in 30 seconds. Press Ctrl+C to cancel." | tee -a "$LOG_FILE" | |
| sleep 5 | |
| echo "π Rebooting in 25 seconds..." | tee -a "$LOG_FILE" | |
| sleep 5 | |
| echo "π Rebooting in 20 seconds..." | tee -a "$LOG_FILE" | |
| sleep 5 | |
| echo "π Rebooting in 15 seconds..." | tee -a "$LOG_FILE" | |
| sleep 5 | |
| echo "π Rebooting in 10 seconds..." | tee -a "$LOG_FILE" | |
| sleep 5 | |
| echo "π Rebooting in 5 seconds..." | tee -a "$LOG_FILE" | |
| sleep 5 | |
| echo "π Rebooting now!" | tee -a "$LOG_FILE" | |
| reboot |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment