summaryrefslogblamecommitdiffstats
path: root/builder/build-initramfs.sh
blob: 039cc32124f414e594b40bf5e600b3577ad8a2c3 (plain) (tree)
1
2
3
4
5
6
7
8
9

                       
               
                                                                  
                                                              
                                                                         
 

         


                                                                         
            
 
                                                                   
                                                     
                                                                           
                                
 
                                                
              

                                                           
                       
                                                         
                                                                                         
              
      
                                                                 

                                    
                      

                                                                           
                                                                       



                                                                           
                                     



                                                                           
                                                                           
                                                                           




                                                                                  


                                                                                                      

                                                                                   
     
        

              
            
 
                               
                                        


            
            
                 
                             
 

                                           
 
 
                      



                      
                                       



                         
                             


                       
                           
                  
                           
                                         
                     

                                                 
                          
                                                                                                                           



                            

                         
                             
                  



                                  

                                          
                                              
                  
                        
                                         
                     

                                              
                          
                                                                                                                      



                            



                                




                                                 
                          




                                                                                                                                     
                                



                                                 
                          




                                                                                                                        




                                               
                          








                                                                                                                            


                                            
                                            

                         
                  
               


                     
                      
                                                                                     


                        
 
            
 
            
                
                     









                                                                                                          
                                                                    
                                             
                                                                  
                                                                       
                                                                   
                                   


                                                                       
                                
                   







                                                                               

                                                     

             
 
                            
           
                     
                                                     
                                           
                                                    
         
             
 
        
            



                                      
                                                                                     
                        


                                     
                                             




                                                                 
                                                                                                             
      
                                             
                                                                    
                                        
 
       
                                      


                                                                             
 






                                                       























                                                                                 


















                                                                                                                         
                                                                       
              




                                   

                                         
                                                            
                                                     
                         
      
 
            
                                                        



                                                                        
                                        
                                                                                 
                                                            
                                                                                  
                  


                                                                                                                                     

                                                                                                   
       


                                                                    
                                             
                                                                                 
                                                            
                                                                        
                          

                                                                                                                           
                              
                                                                                             
              
                                                                                                                          
                                                              
                                           
                                            
              
          
        
 


                                    
      
            
                                                                          
                                       

                                         
                                           

                                          
                                                            
                                           
                                    

                                                     
       
                                    
                                                  

                                         
                                 

                                                     
                                                         
      
                                                            

                                            
                                                                   
              
                                        
                                                    
               
        
            
                               
       





                                                                        
                                       

                                                                              
                             

                                                                          



                                                                  
                                   
              
                                                 
                                                                           
                                                                   
                                                   
                       

                                                           

                  

                                                                   
      
 
         
#!/usr/bin/env bash
# -*- coding: utf-8 -*-
# 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
## endregion

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="master"

## region ensure presence of needed dependencies
set -o errexit
if [ ! -e "$_repo_dir" ]; then
    echo "Missing dracut modules repository, loading them."
    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}"
    pushd "${_repo_dir}"
    git submodule init
    # try to clone submodules as shallowy as possible, since we cannot just
    # use '--depth 1' on submodules residing on non-master branches...
    for mod in $(grep -Po '(?<=^\[submodule ")([^"]+)' .gitmodules); do
        url="$(git config -f .gitmodules --get submodule.${mod}.url)"
        path="$(git config -f .gitmodules --get submodule.${mod}.path)"
        branch="$(git config -f .gitmodules --get submodule.${mod}.branch)"
        commit="$(git submodule status $path | grep -oE '[0-9a-f]{40}')"
        depth_arg=("--shallow-since")
        [ "$mod" = "dnbd3" ]                   && depth_arg+=("2019-02-12")
        [ "$mod" = "rebash" ]                  && depth_arg+=("2016-11-30")
        [ "$mod" = "qemu-xmount" ]             && depth_arg+=("2016-01-01")
        [ "$mod" = "xmount" ]                  && depth_arg+=("2015-11-05")
        [ "$mod" = "kernel-qcow2-linux" ]      && depth_arg+=("2019-08-25")
        [ "$mod" = "kernel-qcow2-util-linux" ] && depth_arg+=("2019-08-15")
        git clone -n --no-tags "${depth_arg[@]}" --branch "$branch" "$url" "$path"
        pushd "$path"
        git checkout "$commit"
        popd
    done
    # apply patches for submodules
    git submodule foreach '
        for p in $(find ${toplevel}/builder/patches/${path##*/} -type f -name "*.patch" | sort -n); do
            patch -p1 < $p || echo "Failed to patch $path with $p - expect errors."
        done 2>/dev/null
    '
    popd
fi
set +o errexit
## endregion

file_path='/boot/initramfs.img'
dracut_parameter=(--force --no-hostonly)
verbose='no'
debug='no'
target=''
cleanup='no'
full_cleanup='no'
use_systemd_in_initramfs='no'

print_help_message() {
				echo "help"
}

parse_command_line() {
    while true; do
        case "$1" in
            -h|--help)
                shift
                print_help_message "$0"
                exit 0
                ;;
            -v|--verbose)
                shift
                verbose='yes'
                ;;
            -d|--debug)
                shift
                debug='yes'
                ;;
            -p|--file-path)
                local given_argument="$1"
                shift
                file_path="$1"
                if [[ "$file_path" == '' ]]; then
                    echo \
                        "Error with given option \"$given_argument\": This option needs a path to save initramfs image to."
                    return 1
                fi
                shift
                ;;
            -c|--cleanup)
                shift
                cleanup='yes'
                ;;
            -f|--full-cleanup)
                shift
                full_cleanup='yes'
                ;;
            -s|--use-systemd-in-initramfs)
                shift
                use_systemd_in_initramfs='yes'
                ;;
            -t|--target)
                local given_argument="$1"
                shift
                target="$1"
                if [[ "$target" == '' ]]; then
                    echo \
                        "Error with given option \"$given_argument\": This option needs a path create initramfs from."
                    return 1
                fi
                shift
                ;;
            -i|--init)
                shift
                initialize='yes'
                ;;
            -k|--kernel-version)
                local given_argument="$1"
                shift
                kernel_version="$1"
                if [ -z "$kernel_version" ]; then
                    echo \
                        "Error with given option \"$given_argument\": This option needs a kernel version to build the initramfs for."
                    return 1
                fi
                shift
                ;;
            -H|--kernel-headers)
                local given_argument="$1"
                shift
                kernel_headers="$1"
                if [ -z "$kernel_headers" ]; then
                    echo \
                        "Error with given option \"$given_argument\": This option needs the path to the kernel headers."
                    return 1
                fi
                shift
                ;;
            -q|--qcow-handler)
                local given_argument="$1"
                shift
                qcow_handler="$1"
                if [ -z "$qcow_handler" ]; then
                    echo \
                        "Error with given option \"$given_argument\": This options needs to be either 'xmount' or 'kernel'."
                    return 1
                fi
                shift
                ;;
            -u|--update)
                shift
                update='yes'
                ;;
            -)
                shift
                while [[ "$1" =~ ^.+$ ]]; do
                    dracut_parameter+=("$1")
                    shift
                done
                ;;
            '')
                break
                ;;
            *)
                echo \
                    "Error with given option \"$1\": This argument is not available."
                return 1
        esac
    done

    return 0
}
## endregion
## region helper
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)
    #  * v46 works with kmod == 20 (CentOS 7.5 only provides kmod v20)
    if [ "$(pkg-config --modversion libkmod)" -ge 23 ]; then
        dracut_version="047"
    else
        dracut_version="046"
    fi
    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"
        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.)
        echo 'Compiling dracut.'
        ./configure
        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
        popd
    fi
    cp "${_root_dir}/dracut/install/dracut-install" \
        "${_root_dir}/dracut/dracut-install"
    return $?
}

