diff options
Diffstat (limited to 'build-initramfs.sh')
-rwxr-xr-x | build-initramfs.sh | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/build-initramfs.sh b/build-initramfs.sh new file mode 100755 index 00000000..d1a8017f --- /dev/null +++ b/build-initramfs.sh @@ -0,0 +1,270 @@ +#!/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 "$@" |