Incorporate base image in refresh plan#493
Merged
Merged
Conversation
41f3c1e to
2da631d
Compare
13 tasks
dmitry-lyfar
reviewed
Oct 1, 2025
Collaborator
dmitry-lyfar
left a comment
There was a problem hiding this comment.
I think the approach is fine, but am not sure about the interface and naming. Specifically, version.
b8b9a31 to
fe400be
Compare
dmitry-lyfar
approved these changes
Oct 1, 2025
Adds a new method GetBase to BaseImageManager. It looks up the latest version of a given base. For the LXD backend, the version is a fingerprint. This will allow a future change to make the base image part of the refresh plan. Also renames Download to DownloadBase. It now accepts a version instead of returning one. I've changed my mind about downloading using the alias instead of the fingerprint. It should be reasonably safe to use fingerprints, since the image servers I know of keep their images around for at least a day after updating them. Also, allowing DownloadBase to change the fingerprint feels like leaking LXD quirks into the generic API. The downside of using fingerprints is that local images won't have an UpdateSource. LXD doesn't use this because we disable auto-updates. Workshop also won't need it if we use a custom property instead, similar to the existing user.workshop.* instance config options. The new property is "workshop-base." I avoided "user.workshop.*" so we can filter by properties.workshop-base (dots in filters are treated like path separators). I don't think there's a high chance of name collisions here. In order to apply the property, I had to use CreateImage instead of CopyImage. The behaviour should be identical for simplestreams servers, but for LXD image servers with multiple addresses, only the main address will be used. As far as I can tell, servers only have multiple addresses when they listen on multiple network interfaces (on the same machine), so I don't see why you would want to use them over the main address. In any case, we can implement this functionality later if we need to.
fe400be to
d08790b
Compare
TICS Quality Gate✔️ PassedworkshopAll conditions passedSee the results in the TICS Viewer The following files have been checked for this project
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Refresh now queries the image server at the same time as the Store. If the base image is outdated, the workshop is rebuilt from scratch based on the new image. This is the same behaviour as switching to a different base. If the current base is up to date, the workshop will likely be restored from a snapshot.
There's no cleanup logic for images at present. They will start to pile up over time, but the snap's remove hook should keep this under control for now.
Implementation
I added a new method
GetBasetoBaseImageManager. It looks up the latest version of a given base. For the LXD backend, the version is a fingerprint, which is likely to be globally unique, but the API only assumes the version string is unique within a given base.I also renamed
DownloadtoDownloadBase. It now accepts a version instead of returning one.Originally I wanted
DownloadBaseto always download the latest image, for two reasons:UpdateSourcefield in the local copy when downloading the latest image.I don't think the first one is a major issue. Even the daily image servers keep at least 2 fingerprints alive at all times. So the fingerprint used in a refresh plan should be valid for at least 1 day.
The second one is not an issue for LXD, because we disable auto-updates for our images. But the
UpdateSourcefield would have been convenient when cleaning up old images, and is currently useful for the image download integration tests.I didn't want to continue using aliases, since the previous implementation had some concurrency issues and I don't know if they've been fixed in LXD. Also, we can't give different images the same alias.
Instead, we now add a
workshop-baseproperty to our images, similar to the existing user.workshop.* instance config options. I avoided theuser.workshop.*format because LXD's filtering syntax treats dots like path separators. I don't think there's a high chance of name collisions, unless the image servers start supporting Workshop explicitly.In order to apply the property, I had to use
CreateImageinstead ofCopyImage. Note thatCopyImageis already a client-side wrapper aroundCreateImage, so there's no difference on the server side. However, for LXD image servers with multiple addresses,CopyImagetries all the addresses, whereasCreateImageonly uses the main address. As far as I can tell, servers only have multiple addresses when they listen on multiple network interfaces (on the same machine), so I don't think this makes much difference in practice.The upside of getting
DownloadBaseto download a specific fingerprint is that it simplifies the API, and detaches it from the LXD implementation details. Given that both downsides are quite minor, I now think this is the right call.I removed the
Basefield from theWorkshopstruct, and addedBaseVersion. Note thatNameandBaseare already available in theFilefield. I opted not to removeNamesince it is used much more heavily thanBase. But we could consider embeddingFileintoWorkshopto preserve the current convenience without duplicating data.Self-review quick check
Docs
Or: