Table of Contents
Introduction
This post is a follow up to How-To: Make Ubuntu Autoinstall ISO with Cloud-init written in Sept. 2021. We will look at changes needed for Ubuntu 22.04.
The Ubuntu sever autoinstall method changed with the release of 20.04. Prior to that the old Debian pre-seed method was used. The new autoinstall method uses a “user-data” file similar in usage to what is done with cloud-init. The Ubuntu installer, ubiquity, was modified for this and became subiquity (server ubiquity).
The autoinstall “user-data” YAML file is a superset of the cloud-init user-data file and contains directives for the install tool curtin. The only real guide for what can go in this file is Automated Server Installs Config File Reference and that is not great reference. Actual usage requires considerable web searching, guess work and trial and error.
My personal feeling is that it’s a poorly documented, convoluted mess. The cloud-init and curtin are good tools but the overall experience of trying to work with these for the special case of the Ubuntu autoinstall is not good. Hopefully this post will help those trying get something working.
While researching for this post I found a delightful post by Jim Angel. He does a respectable job of illuminating the concepts involved. I recommend the post as a good-read.
Step 0) Prerequisites
I am building the autoinstall ISO on an Ubuntu 22.04 system. Here are a few packages you will need,
- 7z
sudo apt install p7zip
for unpacking the source ISO (including mbr and efi partition images) - wget
sudo apt install wget
to download a fresh daily build of the 22.04 service ISO - xorriso
sudo apt install xorriso
for building the modified ISO
Two of the biggest sources of trouble when you are creating the user-data file for an autoinstall ISO are,
- syntax mistakes in user-data (read through Automated Server Installs Config File Reference)
- Misconfigured YAML (see this post for a nice tutorial on YAML).
Step 1) Set up the build environment
Make a directory to work in and get a fresh copy of the server ISO.
mkdir u22.04-autoinstall-ISO
cd u22.04-autoinstall-ISO
mkdir source-files
wget https://cdimage.ubuntu.com/ubuntu-server/jammy/daily-live/current/jammy-live-server-amd64.iso
Step 2) Unpack files and partition images from the Ubuntu 22.04 live server ISO
The Ubuntu 22.04 server ISO layout differs from the 20.04 ISO. 20.04 used a single partition on the ISO but 22.04 has separate gpt partitions for mbr, efi, and the install root image.
7zip is very nice for unpacking the ISO since it will create image files for the mbr and efi partitions for you!
7z -y x jammy-live-server-amd64.iso -osource-files
Note, there is no space in -osource-files
In the source-files directory you will see the ISO files plus a directory named ‘[BOOT]’. That directory contains the the files 1-Boot-NoEmul.img 2-Boot-NoEmul.img
those are are, respectively, the mbr (master boot record) and efi (UEFI) partition images from the ISO. Those will be used when we create the modified ISO. There is no reason to leave the raw image files on the new ISO, so move them out of the way and give the directory a better name,
mv '[BOOT]' ../BOOT
Step 3) Edit the ISO grub.cfg file
Edit source-files/boot/grub/grub.cfg
and add the following stanza above the existing menu entries,
menuentry "Autoinstall Ubuntu Server" {
set gfxpayload=keep
linux /casper/vmlinuz quiet autoinstall ds=nocloud\;s=/cdrom/server/ ---
initrd /casper/initrd
}
Note the backslash “\” in front of the semi-colon. That is needed to escape the “;”, otherwise grub would treat the rest of the line as a comment!
This menu entry adds the autoinstall kernel directive and the “data source” (ds) for cloud-init of type “nocloud”. s=/cdrom/server/
is a reference to the directory where we will add user-data and meta-data files that contain the installer configuration yaml. /cdrom
is the top level directory of the ISO.
…add the directory for the user-data and meta-data files
mkdir source-files/server
Note; you can create other directories to contain alternative user-data file configurations and add extra grub menu entries pointing to those directories. That way you could have multiple install configurations on the same ISO and select the appropriate one from the boot menu during install.
Step 4) Create and add your custom autoinstall user-data files
This is where you will need to read the documentation for the user-data syntax and format. I will provide a sample file to get you started.
Note; the meta-data file is just an empty file that cloud-init expects to be present (it would be populated with data needed when using cloud services)
touch source-files/server/meta-data
user-data example file
#cloud-config
autoinstall:
version: 1
interactive-sections: # Install groups listed here will wait for user input
- storage
storage: # This should set the interactive (lvm set) default
layout:
name: lvm
match:
size: largest
locale: en_US.UTF-8
keyboard:
layout: us
identity:
hostname: puget-000
password: $6$PiTL.ZmMVYG6U4q4$qa8lkOtlAAioKLKqt1q1Ci03HUAE4xRnhrvNd1x1oaSVoma2sTRCHtvt2/QV61tn0QQF6m2e/n0Uf1fQ/3yid0
username: ubuntu
ssh:
allow-pw: true
install-server: true
apt:
primary:
- arches: [default]
uri: http://us.archive.ubuntu.com/ubuntu/
# sources: # Example for adding a ppa source
# ignored1: # This is here to get the yaml formatting right when adding a ppa
# source: ppa:graphics-drivers/ppa
packages:
- build-essential
- network-manager
- dkms
- emacs-nox
# - ubuntu-desktop-minimal^ # uncomment to add a minimal desktop
package_update: true
package_upgrade: true
late-commands:
# Changing from networkd to NetworkManager
# move existing config out of the way
- find /target/etc/netplan/ -name "*.yaml" -exec sh -c 'mv "$1" "$1-orig"' _ {} \;
# Create a new netplan and enable it
- |
cat <<EOF | sudo tee /target/etc/netplan/01-netcfg.yaml
network:
version: 2
renderer: NetworkManager
EOF
- curtin in-target --target /target netplan generate
- curtin in-target --target /target netplan apply
- curtin in-target --target /target systemctl enable NetworkManager.service
# Install NVIDIA driver (with apt-get flags)
- curtin in-target -- apt-get -y install --no-install-recommends nvidia-driver-520
#user-data: # Commands here run during first boot (cannot be interactive)
# runcmd:
# # Install the NVIDIA driver from the ppa we setup earlier
# - [apt-get, install, --yes, nvidia-driver-510, --no-install-recommends]
This gist from my older post has some other ideas for a user-data config along with some useful comments by helpful readers.
Getting the user-data file right is where most of your effort will go. It will likely require trial-and-error iterations to get it right!
Step 5) Generate a new Ubuntu 22.04 server autoinstall ISO
The following command is helpful when trying to setup the arguments for building an ISO. It will give flags and data to closely reproduce the source base install ISO.
xorriso -indev jammy-live-server-amd64.iso -report_el_torito as_mkisofs
Editing the report from the above I was able to come up with the command below for creating the autoinstall ISOs.
cd source-files
xorriso -as mkisofs -r \
-V 'Ubuntu 22.04 LTS AUTO (EFIBIOS)' \
-o ../ubuntu-22.04-autoinstall.iso \
--grub2-mbr ../BOOT/1-Boot-NoEmul.img \
-partition_offset 16 \
--mbr-force-bootable \
-append_partition 2 28732ac11ff8d211ba4b00a0c93ec93b ../BOOT/2-Boot-NoEmul.img \
-appended_part_as_gpt \
-iso_mbr_part_type a2a0d0ebe5b9334487c068b6b72699c7 \
-c '/boot.catalog' \
-b '/boot/grub/i386-pc/eltorito.img' \
-no-emul-boot -boot-load-size 4 -boot-info-table --grub2-boot-info \
-eltorito-alt-boot \
-e '--interval:appended_partition_2:::' \
-no-emul-boot \
.
Note; the “.” at the end. That is indicating the path to the current directory i.e. “use the current directory for the source files to build the ISO”.
The partition images that 7z extracted for us are being added back to the recreated ISO.
Test and debug your new autoinstall ISO
You will almost certainly have debugging to do! It’s hard to get a user-data file right on the first attempt. To mke testing easier I recommend using Virtualbox to setup a simple VM that you can use for autoinstall testing. After a trial you create a new debugged ISO and use the Virtualbox VM settings to point at the new ISO and repeat.
When you get a working user-data in the VM then move to real hardware for validation.
Conclusion
Hopefully this updated guide will save you some time and headaches while building an autoinstall ISO for Ubuntu 22.04 server.
I’m not sure if Canonical/Ubuntu will move the desktop installer to this method in the future. For automating the desktop install you could do a procedure similar to what we did for server but substituting the appropriate Debian preseed file for the user-data file. I have an older post that has a, hopefully, useful pressed file example. Note: Auto-Install Ubuntu with Custom Preseed ISO I have not tested this with the Ubuntu 22.04 desktop installer.
Happy computing! -dbk @dbkinghorn