Support multiple volumes per gadget.yaml

Bug #1641727 reported by Barry Warsaw on 2016-11-14
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
Ubuntu Image
High
Barry Warsaw

Bug Description

The gadget.yaml spec allows for multiple volumes (a.k.a. images) per gadget, but the ubuntu-image implementation only allows a single image.

The bug tracks the work to fully support multiple volumes if defined in the gadget.yaml

Barry Warsaw (barry) on 2016-11-14
summary: - Support multiple volumes
+ Support multiple volumes per gadget.yaml
Barry Warsaw (barry) on 2016-12-05
Changed in ubuntu-image:
milestone: none → 0.13
assignee: nobody → Barry Warsaw (barry)
Barry Warsaw (barry) on 2016-12-14
Changed in ubuntu-image:
importance: Undecided → High
status: New → In Progress
Barry Warsaw (barry) wrote :

Thoughts on the impact of this on the CLI.

We have two options which assume a single disk image result, --output and --image-size. Both of these will have to change, but I think we can do it in a backward compatible way. If the gadget.yaml has only a single volume, then these can just do what they always did, i.e. name the values for that single volume.

If the gadget.yaml has multiple volumes, then what should u-i for these two options if given in previous syntax? We'd ultimately like to fail as early as possible, but we can't know there are multiple volumes in the gadget.yaml until we download the gadget snap. So that means we can't complain during argument parsing, and we'll have to throw away the little bit of work we've done downloading the gadget snap once we notice the incompatibility.

Other options:

* For --output, warn and ignore. The disk name will be taken from the volume name.
* For --output, warn and append a numeric suffix, e.g. --output=my-disk-image.img -> my-disk-image-01.img etc. (Yes that likely means tricks with the suffix)
* For --image-size, warn and use the given size for all disk images, with the current behavior if the size is too small (we ignore them, they are a minimum).

What to do about the case where --output isn't given? (We don't care about --image-size not given, those will just be calculated as normal). Instead of hardcoding the disk image file name to 'disk.img', it should be <volume-name>.img as taken from the gadget.yaml. We'll do this even if there's only a single volume in the gadget.yaml, so it's a minor CLI API break.

How to specify names and sizes for multiple volumes? Let's use a mapping from [volume-name|ordinal] -> value, e.g.

$ ubuntu-image -o 0:disk1.img -o 1:disk2.img -o first:disk3.img

This says, the first volume should be written to disk1.img, the second volume to disk2.img, and the volume named 'first' should be written to disk3.img. If there are any conflicts, (e.g. 'first' is the 0th volume), then warn and ignore.

Sanity check that there won't be any colliding disk file names.

A similar syntax would be used for --image-size, e.g.

$ ubuntu-image --image-size 0:10G --image-size second:12G

Again, if there are any conflicts, warn and ignore (first one wins).

I'm not sure how multi-volume support will affect the state machine options, but as those are mostly for debugging and development purposes, I won't worry about backward compatibility. How the implementation plays out will have a big effect on what happens here.

Barry Warsaw (barry) wrote :

General implementation approach: refactor the ModelAssertionBuilder class to be able to work in parallel or volume-isolation. Have a driver class with one MAB per volume. Run their state machines to the given terminal, then have the driver class collect up all the results.

One tricky bit is that we'd like the driver to also be state-driven, so I have to figure out how to make that manageable. (Perhaps by forwarding the MAB state transitions through the driver.)

Barry Warsaw (barry) on 2016-12-15
Changed in ubuntu-image:
milestone: 0.13 → 0.14
Barry Warsaw (barry) on 2017-01-13
Changed in ubuntu-image:
milestone: 0.14 → 0.15
Barry Warsaw (barry) wrote :

Here's another thought about -o/--output

Let's add a new option called -O/--output-dir and if that is set, we write disk images to that directory based on the volume name with '.img' appended. Thus:

$ ubuntu-image -O /my/image/dir

and a volume name of 'pc' would leave you with /my/image/dir/pc.img

Now, to keep things simple, let's not change -o/--output but instead, we'll raise a warning and ignore it if there are multiple volumes in a gadget.yaml file.

If neither option is given, the we'll use <workdir>/images/ where <workdir> is given by -w/--workdir. If that option isn't given either, then we'll use the current working directory.

Barry Warsaw (barry) wrote :

I've run into a complication, so I'm looking for feedback @slangasek

In the single-volume case (i.e. up until now), we've always implicitly appended a role:system-data (i.e. root fs) partition to the end of the volume specification if we did not see an explicit role:system-data structure defined. This perhaps makes sense in that use case because if there's only one volume defined then that volume (i.e. disk image) will probably be used to boot the device and thus a root file system would be required.

But does that assumption still make sense in a multi-volume gadget.yaml? It seems wrong to me to require that every volume in the multi-volume case contains a root fs. Doesn't it make more sense to require an explicit root fs specification so you know which volume to add it to? (Having implicit data also violates my "no hidden magic" sensibilities. ;).

Note that we can't say that only the first defined volume should have the implicit root fs, but not the subsequent ones. That's just more magical rules a gadget.yaml author needs to remember and it means they might not be able to reorganize their gadget.yaml for fear of getting tripped up by this rule.

I could be wrong, but I recall @slangasek arguing against requiring a role:system-data specification in the gadget.yaml. Maybe it was for backward compatibility? If we aren't able, for b/c reasons, to require a role:system-data structure in the single-volume gadget.yaml case, perhaps we should start by requiring it in the multi-volume case, perhaps also with a deprecation warning in the single-volume case.

We want to deprecate the implicit systemd-data partition, and know that this
will be an interface change.

We can maintain backwards-compatibility by supporting implicit systemd-data
partition for the single volume use case, and disallowing it for the
multiple volume use case. If you have multiple volumes, you need to be
explicit.

Note, you *may* reference the system-data partition multiple times across
different volumes, in which case we reuse the same filesystem multiple
times.

Barry Warsaw (barry) wrote :

On Jan 31, 2017, at 07:31 PM, Steve Langasek wrote:

>We want to deprecate the implicit systemd-data partition, and know that this
>will be an interface change.
>
>We can maintain backwards-compatibility by supporting implicit systemd-data
>partition for the single volume use case, and disallowing it for the
>multiple volume use case. If you have multiple volumes, you need to be
>explicit.

+1

>Note, you *may* reference the system-data partition multiple times across
>different volumes, in which case we reuse the same filesystem multiple
>times.

Yep!

Thanks.

Barry Warsaw (barry) wrote :

I'm not sure if or how to update to cover this, but I will add the appropriate information in the u-i NEWS file.

https://github.com/snapcore/snapd/wiki/Gadget-snap#gadget.yaml

Barry Warsaw (barry) wrote :

Oh, and I note that we already print a deprecation warning for implicit rootfs. All I have to do is check to see if there is more than one volume, in which case I skip the warning and the adding of the implicit rootfs.

Barry Warsaw (barry) on 2017-02-06
Changed in ubuntu-image:
status: In Progress → Fix Committed
Barry Warsaw (barry) on 2017-02-15
Changed in ubuntu-image:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers