ubuntu-image (GitHub)(Launchpad) is a tool for building bootable images of both the Ubuntu Core and Ubuntu Classic flavors of Ubuntu. It is intended to replace disparate tools such as debiancd and others which are currently in use to build various images. It is driven by a declarative YAML file rather than a bunch of custom scripts, and can be used to build images anywhere, with a minimum of external requirements. This means just about anyone can build images just about anywhere.
At the time of this writing (09-Dec-2016), ubuntu-image only builds Snappy images. Planning is underway to extend ubuntu-image to build classic images. ubuntu-image is available as both a classic .deb on Ubuntu Xenial (16.04), Yakkety (16.10) and Zesty (17.04). It's also available as a "devmode" snap. It's written in Python 3 (with 3.5 as a minimal requirement), and contributions are welcome.
For snap images, a user creates a model assertion, which is a signed declarative description of the bits that go into the image, including a kernel snap and a gadget snap. The gadget snap defines specifics about the type of board or machine that you are building the image for, and it contains a YAML file (called the gadget.yaml) that is itself a declarative description of how to lay out the bits in a bootable image, along with specific bootloader declarations. When ubuntu-image builds an Ubuntu Core image, it talks to the store via the snap prepare-image command, pulling down the kernel and gadget snaps, digging out the gadget.yaml file, parsing that, and then using those declarations to assemble the bootable disk image. A user can then flash that image, boot locally using QEMU, or whatever else is appropriate.
For classic images, ubuntu-image will work similarly, although you won't need a model assertion and you won't talk to the snap store. A high level goal is that any user with access to the archive should be able to spin a bootable Ubuntu Classic image on their local desktop, possibly/probably with architecture limitations (i.e. you can build an amd64 image on an amd64 desktop). Design is ongoing.
Here are some requirements for classic image building.
- single source gadget for a given bootloader config
- launchpad service has no deps except archive
- u-i = top-level interface cli
- can be run end-to-end locally for native build
- support local signed apt repository (non-cloud classic)
- support multiple images produced from a consistent archive (no package version delta between images w/same serial-cloud)
- support additional image encapsulations (e.g. qcow2)?
- hybrid iso
- .tar.xz/squashfs output? (lxd)
- zfs volumes
- lvm volumes
Random sprint discussion notes
- first target raspi3
- Won't use snap prepare-image
- Won't use snap store
- We'll just magically get a gadget.yaml
- Bootloader bits will come from us
- Point it at what looks like an unpacked gadget snap
- Some configuration (cli) to tell it what rootfs it's building
- Always build against what's in the archive
- Where does the gadget.yaml come from?
- There won't be a model.assertion, but there will be some equivalent
- arch, distro, blah, blah - e.g. drives launchpadlib to give us the bits
- Calls livecd-rootfs / live-build with the proper bits locally?
- Building in a lxd container is a reasonable assumption
- debiancd is an unmaintained codebase; u-i should replace it
- foundations should maintain bootloader code
- zyga has snapcraft to build gadget snaps