Add .zip file support for docker context import#1895
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1895 +/- ##
==========================================
- Coverage 56.75% 56.71% -0.05%
==========================================
Files 309 310 +1
Lines 21680 21773 +93
==========================================
+ Hits 12305 12349 +44
- Misses 8476 8517 +41
- Partials 899 907 +8 |
|
GitHub is having issues, and looks like they have a full outage of delivering webhooks |
Codecov Report
@@ Coverage Diff @@
## master #1895 +/- ##
==========================================
+ Coverage 56.7% 56.71% +0.01%
==========================================
Files 309 310 +1
Lines 21721 21792 +71
==========================================
+ Hits 12316 12359 +43
- Misses 8504 8518 +14
- Partials 901 915 +14 |
|
@thaJeztah — All comments are resolved, and checks are passing, let me know about the next steps please, thank you! 💯 |
|
I took a quick stab at making some of the changes that were suggested here; pushed it as a PR, but feel free to include it here if it looks good: #1908 |
|
@thaJeztah — The changes look good, I'll bring them in, just one question. I've noticed that you've used the limited reader for the file itself, but not the individual archived files. Is that on purpose, or should I also use limited reader for those files too when brining the changes in. Thank you for your help, let me know. |
|
I left them out for the individual files as that would be a bit of a corner case, but I'm not against doing it for both |
|
@thaJeztah — Following your very helpful PR, I've implemented all those changes here as well. Was not able to cherry-pick across forks, but all updates you made are here as well. I've added a test to check the content type generation & added limited reader usage for individual Zipped files. I will keep an eye on the CI builds, I am hoping all will pass and will land this PR for merging possibilities well. Thank you! |
|
Thanks! Could you also squash some (or all) of the commits? |
|
Ideally we'd have a test as well to try importing from a ZIP |
a684b71 to
0dbabe5
Compare
|
Squashed commits, added tests for specifically testing Let me know, thank you! |
cli/context/store/io_utils.go
Outdated
| } | ||
|
|
||
| // newLimitedReader will result in a limited reader with defined byte limit. | ||
| // This basically extends io.LimitReader with proper errors as io.LimitReader only errors with EOF. |
There was a problem hiding this comment.
io.LimitReader does not only error with EOF. https://golang.org/src/io/io.go#L448
I would much rather use io.LimitReader. Unless I'm misunderstanding something.
There was a problem hiding this comment.
OK I understand now, what you want is https://golang.org/pkg/net/http/#MaxBytesReader but with io instead of http.
There was a problem hiding this comment.
I think I wasn't clear in the comment there. I think the main concern here from @thaJeztah & me was the fact that, if reader hits the limit it won't tell us it's actually over the limit, but instead will just return an EOF.
There was a problem hiding this comment.
Ah, yes, the comment in there returns a non-EOF error for a Read beyond the limit is basically what we wanted.
There was a problem hiding this comment.
Ok so you can simplify this further, because all you need is just a 2 lines change around https://golang.org/src/io/io.go?s=14885:14942#L443
// LimitedReader is a fork of io.LimitedReader to override Read.
type LimitedReader struct {
R Reader // underlying reader
N int64 // max bytes remaining
}
// Read is a fork of io.LimitReader.Read that returns an error when limit is exceeded (instead of io.EOF).
func (l *LimitedReader) Read(p []byte) (n int, err error) {
if l.N < 0 {
return 0, errors.New("read limit exceeded")
}
if l.N == 0 {
return 0, io.EOF
}
if int64(len(p)) > l.N {
p = p[0:l.N]
}
n, err = l.R.Read(p)
l.N -= int64(n)
return
}This should possibly in its own ioutils package, although I see we have on in docker/docker/pkg/ioutils.
Maybe we keep it here for now (with the risk of forgetting about it forever).
There was a problem hiding this comment.
You don't need limitedReadAll. Just call ioutil.ReadAll inline.
There was a problem hiding this comment.
I've implemented the Read as discussed, and called LimitedReader inline from all the places used for context import. I'll resolve this conversation just for the sake of the iteration causing the code being outdated. Please feel free to open another thread if need be.
349f78d to
8a5f795
Compare
|
Got some failure in CI; |
Adds capabilities to import a .zip file with importZip. Detects the content type of source by checking bytes & DetectContentType. Adds LimitedReader reader, a fork of io.LimitedReader, was needed for better error messaging instead of just getting back EOF. We are using limited reader to avoid very big files causing memory issues. Adds a new file size limit for context imports, this limit is used for the main file for .zip & .tar and individual compressed files for .zip. Added TestImportZip that will check the import content type Then will assert no err on Importing .zip file Signed-off-by: Goksu Toprak <goksu.toprak@docker.com>
8a5f795 to
291e862
Compare
|
Pushed a fix for the build. My recent push to fix the linter on empty return statement, |
|
And it's green 🎉 |
It was created for internal use, and is not part of the context-store public API. It was introduced as part of the "zip import" functionality added in 291e862. Initially it was [non-exported][1], but during review, some suggestions were made to improve the implementation, and the [suggested implementation][2] was based on Go stdlib, but review overlooked that the implementation was now exported. Let's un-export it, as this was (as outlined) never meant to be a public type. [1]: docker#1895 (comment) [2]: docker#1895 (comment) Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- What I did
I've introduced a way for
docker context importto accept.zipfiles.- How I did it
I've tried to implement it in a way that it can land itself better for what future additions also bring, with addition of
Clienum type. Once we identify which type of import we are trying to get for context, then I go ahead and use the specific import functions, although these functions share as much functionality as possible. I've tried to also make use of an interface offileDatato tie these two functionalities together.- How to verify it
I've updated the existing tests to define their import types as
Clirepresenting the source. One can test the functionality with using the existing any Docker Context tar file and using the contents to create a.zipfile.docker context importwill work the same. I've also added new tests to check if the import functions properly to determine these different import types.- Description for the changelog
Introduces a
.zipimport support fordocker context.