#!/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. # - wget - The non-interactive network downloader. # - xz - Compress or decompress .xz and lzma files. # - tar - The GNU version of the tar archiving utility. # - 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. # Optional dependencies # --------------------- # TODO # TODO __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' local dependencies=(bash cpio git test shift echo mktemp cat rm sed \ wget xz tar grep) "$_SCOPE" _DEPENDENCIES="${dependencies[*]}" "$_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__ This tool 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. EOF } function build_initramfs_print_help_message() { # Provides a help message for this module. echo -e "\nUsage: $0 [options]\n" archInstallPrintUsageMessage "$@" echo -e '\nExamples:\n' archInstallPrintUsageExamples "$@" echo -e '\nOption descriptions:\n' archInstallPrintCommandLineOptionDescription "$@" 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' ;; '') 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 archInstallLog '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 # endregion # region controller if [[ "$0" == *"${__NAME__}.bash" ]]; then archInstallPerformDependencyCheck "${_DEPENDENCIES[*]}" || \ archInstallLog 'error' 'Satisfying main dependencies failed.' archInstallCommandLineInterface "$@" || return $? _PACKAGES="${_BASIC_PACKAGES[*]} ${_ADDITIONAL_PACKAGES[*]}" && \ if [ "$_INSTALL_COMMON_ADDITIONAL_PACKAGES" == 'yes' ]; then _PACKAGES+=' '${_COMMON_ADDITIONAL_PACKAGES[*]} fi if [ ! -e "$_OUTPUT_SYSTEM" ]; then mkdir --parents "$_OUTPUT_SYSTEM" 1>"$_STANDARD_OUTPUT" \ 2>"$_ERROR_OUTPUT" fi if [ -d "$_OUTPUT_SYSTEM" ]; then _MOUNTPOINT_PATH="$_OUTPUT_SYSTEM" && \ if [[ ! "$_MOUNTPOINT_PATH" =~ .*/$ ]]; then _MOUNTPOINT_PATH+='/' fi elif [ -b "$_OUTPUT_SYSTEM" ]; then _PACKAGES+=' efibootmgr' && \ archInstallPerformDependencyCheck \ "${_BLOCK_INTEGRATION_DEPENDENCIES[*]}" || \ archInstallLog 'error' \ 'Satisfying block device dependencies failed.' && \ if echo "$_OUTPUT_SYSTEM" | grep --quiet --extended-regexp '[0-9]$' then archInstallFormatSystemPartition || \ archInstallLog 'error' 'System partition creation failed.' else archInstallDetermineAutoPartitioning && \ archInstallPrepareBlockdevices || \ archInstallLog 'error' 'Preparing blockdevices failed.' fi else archInstallLog 'error' \ "Could not install into an existing file \"$_OUTPUT_SYSTEM\"." fi archInstallPrepareInstallation || \ archInstallLog 'error' 'Preparing installation failed.' if [[ "$UID" == 0 ]] && [[ "$_PREVENT_USING_PACSTRAP" == 'no' ]] && \ hash pacstrap 1>"$_STANDARD_OUTPUT" 2>/dev/null then archInstallWithPacstrap || \ archInstallLog 'error' 'Installation with pacstrap failed.' else archInstallGenericLinuxSteps || \ archInstallLog 'error' \ 'Installation via generic linux steps failed.' fi archInstallTidyUpSystem && \ archInstallConfigure || \ archInstallLog 'error' 'Configuring installed system failed.' archInstallPrepareNextBoot || \ archInstallLog 'error' 'Preparing reboot failed.' archInstallPackResult || \ archInstallLog 'error' \ 'Packing system into archiv with files owned by root failed.' archInstallLog \ "Generating operating system into \"$_OUTPUT_SYSTEM\" has successfully finished." fi return 0 # endregion mkdir dracut # 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 cd dracut # NOTE: On virtualbox shared folder symlinks are not allowed. # make the dracut-install binary (dracut-install resolves dependencies etc.) make install/dracut-install # copy the binary to current (instead of symlink) cp install/dracut-install dracut-install ## if symlinks are available #make dracut-install cd builder/dnbd3-qcow2-rootfs/kernel_modules/nbd/ make cd - # TODO build dnbd3.ko, nbd.ko (dnbd3-qcow2-rootfs/kernel_modules/Makefile) # TODO add dnbd3-qcow2-rootfs to modules.d # build initramfs ./dracut.sh --local --verbose --force } # region footer if [[ "$0" == *"${__NAME__}.bash" || $(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