Diff for "InstallCDCustomization"


Differences between revisions 1 and 35 (spanning 34 versions)
Revision 1 as of 2006-08-16 23:27:13
Size: 15907
Editor: itpartners
Comment: Initial move from InstallCDCustomizationHowto
Revision 35 as of 2007-10-24 15:11:14
Size: 18551
Editor: 3e6b503c
Comment:
Deletions are marked like this. Additions are marked like this.
Line 9: Line 9:
= CD Customization =

 * '''Applies to:''' Ubuntu 5.10
 * '''Does not apply to:''' Ubuntu 6.06

The process of customizing or "remastering" Ubuntu CDs is not especially complex, but it is a little tedious and finicky. My knowledge of the process is also imperfect so hopefully other people will modify this page as appropriate.

The install CD has three main parts: a bootloader (ISOLINUX on amd64/i386 systems, yaboot on powerpc) and its configuration, which start everything up; debian-installer (d-i) which in this case is really a specialised miniature Ubuntu system; and a Debian-style repository structure, which is what takes up all that space on the disk in the directories "pool" and "dists". Building a new CD may involve modifications to all three parts.

== Modify installer behaviour using a Preseed file ==

When the CD boots up, a Linux kernel is started and the installation tasks are initiated. The installer's default behaviour can be modified through the use of a "preseed" file, which feeds d-i answers to questions normally asked by debconf or in other contexts. If you look closely at your install CD, you'll see that certain options (e.g. "server", "expert", "oem") already have preseed files assigned to them.

