How to customize Ubuntu 14.04 installation CD

Prerequisites
1. A new installed system via Ubuntu-14.04-server-amd64.

2. A installed and configured ubuntu system with GUI, like with lubuntu-desktop installed.

Preparation
1. On the new installed server system, download all deb packages needed to put into new installation CD.

#!/bin/bash
DEB_DIR="/root/offline/debs"
DEB="/root/offline/deb"

if [[ -e "${DEB_DIR}" ]]; then
    echo "PS - Cleaning \"${DEB_DIR}\""
    rm -rf "${DEB_DIR}"
fi

if [[ -e "${DEB}" ]]; then
    echo "PS - Cleaning \"${DEB}\""
    rm -rf "${DEB}"
fi

echo "PS - Re-creating \"${DEB_DIR}\""
mkdir -p "${DEB_DIR}"
mkdir -p "${DEB}"

echo "PS - Downloading DEBs to \"${DEB_DIR}\""
apt-get install -d -o dir::cache=${DEB_DIR} \
        openssh-server build-essential \
        vlan ifenslave bridge-utils \
        lubuntu-desktop vim tightvncserver \
        qemu-kvm libvirt-bin \
        openvswitch-switch openvswitch-common \
        python-libvirt libssl-dev libffi-dev \
        virt-manager virt-viewer \
        chromium-browser \
        tmux traceroute

echo "PS - Downloading DEBs to \"${DEB}\""
cp ${DEB_DIR}/archives/*.deb ${DEB}/
echo "PS - Finished"

2. Generate new keyring file via gpg command

gpg --gen-key

If there is error about not enough random bytes available, we can using stress to make more system load.

stress --cpu 8 --io 12 --vm 8 --hdd 512M --vm-bytes 128M --timeout 20s

Random bytes can be monitored via

watch cat /proc/sys/kernel/random/entropy_avail

3. Build new ubuntu-keyring-2012.05.19 packages for new installation CD.

3.1 List out the new generated key via gpg command

root@jack-ps:/opt/custom-cd# gpg --list-key
/root/.gnupg/pubring.gpg
------------------------
pub 2048R/8D1D2CB5 2014-12-27
uid jack-selfmade <jack-selfmade@jack.com>
sub 2048R/AD460379 2014-12-27

3.2 Get ubuntu-keyring source packages via apt-get

root@jack-ps:/opt/custom-cd# cd /opt/build
root@jack-ps:/opt/build# apt-get install fakeroot
root@jack-ps:/opt/build# apt-get source ubuntu-keyring
root@jack-ps:/opt/build# cd /opt/build/ubuntu-keyring-2012.05.19/keyrings/

3.3 Import ubuntu-keyring in the source packages

root@jack-ps:/opt/build/ubuntu-keyring-2012.05.19/keyrings#  gpg --import < ubuntu-archive-keyring.gpg
root@jack-ps:/opt/build/ubuntu-keyring-2012.05.19/keyrings#  gpg --list-keys "Signing Key"

pub 1024D/437D05B5 2004-09-12
uid Ubuntu Archive Automatic Signing Key <ftpmaster@ubuntu.com>
sub 2048g/79164387 2004-09-12

pub 1024D/FBB75451 2004-12-30
uid Ubuntu CD Image Automatic Signing Key <cdimage@ubuntu.com>

pub 4096R/C0B21F32 2012-05-11
uid Ubuntu Archive Automatic Signing Key (2012) <ftpmaster@ubuntu.com>

pub 4096R/EFE21092 2012-05-11
uid Ubuntu CD Image Automatic Signing Key (2012) <cdimage@ubuntu.com>

root@jack-ps:/opt/build/ubuntu-keyring-2012.05.19/keyrings#  gpg --export 437D05B5 FBB75451  C0B21F32  EFE21092 8D1D2CB5 > ubuntu-archive-keyring.gpg

NOTE:  8D1D2CB5 is the key file generated in previous step.

3.4 Build new ubuntu-keyring packages

root@jack-ps:/opt/build/ubuntu-keyring-2012.05.19/keyrings# cd ..
root@jack-ps:/opt/build/ubuntu-keyring-2012.05.19# dpkg-buildpackage -rfakeroot -m"jack-selfmade <jack-selfmade@jack.com>" -k8D1D2CB5
root@jack-ps:/opt/build/ubuntu-keyring-2012.05.19# cd ..

Customization

1. Copy all files in a CD images, such as ubuntu-14.04-server-amd64.iso. A scripts maybe looks like below:

#!/bin/bash
SRC_ISO="ubuntu-14.04.1-server-amd64.iso"
HOME_DIR="/opt/custom-cd"
SRC_DIR="${HOME_DIR}/src-iso"
NEW_DIR="${HOME_DIR}/new-iso"

echo "PS - Change to \"${HOME_DIR}\""
cd "${HOME_DIR}"

echo "PS - Checking directories"
mkdir -p "${SRC_DIR}"
mkdir -p "${NEW_DIR}"

echo "PS - Mounting ISO file"
mount -o loop,ro "${HOME_DIR}/${SRC_ISO}" "${SRC_DIR}"

echo "PS - Copying all files from ISO to new directory"
#cp -r "${SRC_DIR}"/* "${NEW_DIR}"/
#cp -r "${SRC_DIR}"/.disk/ "${NEW_DIR}"/
cp -rT "${SRC_DIR}" "${NEW_DIR}"
#rsync -av "${SRC_DIR}" "${NEW_DIR}"

echo "PS - Unmounting ISO file"
umount "${SRC_DIR}"

echo "PS - Finished"

2. Customize preseed file. A sample preseed file maybe looks like:

root@jack-ps:/opt/custom-cd# cat new-iso/preseed/ps-lubuntu-server.seed

####################################################################
# General
####################################################################
#Disable gpg authentication
d-i debian-installer/allow_unauthenticated boolean true

####################################################################
# Localizations
####################################################################
### Locale selection ###
#d-i debian-installer/locale string en_US
d-i debian-installer/language string en
d-i debian-installer/country string US
d-i debian-installer/locale string en_US.UTF-8
d-i localechooser/supported-locales en_US.UTF-8

### Keyboard selection ###
d-i console-setup/ask_detect boolean false
d-i keyboard-configuration/layoutcode string us
#d-i keyboard-configuration/variantcode string dvorak

####################################################################
# Networking
####################################################################
# Network Configuration
d-i netcfg/enable boolean true
d-i netcfg/choose_interface select auto
d-i netcfg/disable_dhcp boolean false
d-i netcfg/dhcp_timeout string 30
d-i netcfg/dhcpv6_timeout string 30

d-i netcfg/get_hostname string psnode
d-i netcfg/get_domain string hp.local

####################################################################
# Timezone
####################################################################
d-i time/zone string Asia/Shanghai
d-i clock-setup/utc boolean true
d-i clock-setup/ntp boolean false

####################################################################
# Disk Partitioning / Boot loader
####################################################################

### Disk Partitioning ###
# Remove existing lvm or md
d-i partman-md/device_remove_md boolean true
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-lvm/confirm boolean true

# Configure auto partitioner
#d-i partman-auto/init_automatically_partition select Guided - use entire disk
d-i partman-auto/init_automatically_partition some_device
d-i partman-auto/disk string /dev/sda
d-i partman-auto/method string regular
#d-i partman-auto/choose_recipe select All files in one partition (recommended for new users)
d-i partman-auto/choose_recipe select atomic
d-i partman/confirm_write_new_label boolean true
#d-i partman/choose_partition select Finish partitioning and write changes to disk
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true

####################################################################
# User Creation
####################################################################
# Root User
d-i passwd/root-login boolean true
d-i passwd/root-password password hpinvent
d-i passwd/root-password-again password hpinvent

# Mortal User
d-i passwd/make-user boolean true
d-i passwd/user-fullname string helionps
d-i passwd/username string helionps
d-i passwd/user-password password hpinvent
d-i passwd/user-password-again password hpinvent
d-i passwd/auto-login boolean false
d-i user-setup/allow-password-weak boolean true

d-i user-setup/encrypt-home boolean false

####################################################################
# Package selection
####################################################################
# Install the Ubuntu Server seed.
tasksel tasksel/force-tasks string server
tasksel tasksel/first multiselect openssh-server, virt-host, print-server
# Other extras packages
d-i pkgsel/include string build-essential, vlan, ifenslave, bridge-utils, lubuntu-desktop, vim, tightvncserver, qemu-kvm, libvirt-bin, openvswitch-switch, openvswitch-common, python-libvirt, libssl-dev, libffi-dev, virt-manager, virt-viewer, chromium-browser, tmux, traceroute

# Policy for applying updates.
d-i pkgsel/update-policy select none
# Only install basic language packs. Let tasksel ask about tasks.
d-i pkgsel/language-pack-patterns string
# No language support packages.
d-i pkgsel/install-language-support boolean false
# Verbose output and no boot splash screen.
d-i debian-installer/quiet boolean false
d-i debian-installer/splash boolean false

####################################################################
# Package selection
####################################################################
d-i grub-installer/only_debian boolean true
d-i grub-installer/with_other_os boolean true

####################################################################
# Finishing up
####################################################################
d-i finish-install/keep-consoles boolean true
d-i finish-install/reboot_in_progress note
#d-i cdrom-detect/eject boolean false

3. Modify boot menu/ grub configuration files.

root@jack-ps:/opt/custom-cd# cat new-iso/boot/grub/grub.cfg

if loadfont /boot/grub/font.pf2 ; then
    set gfxmode=auto
    insmod efi_gop
    insmod efi_uga
    insmod gfxterm
    terminal_output gfxterm
fi

set menu_color_normal=white/black
set menu_color_highlight=black/light-gray

menuentry "Install PS Ubuntu Server" {
    set gfxpayload=keep
    linux /install/vmlinuz locale=en_US console-setup/ask_detect=false keyboard-configuration/layoutcode=us console-setup/layoutcode=en file=/cdrom/preseed/ps-lubuntu-server.seed quiet --
    initrd /install/initrd.gz
}
menuentry "Multiple server install with MAAS" {
    set gfxpayload=keep
    linux /install/vmlinuz modules=maas-enlist-udeb vga=788 initrd=/install/initrd.gz quiet --
    initrd /install/initrd.gz
}
menuentry "Check disc for defects" {
    set gfxpayload=keep
    linux /install/vmlinuz MENU=/bin/cdrom-checker-menu quiet --
    initrd /install/initrd.gz
}
menuentry "Rescue a broken system" {
    set gfxpayload=keep
    linux /install/vmlinuz rescue/enable=true --
    initrd /install/initrd.gz
}

4. Other files may related to boot menu

root@jack-ps:/opt/custom-cd# cat new-iso/isolinux/txt.cfg
default install
label install
    menu label ^Install PS Ubuntu Server
    kernel /install/vmlinuz
    append locale=en_US console-setup/ask_detect=false keyboard-configuration/layoutcode=us console-setup/layoutcode=en file=/cdrom/preseed/ps-lubuntu-server.seed vga=788 initrd=/install/initrd.gz quiet --
label cloud
    menu label ^Multiple server install with MAAS
    kernel /install/vmlinuz
    append modules=maas-enlist-udeb vga=788 initrd=/install/initrd.gz quiet --
label check
    menu label ^Check disc for defects
    kernel /install/vmlinuz
    append MENU=/bin/cdrom-checker-menu vga=788 initrd=/install/initrd.gz quiet --
label memtest
    menu label Test ^memory
    kernel /install/mt86plus
label hd
    menu label ^Boot from first hard disk
    localboot 0x80

5. Other files need to be modified, like

root@jack-ps:/opt/custom-cd# cat new-iso/isolinux/langlist
en
zh_CN
zh_TW

6. Generate new filesystem.squashfs with the updated ubuntu-archive-keyring.gpg in previous step.

root@jack-ps:/opt/custom-cd# apt-get -y install squashfs-tools

root@jack-ps:/opt/custom-cd# mkdir -p /opt/custom-cd/SquashFS/

root@jack-ps:/opt/custom-cd# cd SquashFS

root@jack-ps:/opt/custom-cd/SquashFS# unsquashfs /opt/custom-cd/new-iso/install/filesystem.squashfs

root@jack-ps:/opt/custom-cd/SquashFS# cd squashfs-root

root@jack-ps:/opt/custom-cd/SquashFS/squashfs-root# cp /opt/build/ubuntu-keyring-2012.05.19/keyrings/ubuntu-archive-keyring.gpg usr/share/keyrings/ubuntu-archive-keyring.gpg

root@jack-ps:/opt/custom-cd/SquashFS/squashfs-root# cp /opt/build/ubuntu-keyring-2012.05.19/keyrings/ubuntu-archive-keyring.gpg etc/apt/trusted.gpg

root@jack-ps:/opt/custom-cd/SquashFS/squashfs-root# cp /opt/build/ubuntu-keyring-2012.05.19/keyrings/ubuntu-archive-keyring.gpg var/lib/apt/keyrings/ubuntu-archive-keyring.gpg

root@jack-ps:/opt/custom-cd/SquashFS/squashfs-root# rm /opt/custom-cd/new-iso/install/filesystem.squashfs /opt/custom-cd/new-iso/install/filesystem.size

root@jack-ps:/opt/custom-cd/SquashFS/squashfs-root# du -sx --block-size=1 ./ | cut -f1 > /opt/custom-cd/new-iso/install/filesystem.size
root@jack-ps:/opt/custom-cd/SquashFS/squashfs-root# mksquashfs ./ /opt/custom-cd/new-iso/install/filesystem.squashfs

7. Replace ubuntu-keyring package files in pool/main/u/ubuntu-keyring with the one generated in previous step. (See script in Step10)

8. Create pool/extras, and copy all deb files downloaded to this directory.(See script in Step10)

9. Create dists/trusty/extras/binary-amd64/ and generate Packages, Packages.gz, and Release file.(See script in Step10)

root@jack-ps:/opt/custom-cd# cat new-iso/dists/trusty/extras/binary-amd64/Release
Archive: trusty
Version: 14.04
Component: extras
Origin: Ubuntu
Label: Ubuntu
Architecture: amd64

10. Generate new Release and Release.gpg for new ISO in dists/trusty/.(See script in Step10)
Sample of apt-release.conf

root@jack-ps:/opt/custom-cd# cat /opt/custom-cd/scripts/apt-release.conf 
APT::FTPArchive::Release::Origin "Ubuntu";
APT::FTPArchive::Release::Label "Ubuntu";
APT::FTPArchive::Release::Suite "trusty";
APT::FTPArchive::Release::Version "14.04";
APT::FTPArchive::Release::Codename "trusty";
APT::FTPArchive::Release::Architectures "amd64 i386";
APT::FTPArchive::Release::Components "main restricted extras";
APT::FTPArchive::Release::Description "PS lubuntu 14.04.01 Server";

Sample scripts for completing about steps

#!/bin/bash
HOME_DIR="/opt/custom-cd"
SRC_DIR="${HOME_DIR}/src-iso"
NEW_DIR="${HOME_DIR}/new-iso"
DEB_DIR="${HOME_DIR}/deb"
EXTRAS_DIST="${NEW_DIR}/dists/stable/extras/binary-amd64"
EXTRAS_POOL="${NEW_DIR}/pool/extras"

RELEASE_CONF="${HOME_DIR}/scripts/apt-release.conf"
RELEASE_DIR="${NEW_DIR}/dists/trusty"

echo "PS - Change to \"${HOME_DIR}\""
cd "${HOME_DIR}"

echo "PS - Checking directories"
if [[ ! -e "${DEB_DIR}" ]]; then
    echo "Error: Please make sure your debs are located at "
    echo " \"${DEB_DIR}\""
    exit 1
fi
mkdir -p "${EXTRAS_DIST}"
mkdir -p "${EXTRAS_POOL}"

echo "PS - Copying all debs to \"${EXTRAS_POOL}\""
cp ${DEB_DIR}/* ${EXTRAS_POOL}

echo "PS - Updating ubuntu-keyring"
cp /opt/build/ubuntu-keyring*deb ${NEW_DIR}/pool/main/u/ubuntu-keyring

echo "PS - Generating Packages.gz for extras"
cd ${NEW_DIR}
apt-ftparchive packages pool/extras > dists/stable/extras/binary-amd64/Packages
gzip -c dists/stable/extras/binary-amd64/Packages | tee dists/stable/extras/binary-amd64/Packages.gz > /dev/null
#apt-ftparchive packages ${EXTRAS_POOL} | gzip > ${EXTRAS_DIST}/Packages.gz

echo "PS - Generating new Release"
cd ${NEW_DIR}
apt-ftparchive release -c ${RELEASE_CONF} dists/trusty > dists/trusty/Release

echo "PS - Generating new Release.gpg"
cd ${NEW_DIR}
#gpg -b ${RELEASE_DIR}/Release
#mv ${RELEASE_DIR}/Release.sig ${RELEASE_DIR}/Release.gpg
gpg --default-key "8D1D2CB5" --output ${RELEASE_DIR}/Release.gpg -ba ${RELEASE_DIR}/Release
echo "PS - Finished"

11. Generate new md5sum.txt for the new ISO file. (See scripts in step 12)

12. Create the ISO file.  (See scripts in step 12)

#!/bin/bash
HOME_DIR="/opt/custom-cd"
SRC_DIR="${HOME_DIR}/src-iso"
NEW_DIR="${HOME_DIR}/new-iso"
DEB_DIR="${HOME_DIR}/deb"
ISO_NAME="ps-lubuntu-14.04.1-server-amd64.iso"

echo "PS - Generating md5sum.txt"
cd ${NEW_DIR}
#md5sum `find ! -name "md5sum.txt" ! -path "./isolinux/*" -follow -type f` > md5sum.txt
find . -type f -print0 | xargs -0 md5sum > md5sum.txt
cd ..

echo "PS - Greating new ISO file "
mkisofs -r -V "PS lubuntu Server CD" \
        -cache-inodes \
        -J -l -b isolinux/isolinux.bin \
        -c isolinux/isolinux.cat \
        -no-emul-boot \
        -boot-load-size 4 -boot-info-table \
        -z -iso-level 4 \
        -o ./${ISO_NAME} \
        -joliet-long ${NEW_DIR}/

echo "PS - Finished"

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: