IconsPage/info.png These are scripts to help you customize an Ubuntu installation CD. For more information, see InstallCDCustomization.

Simple example installation script for Breezy

# usage 
# update-learningexchange.sh kubuntu|ubuntu|xubuntu

# a very primitive script with no structure of controls etc
# no default behaviour, etc etc
# all ofthis should be trivial to implement but my 
# bash syntax sucks
# obvious thing to do would be to convert to python
# & add a simple gtk front end too
# but I'm rushed at the moment

# Notes;Bugs:
# REMEMBER: this absolutely will not work if you haven't built a new version of ubuntu-keyring 
# package & included that in $STAGE/pool/extras/!  You do that thus:
# apt-get source ubuntu-keyring
# cd ubuntu-keyring-version-info/keyring
# gpg --import < ubuntu-server-keyring.gpg
# gpg --output=ubuntu-server-keyring.gpg --export "ubuntu" "Your Name"
# dpkg-buildpackage -rfakeroot -m"My Name <my.email@my.hosts>"
# cp ../ubuntu-keyring*deb $BUILD/pool/extras/


# VARIABLES
# this script relies on the existence of several files and directories:

# Original = $ORIG: location of the "clean", unmodified CD .iso
# CD mount point = $MOUNT: mount point of clean CD
# Staging area = $STAGE: where you keep all your files
#   this area should include main dirs isolinux/, pool/, and dists/ at a minimum
#   as written the script assumes you have a directory pool/extras with your 
#   extra debs, and that dists/breezy/extras/binary-i386/Release exists (copy it over 
#   from dists/breezy/main/binary-i386, and replace "main" with "extras")
#   There is no doubt a better way to do this but it involves work...
# Building Area = $BUILD: location where your changes are merged into the "clean" directory \
#   structure.
# Image location = $IMAGE: name of the new .iso file you want to build
# apt.conf file = $APTCONF: location of the file used to feed instructions to apt-ftparchive

ORIG="/var/www/jigdo/$1-breezy-install-i386.iso"
STAGE="/home/matt/LearningExchangeCD/$1/"
MOUNT=/mnt/iso/
BUILD="/yeowe/usr/cdbuilder/$1"
IMAGE="/yeowe/usr/cdbuilder/$1-learningexchange.iso"
APTCONF=/home/matt/LearningExchangeCD/apt.conf 


# sync with latest image
sudo umount $MOUNT
sudo mount $ORIG $MOUNT -o loop
# sudo rsync -azvb --delete --exclude="language-pack*" --backup-dir=/yeowe/usr/cdbuilder/old/ $MOUNT $BUILD
sudo rsync -azvb --delete  $MOUNT $BUILD
# now get rid of the old ubuntu-keyring package
sudo rm -r $BUILD/pool/u/ubuntu-keyring/
# note I've excluded a few files, shouldn't matter much for you I reckon
sudo rsync -avzb --exclude='*~' --exclude='INSTRUCTIONS.txt' --backup-dir=/yeowe/usr/cdbuilder/old/ --exclude='example-preseed.txt' $STAGE $BUILD

# generate Packages, Release, Release.gpg
# first thing to realize is, that we only need to generate the Packages files,
# the top-level Release file, and top-level Release.gpg.  
# everything else should be in your $STAGE file structure or usable unchanged 
# in the original form

# remove Release file otherwise you'll have trouble writing to it.  
sudo rm $BUILD/dists/breezy/Release*
# ubuntu-keyring must be included in main/, so main NEEDS to be rebuilt!
for component in main extras; do
    sudo apt-ftparchive packages "$BUILD/pool/$component/" > "$BUILD/dists/breezy/$component/binary-i386/Packages"
    gzip -c "$BUILD/dists/breezy/$component/binary-i386/Packages" | \
        sudo tee "$BUILD/dists/breezy/$component/binary-i386/Packages.gz" > /dev/null
done
sudo apt-ftparchive -c $APTCONF release $BUILD/dists/breezy > $BUILD/dists/breezy/Release
# gpg options: -ba = armored, detached-sig
sudo gpg --output $BUILD/dists/breezy/Release.gpg -ba $BUILD/dists/breezy/Release

# build the actual image.  Note the options to mkisofs, which make the image bootable
sudo chown -R root:root $BUILD/isolinux  $BUILD/preseed 
sudo mkisofs -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -J -hide-rr-moved -o $IMAGE -R $BUILD/

# burn the image to 2nd cd drive on most setups
sudo nice -18 cdrecord dev=ATA:1,1,0 speed=12 --blank=fast -v -gracetime=2 -tao $IMAGE

Complex example installation script for Breezy

An alternative script, which provides the capability to:

  • Cut down the number of packages on a CD
  • Install extra packages
  • Change the USplash image (eg: "University of Antarctica, Ubuntu COE build")
  • Include arbitrary other data on the CD
  • Script the installation via a preseed file.

Requirements:

  • Ubuntu breezy ISO image
  • The packages: libgd2-dev, fakeroot, dpkg-dev
  • The script will create any other files it requires.

Note that the script does its 'package installation magic' by altering the 'ubuntu-desktop' package to depend on all of your installed packages. This may include a subset or superset of the original ubuntu-desktop packages. I tried creating a VERY large base-config/package-selection section instead, but this didn't work for me.

If you are not going to install ubuntu-desktop as part of your preseed file, you will need to modify the script to modify ubuntu-minimal (for example).

#
# Script by Leigh Purdie
#
# 1) Install a Ubuntu system, and remove packages according to your
#    requirements using synaptic.
#    Don't install any new packages that are NOT available from the CD,
#    at this stage, unless you include the packages in an 'extras' directory.
#
# 2) dpkg -l > PackageList
#    Copy this file to $BASEDIR/source on your build server.

# The Base Directory
BASEDIR="/data/MyBuildInstall"

# This directory will contain files that need to be copied over
# to the new CD.
EXTRASDIR="$BASEDIR/MyBuild"
# Seed file
SEEDFILE="mybuild.seed"

# Ubuntu ISO image
CDIMAGE="$BASEDIR/ubuntu-5.10-install-i386.iso"

# Where the ubuntu iso image will be mounted
CDSOURCEDIR="$BASEDIR/cdsource"

# Directory for building packages
SOURCEDIR="$BASEDIR/source"

# GPG
GPGKEYNAME="My Organisation Installation Key"
GPGKEYCOMMENT="Package Signing"
GPGKEYEMAIL="myorg@myorganisation.com"
GPGKEYPHRASE="MyOrg"
MYGPGKEY="$GPGKEYNAME ($GPGKEYCOMMENT) <$GPGKEYEMAIL>"

# Package list (dpkg -l) from an installed system.
PACKAGELIST="$SOURCEDIR/PackageList"

# Output CD name
CDNAME="MyBuild.iso"

# 640x480 PNG with colours as specified in
# https://wiki.ubuntu.com/USplashCustomizationHowto
USPLASH="$SOURCEDIR/MyBuildSplash1.png"

# ------------ End of modifications.


################## Initial requirements
id | grep -c uid=0 >/dev/null
if [ $? -gt 0 ]; then
        echo "You need to be root in order to run this script.."
        echo " - sudo /bin/sh prior to executing."
        exit
fi

which gpg > /dev/null
if [ $? -eq 1 ]; then
        echo "Please install gpg to generate signing keys"
        exit
fi

# Create a few directories.
if [ ! -d $BASEDIR ]; then mkdir -p $BASEDIR; fi
if [ ! -d $BASEDIR/FinalCD ]; then mkdir -p $BASEDIR/FinalCD; fi
if [ ! -z $EXTRASDIR ]; then
        if [ ! -d $EXTRASDIR ]; then mkdir -p $EXTRASDIR; fi
        if [ ! -d $EXTRASDIR/preseed ]; then mkdir -p $EXTRASDIR/preseed; fi
        if [ ! -d $EXTRASDIR/pool/extras ]; then mkdir -p $EXTRASDIR/pool/extras; fi
fi
if [ ! -d $CDSOURCEDIR ]; then mkdir -p $CDSOURCEDIR; fi
if [ ! -d $SOURCEDIR ]; then mkdir -p $SOURCEDIR; fi
if [ ! -d $SOURCEDIR/keyring ]; then mkdir -p $SOURCEDIR/keyring; fi
if [ ! -d $SOURCEDIR/indices ]; then mkdir -p $SOURCEDIR/indices; fi
if [ ! -d $SOURCEDIR/ubuntu-meta ]; then mkdir -p $SOURCEDIR/ubuntu-meta; fi


if [ ! -f $CDIMAGE ]; then
        echo "Cannot find your ubuntu image. Change CDIMAGE path."
        exit
fi


gpg --list-keys | grep "$GPGKEYNAME" >/dev/null
if [ $? -ne 0 ]; then
        echo "No GPG Key found in your keyring."
        echo "Generating a new gpg key ($GPGKEYNAME $GPGKEYCOMMENT) with a passphrase of $GPGKEYPHRASE .."
        echo ""
        echo "Key-Type: DSA
Key-Length: 1024
Subkey-Type: ELG-E
Subkey-Length: 2048
Name-Real: $GPGKEYNAME
Name-Comment: $GPGKEYCOMMENT
Name-Email: $GPGKEYEMAIL
Expire-Date: 0
Passphrase: $GPGKEYPHRASE" > $BASEDIR/key.inc

        gpg --gen-key --batch --gen-key $BASEDIR/key.inc
        # Note: If you wish to remove the passphrase from the key:
        # (Don't do this if you want to use this key for ANYTHING other
        # than a temporary ubuntu CD installation signing key)
        # gpg --edit-key
        # passwd
        # (enter old phrase)
        # (blank)
        # (blank)
        # y
        # quit
        # y
fi

if [ ! -f $CDSOURCEDIR/md5sum.txt ]; then
        echo -n "Mounting Ubuntu iso.. "
        mount | grep $CDSOURCEDIR
        if [ $? -eq 0 ]; then
                umount $CDSOURCEDIR
        fi

        mount -o loop $BASEDIR/ubuntu-5.10-install-i386.iso $CDSOURCEDIR/
        if [ ! -f $CDSOURCEDIR/md5sum.txt ]; then
                echo "Mount did not succeed. Exiting."
                exit
        fi
        echo "OK"
fi

if [ ! -f $SOURCEDIR/apt.conf ]; then
        echo -n "No APT.CONF file found... generating one."
        # Try and generate one?
        cat $CDSOURCEDIR/dists/breezy/Release | egrep -v "^ " | egrep -v "^(Date|MD5Sum|SHA1)" | sed 's/: / "/' | sed 's/^/APT::FTPArchive::Release::/' | sed 's/$/";/' > $SOURCEDIR/apt.conf
        echo "Ok."
fi

if [ ! -f $SOURCEDIR/apt-ftparchive-deb.conf ]; then
        echo "Dir {
  ArchiveDir \"$BASEDIR/FinalCD\";
};

TreeDefault {
  Directory \"pool/\";
};

BinDirectory \"pool/main\" {
  Packages \"dists/breezy/main/binary-i386/Packages\";
  BinOverride \"$SOURCEDIR/indices/override.breezy.main\";
  ExtraOverride \"$SOURCEDIR/indices/override.breezy.extra2.main\";
};

Default {
  Packages {
    Extensions \".deb\";
    Compress \". gzip\";
  };
};

Contents {
  Compress \"gzip\";
};" > $SOURCEDIR/apt-ftparchive-deb.conf
fi

if [ ! -f $SOURCEDIR/apt-ftparchive-udeb.conf ]; then
        echo "Dir {
  ArchiveDir \"$BASEDIR/FinalCD\";
};

TreeDefault {
  Directory \"pool/\";
};

BinDirectory \"pool/main\" {
  Packages \"dists/breezy/main/debian-installer/binary-i386/Packages\";
  BinOverride \"$SOURCEDIR/indices/override.breezy.main.debian-installer\";
};

Default {
  Packages {
    Extensions \".udeb\";
    Compress \". gzip\";
  };
};

Contents {
  Compress \"gzip\";
};" > $SOURCEDIR/apt-ftparchive-udeb.conf
fi

if [ ! -f $SOURCEDIR/apt-ftparchive-extras.conf ]; then
        echo "Dir {
  ArchiveDir \"$BASEDIR/FinalCD\";
};

TreeDefault {
  Directory \"pool/\";
};

BinDirectory \"pool/extras\" {
  Packages \"dists/breezy/extras/binary-i386/Packages\";
};

Default {
  Packages {
    Extensions \".deb\";
    Compress \". gzip\";
  };
};

Contents {
  Compress \"gzip\";
};" > $SOURCEDIR/apt-ftparchive-extras.conf
fi

if [ ! -f $SOURCEDIR/indices/override.breezy.extra.main ]; then
        for i in override.breezy.extra.main override.breezy.main override.breezy.main.debian-installer; do
                cd $SOURCEDIR/indices
                wget http://archive.ubuntu.com/ubuntu/indices/$i
        done
fi

# Create a 'fixed' version of the extras.main override package.
# Idea/Perl by Ferry Hendrikx, 2006
cat $SOURCEDIR/indices/override.breezy.extra.main | egrep -v ' Task ' > $SOURCEDIR/indices/override.breezy.extra2.main
cat $CDSOURCEDIR/dists/breezy/main/binary-i386/Packages | perl -e 'while (<>) { chomp; if(/^Package\:\s*(.+)$/) { $pkg=$1; } elsif(/^Task\:\s(.+)$/) { print "$pkg\tTask\t$1\n"; } }' >> $SOURCEDIR/indices/override.breezy.extra2.main


################## Copy over the source data

echo -n "Resyncing old data...  "

cd $BASEDIR/FinalCD
rsync -atz --delete $CDSOURCEDIR/ $BASEDIR/FinalCD/
echo "OK"


################## Remove packages that we no longer require

# PackageList is a dpkg -l from our 'build' server.
if [ ! -f $PACKAGELIST ]; then
        echo "No PackageList found. Assuming that you do not require any packages to be removed"
else
        cat $PACKAGELIST | grep "^ii" | awk '{print $2 "_" $3}' > $SOURCEDIR/temppackages

        echo "Removing files that are no longer required.."
        cd $BASEDIR/FinalCD
        # Only use main for the moment. Keep all 'restricted' debs
        rm -f $SOURCEDIR/RemovePackages
        # Note: Leave the udeb's alone.
        for i in `find pool/main -type f -name "*.deb" -print`; do
                FILE=`basename $i | sed 's/_[a-zA-Z0-9\.]*$//'`
                GFILE=`echo $FILE | sed 's/\+/\\\+/g' | sed 's/\./\\\./g'`
                # pool/main/a/alien/alien_8.53_all.deb becomes alien_8.53
                egrep "^"$GFILE $SOURCEDIR/temppackages >/dev/null
                if [ $? -ne 0 ]; then
                        # NOT Found
                        # Note: Keep a couple of anciliary files

                        grep "Filename: $i" $CDSOURCEDIR/dists/breezy/main/debian-installer/binary-i386/Packages >/dev/null
                        if [ $? -eq 0 ]; then
                                # Keep the debian-installer files - we need them.
                                echo "* Keeping special file $FILE"
                        else
                                echo "- Removing unneeded file $FILE"
                                rm -f $BASEDIR/FinalCD/$i

                        fi
                else
                        echo "+ Retaining $FILE"
                fi
        done
fi


echo -n "Generating keyfile..   "

cd $SOURCEDIR/keyring
KEYRING=`find * -maxdepth 1 -name "ubuntu-keyring*" -type d -print`
if [ -z "$KEYRING" ]; then
        apt-get source ubuntu-keyring
        KEYRING=`find * -maxdepth 1 -name "ubuntu-keyring*" -type d -print`
        if [ -z "$KEYRING" ]; then
                echo "Cannot grab keyring source! Exiting."
                exit
        fi
fi

cd $SOURCEDIR/keyring/$KEYRING/keyrings
gpg --import < ubuntu-archive-keyring.gpg >/dev/null
rm -f ubuntu-archive-keyring.gpg
gpg --output=ubuntu-archive-keyring.gpg --export FBB75451 437D05B5 "$GPGKEYNAME" >/dev/null
cd ..
dpkg-buildpackage -rfakeroot -m"$MYGPGKEY" -k"$MYGPGKEY" >/dev/null
rm -f $BASEDIR/FinalCD/pool/main/u/ubuntu-keyring/*
cp ../ubuntu-keyring*deb $BASEDIR/FinalCD/pool/main/u/ubuntu-keyring/
if [ $? -gt 0 ]; then
        echo "Cannot copy the modified ubuntu-keyring over to the pool/main folder. Exiting."
        exit
fi

echo "OK"


################## Copy over the extra packages (if any)
if [ ! -z $EXTRASDIR ]; then
        echo -n "Copying Extra files...  "
        rsync -az $EXTRASDIR/ $BASEDIR/FinalCD/
        echo "OK"

        if [ ! -f "$EXTRASDIR/preseed/$SEEDFILE" ]; then
                echo "No seed file found. Creating one in $EXTRASDIR/preseed/$SEEDFILE."
                echo "- You will probably want to modify this file."
                echo "base-config  base-config/package-selection      string ~tubuntu-minimal|~tubuntu-desktop" > $EXTRASDIR/preseed/$SEEDFILE
        fi

        if [ -f $PACKAGELIST ]; then
                echo "Replacing ubuntu-desktop with a pruned package list.. "
                cd $SOURCEDIR/ubuntu-meta
                rm -rf ubuntu-*
                apt-get source ubuntu-meta
                META=`find * -maxdepth 1 -name "ubuntu-meta*" -type d -print`
                if [ -z "$META" ]; then
                      echo "Cannot grab source to ubuntu-meta. Exiting."
                      exit
                fi

                cd $META
                for i in `ls desktop*`; do
                        grep "^ii" $PACKAGELIST | awk '{print $2}' > $i.tmp
                        mv $i.tmp $i
                done

                dpkg-buildpackage -rfakeroot -m"$MYGPGKEY" -k"$MYGPGKEY" >/dev/null
                cd ..
                rm -f $BASEDIR/FinalCD/pool/main/u/ubuntu-meta/ubuntu-desktop*deb
                mv ubuntu-desktop*.deb  $BASEDIR/FinalCD/pool/main/u/ubuntu-meta/

                cp $EXTRASDIR/preseed/$SEEDFILE $BASEDIR/FinalCD/preseed/$SEEDFILE

        fi

        if [ ! -f "$EXTRASDIR/isolinux/isolinux.cfg" ]; then
                cat $CDSOURCEDIR/isolinux/isolinux.cfg | sed "s/^APPEND.*/APPEND   preseed\/file=\/cdrom\/preseed\/$SEEDFILE vga=normal initrd=\/install\/initrd.gz ramdisk_size=16384 root=\/dev\/rd\/0 DEBCONF_PRIORITY=critical debconf\/priority=critical rw --/" > $BASEDIR/FinalCD/isolinux/isolinux.cfg
        fi

        echo "OK"
fi

if [ ! -z "$USPLASH" ]; then
        echo "Modifying Usplash (NOTE: libgd2-dev required)"

        cd $SOURCEDIR
        if [ ! -d usplash ]; then
                mkdir usplash
        fi
        cd usplash
        SPLASH=`find * -maxdepth 1 -type d -name "usplash*" -type d -print`
        if [ -z "$SPLASH" ]; then
                apt-get source usplash
                SPLASH=`find * -maxdepth 1 -type d -name "usplash*" -type d -print`
        fi
        if [ -z "$SPLASH" ]; then
                echo "Cannot download USPLASH source. Exiting."
                exit
        fi

        cp $USPLASH $SOURCEDIR/usplash/$SPLASH/usplash-artwork.png
        cd $SOURCEDIR/usplash/$SPLASH
        dpkg-buildpackage -rfakeroot -m"$MYGPGKEY" -k"$MYGPGKEY" >/dev/null
        cd ..
        rm -f $BASEDIR/FinalCD/pool/main/u/usplash/usplash*deb
        mv usplash*.deb $BASEDIR/FinalCD/pool/main/u/usplash/
fi

echo "Creating apt package list.."
cd $BASEDIR/FinalCD

apt-ftparchive -c $SOURCEDIR/apt.conf generate $SOURCEDIR/apt-ftparchive-deb.conf
apt-ftparchive -c $SOURCEDIR/apt.conf generate $SOURCEDIR/apt-ftparchive-udeb.conf
if [ ! -z $EXTRASDIR ]; then
        if [ ! -f $BASEDIR/FinalCD/dists/breezy/main/binary-i386/Release ]; then                cat $BASEDIR/FinalCD/dists/breezy/main/binary-i386/Release | sed 's/Component: main/Component: extras/' > $BASEDIR/FinalCD/dists/breezy/extras/binary-i386/Release
        fi
        ## Henrique Haas - check if exsits extras dists directory     
        if [ ! -d $BASEDIR/finalcd/dists/breezy/extras/binary-i386 ]; then
                mkdir -p $BASEDIR/finalcd/dists/breezy/extras/binary-i386
        fi
        apt-ftparchive -c $SOURCEDIR/apt.conf generate $SOURCEDIR/apt-ftparchive-extras.conf
fi




# Kill the existing release file
rm -f $BASEDIR/FinalCD/dists/breezy/Release*

apt-ftparchive -c $SOURCEDIR/apt.conf release dists/breezy/ > $BASEDIR/FinalCD/dists/breezy/Release

echo "$GPGKEYPHRASE" | gpg --default-key "$MYGPGKEY" --passphrase-fd 0 --output $BASEDIR/FinalCD/dists/breezy/Release.gpg -ba $BASEDIR/FinalCD/dists/breezy/Release
echo "OK"

cd $BASEDIR/FinalCD
echo -n "Updating md5 checksums.. "
chmod 666 md5sum.txt
rm -f md5sum.txt
find . -type f -print0 | xargs -0 md5sum > md5sum.txt
echo "OK"

cd $BASEDIR/FinalCD
echo "Creating and ISO image..."
mkisofs -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -J -hide-rr-moved -o $BASEDIR/$CDNAME -R $BASEDIR/FinalCD/

echo "CD Available in $BASEDIR/$CDNAME"
echo "You can now remove all files in:"
echo " - $BASEDIR/FinalCD"

# Unmount the old CD
umount $CDSOURCEDIR

Clean your "main" pool to only include installed packages

If your new CD folder is likely to be too large, you can use the following script from inside pool/main to strip out all packages which are unwanted (that is, packages which aren't currently installed):

for j in *
  do
    cd $j
    for k in *
      do
        cd $k
        for l in *.deb
          do
            if [ $l != "*.deb" ]
              then
                n=$(dpkg -l $(echo $l | cut -f1 -d"_") 2> /dev/null| grep "^ii")
                if [ -z "$n" ]
                  then
                    rm $l
                fi
            fi
          done
        cd ..
      done
    cd ..
  done
find -depth -type d -empty -exec rmdir {} \;


InstallCDCustomization/Scripts (last edited 2010-05-26 19:52:50 by static-74-40-144-38)