So, suppose you are installing breezy on a bunch of identical computers and you already know the answers to certain questions (what country and time zone you're in, what keyboard you have, how the network should be configured, how you want to partition the hard disk, etc. etc.). You can "preseed" the answers to these questions in a very simple configuration file.

=== Changing isolinux.cfg to identify your preseed ===

First, though, you need to tell d-i to look for your preseed file in the right place. The standard disk contains a directory /preseed; you should put your seed file there. You tell d-i where to find this file by modifying the bootloader config file, located in isolinux/isolinux.cfg, to pass appropriate parameters on the kernel command line. My file has the following lines in it:

{{{
DEFAULT /install/vmlinuz
APPEND preseed/file=/cdrom/preseed/learnexchange.seed kbd-chooser/method=us debian-installer/locale=en_CA vga=normal initrd=/install/initrd.gz ramdisk_size=16384 root=/dev/rd/0 DEBCONF_PRIORITY=critical debconf/priority=critical rw --
}}}

DEFAULT is the kernel loaded when I just press "enter" at the boot prompt. APPEND contains the options passed to the kernel. preseed/file is the most important one; the next two identify my locale and keyboard as Canadian; DEBCONF_PRIORITY ensures I don't see any unnecessary debconf questions.

Look carefully at your file and modify as you see fit.

=== Writing the preseed file ===

There are lots of example preseed files kicking around; here's one from the CD -- server.seed:

{{{
= Introduction =

||<tablestyle="float:right; font-size: 0.9em; width:40%; background:#F1F1ED; margin: 0 0 1em 1em;" style="padding:0.5em;">'''Contents'''[[BR]][[TableOfContents(3)]]||

The process of customizing or "remastering" Ubuntu install CDs is not especially complex, but it is a little tedious and finicky. This page documents all the problems you might find; if it doesn't, please edit it!

The Ubuntu install CD (since Ubuntu 6.06, the 'alternative install' or 'server' CD) has three main parts: a boot-loader (ISOLINUX on AMD64/x86 systems, yaboot on PowerPC) and its configuration, which start everything up; debian-installer (also known as d-i), which in this case is really a specialized miniature Ubuntu system; and a Debian-style repository structure, which is what takes up all that space on the disk in the directories "pool" and "dists". Building a new CD may involve modifications to all three parts.

This page shows a simple recipe for customizing the CD. It assumes that you copy the contents of the install CD to `/opt/build/` on your local system and create a couple of other dirs in `/opt/`. Modify as needed.

= Copy the CD to your hard drive =

attachment:IconsPage/warning.png This guide is for the Alternative Install or Server Install CDs; there is another page referrring to [:LiveCDCustomization: customization of the Desktop/Live CD].

Copy the entire installation CD to a directory on your hard drive. This guide will assume your CD image is in /opt/cd-image/, but you can put it wherever you like. It will take around 1GB of hard drive space.

If you have an ISO file, you can mount it and copy files out of it without burning it to CD: `mount -o loop /path/to/iso /some/mountpoint`.

You can use '''rsync''' to copy the CD, or just

{{{
mkdir -p /opt/cd-image
cp -rT /cdrom /opt/cd-image
}}}

Be sure to catch the folder ''.disk'' - if you try and copy /cdrom/*, it will ignore the .disk folder, as Bash expands the * to mean "everything it can see".

= Modify installer behaviour using a Preseed file =

When the CD boots up, a Linux kernel is started and the installation tasks are initiated. The installer's default behavior can be modified through the use of a "preseed" file, which feeds d-i answers to questions normally asked by debconf, or in other contexts. If you look in the `preseed` folder in the install CD, you'll see that certain options (e.g. "server", "expert", "oem") already have preseed files assigned to them. The Edgy (6.10) [https://help.ubuntu.com/6.10/ubuntu/installation-guide/i386/appendix-preseed.html installation guide] has a detailed appendix on preseeding (although see below for details on differences between Edgy and earlier versions).

Suppose you are installing Ubuntu on a bunch of identical computers, and you already know the answers to certain questions (what country and time zone you're in, what keyboard you have, how the network should be configured, how you want to partition the hard disk, etc). You can "preseed" the answers to these questions in a very simple configuration file.

== Changing isolinux.cfg to identify your preseed ==

We will create a preseed file called 'firewall.seed', which will live in the /preseed folder of the CD-ROM. We tell d-i where to find this file by modifying the boot-loader configuration file, located in isolinux/isolinux.cfg, to pass appropriate parameters on the kernel command line. In /opt/cd-image/isolinux/isolinux.cfg, add a new section labeled like this:

{{{
LABEL firewall
  menu label ^Firewall installation
  kernel /install/vmlinuz
  append preseed/file=/cdrom/preseed/firewall.seed debian-installer/locale=en_NZ kbd-chooser/method=us initrd=/install/initrd.gz ramdisk_size=16384 root=/dev/ram rw quiet --
}}}

If you want to set the default action to booting with your custom seed, change the DEFAULT line to read 'DEFAULT firewall'.

You must specify a locale and keyboard on the command line, as these questions are asked before the seed is loaded. You can also set DEBCONF_PRIORITY here to ensure you don't see any unnecessary debconf questions.

== Writing the preseed file ==

A preseed file has 4 fields per line:
  1. identity of the program which will pick up this command
  2. name of the variable whose value will be passed
  3. variable type
  4. value of variable

It looks something like this (from the default ubuntu-server.seed on the 6.06 CD):

   {{{
# Always install the server kernel.
d-i base-installer/kernel/override-image string linux-server
Line 47: Line 75:
# Only install the standard system and language packs in the second stage.
base-config base-config/package-selection  string ~t^ubuntu-standard$
base-config base-config/language-pack-patterns    string language-pack-$LL
# Only install the standard system and language packs.
d-i pkgsel/install-pattern string ~t^ubuntu-standard$
d-i pkgsel/language-pack-patterns string
Line 51: Line 79:
base-config base-config/install-language-support boolean false
}}}

(Note that the version of this file on breezy CD images was buggy: it set base-config/package-selection to "~tubuntu-standard" rather than "~t^ubuntu-standard$". Use the new version in preference; the old one will break with Ubuntu 6.04.)

First notice the format. There are 4 fields:

  1. identity of the program which will pick up this command
  2. name of the variable whose value will be passed
  3. variable type
  4. value of variable

Two important notes: currently, d-i expects there to be exactly one space between variable type and variable value; and the version of d-i used in breezy does not allow lines to be broken by the '\' character (newer versions do allow this).

I recommend starting with someone else's preseed file and modifying it -- there's one available at
[http://archive.ubuntu.com/ubuntu/dists/breezy/main/installer-i386/current/doc/manual/en/apcs01.html]. If you can't find what you're looking for, try executing the following commands:

{{{
d-i pkgsel/install-language-support boolean false
}}}

attachment:IconsPage/important.png The version of this file on some Breezy CD images was buggy: it set base-config/package-selection to `"~tubuntu-standard"` rather than `"~t^ubuntu-standard$"`. Use the new format in preference; the old one will break with Ubuntu 6.06 and newer.)

attachment:IconsPage/important.png d-i expects there to be [http://d-i.alioth.debian.org/manual/en.i386/apbs03.html exactly one tab or space between variable type and variable value] (any other space is seen as being part of the value)

The easiest way to create a preseed file is to start with an example and modify it:
  1. You could check out [http://wiki.debian.org/DebianInstaller/Preseed Debian's wiki page on preseeding the installer] - 6.06 and higher use the Etch version of the Debian installer.
  2. The Edgy (6.10) [https://help.ubuntu.com/6.10/ubuntu/installation-guide/i386/preseed-contents.html install guide] has examples of many common preseed directives. (Bear in mind that you may need to modify some to work on older versions.)
  3. If you can't find the option you're looking for you can generate a comprehensive preseed file based on your own install time choices by using `debconf-get-selections`

`debconf-get-selections` usage:
{{{
sudo apt-get install debconf-utils # It is part of the debconf-utils package.
Line 73: Line 98:
This will output a list of all debconf options you've chosen throughout your install; the file will be pretty long and not really suitable for inclusion on an install disk. In particular, '''NOTE:''' debconf-get-selections prints '''2''' spaces between variable type and variable value. You'll need to change that before putting such a file on a disk.

If you want to instruct d-i to install extra packages, or to install only a minimal set you need to change the "base-config/package-selection" directive in the preseed. This should be set to an aptitude pattern; see the aptitude documentation for more information on these. For instance, to install an SSH server along with the standard installation, use this line:

{{{
base-config base-config/package-selection string ~t^ubuntu-standard$|~t^ubuntu-desktop$|~n^openssh-server$
}}}

To install support for additional languages, a different mechanism is available, namely to preseed the detailed locale question asked by the installer in expert mode. See the first column of `/usr/share/i18n/SUPPORTED` for the locale names you can use here. For example, to add support for Bengali and Tamil, use this line:
This will output a list of all debconf options you've chosen throughout your install; you can pick options out of this and put them into your preseed file.

attachment:IconsPage/warning.png debconf-get-selections prints '''2''' spaces between variable type and variable value. You need to change this to one space before putting the line in a preseed file.

=== Installing extra packages in your preseed file ===

base-config has been removed from debian-installer since Ubuntu 6.06. Use:

{{{
d-i pkgsel/install-pattern string ~t^ubuntu-standard$|~n^openssh-server$
}}}

=== Installing language support ===

A different mechanism is used to install additional languages. Preseed the detailed locale question asked by the installer in expert mode. See the first column of `/usr/share/i18n/SUPPORTED` for the locale names you can use here. For example, to add support for Bengali and Tamil, use this line:
Line 87: Line 118:
== Modify pool structure to include/delete packages ==

Probably the main reason to build your own install CDs is to modify which packages are installed; in particular you may want to add some packages to the CD. There are several ways to do this, none of which I understand fully. The easiest thing to do is to build a minimal repository structure containing only your own extra .debs, and merge these into the CD file hierarchy before rebuilding the iso image. The tricky parts here are: generate the Packages files that the Debian package management system expects to see when it encounters a repository; generate the top-level Release file the Debian package management system expects; and sign the release file with gpg. Here's what I did.

 *. designate a file directory as your staging area; in that directory,

{{{
mkdir -p dists/breezy/extras/binary-i386 pool/extras/ isolinux preseed
}}}

Put your modified isolinux.cfg in isolinux/, and your preseed file in preseed/.
 *. put all the extra debs you need on your cd into pool/extras/. You will also need to include a new version of ubuntu-keyring, which I'll explain about in a second.
 *. in a text editor or some other way make a new file dists/breezy/extras/binary-i386/Release with the following content:

{{{
Archive: breezy
Version: 5.10
= Modify pool structure to include more packages =

Probably the prime motivation to build your own install CDs is to modify which packages are installed; in particular you may want to add some packages to the CD.

The easiest way to do this is to build an 'extras' repository structure, containing only your extra .debs, and merge these into the CD file hierarchy before rebuilding the .ISO image. This guide will step you through how to do this.

This requires you to generate the Packages files that defines what files are in your repository; the Release file that indexes your Packages files, and the signed Release.gpg file, approving the repository as being official.

== Create an "Extras" component ==

Create directories for your new component (substituting your version where appropriate):

    {{{
cd /opt/cd-image
mkdir -p dists/dapper/extras/binary-i386 pool/extras/ isolinux preseed
}}}

Put all the extra .debs you want on your CD into `pool/extras`.

Create the file `dists/dapper/extras/binary-i386/Release` with the following content:

    {{{
Archive: dapper
Version: 6.06
Line 110: Line 148:
 *. merge your changes into the cd thusly:
   a. mount your "clean" downloaded iso: {{{mount /path/to/iso /some/mountpoint/ -o loop}}}

   b. copy all the files to a directory somewhere (you'll need a gigabyte or two off space); I use rsync: {{{sudo rsync -azvb --delete --backup-dir=/yeowe/usr/cdbuilder/old/ $MOUNT $BUILD}}} (where $MOUNT isthe mountpoint, $BUILD is the location of the extracted contents)

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

   {{{
#!/bin/bash
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 {} \;
   }}}

   d. '''This is important'''. In just a minute we will generate the packages file and the top-level release file using the apt-ftparchive tool. Then we will need to sign the release file using a gpg key. The install system will then check the signature against the public keys held in the package ubuntu-keyring. But your signature isn't in that keyring. So you need to make a new version of the ubuntu-keyring package. This is actually really easy, but it took me forever to do it right. So here's the necessary code:

   {{{
On the [:/Scripts:scripts page] there is a useful script that will strip out all of the packages from your CD image that are not currently installed. You will need to run `apt-ftparchive` (below) to generate the Packages file.

== Generating a new ubuntu-keyring .deb to sign your CD ==

In order to sign the Release file, we need to use GPG. The install system will then check the signature against the public keys held in the package ubuntu-keyring. You do not have a private key that matches one of the ones in the shipped ubuntu-keyring, so we need to build a custom version of the ubuntu-keyring package. Install the `gnupg` package if you do not have it already.

To create a signing key, enter `gpg --gen-key`. Accept the defaults, (for this use, it is probably OK to use "No expiry"). For your Real Name and E-mail address, you might like to use something like "XXX Signing Key" and "packages@xxx.example.org". Enter an appropriate passphrase.

In another directory (I use `/opt/build/`), we will download the source for the ubuntu-keyring package, unpack it, add our own GPG key, and rebuild the package. These steps import the 2 Ubuntu public signing keys into your main keyring, then exports them, along with your own public signing key, into a replacement keyring. "YOURKEYID" should be replaced with the 8-digit hexadecimal code that gpg tells you when you do the --list-keys command."Signing Key Name" is what you used in the previous step, when running `gpg --gen-key`.

To clarify, below is an example 'gpg --list-keys' response. In this example, "YOURKEYID" immediately follows the '/' on the line beginning with 'pub' (which in this example is '437D05B5'.)

{{{
gpg --list-keys
pub 1024D/437D05B5 2006-09-08
uid XXX Signing Key <packages@xxx.example.org>
sub 2048g/79164387 2006-09-08
}}}

Here is an example, which you will need to customize to suit your own setup:

{{{
cd /opt/build
sudo apt-get install fakeroot # requires the fakeroot package which may not be installed on your system.
Line 147: Line 173:
cd ubuntu-keyring--2005.01.11/keyring cd ubuntu-keyring-2005.01.12.1/keyrings
Line 149: Line 175:
gpg --list-keys "Your Name"
gpg --export FBB75451 437D05B5 YOURKEYID > ubuntu-archive-keyring.gpg
cd ..
dpkg-buildpackage -rfakeroot -m"Your Name <your.email@your.host> -k"Your Name <your.email@your.host>"
cp ubuntu-keyring*deb $BUILD/pool/extras/
}}}

'''NOTE:''' Copying the ubuntu-keyring (u)deb to the above location will not work correctly for Dapper CDs. I have tested it with flight4 and flight5 and the result of the above is that the installer cannot find the kernel as it cannot extract the correct GPG key (the one you signed the Release file with). In order for the procedure to work, you need to copy the generated ubuntu-keyring*deb files to $BUILD/pool/main/u/ubuntu-keyring instead.


   OK -- what we've done here is import the 2 Ubuntu keys into your main keyring, then exported them along with your own key into a replacement keyring. "YOURKEYID" should be replaced with the 8-digit hexadecimal code that gpg tells you when you do the --list-keys command above. And really, the best policy would be to do all that first, and copy a version into your $STAGE file structure so that you have it permanently available.

Note: If you do not have an existing gpg signing key, use the following code:
   {{{ gpg --gen-key
   }}}

Accept all defaults, select "No expiry", and enter an appropriate passphrase.

In order to use apt-ftparchive, we will need to provide it with some defaults.
Create the files "apt-ftparchive-deb.conf, "apt-ftparchive-udeb.conf", and "apt-ftparchive-extras.conf" as follows (substitude $BUILD for the absolute path to your BUILD directory, and /path/to/indices to the location of the indices files, which you can download from http://archive.ubuntu.com/ubuntu/indices/ ):

   {{{
apt-ftparchive-deb.conf:
gpg --list-keys "Signing Key Name"
gpg --export FBB75451 437D05B5 YOURKEYID > ubuntu-archive-keyring.gpg
cd .. # you are now on ubuntu-keyring-2005.01.12.1
dpkg-buildpackage -rfakeroot -m"Your Name <your.email@your.host>" -kYOURKEYID
cd .. # you are now on the directory where you started, in the example, /opt/build
cp ubuntu-keyring*deb /opt/cd-image/pool/main/u/ubuntu-keyring
}}}

You will end up with a udeb file for the installer, and a .deb file for the system. Both files need to be copied into the '''main''' component of your CD, because the CD will not check the extras directory.


== Building the repository with apt-ftparchive ==

`apt-ftparchive` builds the `Packages` and `Packages.gz` files, needed by the installer. In order to use `apt-ftparchive` we will need to provide it with some configuration and some index files.

We will put the index files in `/opt/indices`:

    {{{
mkdir -p /opt/indices /opt/apt-ftparchive
cd /opt/indices/
DIST=dapper; wget http://archive.ubuntu.com/ubuntu/indices/override.$DIST.{extra.main,main,main.debian-installer,restricted,restricted.debian-installer}
}}}

Create the files `apt-ftparchive-deb.conf`, `apt-ftparchive-udeb.conf`, `apt-ftparchive-extras.conf`, and `release.conf` in a directory (`/opt/apt-ftparchive`), substituting `/opt/cd-image/` for the path to your CD image directory, and `/opt/indices/` for the location of the index files, if they differ.

__/opt/apt-ftparchive/apt-ftparchive-deb.conf:__

    {{{
Line 173: Line 204:
  ArchiveDir "$BUILD";   ArchiveDir "/opt/cd-image/";
Line 181: Line 212:
  Packages "dists/breezy/main/binary-i386/Packages";
  BinOverride "/path/to/indices/override.breezy.main";
  ExtraOverride "path/to/indices/override.breezy.extra.main";
};

// Uncomment the lines below if you're customizing the Dapper release
//BinDirectory "pool/restricted" {
// Packages "dists/dapper/restricted/binary-i386/Packages";
// BinOverride "/path/to/indices/override.dapper.restricted";
//};
  Packages "dists/dapper/main/binary-i386/Packages";
  BinOverride "/opt/indices/override.dapper.main";
  ExtraOverride "/opt/indices/override.dapper.extra.main";
};

BinDirectory "pool/restricted" {
 Packages "dists/dapper/restricted/binary-i386/Packages";
 BinOverride "/opt/indices/override.dapper.restricted";
};
Line 202: Line 232:

   }}}

   {{{
apt-ftparchive-udeb.conf:
}}}

The ExtraOverride component above is needed to add the Task header to main packages, referenced from the preseed file with ~t<task name>. This is not supplied - but can be extracted from the existing main Packages file with a simple perl script :-

    {{{
#! /usr/bin/perl
# extraoverride.pl
# generate ExtraOverride file
# use as follows :-
# extraoverride.pl < /opt/cd-image/dists/dapper/main/binary-i386/Packages >> /opt/indices/override.dapper.extra.main

while (<>) {
        chomp;
        next if /^ /;
        if (/^$/ && defined($task)) {
                print "$package Task $task\n";
                undef $package;
                undef $task;
        }
        ($key, $value) = split /: /, $_, 2;
        if ($key eq 'Package') {
                $package = $value;
        }
        if ($key eq 'Task') {
                $task = $value;
        }
}
}}}

__/opt/apt-ftparchive/apt-ftparchive-udeb.conf:__

    {{{
Line 208: Line 265:
  ArchiveDir "$BUILD";   ArchiveDir "/opt/cd-image/";
Line 216: Line 273:
  Packages "dists/breezy/main/debian-installer/binary-i386/Packages";
  BinOverride "/path/to/indices/override.breezy.main.debian-installer";
};

// Uncomment the lines below if you're customizing a Dapper release
//BinDirectory
"pool/restricted" {
// Packages "dists/dapper/restricted/debian-installer/binary-i386/Packages";
// BinOverride "/path/to/indices/override.dapper.restricted.debian-installer";
//};
  Packages "dists/dapper/main/debian-installer/binary-i386/Packages";
  BinOverride "/opt/indices/override.dapper.main.debian-installer";
};

BinDirector
y "pool/restricted" {
  Packages "dists/dapper/restricted/debian-installer/binary-i386/Packages";
  BinOverride "/opt/indices/override.dapper.restricted.debian-installer";
};
Line 236: Line 292:
   }}} }}}

__/opt/apt-ftparchive/apt-ftparchive-extras.conf:__
Line 239: Line 297:
apt-ftparchive-extras.conf:
Line 241: Line 298:
  ArchiveDir "$BUILD";   ArchiveDir "/opt/cd-image/";
Line 249: Line 306:
  Packages "dists/breezy/extras/binary-i386/Packages";   Packages "dists/dapper/extras/binary-i386/Packages";
Line 262: Line 319:
   }}}


 *. Now use apt-ftparchive to make the Packages and Release files:
   
}}}

__release.conf__

This is the configuration file for apt-ftparchive. Change to suit your distribution version:
Line 268: Line 326:
cd $BUILD
sudo apt-ftparchive -c $APTCONF generate /path/to/apt-ftparchive-deb.conf
sudo apt-ftparchive -c $APTCONF generate /path/to/apt-ftparchive-udeb.conf
sudo apt-ftparchive -c $APTCONF generate /path/to/apt-ftparchive-extras.conf
}}}

'''NOTE:''' For Dapper custom CD (possibly for Breezy as well, but I haven't tested it and I assume the original author of this HOWTO tested the procedure) you need to issue one more command after the above:

{{{
sudo apt-ftparchive -c $APTCONF release $BUILD/dists/$DISTNAME | sudo tee $BUILD/dists/$DISTNAME/Release 2>&1 > /dev/null
}}}

where '''$DISTNAME''' should be replaced with '''breezy''' or '''dapper''' for the name of the release you are customizing.

   $APTCONF is a file somewhere that looks about like this:
{{{APT::FTPArchive::Release::Origin "Ubuntu";
APT::FTPArchive::Release::Origin "Ubuntu";
Line 285: Line 328:
APT::FTPArchive::Release::Suite "breezy";
APT::FTPArchive::Release::Version "5.10";
APT::FTPArchive::Release::Codename "breezy";
APT::FTPArchive::Release::Suite "dapper";
APT::FTPArchive::Release::Version "6.06";
APT::FTPArchive::Release::Codename "dapper";
Line 290: Line 333:
APT::FTPArchive::Release::Description "Ubuntu Breezy";
}}}

   a. sign the Release file with gpg: {{{
sudo gpg --default-key "MY GPG KEY ID" --output $BUILD/dists/breezy/Release.gpg -ba $BUILD/dists/breezy/Release
}}}

*. Regenerate the md5 checksums: {{{
cd $BUILD
APT::FTPArchive::Release::Description "Ubuntu 6.06 LTS";
}}}

To build the repository, sign it, and update the MD5SUM file, you can use a script like this:

{{{
BUILD=/opt/cd-image
APTCONF=/opt/apt-ftparchive/release.conf
DISTNAME=dapper

pushd $BUILD
apt-ftparchive -c $APTCONF generate /opt/apt-ftparchive/apt-ftparchive-deb.conf
apt-ftparchive -c $APTCONF generate /opt/apt-ftparchive/apt-ftparchive-udeb.conf
apt-ftparchive -c $APTCONF generate /opt/apt-ftparchive/apt-ftparchive-extras.conf
apt-ftparchive -c $APTCONF release $BUILD/dists/$DISTNAME > $BUILD/dists/$DISTNAME/Release

gpg --default-key "YOURKEYID" --output $BUILD/dists/$DISTNAME/Release.gpg -ba $BUILD/dists/$DISTNAME/Release
Line 300: Line 351:
}}}

 *. Then we re-build the cd. '''NOTE: ''' This procedure is specific to the Intel x86 (i386) and x86_64 (amd64) live CDs. Other architectures, such as PowerPC and IA64, will require different command line options. {{{
$ sudo mkisofs -r -V "Custom Ubuntu Install CD" \
popd
}}}


= Burning the CD =

At this point, you have a directory which is ready to be collected into an .ISO file and then burnt to a CD.

== Building the ISO image ==

__x86 and AMD64__

{{{
IMAGE=custom.iso
BUILD=/opt/cd-image/

mkisofs -r -V "Custom Ubuntu Install CD" \
Line 311: Line 375:
 On PowerPC, download [http://people.ubuntu.com/~cjwatson/hfs.map], then use the following command: {{{
$ sudo mkisofs -r -V "Custom Ubuntu Install CD" \
__Power PC__

D
ownload [http://people.ubuntu.com/~cjwatson/hfs.map the HFS map], then use the following command:
{{{
IMAGE=custom.iso
BUILD=/opt/c
d-image/

mkisofs -r -V "Custom Ubuntu Install CD" \
Line 316: Line 386:
            -hfs-volid Ubuntu/PowerPC_breezy \             -hfs-volid Ubuntu/PowerPC_dapper \
Line 320: Line 390:
 On ia64: {{{
$ sudo mkisofs -r -V 'Custom Ubuntu 5.10 install ia64' \
__ia64__
{{{
IMAGE=custom.iso
BUILD=/opt/c
d-image/

mkisofs -r -V 'Custom Ubuntu Install CD' \
Line 328: Line 402:
 *. finally, burn your cd using cdrecord:

{{{
sudo nice -18 cdrecord dev=ATA:1,1,0 speed=12 --blank=fast -v -gracetime=2 -tao $IMAGE
}}}
that will burn the image on the second cd drive; if your cd-burner is the first or only cd-drive, change dev argument to ATA``:1,0,0. I '''strongly''' recommend using rewritable media -- I've burned a LOT of coasters on this project.

OK, that should do it!

Check out [:/Scripts:install CD customization scripts] that can be used to automate this process.
== Burning the image to CD ==

To detect the location of your CD drive, try `cdrecord --scanbus`. For a primary IDE CD drive on /dev/hdc:

{{{
sudo nice -18 cdrecord dev=ATA:0,1,0 --speed=24 --blank=fast -v -gracetime=2 -tao $IMAGE
}}}

You will burn a lot of coasters in experimenting with this process, so please use rewritable media!

= Testing =

You can now boot off your CD. Select the new menu item you created. If you've used preseeding to stop the CD asking questions, the installation could be totally automatic.

= Troubleshooting =

 * If your CD fails to read, try re-burning it, possibly at a slower speed.
 * If you get a red d-i screen, check the error message (use Alt-F2, Alt-F3 etc to cycle through the terminals to read the log), and fix your CD appropriately.

= See also =

Check out some [:/Scripts:install CD customization scripts] that can be used to automate this process.

Introduction

The process of customizing or "remastering" Ubuntu install CDs is not especially complex, but it is a little tedious and finicky. This page documents all the problems you might find; if it doesn't, please edit it!

The Ubuntu install CD (since Ubuntu 6.06, the 'alternative install' or 'server' CD) has three main parts: a boot-loader (ISOLINUX on AMD64/x86 systems, yaboot on PowerPC) and its configuration, which start everything up; debian-installer (also known as d-i), which in this case is really a specialized miniature Ubuntu system; and a Debian-style repository structure, which is what takes up all that space on the disk in the directories "pool" and "dists". Building a new CD may involve modifications to all three parts.

This page shows a simple recipe for customizing the CD. It assumes that you copy the contents of the install CD to /opt/build/ on your local system and create a couple of other dirs in /opt/. Modify as needed.

Copy the CD to your hard drive

attachment:IconsPage/warning.png This guide is for the Alternative Install or Server Install CDs; there is another page referrring to [:LiveCDCustomization: customization of the Desktop/Live CD].

Copy the entire installation CD to a directory on your hard drive. This guide will assume your CD image is in /opt/cd-image/, but you can put it wherever you like. It will take around 1GB of hard drive space.

If you have an ISO file, you can mount it and copy files out of it without burning it to CD: mount -o loop /path/to/iso /some/mountpoint.

You can use rsync to copy the CD, or just

mkdir -p /opt/cd-image
cp -rT /cdrom /opt/cd-image

Be sure to catch the folder .disk - if you try and copy /cdrom/*, it will ignore the .disk folder, as Bash expands the * to mean "everything it can see".

Modify installer behaviour using a Preseed file

When the CD boots up, a Linux kernel is started and the installation tasks are initiated. The installer's default behavior can be modified through the use of a "preseed" file, which feeds d-i answers to questions normally asked by debconf, or in other contexts. If you look in the preseed folder in the install CD, you'll see that certain options (e.g. "server", "expert", "oem") already have preseed files assigned to them. The Edgy (6.10) [https://help.ubuntu.com/6.10/ubuntu/installation-guide/i386/appendix-preseed.html installation guide] has a detailed appendix on preseeding (although see below for details on differences between Edgy and earlier versions).

Suppose you are installing Ubuntu on a bunch of identical computers, and you already know the answers to certain questions (what country and time zone you're in, what keyboard you have, how the network should be configured, how you want to partition the hard disk, etc). You can "preseed" the answers to these questions in a very simple configuration file.

Changing isolinux.cfg to identify your preseed

We will create a preseed file called 'firewall.seed', which will live in the /preseed folder of the CD-ROM. We tell d-i where to find this file by modifying the boot-loader configuration file, located in isolinux/isolinux.cfg, to pass appropriate parameters on the kernel command line. In /opt/cd-image/isolinux/isolinux.cfg, add a new section labeled like this:

LABEL firewall
  menu label ^Firewall installation
  kernel /install/vmlinuz
  append  preseed/file=/cdrom/preseed/firewall.seed debian-installer/locale=en_NZ kbd-chooser/method=us initrd=/install/initrd.gz ramdisk_size=16384 root=/dev/ram rw quiet --

If you want to set the default action to booting with your custom seed, change the DEFAULT line to read 'DEFAULT firewall'.

You must specify a locale and keyboard on the command line, as these questions are asked before the seed is loaded. You can also set DEBCONF_PRIORITY here to ensure you don't see any unnecessary debconf questions.

Writing the preseed file

A preseed file has 4 fields per line:

  1. identity of the program which will pick up this command
  2. name of the variable whose value will be passed
  3. variable type
  4. value of variable

It looks something like this (from the default ubuntu-server.seed on the 6.06 CD):

  • # Always install the server kernel.
    d-i     base-installer/kernel/override-image    string linux-server
    # Don't install usplash.
    d-i     base-installer/kernel/linux/extra-packages-2.6  string
    # Desktop system not installed; don't waste time and disk space copying it.
    d-i     archive-copier/desktop-task     string ubuntu-standard
    d-i     archive-copier/ship-task        string
    # Only install the standard system and language packs.
    d-i     pkgsel/install-pattern  string ~t^ubuntu-standard$
    d-i     pkgsel/language-pack-patterns   string
    # No language support packages.
    d-i     pkgsel/install-language-support boolean false

attachment:IconsPage/important.png The version of this file on some Breezy CD images was buggy: it set base-config/package-selection to "~tubuntu-standard" rather than "~t^ubuntu-standard$". Use the new format in preference; the old one will break with Ubuntu 6.06 and newer.)

attachment:IconsPage/important.png d-i expects there to be [http://d-i.alioth.debian.org/manual/en.i386/apbs03.html exactly one tab or space between variable type and variable value] (any other space is seen as being part of the value)

The easiest way to create a preseed file is to start with an example and modify it:

  1. You could check out [http://wiki.debian.org/DebianInstaller/Preseed Debian's wiki page on preseeding the installer] - 6.06 and higher use the Etch version of the Debian installer.

  2. The Edgy (6.10) [https://help.ubuntu.com/6.10/ubuntu/installation-guide/i386/preseed-contents.html install guide] has examples of many common preseed directives. (Bear in mind that you may need to modify some to work on older versions.)

  3. If you can't find the option you're looking for you can generate a comprehensive preseed file based on your own install time choices by using debconf-get-selections

debconf-get-selections usage:

sudo apt-get install debconf-utils    # It is part of the debconf-utils package.
debconf-get-selections --installer > somefile.txt
debconf-get-selections >> somefile.txt

This will output a list of all debconf options you've chosen throughout your install; you can pick options out of this and put them into your preseed file.

attachment:IconsPage/warning.png debconf-get-selections prints 2 spaces between variable type and variable value. You need to change this to one space before putting the line in a preseed file.

Installing extra packages in your preseed file

base-config has been removed from debian-installer since Ubuntu 6.06. Use:

d-i     pkgsel/install-pattern          string ~t^ubuntu-standard$|~n^openssh-server$

Installing language support

A different mechanism is used to install additional languages. Preseed the detailed locale question asked by the installer in expert mode. See the first column of /usr/share/i18n/SUPPORTED for the locale names you can use here. For example, to add support for Bengali and Tamil, use this line:

d-i localechooser/supported-locales multiselect bn_IN, ta_IN

Modify pool structure to include more packages

Probably the prime motivation to build your own install CDs is to modify which packages are installed; in particular you may want to add some packages to the CD.

The easiest way to do this is to build an 'extras' repository structure, containing only your extra .debs, and merge these into the CD file hierarchy before rebuilding the .ISO image. This guide will step you through how to do this.

This requires you to generate the Packages files that defines what files are in your repository; the Release file that indexes your Packages files, and the signed Release.gpg file, approving the repository as being official.

Create an "Extras" component

Create directories for your new component (substituting your version where appropriate):

  • cd /opt/cd-image
    mkdir -p dists/dapper/extras/binary-i386 pool/extras/ isolinux preseed

Put all the extra .debs you want on your CD into pool/extras.

Create the file dists/dapper/extras/binary-i386/Release with the following content:

  • Archive: dapper
    Version: 6.06
    Component: extras
    Origin: Ubuntu
    Label: Ubuntu
    Architecture: i386

On the [:/Scripts:scripts page] there is a useful script that will strip out all of the packages from your CD image that are not currently installed. You will need to run apt-ftparchive (below) to generate the Packages file.

Generating a new ubuntu-keyring .deb to sign your CD

In order to sign the Release file, we need to use GPG. The install system will then check the signature against the public keys held in the package ubuntu-keyring. You do not have a private key that matches one of the ones in the shipped ubuntu-keyring, so we need to build a custom version of the ubuntu-keyring package. Install the gnupg package if you do not have it already.

To create a signing key, enter gpg --gen-key. Accept the defaults, (for this use, it is probably OK to use "No expiry"). For your Real Name and E-mail address, you might like to use something like "XXX Signing Key" and "packages@xxx.example.org". Enter an appropriate passphrase.

In another directory (I use /opt/build/), we will download the source for the ubuntu-keyring package, unpack it, add our own GPG key, and rebuild the package. These steps import the 2 Ubuntu public signing keys into your main keyring, then exports them, along with your own public signing key, into a replacement keyring. "YOURKEYID" should be replaced with the 8-digit hexadecimal code that gpg tells you when you do the --list-keys command."Signing Key Name" is what you used in the previous step, when running gpg --gen-key.

To clarify, below is an example 'gpg --list-keys' response. In this example, "YOURKEYID" immediately follows the '/' on the line beginning with 'pub' (which in this example is '437D05B5'.)

gpg --list-keys
pub   1024D/437D05B5 2006-09-08
uid                  XXX Signing Key <packages@xxx.example.org>
sub   2048g/79164387 2006-09-08

Here is an example, which you will need to customize to suit your own setup:

cd /opt/build
sudo apt-get install fakeroot   # requires the fakeroot package which may not be installed on your system.
apt-get source ubuntu-keyring
cd ubuntu-keyring-2005.01.12.1/keyrings
gpg --import < ubuntu-archive-keyring.gpg
gpg --list-keys "Signing Key Name"
gpg --export FBB75451 437D05B5 YOURKEYID > ubuntu-archive-keyring.gpg
cd ..    # you are now on ubuntu-keyring-2005.01.12.1
dpkg-buildpackage -rfakeroot -m"Your Name <your.email@your.host>" -kYOURKEYID
cd ..  # you are now on the directory where you started, in the example, /opt/build
cp ubuntu-keyring*deb /opt/cd-image/pool/main/u/ubuntu-keyring

You will end up with a udeb file for the installer, and a .deb file for the system. Both files need to be copied into the main component of your CD, because the CD will not check the extras directory.

Building the repository with apt-ftparchive

apt-ftparchive builds the Packages and Packages.gz files, needed by the installer. In order to use apt-ftparchive we will need to provide it with some configuration and some index files.

We will put the index files in /opt/indices:

  • mkdir -p /opt/indices /opt/apt-ftparchive
    cd /opt/indices/
    DIST=dapper; wget http://archive.ubuntu.com/ubuntu/indices/override.$DIST.{extra.main,main,main.debian-installer,restricted,restricted.debian-installer}

Create the files apt-ftparchive-deb.conf, apt-ftparchive-udeb.conf, apt-ftparchive-extras.conf, and release.conf in a directory (/opt/apt-ftparchive), substituting /opt/cd-image/ for the path to your CD image directory, and /opt/indices/ for the location of the index files, if they differ.

/opt/apt-ftparchive/apt-ftparchive-deb.conf:

  • Dir {
      ArchiveDir "/opt/cd-image/";
    };
    
    TreeDefault {
      Directory "pool/";
    };
    
    BinDirectory "pool/main" {
      Packages "dists/dapper/main/binary-i386/Packages";
      BinOverride "/opt/indices/override.dapper.main";
      ExtraOverride "/opt/indices/override.dapper.extra.main";
    };
    
    BinDirectory "pool/restricted" {
     Packages "dists/dapper/restricted/binary-i386/Packages";
     BinOverride "/opt/indices/override.dapper.restricted";
    };
    
    Default {
      Packages {
        Extensions ".deb";
        Compress ". gzip";
      };
    };
    
    Contents {
      Compress "gzip";
    };

The ExtraOverride component above is needed to add the Task header to main packages, referenced from the preseed file with ~t<task name>. This is not supplied - but can be extracted from the existing main Packages file with a simple perl script :-

  • # extraoverride.pl
    # generate ExtraOverride file
    # use as follows :-
    # extraoverride.pl < /opt/cd-image/dists/dapper/main/binary-i386/Packages >> /opt/indices/override.dapper.extra.main
    
    while (<>) {
            chomp;
            next if /^ /;
            if (/^$/ && defined($task)) {
                    print "$package Task $task\n";
                    undef $package;
                    undef $task;
            }
            ($key, $value) = split /: /, $_, 2;
            if ($key eq 'Package') {
                    $package = $value;
            }
            if ($key eq 'Task') {
                    $task = $value;
            }
    }

/opt/apt-ftparchive/apt-ftparchive-udeb.conf:

  • Dir {
      ArchiveDir "/opt/cd-image/";
    };
    
    TreeDefault {
      Directory "pool/";
    };
    
    BinDirectory "pool/main" {
      Packages "dists/dapper/main/debian-installer/binary-i386/Packages";
      BinOverride "/opt/indices/override.dapper.main.debian-installer";
    };
    
    BinDirectory "pool/restricted" {
      Packages "dists/dapper/restricted/debian-installer/binary-i386/Packages";
      BinOverride "/opt/indices/override.dapper.restricted.debian-installer";
    };
    
    Default {
      Packages {
        Extensions ".udeb";
        Compress ". gzip";
      };
    };
    
    Contents {
      Compress "gzip";
    };

/opt/apt-ftparchive/apt-ftparchive-extras.conf:

  • Dir {
      ArchiveDir "/opt/cd-image/";
    };
    
    TreeDefault {
      Directory "pool/";
    };
    
    BinDirectory "pool/extras" {
      Packages "dists/dapper/extras/binary-i386/Packages";
    };
    
    Default {
      Packages {
        Extensions ".deb";
        Compress ". gzip";
      };
    };
    
    Contents {
      Compress "gzip";
    };

release.conf

This is the configuration file for apt-ftparchive. Change to suit your distribution version:

  • APT::FTPArchive::Release::Origin "Ubuntu";
    APT::FTPArchive::Release::Label "Ubuntu";
    APT::FTPArchive::Release::Suite "dapper";
    APT::FTPArchive::Release::Version "6.06";
    APT::FTPArchive::Release::Codename "dapper";
    APT::FTPArchive::Release::Architectures "i386";
    APT::FTPArchive::Release::Components "main restricted extras";
    APT::FTPArchive::Release::Description "Ubuntu 6.06 LTS";

To build the repository, sign it, and update the MD5SUM file, you can use a script like this:

BUILD=/opt/cd-image
APTCONF=/opt/apt-ftparchive/release.conf
DISTNAME=dapper

pushd $BUILD
apt-ftparchive -c $APTCONF generate /opt/apt-ftparchive/apt-ftparchive-deb.conf
apt-ftparchive -c $APTCONF generate /opt/apt-ftparchive/apt-ftparchive-udeb.conf
apt-ftparchive -c $APTCONF generate /opt/apt-ftparchive/apt-ftparchive-extras.conf
apt-ftparchive -c $APTCONF release $BUILD/dists/$DISTNAME > $BUILD/dists/$DISTNAME/Release

gpg --default-key "YOURKEYID" --output $BUILD/dists/$DISTNAME/Release.gpg -ba $BUILD/dists/$DISTNAME/Release
find . -type f -print0 | xargs -0 md5sum > md5sum.txt
popd

Burning the CD

At this point, you have a directory which is ready to be collected into an .ISO file and then burnt to a CD.

Building the ISO image

x86 and AMD64

IMAGE=custom.iso
BUILD=/opt/cd-image/

mkisofs -r -V "Custom Ubuntu Install CD" \
            -cache-inodes \
            -J -l -b isolinux/isolinux.bin \
            -c isolinux/boot.cat -no-emul-boot \
            -boot-load-size 4 -boot-info-table \
            -o $IMAGE $BUILD

Power PC

Download [http://people.ubuntu.com/~cjwatson/hfs.map the HFS map], then use the following command:

IMAGE=custom.iso
BUILD=/opt/cd-image/

mkisofs -r -V "Custom Ubuntu Install CD" \
            --netatalk -hfs -probe -map hfs.map \
            -chrp-boot -iso-level 2 -part -no-desktop \
            -hfs-bless $BUILD/install \
            -hfs-volid Ubuntu/PowerPC_dapper \
            -o $IMAGE $BUILD

ia64

IMAGE=custom.iso
BUILD=/opt/cd-image/

mkisofs -r -V 'Custom Ubuntu Install CD' \
        -o $IMAGE -no-emul-boot \
        -J -b boot/boot.img -c boot/boot.catalog $BUILD
  • $IMAGE is just the location of your iso image.

Burning the image to CD

To detect the location of your CD drive, try cdrecord --scanbus. For a primary IDE CD drive on /dev/hdc:

sudo nice -18 cdrecord dev=ATA:0,1,0 --speed=24 --blank=fast -v -gracetime=2 -tao $IMAGE

You will burn a lot of coasters in experimenting with this process, so please use rewritable media!

Testing

You can now boot off your CD. Select the new menu item you created. If you've used preseeding to stop the CD asking questions, the installation could be totally automatic.

Troubleshooting

  • If your CD fails to read, try re-burning it, possibly at a slower speed.
  • If you get a red d-i screen, check the error message (use Alt-F2, Alt-F3 etc to cycle through the terminals to read the log), and fix your CD appropriately.

See also

Check out some [:/Scripts:install CD customization scripts] that can be used to automate this process.

InstallCDCustomization (last edited 2020-01-28 16:26:26 by akrosikam)