Skip to content

Add .zip file support for docker context import#1895

Merged
thaJeztah merged 1 commit intodocker:masterfrom
goksu:gt-cli-zipCtxImport
May 29, 2019
Merged

Add .zip file support for docker context import#1895
thaJeztah merged 1 commit intodocker:masterfrom
goksu:gt-cli-zipCtxImport

Conversation

@goksu
Copy link
Contributor

@goksu goksu commented May 20, 2019

- What I did
I've introduced a way for docker context import to accept .zip files.

- 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 Cli enum 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 of fileData to tie these two functionalities together.

- How to verify it
I've updated the existing tests to define their import types as Cli representing the source. One can test the functionality with using the existing any Docker Context tar file and using the contents to create a .zip file. docker context import will 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 .zip import support for docker context.

@codecov-io
Copy link

codecov-io commented May 20, 2019

Codecov Report

Merging #1895 into master will decrease coverage by 0.04%.
The diff coverage is 49.58%.

@@            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

@thaJeztah
Copy link
Member

GitHub is having issues, and looks like they have a full outage of delivering webhooks

@codecov-io
Copy link

codecov-io commented May 22, 2019

Codecov Report

Merging #1895 into master will increase coverage by 0.01%.
The diff coverage is 62.79%.

@@            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

@goksu
Copy link
Contributor Author

goksu commented May 24, 2019

@thaJeztah — All comments are resolved, and checks are passing, let me know about the next steps please, thank you! 💯

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

Some quick comments

@thaJeztah
Copy link
Member

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

@goksu
Copy link
Contributor Author

goksu commented May 25, 2019

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

@thaJeztah
Copy link
Member

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

@goksu
Copy link
Contributor Author

goksu commented May 27, 2019

@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!

@thaJeztah
Copy link
Member

Thanks! Could you also squash some (or all) of the commits?

@thaJeztah
Copy link
Member

Ideally we'd have a test as well to try importing from a ZIP

@goksu goksu force-pushed the gt-cli-zipCtxImport branch 4 times, most recently from a684b71 to 0dbabe5 Compare May 27, 2019 22:45
@goksu
Copy link
Contributor Author

goksu commented May 27, 2019

Squashed commits, added tests for specifically testing .zip & CI is looking good, I think we are almost there with the PR.

Let me know, thank you!

@thaJeztah
Copy link
Member

@tiborvass @silvin-lubecki PTAL

Copy link
Contributor

@simonferquel simonferquel left a comment

Choose a reason for hiding this comment

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

lgtm

}

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

Choose a reason for hiding this comment

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

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.

Copy link
Collaborator

Choose a reason for hiding this comment

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

OK I understand now, what you want is https://golang.org/pkg/net/http/#MaxBytesReader but with io instead of http.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, yes, the comment in there returns a non-EOF error for a Read beyond the limit is basically what we wanted.

Copy link
Collaborator

@tiborvass tiborvass May 29, 2019

Choose a reason for hiding this comment

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

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

Copy link
Collaborator

Choose a reason for hiding this comment

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

You don't need limitedReadAll. Just call ioutil.ReadAll inline.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

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.

@goksu goksu force-pushed the gt-cli-zipCtxImport branch 2 times, most recently from 349f78d to 8a5f795 Compare May 29, 2019 18:50
@thaJeztah
Copy link
Member

Got some failure in CI;

=== FAIL: cli/command/context TestCreateFromContext/no-override (600.02s)
SIGQUIT: quit
PC=0x405b9a m=0 sigcode=0

goroutine 20 [running]:
runtime.chanrecv(0xc0004ca600, 0x0, 0x0, 0x0)
	/usr/local/go/src/runtime/chan.go:456 +0x6a fp=0xc0003357d0 sp=0xc000335740 pc=0x405b9a
runtime.selectnbrecv(0x0, 0xc0004ca600, 0xc00003e050)
	/usr/local/go/src/runtime/chan.go:636 +0x3a fp=0xc000335800 sp=0xc0003357d0 pc=0x40644a
io.(*pipe).Read(0xc0002a20f0, 0xc00033a000, 0x1000, 0x1000, 0x0, 0x11a8fa0, 0xc00003e050)
	/usr/local/go/src/io/pipe.go:45 +0x4d fp=0xc0003358b8 sp=0xc000335800 pc=0x468d9d
io.(*PipeReader).Read(0xc000320868, 0xc00033a000, 0x1000, 0x1000, 0x0, 0x11a8fa0, 0xc00003e050)
	/usr/local/go/src/io/pipe.go:127 +0x4c fp=0xc000335900 sp=0xc0003358b8 pc=0x4696ec
bufio.(*Reader).Read(0xc00034e2a0, 0xc000385468, 0x1f9, 0x200, 0x0, 0x11a8fa0, 0xc00003e050)
	/usr/local/go/src/bufio/bufio.go:223 +0x23e fp=0xc000335958 sp=0xc000335900 pc=0x504d9e
github.com/docker/cli/cli/context/store.(*LimitedReader).Read(0xc00047dc60, 0xc000385468, 0x1f9, 0x200, 0x0, 0x0,

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>
@goksu goksu force-pushed the gt-cli-zipCtxImport branch from 8a5f795 to 291e862 Compare May 29, 2019 19:59
@goksu
Copy link
Contributor Author

goksu commented May 29, 2019

Pushed a fix for the build. My recent push to fix the linter on empty return statement, err was carried as nil, I've properly changed that statement now, tests should pass as expected.

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

LGTM if green

@thaJeztah
Copy link
Member

And it's green 🎉

@thaJeztah thaJeztah merged commit c02f389 into docker:master May 29, 2019
@GordonTheTurtle GordonTheTurtle added this to the 19.09.0 milestone May 29, 2019
thaJeztah added a commit to thaJeztah/cli that referenced this pull request Apr 1, 2025
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants