Initial commit
This commit is contained in:
commit
1abc5b8b59
2 changed files with 490 additions and 0 deletions
43
README.md
Normal file
43
README.md
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
# Gentoo Installation Helper Script
|
||||||
|
|
||||||
|
Used to provide good defaults to Gentoo to install with or without encryption, hibernation support, and with BtrFS subvolumes.
|
||||||
|
|
||||||
|
```
|
||||||
|
Usage: gentoo-install.sh <disk> [<options>...]
|
||||||
|
|
||||||
|
Positional Arguments:
|
||||||
|
<drive> Disk device used for system
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h, --help Help on this tool.
|
||||||
|
-e, --encryption Enable LUKS encryption.
|
||||||
|
-c, --compression Enable BtrFS compression.
|
||||||
|
-s, --swap Enable Swap/Hibernation support.
|
||||||
|
-d, --debug Enable DEBUG mode for testing.
|
||||||
|
|
||||||
|
--stage <stage> Installation using stagefile <stage>, for stage3 or stage4
|
||||||
|
--clean Cleanup disk for clean slate
|
||||||
|
```
|
||||||
|
|
||||||
|
## Initial Setup
|
||||||
|
|
||||||
|
This installation script is intended to work on a clean disk to provision all partitions
|
||||||
|
as appropriate to the generalized setup defined.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Run gentoo-install.sh with appropriate parameters. An example of this for NVME-based SSD, and Encryption with Hibernation:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo ./gentoo-install.sh /dev/nvme0n1 -e -s
|
||||||
|
```
|
||||||
|
|
||||||
|
This will start the provisioning setup, with the full expectations that the system is ready to go as-is, as it will format. You will get one prompt before it actually starts.
|
||||||
|
|
||||||
|
## Stage Installation
|
||||||
|
|
||||||
|
After the preparation phase, it completes and allows you time to verify what's happened and
|
||||||
|
go over any issues you may or may not see, before you continue on to stage installation.
|
||||||
|
|
||||||
|
The Stage installation, using `--stage <stage>` allows you to setup stage3 or stage4 based on
|
||||||
|
what you provide for <stage>, which can be a url or a file to an appropriate stagefile.
|
447
gentoo-install.sh
Normal file
447
gentoo-install.sh
Normal file
|
@ -0,0 +1,447 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [[ "$(id -u)" -ne 0 ]]; then
|
||||||
|
echo "ERROR: This needs to be run as root"
|
||||||
|
exit 250
|
||||||
|
fi
|
||||||
|
|
||||||
|
declare -rA SUBVOLS_DEFAULT=(
|
||||||
|
["@home"]="home"
|
||||||
|
["@root"]="root"
|
||||||
|
["@srv"]="srv"
|
||||||
|
["@opt"]="opt"
|
||||||
|
["@local"]="usr/local"
|
||||||
|
["@cache"]="var/cache"
|
||||||
|
["@repos"]="/var/db/repos"
|
||||||
|
["@containers"]="var/lib/containers"
|
||||||
|
["@libvirt"]="var/lib/libvirt/images"
|
||||||
|
["@machines"]="var/lib/machines"
|
||||||
|
["@portables"]="var/lib/portables"
|
||||||
|
["@log"]="var/log"
|
||||||
|
["@spool"]="var/spool"
|
||||||
|
["@www"]="var/www"
|
||||||
|
["@snapshots"]=".snapshots"
|
||||||
|
)
|
||||||
|
|
||||||
|
gunction show_help() {
|
||||||
|
echo "Usage: $0 <disk> [<options>...]"
|
||||||
|
echo ""
|
||||||
|
echo "Positional Arguments:"
|
||||||
|
echo "<drive> Disk device used for system"
|
||||||
|
echo ""
|
||||||
|
echo "Options:"
|
||||||
|
echo "-h, --help Help on this tool."
|
||||||
|
echo "-e, --encryption Enable LUKS encryption."
|
||||||
|
echo "-c, --compression Enable BtrFS compression."
|
||||||
|
echo "-s, --swap Enable Swap/Hibernation support."
|
||||||
|
echo "-d, --debug Enable DEBUG mode for testing."
|
||||||
|
echo ""
|
||||||
|
echo "--stage <stage> Installation using stagefile <stage>, for stage3 or stage4"
|
||||||
|
echo "--clean Cleanup disk for clean slate"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepare_disk() {
|
||||||
|
if [[ "$DEBUG" ]]; then
|
||||||
|
local cmd="echo"
|
||||||
|
else
|
||||||
|
local cmd=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -b "$RootDisk" ]]; then
|
||||||
|
if [[ -b "$EFIPart" || -b "$RootPart" ]]; then
|
||||||
|
echo "FATAL: Disk already provisioned. Clean required to continue."
|
||||||
|
exit 250
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$ENCRYPTION" ]]; then
|
||||||
|
parted "$RootDisk" --script --align optimal -- "$RootDisk" \
|
||||||
|
mklabel gpt \
|
||||||
|
mkpart primary 1MiB 100MiB \
|
||||||
|
mkpart primary 100MiB 2048MiB \
|
||||||
|
mkpart primary 2148MiB -2048s \
|
||||||
|
set 1 esp
|
||||||
|
#mkfs.vfat -F 32 -n "EFI" "$RootPart"
|
||||||
|
#mkfs.ext4 -L "Boot" -m 0 "$EFIPart"
|
||||||
|
#mkfs.btrfs -L "System" "$RootPart"
|
||||||
|
else
|
||||||
|
parted "$RootDisk" --script --align optimal -- "$RootDisk" \
|
||||||
|
mklabel gpt \
|
||||||
|
mkpart primary 1MiB 100MiB \
|
||||||
|
mkpart primary 100MiB -2048s \
|
||||||
|
set 1 esp
|
||||||
|
#mkfs.vfat -F 32 -n "EFI" "$RootPart"
|
||||||
|
#mkfs.btrfs -L "System" "$RootPart"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_luks() {
|
||||||
|
if [[ "$DEBUG" ]]; then
|
||||||
|
local cmd="echo"
|
||||||
|
else
|
||||||
|
local cmd=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
${cmd} cryptsetup --cipher aes-xts-plain64 --hash sha512 --use-random --verify-passphrase luksFormat "$RootPart"
|
||||||
|
${cmd} cryptsetup luksOpen "$RootPart" luksvol
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepare_format() {
|
||||||
|
if [[ "$DEBUG" ]]; then
|
||||||
|
local cmd="echo"
|
||||||
|
else
|
||||||
|
local cmd=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Formatting EFI: $EFIPart"
|
||||||
|
${cmd} mkfs.fat -F32 -n "EFI" "$EFIPart"
|
||||||
|
|
||||||
|
if [[ "$BootPart" != "@boot" ]]; then
|
||||||
|
echo "Formatting Boot: $BootPart"
|
||||||
|
${cmd} mkfs.ext4 -FF -L "Boot" "$BootPart"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$ENCRYPTION" ]]; then
|
||||||
|
echo "Formatting Root: /dev/mapper/luksvol"
|
||||||
|
${cmd} mkfs.btrfs -L "System" /dev/mapper/luksvol
|
||||||
|
else
|
||||||
|
echo "Formatting Root: $RootPart"
|
||||||
|
${cmd} mkfs.btrfs -L "System" "$RootPart"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_subvolumes() {
|
||||||
|
local -a subvols=("@")
|
||||||
|
|
||||||
|
if [[ "$DEBUG" ]]; then
|
||||||
|
local cmd="echo"
|
||||||
|
else
|
||||||
|
local cmd=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$BootPart" == "@boot" ]]; then
|
||||||
|
subvols+=("@boot")
|
||||||
|
fi
|
||||||
|
|
||||||
|
subvols+=("@swap")
|
||||||
|
subvols+=("${!SUBVOLS_DEFAULT[@]}")
|
||||||
|
|
||||||
|
mkdir -p /mnt/btrfs
|
||||||
|
if [[ "$ENCRYPTION" ]]; then
|
||||||
|
${cmd} mount "/dev/mapper/luksvol" /mnt/btrfs
|
||||||
|
else
|
||||||
|
${cmd} mount "$RootPart" /mnt/btrfs
|
||||||
|
fi
|
||||||
|
|
||||||
|
for subvol in "${subvols[@]}"
|
||||||
|
do
|
||||||
|
${cmd} btrfs subvolume create /mnt/btrfs/"$subvol"
|
||||||
|
done
|
||||||
|
|
||||||
|
${cmd} umount /mnt/btrfs
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_hibernate_size() {
|
||||||
|
free --giga | awk '/^Mem:/{print $2}'
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepare_target() {
|
||||||
|
local subvol
|
||||||
|
local rootmount
|
||||||
|
local compopt
|
||||||
|
|
||||||
|
if [[ "$DEBUG" ]]; then
|
||||||
|
local cmd="echo"
|
||||||
|
else
|
||||||
|
local cmd=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
${cmd} mkdir /mnt/gentoo
|
||||||
|
|
||||||
|
if [[ "$ENCRYPTION" ]]; then
|
||||||
|
rootmount="/dev/mapper/luksvol"
|
||||||
|
else
|
||||||
|
rootmount="$RootPart"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$COMPRESSION" ]]; then
|
||||||
|
compopt=",compress=zstd:3"
|
||||||
|
|
||||||
|
${cmd} mount -o noatime,space_cache=v2${compopt},ssd,subvol=@ "$rootmount" /mnt/gentoo
|
||||||
|
|
||||||
|
for subvol in "${!SUBVOLS_DEFAULT[@]}"
|
||||||
|
do
|
||||||
|
${cmd} mkdir -p /mnt/gentoo/"${SUBVOLS_DEFAULT[$subvol]}"
|
||||||
|
done
|
||||||
|
|
||||||
|
${cmd} mkdir -p /mnt/gentoo/boot
|
||||||
|
if [[ "$BootPart" == "@boot" ]]; then
|
||||||
|
${cmd} mount -o noatime,space_cache=v2,ssd,subvol=@boot "$rootmount" /mnt/gentoo/boot
|
||||||
|
else
|
||||||
|
${cmd} mount "$BootPart" /tamnt/gentooget/boot
|
||||||
|
fi
|
||||||
|
|
||||||
|
for subvol in "${!SUBVOLS_DEFAULT[@]}"
|
||||||
|
do
|
||||||
|
${cmd} mount -o noatime,space_cache=v2,ssd,subvol="$subvol" "$rootmount" /mnt/gentoo/"${SUBVOLS_DEFAULT[$subvol]}"
|
||||||
|
done
|
||||||
|
|
||||||
|
${cmd} mkdir -p /mnt/gentoo/efi
|
||||||
|
${cmd} mount "$EFIPart" /mnt/gentoo/efi
|
||||||
|
|
||||||
|
${cmd} mkdir -p /mnt/gentoo/swap
|
||||||
|
${cmd} mount -o noatime,ssd,subvol=@swap "$rootmount" /mnt/gentoo/swap
|
||||||
|
|
||||||
|
if [[ "$SWAP" ]]; then
|
||||||
|
#${cmd} mkdir -p /mnt/gentoo/swap
|
||||||
|
#${cmd} mount -o noatime,ssd,subvol=@swap "$rootmount" /mnt/gentoo/swap
|
||||||
|
${cmd} btrfs filesystem mkswapfile --size "$(get_hibernate_size)g" --uuid clear /mnt/gentoo/swap/hibernate.swp
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function stage_step() {
|
||||||
|
local UUID PART_ENTRY_UUID
|
||||||
|
local SwapUUID SwapOffset
|
||||||
|
|
||||||
|
if [[ "$DEBUG" ]]; then
|
||||||
|
local cmd="echo"
|
||||||
|
else
|
||||||
|
local cmd=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$DEBUG" ]]; then
|
||||||
|
echo "genfstab -U /mnt/gentoo >> /mnt/gentoo/etc/fstab"
|
||||||
|
else
|
||||||
|
genfstab -U /mnt/gentoo >> /mnt/gentoo/etc/fstab
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$ENCRYPTION" ]]; then
|
||||||
|
eval "$(blkid -p --output export "$RootPart" | grep UUID)"
|
||||||
|
if [[ "$DEBUG" ]]; then
|
||||||
|
echo "echo \"luksvol UUID=$UUID none luks\" >> /mnt/gentoo/etc/crypttab"
|
||||||
|
else
|
||||||
|
echo "luksvol UUID=$UUID none luks" >> /mnt/gentoo/etc/crypttab
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$SWAP" ]]; then
|
||||||
|
if [[ "$DEBUG" ]]; then
|
||||||
|
echo "echo \"/swap/hibernate.swp none swap defaults 0 0\" >> /mnt/gentoo/etc/fstab"
|
||||||
|
else
|
||||||
|
echo "/swap/hibernate.swp none swap defaults 0 0" >> /mnt/gentoo/etc/fstab
|
||||||
|
fi
|
||||||
|
SwapUUID=$(grep btrfs /mnt/gentoo/etc/fstab | head -n1 | cut -f1)
|
||||||
|
SwapOffset=$(btrfs inspect-internal map-swapfile -r /mnt/gentoo/swap/hibernate.swp)
|
||||||
|
${cmd} sed -i "s/^#GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"resume=${SwapUUID} resume_offset=${SwapOffset}\"/g" /mnt/gentoo/etc/default/grub
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function show_options() {
|
||||||
|
echo "System Disk: $RootDisk"
|
||||||
|
echo "Root Partition: $RootPart"
|
||||||
|
echo "Boot Partition: $BootPart"
|
||||||
|
echo "EFI Partition: $EFIPart"
|
||||||
|
|
||||||
|
if [[ "$INSTALL_MODE" == "stage" ]]; then
|
||||||
|
echo "Install Mode: Stage"
|
||||||
|
echo "STAGE File: $INSTALL_STAGE"
|
||||||
|
elif [[ "$INSTALL_MODE" == "clean" ]]; then
|
||||||
|
echo "Install Mode: Clean"
|
||||||
|
else
|
||||||
|
echo "Install Mode: Normal"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$ENCRYPTION" ]]; then
|
||||||
|
echo "Encryption: Enabled"
|
||||||
|
else
|
||||||
|
echo "Encryption: Disabled"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$COMPRESSION" ]]; then
|
||||||
|
echo "Compression: Enabled"
|
||||||
|
else
|
||||||
|
echo "Compression: Disabled"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$SWAP" ]]; then
|
||||||
|
echo "Swap: Enabled"
|
||||||
|
else
|
||||||
|
echo "Swap: Disabled"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$DEBUG" ]]; then
|
||||||
|
echo "Debug: Enabled"
|
||||||
|
else
|
||||||
|
echo "Debug: Disabled"
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
function install_prep() {
|
||||||
|
show_options
|
||||||
|
|
||||||
|
read -rsn1 -p"Preparation: To proceed, press enter to continue." proceed
|
||||||
|
echo
|
||||||
|
if [[ "$proceed" != "" ]]; then
|
||||||
|
echo "Aborting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Creating Partitions on ${RootDisk}..."
|
||||||
|
prepare_disk
|
||||||
|
|
||||||
|
if [[ "$ENCRYPTION" ]]; then
|
||||||
|
echo
|
||||||
|
echo "Initiallizing LUKSv2 on ${RootPart}:"
|
||||||
|
create_luks
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Formatting Filesystems..."
|
||||||
|
prepare_format
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Preparing Subvolumes..."
|
||||||
|
create_subvolumes
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Preparing Installation Target..."
|
||||||
|
prepare_target
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Installation is ready and mounted in /mnt/gentoo for stage3 or stage4 install"
|
||||||
|
echo "Please verify all went well, and re-run this script with --stage <stagefile>"
|
||||||
|
echo "as appropriate, to continue."
|
||||||
|
}
|
||||||
|
|
||||||
|
function install_stage() {
|
||||||
|
show_options
|
||||||
|
|
||||||
|
read -rsn1 -p"Stage-Installation: To proceed, press enter to continue." proceed
|
||||||
|
echo
|
||||||
|
|
||||||
|
if [[ "$proceed" != "" ]]; then
|
||||||
|
echo "Aborting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Running Stage-Mode Installation Steps..."
|
||||||
|
stage_step
|
||||||
|
}
|
||||||
|
|
||||||
|
function install_cleanup() {
|
||||||
|
show_options
|
||||||
|
|
||||||
|
echo "!!!WARNING!!! This is about to destructively wipe ${RootDisk}!"
|
||||||
|
read -rsn -p"Enter YES to continue." proceed
|
||||||
|
echo
|
||||||
|
if [[ "${proceed,,}" != "yes" ]]; then
|
||||||
|
echo "Aborting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$DEBUG" ]]; then
|
||||||
|
local cmd="echo"
|
||||||
|
else
|
||||||
|
local cmd=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
for subvol in "${!SUBVOLS_DEFAULT[@]}"
|
||||||
|
do
|
||||||
|
${cmd} umount /mnt/gentoo/"${SUBVOLS_DEFAULT[$subvol]}"
|
||||||
|
done
|
||||||
|
|
||||||
|
${cmd} umount /mnt/gentoo/efi
|
||||||
|
${cmd} umount /mnt/gentoo/boot
|
||||||
|
${cmd} umount /mnt/gentoo/swap
|
||||||
|
${cmd} umount /mnt/gentoo
|
||||||
|
|
||||||
|
if [[ "$ENCRYPTION" ]]; then
|
||||||
|
${cmd} cryptsetup luksClose luksvol
|
||||||
|
fi
|
||||||
|
|
||||||
|
${cmd} dd if=/dev/zero of="${RootDisk}" bs=1024 count=10
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare -a POSITIONAL_ARGS=()
|
||||||
|
declare INSTALL_MODE="normal"
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
-h|--help)
|
||||||
|
show_help
|
||||||
|
;;
|
||||||
|
-e|--encryption)
|
||||||
|
ENCRYPTION=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-c|--compression)
|
||||||
|
COMPRESSION=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-s|--swap)
|
||||||
|
SWAP=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-d|--debug)
|
||||||
|
DEBUG=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--stage)
|
||||||
|
INSTALL_MODE=stage
|
||||||
|
INSTALL_STAGE=$1
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--clean)
|
||||||
|
INSTALL_MODE=clean
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
POSITIONAL_ARGS+=("$1") # save positional arg
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters
|
||||||
|
|
||||||
|
RootDisk="$1"
|
||||||
|
|
||||||
|
if [[ ! -b "$RootDisk" ]]; then
|
||||||
|
echo "ERROR: Invalid parameters. See --help for help"
|
||||||
|
exit 3
|
||||||
|
elif
|
||||||
|
if [[ "$ENCRYPTION" ]]; then
|
||||||
|
diskdev="${RootDisk##*/}"
|
||||||
|
if [[ "$diskdev" =~ ^nvme.* ]]; then
|
||||||
|
RootPart="${RootDisk}p3"
|
||||||
|
BootPart="${RootDisk}p2"
|
||||||
|
EFIPart="${RootDisk}p1"
|
||||||
|
else
|
||||||
|
RootPart="${RootDisk}3"
|
||||||
|
BootPart="${RootDisk}2"
|
||||||
|
EFIPart="${RootDisk}1"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
BootPart="@boot"
|
||||||
|
if [[ "$diskdev" =~ ^nvme.* ]]; then
|
||||||
|
RootPart="${RootDisk}p2"
|
||||||
|
EFIPart="${RootDisk}p1"
|
||||||
|
else
|
||||||
|
RootPart="${RootDisk}2"
|
||||||
|
EFIPart="${RootDisk}1"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$INSTALL_MODE" in
|
||||||
|
normal) install_prep;;
|
||||||
|
stage) install_stage;;
|
||||||
|
clean) install_cleanup;;
|
||||||
|
*)
|
||||||
|
echo "Error, unknown installation mode detected."
|
||||||
|
exit 3
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
Loading…
Reference in a new issue