Skip to content

Commit 28158c7

Browse files
authored
Merge pull request #2814 from OSInside/support_live_http
Update live boot remote boot features
2 parents 49f3320 + 49a8d25 commit 28158c7

File tree

7 files changed

+263
-71
lines changed

7 files changed

+263
-71
lines changed

doc/source/working_with_images/network_live_iso_boot.rst

Lines changed: 94 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -28,67 +28,39 @@ the network:
2828

2929
.. code:: bash
3030
31-
$ mount {exc_image_base_name}.x86_64-{exc_image_version}.iso /mnt
32-
$ cp /mnt/boot/x86_64/loader/initrd /srv/tftpboot/boot/initrd
33-
$ cp /mnt/boot/x86_64/loader/linux /srv/tftpboot/boot/linux
34-
$ umount /mnt
31+
$ mount {exc_image_base_name_live}.x86_64-{exc_image_version}.iso /mnt
32+
$ cp /mnt/boot/x86_64/loader/initrd /srv/tftpboot/boot/initrd
33+
$ cp /mnt/boot/x86_64/loader/linux /srv/tftpboot/boot/linux
34+
$ umount /mnt
3535
3636
.. note::
3737

38-
This step must be repeated with any new build of the live ISO image
38+
This step must be repeated with any new build of the live ISO image
3939

4040
2. Export Live ISO To The Network
4141

42-
Access to the live ISO file is implemented using the AoE protocol
43-
in {kiwi}. This requires the export of the live ISO file as remote
44-
block device which is typically done with the :command:`vblade`
45-
toolkit. Install the following package on the system which is
46-
expected to export the live ISO image:
42+
Access to the live ISO file must be provided by either `ftp`,
43+
`http`, `https` or `dolly`. The most simple method is to setup a FTP server
44+
e.g. `vsftpd` and copy the live ISO file to the data directory:
4745

4846
.. code:: bash
4947
50-
$ zypper in vblade
48+
$ mkdir -p /srv/ftp/image
49+
$ cp {exc_image_base_name_live}.x86_64-{exc_image_version}.iso /srv/ftp/image
5150
5251
.. note::
5352

54-
Not all versions of AoE are compatible with any kernel. This
55-
means the kernel on the system exporting the live ISO image
56-
must provide a compatible aoe kernel module compared to the
57-
kernel used in the live ISO image.
58-
59-
Once done, export the live ISO image as follows:
60-
61-
.. code:: bash
62-
63-
$ vbladed 0 1 INTERFACE {exc_image_base_name}.x86_64-{exc_image_version}.iso
64-
65-
The above command exports the given ISO file as a block storage
66-
device to the network of the given INTERFACE. On any machine
67-
except the one exporting the file, it will appear as
68-
:file:`/dev/etherd/e0.1` once the :command:`aoe` kernel module
69-
was loaded. The two numbers, 0 and 1 in the above example, classifies
70-
a major and minor number which is used in the device node name
71-
on the reading side, in this case :file:`e0.1`. The numbers given
72-
at export time must match the AOEINTERFACE name as described in
73-
the next step.
74-
75-
.. note::
76-
77-
Only machines in the same network of the given INTERFACE
78-
can see the exported live ISO image. If virtual machines
79-
are the target to boot the live ISO image they could all
80-
be connected through a bridge. In this case INTERFACE
81-
is the bridge device. The availability scope of the live
82-
ISO image on the network is in general not influenced
83-
by {kiwi} and is a task for the network administrators.
53+
Check if the image can be downloaded via:
54+
`wget ftp://IP/image/{exc_image_base_name_live}.x86_64-{exc_image_version}.iso`
55+
before the next step.
8456

8557
3. Setup live ISO boot entry in PXE configuration
8658

8759
.. note::
8860

89-
The following step assumes that the pxelinux.0 loader
90-
has been configured on the boot server to boot up network
91-
clients
61+
The following step assumes that the pxelinux.0 loader
62+
has been configured on the boot server to boot up network
63+
clients
9264

