Add .zip file support for docker context import (alternative)#1908
Add .zip file support for docker context import (alternative)#1908thaJeztah wants to merge 8 commits intodocker:masterfrom
Conversation
Adds capabilities to import a .zip file Introduces ImportType enum to control import func Introduces fileData interface to share functionality between types Created an abstract layer between with doImport to share functionality Implemented re-usable parsers for both .zip and .tar cases Updated instances that call store.Import to have the new ImportType.Cli arg Signed-off-by: Goksu Toprak <goksu.toprak@docker.com>
Adds a file size check of 10 MB on individual files in zip or tar If bigger than allowed amount will error Signed-off-by: Goksu Toprak <goksu.toprak@docker.com>
This util will be used for context imports instead of using ioutil.ReadAll ReadAll by default may cause memory issues and has no limit io.LimitReader can be used to introduce these limitations but has no error handling, which in turn may cause red herrings With LimitedReadAll util we will be able to identify if the file is too big, and error to the user properly Also removed checkFileSize from context import functionality as it's no longer needed Signed-off-by: Goksu Toprak <goksu.toprak@docker.com>
Signed-off-by: Goksu Toprak <goksu.toprak@docker.com>
Removed exported error type ReadExceedsLimitError, since it was only used for testing purposes. Signed-off-by: Goksu Toprak <goksu.toprak@docker.com>
Moved the funcionality to determing reader and import type out to, getReaderAndImportType and added a test to check for Cli, Tar & Zip. Signed-off-by: Goksu Toprak <goksu.toprak@docker.com>
Certain tests were failing per not having a proper cleanup Also fixes a linter issue Signed-off-by: Goksu Toprak <goksu.toprak@docker.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Codecov Report
@@ Coverage Diff @@
## master #1908 +/- ##
==========================================
- Coverage 56.7% 56.68% -0.03%
==========================================
Files 309 310 +1
Lines 21721 21757 +36
==========================================
+ Hits 12316 12332 +16
- Misses 8504 8521 +17
- Partials 901 904 +3 |
| func Import(name string, s Writer, reader io.Reader) error { | ||
| tr := tar.NewReader(reader) | ||
| // need a buffered reader to read the header without advancing the reader | ||
| r := bufio.NewReader(reader) |
There was a problem hiding this comment.
Decided to go with adding detection here; it adds a bit of complexity here, but by doing it here, the Import() signature remains unmodified. Also, by detecting, piping a ZIP works (whereas previously it required a file as the extension was used).
There was a problem hiding this comment.
This and usage of the DetectContentType looks good to me.
| } | ||
|
|
||
| func importZip(name string, s Writer, reader io.Reader) error { | ||
| body, err := limitedReadAll(reader, maxFileSize) |
There was a problem hiding this comment.
Moved the limiting here; previously, this would to a ioutils.ReadAll()
| // skip this entry, only taking files into account | ||
| continue | ||
| } | ||
| if zf.Name == metaFile { |
There was a problem hiding this comment.
I went for just duplicating this import, instead of trying to abstract it; it felt like the abstraction was adding a bit too much complexity (e.g. the addition of the fileData interface, the newZipFileData and newTarFileData etc.) for a (not too) complicated function. We could probably do a bit more refactoring, but I left that for later if we want to.
There was a problem hiding this comment.
The main reason for the abstraction was in fact removing the code duplication, when I was doing it I was envisioning having multiples of different file types, but as we moved along, it's clear that it's very unlikely that we will get support in for more than tar & zip, thus I am good with removing the abstracted layer.
As you said, if we end up needing more and more file types, then probably would be the time to re-factor and create that additional layer.
There was a problem hiding this comment.
Yes, it's a pity it wasn't easy to reuse the code, due to reading, and iterating over the files in Tar and Zip archives is quite different
| if err != nil { | ||
| return err | ||
| } | ||
| data, err := ioutil.ReadAll(f) |
There was a problem hiding this comment.
This could be limitedReadAll, but that would only be for really corner cases (specially crafted ZIP containing a sparse-file, e.g.)
There was a problem hiding this comment.
I've mentioned this specific section on the other PR, I am still wondering if adding limited reader for all of these is the safest way to go, since we already have the interface implemented.
There was a problem hiding this comment.
I initially had it here, but removed it; I'm fine with having it in both places (whole file, and individual files reading from the Zip)
For the tar, we won't need it, as it's not compressed, so if the file as a whole is within limits, files inside the tar should be as well
| return errors.New("archive format is invalid") | ||
| } | ||
|
|
||
| epName := parts[0] |
There was a problem hiding this comment.
Removed the tlsData.Push() and inlined it here. Push() was effectively only used here (during import), so there was no need yet to add it as a new "interface"
There was a problem hiding this comment.
The odd thing here for me was the function returning nil, and creating a side-affect by changing content of the arguments at the same time. I've tried to change this function to be pure, and that's why I've added the Push, but I am guessing it added more complexity than it should've.
|
closing, because #1895 was merged |
Quick stab at making some changes that were suggested in the review of #1895
This will need squashing, and we'll likely want a test (could be in a follow-up)
- 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.