summaryrefslogblamecommitdiffstats
path: root/builder/modules.d/dnbd3-rootfs/hooks/prepare-root-partition.sh
blob: 23f1185b84bc08cdaf89bc23f3ff8a992be66875 (plain) (tree)
1
2
3
4
5
6
7
8
                   
                

                                                                  
                                
                      
                   
           





















                                                                   















                                                                       
                  
                      


           
                            




                                                
                                  
                                                                  
                                                       
  











                                                            
 
        





                                                                  
                                         



                                                     
                                                   

             
    
 
           
                           
                                                       






                                                                
 
                                            


                                                       
 
           
                                                 
                                                          
                                                      

                                                                                                 
      

                                                                
    






                                                                    
  
                                                              

           


                                                                
           
 


                
                                              

                                                





                                                     
#!/usr/bin/env bash
# region imports
type emergency_shell > /dev/null 2>&1 || source /lib/dracut-lib.sh
source /etc/openslx
source '/usr/lib/rebash/core.sh'
core.import exceptions
core.import logging
# endregion

# region globals/helper
logging.set_log_file "${SLX_LOG_FILE_PATH:-/var/log/openslx}"
# hardcode dnbd device path
declare -rg _dnbd3_dev="/dev/dnbd0"

# all outputs are redirected to stderr, since this functions should
# only echo the path to the unpacked container to stdout.
container_unpack_xmount() {
    local in_device="$1"
    local out_path="/mnt/xmount"
    mkdir -p "$out_path"
    # check tools first
    if ! hash xmount systemd-preserve-process-marker; then
        logging.warn "Missing xmount deps, will try raw..." 1>&2
    elif ! systemd-preserve-process-marker xmount \
            --in qemu "$in_device" \
            --out raw "$out_path" &>/dev/null; then
        logging.warn "xmount call failed, assuming raw image." 1>&2
    else
        in_device="${out_path}/${_dnbd3_dev##*/}.dd"
    fi
    local out_device="$(losetup -f)"
    if ! losetup "$out_device" "$in_device" --partscan; then
        logging.warn "Failed to attach '$in_device' to '$out_device'."
        return
    fi
    udevadm settle
    echo "$out_device"
}

container_unpack_losetup() {
    local in_device="$1"
    local out_device="$(losetup -f)"
    if ! losetup -r -t QCOW "$out_device" "$in_device" --partscan; then
        logging.warn "Failed to attach '$in_device' to '$out_device'."
        return
    fi
    udevadm settle
    echo "$out_device"
}
# endregion

# region connect dnbd3 image
# Determine stage4 image path and revision
if [ -z "$SLX_DNBD3_IMAGE" ]; then
    # specified on the KCL?
    SLX_DNBD3_IMAGE="$(getarg slx.stage4.path=)"
fi
if [ -z "$SLX_DNBD3_IMAGE" ]; then
    # not specified, fall back to old bwlp default path convention
    SLX_DNBD3_IMAGE="stage4/bwlp/maxilinux-$(uname -r)"
fi
# save it for later
echo "SLX_DNBD3_IMAGE='$SLX_DNBD3_IMAGE'" >> /etc/openslx
if [ -z "$SLX_DNBD3_RID" ]; then
    # specified on the KCL?
    SLX_DNBD3_RID="$(getarg slx.stage4.rid=)"
fi
if [ -n "$SLX_DNBD3_RID" ]; then
    _dnbd3_client_additional_args=("--rid" "$SLX_DNBD3_RID")
    echo "SLX_DNBD3_RID='$SLX_DNBD3_RID'" >> /etc/openslx
fi
exceptions.try
{
(
IFS=", "
for host in ${SLX_DNBD3_SERVERS} FAIL; do
    if [ "$host" = "FAIL" ]; then
        emergency_shell "Failed to connect '${SLX_DNBD3_IMAGE}' "\
            "${SLX_DNBD3_RID:+(revision: $SLX_DNBD3_RID)} "
            "from one of '$SLX_DNBD3_SERVERS' to '$_dnbd3_dev'."
    fi
    logging.info "Trying host \"$host\"."
    if systemd-preserve-process-marker dnbd3-client \
        --host "$host" \
        --image "${SLX_DNBD3_IMAGE}" \
        --device "$_dnbd3_dev" \
        "${_dnbd3_client_additional_args[@]}"; then
        break
    fi
done
)
# endregion
# region unpack dnbd3 image
[ -z "$SLX_QCOW_HANDLER" ] && SLX_QCOW_HANDLER="kernel"
if [ "$SLX_QCOW_HANDLER" = "xmount" ]; then
    read_only_device="$(container_unpack_xmount "$_dnbd3_dev")"
elif [ "$SLX_QCOW_HANDLER" = "kernel" ]; then
    read_only_device="$(container_unpack_losetup "$_dnbd3_dev")"
else
    logging.warn "Unsupported QCOW handler: $SLX_QCOW_HANDLER"
fi

# Fail fast if unpacking dnbd3 image failed.
if [ -z "$read_only_device" ]; then
    emergency_shell "Failed to unpack the qcow2 image!"
fi

# endregion
# region find system partition within dnbd3 image
if [ -z "$SLX_SYSTEM_PARTITION_PREPARATION_SCRIPT" ]; then
    if [ -z "$SLX_SYSTEM_PARTITION_IDENTIFIER" ]; then
        SLX_SYSTEM_PARTITION_IDENTIFIER="SLX_SYS"
        echo "SLX_SYSTEM_PARTITION_IDENTIFIER='$SLX_SYSTEM_PARTITION_IDENTIFIER'" >> /etc/openslx
    fi
    read_only_partition="$(slx-tools dev_find_partitions \
        "$read_only_device" "$SLX_SYSTEM_PARTITION_IDENTIFIER")"
else
    eval "$SLX_SYSTEM_PARTITION_PREPARATION_SCRIPT"
fi
if [[ ! $? || -z "$read_only_partition" ]]; then
    logging.error "Failed to find unique device with identifier" \
        "\"${SLX_SYSTEM_PARTITION_IDENTIFIER}\"; matched devices:" \
        "\"${read_only_partition}\""
    exit 1
fi
logging.info "Using read-only partition: $read_only_partition"
# endregion

# region add rw layer to dnbd3 image
# don't be fooled to think we are done, the next part is crucial
dmsetup-slx-device "$read_only_partition"
# endregion

}
exceptions.catch
{
    logging.error "$exceptions_last_traceback"
    emergency_shell "error in ${BASH_SOURCE[0]}"
}
# region vim modline

# vim: set tabstop=4 shiftwidth=4 expandtab:
# vim: foldmethod=marker foldmarker=region,endregion:

# endregion