[LXD] ISO images as storage volumes

Project LXD
Status Implemented
Author(s) @monstermunchkin
Approver(s) @stgraber @tomp
Release 5.16
Internal ID LX045


This introduces the ability to add ISO images as read-only storage volumes which can be attached to VMs.


Currently, the only clean way of attaching ISO images to VMs is by adding a disk device to the instance:

lxc config device add win10 install disk source=/path/to/win.iso

For this to work, LXD needs to have access to /path/to/win.iso. This however will not work out-of-the-box, if the machines of the client and LXD aren’t the same. First, the ISO would need to be uploaded to the LXD host. Then, the device could be attached to the instance.

There are two unclean ways of performing this task which are via the migration API, and via the custom volume restore.

A clean solution for this task would be to allow importing an ISO image.

This will also make it easier in the LXD UI to import ISOs as storage volumes, as dealing with protobuf and migration makes it slightly harder.



A new content type iso for custom storage volumes will be introduced. That is to distinguish normal block volumes from ISOs, as the latter will be attached as cdrom to the instance. Normal block volumes are attached as disks.

In order to upload ISO images, the existing lxc storage volume import command will be used:

lxc storage volume import <pool> /path/to/win.iso <volume_name> --type=iso

This makes use of the existing POST /1.0/storage-pools/<pool>/volumes/custom API endpoint which currently handles importing storage volume backups. If LXD detects an ISO header, it will create a new custom volume with the iso content type.

The created custom volume will be marked as read-only as ISOs shouldn’t be read-write.

Custom volumes of content type iso cannot be updated. Instead they need to be deleted and re-created. Also, since these volumes are read-only, neither snapshots nor backups will be supported.

Although setting a volume name when importing backups is optional, it is required when import ISOs. Backups contain a special file containing information e.g. volume name, and pool. For ISOs this isn’t the case, therefore the volume name needs to be set explicitly.

If the filepath suffix is .iso, the --type=iso flag can be omitted as it is set automatically in this case.

API changes

No API endpoint changes.

There will be a new X-LXD-type header which needs to be set to iso when wanting to create an ISO custom volume.

CLI changes

The lxc storage volume import command will gain a new flag --type. This needs to be set to iso if importing an ISO. The default value is backup which imports the data as a backup.

Database changes

No database changes.

Upgrade handling

No upgrade handling.

Further information

No further information.


So I think the lxc storage volume push and lxc storage volume pull approach could simply be done through the existing lxc storage volume import and (maybe at a later stage) lxc storage volume export.

That’s because with pull/push, the user would be expected to create a volume first, but may not know the exact size needed to hold the ISO. The volume being larger than the ISO being uploaded could also become a problem.

Instead I think it’d be better to now allow the traditional creation of an ISO volume, so no lxc storage volume create --type iso but instead require ISO volumes be created through an import with lxc storage volume import /path/to/iso some-name.

The CLI should then set the correct Content-Type for the import and LXD will know that it’s dealing with an ISO and so can create a volume of the appropriate size and write the raw data for it.

The spec should probably also highlight that such a volume will always be read-only. The only way to update it will be to delete it and create it again. An iso volume would not support snapshots or backups either as those aren’t useful features for a read-only volume.

I don’t see why the CLI should set the content type. When importing backups, LXD detects the compression. Here, we could just add an ISO check which then could set the content type, and create the custom volume accordingly.

That may work, though note that not all ISOs will actually be ISOs as over the years a large number of them have actually switched to a very confusing format that’s a cross of ISO, MBR and GPT to accommodate the file being written to either an actual CD-ROM or alternatively directly to a USB stick to be used on BIOS or UEFI systems.

So something to be careful about when testing the feature.

Can’t we just limit it to “normal” ISO 9660 file systems? These are easy to detect.

We’ll need to check a decent sample size of current ISO images as with those weird hybrid headers I’m not sure that they will all be detected as standard ISO.

Perhaps we can make this more explicit by having the import command grow a --iso flag an and associated API field that can be explicitly populated by CLI or UI?

Probably better for it to be --type=iso to give us some flexibility should we add something else later and to align with the create command.

That wouldn’t be an API field though as import uses a raw POST endpoint, it needs to effectively override the Content-Type HTTP header to tell LXD that this is to be treated as an ISO volume.

1 Like

Should we then just trust this field instead of having LXD check ISO headers?

The current Content-Type header for importing backups is application/octet-stream because it’s arbitrary binary data. This shouldn’t change for ISOs. How about we introduce and set X-LXD-ContentType to iso?

1 Like

Yeah, though the CLI could also just do --type=iso automatically if the filename ends with .iso :slight_smile:

For the type, a new X-LXD-Type header or something along those lines should be fine.

1 Like