Skip to content

Conversation

@danail-branekov
Copy link
Contributor

This is a follow up of #348, which added the URL property to the BlobInfo descriptor.

This will allow GetBlob to fetch external blobs when the "urls" property is present. The download is performed by an HTTP client that has its Transport configured depending on the newly introduced SytemContext.OCICertPath and SystemContext.OCIInsecureSkipTLSVerify properties.

BlobInfo.URLs is an array and therefore the implementation would iterate over the URLs until HTTP OK response is returned.

When the SytemContext.OCICertPath is specified the implementation would look for CA, private key and public key certificates the same way the Docker client does. As a matter of fact they both use one and the same certificate handling implementation that is extracted in the newly introduced tlsclientconfig package.

(this is part of a CloudFoundry/Grootfs story to support OCI images based buildpacks in the future)

@tscolari
Copy link
Contributor

So that test broke because of the use of go < 1.8 on the tests (where the http.Server.Close method didn't exist).

That's a bit misleading because the tests output says

$ go version
go version go1.9 linux/amd64

but that doesn't seem to be the case.

We tried to reproduce the error with different versions of go and could only reproduce it with 1.7 and bellow. (1.9 and 1.8 was all green)

@tscolari
Copy link
Contributor

The PR #352 should update the version of go in the docker image

@mtrmac
Copy link
Collaborator

mtrmac commented Sep 28, 2017

Thanks. I will take a detailed look later (hopefully tomorrow), this seem reasonable at a first glance.

(Note to self: Previous discussion in #147 ).

@@ -0,0 +1,13 @@
-----BEGIN CERTIFICATE-----
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: Please use fixtures for the name of the subdirectory containing test fixtures, to be consistent with the other subpackages.

Copy link
Contributor

Choose a reason for hiding this comment

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

👍
going to update it

Copy link
Collaborator

@mtrmac mtrmac left a comment

Choose a reason for hiding this comment

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

ACK overall, just various minor things.

Should ociImageDestination.AcceptsForeignLayerURLs now return true? It’s, strictly speaking, orthogonal.

}

// TODO? Fix bug here: looping over urls continues even after successful request...
// this is slow, and also leaks response bodies which don't get closed.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Good catch; please file a GitHub issue instead. Using the source code as a bug tracker does not really work.

@@ -0,0 +1 @@
{"schemaVersion":2,"manifests":[{"mediaType":"application/vnd.oci.image.manifest.v1+json","digest":"sha256:84afb6189c4d69f2d040c5f1dc4e0a16fed9b539ce9cfb4ac2526ae4e0576cc0","size":496,"annotations":{"org.opencontainers.image.ref.name":"v0.1.1"},"platform":{"architecture":"amd64","os":"linux"}}]} No newline at end of file
Copy link
Collaborator

Choose a reason for hiding this comment

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

Move this to fixtures as well, please.

client := &http.Client{}
if ctx != nil {
tr := tlsclientconfig.NewTransport()
tr.TLSClientConfig = tlsconfig.ServerDefault()
Copy link
Collaborator

Choose a reason for hiding this comment

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

ctx == nil is defined to be equal to ctx == &types.SystemContext{}, but this code treats them differently.

The ServerDefault should probably be always used.

tr := tlsclientconfig.NewTransport()
tr.TLSClientConfig = tlsconfig.ServerDefault()
if ctx.OCICertPath != "" {
tlsclientconfig.SetupCertificates(ctx.OCICertPath, tr.TLSClientConfig)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This needs error handling.

func (s *ociImageSource) getExternalBlob(urls []string) (io.ReadCloser, int64, error) {
var (
resp *http.Response
err error
Copy link
Collaborator

Choose a reason for hiding this comment

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

resp does not need to be pre-declared.

err might be better initialized to errors.New("Internal error: getExternalBlob called with no URLs") or something like that, to be defensive and strictly correct.

(Both non-blocking.)

ClientCAs: clientCertPool,
}

tlsConfig.BuildNameToCertificate()
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems to read tlsConfig.Certificates, which is empty at this point?!

http.HandleFunc("/", remoteLayerContent)

httpServer := &http.Server{
Addr: ":12000",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nothing guarantees that the port is available. Could this use :0 to automatically choose an available one?

(There is also net/http/httptest; would it simplify things?)

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I think so, I'm going to give it a try here ^^

layerInfo := types.BlobInfo{
URLs: []string{
"brokenurl",
"https://example.com",
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is not really blocking, but it would be nice for an unit test not to depend on an external service like this.

Could this use something like https://golang.org/src/net/http/httptest/example_test.go:ExampleServer?


func TestGetBlobForRemoteLayers(t *testing.T) {
imageSource := createImageSource(t, &types.SystemContext{})
layerInfo := types.BlobInfo{
Copy link
Collaborator

Choose a reason for hiding this comment

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

(Non-blocking: Strictly speaking, the Digest field is mandatory and Size should be -1 if unknown. OTOH I realize that computing the digests would be fairly pointless pain.)

func createImageSource(t *testing.T, context *types.SystemContext) types.ImageSource {
imageSource, err := newImageSource(context, ociReference{
dir: "assets/manifest",
})
Copy link
Collaborator

Choose a reason for hiding this comment

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

(Non-blocking: Calling NewReference like a public user would make it obvious that there’s nothing special about constructing this reference.)

Copy link
Contributor

Choose a reason for hiding this comment

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

So on this one it seems that go doesn't allow the NewReference return (type.ImageReference) to be used as an ociReference.

cannot use imageRef (type types.ImageReference) as type ociReference in argument to newImageSource: need type assertion

casting seems to work

Copy link
Collaborator

Choose a reason for hiding this comment

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

The public ociReference.NewImageSource can be called instead.

@tscolari tscolari force-pushed the tls-layer-downloads branch 2 times, most recently from c4d3ace to c0f8e4b Compare October 2, 2017 10:32
hash.Write([]byte("Hello world"))
imageSource := createImageSource(t, &types.SystemContext{})
layerInfo := types.BlobInfo{
Digest: digest.NewDigest("sha256", hash),
Copy link
Collaborator

Choose a reason for hiding this comment

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

(FWIW this could be digest.FromBytes([]byte(…)). This is fine as well.)

@tscolari tscolari force-pushed the tls-layer-downloads branch 2 times, most recently from 3b01125 to 4849f5e Compare October 3, 2017 10:57
@williammartin
Copy link

@mtrmac PTAL

* Support for custom certs and keys when downloading OCI layers

Signed-off-by: Will Martin <[email protected]>
@tscolari tscolari force-pushed the tls-layer-downloads branch from 4849f5e to 1ed776f Compare October 3, 2017 12:41
@mtrmac
Copy link
Collaborator

mtrmac commented Oct 3, 2017

👍

Approved with PullApprove

@runcom
Copy link
Member

runcom commented Oct 3, 2017

LGTM

Approved with PullApprove

@runcom runcom merged commit 7434c9c into containers:master Oct 3, 2017
umohnani8 added a commit to umohnani8/image that referenced this pull request Oct 11, 2017
Part of the fixes from containers#351 got undone

Signed-off-by: umohnani8 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants