#!/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. source dnbd3-rootfs/scripts/utils.sh __NAME__='build-initramfs' # endregion function build-initramfs() { # Provides the main module scope. # region properties local _SCOPE='local' && \ if [[ $(echo "\"$@\"" | grep --extended-regexp \ '(^"| )(-l|--load-environment)("$| )') != '' ]] then local _SCOPE='export' fi # NOTE: Only initialize environment if current scope wasn't set yet. if [ "$UTILS_VERBOSE" == '' ]; then "$_SCOPE" UTILS_VERBOSE='no' "$_SCOPE" _LOAD_ENVIRONMENT='no' "$_SCOPE" _CREATE_SYSTEM_IMAGE='no' local dependencies=(bash cpio git test shift echo mktemp cat rm sed \ gzip curl tar grep make cmake) "$_SCOPE" _DEPENDENCIES="${dependencies[*]}" fi # endregion # region functions ## region command line interface function build_initramfs_print_usage_message() { # Prints a description about how to use this program. cat << EOF $__NAME__ 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. 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. 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"). -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: "$_CREATE_SYSTEM_IMAGE"). EOF } function build_initramfs_print_help_message() { # Provides a help message for this module. echo -e "\nUsage: $0 [options]\n" build_initramfs_print_usage_message "$@" echo -e '\nExamples:\n' build_initramfs_print_usage_examples "$@" echo -e '\nOption descriptions:\n' build_initramfs_print_command_line_option_description "$@" echo } function build_initramfs_command_line_interface() { # 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 UTILS_VERBOSE='yes' ;; -d|--debug) shift _DEBUG='yes' UTILS_STANDARD_OUTPUT=/dev/stdout UTILS_ERROR_OUTPUT=/dev/stderr ;; -l|--load-environment) shift _LOAD_ENVIRONMENT='yes' ;; -c|--create-system-image) shift _CREATE_SYSTEM_IMAGE="$1" shift ;; '') shift break ;; *) utils_log 'critical' \ "Given argument: \"$1\" is not available." '\n' && \ if [[ "$_SCOPE" == 'local' ]]; then build_initramfs_print_help_message "$0" fi return 1 esac done if [[ "$UID" != '0' ]]; then utils_log '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 1>"$UTILS_STANDARD_OUTPUT" 2>"$UTILS_ERROR_OUTPUT" && \ utils_log '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 \ 1>"$UTILS_STANDARD_OUTPUT" 2>"$UTILS_ERROR_OUTPUT" && \ pushd dracut 1>"$UTILS_STANDARD_OUTPUT" 2>"$UTILS_ERROR_OUTPUT" && \ # NOTE: On virtualbox shared folder symlinks are not allowed. # make the dracut-install binary (dracut-install resolves dependencies etc.) utils_log 'Compile dracut.' && \ make install/dracut-install 1>"$UTILS_STANDARD_OUTPUT" \ 2>"$UTILS_ERROR_OUTPUT" && \ # 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 1>"$UTILS_STANDARD_OUTPUT" \ 2>"$UTILS_ERROR_OUTPUT" && \ popd 1>"$UTILS_STANDARD_OUTPUT" 2>"$UTILS_ERROR_OUTPUT" 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 if [[ "$0" == *"${__NAME__}.sh" ]]; then utils_dependency_check "${_DEPENDENCIES[*]}" || \ utils_log 'error' 'Satisfying main dependencies failed.' build_initramfs_command_line_interface "$@" || return $? utils_log 'Checking dracut.' && \ if ! [[ -d ./dracut ]]; then utils_log "Dracut isn't available yet loading it." && \ build_initramfs_initialize_dracut fi utils_log 'Build initramfs.' && \ utils_log 'Link dnbd3 plugin into dracut modules folder.' && \ local dracut_modules_source='../../dnbd3-rootfs' && \ local dracut_modules_target='dracut/modules.d/90dnbd3-rootfs' && \ if [[ ! -L "$dracut_modules_target" || "$(readlink \ "$dracut_modules_target")" != "$dracut_modules_source" ]] then ln --symbolic "$dracut_modules_source" "$dracut_modules_target" \ 1>"$UTILS_STANDARD_OUTPUT" 2>"$UTILS_ERROR_OUTPUT" # NOTE: If you copy we would have to recompile each binaries every # time. #cp --recursive --force --no-target-directory \ # dnbd3-rootfs/ dracut/modules.d/90dnbd3-rootfs \ # 1>"$UTILS_STANDARD_OUTPUT" 2>"$UTILS_ERROR_OUTPUT" fi local loglevel='' if [ "$UTILS_VERBOSE" == 'yes' ]; then loglevel='--verbose' fi if [ "$_DEBUG" == 'yes' ]; then loglevel="$loglevel --stdlog 4" fi dracut/dracut.sh --local $loglevel --force --modules "dnbd3-rootfs" \ --no-hostonly 1>"$UTILS_STANDARD_OUTPUT" 2>"$UTILS_ERROR_OUTPUT" fi return 0 # endregion } # region footer if [[ "$0" == *"${__NAME__}.sh" || $(echo "$@" | grep --extended-regexp \ '(^| )(-l|--load-environment)($| )') ]] then "$__NAME__" "$@" fi # endregion # region vim modline # vim: set tabstop=4 shiftwidth=4 expandtab: # vim: foldmethod=marker foldmarker=region,endregion: # endregion