-
Notifications
You must be signed in to change notification settings - Fork 395
docker-daemon: transparently decompress layers in GetBlob #193
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ../../pkg/compression/fixtures/Hello.bz2 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ../../pkg/compression/fixtures/Hello.gz |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ../../pkg/compression/fixtures/Hello.uncompressed |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ../../pkg/compression/fixtures/Hello.xz |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,7 @@ import ( | |
| "path" | ||
|
|
||
| "github.com/containers/image/manifest" | ||
| "github.com/containers/image/pkg/compression" | ||
| "github.com/containers/image/types" | ||
| "github.com/docker/docker/client" | ||
| "github.com/opencontainers/go-digest" | ||
|
|
@@ -334,6 +335,18 @@ func (s *daemonImageSource) GetTargetManifest(digest digest.Digest) ([]byte, str | |
| return nil, "", errors.Errorf(`Manifest lists are not supported by "docker-daemon:"`) | ||
| } | ||
|
|
||
| type readCloseWrapper struct { | ||
| io.Reader | ||
| closeFunc func() error | ||
| } | ||
|
|
||
| func (r readCloseWrapper) Close() error { | ||
| if r.closeFunc != nil { | ||
| return r.closeFunc() | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| // GetBlob returns a stream for the specified blob, and the blob’s size (or -1 if unknown). | ||
| func (s *daemonImageSource) GetBlob(info types.BlobInfo) (io.ReadCloser, int64, error) { | ||
| if err := s.ensureCachedDataIsPresent(); err != nil { | ||
|
|
@@ -349,7 +362,37 @@ func (s *daemonImageSource) GetBlob(info types.BlobInfo) (io.ReadCloser, int64, | |
| if err != nil { | ||
| return nil, 0, err | ||
| } | ||
| return stream, li.size, nil | ||
|
|
||
| // In order to handle the fact that digests != diffIDs (and thus that a | ||
| // caller which is trying to verify the blob will run into problems), | ||
| // we need to decompress blobs. This is a bit ugly, but it's a | ||
| // consequence of making everything addressable by their DiffID rather | ||
| // than by their digest... | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. “digests != diffIDs” is true in general; it would still be worth explaining explicitly that we (choose to) generate a v2s2 manifest with the available DiffID values, so |
||
| // | ||
| // In particular, because the v2s2 manifest being generated uses | ||
| // DiffIDs, any caller of GetBlob is going to be asking for DiffIDs of | ||
| // layers not their _actual_ digest. The result is that copy/... will | ||
| // be verifing a "digest" which is not the actual layer's digest (but | ||
| // is instead the DiffID). | ||
|
|
||
| decompressFunc, reader, err := compression.DetectCompression(stream) | ||
| if err != nil { | ||
| return nil, 0, errors.Wrapf(err, "Detecting compression in blob %s", info.Digest) | ||
| } | ||
|
|
||
| if decompressFunc != nil { | ||
| reader, err = decompressFunc(reader) | ||
| if err != nil { | ||
| return nil, 0, errors.Wrapf(err, "Decompressing blob %s stream", info.Digest) | ||
| } | ||
| } | ||
|
|
||
| newStream := readCloseWrapper{ | ||
| Reader: reader, | ||
| closeFunc: stream.Close, | ||
| } | ||
|
|
||
| return newStream, li.size, nil | ||
| } | ||
|
|
||
| return nil, 0, errors.Errorf("Unknown blob %s", info.Digest) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Hello |
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.
There already is a
tarReadCloserin this file. Modifying that to use thisreadCloseWrapperwould be nice.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.
The two are wrapping different internal objects. I can't really see a nice way of combining the two.
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.
AFAICS the
*tar.ReaderintarReadClosercan just as well be anio.Reader; nothing depends on that being a*.tar.Reader.