Skip to content

Instantly share code, notes, and snippets.

@facundoq
Created June 3, 2026 12:14
Show Gist options
  • Select an option

  • Save facundoq/715dc4b230d6362aa98fe4440c1ec992 to your computer and use it in GitHub Desktop.

Select an option

Save facundoq/715dc4b230d6362aa98fe4440c1ec992 to your computer and use it in GitHub Desktop.
Create a bootable partition with a linux installer, so as to avoid using a usb to install linux.
#!/usr/bin/env bash
# Enforce strict error handling
set -euo pipefail
# --- Configuration ---
TARGET_DEV="/dev/nvme0n1"
PARTITION="${TARGET_DEV}p1"
ISO_URL="https://releases.ubuntu.com/26.04/ubuntu-26.04-live-server-amd64.iso"
ISO_TMP="/tmp/ubuntu-26.04-server.iso"
MOUNT_ISO="/mnt/ubuntu_iso"
MOUNT_DEST="/mnt/ubuntu_installer"
PART_LABEL="installer"
# --- Pre-flight Checks ---
if [[ $EUID -ne 0 ]]; then
echo "Error: This script must be run as root."
exit 1
fi
if [[ ! -b "$TARGET_DEV" ]]; then
echo "Error: Target device $TARGET_DEV does not exist."
exit 1
fi
echo "WARNING: This will completely WIPE the partition table on $TARGET_DEV."
read -p "Are you absolutely sure you want to continue? (y/N): " confirm
if [[ "${confirm,,}" != "y" ]]; then
echo "Aborted by user."
exit 0
fi
# --- 1. Disk Wiping & Partitioning ---
echo "[*] Wiping current partition table and creating new GPT label..."
parted -s "$TARGET_DEV" mklabel gpt
echo "[*] Creating 8GB partition at the END of the drive..."
parted -a optimal -s "$TARGET_DEV" mkpart primary fat32 -- -8GiB 100%
# Wait for the OS to recognize the new partition block device
udevadm settle
echo "[*] Setting EFI/Boot flags..."
parted -s "$TARGET_DEV" name 1 "$PART_LABEL"
parted -s "$TARGET_DEV" set 1 esp on
parted -s "$TARGET_DEV" set 1 boot on
echo "[*] Formatting partition as FAT32..."
mkfs.vfat -F 32 -n "$PART_LABEL" "$PARTITION"
# --- 2. ISO Acquisition ---
echo "[*] Checking for existing Ubuntu 26.04 ISO..."
if [[ -f "$ISO_TMP" ]]; then
echo "[+] ISO already found at $ISO_TMP. Skipping download."
else
echo "[*] Downloading Ubuntu 26.04 ISO..."
wget --continue --show-progress -O "$ISO_TMP" "$ISO_URL"
fi
# --- 3. Mounting & Extraction ---
echo "[*] Creating mount points..."
mkdir -p "$MOUNT_ISO" "$MOUNT_DEST"
echo "[*] Mounting ISO and target partition..."
mount -o loop,ro "$ISO_TMP" "$MOUNT_ISO"
mount "$PARTITION" "$MOUNT_DEST"
echo "[*] Extracting ISO contents to the NVMe partition..."
# Using rsync with --no-links to bypass FAT32 symlink limitations
rsync -a --no-links --info=progress2 --no-o --no-g --no-perms "${MOUNT_ISO}/" "${MOUNT_DEST}/"
# --- 4. Cleanup & Sync ---
echo "[*] Syncing I/O buffers (this may take a moment)..."
sync
echo "[*] Unmounting filesystems..."
umount "$MOUNT_DEST"
umount "$MOUNT_ISO"
echo "[*] Cleaning up temporary files..."
# Commenting out the ISO removal so it stays cached for future runs if needed
# rm -f "$ISO_TMP"
rmdir "$MOUNT_DEST" "$MOUNT_ISO"
echo "[+] Success! The installer partition is ready at $PARTITION."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment