Skip to content

Instantly share code, notes, and snippets.

@0xdeafbeef
Created February 24, 2026 18:37
Show Gist options
  • Select an option

  • Save 0xdeafbeef/9600e57e130a7ab557f9d8a46624f247 to your computer and use it in GitHub Desktop.

Select an option

Save 0xdeafbeef/9600e57e130a7ab557f9d8a46624f247 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<'EOF'
Usage:
sudo ./fedora-disk-setup.sh /dev/<disk> [--swap-size 34G] [--efi-size 600M] [--boot-size 1G] [--no-mount] [--yes]
Examples:
sudo ./fedora-disk-setup.sh /dev/nvme0n1
sudo ./fedora-disk-setup.sh /dev/sda --swap-size 32G --yes
EOF
}
need() { command -v "$1" >/dev/null 2>&1 || { echo "Missing: $1"; exit 1; }; }
DISK="${1:-}"
[[ -z "${DISK}" || "${DISK}" == "-h" || "${DISK}" == "--help" ]] && usage && exit 0
shift || true
EFI_SIZE="600M"
BOOT_SIZE="1G"
SWAP_SIZE="" # empty => auto (RAM + 2G)
DO_MOUNT=1
ASSUME_YES=0
while [[ $# -gt 0 ]]; do
case "$1" in
--efi-size) EFI_SIZE="${2:?}"; shift 2 ;;
--boot-size) BOOT_SIZE="${2:?}"; shift 2 ;;
--swap-size) SWAP_SIZE="${2:?}"; shift 2 ;;
--no-mount) DO_MOUNT=0; shift ;;
--yes) ASSUME_YES=1; shift ;;
*) echo "Unknown arg: $1"; usage; exit 1 ;;
esac
done
[[ -b "${DISK}" ]] || { echo "Not a block device: ${DISK}"; exit 1; }
need sgdisk
need wipefs
need mkfs.fat
need mkfs.ext4
need mkswap
need mkfs.btrfs
need lsblk
need partprobe
need findmnt
# Compute swap size if not provided: RAM + 2G (rounded up to GiB)
if [[ -z "${SWAP_SIZE}" ]]; then
mem_kib=$(awk '/MemTotal:/ {print $2}' /proc/meminfo)
mem_gib=$(( (mem_kib + 1024*1024 - 1) / (1024*1024) ))
swap_gib=$(( mem_gib + 2 ))
SWAP_SIZE="${swap_gib}G"
fi
# Partition naming helper (nvme0n1p1 vs sda1)
part() {
local n="$1"
if [[ "${DISK}" =~ [0-9]$ ]]; then
echo "${DISK}p${n}"
else
echo "${DISK}${n}"
fi
}
echo "About to WIPE and repartition: ${DISK}"
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT "${DISK}" || true
echo
echo "Layout:"
echo " 1) EFI : ${EFI_SIZE} (FAT32) -> /boot/efi"
echo " 2) /boot: ${BOOT_SIZE} (ext4) -> /boot"
echo " 3) swap : ${SWAP_SIZE} (swap) -> hibernation"
echo " 4) root : rest (btrfs) -> / (subvol root, home)"
echo
if [[ "${ASSUME_YES}" -ne 1 ]]; then
read -r -p "Type YES to continue: " ans
[[ "${ans}" == "YES" ]] || { echo "Aborted."; exit 1; }
fi
# Safety: refuse if any partitions are mounted
if findmnt -rn -S "${DISK}" >/dev/null 2>&1; then
echo "Some part of ${DISK} is mounted. Unmount first."
exit 1
fi
# Best-effort swapoff if this disk contains swap currently
for s in $(swapon --noheadings --raw | awk '{print $1}' | grep -E "^${DISK}" || true); do
sudo swapoff "$s" || true
done
echo "Wiping signatures + partition table..."
wipefs -a "${DISK}"
sgdisk --zap-all "${DISK}"
echo "Creating GPT partitions..."
sgdisk -n1:1MiB:+"${EFI_SIZE}" -t1:EF00 -c1:"EFI" "${DISK}"
sgdisk -n2:0:+"${BOOT_SIZE}" -t2:8300 -c2:"boot" "${DISK}"
sgdisk -n3:0:+"${SWAP_SIZE}" -t3:8200 -c3:"swap" "${DISK}"
sgdisk -n4:0:0 -t4:8300 -c4:"root" "${DISK}"
partprobe "${DISK}"
P1="$(part 1)"
P2="$(part 2)"
P3="$(part 3)"
P4="$(part 4)"
echo "Formatting..."
mkfs.fat -F32 -n EFI "${P1}"
mkfs.ext4 -F -L boot "${P2}"
mkswap -L swap "${P3}"
mkfs.btrfs -f -L fedora "${P4}"
if [[ "${DO_MOUNT}" -eq 1 ]]; then
echo "Creating Btrfs subvolumes + mounting to /mnt..."
mkdir -p /mnt
mount "${P4}" /mnt
btrfs subvolume create /mnt/root >/dev/null
btrfs subvolume create /mnt/home >/dev/null
umount /mnt
mount -o subvol=root,compress=zstd:1 "${P4}" /mnt
mkdir -p /mnt/{home,boot,boot/efi}
mount -o subvol=home,compress=zstd:1 "${P4}" /mnt/home
mount "${P2}" /mnt/boot
mount "${P1}" /mnt/boot/efi
swapon "${P3}"
echo
echo "Done. Mounted under /mnt:"
findmnt /mnt /mnt/home /mnt/boot /mnt/boot/efi || true
echo
echo "Swap enabled:"
swapon --show
else
echo "Done. (Not mounted; --no-mount)"
fi
echo
echo "Next steps (after installing Fedora):"
echo " - Add resume=UUID=<swap-uuid> to kernel cmdline (for hibernation resume)"
echo " - Consider disabling zram if you want predictable hibernation behavior"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment