#!/usr/bin/env bash # -*- coding: utf-8 -*- # region header # Copyright Torben Sickert (info["~at~"]torben.website) 29.10.2015 # Janosch Dobler (info["~at~"]jandob.com) 29.10.2015 # Jonathan Bauer (jonathan.bauer@rz.uni-freiburg.de) 19.09.2019 # License # ------- # This library written by Torben Sickert and Janosch Dobler stand under a # creative commons naming 3.0 unported license. # see http://creativecommons.org/licenses/by/3.0/deed.de ## endregion # I think this are the same... declare -rg _root_dir="$(readlink -f $(dirname ${BASH_SOURCE[0]}))" declare -rg _repo_dir="${_root_dir}" file_path='/boot/initramfs.img' dracut_parameter=(--force --no-hostonly) verbose='no' debug='no' target='' cleanup='no' full_cleanup='no' use_systemd_in_initramfs='no' print_help_message() { echo "help" } parse_command_line() { while true; do case "$1" in -h|--help) shift print_help_message "$0" exit 0 ;; -v|--verbose) shift verbose='yes' ;; -d|--debug) shift debug='yes' ;; -p|--file-path) local given_argument="$1" shift file_path="$1" if [[ "$file_path" == '' ]]; then echo \ "Error with given option \"$given_argument\": This option needs a path to save initramfs image to." return 1 fi shift ;; -c|--cleanup) shift cleanup='yes' ;; -f|--full-cleanup) shift full_cleanup='yes' ;; -s|--use-systemd-in-initramfs) shift use_systemd_in_initramfs='yes' ;; -t|--target) local given_argument="$1" shift target="$1" if [[ "$target" == '' ]]; then echo \ "Error with given option \"$given_argument\": This option needs a path create initramfs from." return 1 fi shift ;; -i|--init) shift initialize='yes' ;; -k|--kernel-version) local given_argument="$1" shift kernel_version="$1" if [ -z "$kernel_version" ]; then echo \ "Error with given option \"$given_argument\": This option needs a kernel version to build the initramfs for." return 1 fi shift ;; -H|--kernel-headers) local given_argument="$1" shift kernel_headers="$1" if [ -z "$kernel_headers" ]; then echo \ "Error with given option \"$given_argument\": This option needs the path to the kernel headers." return 1 fi shift ;; -q|--qcow-handler) local given_argument="$1" shift qcow_handler="$1" if [ -z "$qcow_handler" ]; then echo \ "Error with given option \"$given_argument\": This options needs to be either 'xmount' or 'kernel'." return 1 fi shift ;; -u|--update) shift update='yes' ;; -) shift while [[ "$1" =~ ^.+$ ]]; do dracut_parameter+=("$1") shift done ;; '') break ;; *) echo \ "Error with given option \"$1\": This argument is not available." return 1 esac done return 0 } ## endregion ## region helper initialize_dracut() { pushd "${_root_dir}/dracut" # NOTE: On virtualbox shared folder symlinks are not allowed. # NOTE: make the dracut-install binary (dracut-install resolves # dependencies etc.) echo 'Compiling dracut.' ./configure make install/dracut-install # NOTE: We have to copy the binary to current instead of symlinking # them since this feature isn't supported in shared virtual box machine # folders. # If symlinks would be available we could simply use: # >>> make dracut-install popd cp "${_root_dir}/dracut/install/dracut-install" \ "${_root_dir}/dracut/dracut-install" return $? } # The idea here was to source each module-setup.sh from our # custom dracut modules and call their clean() function. # TODO: Does this still work? cleanup() { local plugin_path plugin_path="${_root_dir}/modules.d/dnbd3-rootfs" source "${plugin_path}/module-setup.sh" moddir="$(cd "$plugin_path" &>/dev/null && pwd)" clean return $? } main() { if ! parse_command_line "$@"; then print_help_message "$0" exit 1 fi # if no kernel was specified as dracut argument, use the running kernel's version echo "Building for:" if [ -z "$kernel_version" ]; then kernel_version="$(uname -r)" fi echo " * kernel version: $kernel_version" # similar for kernel headers needed to compile dnbd3 against. if [ -z "$kernel_headers" ]; then kernel_headers="/lib/modules/${kernel_version}/build" fi if [ ! -f "${kernel_headers}/Makefile" ]; then echo 'Missing core dependency "linux-headers" for version to compile against given or current kernel.' fi echo " * kernel headers: $kernel_headers" [ -n "$qcow_handler" ] && echo " * qcow2 handler: $qcow_handler" export _QCOW_HANDLER="$qcow_handler" if [ "$update" == "yes" ]; then pushd "${_repo_dir}" git pull popd fi echo 'Checking dracut...' if [[ ! -f "${_root_dir}/dracut/dracut-install" ]]; then echo "Dracut isn't available yet loading it." initialize_dracut fi for _dracut_module_dir in "${_repo_dir}/modules.d/"*; do [ -d "${_dracut_module_dir}" ] || continue _dracut_module="$(basename $_dracut_module_dir)" # TODO allow module-specific priority _dracut_module_target="${_root_dir}/dracut/modules.d/00${_dracut_module}" if [[ ! -L "$_dracut_module_target" || "$(readlink \ "$_dracut_module_target")" != "$_dracut_module_dir" ]]; then echo \ "Link ${_dracut_module} plugin into dracut modules folder ($_dracut_module_dir -> $_dracut_module_target)." if ! ln --symbolic --force "$_dracut_module_dir" "$_dracut_module_target"; then echo \ "Linking \"$_dracut_module_dir\" to \"$_dracut_module_target\" failed." \ " We will copy them. So we have to recopy it every time to ensure that recompiled things take effect." cp --recursive --force --no-target-directory \ "$_dracut_module_dir" \ "$_dracut_module_target" fi fi done _loglevel='' if [ "$verbose" == 'yes' ]; then _loglevel='--verbose' fi _modules=(dnbd3-rootfs conf-tgz) echo "Default modules: ${_modules[@]}" if [ "$debug" == 'yes' ]; then _loglevel="$_loglevel --stdlog 4" _modules+=(i18n terminfo) fi if [ "$use_systemd_in_initramfs" == 'yes' ]; then _modules+=(systemd systemd-initrd dracut-systemd) fi # Preprocess done - start build, cleanup or full cleanup if [[ "$full_cleanup" == 'yes' ]]; then echo 'Removing all modules.' rm "${_repo_dir}" "${_root_dir}/dracut" --recursive --force elif [[ "$cleanup" == 'yes' ]]; then echo 'Removing distribution specific files.' cleanup else . "${_repo_dir}/modules.d/dnbd3-rootfs/helper/build.inc" build_initialize_components if [[ "$initialize" == 'yes' ]]; then echo "Initialized." exit 0 fi echo 'Build initramfs.' "${_root_dir}/dracut/dracut.sh" --local \ $_loglevel --modules "${_modules[*]}" --conf /etc/dracut.conf \ --confdir /etc/dracut.conf.d "${dracut_parameter[@]}" \ --kver "${kernel_version}" "$file_path" _return_code=$? if [ "$_return_code" != 0 ]; then echo 'Building initial ram file system failed.' exit 1 fi # NOTE: dracut generate the initramfs with 0600 permissions chmod 0644 "${file_path}" fi } main "$@"