[Fedora-livecd-list] Branch 'f17-branch' - tools/livecd-iso-to-disk.sh

Brian C. Lane bcl at fedoraproject.org
Fri Feb 24 02:03:18 UTC 2012


 tools/livecd-iso-to-disk.sh |  248 ++++++++++++++++++++++++++++++--------------
 1 file changed, 171 insertions(+), 77 deletions(-)

New commits:
commit d97c367698d6f43f6a354f7077cbda8373384427
Author: Brian C. Lane <bcl at redhat.com>
Date:   Tue Feb 21 14:55:51 2012 -0800

    livecd-iso-to-disk: create partition for iso
    
    In Fedora 17 the installer runs from the squashfs.img on the install
    media. This means that the installer environment doesn't have direct
    access to the install media, and it cannot mount it.
    
    In order to support writing DVD's to USB sticks we now need to create a
    second partition just for the .iso image and direct the installer to it
    using the repo=UUID=... command
    
    This patch adds creating the 2nd partition if needed and also cleans up
    some of the bootloader config editing code.

diff --git a/tools/livecd-iso-to-disk.sh b/tools/livecd-iso-to-disk.sh
index 2db2903..3ae88a2 100755
--- a/tools/livecd-iso-to-disk.sh
+++ b/tools/livecd-iso-to-disk.sh
@@ -1,7 +1,9 @@
 #!/bin/bash
 # Transfer a Live image so that it's bootable off of a USB/SD device.
-# Copyright 2007  Red Hat, Inc.
+# Copyright 2007-2012  Red Hat, Inc.
+#
 # Jeremy Katz <katzj at redhat.com>
+# Brian C. Lane <bcl at redhat.com>
 #
 # overlay/persistence enhancements by Douglas McClendon <dmc at viros.org>
 # GPT+MBR hybrid enhancements by Stewart Adam <s.adam at diffingo.com>
