#!/bin/bash set -eu grub_destination="" grub_binary="" rootfs_destination="" rootfs_targz="" drive="" function unmount_drives(){ echo "Checking if drives are mounted from $1" mounts=$(mount | grep $1 | awk '{print $3}') for i in $mounts; do echo unmounting $i umount $i done } function deploy_installer() { rootfs_dest="$1" this_script=$(readlink -f $0) mkdir -p "$rootfs_dest/usr/bin" cp "$this_script" "$rootfs_dest/usr/bin/" } function deploy_rootfs_targz(){ rootfs_destination="$1" rootfs_targz="$2" echo "Deploying tar.gz" echo "Generate random name" mount_dir="/tmp/$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)" echo "Create mount folder" mkdir -p "$mount_dir" echo "Mount drive to mount folder" mount "$rootfs_destination" "$mount_dir" echo "Clean up mounted folder" rm -rf "$mount_dir"/* echo "Untar archive to destination folder" tar -zvxf "$rootfs_targz" -C "$mount_dir" deploy_installer "$mount_dir" echo "Cleanup" umount "$mount_dir" rm -rf "$mount_dir" echo "rootfs deployment done!" } function deploy_grub(){ grub_destination="$1" grub_binary="$2" rootfs_destination="$3" echo "Deploying grub" echo "Generate random name" mount_dir="/tmp/$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)" echo "Create mount folder" mkdir -p "$mount_dir" echo "Mount drive to mount folder" mount "$grub_destination" "$mount_dir" echo "Create grub path" mkdir -p "$mount_dir"/EFI/boot/ echo "Copy the grub binary" cp "$grub_binary" "$mount_dir"/EFI/boot/bootx64.efi rootfs_uuid=$(ls -l /dev/disk/by-partuuid/ | grep $(basename "$rootfs_destination") | awk '{print $9}') echo "setting root in grub.cfg to: $rootfs_uuid" echo "Create grub.cfg" cat< "$mount_dir"/EFI/boot/grub.cfg default=1 menuentry "Enea Linux - normal booting" { linux (hd0,gpt2)/boot/bzImage root=PARTUUID=${rootfs_uuid} ip=dhcp console=ttyS0,115200 earlyprintk=ttyS0,115200 } menuentry "Enea Linux - high performance booting" { linux (hd0,gpt2)/boot/bzImage root=PARTUUID=${rootfs_uuid} console=ttyS0,115200 earlyprintk=ttyS0,115200 ip=dhcp nohz_full=1-7 isolcpus=1-7 rcu-nocbs=1-7 rcu_nocb_poll intel_pstate=disable clocksource=tsc tsc=reliable nohpet nosoftlockup intel_idle.max_cstate=0 processor.max_cstate=0 mce=ignore_ce audit=0 nmi_watchdog=0 iommu=pt intel_iommu=on hugepagesz=1GB hugepages=8 default_hugepagesz=1GB hugepagesz=2M hugepages=2048 vfio_iommu_type1.allow_unsafe_interrupts=1 } EOT echo "Cleanup" umount "$mount_dir" rm -rf "$mount_dir" echo "grub deployment done!" } function format_drive(){ unmount_drives "$1" sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' << EOF | fdisk ${1} o # clear the in memory partition table g # GPT partition type n # new partition 1 # partition number 1 # default - start at beginning of disk +512M # 100 MB boot parttion t # change parition type 1 # set type to EFI System n # new partition 2 # partion number 2 # default, start immediately after preceding partition # default, extend partition to end of disk p # print the in-memory partition table w # write the partition table q # and we're done EOF sleep 1 unmount_drives "$1" mkfs.fat -F32 -nEFI "$1"1 unmount_drives "$1" yes | mkfs.ext2 -LROOT "$1"2 } function help(){ cat<" console is displayed: help - a guide on how to use the installer list-params - lists parameters list-steps - lists the available steps and the parameters that they depend on set - sets a parameter (e.g. "set drive=/dev/sda") clear - clears a parameter (e.g. "clear drive") list-partitions - lists current drives and partitions dry - describes the steps to be executed and checks if the files exist run - executes the steps q or quit - exits the script Run 'list-steps' to understand the built-in steps that the installer can execute and what parameters they depend on in order to be executed. Running 'list-steps' will print the following: 1. Format drive - Uses the drive set for the "drive" parameter to create a 512MB partition for GRUB and another partition for the rootfs. The rootfs partition will be as large as the physical media minus 512MB. Depends on the following parameter(s): drive= 2. GRUB install - Installs the binary pointed by "grub_binary" on the drive set in "grub_destination". A grub.cfg file will be created that will be configured to boot off of "rootfs_destination". Depends on the following parameters: grub_destination= grub_binary= rootfs_destination= 3. Root filesystem install - Copies the files found in "rootfs_targz" to the drive set in "rootfs_destination". Depends on the following parameters: rootfs_targz= rootfs_destination= A parameter can be set through the "set" command or cleared through "clear". As some parameters are common for multiple steps, like rootfs_destination is for the GRUB and rootfs installation steps, you can get a list of all the parameters, by running "list-params". The following parameters can be configured: grub_destination=[drive] - specifies the drive where GRUB will be installed grub_binary=[file] - points to the GRUB executable to be installed where grub_destination is set rootfs_destination=[drive] - specifies where the rootfs will be deployed rootfs_targz=[.tar.gz file] - what file to unpack to where rootfs_destination is set drive=[/dev/sdaX] - what drive to partition Before running the actual partitioning and copying, a dry run can be executed without affecting the actual layout of the physical media, by running the "dry" command. Example of partitioning a drive: set drive=/dev/sda run Example of partitioning a drive, installing GRUB and a root filesystem: set drive=/dev/sda set grub_destination=/dev/sda1 set grub_binary=/home/user/grub-binary.efi set rootfs_destination=/dev/sda2 set rootfs_targz=/home/user/rootfs.tar.gz run Example of deploying ONLY a root filesystem: set rootfs_destination=/dev/sda2 set rootfs_targz=/home/user/rootfs.tar.gz run EOH } function bye(){ echo "Exiting. Bye!" exit 0 } function list_part(){ fdisk -l | grep \/dev\/ } function list_params(){ echo " grub_destination=$grub_destination" echo " grub_binary=$grub_binary" echo " rootfs_destination=$rootfs_destination" echo " rootfs_targz=$rootfs_targz" echo " drive=$drive" } function clear_param(){ shift case "${1}" in grub_destination) grub_destination="" ;; grub_binary) grub_binary="" ;; rootfs_destination) rootfs_destination="" ;; rootfs_targz) rootfs_targz="" ;; drive) drive="" ;; *) echo "Unknown parameter: ${1}" >&2 esac } function set_param(){ shift case "${1}" in grub_destination=*) grub_destination="${1#*=}" ;; grub_binary=*) grub_binary="${1#*=}" ;; rootfs_destination=*) rootfs_destination="${1#*=}" ;; rootfs_targz=*) rootfs_targz="${1#*=}" ;; drive=*) drive="${1#*=}" ;; *) echo "Unknown parameter: ${1}" >&2 esac } function check_for_file() { if [ ! -e "$1" ]; then echo " Warning: $1 does not exist" fi } function list_steps() { cat< " line; do case $line in q) bye;; quit) bye;; list-partitions) list_part;; list-params) list_params;; set\ *) set_param $line;; clear\ *) clear_param $line;; help) help;; dry) run "dry-run";; run) run "run-it";; list-steps) list_steps;; *) echo "Unknown command $line" echo "Commands:" echo " help - guide on how to use the installer" echo " list-params - lists parameters" echo " list-steps - lists the available steps and the parameters that they depend on" echo " set - set a parameter (e.g. \"set drive=/dev/sda\")" echo " clear - clears a parameter (e.g. \"clear drive\")" echo " list-partitions - lists current drives and partitions" echo " dry - describes the steps to be executed and checks if the files exist" echo " run - executes the steps" echo " q or quit - exits the script" esac history -s "$line" echo "" done