#!/bin/bash # SPDX-License-Identifier: Unlicense echo_cyan() { echo -e "\033[0;36m$1\033[0m" } echo_blue() { echo -e "\033[0;34m$1\033[0m" } echo_yellow() { echo -e "\033[0;33m$1\033[0m" } echo_red() { echo -e "\033[0;31m$1\033[0m" } # TODO: prepare DTRFS to create initrd for other distros install_build_deps() { if grep "Arch Linux" /etc/os-release > /dev/null; then which wget fsarchiver cpio mkinitcpio || { echo_red "Please install build deps: wget fsarchiver cpio mkinitcpio" exit 1 } qemu_guest_modules="../arch_guest_mods" else echo_red "ArchLinux is the only distribution currently supported by DTRFS." exit 1 fi } create_dirs() { rm -rf "$ROOT" 2>/dev/null mkdir -p "${ROOT}/usr/bin" mkdir -p "${ROOT}/usr/lib/dtrfs" mkdir -p "${ROOT}/dev" mkdir -p "${ROOT}/etc" mkdir -p "${ROOT}/mnt" mkdir -p "${ROOT}/proc" mkdir -p "${ROOT}/run" mkdir -p "${ROOT}/sys" mkdir -p "${ROOT}/tmp" mkdir -p "${ROOT}/var" ln -s usr/bin "${ROOT}/bin" ln -s usr/bin "${ROOT}/sbin" ln -s usr/lib "${ROOT}/lib" ln -s usr/lib "${ROOT}/lib64" ln -s lib "${ROOT}/usr/lib64" ln -s bin "${ROOT}/usr/sbin" ln -s ../run "${ROOT}/var/run" } # Installs a library. Expects absolute path. install_dep() { local lib="$1" [[ -f "$lib" ]] || { echo "Did not find library at path: $lib" exit 1 } [[ -f "${ROOT}${lib}" ]] || { mkdir -p $(dirname "${ROOT}${lib}") echo_blue "Adding dependency: $lib" cp "$lib" "${ROOT}${lib}" } } # Expects to receive the absolute path as the full argument. # Use `which binary_name` if it's in your path. # Installs to /usr/bin install_binary() { local binary="$1" lib='' [[ -f "$binary" ]] || { echo_red "Did not find binary at path: $binary" exit 1 } echo_blue "Adding binary: $binary" cp "$binary" "${ROOT}/usr/bin/" ldd_deps="$(ldd "$binary")" if [[ $ldd_deps == *"not a dynamic executable"* ]]; then return 0 fi while read -r lib; do install_dep "$lib" done <<< "$( echo "$ldd_deps" | grep -F ' => ' | awk '{ print $3 }' )" } install_kmod() { echo_cyan "Installing kmod (depmod, insmod, lsmod, modinfo, modprobe, rmmod)..." install_binary /usr/bin/kmod || return 1 ln -s kmod "${ROOT}/usr/bin/lsmod" ln -s kmod "${ROOT}/usr/bin/rmmod" ln -s kmod "${ROOT}/usr/bin/insmod" ln -s kmod "${ROOT}/usr/bin/modinfo" ln -s kmod "${ROOT}/usr/bin/modprobe" ln -s kmod "${ROOT}/usr/bin/depmod" } install_busybox() { echo_cyan "Installing busybox..." [[ -f "$BUSYBOX_PATH" ]] || { echo_red "Did not find busybox at $BUSYBOX_PATH" echo_red "Please compile or download busybox. You can also change the path." exit 1 } install_binary "$BUSYBOX_PATH" || return 1 for applet in $($BUSYBOX_PATH --list); do ln -s busybox "${ROOT}/usr/bin/$applet" done } install_init_script() { cp ../init.sh "${ROOT}/init" cp ../init_functions.sh "${ROOT}/usr/lib/dtrfs/" cp ../install_os.sh "${ROOT}/usr/lib/dtrfs/" } install_module() { local module="$1" echo "modprobe $module" >> "${ROOT}/load_modules.sh" _install_module "$module" } _install_module() { local module="$1" depends='' dep='' filename='' filenames='' filenames="$( modinfo -k $KERNEL $module | grep '^filename:' | awk '{ print $2 }' )" [[ "$filenames" == "(builtin)" ]] && { echo_yellow "Module $module is builtin. Installation not needed." return 0 } while read -r filename; do [[ -z $filename ]] && continue install_dep "$filename" done <<< "$( echo "$filenames" )" depends="$( \ modinfo -k $KERNEL $module | grep '^depends:' | awk '{ print $2 }' | sed 's/,/\n/g'; modinfo -k $KERNEL $module | grep '^softdep:' | awk '{ print $3 }' )" while read -r dep; do [[ -z $dep ]] && continue _install_module "$dep" done <<< "$( echo "$depends" )" } install_guest_mods() { local mod='' echo_cyan "Installing kernel modules needed for QEMU guests..." while read -r mod; do [[ -z $mod ]] && continue _install_module "$mod" done <<< "$(cat "$qemu_guest_modules")" } backup_active_modules() { local modules='' mod='' echo_yellow "Installing to the initrd all kernel modules currently loaded..." modules="$(lsmod | awk '{ print $1 }' | grep -v Module)" while read -r mod; do [[ -z $mod ]] && continue _install_module "$mod" done <<< "$( echo "$modules" )" } scan_modules() { local drivers='' mod='' echo_yellow "Installing kernel modules based on current hardware..." install_module "$(df -T / | awk '{ print $2 }' | tail -1)" drivers=$(lshw -c disk 2>/dev/null | grep -oE 'driver=[a-z\_\-]+' | cut -d '=' -f2; lshw -c network 2>/dev/null | grep -oE 'driver=[a-z\_\-]+' | cut -d '=' -f2) while read -r mod; do [[ -z $mod ]] && continue _install_module "$mod" done <<< "$( echo "$drivers" )" } install_dtrfs_api() { local my_location="$(pwd)" echo_cyan "Building dtrfs_api..." cd ../../dtrfs_api && cargo build --release || { echo_yellow "Could not build dtrfs_api. Looking for binary at $(pwd)/dtrfs_api" } cd "$my_location" cp ../../dtrfs_api/target/release/dtrfs_api ./ install_binary "$(pwd)/dtrfs_api" } create_archive() { local archive="detee-$(hostnamectl hostname)-${KERNEL}.cpio.gz" echo_cyan "Creating archive $(pwd)/$archive" echo $archive > .archive_name my_location="$(pwd)" cd ${ROOT} find . | cpio -o -H newc | gzip \ > "${my_location}/detee-$(hostnamectl hostname)-${KERNEL}.cpio.gz" cd "$my_location" }