Skip to content

Instantly share code, notes, and snippets.

@JucaRei
Forked from ryza-dytalabs-io/ubuntu-build.sh
Created April 4, 2025 19:31
Show Gist options
  • Save JucaRei/eb689f919003ba90d598a866a5bd9a24 to your computer and use it in GitHub Desktop.
Save JucaRei/eb689f919003ba90d598a866a5bd9a24 to your computer and use it in GitHub Desktop.
secure installation of ubuntu
#!/bin/bash
# Ubuntu Installation Script with LUKS-encrypted BTRFS, systemd-boot, and Secure Boot
# Author: Claude (modified and improved with apt speed enhancements)
# Usage: sudo bash script.sh [install_device] [username] [hostname] [locale] [language] [timezone]
# Passwords can be provided via environment or will be prompted securely.
set -euo pipefail
# Log file for the installation process
LOGFILE="/var/log/ubuntu_install_script.log"
exec > >(tee -a "$LOGFILE") 2>&1
# Error handling function
error_exit() {
echo "ERROR: $1" >&2
exit 1
}
# Check if running as root
check_root() {
if [ "$EUID" -ne 0 ]; then
error_exit "Please run as root."
fi
}
# Check for UEFI mode
check_uefi() {
if [ ! -d "/sys/firmware/efi" ]; then
error_exit "This script requires UEFI mode. Please boot in UEFI mode and try again."
fi
}
# Detect available disk (first try unpartitioned; fallback to any)
detect_disk() {
local disk
echo "Probing system for available disk..."
for disk in $(find /dev -maxdepth 1 -type b | grep -E '^(\/dev\/nvme|\/dev\/vd|\/dev\/sd)'); do
if ! lsblk -no NAME "$disk" | grep -q "[0-9]"; then
echo "Selected disk: $disk"
echo "$disk"
return 0
fi
done
error_exit "No suitable disk found!"
}
# Return partition names for EFI and root based on device naming
get_partition_names() {
local device="$1"
if [[ "$device" == *"nvme"* ]]; then
echo "${device}p1 ${device}p2"
else
echo "${device}1 ${device}2"
fi
}
# Check if the disk is SSD (returns 0 for SSD)
is_ssd() {
local device="$1"
if [ -z "$device" ]; then
# Default to false if no device provided
return 0
fi
local base_device
base_device=$(basename "$(echo "$device" | sed 's/[0-9]*$//')")
if [ -f "/sys/block/${base_device}/queue/rotational" ] && [ "$(cat /sys/block/${base_device}/queue/rotational)" -eq 0 ]; then
return 1
else
return 0
fi
}
# Securely prompt for a password if not set already.
get_password() {
local prompt="$1"
local var_name="$2"
if [ -n "${!var_name:-}" ]; then
return
fi
local pass1 pass2
while true; do
echo -n "$prompt: "
read -rs pass1
echo
echo -n "Confirm $prompt: "
read -rs pass2
echo
if [[ "$pass1" == "$pass2" && -n "$pass1" ]]; then
eval "$var_name=\$pass1"
break
else
echo "Passwords do not match or are empty. Try again."
fi
done
}
# Prepare disk: wipe, create partition table, and partitions.
prepare_disk() {
local device="$1"
local EFI_SIZE="1024M"
echo "Wiping and partitioning disk $device..."
umount -fR /mnt 2>/dev/null || true
cryptsetup luksClose root_fs 2>/dev/null || true
wipefs -a "$device" || echo "Warning: wipefs failed, continuing."
dd if=/dev/zero of="$device" bs=1M count=10 conv=fsync 2>/dev/null || echo "Warning: dd wipe failed, continuing."
if is_ssd "$device"; then
if command -v hdparm &>/dev/null; then
echo "Attempting SSD secure erase..."
hdparm --security-set-pass password "$device" 2>/dev/null || true
hdparm --security-erase password "$device" 2>/dev/null || true
fi
if command -v blkdiscard &>/dev/null; then
echo "Running blkdiscard on SSD..."
blkdiscard "$device" 2>/dev/null || true
fi
fi
echo "Creating GPT partition table..."
parted -s "$device" mklabel gpt || error_exit "Failed to create GPT partition table"
echo "Creating EFI partition..."
parted -s "$device" mkpart ESP fat32 1MiB "$EFI_SIZE" || error_exit "Failed to create EFI partition"
parted -s "$device" set 1 esp on || error_exit "Failed to set EFI flag"
echo "Creating root partition..."
parted -s "$device" mkpart primary "$EFI_SIZE" 100% || error_exit "Failed to create root partition"
}
# Set up LUKS encryption on the root partition
setup_luks() {
local ROOT_PARTITION="$1"
echo "Setting up LUKS encryption on $ROOT_PARTITION..."
echo -n "$ENCRYPT_PASSWORD" | cryptsetup luksFormat "$ROOT_PARTITION" -q || error_exit "Failed to encrypt root partition"
echo -n "$ENCRYPT_PASSWORD" | cryptsetup luksOpen "$ROOT_PARTITION" root_fs -q || error_exit "Failed to open encrypted partition"
}
# Create BTRFS filesystem and subvolumes
setup_btrfs() {
echo "Creating BTRFS filesystem on /dev/mapper/root_fs..."
mkfs.btrfs /dev/mapper/root_fs || error_exit "Failed to create BTRFS filesystem"
mount /dev/mapper/root_fs /mnt || error_exit "Failed to mount BTRFS filesystem"
echo "Creating BTRFS subvolumes..."
for subvol in "@" "@home" "@log" "@pkg" "@snapshots" "@swap" "@tmp" "@var_tmp"; do
btrfs subvolume create "/mnt/$subvol" || error_exit "Failed to create subvolume $subvol"
done
umount /mnt || error_exit "Failed to unmount /mnt"
}
# Mount subvolumes with options
mount_subvolumes() {
# Define SSD_OPTS as a global variable so it can be used elsewhere
SSD_OPTS=""
if is_ssd "$INSTALL_DEVICE"; then
SSD_OPTS=",ssd,discard=async"
echo "Mounting with SSD options: $SSD_OPTS"
else
echo "Mounting with standard options"
fi
echo "Mounting root subvolume (@)..."
mount -o subvol=@,rw,noatime,compress=zstd:3${SSD_OPTS},space_cache=v2 /dev/mapper/root_fs /mnt || error_exit "Failed to mount root subvolume"
mkdir -p /mnt/{efi,home,var/log,var/cache/apt,.snapshots,swap,tmp,var/tmp} || error_exit "Failed to create mount point directories"
echo "Formatting EFI partition ($EFI_PARTITION)..."
mkfs.fat -F32 "$EFI_PARTITION" || error_exit "Failed to format EFI partition"
echo "Mounting EFI partition..."
mount "$EFI_PARTITION" /mnt/efi -o "defaults,umask=0077" || error_exit "Failed to mount EFI partition"
echo "Mounting additional subvolumes..."
mount -o subvol=@home,rw,noatime,compress=zstd:3${SSD_OPTS},space_cache=v2 /dev/mapper/root_fs /mnt/home || error_exit "Failed to mount @home"
mount -o subvol=@log,rw,noatime,compress=zstd:3${SSD_OPTS},space_cache=v2 /dev/mapper/root_fs /mnt/var/log || error_exit "Failed to mount @log"
mount -o subvol=@pkg,rw,noatime,compress=zstd:3${SSD_OPTS},space_cache=v2 /dev/mapper/root_fs /mnt/var/cache/apt || error_exit "Failed to mount @pkg"
mount -o subvol=@snapshots,rw,noatime,compress=zstd:3${SSD_OPTS},space_cache=v2 /dev/mapper/root_fs /mnt/.snapshots || error_exit "Failed to mount @snapshots"
mount -o subvol=@swap,rw,relatime,nodatacow,compress=no${SSD_OPTS} /dev/mapper/root_fs /mnt/swap || error_exit "Failed to mount @swap"
mount -o subvol=@tmp,rw,noatime,compress=zstd:3${SSD_OPTS},space_cache=v2 /dev/mapper/root_fs /mnt/tmp || error_exit "Failed to mount @tmp"
mount -o subvol=@var_tmp,rw,noatime,compress=zstd:3${SSD_OPTS},space_cache=v2 /dev/mapper/root_fs /mnt/var/tmp || error_exit "Failed to mount @var_tmp"
}
# Install base system using debootstrap with apt acceleration techniques.
install_base_system() {
echo "Updating package lists..."
if command -v apt-fast >/dev/null 2>&1; then
apt-fast update || error_exit "Failed to update package lists using apt-fast"
else
apt update || error_exit "Failed to update package lists"
fi
echo "Installing debootstrap and wget..."
if command -v apt-fast >/dev/null 2>&1; then
apt-fast install -y debootstrap wget || error_exit "Failed to install required packages using apt-fast"
else
apt install -y debootstrap wget || error_exit "Failed to install required packages"
fi
echo "Installing base system with debootstrap..."
if [ -f "/usr/lib/x86_64-linux-gnu/libeatmydata.so" ]; then
echo "Using eatmydata to speed up debootstrap..."
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libeatmydata.so debootstrap --arch=amd64 "$UBUNTU_VERSION" /mnt || error_exit "Failed to install base system with debootstrap"
else
echo "eatmydata not found, falling back to normal debootstrap"
debootstrap --arch=amd64 "$UBUNTU_VERSION" /mnt || error_exit "Failed to install base system with debootstrap"
fi
}
# Generate fstab manually
generate_fstab() {
echo "Generating fstab..."
mkdir -p /mnt/etc || error_exit "Failed to create /mnt/etc"
EFI_UUID=$(blkid -s UUID -o value "$EFI_PARTITION") || error_exit "Failed to get EFI UUID"
# For BTRFS, use the UUID of the device mapper target
BTRFS_UUID=$(blkid -s UUID -o value /dev/mapper/root_fs) || error_exit "Failed to get root_fs UUID"
if [ -z "$EFI_UUID" ] || [ -z "$BTRFS_UUID" ]; then
error_exit "Failed to get partition UUIDs"
fi
cat > /mnt/etc/fstab <<EOF
# /etc/fstab: static file system information.
UUID=${EFI_UUID} /efi vfat defaults,umask=0077 0 1
UUID=${BTRFS_UUID} / btrfs subvol=@,rw,noatime,compress=zstd:3${SSD_OPTS},space_cache=v2 0 1
UUID=${BTRFS_UUID} /home btrfs subvol=@home,rw,noatime,compress=zstd:3${SSD_OPTS},space_cache=v2 0 2
UUID=${BTRFS_UUID} /var/log btrfs subvol=@log,rw,noatime,compress=zstd:3${SSD_OPTS},space_cache=v2 0 2
UUID=${BTRFS_UUID} /var/cache/apt btrfs subvol=@pkg,rw,noatime,compress=zstd:3${SSD_OPTS},space_cache=v2 0 2
UUID=${BTRFS_UUID} /.snapshots btrfs subvol=@snapshots,rw,noatime,compress=zstd:3${SSD_OPTS},space_cache=v2 0 2
UUID=${BTRFS_UUID} /swap btrfs subvol=@swap,rw,relatime,nodatacow,compress=no${SSD_OPTS} 0 0
UUID=${BTRFS_UUID} /tmp btrfs subvol=@tmp,rw,noatime,compress=zstd:3${SSD_OPTS},space_cache=v2 0 2
UUID=${BTRFS_UUID} /var/tmp btrfs subvol=@var_tmp,rw,noatime,compress=zstd:3${SSD_OPTS},space_cache=v2 0 2
/swap/swapfile none swap defaults 0 0
EOF
echo "fstab content:"
cat /mnt/etc/fstab
}
# Prepare chroot environment by binding system directories
prepare_chroot() {
echo "Binding /dev, /proc, /sys..."
for dir in dev dev/pts proc sys; do
mkdir -p "/mnt/$dir"
mount --bind "/$dir" "/mnt/$dir" || error_exit "Failed to bind mount /$dir"
done
mkdir -p /mnt/sys/firmware/efi/efivars
mount -t efivarfs efivarfs /mnt/sys/firmware/efi/efivars
}
# Write and execute the chroot setup script with actual configuration code.
configure_chroot() {
# Pass environment variables to the chroot script
cat > /mnt/setup.sh <<'EOF'
#!/bin/bash
set -e
# Check if the disk is SSD (returns 0 for SSD)
is_ssd() {
local device="$1"
if [ -z "$device" ]; then
return 0
fi
# First remove any trailing digits
local tmp
tmp=$(echo "$device" | sed 's/[0-9]*$//')
# Then get the basename
local base_device
base_device=$(basename "$tmp")
if [ -f "/sys/block/${base_device}/queue/rotational" ] && [ "$(cat /sys/block/${base_device}/queue/rotational)" -eq 0 ]; then
return 1
else
return 0
fi
}
error_exit() { echo "ERROR: $1" >&2; exit 1; }
# Set hostname
echo "$HOSTNAME" > /etc/hostname
# Configure /etc/hosts
cat > /etc/hosts <<HOSTS
127.0.0.1 localhost
127.0.1.1 $HOSTNAME
::1 localhost
HOSTS
# Update package lists and install essential packages
apt update -y || error_exit "Failed to update packages"
(apt install -y software-properties-common && add-apt-repository universe -y && add-apt-repository ppa:apt-fast/stable -y && apt update -y) || error_exit "Failed to update universe packages"
DEBIAN_FRONTEND=noninteractive apt install -y network-manager btrfs-progs binutils linux-image-generic linux-headers-generic \
cryptsetup-initramfs sbsigntool efitools sudo vim bash-completion systemd-boot systemd-boot-efi \
apt-fast aria2 || error_exit "Failed to install essential packages"
# Verify systemd-boot is installed properly
if ! command -v bootctl >/dev/null 2>&1; then
error_exit "systemd-boot installation failed"
fi
# Configure apt-fast for future use
if [ -f "/etc/apt-fast.conf" ]; then
sed -i 's|^_MAXNUM=.*|_MAXNUM=10|g' /etc/apt-fast.conf
sed -i 's|^DOWNLOADBEFORE=.*|DOWNLOADBEFORE=true|g' /etc/apt-fast.conf
fi
# Create swapfile (twice RAM size)
echo "Creating swapfile..."
if [ ! -d "/swap" ]; then
error_exit "/swap directory doesn't exist"
fi
# Get RAM size in kB and calculate twice that for swap
RAM_KB=$(grep MemTotal /proc/meminfo | awk '{print $2}')
SWAP_MB=$((RAM_KB / 512)) # Convert to MB and double
echo "System RAM: $((RAM_KB / 1024)) MB, creating $SWAP_MB MB swap"
dd if=/dev/zero of=/swap/swapfile bs=1M count=$SWAP_MB || error_exit "Failed to create swapfile"
chmod 600 /swap/swapfile || error_exit "Failed to set swapfile permissions"
mkswap -U clear /swap/swapfile || error_exit "Failed to format swapfile"
# Get the resume offset for hibernate
RESUME_OFFSET=$(filefrag -v /swap/swapfile | awk '{ if($1=="0:"){print $4} }' | tr -d '.')
RESUME_UUID=$(blkid -s UUID -o value /dev/mapper/root_fs)
echo "Swap resume offset: $RESUME_OFFSET"
# Set locale and generate locales
echo "$LOCALE UTF-8" > /etc/locale.gen && locale-gen
echo "LANG=$LOCALE" > /etc/default/locale
# Set timezone
ln -sf /usr/share/zoneinfo/$TIMEZONE /etc/localtime && dpkg-reconfigure --frontend noninteractive tzdata
# Create user and configure sudoers
echo "Adding user ($USERNAME)"
useradd -r -m -s /bin/bash -d /var/lib/"$USERNAME" "$USERNAME" || true
echo "$USERNAME:$USER_PASSWORD" | chpasswd || error_exit "Failed to set user password"
groupadd -f wheel
usermod -aG sudo,wheel "$USERNAME"
echo '%wheel ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/wheel
chmod 440 /etc/sudoers.d/wheel
# Get the UUID of the underlying encrypted device (not the mapper)
ROOT_PART_UUID=$(blkid -s UUID -o value /dev/$(dmsetup deps -o devname root_fs | grep -Eo "[^ : (]*$" | sed 's/)$//'))
if [ -z "$ROOT_PART_UUID" ]; then
error_exit "Could not determine encrypted root partition UUID"
fi
# Set up crypttab for the encrypted root filesystem
if is_ssd "$INSTALL_DEVICE"; then
DISCARD_OPTION=",discard"
else
DISCARD_OPTION=""
fi
echo "root_fs UUID=$ROOT_PART_UUID none luks$DISCARD_OPTION" > /etc/crypttab
echo "Configured crypttab with UUID $ROOT_PART_UUID"
# Configure kernel parameters for systemd-boot
# These match the ArchLinux style parameters requested
KERNEL_OPTS="cryptdevice=UUID=$ROOT_PART_UUID:root_fs${DISCARD_OPTION} root=/dev/mapper/root_fs rootflags=subvol=@ rw rootfstype=btrfs resume=UUID=$RESUME_UUID resume_offset=$RESUME_OFFSET intel_iommu=on kvm.ignore_msrs=1 acpi_osi=\"Windows 2018.2\" no_console_suspend splash quiet ip=:::::eth0:dhcp"
# Update initramfs to include cryptsetup support
echo "Including cryptsetup in initramfs..."
echo "CRYPTSETUP=y" > /etc/cryptsetup-initramfs/conf-hook
update-initramfs -u -k all || error_exit "Failed to update initramfs"
# Install boot loader
if command -v bootctl >/dev/null 2>&1; then
echo "Installing systemd-boot..."
bootctl --path=/efi install || error_exit "Failed to install systemd-boot"
# Create loader configuration
mkdir -p /efi/loader/entries
cat > /efi/loader/loader.conf <<LOADER_CONF
default ubuntu.conf
timeout 5
console-mode max
editor no
LOADER_CONF
KERNEL_VERSION=$(ls /lib/modules | sort -V | tail -n1)
# Create Ubuntu entry
cat > /efi/loader/entries/ubuntu.conf <<UBUNTU_ENTRY
title Ubuntu Linux
linux /vmlinuz-${KERNEL_VERSION}
initrd /initrd.img-${KERNEL_VERSION}
options ${KERNEL_OPTS}
UBUNTU_ENTRY
# Copy the kernel and initramfs to the ESP
cp /boot/vmlinuz-${KERNEL_VERSION} /efi/
cp /boot/initrd.img-${KERNEL_VERSION} /efi/
# Create a hook to update systemd-boot entries on kernel updates
cat > /etc/kernel/postinst.d/update-systemd-boot <<UPDATE_BOOT
#!/bin/bash
set -e
# Get the kernel version that was just installed
KERNEL_VERSION=\$1
# Copy kernel and initramfs to the ESP
cp /boot/vmlinuz-\${KERNEL_VERSION} /efi/
cp /boot/initrd.img-\${KERNEL_VERSION} /efi/
# Create a new loader entry
cat > /efi/loader/entries/ubuntu-\${KERNEL_VERSION}.conf <<ENTRY
title Ubuntu Linux \${KERNEL_VERSION}
linux /vmlinuz-\${KERNEL_VERSION}
initrd /initrd.img-\${KERNEL_VERSION}
options ${KERNEL_OPTS}
ENTRY
# Update the default entry to point to the new kernel
sed -i "s/^default.*/default ubuntu-\${KERNEL_VERSION}.conf/" /efi/loader/loader.conf
exit 0
UPDATE_BOOT
chmod +x /etc/kernel/postinst.d/update-systemd-boot
else
# systemd-boot is a hard requirement
error_exit "systemd-boot is required but not available"
fi
echo "Chroot configuration complete."
EOF
chmod +x /mnt/setup.sh
echo "Chroot setup script written to /mnt/setup.sh"
}
# Clean up after installation
cleanup() {
echo "Cleaning up..."
for dir in dev/pts dev proc sys; do
umount "/mnt/$dir" 2>/dev/null || true
done
umount -R /mnt 2>/dev/null || true
cryptsetup luksClose root_fs 2>/dev/null || true
echo "Cleanup complete."
}
# Main function: sequence of operations
main() {
check_root
check_uefi
# Parameters: device, username, hostname, locale, language, timezone
INSTALL_DEVICE="${1:-$(detect_disk)}"
HOSTNAME="${3:-spectre}"
LOCALE="${4:-en_AU.UTF-8}"
LANGUAGE="${5:-en_AU:en}"
TIMEZONE="${6:-Australia/Melbourne}"
USERNAME="${2:-archie}"
UBUNTU_VERSION="noble" # or your desired Ubuntu release
# Prompt for sensitive passwords if not provided via environment
get_password "Enter encryption password" ENCRYPT_PASSWORD
get_password "Enter user password" USER_PASSWORD
# Determine partition names and check device validity
if [ ! -b "$INSTALL_DEVICE" ]; then
error_exit "$INSTALL_DEVICE is not a valid block device"
fi
read -r EFI_PARTITION ROOT_PARTITION <<< "$(get_partition_names "$INSTALL_DEVICE")"
echo "Using EFI partition: $EFI_PARTITION and root partition: $ROOT_PARTITION"
if is_ssd "$INSTALL_DEVICE"; then
echo "Detected SSD: enabling SSD-specific mount options."
else
echo "Detected HDD: using standard mount options."
fi
# Execute installation steps
prepare_disk "$INSTALL_DEVICE"
setup_luks "$ROOT_PARTITION"
setup_btrfs
mount_subvolumes
install_base_system
generate_fstab
prepare_chroot
configure_chroot
echo "Running chroot installation script..."
(chroot /mnt /bin/bash -c "INSTALL_DEVICE=\"$INSTALL_DEVICE\" HOSTNAME=\"$HOSTNAME\" USERNAME=\"$USERNAME\" USER_PASSWORD=\"$USER_PASSWORD\" LOCALE=\"$LOCALE\" TIMEZONE=\"$TIMEZONE\" UBUNTU_VERSION=\"$UBUNTU_VERSION\" /setup.sh") || error_exit "Chroot script failed"
#cleanup
echo "Installation complete. You may now reboot into your new system."
}
main "$@"
#!/bin/bash
# Create timestamped backup directory
timestamp=$(date +%Y%m%d_%H%M%S)
backup_dir=~/system_backup_$timestamp
mkdir -p $backup_dir
# Check if snap is installed
if command -v snap &> /dev/null; then
echo "Backing up snap packages..."
snap list --all > $backup_dir/snap_packages.txt
fi
# Backup sources.list and sources.list.d directory
echo "Backing up APT sources..."
cp /etc/apt/sources.list $backup_dir/
cp -r /etc/apt/sources.list.d $backup_dir/
# Backup installed packages list
echo "Backing up installed packages list..."
dpkg --get-selections > $backup_dir/installed_packages.txt
# Find and backup modified package files using debsums
echo "Installing debsums if not present..."
apt-get install -y debsums >/dev/null 2>&1
echo "Finding modified package files..."
debsums -c 2>/dev/null > $backup_dir/modified_files.txt
# Find custom /etc files
echo "Finding custom /etc files..."
find /etc -type f -print0 | xargs -0 dpkg -S 2>&1 | grep "no path found" | awk '{print $7}' | sort | grep -vE "snap|/etc/systemd/system/|group|passwd|shadow|subgid|subuid|sudoers|microsoft|oms" >> $backup_dir/modified_files.txt
# Create directory for all modified files
mkdir -p $backup_dir/modified_files
while read file; do
if [ -f "$file" ]; then
dir=$(dirname "$file")
mkdir -p "$backup_dir/modified_files$dir"
cp "$file" "$backup_dir/modified_files$file"
echo "Backed up: $file"
fi
done < $backup_dir/modified_files.txt
# Create tar archive
echo "Creating tar archive..."
tar -czf $backup_dir.tar.gz -C $(dirname $backup_dir) $(basename $backup_dir)
# Clean up
rm -rf $backup_dir
echo "Backup completed at $backup_dir.tar.gz"
#!/bin/bash
# Check if backup file is provided
if [ $# -lt 1 ]; then
echo "Usage: $0 <backup_tar_file>"
exit 1
fi
backup_tar=$1
# Check if backup file exists
if [ ! -f "$backup_tar" ]; then
echo "Error: Backup file $backup_tar not found!"
exit 1
fi
# Create temporary directory
temp_dir=$(mktemp -d)
echo "Extracting backup to $temp_dir..."
# Extract backup
tar -xzf $backup_tar -C $temp_dir
# Find the actual backup directory (first subdirectory)
backup_dir=$(find $temp_dir -maxdepth 1 -type d | grep -v "^$temp_dir$" | head -1)
if [ -z "$backup_dir" ]; then
echo "Error: Could not find backup directory in archive"
exit 1
fi
# Restore sources.list
echo "Restoring APT sources..."
sudo cp $backup_dir/sources.list /etc/apt/
# Restore sources.list.d directory
sudo mkdir -p /etc/apt/sources.list.d/
sudo cp -r $backup_dir/sources.list.d/* /etc/apt/sources.list.d/
# Update package lists
echo "Updating package lists..."
sudo apt update
# Restore installed packages
echo "Restoring installed packages..."
sudo dpkg --set-selections < $backup_dir/installed_packages.txt
sudo apt-get dselect-upgrade -y
# Restore snap packages
if [ -f "$backup_dir/snap_packages.txt" ]; then
echo "Restoring snap packages..."
# Skip the header line and extract package names and channels
tail -n +2 "$backup_dir/snap_packages.txt" | while read -r name version rev tracking publisher notes; do
if [ "$notes" != "disabled" ]; then
echo "Installing snap package: $name"
sudo snap install $name
fi
done
fi
# Restore all modified files
echo "Restoring modified files..."
if [ -d "$backup_dir/modified_files" ]; then
sudo cp -r $backup_dir/modified_files/* /
echo "All modified files restored"
fi
# Clean up
rm -rf $temp_dir
echo "System restore completed."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment