blob: 619226f594ffce02c7d996bc3ade63834c6cfcfe (
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
|
#!/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
exceptions.try
{
# region connect dnbd3 image
(
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" \
${SLX_DNBD3_RID:+--rid "$SLX_DNBD3_RID"}; then
break
fi
done
)
# endregion
# region unpack dnbd3 image
[ -z "$SLX_QCOW_HANDLER" ] && SLX_QCOW_HANDLER="xmount"
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.
[ -z "$read_only_device" ] && exit 1
# endregion
# region find system partition within dnbd3 image
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="$(slx-tools dev_find_partitions \
"$read_only_device" "$SLX_SYSTEM_PARTITION_IDENTIFIER")"
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
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
|