summaryrefslogtreecommitdiffstats
path: root/builder/build-initramfs.sh
diff options
context:
space:
mode:
Diffstat (limited to 'builder/build-initramfs.sh')
-rwxr-xr-xbuilder/build-initramfs.sh435
1 files changed, 44 insertions, 391 deletions
diff --git a/builder/build-initramfs.sh b/builder/build-initramfs.sh
index 9cf0b641..01d08059 100755
--- a/builder/build-initramfs.sh
+++ b/builder/build-initramfs.sh
@@ -3,28 +3,20 @@
# 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
-# This tool provides a generic way to install systemd based remote linux
-# initramfs.
-
-# Examples
-# --------
-
-# Start install progress command (Assuming internet is available):
-# >>> ./build-initramfs.sh
+## endregion
-# Note that you only get very necessary output until you provide "--verbose" as
-# commandline options.
declare -rg _root_dir="$(readlink -f $(dirname ${BASH_SOURCE[0]}))"
declare -rg _repo_dir="${_root_dir}/systemd-init.git"
declare -rg _git_source="git://git.openslx.org/openslx-ng/systemd-init.git"
declare -rg _git_branch="centos8"
+
## region ensure presence of needed dependencies
set -o errexit
if [ ! -e "$_repo_dir" ]; then
@@ -32,6 +24,7 @@ if [ ! -e "$_repo_dir" ]; then
if ! hash git; then
echo "Needed dependency \"git\" isn't available."
echo "Please install \"git\" or provide the main repository in \"${_repo_dir}\"."
+ exit 1
fi
git clone --branch "$_git_branch" --single-branch --depth 1 \
"$_git_source" "${_repo_dir}"
@@ -66,16 +59,7 @@ if [ ! -e "$_repo_dir" ]; then
fi
set +o errexit
## endregion
-# shellcheck source=./dnbd3-rootfs/scripts/rebash/core.sh
-source "${_repo_dir}/builder/modules.d/dnbd3-rootfs/scripts/rebash/core.sh"
-core.import exceptions
-core.import logging
-core.import utils
-core.import change_root
-# endregion
-# region properties
-# shellcheck disable=SC2034
-build_initramfs__doc_test_setup__='exceptions.activate'
+
file_path='/boot/initramfs.img'
dracut_parameter=(--force --no-hostonly)
verbose='no'
@@ -84,217 +68,12 @@ target=''
cleanup='no'
full_cleanup='no'
use_systemd_in_initramfs='no'
-# shellcheck disable=SC2034
-declare -A core_dependencies=(
- [cat]='print messages' \
- [cpio]='pack initramfs' \
- ['dhclient arping']='support network connection in resulting initramfs' \
- [dirname]='core logic' \
- [dmsetup]='create a (temporary) writable layer during boot' \
- [grep]='retrieve right boot partition during boot' \
- [mktemp]='create save temporary files and dictionaries' \
- [pkg-config]='retrieve information of installed development packages' \
- [tee]='read from standard input and write to standard output and files' \
- [readlink]="connect dracut module with dracut's module system" \
- [rm]='remove (temporary) files' \
- [shift]='parse command line' \
- [sed]='process strings' \
- ['cmake gcc make']='dynamically compile needed resources against current or given kernel')
-# shellcheck disable=SC2034
-declare -A optional_dependencies=(
- [chroot]='build against a distribution other than this program runs in' \
- ['curl git gzip tar']='dynamically retrieve and unpack missing application which will be compiled for current or given kernel' \
- ['mkfs.ext4 fsck']='support for persistent binary diffs in image files')
-# shellcheck disable=SC2034
-declare -A core_shared_library_pattern_dependencies=(
- [libz]='compile dnbd3 for given or current kernel')
-# shellcheck disable=SC2034
-declare -A optional_shared_library_pattern_dependencies=()
-# shellcheck disable=SC2034
-declare -A core_package_dependencies=()
-# shellcheck disable=SC2034
-declare -A optional_package_dependencies=(
- ['fuse glib-2.0 pixman-1']='support template systems in container (usually used by virtual runtime environments)')
-# endregion
-# region functions
-## region command line interface
-print_usage_message() {
- # shellcheck disable=SC2016,SC2034
- local __doc__='
- Prints a description about how to use this program.
-
- >>> print_usage_message &>/dev/null
- '
- logging.cat << EOF
-This program provides a generic way to install systemd based remote linux
-initramfs.
-EOF
-}
-print_usage_examples() {
- # shellcheck disable=SC2016,SC2034
- local __doc__='
- Prints a description about how to use this program by providing examples.
-
- >>> print_usage_examples &>/dev/null
- '
- logging.cat << EOF
-Start install progress:
->>> ./build_initramfs.sh
-EOF
-}
-print_command_line_option_description() {
- # shellcheck disable=SC2016,SC2034
- local __doc__='
- Prints descriptions about each available command line option.
-
- >>> print_command_line_option_description &>/dev/null
- '
- logging.cat << EOF
--h --help Shows this help message.
-
--v --verbose Tells you what is going on (default: "$verbose").
-
--d --debug Gives you any output from all tools which are used
- (default: "$debug").
-
--p --file-path Target location for initramfs file
- (default: "$file_path").
-
--c --cleanup Removes all distribution specific compiled files.
--f --full-cleanup Removes all retrieved and compiled files (usefull to retrieve latest version of all nested modules).
-
--t --target Creates an image against given target template filesystem. If not
- explicitly specified current system will be used as template system
- (default: "$target").
-
--i --init Initializes the various repositories and build the required
- dependencies but do not build the initramfs. Use this to accelerate
- subsequent calls of this script.
-
--k --kernel-version Creates an image for the given kernel version. Will
- require the presence of kernel headers for this version.
- (default: "$(uname -r)")
-
--s --use-systemd-in-initramfs Use Systemd as init process in initramfs
- (improved performance but less features)
- (default: "$use_systemd_in_initramfs").
-
-Additional dracut parameter and normal parameter can be added by delimiting
-them via a single dash (-) (default: "$dracut_parameter" with
-"--modules" and dynamically determined modules. Additional custom modules are
-concatenated.).
-EOF
-}
print_help_message() {
- # shellcheck disable=SC2016,SC2034
- local __doc__='
- Provides a help message for this module.
-
- >>> print_help_message &>/dev/null
- '
- logging.plain "\nUsage: $0 [options]\n"
- print_usage_message "$@"
- logging.plain '\nExamples:\n'
- print_usage_examples "$@"
- logging.plain -e '\nOption descriptions:\n'
- print_command_line_option_description "$@"
- logging.plain
+ echo "help"
}
-parse_command_line() {
- # shellcheck disable=SC2016,SC2034
- local __doc__='
- Provides the command line interface and interactive questions.
-
- >>> parse_command_line -h &>/dev/null
-
- >>> echo "$verbose"
- no
- >>> logging.get_level
- critical
- >>> parse_command_line -v
- >>> echo "$verbose"
- >>> logging.get_level
- yes
- info
-
- >>> echo "$debug"
- no
- >>> parse_command_line --debug
- >>> echo "$debug"
- >>> logging.get_level
- yes
- debug
-
- >>> parse_command_line -p
- +doc_test_capture_stderr
- +doc_test_contains
- +doc_test_ellipsis
- Error with given option "-p":
- Traceback (most recent call first):
- ...
-
- >>> echo "$file_path"
- /boot/initramfs.img
- >>> parse_command_line -p /tmp/test.img
- >>> echo "$file_path"
- /tmp/test.img
-
- >>> echo "$cleanup"
- no
- >>> parse_command_line --cleanup
- >>> echo "$cleanup"
- yes
-
- >>> echo "$full_cleanup"
- no
- >>> parse_command_line --full-cleanup
- >>> echo "$full_cleanup"
- yes
-
- >>> echo "$full_cleanup"
- no
- >>> parse_command_line --full-cleanup
- >>> echo "$full_cleanup"
- yes
-
- >>> echo "$use_systemd_in_initramfs"
- no
- >>> parse_command_line -s
- >>> echo "$use_systemd_in_initramfs"
- yes
-
- >>> parse_command_line -t; echo $?
- +doc_test_capture_stderr
- +doc_test_contains
- +doc_test_ellipsis
- Error with given option "-t":
- Traceback (most recent call first):
- ...
- >>> [[ "$target" = "" ]]
- >>> parse_command_line -t /tmp/
- >>> echo "$target"
- /tmp/
-
- >>> echo "${dracut_parameter[@]}"
- --force --no-hostonly
- >>> parse_command_line - --test
- >>> echo "${dracut_parameter[@]}"
- --force --no-hostonly --test
-
- >>> parse_command_line - --install "vim htop"
- >>> echo "${dracut_parameter[3]}"
- vim htop
-
- >>> parse_command_line --no-available-option; echo $?
- +doc_test_capture_stderr
- +doc_test_contains
- +doc_test_ellipsis
- Error with given option "--no-available-option":
- Traceback (most recent call first):
- ...
- '
+parse_command_line() {
while true; do
case "$1" in
-h|--help)
@@ -315,7 +94,7 @@ parse_command_line() {
shift
file_path="$1"
if [[ "$file_path" == '' ]]; then
- logging.critical \
+ echo \
"Error with given option \"$given_argument\": This option needs a path to save initramfs image to."
return 1
fi
@@ -338,7 +117,7 @@ parse_command_line() {
shift
target="$1"
if [[ "$target" == '' ]]; then
- logging.critical \
+ echo \
"Error with given option \"$given_argument\": This option needs a path create initramfs from."
return 1
fi
@@ -353,7 +132,7 @@ parse_command_line() {
shift
kernel_version="$1"
if [ -z "$kernel_version" ]; then
- logging.critical \
+ echo \
"Error with given option \"$given_argument\": This option needs a kernel version to build the initramfs for."
return 1
fi
@@ -364,7 +143,7 @@ parse_command_line() {
shift
kernel_headers="$1"
if [ -z "$kernel_headers" ]; then
- logging.critical \
+ echo \
"Error with given option \"$given_argument\": This option needs the path to the kernel headers."
return 1
fi
@@ -375,7 +154,7 @@ parse_command_line() {
shift
qcow_handler="$1"
if [ -z "$qcow_handler" ]; then
- logging.critical \
+ echo \
"Error with given option \"$given_argument\": This options needs to be either 'xmount' or 'kernel'."
return 1
fi
@@ -396,74 +175,17 @@ parse_command_line() {
break
;;
*)
- logging.critical \
+ echo \
"Error with given option \"$1\": This argument is not available."
return 1
esac
done
- if [ "$verbose" == 'yes' ]; then
- logging.set_level info
- fi
- if [ "$debug" == 'yes' ]; then
- logging.set_level debug
- fi
- # NOTE: Remove the following line if this sanity check should be performed.
- return 0
- if [[ "$UID" != '0' ]]; then
- logging.critical \
- "You have to run this script as \"root\" not as \"${USER}\"."
- exit 2
- fi
+
return 0
}
## endregion
## region helper
-dependency_check() {
- # shellcheck disable=SC2016,SC2034
- local __doc__='
- Check for given dependencies with given dependency checker and log
- corresponding messages.
-
- Example:
-
- `dependency_check core dependencies utils_dependency_check program`
- '
- local result=0
-
- # shellcheck disable=SC2016,SC1004
- eval 'for dependency_group in "${!'"$1"'_'"$2"'[@]}"; do
- # NOTE: If "dependency_check_result" would be marked as local it is
- # empty later.
- dependency_check_result="$($3 $dependency_group)" || \
- local return_code=$?
- if [[ $return_code == 1 ]]; then
- echo "$dependency_check_result"
- return $return_code
- elif [[ $return_code == 2 ]]; then
- while read dependency; do
- eval "local reason=\${${1}_${2}[\"\$dependency_group\"]}"
- local message="Missing $1 $4 dependency \"$dependency\" needed to $reason."
- if [[ $1 == core ]]; then
- logging.critical "$message"
- else
- logging.warn "$message"
- fi
- done <<< $dependency_check_result
- result=2
- fi
- return_code=0
- done'
- return $result
-}
initialize_dracut() {
- # shellcheck disable=SC2016,SC2034
- local __doc__='
- Downloads and compiles dracut.
-
- Example:
-
- `initialize_dracut`
- '
# First check what version to get
# Autodetect the kmod version present on the system to decide which dracut version to get
# * v47 requires kmod >= 23 (Available in Ubuntu 18.04)
@@ -476,14 +198,14 @@ initialize_dracut() {
dracut_resource_url="https://www.kernel.org/pub/linux/utils/boot/dracut/dracut-$dracut_version.tar.gz"
if [[ ! -f "${_root_dir}/dracut/install/dracut-install" ]]; then
mkdir --parents "${_root_dir}/dracut"
- logging.info "Download and extract dracut version $dracut_version"
+ echo "Download and extract dracut version $dracut_version"
curl --location "$dracut_resource_url" | tar --extract --gzip \
--directory "${_root_dir}/dracut" --strip-components 1
pushd "${_root_dir}/dracut"
# NOTE: On virtualbox shared folder symlinks are not allowed.
# NOTE: make the dracut-install binary (dracut-install resolves
# dependencies etc.)
- logging.info 'Compiling dracut.'
+ echo 'Compiling dracut.'
./configure
make install/dracut-install
# NOTE: We have to copy the binary to current instead of symlinking
@@ -498,94 +220,48 @@ initialize_dracut() {
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() {
- # shellcheck disable=SC2016,SC2034
- local __doc__='
- Removes distribution specific generated files.
-
- Example:
-
- `cleanup`
- '
local plugin_path
plugin_path="${_root_dir}/modules.d/dnbd3-rootfs"
- # shellcheck disable=SC1090
source "${plugin_path}/module-setup.sh"
- # shellcheck disable=SC2034
moddir="$(cd "$plugin_path" &>/dev/null && pwd)"
clean
return $?
}
-## endregion
-# endregion
-# region controller
main() {
- # shellcheck disable=SC2016,SC2034
- local __doc__='
- Main Entry point for the build initramfs logic. Triggers command line
- parsing and calls sub routines depending on given command line arguments.
-
- Example:
-
- `main`
- '
- exceptions.activate
- # region dependency checks and command line parsing
- result=0
- dependency_check core dependencies utils_dependency_check program || \
- result=$?
- dependency_check core shared_library_pattern_dependencies \
- utils_dependency_check_shared_library 'shared library' || result=$?
- dependency_check core package_dependencies utils_dependency_check_pkgconfig \
- package || result=$?
- [[ $result == 0 ]] || exit $result
-
- logging.set_commands_level debug
- logging.set_level critical
-
if ! parse_command_line "$@"; then
print_help_message "$0"
exit 1
fi
-
- dependency_check optional dependencies utils_dependency_check program || \
- result=$?
- dependency_check optional shared_library_pattern_dependencies \
- utils_dependency_check_shared_library 'shared library' || result=$?
- dependency_check optional package_dependencies \
- utils_dependency_check_pkgconfig package || result=$?
- [[ $result == 1 ]] && exit $result
- # endregion
-
- # region sanity check kernel version and qcow handler
# if no kernel was specified as dracut argument, use the running kernel's version
- logging.info "Building for:"
+ echo "Building for:"
if [ -z "$kernel_version" ]; then
kernel_version="$(uname -r)"
fi
- logging.info " * kernel version: $kernel_version"
+ 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
- logging.critical 'Missing core dependency "linux-headers" for version to compile against given or current kernel.'
+ echo 'Missing core dependency "linux-headers" for version to compile against given or current kernel.'
fi
- logging.info " * kernel headers: $kernel_headers"
- [ -n "$qcow_handler" ] && logging.info " * qcow2 handler: $qcow_handler"
- # endregion
+ echo " * kernel headers: $kernel_headers"
+ [ -n "$qcow_handler" ] && echo " * qcow2 handler: $qcow_handler"
+ export _QCOW_HANDLER="$qcow_handler"
- # region handle '--update' to update all the modules in 'modules.d'
if [ "$update" == "yes" ]; then
pushd "${_repo_dir}"
git pull
popd
fi
- # endregion
- # region handle dependencies which can be resolved automatically
- logging.info 'Checking dracut.'
+
+ echo 'Checking dracut...'
if [[ ! -f "${_root_dir}/dracut/dracut-install" ]]; then
- logging.info "Dracut isn't available yet loading it."
+ echo "Dracut isn't available yet loading it."
initialize_dracut
fi
@@ -596,10 +272,10 @@ main() {
_dracut_module_target="${_root_dir}/dracut/modules.d/00${_dracut_module}"
if [[ ! -L "$_dracut_module_target" || "$(readlink \
"$_dracut_module_target")" != "$_dracut_module_dir" ]]; then
- logging.info \
+ 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
- logging.warn \
+ 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 \
@@ -608,70 +284,47 @@ main() {
fi
fi
done
- # endregion
- # region prepare modules and perform final dracut call
_loglevel=''
if [ "$verbose" == 'yes' ]; then
_loglevel='--verbose'
fi
_modules=(dnbd3-rootfs conf-tgz)
- logging.info "Default modules: ${_modules[@]}"
+ echo "Default modules: ${_modules[@]}"
if [ "$debug" == 'yes' ]; then
_loglevel="$_loglevel --stdlog 4"
- _modules+=(i18n terminfo)
+ _modules+=(i18n terminfo)
fi
if [ "$use_systemd_in_initramfs" == 'yes' ]; then
- _modules+=(systemd systemd-initrd dracut-systemd)
+ _modules+=(systemd systemd-initrd dracut-systemd)
fi
# Preprocess done - start build, cleanup or full cleanup
if [[ "$full_cleanup" == 'yes' ]]; then
- logging.info 'Removing all modules.'
+ echo 'Removing all modules.'
rm "${_repo_dir}" "${_root_dir}/dracut" --recursive --force
elif [[ "$cleanup" == 'yes' ]]; then
- logging.info 'Removing distribution specific files.'
+ echo 'Removing distribution specific files.'
cleanup
else
. "${_repo_dir}/builder/modules.d/dnbd3-rootfs/helper/build.inc"
build_initialize_components
- if [[ "$initialize" == 'yes' ]]; then
- logging.info "Initialized."
- exit 0
- fi
- logging.info 'Build initramfs.'
- # NOTE: We deactivate our exception handle since dracut returns "1" if
- # it is launched with help parameter ("-h" or "--help").
- exceptions.deactivate
- # NOTE: We temporary allow dracut to forward all messages since we
- # forward all logging configurations.
- _commands_log_level_backup="$(logging.get_commands_level)"
- _log_level_backup="$(logging.get_level)"
- logging.set_level debug
- logging.set_commands_level debug
- # shellcheck disable=SC2086
+ 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=$?
- logging.set_commands_level "$_commands_log_level_backup"
- logging.set_level "$_log_level_backup"
- if [[ "$_return_code" != 0 ]]; then
- logging.error 'Building initial ram file system failed.'
+ if [ "$_return_code" != 0 ]; then
+ echo 'Building initial ram file system failed.'
exit 1
fi
- exceptions.activate
# NOTE: dracut generate the initramfs with 0600 permissions
chmod 0644 "${file_path}"
fi
- # endregion
- exceptions.deactivate
}
-# endregion
-if core.is_main; then
- main "$@"
-fi
-# region vim modline
-# vim: set tabstop=4 shiftwidth=4 expandtab:
-# vim: foldmethod=marker foldmarker=region,endregion:
-# endregion
+main "$@"