Image building

Any device running Ubuntu Core is instantiated from an image. This image contains little more than the kernel, an init process, and a few essential tools. On all but the earliest releases of Ubuntu Core, even the snapd daemon that manages snaps is itself installed via its own snap.

Reference images are available for supported platforms, including Raspberry Pi, Qualcomm Snapdragon and x86/KVM virtualisation, and these can be download and easily installed. See Supported platforms for the current list and for download links to both the images and the model assertions they use.

Inside a model assertion

Creating an Ubuntu Core image starts with a model assertion, a digitally signed text file with structured headers defining every aspect of the image.

The input for defining and signing such a document is provided as JSON text:

{
    "type": "model",
    "series": "16",
    "authority-id": "canonical",
    "brand-id": "canonical",
    "model": "ubuntu-core-20-amd64",
    "architecture": "amd64",
    "timestamp": "2019-11-14T07:13:24.0Z",
    "base": "core20",
    "grade": "signed",
    "snaps": [
        {
            "name": "pc",
            "type": "gadget",
            "default-channel": "20/stable",
            "id": "UqFziVZDHLSyO3TqSWgNBoAdHbLI4dAH"
        },
        {
            "name": "pc-kernel",
            "type": "kernel",
            "default-channel": "20/stable",
            "id": "pYVQrBcKmBa0mZ4CCN7ExT6jH8rY1hza"
        },
        {
            "name": "core20",
            "type": "base",
            "default-channel": "latest/stable",
            "id": "DLqre5XGLbDqg9jPtiAhRRjDuPVa5X1q"
        },
        {
            "name": "snapd",
            "type": "snapd",
            "default-channel": "latest/stable",
            "id": "PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4"
        }
    ]
}

The above example shows the reference model assertion for amd64. To see how this can be modified and signed, see Custom images.

The model assertion includes details such as the store to use (brand-id and authority-id), the model name (ubuntu-core-20-amd64) and the hardware architecture
(amd64). Any snaps installed on the device will respect this selected architecture.

As outlined in Snaps in Ubuntu Core, there are four principle snaps-types that combine to create the Ubuntu Core environment. These are kernel, gadget, base and snapd, and all four need to be referenced within a model assertion.

Building with ubuntu-image

Images are built from a model assertion using ubuntu-image, a tool to generate a bootable image. It can be installed on a snap-supporting Linux system as follows:

$ sudo snap install ubuntu-image --beta --classic

The ubuntu-image command needs only the filename of the model assertion to build an image.

The following will build an amd64 image using the ubuntu-core-20-amd64.model reference model assertion:

$ ubuntu-image snap ubuntu-core-20-amd64.model
Fetching snapd
Fetching pc-kernel
Fetching core20
Fetching pc

The output includes the img file itself, alongside a seed.manifest file. The manifest file simply lists the specific revision numbers of the snapd, pc, pc-kernel and core snaps built within the image, plus any other snaps added to the model.

Testing an image

To test the image with QEMU (https://www.qemu.org/), first install the OVMF package (eg. sudo apt install ovmf) then run the following command to boot a UC20 image (renamed pc.img) within a virtual machine:

sudo qemu-system-x86_64 -smp 2 -m 2048 \
 -net nic,model=virtio -net user,hostfwd=tcp::8022-:22 \
 -drive file=/usr/share/OVMF/OVMF_CODE.fd,if=pflash,format=raw,unit=0,readonly=on \
 -drive file=pc.img,cache=none,format=raw,id=disk1,if=none \
 -device virtio-blk-pci,drive=disk1,bootindex=1 -machine accel=kvm

Older OVMF packages can cause QEMU boot problems. Either build them manually, or consider extracting the files from a more recent package. OVMF for Ubuntu 20.04 LTS (Focal Fossa)](https://releases.ubuntu.com/20.04/) is known to work.

With a successful boot, Ubuntu Core initialisation will ask for both networking parameters and an Ubuntu One account (see https://snapcraft.io/account).

When the initialisation process has finished, and rebooted, you can SSH to the device using either the physical device network address, or localhost port 8022 for the above QEMU example command:

$ ssh <username>@localhost -p 8022

You are now connected to the Ubuntu Core virtual machine, from where you can configure and install whatever apps you need.

To list which snaps are installed, for example, type ‘snap list’:

$ snap list
Name       Version        Rev    Tracking       Publisher   Notes
core20     20201210       904    latest/stable  canonical✓  base
pc         20-0.4         115    20/stable      canonical✓  gadget
pc-kernel  5.4.0-66.74.1  722    20/stable      canonical✓  kernel
snapd      2.49           11107  latest/stable  canonical✓  snapd

To view the model assertion used to build the image, type snap model --assertion:

$ snap model --assertion
type: model                                                                                                                                                
authority-id: canonical                                                                                                                                    
series: 16                                                                                                                                                 
brand-id: canonical                                                                                                                                        
model: ubuntu-core-20-amd64                                                                                                                                
architecture: amd64                                                                                                                                        
base: core20                                                                                                                                               
grade: signed                                                                                                                                              
[...]

To output the serial assertion rather than the model assertion, type snap model --serial:

$ snap model --serial
brand-id:  canonical
model:     ubuntu-core-20-amd64
grade:     signed
serial:    1194d330-d27b-4230-a16f-ab0d23665010

See the Snap documentation for more details on working with snaps. To build a custom image that includes your own selection of snaps, take a look at Custom images.

Last updated 2 months ago. Help improve this document in the forum.