9365
Edit the file :file:`/srv/tftpboot/pxelinux.cfg/default` and create
9466
a boot entry of the form:
@@ -97,22 +69,91 @@ the network:
9769
9870
LABEL Live-Boot
9971
kernel boot/linux
100-
append initrd=boot/initrd rd.kiwi.live.pxe root=live:AOEINTERFACE=e0.1
72+
append initrd=boot/initrd ip=dhcp root=live:ftp://IP/image/{exc_image_base_name_live}.x86_64-{exc_image_version}.iso
10173
102-
* The boot parameter `rd.kiwi.live.pxe` tells the {kiwi} boot process to
103-
setup the network and to load the required :mod:`aoe` kernel module.
74+
* The `ip=` parameter controls how the dracut network module sets up
75+
the network. Several options exists to control how the network
76+
interface should be setup. Please consult the dracut manual
77+
for further information.
10478

105-
* The boot parameter `root=live:AOEINTERFACE=e0.1` specifies the
106-
interface name as it was exported by the :command:`vbladed` command
107-
from the last step. Currently only AoE (Ata Over Ethernet)
108-
is supported.
79+
* The boot parameter `root=live:PROTOCOL://IP/PATH...` specifies the
80+
remote endpoint and protocol to find the live ISO file. So far
81+
`ftp`, `http`, `https` and `dolly` are supported.
10982

11083
4. Boot from the Network
11184

11285
Within the network which has access to the PXE server and the
113-
exported live ISO image, any network client can now boot the
86+
IP in the root= option, any network client can now boot the
11487
live system. A test based on QEMU is done as follows:
11588

11689
.. code:: bash
11790
118-
$ sudo qemu -boot n
91+
$ qemu -boot n
92+
93+
Available Remote Boot Options
94+
-----------------------------
95+
96+
There are the following kernel boot options available to control
97+
the behavior of the remote boot process.
98+
99+
rd.kiwi.live.curl_options=
100+
Options passed along to the curl call
101+
102+
rd.kiwi.live.dolly_options=
103+
Options passed along to the dolly call
104+
105+
rd.kiwi.live.system=
106+
Block device to use for the system. By default this is set to `/dev/ram0`
107+
108+
ramdisk_size=bytes
109+
Size of the ramdisk in bytes. By default this is set to 2097152 (2G)
110+
111+
rd.kiwi.live.reset
112+
Force reset of the live system. This option only makes sense if
113+
the live system device (rd.kiwi.live.system) points to a persistent
114+
storage device. In this case {kiwi} loads the system only once
115+
and does not overwrite it unless a reset is requested.
116+
117+
Persistent Live System
118+
----------------------
119+
120+
The remote boot process of a live ISO image, places the ISO file
121+
into a ramdisk by default. This means all data lives in memory and
122+
is not persistent. In order to boot up the live system from a remote
123+
location and keep it on a persistent storage, it's required to
124+
pass the `rd.kiwi.live.system` boot option with the device name
125+
pointing to that persistent storage.
126+
127+
.. warning::
128+
129+
All data on the device given via `rd.kiwi.live.system` will be wiped
130+
131+
A test based on QEMU is done as follows:
132+
133+
Edit the file :file:`/srv/tftpboot/pxelinux.cfg/default` and create
134+
a boot entry of the form:
135+
136+
.. code:: bash
137+
138+
LABEL Live-Boot
139+
kernel boot/linux
140+
append initrd=boot/initrd ip=dhcp root=live:ftp://IP/image/{exc_image_base_name_live}.x86_64-{exc_image_version}.iso ramdisk_size=3545728 rd.kiwi.live.system=/dev/sda rd.live.overlay.persistent rd.live.overlay.cowfs=xfs
141+
142+
* The `rd.live.overlay.persistent` and `rd.live.overlay.cowfs=xfs`
143+
options are standard {kiwi} live ISO options to control if and how a
144+
persistent write partition should be created. The options only take
145+
an effect when booting into a persistent storage device.
146+
147+
Next create a persistent storage disk of 3G and attach it to the
148+
QEMU instance.
149+
150+
.. code:: bash
151+
152+
$ qemu-img create mydisk.raw 3G
153+
$ qemu -boot n -hda mydisk.raw
154+
155+
The live system will be deployed once to the locally attached disk and
156+
boots from it. Any subsequent boot process will not modify the local
157+
disk unless `rd.kiwi.live.reset` is passed on the kernel command line.
158+
If deployed there is also no need for the network anymore and the
159+
system could also boot standalone.

