#!/usr/bin/env bash # -*- coding: utf-8 -*- # region header # Copyright Torben Sickert (t.sickert["~at~"]gmail.com) 29.10.2015 # Janosch Dobler (TODO) 29.10.2015 # 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 # Note that you only get very necessary output until you provide "--verbose" as # commandline options. # Dependencies # ------------ # - bash (or any bash like shell) # - cpio - Copies files into or out of a cpio or tar archive. The # archive can be another file on the disk, a magnetic tape, # or a pipe. # - git - The stupid content tracker. # - test - Check file types and compare values (part of the shell). # - shift - Shifts the command line arguments (part of the shell). # - echo - Display a line of text (part of coreutils). # - mktemp - Create a temporary file or directory (part of coreutils). # - cat - Concatenate files and print on the standard output (part of # coreutils). # - rm - Remove files or directories (part of coreutils). # - sed - Stream editor for filtering and transforming text. # - gzip - Compress or expand files. # - curl - Transfer a URL # - tar - The GNU version of the tar archiving utility. # - make - GNU make utility to maintain groups of programs. # - cmake - The "cmake" executable is the CMake command-line interface. # - linux-headers - GNU make utility to maintain groups of programs. # - grep - Searches the named input files (or standard input if no # files are named, or if a single hyphen-minus (-) is given # as file name) for lines containing a match to the given # PATTERN. By default, grep prints the matching lines. # endregion source $(dirname ${BASH_SOURCE[0]})/dnbd3-rootfs/scripts/rebash/core.sh core.import logging core.import utils core.import exceptions exceptions.init # region properties build_initramfs_verbose='no' build_initramfs_debug='no' build_initramfs_create_system_image='no' build_initramfs_dependencies=(bash cpio git test shift echo mktemp cat rm sed \ gzip curl tar grep make gcc cmake) # TODO Check for: # /usr/lib/x86_64-linux-gnu/libz.so ldconfig -p |grep libz.so # for dnbd3 # endregion # region functions ## region command line interface function build_initramfs_print_usage_message() { # Prints a description about how to use this program. logging.cat << EOF This program provides a generic way to install systemd based remote linux initramfs. EOF } function build_initramfs_print_usage_examples() { # Prints a description about how to use this program by providing examples. logging.cat << EOF Start install progress: >>> ./build_initramfs.sh EOF } function build_initramfs_print_command_line_option_description() { # Prints descriptions about each available command line option. logging.cat << EOF -h --help Shows this help message. -v --verbose Tells you what is going on (default: "$build_initramfs_verbose"). -d --debug Gives you any output from all tools which are used (default: "$build_initramfs_debug"). -l --load-environment Simple load the install arch linux scope without doing anything else. -c --create-system-image Creates a system image file for given path (default: "$build_initramfs_create_system_image"). EOF } function build_initramfs_print_help_message() { # Provides a help message for this module. logging.plain "\nUsage: $0 [options]\n" build_initramfs_print_usage_message "$@" logging.plain '\nExamples:\n' build_initramfs_print_usage_examples "$@" logging.plain -e '\nOption descriptions:\n' build_initramfs_print_command_line_option_description "$@" logging.plain } function build_initramfs_parse_command_line() { # Provides the command line interface and interactive questions. while true; do case "$1" in -h|--help) shift build_initramfs_print_help_message "$0" exit 0 ;; -v|--verbose) shift build_initramfs_verbose='yes' logging.set_commands_log_level debug logging.set_log_level info ;; -d|--debug) shift build_initramfs_debug='yes' logging.set_commands_log_level debug logging.set_log_level debug ;; -c|--create-system-image) shift build_initramfs_create_system_image="$1" shift ;; '') break ;; *) logging.critical "Given argument: \"$1\" is not available." return 1 esac done if [[ "$UID" != '0' ]]; then logging.critical \ "You have to run this script as \"root\" not as \"${USER}\"." exit 2 fi return 0 } ## endregion function build_initramfs_initialize_dracut() { # Downloads and compiles dracut. # # Examples: # # >>> build_initramfs_initialize_dracut # ... mkdir dracut logging.info 'Download and extract dracut.' curl --location \ https://www.kernel.org/pub/linux/utils/boot/dracut/dracut-043.tar.gz | \ tar --extract --gzip --directory dracut --strip-components 1 pushd 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.' 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 cp install/dracut-install dracut-install popd return $? } function build_initramfs_create_qcow2_system() { # Packs current distribution in a qcow2 container. # # Examples: # # >>> build_initramfs_create_qcow2_system # TODO qemu-img create -f qcow2 "${CONTAINER_PATH}" "${QCOW_SIZE}" return $? } # endregion # region controller # TODO link dracut module if present in same folder or download if not present # already. # TODO write clean procedure (also clean dracut module). # TODO check for existing kernel headers: # ubuntu: sudo apt-get install linux-headers-$(uname -r) utils.dependency_check "${build_initramfs_dependencies[*]}" if ! build_initramfs_parse_command_line "$@"; then build_initramfs_print_help_message "$0" exit 1 fi logging.info 'Checking dracut.' if ! [[ -d ./dracut ]]; then logging.info "Dracut isn't available yet loading it." build_initramfs_initialize_dracut fi build_initramfs__dracut_modules_source='../../dnbd3-rootfs' build_initramfs__dracut_modules_target='dracut/modules.d/90dnbd3-rootfs' if [[ ! -L "$build_initramfs__dracut_modules_target" || "$(readlink \ "$build_initramfs__dracut_modules_target")" != \ "$build_initramfs__dracut_modules_source" ]] then logging.info \ "Link dnbd3 plugin into dracut modules folder ($build_initramfs__dracut_modules_source -> $build_initramfs__dracut_modules_target)." ln --symbolic "$build_initramfs__dracut_modules_source" \ "$build_initramfs__dracut_modules_target" # NOTE: If you copy we would have to recompile each binaries every time: # >>> cp --recursive --force --no-target-directory \ # ... "$(basename "$build_initramfs__dracut_modules_source")" \ # ... "$build_initramfs__dracut_modules_target" fi build_initramfs__loglevel='' if [ "$build_initramfs_verbose" == 'yes' ]; then build_initramfs__loglevel='--verbose' fi build_initramfs__modules='dnbd3-rootfs' if [ "$build_initramfs_debug" == 'yes' ]; then build_initramfs__loglevel="$build_initramfs__loglevel --stdlog 4" build_initramfs__modules="$build_initramfs__modules i18n terminfo" fi logging.info 'Build initramfs.' dracut/dracut.sh --local $build_initramfs__loglevel --force --modules \ "$build_initramfs__modules" --no-hostonly /boot/initramfs-test.img logging.info 'All done!' # endregion # region vim modline # vim: set tabstop=4 shiftwidth=4 expandtab: # vim: foldmethod=marker foldmarker=region,endregion: # endregion