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 --classic
The ubuntu-image
command needs only the filename of the model assertion to build an image.
If you want to include your own core snaps, such as a custom gadget snap, see Building an image with custom snaps for details on how the model assertion and ubuntu-image command need to be modified.
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 an unsigned 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 types of snap 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
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.