Skip to content
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

Merged
merged 18 commits into from Mar 9, 2021

Conversation

mvo5
Copy link
Collaborator

@mvo5 mvo5 commented Feb 8, 2021

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

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.
@pedronis pedronis self-requested a review February 8, 2021 14:34
image/helpers.go Outdated
if err != nil {
return err
}
for _, ps := range lv.LaidOutStructure {
Copy link
Collaborator

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

Copy link
Collaborator Author

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).

Copy link
Collaborator Author

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>
Copy link
Member

@anonymouse64 anonymouse64 left a 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 😄

image/helpers.go Show resolved Hide resolved
image/image_linux.go Outdated Show resolved Hide resolved
image/helpers.go Outdated Show resolved Hide resolved
image/helpers_test.go Outdated Show resolved Hide resolved
@mvo5 mvo5 marked this pull request as ready for review February 26, 2021 08:48
@mvo5 mvo5 added the Skip spread Indicate that spread job should not run label Feb 26, 2021
Copy link
Collaborator

@pedronis pedronis left a 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 {
Copy link
Collaborator

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/..

@@ -130,6 +130,13 @@ func unpackGadget(gadgetFname, gadgetUnpackDir string) error {
return snap.Unpack("*", gadgetUnpackDir)
}

func unpackKernel(kernelFname, kernelUnpackDir string) error {
Copy link
Collaborator

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

Copy link
Collaborator Author

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)
Copy link
Collaborator

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

Copy link
Collaborator Author

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.

Copy link
Collaborator

@pedronis pedronis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you

@mvo5 mvo5 removed the Skip spread Indicate that spread job should not run label Mar 1, 2021
@mvo5 mvo5 closed this Mar 1, 2021
@mvo5 mvo5 reopened this Mar 1, 2021
@anonymouse64 anonymouse64 self-requested a review March 1, 2021 17:44
@bboozzoo bboozzoo self-requested a review March 3, 2021 14:34
Copy link
Member

@anonymouse64 anonymouse64 left a 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>
@anonymouse64
Copy link
Member

(I pushed a fix for the failing unit test which was racy I think since the output wasn't sorted)

Copy link
Collaborator

@bboozzoo bboozzoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

image/helpers.go Outdated Show resolved Hide resolved
@mvo5
Copy link
Collaborator Author

mvo5 commented Mar 5, 2021

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 <volume-name>/<structure-number> by default

mvo5 added 2 commits March 5, 2021 21:45
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
```
@mvo5
Copy link
Collaborator Author

mvo5 commented Mar 8, 2021

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:

$ UBUNTU_IMAGE_SNAP_CMD=/tmp/snap PYTHONPATH=. ./ubuntu-image snap \
  ubuntu-core-20-pi-arm64-dangerous.model \
  --snap ~/tmp/kernel-dtb/pi/pi_20-1_arm64.snap \
  --snap ~/tmp/kernel-dtb/pi-kernel/pi-kernel_5.4.0-1030.33_arm64.snap \
  --snap ~/tmp/kernel-dtb/snapd_r1140_arm64.snap \
  --snap ~/tmp/kernel-dtb/core20_r961_arm64.snap

Note that snapd/core20 are not modified for this.

And a similar successful install with UC18:

$ UBUNTU_IMAGE_SNAP_CMD=/tmp/snap PYTHONPATH=. ./ubuntu-image snap  \
 ubuntu-core-18-pi-arm64.model  \
 --snap ~/tmp/kernel-dtb/uc18/pi/pi_18-1_arm64.snap   \
 --snap ~/tmp/kernel-dtb/uc18/pi-kernel/pi-kernel_5.3.0-1037.39_arm64.snap  \
 --snap ~/tmp/kernel-dtb/snapd_r1140_arm64.snap  \
 --snap ~/tmp/kernel-dtb/uc18/core18_r1996_arm64.snap

Note that snapd/core18 are not modified for this.

@mvo5
Copy link
Collaborator Author

mvo5 commented Mar 8, 2021

@pedronis I did a small tweak to the dir structure in my latest commit, it uses resolved-content/<vol-name>/part<NR>/ now (e.g. resolved-content/pi/part1) because a lot of the volume structures do not have names and ubuntu-image is already doing the "part" bit internal. Would love to get your okay on this particular chagne before I merge this PR.

@pedronis pedronis requested review from pedronis and anonymouse64 and removed request for anonymouse64 March 9, 2021 09:10
Copy link
Collaborator

@pedronis pedronis left a 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>/...
Copy link
Collaborator

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,...}
Copy link
Collaborator

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 ?

@mvo5 mvo5 added the Skip spread Indicate that spread job should not run label Mar 9, 2021
@mvo5 mvo5 merged commit 4a12a9f into snapcore:master Mar 9, 2021
Copy link
Member

@anonymouse64 anonymouse64 left a 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Skip spread Indicate that spread job should not run
Projects
None yet
4 participants