# TODO does this even works?
cleanup() {
    local plugin_path
    plugin_path="${_root_dir}/modules.d/dnbd3-rootfs"
    source "${plugin_path}/module-setup.sh"
    moddir="$(cd "$plugin_path" &>/dev/null && pwd)"
    clean
    return $?
}
main() {
<<<<<<< HEAD
    if ! parse_command_line "$@"; then
        print_help_message "$0"
        exit 1
    fi
    # if no kernel was specified as dracut argument, use the running kernel's version
    echo "Building for:"
    if [ -z "$kernel_version" ]; then
       kernel_version="$(uname -r)"
    fi
    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
       echo 'Missing core dependency "linux-headers" for version to compile against given or current kernel.'
    fi
    echo " * kernel headers: $kernel_headers"
    [ -n "$qcow_handler" ] && echo " * qcow2 handler: $qcow_handler"
    export _QCOW_HANDLER="$qcow_handler"

=======
    # 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:"
    if [ -z "$kernel_version" ]; then
       kernel_version="$(uname -r)"
    fi
    logging.info " * 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.'
    fi
    logging.info " * kernel headers: $kernel_headers"
    [ -n "$qcow_handler" ] && logging.info " * qcow2 handler: $qcow_handler"
    # endregion

    # region handle '--update' to update all the modules in 'modules.d'
>>>>>>> master
    if [ "$update" == "yes" ]; then
        pushd "${_repo_dir}"
        git pull
        popd
    fi

		echo 'Checking dracut...'
    if [[ ! -f "${_root_dir}/dracut/dracut-install" ]]; then
        echo "Dracut isn't available yet loading it."
        initialize_dracut
    fi

<<<<<<< HEAD
    for _dracut_module in "${_root_dir}/modules.d/"*; do
        [ -d "${_dracut_module}" ] || continue
        _dracut_module="$(basename $_dracut_module)"
        # shouldn't we use absolute paths here?
        _dracut_module_relative_path="../../modules.d/${_dracut_module}"
        # TODO introduce module priority
        _dracut_module_target="${_root_dir}/dracut/modules.d/00${_dracut_module}"
        if [[ ! -L "$_dracut_module_target" || "$(readlink \
            "$_dracut_module_target")" != "$_dracut_module_relative_path" ]]; then
            echo \
                "Link ${_dracut_module} plugin into dracut modules folder ($_dracut_module_relative_path -> $_dracut_module_target)."
            if ! ln --symbolic --force "$_dracut_module_relative_path" \
            "$_dracut_module_target"; then
                echo \
                    "Linking '$_dracut_module_relative_path' to '$_dracut_module_target' failed." \
=======
    for _dracut_module_dir in "${_repo_dir}/builder/modules.d/"*; do
        [ -d "${_dracut_module_dir}" ] || continue
        _dracut_module="$(basename $_dracut_module_dir)"
        # TODO allow module-specific priority
        _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 \
                "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 \
                    "Linking \"$_dracut_module_dir\" to \"$_dracut_module_target\" failed." \
>>>>>>> master
                    " 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 \
                    "$_dracut_module_dir" \
                    "$_dracut_module_target"
            fi
        fi
    done

    _loglevel=''
    if [ "$verbose" == 'yes' ]; then
        _loglevel='--verbose'
    fi
<<<<<<< HEAD
    _modules='dnbd3-rootfs conf-tgz systemd systemd-initrd dracut-systemd'
    echo "Default modules: ${_modules}"
    if [ "$debug" == 'yes' ]; then
        _loglevel="$_loglevel --stdlog 4"
        # TODO check if we always want this
        _modules="$_modules i18n terminfo"
    fi
    # Preprocess done - start build, cleanup or full cleanup
    if [[ "$full_cleanup" == 'yes' ]]; then
        echo 'Removing all modules.'
        rm "${_root_dir}/modules.d" \
            "${_root_dir}/dracut" --recursive --force
=======
    _modules=(dnbd3-rootfs conf-tgz)
    logging.info "Default modules: ${_modules[@]}"
    if [ "$debug" == 'yes' ]; then
        _loglevel="$_loglevel --stdlog 4"
	_modules+=(i18n terminfo)
    fi
    if [ "$use_systemd_in_initramfs" == 'yes' ]; then
	_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.'
        rm "${_repo_dir}" "${_root_dir}/dracut" --recursive --force
>>>>>>> master
    elif [[ "$cleanup" == 'yes' ]]; then
        echo 'Removing distribution specific files.'
        cleanup
    else
<<<<<<< HEAD
        echo 'Build initramfs.'
=======
        . "${_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
>>>>>>> master
        "${_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=$?
        if [ "$_return_code" != 0 ]; then
            echo 'Building initial ram file system failed.'
            exit 1
        fi
        # NOTE: dracut generate the initramfs with 0600 permissions
        chmod 0644 "${file_path}"
    fi
}
main "$@"