dracut/modules.d/90kiwi-live/kiwi-generator.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ case "${liveroot}" in
2222
root="${root//\//\\x2f}"
2323
root="live:aoe:/dev/etherd/${root#AOEINTERFACE=}"
2424
rootok=1 ;;
25+
live:ftp:*|live:http:*|live:https:*|live:dolly:*) \
26+
root="${root#live:}"
27+
root="live:net:${root}"
28+
rootok=1 ;;
2529
esac
2630

2731
[ "${rootok}" != "1" ] && exit 0

dracut/modules.d/90kiwi-live/kiwi-live-genrules.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#!/bin/bash
22

3+
# shellcheck disable=SC1091
4+
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
5+
36
declare root=${root}
47

58
case "${root}" in
@@ -22,4 +25,16 @@ case "${root}" in
2225
} >> /etc/udev/rules.d/99-live-aoe-kiwi.rules
2326
wait_for_dev -n "${root#live:aoe:}"
2427
;;
28+
live:net:*)
29+
system=$(getarg rd.kiwi.live.system=)
30+
if [ -z "${system}" ];then
31+
system=/dev/ram0
32+
fi
33+
{
34+
printf 'KERNEL=="%s", RUN+="/sbin/initqueue %s %s %s"\n' \
35+
"${system#/dev/}" "--settled --onetime --unique" \
36+
"/sbin/kiwi-live-root" "${root}"
37+
} >> /etc/udev/rules.d/99-live-net-kiwi.rules
38+
wait_for_dev -n "${system}"
39+
;;
2540
esac

dracut/modules.d/90kiwi-live/kiwi-live-lib.sh

Lines changed: 139 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,60 @@ function getOverlayBaseDirectory {
1515
echo "${overlay_base}"
1616
}
1717

