New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
image: write resolved-content from snap prepare-image #9914
Conversation
This commit adds code to create a new "resolved-content" directory under opts.PrepareDir that can be picked up by ubuntu-image. This dir will contain the resolved content for each volume structure that should be written to the image.
image/helpers.go
Outdated
if err != nil { | ||
return err | ||
} | ||
for _, ps := range lv.LaidOutStructure { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for UC20 this code will write files that are not needed, because we really need to take care only of system-seed, no? OTOH maybe it's ok because is ready if we do some of install work already at ubuntu-image time later.
ATM the layouts are already different:
UC16/18
<prepare-dir>/image
UC20
<prepare-dir>/system-seed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this will produce too much data on uc20 currently (it. should stop after it found the system-seed).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It maybe okay for now that prepare-image just outputs all the resolved content and ubuntu-image picks what it needs. Longer term ubuntu-image will be in go and it will call better and richer APIs than a (very limited) CLI itnerface.
Using relative directories falls apart when used with ubuntu-image because ubuntu-image provides a relative dir as prepareDir here, and thus the symlink created is broken. Making it an absolute link fixes the problem. Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks good to me, I pushed one change to fix the symlink issue I mention below, but otherwise I think it's good with an additional unit test
This also fully enables my uc20 pi-config work too so +2 from me 😄
At this point we know already we are not in classic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good, some comments mostly around the signature of writeResolvedContent
image/helpers.go
Outdated
var writeResolvedContent = writeResolvedContentImpl | ||
|
||
// XXX: move to gadget? | ||
func writeResolvedContentImpl(targetDir, prepareDir, gadgetUnpackDir, kernelUnpackDir string, model *asserts.Model) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe s/targetDir/resolvedContentDIr/ ?
given the logic about the symlink and the fact it takes a prepareDir it should probably live here, it could be made a gadget function but it would need a more complicated interface.
It probably merits a doc comment though about what it does and the main params as it has so many
do we need to pass both targetDir and prepareDir? given where this lives it could compute one from the other:
prepareDir = targetDir/..
image/image_linux.go
Outdated
@@ -130,6 +130,13 @@ func unpackGadget(gadgetFname, gadgetUnpackDir string) error { | |||
return snap.Unpack("*", gadgetUnpackDir) | |||
} | |||
|
|||
func unpackKernel(kernelFname, kernelUnpackDir string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bit unclear why the 2nd function copy given that they do the same thing, maybe just rename it to unpackEssentialSnap
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, silly me. Removed the duplicated helper.
image/helpers.go
Outdated
return err | ||
} | ||
|
||
info, err := gadget.ReadInfoAndValidate(gadgetUnpackDir, model, nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's an argument to be made that this function should receive the gadget.Info directly instead of the model.
the arguments would be:
targetDir, info, gadgetUnpackDir, kernelUnpackDir
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, I like that. I updated the code and had to tweak some tests. Note that the signature is slightly different (not targetDir) as I applied the earlier feedback about just using gadgetUnpackDir. Let me know if you feel it should be done differently.
This now take gadget.Info instead of the asserts.Model. Thanks to Samuele for the suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, thanks for the additional unit tests here
…cible Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
(I pushed a fix for the failing unit test which was racy I think since the output wasn't sorted) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
After spending some quality time with ubuntu-image it looks like this needs a little bit of tweaking because volume structures often do not have names and ubuntu-image uses the structure number instead. So prepare-image should layout as |
Not all volume structures have names so to avoid issues do what ubuntu-image is doing and use the partition number whe writing the resolved content dir structure, e.g.: ``` resolved-content/vol1/part2/foo ```
Fwiw, I tested this with the coresponding ubuntu-image changes in https://github.com/CanonicalLtd/ubuntu-image/compare/master...mvo5:snap-prepare-image-resolved-content?expand=1 and got a working image that had the DTBs, seeded and subsequent kernel/gadget updates cause no observable issues. Using canonical/ubuntu-image-legacy#198 and the snaps from https://people.canonical.com/~mvo/tmp/kernel-assets/ that include the changes from https://bugs.launchpad.net/snapd/+bug/1907056 (wihtout the assumes part) an image was created with:
Note that snapd/core20 are not modified for this. And a similar successful install with UC18:
Note that snapd/core18 are not modified for this. |
@pedronis I did a small tweak to the dir structure in my latest commit, it uses |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks ok as we discussed, some nitpicks about the comment
image/helpers.go
Outdated
@@ -412,10 +412,10 @@ var writeResolvedContent = writeResolvedContentImpl | |||
// writeResolvedContent takes gadget.Info and the unpacked | |||
// gadget/kernel snaps and outputs the resolved content from the | |||
// {gadget,kernel}.yaml into a filesystem tree with the structure: | |||
// <prepareImageDir>/resolved-content/<volume-name>/<structure-name>/... | |||
// <prepareImageDir>/resolved-content/<volume-name>/<structure-nr>/... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is missing "part" ?
image/helpers.go
Outdated
// | ||
// E.g. | ||
// /tmp/prep-img/resolved-content/pi/ubuntu-seed/{config.txt,bootcode.bin,...} | ||
// /tmp/prep-img/resolved-content/pi/part1/{config.txt,bootcode.bin,...} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is ubuntu-seed the first structure? then it should be part0 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
post merge +1 from me again
This commit adds code to create a new "resolved-content" directory
under opts.PrepareDir that can be picked up by ubuntu-image. This
dir will contain the resolved content for each volume structure
that should be written to the image.
The corresponding ubuntu-image code would be something like https://github.com/CanonicalLtd/ubuntu-image/compare/master...mvo5:snap-prepare-image-resolved-content?expand=1