From d93a1fd23ce8f0a157d251aa74a6e76b9ac1c046 Mon Sep 17 00:00:00 2001 From: torben Date: Thu, 5 Nov 2015 15:32:34 +0100 Subject: Refactoring. --- build-initramfs.sh | 316 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100755 build-initramfs.sh (limited to 'build-initramfs.sh') diff --git a/build-initramfs.sh b/build-initramfs.sh new file mode 100755 index 00000000..ae71bada --- /dev/null +++ b/build-initramfs.sh @@ -0,0 +1,316 @@ +#!/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. + +__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 [ "$_VERBOSE" == '' ]; then + "$_SCOPE" _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[*]}" + "$_SCOPE" _KERNEL_MODULE_DIRECTORY="builder/dnbd3-qcow2-rootfs/kernel_modules/" + "$_SCOPE" _STANDARD_OUTPUT=/dev/null + "$_SCOPE" _ERROR_OUTPUT=/dev/null + 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 + _VERBOSE='yes' + ;; + -d|--debug) + shift + _STANDARD_OUTPUT=/dev/stdout + _ERROR_OUTPUT=/dev/stderr + ;; + -l|--load-environment) + shift + _LOAD_ENVIRONMENT='yes' + ;; + -c|--create-system-image) + shift + _CREATE_SYSTEM_IMAGE="$1" + shift + ;; + + '') + shift + break + ;; + *) + build_initramfs_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 + build_initramfs_log 'critical' \ + "You have to run this script as \"root\" not as \"${USER}\"." + exit 2 + fi + return 0 + } + function build_initramfs_log() { + # Handles logging messages. Returns non zero and exit on log level + # error to support chaining the message into toolchain. + # + # Examples: + # + # >>> build_initramfs_log + # info: test + # >>> build_initramfs_log debug message + # debug: message + # >>> build_initramfs_log info message '\n' + # + # info: message + local loggingType='info' && \ + local message="$1" && \ + if [ "$2" ]; then + loggingType="$1" + message="$2" + fi + if [ "$_VERBOSE" == 'yes' ] || [ "$loggingType" == 'error' ] || \ + [ "$loggingType" == 'critical' ]; then + if [ "$3" ]; then + echo -e -n "$3" + fi + echo -e "${loggingType}: $message" + fi + if [ "$loggingType" == 'error' ]; then + exit 1 + fi + return 0 + } + + ## endregion + + ## region tools + + function build_initramfs_perform_dependency_check() { + # This function check if all given dependencies are present. + # + # Examples: + # + # >>> build_initramfs_perform_dependency_check "mkdir pacstrap mktemp" + # ... + local dependenciesToCheck="$1" && \ + local result=0 && \ + local dependency && \ + for dependency in ${dependenciesToCheck[*]}; do + if ! hash "$dependency" 1>"$_STANDARD_OUTPUT" 2>/dev/null; then + build_initramfs_log 'critical' \ + "Needed dependency \"$dependency\" isn't available." && \ + result=1 + fi + done + return $result + } + + ## endregion + + function build_initramfs_initialize_dracut() { + # Downloads and compiles dracut. + # + # Examples: + # + # >>> build_initramfs_initialize_dracut + # ... + mkdir dracut 1>"$_STANDARD_OUTPUT" 2>"$_ERROR_OUTPUT" && \ + build_initramfs_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>"$_STANDARD_OUTPUT" 2>"$_ERROR_OUTPUT" && \ + pushd dracut 1>"$_STANDARD_OUTPUT" 2>"$_ERROR_OUTPUT" && \ + # NOTE: On virtualbox shared folder symlinks are not allowed. + # make the dracut-install binary (dracut-install resolves dependencies etc.) + build_initramfs_log 'Compile dracut.' && \ + make install/dracut-install 1>"$_STANDARD_OUTPUT" \ + 2>"$_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>"$_STANDARD_OUTPUT" \ + 2>"$_ERROR_OUTPUT" && \ + popd 1>"$_STANDARD_OUTPUT" 2>"$_ERROR_OUTPUT" + return $? + } + function build_initramfs_create_qcow2_system() { + # TODO + qemu-img create -f qcow2 "${CONTAINER_PATH}" "${QCOW_SIZE}" + return $? + } + + # endregion + + # region controller + + if [[ "$0" == *"${__NAME__}.sh" ]]; then + build_initramfs_perform_dependency_check "${_DEPENDENCIES[*]}" || \ + build_initramfs_log 'error' 'Satisfying main dependencies failed.' + build_initramfs_command_line_interface "$@" || return $? + + build_initramfs_log 'Checking dracut.' && \ + if ! [[ -d ./dracut ]]; then + build_initramfs_log "Dracut isn't available yet loading it." && \ + build_initramfs_initialize_dracut + fi + build_initramfs_log 'Build initramfs.' && \ + build_initramfs_log \ + 'Copy dnbd3 qcow2 plugin into dracut modules folder.' && \ + cp --recursive builder/dnbd3-qcow2-rootfs/ \ + dracut/modules.d/90dndb3-qcow2-rootfs \ + 1>"$_STANDARD_OUTPUT" 2>"$_ERROR_OUTPUT" && \ + dracut/dracut.sh --local --verbose --force \ + 1>"$_STANDARD_OUTPUT" 2>"$_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 -- cgit v1.2.3-55-g7522