--- dracut/repo-genrules.sh | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/dracut/repo-genrules.sh b/dracut/repo-genrules.sh index 5f44a13..6ba8dcd 100755 --- a/dracut/repo-genrules.sh +++ b/dracut/repo-genrules.sh @@ -14,6 +14,6 @@ case "$root" in # special catch-all rule for CDROMs echo 'ENV{ID_CDROM}=="1",' \ 'RUN+="/sbin/initqueue --settled --onetime' \ - '/sbin/anaconda-diskroot $env{DEVNAME}"\n' >> $rulesfile + '/sbin/anaconda-diskroot $env{DEVNAME}"' >> $rulesfile ;; esac
copytree() is a function for copying/merging directory trees - useful for stuff like updates images.
dev_is_mounted is confusingly similar to dracut-lib's 'ismounted', so it's been renamed for clarity. --- dracut/anaconda-lib.sh | 8 +++++++- dracut/fetch-kickstart-disk | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/dracut/anaconda-lib.sh b/dracut/anaconda-lib.sh index 115456d..476c6c8 100755 --- a/dracut/anaconda-lib.sh +++ b/dracut/anaconda-lib.sh @@ -80,6 +80,12 @@ anaconda_live_root_dir() {
# These could probably be in dracut-lib or similar
+copytree() { + local src="$1" dest="$2" + mkdir -p "$dest"; dest=$(readlink -f -q "$dest") + ( cd "$src"; cp -a . -t "$dest" ) +} + disk_to_dev_path() { case "$1" in CDLABEL=*|LABEL=*) echo "/dev/disk/by-label/${1#*LABEL=}" ;; @@ -89,7 +95,7 @@ disk_to_dev_path() { esac }
-dev_is_mounted() { +find_mount() { local dev mnt etc wanted_dev="$(readlink -e -q $1)" while read dev mnt etc; do [ "$dev" = "$wanted_dev" ] && echo $mnt && return 0 diff --git a/dracut/fetch-kickstart-disk b/dracut/fetch-kickstart-disk index 9650241..3172049 100755 --- a/dracut/fetch-kickstart-disk +++ b/dracut/fetch-kickstart-disk @@ -11,7 +11,7 @@ path="${2:-/ks.cfg}" [ -b "$dev" ] || exit 1
info "anaconda: fetching kickstart from $dev:$path" -mnt="$(dev_is_mounted $dev)" +mnt="$(find_mount $dev)"
if [ -n "$mnt" ]; then cp $mnt$path /tmp/ks.cfg
Since we've removed all UI from initramfs, plain 'updates' no longer works if you want to load an updates image from disk.
This adds support for fetching updates images, much the same way as we do with kickstarts.
Note that I'd really like to merge all the *-genrules.sh / fetch-*-disk junk, but time is short.. --- dracut/Makefile.am | 4 +++- dracut/anaconda-lib.sh | 4 ++++ dracut/fetch-updates-disk | 33 +++++++++++++++++++++++++++++++++ dracut/module-setup.sh | 2 ++ dracut/parse-anaconda-options.sh | 16 ++++++++++++---- dracut/updates-genrules.sh | 21 +++++++++++++++++++++ 6 files changed, 75 insertions(+), 5 deletions(-) create mode 100755 dracut/fetch-updates-disk create mode 100755 dracut/updates-genrules.sh
diff --git a/dracut/Makefile.am b/dracut/Makefile.am index 2efe38d..0324766 100644 --- a/dracut/Makefile.am +++ b/dracut/Makefile.am @@ -26,13 +26,15 @@ dist_dracut_SCRIPTS = module-setup.sh \ parse-anaconda-kickstart.sh \ parse-anaconda-net.sh \ repo-genrules.sh \ - anaconda-udevprop.sh \ kickstart-genrules.sh \ + updates-genrules.sh \ + anaconda-udevprop.sh \ anaconda-netroot.sh \ anaconda-diskroot \ anaconda-copy-ks.sh \ fetch-kickstart-net.sh \ fetch-kickstart-disk \ + fetch-updates-disk \ parse-kickstart \ anaconda-modprobe.sh
diff --git a/dracut/anaconda-lib.sh b/dracut/anaconda-lib.sh index 476c6c8..49c4f9e 100755 --- a/dracut/anaconda-lib.sh +++ b/dracut/anaconda-lib.sh @@ -188,3 +188,7 @@ run_kickstart() { wait_for_kickstart() { echo "[ -e /tmp/ks.cfg.done ]" > $hookdir/initqueue/finished/kickstart.sh } + +wait_for_updates() { + echo "[ -e /tmp/liveupdates.done ]" > $hookdir/initqueue/finished/updates.sh +} diff --git a/dracut/fetch-updates-disk b/dracut/fetch-updates-disk new file mode 100755 index 0000000..168fe5d --- /dev/null +++ b/dracut/fetch-updates-disk @@ -0,0 +1,33 @@ +#!/bin/bash +# fetch-updates-disk - fetch updates from a block device + +command -v getarg >/dev/null || . /lib/dracut-lib.sh +command -v unpack_updates_img >/dev/null || . /lib/anaconda-lib.sh + +dev="$1" +path="${2:-/updates.img}" + +[ -d "$path" ] && path=$path/updates.img +[ -b "$dev" ] || exit 1 + +info "anaconda: fetching updates from $dev:$path" + +mnt="$(find_mount $dev)" +if [ -n "$mnt" ]; then + cp $mnt$path /tmp/updates.img +else + tmpmnt="$(mkuniqdir /run/install tmpmnt)" + if mount -o ro $dev $tmpmnt; then + cp $tmpmnt$path /tmp/updates.img + umount $tmpmnt + fi + rmdir $tmpmnt +fi + +if [ -f /tmp/updates.img ]; then + unpack_updates_img /tmp/updates.img /updates + rm /tmp/updates.img + echo "$dev:$path" >> /tmp/liveupdates.done +else + warn "anaconda: failed to get updates from $dev:$path" +fi diff --git a/dracut/module-setup.sh b/dracut/module-setup.sh index ceac67f..39ecc58 100755 --- a/dracut/module-setup.sh +++ b/dracut/module-setup.sh @@ -24,6 +24,7 @@ install() { inst_hook cmdline 28 "$moddir/parse-anaconda-net.sh" inst_hook pre-udev 40 "$moddir/repo-genrules.sh" inst_hook pre-udev 40 "$moddir/kickstart-genrules.sh" + inst_hook pre-udev 40 "$moddir/updates-genrules.sh" inst_hook pre-trigger 40 "$moddir/anaconda-udevprop.sh" inst_hook initqueue/online 80 "$moddir/anaconda-netroot.sh" inst "$moddir/anaconda-diskroot" "/sbin/anaconda-diskroot" @@ -31,6 +32,7 @@ install() { # kickstart parsing, WOOOO inst_hook initqueue/online 10 "$moddir/fetch-kickstart-net.sh" inst "$moddir/fetch-kickstart-disk" "/sbin/fetch-kickstart-disk" + inst "$moddir/fetch-updates-disk" "/sbin/fetch-updates-disk" inst "$moddir/parse-kickstart" "/sbin/parse-kickstart" # python deps for parse-kickstart. DOUBLE WOOOO $moddir/python-deps $moddir/parse-kickstart | while read dep; do diff --git a/dracut/parse-anaconda-options.sh b/dracut/parse-anaconda-options.sh index 0076fce..1343ebc 100755 --- a/dracut/parse-anaconda-options.sh +++ b/dracut/parse-anaconda-options.sh @@ -101,10 +101,18 @@ warn_renamed_arg "kssendmac" "inst.ks.sendmac" warn_renamed_arg "kssendsn" "inst.ks.sendsn"
# updates -warn_renamed_arg "updates" "inst.updates" -updates=$(getarg updates inst.updates) -if [ -n "$updates" ]; then - echo "live.updates=$updates" >> /etc/cmdline.d/75-anaconda-options.conf +warn_renamed_arg "updates=" "inst.updates" +if updates=$(getarg updates inst.updates); then + if [ -n "$updates" ]; then + export anac_updates=$updates + case $updates in + http*|ftp*|nfs*) + echo "live.updates=$updates" \ + >> /etc/cmdline.d/75-anaconda-options.conf ;; + esac + else + warn "'updates' requires a location for the updates disk" + fi fi
# make sure we get ifcfg for every interface that comes up diff --git a/dracut/updates-genrules.sh b/dracut/updates-genrules.sh new file mode 100755 index 0000000..14273df --- /dev/null +++ b/dracut/updates-genrules.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# generate udev rules for fetching updates + +updates=$anac_updates +case $updates in + # updates=<url>: handled by livenet's fetch-liveupdate.sh + http*|ftp*|nfs*) + wait_for_updates + ;; + # updates=<disk>:<path> + # <disk> is sdb, /dev/sdb, LABEL=xxx, UUID=xxx + # <path> defaults to /updates.img if missing + *) + # accept hd:<dev>:<path> (or cdrom:<dev>:<path>) + updates=${updates#hd:}; updates=${updates#cdrom:} + splitsep ":" "$updates" dev path + dev=$(disk_to_dev_path $dev) + when_diskdev_appears $dev fetch-updates-disk $env{DEVNAME} $path + wait_for_updates + ;; +esac
So, loader used to look for updates.img/product.img/RHUpdates under whatever path it was given for the stage2 image. We need product.img for variant installers (like the RHEL installer) so we need to look for these things.
Add the anaconda_auto_updates() function to look for these things and put them in the appropriate places. Also add unpack_updates_img() as a helper for cleanly unpacking updates images. --- dracut/anaconda-lib.sh | 32 +++++++++++++++++++++++++++++++- 1 files changed, 31 insertions(+), 1 deletions(-)
diff --git a/dracut/anaconda-lib.sh b/dracut/anaconda-lib.sh index 49c4f9e..a045bab 100755 --- a/dracut/anaconda-lib.sh +++ b/dracut/anaconda-lib.sh @@ -1,5 +1,7 @@ #!/bin/bash
+command -v unpack_img >/dev/null || . /lib/img-lib.sh + # config_get SECTION KEY < FILE # read an .ini-style config file, find the KEY in the given SECTION, and return # the value provided for that key. @@ -48,14 +50,16 @@ rulesfile="/etc/udev/rules.d/90-anaconda.rules" # try to find a usable runtime image from the repo mounted at $mnt. # if successful, move the mount(s) to $repodir/$isodir. anaconda_live_root_dir() { - local img="" iso="" mnt="$1" path="$2"; shift 2 + local img="" iso="" srcdir="" mnt="$1" path="$2"; shift 2 img=$(find_runtime $mnt/$path) if [ -n "$img" ]; then info "anaconda: found $img" [ "$mnt" = "$repodir" ] || mount --move $mnt $repodir + anaconda_auto_updates $repodir/$path/images else if [ "${path%.iso}" != "$path" ]; then iso=$path + path=${path%/*.iso} else iso=$(find_iso $mnt/$path) fi @@ -65,6 +69,7 @@ anaconda_live_root_dir() { iso=${isodir}/${iso#$mnt} mount -o loop,ro $iso $repodir img=$(find_runtime $repodir) || { warn "$iso has no suitable runtime"; } + anaconda_auto_updates $isodir/$path/images fi # FIXME: make rd.live.ram clever enough to do this for us if [ "$1" = "--copy-to-ram" ]; then @@ -78,6 +83,31 @@ anaconda_live_root_dir() { [ -e "$img" ] && /sbin/dmsquash-live-root $img }
+# find updates.img/product.img/RHUpdates and unpack/copy them so they'll +# end up in the location(s) that anaconda expects them +anaconda_auto_updates() { + local dir="$1" + if [ -d $dir/RHupdates ]; then + copytree $dir/RHupdates /updates + fi + if [ -e $dir/updates.img ]; then + unpack_updates_img $dir/updates.img /updates + fi + if [ -e $dir/product.img ]; then + unpack_updates_img $dir/product.img /updates/tmp/product + fi +} + +# Unpack an image into the given dir. +unpack_updates_img() { + local img="$1" tmpdir="/tmp/${1##*/}.$$" outdir="${2:+/updates}" + # NOTE: unpack_img $img $outdir can clobber existing subdirs in $outdir, + # which is why we use a tmpdir and copytree (which doesn't clobber) + unpack_img $img $tmpdir + copytree $tmpdir $outdir + rm -rf $tmpdir +} + # These could probably be in dracut-lib or similar
copytree() {
Ack to all of these.
anaconda-devel@lists.stg.fedoraproject.org