18+
function ProvideIso {
19+
local root=$1
20+
local iso_url=${root#live:net:}
21+
local system
22+
local rd_size
23+
local custom_rd_size
24+
local modfile=/etc/modprobe.d/99-brd.conf
25+
system=$(getarg rd.kiwi.live.system=)
26+
if [ ! -b "${system}" ];then
27+
system=/dev/ram0
28+
fi
29+
ptable=$(blkid -s PTTYPE -o value "${system}" 2>/dev/null)
30+
case "${iso_url}" in
31+
ftp:*|http:*|https:*|dolly:*) \
32+
if [ -z "${ptable}" ] || getargbool 0 rd.kiwi.live.reset; then
33+
custom_rd_size=$(getarg ramdisk_size=)
34+
if [ -n "${custom_rd_size}" ];then
35+
rd_size="${custom_rd_size}"
36+
else
37+
# set minimum default ramdisk size: 2G
38+
rd_size="2097152"
39+
fi
40+
mkdir -p /etc/modprobe.d
41+
if [ -n "${rd_size}" ];then
42+
echo "options brd rd_size=${rd_size}" > ${modfile}
43+
fi
44+
modprobe --remove brd
45+
modprobe brd
46+
udev_pending
47+
fetch_file "${iso_url}" | dd bs=32k of="${system}" &>/dev/null
48+
fi
49+
if [[ ${system} =~ ^/dev/ram ]];then
50+
echo "${system}"
51+
else
52+
udev_pending
53+
# This is not 100% safe as in theory the volume ID
54+
# of the live ISO could be configured in the kiwi image
55+
# description and doesn't have to be set to: CDROM.
56+
# The value could be obtained as follows:
57+
# label=$(
58+
# isoinfo -j utf-8 -d -i ${system} |\
59+
# grep "Volume id:" | cut -f2 -d:
60+
# )
61+
# but this would require an additional tool as part of the
62+
# initrd. Thus this is subject to a followup pull request
63+
echo "/dev/disk/by-label/CDROM"
64+
fi
65+
;;
66+
*) \
67+
echo "${root}"
68+
;;
69+
esac
70+
}
71+
1872
function lookupIsoDiskDevice {
1973
local root=$1
2074
local iso_label=${root#/dev/disk/by-label/}
@@ -276,9 +330,73 @@ function runMediaCheck {
276330
fi
277331
}
278332

333+
function fetch_file {
334+
# Fetch file from remote location
335+
local source_url=$1
336+
local source_uncompressed_bytes=$2
337+
local fetch_info=/tmp/fetch.info
338+
local fetch
339+
local curl_options
340+
local dolly_options
341+
curl_options=$(getarg rd.kiwi.live.curl_options=)
342+
dolly_options=$(getarg rd.kiwi.live.dolly_options=)
343+
if [ -n "${curl_options}" ]; then
344+
curl_options=$(str_replace "${curl_options}" "," " ")
345+
fetch="curl ${curl_options} -f ${source_url}"
346+
else
347+
fetch="curl -f ${source_url}"
348+
fi
349+
if [ -n "${dolly_options}" ]; then
350+
dolly_options=$(str_replace "${dolly_options}" "," " ")
351+
fetch="dolly ${dolly_options} -f ${source_url}"
352+
fi
353+
if _is_dolly "${source_url}";then
354+
fetch="dolly"
355+
fi
356+
if _is_xz_compressed "${source_url}";then
357+
fetch="${fetch} | xz -d"
358+
fi
359+
if [ -z "${source_uncompressed_bytes}" ];then
360+
eval "${fetch}" 2>${fetch_info}
361+
else
362+
eval "${fetch}" 2>${fetch_info} |\
363+
pv --size "${source_uncompressed_bytes}" --stop-at-size -n
364+
fi
365+
return "${PIPESTATUS[0]}"
366+
}
367+
368+
function show_log_and_quit {
369+
local text_message="$1"
370+
local log_file="$2"
371+
local timeout
372+
timeout=$(_dialog_timeout)
373+
if [ "${timeout}" = "off" ];then
374+
_run_dialog --backtitle "\"${text_message}\"" \
375+
--textbox "${log_file}" 15 80
376+
else
377+
_run_dialog --timeout "${timeout}" --backtitle "\"${text_message}\"" \
378+
--textbox "${log_file}" 15 80
379+
fi
380+
if getargbool 0 rd.debug; then
381+
die "${text_message}"
382+
else
383+
reboot -f
384+
fi
385+
}
386+
279387
#=========================================
280388
# Methods considered private
281389
#-----------------------------------------
390+
function _is_xz_compressed {
391+
local source_url=$1
392+
[[ ${source_url} =~ .xz$ ]]
393+
}
394+
395+
function _is_dolly {
396+
local source_url=$1
397+
[[ ${source_url} =~ ^dolly ]]
398+
}
399+
282400
function _setup_interactive_service {
283401
local service=/run/systemd/system/dracut-run-interactive.service
284402
mkdir -p /run/systemd/system
@@ -312,9 +430,29 @@ function _run_interactive {
312430
systemctl start dracut-run-interactive.service
313431
}
314432

433+
function _dialog_timeout {
434+
local timeout=60
435+
custom_timeout=$(getarg "rd.kiwi.dialog.timeout=")
436+
[ -n "${custom_timeout}" ] && timeout="${custom_timeout}"
437+
echo "${timeout}"
438+
}
439+
315440
function _run_dialog {
316-
echo "dialog $*" >/run/dracut-interactive
441+
# """
442+
# Run the dialog program via the systemd service either in a
443+
# framebuffer terminal or on the console. The return code of
444+
# the function is the return code of the dialog call. The
445+
# output of the dialog call is stored in a file and can be
446+
# one time read via the get_dialog_result function
447+
# """
448+
local dialog_result=/tmp/dialog_result
449+
local dialog_exit_code=/tmp/dialog_code
450+
{
451+
echo "dialog $* 2>$dialog_result"
452+
echo "echo -n \$? >$dialog_exit_code"
453+
} >/run/dracut-interactive
317454
_run_interactive
455+
return "$(cat $dialog_exit_code)"
318456
}
319457

320458
function _partition_count {

0 commit comments

Comments
 (0)