#!/bin/bash # Copyright (C) 2016-2018 Iru Cai # SPDX-License-Identifier: GPL-3.0-or-later set -e DISTROLIST=() ISOLIST=() BOOTPATH= ROOTPATH= DEVNAME= KERNELDIR= DATADIR= INSTALL_GRUB=1 GRUBCFG_ONLY=0 DOWNLOAD_ONLY=0 . functions.sh msg() { echo -e "$1" >&2 } fatalerror() { msg "\x1b[1;31m$1\x1b[0m" exit 1 } usage() { >&2 cat << EOF $0 [--root ] [options] [distro 1] [distro 2] ... use $0 -L to list available distros options: --root --root=: set the path to put the live USB data files --boot --boot=: set the path to put the kernel and loader files --no-grub: do not install GRUB loader (still generate grub.cfg) --grubcfg: do not do real install, only generate grub.cfg file --downloadonly: only download the ISO files --dev=: write boot sector to (default is autodetected from ) EOF } unset ISOPATH CFGFILE="$HOME/.liveusb-builder" test -f "$CFGFILE" && source "$CFGFILE" || true ISOPATH=${ISOPATH:-"$HOME/isofiles"} while [[ -n "$1" ]] do case "$1" in -L) exec ./listisos.sh ;; --boot=*) BOOTPATH="${1/--boot=}" ;; --boot) shift BOOTPATH="$1" ;; --root=*) ROOTPATH="${1/--root=}" ;; --root) shift ROOTPATH="$1" ;; --dev=*) DEVNAME=${1/--dev=} ;; --no-grub) INSTALL_GRUB=0 ;; --grubcfg) GRUBCFG_ONLY=1 ;; --downloadonly) DOWNLOAD_ONLY=1 ;; *=*|-*) usage exit 1 ;; *) if [ -f "distro/$1/isoinfo" ] then DISTROLIST=(${DISTROLIST[@]} "$1") else fatalerror "directory distro/$1/isoinfo not found" fi ;; esac shift done if [[ -z "$ROOTPATH" && "$DOWNLOAD_ONLY" == 0 ]]; then usage exit 1 fi if [[ -z "$BOOTPATH" ]]; then BOOTPATH="$ROOTPATH" fi if [[ "$DOWNLOAD_ONLY" == 0 ]]; then UUID="$(findmnt -o UUID --raw --noheadings $ROOTPATH \ || fatalerror "UUID of $ROOTPATH not found, not a mountpoint?")" BOOTPART="$(findmnt -o SOURCE --raw --noheadings $BOOTPATH \ || fatalerror "$BOOTPATH seems not a mountpoint!")" # liveusb kernel and data should be placed on one disk # so get DEVNAME by the mountpoint of ROOTPATH is ok DEVNAME="/dev/$(getdiskbypart "/dev/disk/by-uuid/$UUID")" KERNELDIR="$BOOTPATH/liveusb-kernel" DATADIR="$ROOTPATH/liveusb-data" GRUBCFG="$BOOTPATH/grub/grub.cfg" SYSLINUXCFG="$BOOTPATH/syslinux/syslinux.cfg" install -d "$BOOTPATH/grub" "$BOOTPATH/syslinux" install -d "$KERNELDIR" "$DATADIR" msg "Files will be copy to $ROOTPATH" fi if [[ "${#DISTROLIST[@]}" == 0 ]]; then usage exit 1 fi if [ ! -z "$DEVNAME" ]; then msg "Boot sector will be written to $DEVNAME" fi for i in ${DISTROLIST[@]} do process_isoinfo "$i" ISOLIST=("${ISOLIST[@]}" "$ISOFILE") ISONAMELIST=("${ISONAMELIST[@]}" "$ISONAME") if [ -f "$ISOPATH/$ISOFILE" ] && checksum_verify; then true else download_iso fi done if [[ "$DOWNLOAD_ONLY" == 1 ]]; then exit 0 fi grubcfg_header > "$GRUBCFG" syslinux_header > "$SYSLINUXCFG" for i in `seq 1 ${#DISTROLIST[@]}` do ISOFILE="${ISOLIST[$i-1]}" ISONAME="${ISONAMELIST[$i-1]}" DISTRO="${DISTROLIST[$i-1]}" process_distro "$DISTRO" if [ "$GRUBCFG_ONLY" == 0 ]; then install_live fi gen_grubcfg "$DISTRO" >> "$GRUBCFG" gen_syslinux "$DISTRO" >> "$SYSLINUXCFG" done if [ "$GRUBCFG_ONLY" == 1 ]; then msg 'Only generate grub.cfg and syslinux.cfg, will not install bootloader.' elif [ "$INSTALL_GRUB" == 1 ]; then read -p 'Answer Y to install bootloader.[Y/n] ' if [[ "$REPLY" =~ ^[Yy]|^$ ]]; then if ! as-root ./install_syslinux "$DEVNAME" "$BOOTPART" "$BOOTPATH"; then msg 'Failed to install syslinux, try to install GRUB as legacy BIOS bootloader.' as-root grub-install --force --boot-directory="$BOOTPATH" --target=i386-pc "$DEVNAME" fi as-root grub-install --boot-directory="$BOOTPATH" --efi-directory="$BOOTPATH" --bootloader-id=grub --target=x86_64-efi --removable --no-nvram "$DEVNAME" fi fi