#! /usr/bin/env bash FILE="$(realpath "${BASH_SOURCE[0]}")" DIRECTORY="$(dirname "${FILE}")" ROOT="$(dirname "${DIRECTORY}")" [ -d "${ROOT}" ] || exit 1 PROJECT="$(basename "${DIRECTORY}")" function get_path_mount { stat --format '%m' "${1}" } function get_mount_uuid { findmnt --noheadings --output 'UUID' "${1}" } function get_path_uuid { local tmp="$(get_path_mount "${1}")" get_mount_uuid "${tmp}" } ESP="$(get_path_uuid "${ROOT}")" if [ "${1}" ] ; then DATA="$(get_path_uuid "${1}")" else DATA="${ESP}" fi PGP_PUB='312ACDF9BB03C81ADE95B9C09C7613450C80C24F' function sign { if [ -d "${1}" ] ; then local file local files readarray -t files <<< "$(find "${1}" -type f | sort)" echo echo "${1}" for file in "${files[@]}" ; do sign "${file}" "${1}" done fi if [ -f "${1}" ] ; then if [ "${2}" ] ; then echo "$(realpath --relative-to "${2}" "${1}")" else echo "${1}" fi gpg \ --quiet \ --default-key "${PGP_PUB}!" \ --detach-sign \ "${1}" fi } NAME="$(basename "${FILE}")" PREVIOUS="${PWD}" cd "${DIRECTORY}" # imports ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ source "${NAME%.*}.mod" # variables ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ MEMDISK_ROOT='boot' MEMDISK_DIRECTORY="${MEMDISK_ROOT}/grub" MEMDISK_FILE="${MEMDISK_DIRECTORY}/grub.cfg" MEMDISK_ARCHIVE="${MEMDISK_ROOT}.tar" UEFI_ROOT="${ROOT}/efi" UEFI_DIRECTORY="${UEFI_ROOT}/boot" UEFI_CORE="${UEFI_DIRECTORY}/core.efi" UEFI_FILE="${UEFI_DIRECTORY}/bootx64.efi" UEFI_GRUB="${UEFI_DIRECTORY}/grubx64.efi" SIGNED_GRUB='/usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed' SIGNED_SHIM='/usr/lib/shim/shimx64.efi.signed' BIOS_BOOT='/usr/lib/grub/i386-pc/boot.img' BIOS_DIRECTORY="${ROOT}/bios" BIOS_FILE="${BIOS_DIRECTORY}/core.img" BIOS_SETUP="${BIOS_DIRECTORY}/setup.sh" COMPRESSION='xz' BOOT_ROOT="${ROOT}/boot" GRUB_ROOT="${BOOT_ROOT}/grub" GRUB_CFG="${GRUB_ROOT}/grub.cfg" GRUB_CFG_SH="${DIRECTORY}/grub.cfg.sh" GRUBENV="${GRUB_ROOT}/grubenv" GRUB_ENV="${ROOT}/grub.env" GRUB_FONTS="${GRUB_ROOT}/fonts" GRUB_HEAD='# GRUB Environment Block' GRUB_LOCALES="${GRUB_ROOT}/locale" GRUB_PUB="${GRUB_ROOT}/grub.pgp" GRUB_SHIGNED="${DIRECTORY}/grubx64.efi.signed.sh" GRUB_THEMES="${GRUB_ROOT}/themes" # wipe ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ echo -n " → ${MEMDISK_ROOT} → ${UEFI_ROOT} → ${BIOS_DIRECTORY} " rm --force --recursive \ "${MEMDISK_ROOT}" "${UEFI_ROOT}" "${BIOS_DIRECTORY}" # memdisk ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ echo -n " → ${MEMDISK_DIRECTORY} " mkdir --parents "${MEMDISK_DIRECTORY}" echo -n " → ${MEMDISK_FILE} " echo -n "\ # header " > "${MEMDISK_FILE}" echo -n " ↙ ${GRUB_SHIGNED} ↘ ${MEMDISK_FILE} " cat "${GRUB_SHIGNED}" >> "${MEMDISK_FILE}" echo -n " → ${MEMDISK_FILE} " echo -n "\ # footer " >> "${MEMDISK_FILE}" echo -n " ↙ ${MEMDISK_ROOT} ↘ ${MEMDISK_ARCHIVE} " tar --create --auto-compress \ --file "${MEMDISK_ARCHIVE}" "${MEMDISK_ROOT}" # uefi ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ echo -n " → ${UEFI_DIRECTORY} " mkdir --parents "${UEFI_DIRECTORY}" echo -n " ↙ ${MEMDISK_ARCHIVE} ↘ ${UEFI_FILE} " grub-mkimage \ --compress "${COMPRESSION}" \ --memdisk "${MEMDISK_ARCHIVE}" \ --format 'x86_64-efi' \ --output "${UEFI_FILE}" \ "${MODULES[@]}" if [ -f "${SIGNED_SHIM}" ] ; then echo -n " ↙ ${UEFI_FILE} ↘ ${UEFI_GRUB} " mv "${UEFI_FILE}" "${UEFI_GRUB}" echo -n " ↙ ${SIGNED_SHIM} ↘ ${UEFI_FILE} " cp "${SIGNED_SHIM}" "${UEFI_FILE}" fi if [ -f "${SIGNED_GRUB}" ] ; then echo -n " ↙ ${UEFI_GRUB} ↘ ${UEFI_CORE} " mv "${UEFI_GRUB}" "${UEFI_CORE}" echo -n " ↙ ${SIGNED_GRUB} ↘ ${UEFI_GRUB} " cp "${SIGNED_GRUB}" "${UEFI_GRUB}" fi # bios ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ echo -n " → ${BIOS_DIRECTORY} " mkdir "${BIOS_DIRECTORY}" echo -n " ↙ ${BIOS_BOOT} ↘ ${BIOS_DIRECTORY} " cp "${BIOS_BOOT}" "${BIOS_DIRECTORY}" echo -n " ↙ ${MEMDISK_ARCHIVE} ↘ ${BIOS_FILE} " grub-mkimage \ --compress "${COMPRESSION}" \ --memdisk "${MEMDISK_ARCHIVE}" \ --format 'i386-pc' \ --output "${BIOS_FILE}" \ "${MODULES[@]}" "${MODULES_BIOS[@]}" echo -n " → ${BIOS_SETUP} " echo -n '#! /usr/bin/env bash FILE="$(realpath "${BASH_SOURCE[0]}")" DIRECTORY="$(dirname "${FILE}")" /usr/lib/grub/i386-pc/grub-bios-setup \ --directory "${DIRECTORY}" \ "${1}" ' >> "${BIOS_SETUP}" # grub ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ echo -n " → ${GRUB_ROOT} " rm --force --recursive "${GRUB_ROOT}" mkdir --parents "${GRUB_ROOT}" # grub / cfg ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ echo -n " ↙ ${GRUB_CFG_SH} ↘ ${GRUB_CFG} " cp "${GRUB_CFG_SH}" "${GRUB_CFG}" # grub / env ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ function write_env { local file="${1}" local kv="${2}" local text="${GRUB_HEAD} ${kv}" while [ ${#text} -lt 1024 ] ; do text="${text}#" done echo -n "${text}" > "${file}" } echo -n " → ${GRUBENV} → ${GRUB_ENV} " write_env "${GRUBENV}" "\ live_name=${PROJECT} data_uuid=${DATA} " write_env "${GRUB_ENV}" "\ grub_sleep=999 " # grub / fonts ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ echo -n " → ${GRUB_FONTS} " mkdir --parents "${GRUB_FONTS}" for font in $(find '/usr/share/grub' -type 'f' -name '*.pf2') ; do cp "${font}" "${GRUB_FONTS}" done # grub / themes ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ if cd '/usr/share/grub/themes' ; then echo -n " → ${GRUB_THEMES} " mkdir --parents "${GRUB_THEMES}" for theme in * ; do if [ -f "${theme}/theme.txt" ] ; then cp --recursive "${theme}" "${GRUB_THEMES}" fi done fi cd "${DIRECTORY}" # grub / locales ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ echo -n " → ${GRUB_LOCALES} " mkdir --parents "${GRUB_LOCALES}" cd '/usr/share/locale' for locale in * ; do file="${locale}/LC_MESSAGES/grub.mo" if [ -f "${file}" ] ; then cp "${file}" "${GRUB_LOCALES}/${locale}.mo" fi done cd "${DIRECTORY}" # grub / pubkey ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ echo -n " ↙ ${PGP_PUB} ↘ ${GRUB_PUB} " gpg --export "${PGP_PUB}" > "${GRUB_PUB}" # grub / modules ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ for target in 'x86_64-efi' 'i386-pc' ; do echo -n " ↙ /usr/lib/grub/${target} ↘ ${GRUB_ROOT}/${target} " mkdir --parents "${GRUB_ROOT}/${target}" cd "/usr/lib/grub/${target}" for module in *.lst *.mod ; do cp "${module}" "${GRUB_ROOT}/${target}" done done cd "${DIRECTORY}" # sign ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ sign "${BIOS_DIRECTORY}" sign "${UEFI_DIRECTORY}" sign "${ROOT}/${PROJECT}/live" sign "${GRUB_ROOT}" # display ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ echo du --human-readable --summarize \ "${BIOS_DIRECTORY}" \ "${UEFI_ROOT}" \ "${BOOT_ROOT}" \ "${ROOT}" echo echo "ESP: ${ESP}" echo "DATA: ${DATA}" # clean ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ rm --force --recursive \ "${MEMDISK_ARCHIVE}" \ "${MEMDISK_ROOT}" # back ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ cd "${PREVIOUS}"