-
Notifications
You must be signed in to change notification settings - Fork 594
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
store: add functions to download snap icons #14990
base: master
Are you sure you want to change the base?
store: add functions to download snap icons #14990
Conversation
These new functions, `downloadIconImpl` and `DownloadIcon`, mirror their non-icon counterparts `downloadImpl` and `Download`, except that because snap icons are small, simple assets on a fileserver, there is no need for snap-specific headers, authentication, partial downloads, or caching. These will be used in the future in order to download a snap's icon whenever the new `.snap` blob is downloaded for that snap and linked to a snap icons directory so that the snapd API can serve snap icons from local icon files, rather than returning an error if the snap does not ship an icon at `meta/gui/icon.*`. Signed-off-by: Oliver Calder <[email protected]>
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #14990 +/- ##
=========================================
Coverage ? 78.21%
=========================================
Files ? 1164
Lines ? 154433
Branches ? 0
=========================================
Hits ? 120791
Misses ? 26194
Partials ? 7448
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
Wed Feb 5 01:05:14 UTC 2025 Failures:Executing:
Restoring:
|
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, small nitpicks and a question.
Is the icon file validation (max size, format ..etc) intentionally ignored because snapd is guaranteed to get the URL from the store which should be trusted?
Signed-off-by: Oliver Calder <[email protected]>
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.
Some questions about the cleanup code, and maybe consider making that retry loop body into a function?
var finalErr error | ||
startTime := time.Now() | ||
for attempt := retry.Start(downloadRetryStrategy, nil); attempt.Next(); { | ||
httputil.MaybeLogRetryAttempt(iconURL.String(), attempt, startTime) |
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.
Would it be possible to make this inner loop a function? I understand it might be awkward because you need to hold on to finalErr
.
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.
I've made it a function now
store/store_download_test.go
Outdated
// ... and ensure that the tempfile is removed | ||
c.Assert(osutil.FileExists(tmpfile.Name()), Equals, false) | ||
// ... because it's been renamed to the target path already | ||
c.Assert(osutil.FileExists(path), Equals, true) |
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 seems this test is expecting that behavior from my other comment? Seems like this could be avoided? If we fail to download the file and attempt cleanup, I feel like we should properly do the cleanup, unless there is some other use case I'm missing.
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.
My guess is that if the file is renamed, its contents are good, so for large .snap
files we want to keep it around. But that doesn't hold up since an error would suggest it's not in the cache, so it wouldn't be used on subsequent download anyway. So I'm not really sure why. Some git
spelunking shows the code this is originally based on was written by John Lenton to support preserving partial download files after error: ebbb57e
I really don't know why the sync occurs after the rename. On unix, the rename should be atomic. Maybe it's an optimization to avoid committing the write to disk until we're sure the rename will work? But that seems silly, since a sync may occur anyway in the background during this time. Either way, it seems like an optimization for dealing with large .snap
files, not applicable here.
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.
All of this was now replaced with usage of osutil.AtomicFile
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!
Other than addressing comments from @andrewphelpsj, I think this looks good.
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.
remark about being careful with the download length/icon size
@olivercalder I added @bboozzoo to also look at this |
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.
actual vote
Signed-off-by: Oliver Calder <[email protected]>
Signed-off-by: Oliver Calder <[email protected]>
Signed-off-by: Oliver Calder <[email protected]>
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.
further comment
Signed-off-by: Oliver Calder <[email protected]>
store/store_download.go
Outdated
logger.Debugf("Download size for %s: %d", downloadURL, resp.ContentLength) | ||
} | ||
|
||
_, finalErr = io.CopyN(w, resp.Body, resp.ContentLength) |
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.
btw. no integrity check?
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.
I think we need a test to verify the size limit
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.
We don't have any information about what the icon contents are supposed to be, so there's no way to check them. We could leverage the etag
to see if the server reports that the file has changed, but I don't think there's a way to use the etag
to check for file integrity.
I'll add a test to verify the size limit though, thanks.
Signed-off-by: Oliver Calder <[email protected]>
Signed-off-by: Oliver Calder <[email protected]> Co-authored-by: Maciej Borzecki <[email protected]>
Signed-off-by: Oliver Calder <[email protected]>
Signed-off-by: Oliver Calder <[email protected]>
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.
Thanks, some small comments.
Also add comments noting that the http clients for both snap downloads and snap icon downloads have no timeout defined. Signed-off-by: Oliver Calder <[email protected]>
Signed-off-by: Oliver Calder <[email protected]>
Signed-off-by: Oliver Calder <[email protected]>
These new functions,
downloadIconImpl
andDownloadIcon
, mirror their non-icon counterpartsdownloadImpl
andDownload
, except that because snap icons are small, simple assets on a fileserver, there is no need for snap-specific headers, authentication, partial downloads, or caching.These will be used in the future in order to download a snap's icon whenever the new
.snap
blob is downloaded for that snap and linked to a snap icons directory so that the snapd API can serve snap icons from local icon files, rather than returning an error if the snap does not ship an icon atmeta/gui/icon.*
.This work is tracked internally by https://warthogs.atlassian.net/browse/SNAPDENG-34095