diff options
Diffstat (limited to 'builder/modules.d/dnbd3-rootfs/hooks/prepare-root-partition.sh')
-rwxr-xr-x | builder/modules.d/dnbd3-rootfs/hooks/prepare-root-partition.sh | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/builder/modules.d/dnbd3-rootfs/hooks/prepare-root-partition.sh b/builder/modules.d/dnbd3-rootfs/hooks/prepare-root-partition.sh new file mode 100755 index 00000000..3e93253f --- /dev/null +++ b/builder/modules.d/dnbd3-rootfs/hooks/prepare-root-partition.sh @@ -0,0 +1,163 @@ +#!/usr/bin/env bash +# region imports +source '/usr/lib/rebash/core.sh' +core.import '/usr/lib/openslx/tools.sh' +core.import exceptions +core.import utils +core.import logging +type emergency_shell >/dev/null 2>&1 || source /lib/dracut-lib.sh +# endregion +exceptions.try +{ +source /etc/openslx +logging.set_commands_level debug +logging.set_level debug +[[ "$SLX_LOG_FILE_PATH" == "" ]] && SLX_LOG_FILE_PATH=/var/log/openslx +logging.set_log_file "$SLX_LOG_FILE_PATH" + +# region find writable partition +if [[ "$SLX_WRITABLE_DEVICE_IDENTIFIER" != '' ]] && + ! persistent_device="$( + tools.find_block_device "$SLX_WRITABLE_DEVICE_IDENTIFIER" '' \ + "$SLX_WRITABLE_DEVICE_IDENTIFIER_TIMEOUT_IN_SECONDS" + )" +then + logging.warn "Failed to find unique device with identifier" \ + "\"${SLX_WRITABLE_DEVICE_IDENTIFIER}\"; matched devices:" \ + "\"${persistent_device}\"" +fi +if [ -n "$SLX_WRITABLE_DEVICE_STORAGE_FILE_PATH" ] && [ -n "$persistent_device" ] +then + persistent_mountpoint=/mnt/slx_writable_device + storage_file_path="${persistent_mountpoint}/$SLX_WRITABLE_DEVICE_STORAGE_FILE_PATH" + ! mkdir --parents "$(dirname "$storage_file_path")" + if ! mount --type auto "$persistent_device" "$persistent_mountpoint"; then + logging.warn "Failed to mount $persistent_device, checking filesystem." + ! $SLX_WRITABLE_DEVICE_STORAGE_FILESYSTEM_CHECK_COMMAND \ + "$persistent_device" + if ! mount --type auto "$persistent_device" "$persistent_mountpoint" + then + logging.warn "Mounting $persistent_device, still failing," \ + "creating new filesystem on device" + $SLX_WRITABLE_DEVICE_STORAGE_FILESYSTEM_CREATE_COMMAND \ + "$persistent_device" + fi + if ! mount --type auto "$persistent_device" "$persistent_mountpoint" + then + logging.warn "Mounting $persistent_device, still failing," \ + "giving up, and using ramdisk" + persistent_device="" + fi + fi + if [ -n "$persistent_device" ]; then + if [ ! -e "$storage_file_path" ]; then + # Create a sparse file. + dd of="$storage_file_path" bs=1M \ + seek="$SLX_WRITABLE_DEVICE_STORAGE_MAXIMUM_FILE_SIZE_IN_MB" count=0 + fi + persistent_device="$(losetup --find)" + losetup "$persistent_device" "$storage_file_path" + fi +fi + +# "P" for persistent storage, "N" for not persistent (affects dmsetup call, +# see scripts/device-add-write-layer.sh) +persistent='N' +if [ -n "$persistent_device" ]; then + writable_device="$persistent_device" + if [ "$SLX_WRITABLE_DEVICE_PERSISTENT" = "yes" ]; then + persistent='P' + fi +else + ramdisk_size_in_kb="$SLX_RAMDISK_SIZE_IN_KB" + if [ "$ramdisk_size_in_kb" = '' ]; then + ramdisk_size_in_kb="$(awk '/MemTotal/ {print $2}' /proc/meminfo)" + fi + # NOTE: If the kernel modul "brd" is compiled into current kernel we can't + # configure ram disk size dynamically. In this case it have to be + # configured via kernel command line: "brd.rd_size=SITE_IN_KILOBYTE" + # statically: + #! rmmod brd 2>/dev/null + #modprobe brd max_part=1 rd_size="$ramdisk_size_in_kb" + #writable_device='/dev/ram0' + ramdisk_location="$(mktemp)" + dd of="$ramdisk_location" seek="$ramdisk_size_in_kb" count=0 1>/dev/null + writable_device="$(losetup --find)" + losetup "$writable_device" "$ramdisk_location" +fi +# endregion +# region connect dnbd3 +IFS_backup="$IFS" +IFS="," +return_code=1 +for host in ${SLX_DNBD3_SERVERS}; do + logging.info "Trying host \"$host\"." + if systemd-preserve-process-marker dnbd3-client --host "$host" --image \ + "${SLX_DNBD3_IMAGE}" --device "$SLX_DNBD3_DEVICE" \ + --rid "$SLX_DNBD3_RID" + then + return_code=0 + break + fi +done +IFS="$IFS_backup" + +if [[ $return_code != 0 ]]; then + logging.warn "Failed to connect \"${SLX_DNBD3_IMAGE}\" (revision" \ + "\"$SLX_DNBD3_RID\") from one of \"$SLX_DNBD3_SERVERS\" to" \ + "\"$SLX_DNBD3_DEVICE\"." + exit 1 +fi +# endregion +# region scan partitions +if [ "$SLX_LOG_FILE_PATH" != "" ]; then + read_only_device="$(container-unpack-xmount "$SLX_DNBD3_DEVICE" \ + 2>>"$SLX_LOG_FILE_PATH")" +else + read_only_device="$(container-unpack-xmount "$SLX_DNBD3_DEVICE")" +fi + + +# Fail fast if no device could be determined. +[ -z "$read_only_device" ] && exit 1 +# endregion +# region find read-only partition +if [ -z "$SLX_SYSTEM_PARTITION_PREPARATION_SCRIPT" ]; then + if [ -z "$SLX_SYSTEM_PARTITION_IDENTIFIER" ]; then + # if empty use whole device + read_only_partition="$read_only_device" + true + else + read_only_partition="$(tools.find_block_device \ + "$SLX_SYSTEM_PARTITION_IDENTIFIER" "$read_only_device")" + fi +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 +# endregion + +logging.info "Using read-only partition: $read_only_partition" +logging.info "Using writable device $writable_device, persistency: $persistent" + +# combine devices with device mapper +device-add-write-layer "root" "$read_only_partition" "$writable_device" \ + "$persistent" + +} +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 |