This commit is contained in:
2025-02-16 06:44:43 +03:00
parent 299f6dea06
commit 01db4540b1
14 changed files with 788 additions and 0 deletions

View File

@@ -0,0 +1,191 @@
#!/bin/bash
set -euo pipefail
###############################################################################
# WARNING: THIS SCRIPT ERASES DATA!
#
# This script will:
# 1. Identify all internal (nonremovable) SSD and NVMe disks, excluding the
# live USB from which Ubuntu is booted.
# 2. Wipe their partition tables.
# 3. On the first detected disk, create:
# - a 1GB EFI partition (formatted FAT32, flagged as ESP)
# - a ~19GB partition for Ubuntu root (formatted ext4)
# - if any space remains, a partition covering the rest (formatted btrfs)
# 4. On every other disk, create one partition spanning the entire disk and
# format it as btrfs.
#
# Doublecheck that you want to wipe all these disks BEFORE you run this script.
###############################################################################
# Ensure the script is run as root.
if [ "$EUID" -ne 0 ]; then
echo "This script must be run as root."
exit 1
fi
# Helper: given a device like /dev/sda1 or /dev/nvme0n1p1, return the base device.
get_base_device() {
local dev="$1"
if [[ "$dev" =~ ^/dev/nvme.*p[0-9]+$ ]]; then
# For NVMe devices, remove the trailing 'pX'
echo "$dev" | sed -E 's/p[0-9]+$//'
else
# For /dev/sdX type devices, remove trailing numbers
echo "$dev" | sed -E 's/[0-9]+$//'
fi
}
# Helper: given a disk (e.g. /dev/sda or /dev/nvme0n1) and a partition number,
# print the proper partition name.
get_partition_name() {
local disk="$1"
local partnum="$2"
if [[ "$disk" =~ nvme ]]; then
echo "${disk}p${partnum}"
else
echo "${disk}${partnum}"
fi
}
# Determine the boot device (i.e. the device from which the live system is running)
boot_dev_full=$(findmnt -n -o SOURCE /)
boot_disk=$(get_base_device "$boot_dev_full")
echo "Detected boot device (from /): $boot_dev_full"
echo "Base boot disk (will be used for Ubuntu install): $boot_disk"
# Now, enumerate candidate target disks.
# We will scan /sys/block for devices starting with "sd" or "nvme".
target_disks=()
# Loop over sd* and nvme* disks.
for dev_path in /sys/block/sd* /sys/block/nvme*; do
[ -e "$dev_path" ] || continue
disk_name=$(basename "$dev_path")
disk="/dev/$disk_name"
# Skip removable devices (e.g. USB sticks)
if [ "$(cat "$dev_path/removable")" -ne 0 ]; then
continue
fi
# Skip disks that are rotational (i.e. likely HDD) if you want only SSD/NVMe.
# (Usually SSD/NVMe have rotational=0.)
if [ -f "$dev_path/queue/rotational" ]; then
if [ "$(cat "$dev_path/queue/rotational")" -ne 0 ]; then
continue
fi
fi
# Add disk to list.
target_disks+=("$disk")
done
# Ensure the boot disk is in our list. (It will be partitioned for Ubuntu.)
if [[ ! " ${target_disks[@]} " =~ " ${boot_disk} " ]]; then
# Check if boot_disk qualifies (nonremovable and nonrotational)
disk_dir="/sys/block/$(basename "$boot_disk")"
if [ -f "$disk_dir/removable" ] && [ "$(cat "$disk_dir/removable")" -eq 0 ]; then
if [ -f "$disk_dir/queue/rotational" ] && [ "$(cat "$disk_dir/queue/rotational")" -eq 0 ]; then
target_disks=("$boot_disk" "${target_disks[@]}")
fi
fi
fi
if [ "${#target_disks[@]}" -eq 0 ]; then
echo "No qualifying internal SSD/NVMe disks found."
exit 1
fi
echo
echo "The following disks will be wiped and re-partitioned:"
for disk in "${target_disks[@]}"; do
echo " $disk"
done
echo
read -p "ARE YOU SURE YOU WANT TO PROCEED? This will permanently erase all data on these disks (type 'yes' to continue): " answer
if [ "$answer" != "yes" ]; then
echo "Aborting."
exit 1
fi
###############################################################################
# Wipe all target disks.
###############################################################################
for disk in "${target_disks[@]}"; do
echo "Wiping partition table on $disk..."
sgdisk --zap-all "$disk"
# Overwrite beginning of disk (optional but recommended)
dd if=/dev/zero of="$disk" bs=512 count=2048 status=none
# Overwrite end of disk (ignoring errors if size is too small)
total_sectors=$(blockdev --getsz "$disk")
dd if=/dev/zero of="$disk" bs=512 count=2048 seek=$(( total_sectors - 2048 )) status=none 2>/dev/null || true
done
###############################################################################
# Partition the FIRST disk for Ubuntu installation.
###############################################################################
boot_install_disk="${target_disks[0]}"
echo
echo "Partitioning boot/install disk: $boot_install_disk"
parted -s "$boot_install_disk" mklabel gpt
# Create EFI partition: from 1MiB to 1025MiB (~1GB).
parted -s "$boot_install_disk" mkpart ESP fat32 1MiB 1025MiB
parted -s "$boot_install_disk" set 1 esp on
# Create root partition: from 1025MiB to 21025MiB (~20GB total for install).
parted -s "$boot_install_disk" mkpart primary ext4 1025MiB 21025MiB
# Determine if theres any space left.
disk_size_bytes=$(blockdev --getsize64 "$boot_install_disk")
# Calculate 21025MiB in bytes.
min_install_bytes=$((21025 * 1024 * 1024))
if [ "$disk_size_bytes" -gt "$min_install_bytes" ]; then
echo "Creating additional partition on $boot_install_disk for btrfs (using remaining space)..."
parted -s "$boot_install_disk" mkpart primary btrfs 21025MiB 100%
boot_disk_partitions=(1 2 3)
else
boot_disk_partitions=(1 2)
fi
# Format the partitions on the boot/install disk.
efi_part=$(get_partition_name "$boot_install_disk" 1)
root_part=$(get_partition_name "$boot_install_disk" 2)
echo "Formatting EFI partition ($efi_part) as FAT32..."
mkfs.fat -F32 "$efi_part"
echo "Formatting root partition ($root_part) as ext4..."
mkfs.ext4 -F "$root_part"
# If a third partition exists, format it as btrfs.
if [ "${boot_disk_partitions[2]:-}" ]; then
btrfs_part=$(get_partition_name "$boot_install_disk" 3)
echo "Formatting extra partition ($btrfs_part) as btrfs..."
mkfs.btrfs -f "$btrfs_part"
fi
###############################################################################
# Partition all OTHER target disks entirely as btrfs.
###############################################################################
if [ "${#target_disks[@]}" -gt 1 ]; then
echo
echo "Partitioning remaining disks for btrfs:"
for disk in "${target_disks[@]:1}"; do
echo "Processing disk $disk..."
parted -s "$disk" mklabel gpt
parted -s "$disk" mkpart primary btrfs 1MiB 100%
# Determine the partition name (e.g. /dev/sdb1 or /dev/nvme0n1p1).
if [[ "$disk" =~ nvme ]]; then
part="${disk}p1"
else
part="${disk}1"
fi
echo "Formatting $part as btrfs..."
mkfs.btrfs -f "$part"
done
fi
echo
echo "All operations complete. Ubuntu install partitions and btrfs volumes have been created."