@@ -274,11 +276,14 @@ cleanup() {
     sleep 2
     [ -d "$SRCMNT" ] && umount $SRCMNT && rmdir $SRCMNT
     [ -d "$TGTMNT" ] && umount $TGTMNT && rmdir $TGTMNT
+    if [ -n "$REPOMNT" ]; then
+        [ -d "$REPOMNT" ] && umount $REPOMNT && rmdir $REPOMNT
+    fi
 }
 
 exitclean() {
     RETVAL=$?
-    if [ -d "$SRCMNT" ] || [ -d "$TGTMNT" ];
+    if [ -d "$SRCMNT" ] || [ -d "$TGTMNT" ] || [ -n "$REPOMNT" ];
     then
         [ "$RETVAL" = 0 ] || echo "Cleaning up to exit..."
         cleanup
@@ -319,13 +324,6 @@ getdisk() {
     partnum=${p##$device}
 }
 
-getpartition() {
-    DEV=$1
-    pa=$( < /proc/partitions )
-    pa=${pa##*$DEV}
-    partnum=${pa%% *}
-}
-
 resetMBR() {
     if isdevloop "$DEV"; then
         return
@@ -423,18 +421,47 @@ createGPTLayout() {
     umount ${device}* &> /dev/null || :
     wipefs -a ${device}
     /sbin/parted --script $device mklabel gpt
-    partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit b print" |grep ^$device:)
-    size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/B$//')
-    /sbin/parted --script $device unit b mkpart '"EFI System Partition"' fat32 1048576 $(($size - 1048576)) set 1 boot on
+    partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit MB print" |grep ^$device:)
+    dev_size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/MB$//')
+
+    # Is a 2nd partition needed for package iso?
+    if [ -n "$packages" ]; then
+        src_size=$(du -s -B 1MB "$SRC" | awk {'print $1;'})
+        # iso size + 7% of slop for filesystem metadata
+        p2_size=$(($src_size * 107 / 100))
+    else
+        p2_size=0
+    fi
+    p1_size=$(($dev_size - 1 - $p2_size))
+
+    if [ $p1_size -le 0 ]; then
+        echo "Your device isn't big enough to hold $SRC"
+        echo "It is $(($p1_size * -1)) MB too small"
+        exitclean
+    fi
+    p1_start=1
+    p1_end=$(($p1_size + 1))
+    /sbin/parted -s $device u MB mkpart '"EFI System Partition"' fat32 $p1_start $p1_end set 1 boot on
+    if [ $p2_size -gt 0 ]; then
+        p2_start=$p1_end
+        p2_end=$(($p2_size + $p2_start))
+        /sbin/parted -s $device u MB mkpart '"LIVE REPO"' fat32 $p2_start $p2_end
+    fi
     # Sometimes automount can be _really_ annoying.
     echo "Waiting for devices to settle..."
     /sbin/udevadm settle
     sleep 5
-    getpartition ${device#/dev/}
-    TGTDEV=${device}${partnum}
+    TGTDEV=${device}1
     umount $TGTDEV &> /dev/null || :
     /sbin/mkdosfs -n LIVE $TGTDEV
     TGTLABEL="UUID=$(/sbin/blkid -s UUID -o value $TGTDEV)"
+
+    if [ $p2_size -gt 0 ]; then
+        REPODEV=${device}2
+        umount $REPODEV &> /dev/null || :
+        /sbin/mkdosfs -n LIVE-REPO $REPODEV
+        REPOLABEL="UUID=$(/sbin/blkid -s UUID -o value $REPODEV)"
+    fi
 }
 
 createMSDOSLayout() {
@@ -447,22 +474,51 @@ createMSDOSLayout() {
     umount ${device}* &> /dev/null || :
     wipefs -a ${device}
     /sbin/parted --script $device mklabel msdos
-    partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit b print" |grep ^$device:)
-    size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/B$//')
-    /sbin/parted --script $device unit b mkpart primary fat32 1048576 $(($size - 1048576)) set 1 boot on
+    partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit MB print" |grep ^$device:)
+    dev_size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/MB$//')
+
+    # Is a 2nd partition needed for package iso?
+    if [ -n "$packages" ]; then
+        src_size=$(du -s -B 1MB "$SRC" | awk {'print $1;'})
+        # iso size + 7% of slop for filesystem metadata
+        p2_size=$(($src_size * 107 / 100))
+    else
+        p2_size=0
+    fi
+    p1_size=$(($dev_size - 1 - $p2_size))
+
+    if [ $p1_size -le 0 ]; then
+        echo "Your device isn't big enough to hold $SRC"
+        echo "It is $(($p1_size * -1)) MB too small"
+        exitclean
+    fi
+    p1_start=1
+    p1_end=$(($p1_size + 1))
+    /sbin/parted -s $device u MB mkpart primary fat32 $p1_start $p1_end set 1 boot on
+    if [ $p2_size -gt 0 ]; then
+        p2_start=$p1_end
+        p2_end=$(($p2_size + $p2_start))
+        /sbin/parted -s $device u MB mkpart primary fat32 $p2_start $p2_end
+    fi
     # Sometimes automount can be _really_ annoying.
     echo "Waiting for devices to settle..."
     /sbin/udevadm settle
     sleep 5
     if ! isdevloop "$DEV"; then
-        getpartition ${device#/dev/}
-        TGTDEV=${device}${partnum}
+        TGTDEV=${device}1
     else
         TGTDEV=${device}
     fi
     umount $TGTDEV &> /dev/null || :
     /sbin/mkdosfs -n LIVE $TGTDEV
     TGTLABEL="UUID=$(/sbin/blkid -s UUID -o value $TGTDEV)"
+
+    if [ $p2_size -gt 0 ]; then
+        REPODEV=${device}2
+        umount $REPODEV &> /dev/null || :
+        /sbin/mkdosfs -n LIVE-REPO $REPODEV
+        REPOLABEL="UUID=$(/sbin/blkid -s UUID -o value $REPODEV)"
+    fi
 }
 
 createEXTFSLayout() {
@@ -474,25 +530,55 @@ createEXTFSLayout() {
     read
     umount ${device}* &> /dev/null || :
     wipefs -a ${device}
-    /sbin/parted --script $device mklabel msdos
-    partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit b print" |grep ^$device:)
-    size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/B$//')
-    /sbin/parted --script $device unit b mkpart primary ext2 1048576 $(($size - 1048576)) set 1 boot on
+    /sbin/parted -s $device mklabel msdos
+    partinfo=$(LC_ALL=C /sbin/parted -s -m $device "u MB print" |grep ^$device:)
+    dev_size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/MB$//')
+
+    # Is a 2nd partition needed for package iso?
+    if [ -n "$packages" ]; then
+        src_size=$(du -s -B 1MB "$SRC" | awk {'print $1;'})
+        # iso size + 7% of slop for filesystem metadata
+        p2_size=$(($src_size * 107 / 100))
+    else
+        p2_size=0
+    fi
+    p1_size=$(($dev_size - 1 - $p2_size))
+
+    if [ $p1_size -le 0 ]; then
+        echo "Your device isn't big enough to hold $SRC"
+        echo "It is $(($p1_size * -1)) MB too small"
+        exitclean
+    fi
+    p1_start=1
+    p1_end=$(($p1_size + 1))
+    /sbin/parted -s $device u MB mkpart primary ext2 $p1_start $p1_end set 1 boot on
+    if [ $p2_size -gt 0 ]; then
+        p2_start=$p1_end
+        p2_end=$(($p2_size + $p2_start))
+        /sbin/parted -s $device u MB mkpart primary ext2 $p2_start $p2_end
+    fi
     # Sometimes automount can be _really_ annoying.
     echo "Waiting for devices to settle..."
     /sbin/udevadm settle
     sleep 5
-    getpartition ${device#/dev/}
-    TGTDEV=${device}${partnum}
+    TGTDEV=${device}1
     umount $TGTDEV &> /dev/null || :
 
     # Check extlinux version
     if extlinux -v 2>&1 | grep -q 'extlinux 3'; then
-        /sbin/mkfs.ext3 -L LIVE $TGTDEV
+        mkfs=/sbin/mkfs.ext3
     else
-        /sbin/mkfs.ext4 -L LIVE $TGTDEV
+        mkfs=/sbin/mkfs.ext4
     fi
+    $mkfs -L LIVE $TGTDEV
     TGTLABEL="UUID=$(/sbin/blkid -s UUID -o value $TGTDEV)"
+
+    if [ $p2_size -gt 0 ]; then
+        REPODEV=${device}2
+        umount $REPODEV &> /dev/null || :
+        $mkfs -L LIVE-REPO $REPODEV
+        REPOLABEL="UUID=$(/sbin/blkid -s UUID -o value $REPODEV)"
+    fi
 }
 
 checkGPT() {
@@ -607,17 +693,24 @@ if [ $(id -u) != 0 ]; then
 fi
 
 detectsrctype() {
-    if [[ -e $SRCMNT/LiveOS/squashfs.img ]]; then
+    if [[ -e "$SRCMNT/Packages" ]]; then
+        # This will cause the source .iso to be copied to a second partiton
+        # on the target and the boot args to have repo=... pointing to the iso
+        echo "/Packages found, will copy source .iso to target"
+        packages=1
+    fi
+    if [[ -e "$SRCMNT/LiveOS/squashfs.img" ]]; then
+        # LiveOS style boot image
         srctype=live
         return
     fi
     if [ -e $SRCMNT/images/install.img -o $SRCMNT/isolinux/initrd.img ]; then
-        imgtype=install
-        if [ -e $SRCMNT/Packages ]; then
+        if [ -n "$packages" ]; then
             srctype=installer
         else
             srctype=netinst
         fi
+        imgtype=install
         if [ ! -e $SRCMNT/images/install.img ]; then
             echo "$SRC uses initrd.img w/o install.img"
             imgtype=initrd
@@ -674,6 +767,7 @@ swapsizemb=0
 overlaysizemb=0
 srctype=
 imgtype=
+packages=
 LIVEOS=LiveOS
 HOMEFILE="home.img"
 
@@ -813,6 +907,19 @@ fi
 # do some basic sanity checks.
 checkMounted $TGTDEV
 
+# FIXME: would be better if we had better mountpoints
+SRCMNT=$(mktemp -d /media/srctmp.XXXXXX)
+if [ -b "$SRC" ]; then
+    mount -o ro "$SRC" $SRCMNT || exitclean
+elif [ -f "$SRC" ]; then
+    mount -o loop,ro "$SRC" $SRCMNT || exitclean
+else
+    echo "$SRC is not a file or block device."
+    exitclean
+fi
+# Figure out what needs to be done based on the source image
+detectsrctype
+
 # Format the device
 if [ -n "$format" -a -z "$skipcopy" ]; then
     checkLVM $TGTDEV
@@ -865,23 +972,15 @@ if [ "$swapsizemb" -gt 0 -a "$TGTFS" = "vfat" ]; then
     fi
 fi
 
-# FIXME: would be better if we had better mountpoints
-SRCMNT=$(mktemp -d /media/srctmp.XXXXXX)
-if [ -b "$SRC" ]; then
-    mount -o ro "$SRC" $SRCMNT || exitclean
-elif [ -f "$SRC" ]; then
-    mount -o loop,ro "$SRC" $SRCMNT || exitclean
-else
-    echo "$SRC is not a file or block device."
-    exitclean
-fi
 TGTMNT=$(mktemp -d /media/tgttmp.XXXXXX)
 mount $mountopts $TGTDEV $TGTMNT || exitclean
+if [ -n "$REPODEV" ]; then
+    REPOMNT=$(mktemp -d /media/repotmp.XXXXXX)
+    mount $mountopts $REPODEV $REPOMNT || exitclean
+fi
 
 trap exitclean SIGINT SIGTERM
 
-detectsrctype
-
 if [ -f "$TGTMNT/$LIVEOS/$HOMEFILE" -a -n "$keephome" -a "$homesizemb" -gt 0 ]; then
     echo "ERROR: Requested keeping existing /home and specified a size for /home"
     echo "Please either don't specify a size or specify --delete-home"
@@ -979,11 +1078,6 @@ fi
 
 # Verify available space for DVD installer
 if [ "$srctype" = "installer" ]; then
-    if [ -z "$skipcopy" ]; then
-        srcsize=$(du -s -B 1M "$SRC" | awk {'print $1;'})
-    else
-        srcsize=0
-    fi
     if [ "$imgtype" = "install" ]; then
         imgpath=images/install.img
     else
@@ -998,10 +1092,9 @@ if [ "$srctype" = "installer" ]; then
     if [ -e $TGTMNT/$(basename "$SRC") ]; then
         tbd=$(($tbd + $(du -s -B 1M $TGTMNT/$(basename "$SRC") | awk {'print $1;'})))
     fi
-    echo "Size of DVD image: $srcsize"
     echo "Size of $imgpath: $installimgsize"
     echo "Available space: $((freespace + tbd))"
-    if (( ((srcsize + installimgsize)) > ((freespace + tbd)) )); then
+    if (( installimgsize > ((freespace + tbd)) )); then
         echo "ERROR: Unable to fit DVD image + install.img on available space on the target device."
         exitclean
     fi
@@ -1051,6 +1144,7 @@ if [ "$srctype" = "live" -a -z "$skipcopy" ]; then
 fi
 
 # DVD installer copy
+# Also copies over the source .iso if the image is a new-style LiveOS DVD (F17+)
 if [ \( "$srctype" = "installer" -o "$srctype" = "netinst" \) ]; then
     echo "Copying DVD image to target device."
     mkdir -p $TGTMNT/images/
@@ -1061,9 +1155,12 @@ if [ \( "$srctype" = "installer" -o "$srctype" = "netinst" \) ]; then
             fi
         done
     fi
-    if [ "$srctype" = "installer" -a -z "$skipcopy" ]; then
-        copyFile "$SRC" $TGTMNT/
-    fi
+fi
+
+# Copy source .iso to repo partition
+if [ -n "$packages" -a -z "$skipcopy" ]; then
+    echo "Copying $SRC"
+    copyFile "$SRC" $REPOMNT/
     sync
 fi
 
@@ -1139,40 +1236,45 @@ if [[ live == $srctype ]]; then
                -e "/^totaltimeout.*$/d" $BOOTCONFIG
     fi
 fi
+
+
 echo "Updating boot config file"
 # adjust label and fstype
-if [ -n "$LANG" ]; then
-    kernelargs="$kernelargs LANG=$LANG"
-fi
 sed -i -e "s/CDLABEL=[^ ]*/$TGTLABEL/" -e "s/rootfstype=[^ ]*/rootfstype=$TGTFS/" -e "s/LABEL=[^ ]*/$TGTLABEL/" $BOOTCONFIG  $BOOTCONFIG_EFI
 if [ -n "$kernelargs" ]; then
-    sed -i -e "s/liveimg/liveimg ${kernelargs}/" $BOOTCONFIG $BOOTCONFIG_EFI
+    sed -i -e "s;initrd.img;initrd.img ${kernelargs};" $BOOTCONFIG
+    if [ -n "$efi" ]; then
+        sed -i -e "s;vmlinuz;vmlinuz ${kernelargs};" $BOOTCONFIG_EFI
+    fi
 fi
 if [ "$LIVEOS" != "LiveOS" ]; then
     sed -i -e "s;liveimg;liveimg live_dir=$LIVEOS;" $BOOTCONFIG $BOOTCONFIG_EFI
 fi
 
-# DVD Installer
-if [ "$srctype" = "installer" ]; then
-    sed -i -e "s;initrd=initrd.img;initrd=initrd.img ${LANG:+LANG=$LANG} repo=hd:$TGTLABEL:/;g" $BOOTCONFIG
-    sed -i -e "s;stage2=\S*;;g" $BOOTCONFIG
+# EFI images are in $SYSLINUXPATH now
+if [ -n "$efi" ]; then
+    sed -i -e "s;/images/pxeboot/;/$SYSLINUXPATH/;g" $BOOTCONFIG_EFI
+    sed -i -e "s;findiso;;g" $BOOTCONFIG_EFI
+fi
+
+# Add repo= to point to the source .iso with the packages
+if [[ -n "$packages" ]]; then
+    sed -i -e "s;initrd.img;initrd.img repo=hd:$REPOLABEL:/;g" $BOOTCONFIG
     if [ -n "$efi" ]; then
-        # Images are in $SYSLINUXPATH now
-        sed -i -e "s;/images/pxeboot/;/$SYSLINUXPATH/;g" -e "s;vmlinuz;vmlinuz ${LANG:+LANG=$LANG} repo=hd:$TGTLABEL:/;g" $BOOTCONFIG_EFI
+        sed -i -e "s;vmlinuz;vmlinuz repo=hd:$REPOLABEL:/;g" $BOOTCONFIG_EFI
     fi
 fi
 
 # DVD Installer for netinst
-if [ "$srctype" = "netinst" ]; then
+if [ "$srctype" != "live" ]; then
     if [ "$imgtype" = "install" ]; then
-        sed -i -e "s;stage2=\S*;stage2=hd:$TGTLABEL:/images/install.img;g" $BOOTCONFIG
+        sed -i -e "s;initrd.img;initrd.img stage2=hd:$TGTLABEL:/images/install.img;g" $BOOTCONFIG
+        if [ -n "$efi" ]; then
+            sed -i -e "s;vmlinuz;vmlinuz stage2=hd:$TGTLABEL:/images/install.img;g" $BOOTCONFIG_EFI
+        fi
     else
         # The initrd has everything, so no stage2
-        sed -i -e "s;stage2=\S*;;g" $BOOTCONFIG
-    fi
-    if [ -n "$efi" ]; then
-        # Images are in $SYSLINUXPATH now
-        sed -ie "s;/images/pxeboot/;/$SYSLINUXPATH/;g" $BOOTCONFIG_EFI
+        sed -i -e "s;stage2=\S*;;g" $BOOTCONFIG $BOOTCONFIG_EFI
     fi
 fi
 
@@ -1184,14 +1286,6 @@ if [ -n "$totaltimeout" ]; then
     sed -i -e "/^timeout.*$/a\totaltimeout\ $totaltimeout" $BOOTCONFIG
 fi
 
-# Use repo if the .iso has the repository on it, otherwise use stage2 which
-# will default to using the network mirror
-if [ -e "$SRCMNT/.discinfo" ]; then
-    METHODSTR=repo
-else
-    METHODSTR=stage2
-fi
-
 if [ "$overlaysizemb" -gt 0 ]; then
     echo "Initializing persistent overlay file"
     OVERFILE="overlay-$( /sbin/blkid -s LABEL -o value $TGTDEV )-$( /sbin/blkid -s UUID -o value $TGTDEV )"




More information about the livecd mailing list