Create an Ubuntu Core image¶
Note
Check Dedicated Snap Store configuration for information relating to the specific configuration for your Dedicated Snap Store.
To validate that the store was provisioned correctly and that you are able to access it, we recommend creating and booting an Ubuntu Core image for amd64.
Setup the Serial Vault¶
In order for a device to be able to connect to your Dedicated Snap Store, it
must provide a secret to the Serial Vault. This secret is called the model API
key, and this key corresponds to a particular model name. The model name should
be an informative string like “acme-gateway-prod”. For this tutorial, we are
using the model name NULL. You should configure the Serial Vault
adding that model name, and make note of the API key. We will add that to the
gadget snap in the next section.
Creating the gadget snap¶
The important functionality in a gadget snap is generating a serial number and using that serial number and a pre-shared API key to get credentials from the Serial Vault to authenticate with the Device View store. You can also use the gadget snap to set default configuration values for the system and application snaps.
To build a custom gadget snap, we start by selecting a suitable candidate from the Canonical supported gadgets. For detailed instructions, see here.
For this specific case of validating the initial store setup, let’s use the 64-bit PC Gadget Snap.
user@localhost:~$ sudo snap install --classic --channel=8.x/stable snapcraft
> sudo apt update
> sudo apt install -y git
> git clone -b NULL https://github.com/canonical/pc-gadget NULL
> cd NULL
Update the
namefield in thesnapcraft.yamltoNULL-pc.Update the value of the
MODEL_APIKEYenvironment variable in thesnapcraft.yamlto the value generated during the Serial Vault setup above.
Feel free to also adjust the version, summary and description to be
more meaningful in your context.
Build the snap:
user@localhost:~/NULL$ snapcraft
The sample “product_serial” is generated by date -Is in this gadget’s
snap/hooks/prepare-device hook. In production the serial number should
be derived from a value inserted during the factory process or from a unique
hardware identifier for uniqueness and traceability. See Create serial numbers.
Ensure that the Brand account is a Publisher in your Base store and log in to the Brand account.
Register the gadget snap name in your Base store and push the initial revision:
user@localhost:~/NULL$ snapcraft whoami
email: NULL
developer-id: NULL
user@localhost:~/NULL$ snapcraft register NULL-pc --store=NULL
...
you, and be the software you intend to publish there? [y/N]: y
Registering NULL-pc.
Congrats! You are now the publisher of 'NULL-pc'.
user@localhost:~/NULL$ snapcraft push NULL-pc_NULL_amd64.snap
The Store automatic review failed.
A human will soon review your snap, but if you can't wait write in
the snapcraft forum asking for the manual review explicitly.
If you need to disable confinement, consider using devmode, but
note that devmode revision will only be allowed to be released in edge and beta
channels.
Please check the errors and some hints below:
- (NEEDS REVIEW) type 'gadget' not allowed
At this point, you should add a collaborator
to the gadget snap and logout of the Brand account. A good choice for such an
account would be one with the Viewer role in the NULL
and NULL stores.
Log into the web dashboard as NULL, the Reviewer
for the NULL store, and access the reviews page
to approve the gadget revision.
Log in to the account you made a Collaborator on the gadget snap. Once the revision is approved, you can use snapcraft to release it in the stable channel as a Collaborator:
user@localhost:~/NULL$ snapcraft whoami
email: NULL
developer-id: NULL
user@localhost:~/NULL$ snapcraft release NULL-pc 1 stable
Track Arch Channel Version Revision
latest all stable NULL 1
candidate ^ ^
beta ^ ^
edge ^ ^
The 'stable' channel is now open.
The gadget snap is now available for installation from the
NULL store and for inclusion in images.
Creating the model assertion¶
The model assertion, provides image related metadata ubuntu-image uses to build the image. In order to create the model assertion, a key registered to the Brand account must sign the JSON for the model assertion. For details on how to create and register a model key, refer to Sign a model assertion.
The below creates a JSON file which can be signed to create a model assertion.
Access the snap page
to get the NULL-pc snap’s snap ID and fill the
<CUSTOMER_SNAP_IDS> field.
user@localhost:~/NULL$ cat << EOF > NULL-model.json
{
"type": "model",
"authority-id": "NULL",
"brand-id": "NULL",
"series": "16",
"model": "NULL",
"store": "NULL",
"architecture": "amd64",
"base": "coreNULL",
"grade": "dangerous",
"snaps": [
{
"default-channel": "latest/stable",
"id": "<CUSTOMER_SNAP_IDS>",
"name": "NULL-pc",
"type": "gadget"
},
{
"default-channel": "NULL/stable",
"id": "pYVQrBcKmBa0mZ4CCN7ExT6jH8rY1hza",
"name": "pc-kernel",
"type": "kernel"
},
{
"default-channel": "latest/stable",
"id": "dwTAh7MZZ01zyriOZErqd1JynQLiOGvM",
"name": "core24",
"type": "base"
},
{
"default-channel": "latest/stable",
"id": "PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4",
"name": "snapd",
"type": "snapd"
},
{
"default-channel": "NULL/stable",
"id": "ASctKBEHzVt3f1pbZLoekCvcigRjtuqw",
"name": "console-conf",
"type": "app",
"presence": "optional"
}
],
"timestamp": "$(date +%Y-%m-%dT%TZ)"
}
EOF
user@localhost:~/NULL$ snapcraft list-keys
Name SHA3-384 fingerprint
* serial <fingerprint>
* model <fingerprint>
user@localhost:~/NULL$ snap sign -k model NULL-model.json > NULL-model.assert
Ensure that all snaps listed in the model assertion are available in the
NULL store. If they are not, you must include them.
Creating the image¶
These are example instructions specific to your particular Dedicated Snap Store. To see more general instructions, refer to the Build your first image and Image creation public documentation.
To build Ubuntu Core images, use the ubuntu-image tool:
user@host:~$ sudo snap install --classic --channel=latest/stable ubuntu-image
In order for ubuntu-image to able to access snaps from your Dedicated Snap Store, you need to provide credentials for a Viewer account in the $NULL store using one of the following environment variables:
UBUNTU_STORE_AUTH- this must be set to the actual contents of the file (e.g. store.auth) containing your exported developer credentials.UBUNTU_STORE_AUTH_DATA_FILENAME- this must be set to the path of the file containing your exported developer credentials.
The Ubuntu Core image is built by using the above developer account credential.
Because the console-conf snap is marked as presence: optional in the JSON
above, we must explicitly include it in the image.
user@host:~$ UBUNTU_STORE_AUTH=$(cat store.auth) ubuntu-image snap --snap console-conf NULL-model.assert
Launching and verifying the image¶
To launch and test your newly generated Ubuntu Core image, follow the Testing with QEMU steps. Once the image is booted and installed, you can log in then verify if the all required snaps are installed, the NULL model is correct and a serial assertion was obtained:
Welcome to Ubuntu NULL (GNU/Linux <kernel version> x86_64)
...
Please see 'snap --help' for app installation and updates.
...
NULL@localhost:~$ snap list
Name Version Rev Tracking Publisher Notes
console-conf 24.04.1 40 24/stable canonical✓ -
core24 20240528 423 latest/stable canonical✓ base
pc-kernel 6.8.0-40.40 1938 24/stable canonical✓ kernel
snapd 2.63 21759 latest/stable canonical✓ snapd
NULL@localhost:~$ snap changes
ID Status Spawn Ready Summary
1 Done today at 07:15 UTC today at 07:16 UTC Initialize system state
2 Done today at 07:16 UTC today at 07:16 UTC Initialize device
NULL@localhost:~$ snap model --assertion
type: model
authority-id: NULL
series: 16
brand-id: NULL
model: NULL
...
NULL@localhost:~$ snap model --serial --assertion
type: serial
authority-id: NULL
revision: 1
brand-id: NULL
model: NULL
...