summaryrefslogtreecommitdiffstats
path: root/builder/dnbd3-rootfs/hooks/prepare-root-partition.sh
blob: 885689952df21f6f3e251e3418fea32e12d48455 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/usr/bin/env bash
# region imports
type getarg >/dev/null 2>&1 || source /lib/dracut-lib.sh
source "/usr/lib/rebash/core.sh"
core.import exceptions
exceptions.activate
core.import utils
core.import logging
logging.set_commands_level debug
logging.set_level debug
# endregion
( # subshell for variable scoping

SLX_SERVER_BASE="$(getargs slxbase=)"
source /etc/openslx

# region find writable partition
if ! persistent_device=$(utils.find_block_device \
        "$SLX_WRITABLE_DEVICE_IDENTIFIER"); then
    logging.warn "Failed to find unique device with identifier" \
        "'${SLX_WRITABLE_DEVICE_IDENTIFIER}'; matched devices:" \
        "'${persistent_device}'"
fi

# TODO move somewhere else
#tmp_device="$(utils.find_block_device \
    #'$SLX_TMP_PARTITION_IDENTIFIER')"

#if [ -n $tmp_device ]; then
    #mount --type auto "$tmp_device" "$NEWROOT/tmp"
#fi

persistent='N' # 'P' for persistent storage, 'N' for not persistent
if [ -n "$persistent_device" ]; then
    writable_device="$persistent_device"
    if [ "$SLX_WRITABLE_DEVICE_PERSISTENT" = "yes" ]; then
        persistent='P'
    fi
else
    ramdisk_size="$SLX_RAMDISK_SIZE"
    if [ "$ramdisk_size" = "" ]; then
        ramdisk_size="$(cat /proc/meminfo | awk '/MemTotal/ {print $2}')"
    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"
    #writable_device='/dev/ram0'
    ramdisk_location="$(mktemp)"
    dd of="$ramdisk_location" seek="$ramdisk_size" count=0 1>/dev/null
    writable_device="$(losetup --find)"
    losetup "$writable_device" "$ramdisk_location"
    #
    persistent='N'
fi

# persistent storage on a filesystem (e.g. usb stick)
# writable_device="$(losetup --find)"
#dd if=/dev/zero of=persistent_storage.img bs=1k count=1000
#losetup "$writable_device" persistent_storage.img
#persistent='P'

# 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}' from" \
        "one of '$SLX_DNBD3_SERVERS' to '$SLX_DNBD3_DEVICE'."
    exit 1
fi
# endregion

# region scan partitions
read_only_device=""
if utils.dependency_check qemu-img && ! qemu-img info \
    "$SLX_DNBD3_DEVICE" | grep 'file format: raw'
then
    read_only_device="$(container-unpack-xmount $SLX_DNBD3_DEVICE)"
else
    # Workaround to detect partitions on raw disks can be omitted when the
    # dnbd3 kernel module supports it (like the nbd kernel module with
    # parameter "max_part").
    loop_device="$(losetup --find)"
    losetup "$loop_device" "$SLX_DNBD3_DEVICE" --partscan
    read_only_device="$loop_device"
    touch "$read_only_device"
    udevadm settle
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
    read_only_partition="$(utils.find_block_device \
        "$SLX_SYSTEM_PARTITION_IDENTIFIER" "$read_only_device")"
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"

) || exit $?
exceptions.deactivate
# region vim modline

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

# endregion