Skip to content
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

allow to use context for getting signatures #316

Merged
merged 2 commits into from
Aug 3, 2017

Conversation

mfojtik
Copy link
Contributor

@mfojtik mfojtik commented Jul 28, 2017

@mtrmac @runcom since we plan to use the containers/image for downloading signatures from external location, we want to wrap every HTTP request to any location with context.Context that allows to set timeouts and deadlines for the request (so we won't open a request to a black hole, etc.)

i don't want to sweep all containers/image code and address all cases for now (but somebody should ;-) just plumb the code we currently need for openshift/origin#15494

@smarterclayton FYI

@mtrmac
Copy link
Collaborator

mtrmac commented Jul 28, 2017

ACK, something like that needs to happen, but context.Context is weird to have in SystemContext, I’d prefer to do that sweep to changing the API later. I'll see what I can do.

You only care about ImageSource for now, is that correct?

@mfojtik
Copy link
Contributor Author

mfojtik commented Jul 28, 2017

@mtrmac yes, that is correct. I can add this as new argument for reference.NewImageSource but I didn't want to break the API.

@mtrmac
Copy link
Collaborator

mtrmac commented Jul 28, 2017

(BTW if you are planning to carry this patch, there are more places that need to be patched: makeRequestToResolvedURL and getBearerToken.)

@mtrmac
Copy link
Collaborator

mtrmac commented Jul 28, 2017

I can add this as new argument for reference.NewImageSource but I didn't want to break the API.

https://golang.org/pkg/context/ says

Do not store Contexts inside a struct type; instead, pass a Context explicitly to each function that needs it.

so this would be an even bigger API break.

Oh well, we can do it, or perhaps add …WithContext methods to the interface — but I guess I’d prefer the API break for now; we don’t have a documented ABI commitment (@runcom WDYT?).

(For reference, previous stab at this: #43 )

@runcom
Copy link
Member

runcom commented Jul 29, 2017

Right we don't have an API commitment yet so I'm fine adding CTX to the first argument of interfaces so we'll be more idiomatic. I had started doing this somewhere in another PR also but not sure where it went.

I'm +1 here

@mfojtik
Copy link
Contributor Author

mfojtik commented Jul 31, 2017

i'm fine with adding .WithContext() into interfaces

@mfojtik
Copy link
Contributor Author

mfojtik commented Jul 31, 2017

(for now we only care about signatures, so I can plumb that, leaving you guys with the rest ;-)

@mfojtik mfojtik force-pushed the add-context branch 2 times, most recently from 8316870 to f6b7b85 Compare July 31, 2017 10:45
@mfojtik
Copy link
Contributor Author

mfojtik commented Jul 31, 2017

@mtrmac @runcom my last commit add context.Context to the codepath we need in origin to get the autoimport of signatures done. I left bunch of TODO's for methods that have to be plumbed.

PTAL

Copy link
Member

@runcom runcom left a comment

Choose a reason for hiding this comment

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

Seems ok but I want to explicitly use context.TODO or context.Background when you pass nil as context

@@ -145,7 +145,7 @@ func TestGetPutSignatures(t *testing.T) {
src, err := ref.NewImageSource(nil, nil)
require.NoError(t, err)
defer src.Close()
sigs, err := src.GetSignatures()
sigs, err := src.GetSignatures(nil)
Copy link
Member

Choose a reason for hiding this comment

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

I believe we want to pass context.TODO here even if this is a test (or context.Background better)

@@ -254,24 +255,27 @@ func newDockerClient(ctx *types.SystemContext, ref dockerReference, write bool,

// makeRequest creates and executes a http.Request with the specified parameters, adding authentication and TLS options for the Docker client.
// The host name and schema is taken from the client or autodetected, and the path is relative to it, i.e. the path usually starts with /v2/.
func (c *dockerClient) makeRequest(method, path string, headers map[string][]string, stream io.Reader) (*http.Response, error) {
func (c *dockerClient) makeRequest(ctx context.Context, method, path string, headers map[string][]string, stream io.Reader) (*http.Response, error) {
if err := c.detectProperties(); err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

This function also needs ctx

req, err := http.NewRequest(method, url, stream)
if err != nil {
return nil, err
}
if ctx != nil {
Copy link
Member

Choose a reason for hiding this comment

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

We should make sure context is either todo or background here so I'll drop this if.
req.WithContext can accept nil?

Copy link
Contributor Author

@mfojtik mfojtik Jul 31, 2017

Choose a reason for hiding this comment

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

req.WithContext can't accept nil unfortunately but context.Background seems ok here?

Copy link
Member

Choose a reason for hiding this comment

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

Yes please :)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Why should this accept nil? nil is an invalid Context value, and callers who pass it should just crash. This PR is already touching all callers, so it can ensure that nil is never used.

Or am I missing anything?

@@ -454,7 +458,8 @@ func (c *dockerClient) detectProperties() error {

ping := func(scheme string) error {
url := fmt.Sprintf(resolvedPingV2URL, scheme, c.registry)
resp, err := c.makeRequestToResolvedURL("GET", url, nil, nil, -1, true)
// FIXME: Pass the context.Context
resp, err := c.makeRequestToResolvedURL(nil, "GET", url, nil, nil, -1, true)
Copy link
Member

Choose a reason for hiding this comment

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

Use context.TODO or Background

@@ -41,7 +41,8 @@ func (i *Image) SourceRefFullName() string {
// GetRepositoryTags list all tags available in the repository. Note that this has no connection with the tag(s) used for this specific image, if any.
func (i *Image) GetRepositoryTags() ([]string, error) {
path := fmt.Sprintf(tagsPath, reference.Path(i.src.ref.ref))
res, err := i.src.c.makeRequest("GET", path, nil, nil)
// FIXME: Pass the context.Context
res, err := i.src.c.makeRequest(nil, "GET", path, nil, nil)
Copy link
Member

Choose a reason for hiding this comment

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

TODO or Background

@mfojtik mfojtik force-pushed the add-context branch 3 times, most recently from d054424 to 61bb862 Compare July 31, 2017 11:19
@mfojtik
Copy link
Contributor Author

mfojtik commented Jul 31, 2017

@runcom all fixed :)

@mfojtik
Copy link
Contributor Author

mfojtik commented Jul 31, 2017

@mtrmac @runcom why are the travis tests broken? ;-) doesn't seems this broken them

@runcom
Copy link
Member

runcom commented Jul 31, 2017

@mfojtik you need to sign your commits (git commit -s)

@mfojtik
Copy link
Contributor Author

mfojtik commented Jul 31, 2017

@runcom i'm sure they are signed :-) (github shows "verified") i guess you checking the commit message?

@runcom
Copy link
Member

runcom commented Jul 31, 2017

@mfojtik Verified means GPG signed, you need "Signed-by"

@mfojtik
Copy link
Contributor Author

mfojtik commented Jul 31, 2017

@runcom the bot still does not like me :/

@runcom
Copy link
Member

runcom commented Jul 31, 2017

seems like everything's ok now

@runcom
Copy link
Member

runcom commented Jul 31, 2017

you just need to rebase this I guess

@mfojtik
Copy link
Contributor Author

mfojtik commented Jul 31, 2017

@runcom already did :)

@mfojtik
Copy link
Contributor Author

mfojtik commented Jul 31, 2017

ok weird... i must have the link to travis cached... all green now. guess this is ready for shipping?

@runcom
Copy link
Member

runcom commented Jul 31, 2017

LGTM but we also need @mtrmac review :)

Approved with PullApprove

var offset int
// FIXME: pass the context.Context
Copy link
Collaborator

@mtrmac mtrmac Jul 31, 2017

Choose a reason for hiding this comment

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

containers/storage is generally dealing with local files, ignoring the ctx here should be fine.

@@ -226,7 +227,7 @@ func (s *openshiftImageSource) GetBlob(info types.BlobInfo) (io.ReadCloser, int6
return s.docker.GetBlob(info)
}

func (s *openshiftImageSource) GetSignatures() ([][]byte, error) {
func (s *openshiftImageSource) GetSignatures(ctx context.Context) ([][]byte, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could this one be implemented now?

I’m perfectly fine with having context support missing in most of the API, but when it exists, it would be better for users if it reliably worked.

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 containers/image should switch to use the client-go from openshift as external dependency once we cut that out. In that case the context will be available.
This change was just to satisfy the interface.

Copy link
Collaborator

Choose a reason for hiding this comment

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

In the mean time we would still have unreliable API, that’s not great. I’ll take a stab at this.

(As for using the OpenShift client, that would be great (I extracting those thousand lines in openshift-copies.go was annoying and by now it’s probably pretty behind the original, and I do hate the duplication), but the two times this was attempted, it added 60? MB to the size of skopeo, which is just too much.)

Copy link
Collaborator

Choose a reason for hiding this comment

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

@mfojtik added in https://github.com/mtrmac/image/tree/add-context-openshift , can you add that into this PR?

(Disclaimer: I’m still on Go 1.6, so this is untested. I’ll have to update ~immediately, I know.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added your commit.

req, err := http.NewRequest(method, url, stream)
if err != nil {
return nil, err
}
if ctx != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why should this accept nil? nil is an invalid Context value, and callers who pass it should just crash. This PR is already touching all callers, so it can ensure that nil is never used.

Or am I missing anything?

if c.scheme != "" {
return nil
}

ping := func(scheme string) error {
url := fmt.Sprintf(resolvedPingV2URL, scheme, c.registry)
resp, err := c.makeRequestToResolvedURL("GET", url, nil, nil, -1, true)
// FIXME: Pass the context.Context
resp, err := c.makeRequestToResolvedURL(ctx, "GET", url, nil, nil, -1, true)
Copy link
Collaborator

Choose a reason for hiding this comment

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

The FIXME seems to already have been resolved.

req = req.WithContext(ctx)
} else {
req = req.WithContext(context.Background())
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Below this, setupRequestAuth and getBearerToken also need Context support.

@@ -481,7 +488,8 @@ func (c *dockerClient) detectProperties() error {
// best effort to understand if we're talking to a V1 registry
pingV1 := func(scheme string) bool {
url := fmt.Sprintf(resolvedPingV1URL, scheme, c.registry)
resp, err := c.makeRequestToResolvedURL("GET", url, nil, nil, -1, true)
// FIXME: Pass the context.Context
resp, err := c.makeRequestToResolvedURL(ctx, "GET", url, nil, nil, -1, true)
Copy link
Collaborator

Choose a reason for hiding this comment

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

The FIXME seems to already have been resolved.

@@ -132,7 +133,7 @@ func (d *dockerImageDestination) PutBlob(stream io.Reader, inputInfo types.BlobI
// FIXME? Chunked upload, progress reporting, etc.
uploadPath := fmt.Sprintf(blobUploadPath, reference.Path(d.ref.ref))
logrus.Debugf("Uploading %s", uploadPath)
res, err := d.c.makeRequest("POST", uploadPath, nil, nil)
res, err := d.c.makeRequest(context.Background(), "POST", uploadPath, nil, nil)
Copy link
Collaborator

Choose a reason for hiding this comment

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

All of the .Background() in this file should be .TODO() AFAICT.

@@ -396,7 +397,7 @@ func (d *dockerImageDestination) putSignaturesToAPIExtension(signatures [][]byte
// always adds signatures. Eventually we should also allow removing signatures,
// but the X-Registry-Supports-Signatures API extension does not support that yet.

existingSignatures, err := d.c.getExtensionsSignatures(d.ref, d.manifestDigest)
existingSignatures, err := d.c.getExtensionsSignatures(nil, d.ref, d.manifestDigest)
Copy link
Collaborator

Choose a reason for hiding this comment

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

context.TODO(), not nil, please.

default:
return [][]byte{}, nil
}
}

// getSignaturesFromLookaside implements GetSignatures() from the lookaside location configured in s.c.signatureBase,
// which is not nil.
func (s *dockerImageSource) getSignaturesFromLookaside() ([][]byte, error) {
func (s *dockerImageSource) getSignaturesFromLookaside(ctx context.Context) ([][]byte, error) {
if err := s.ensureManifestIsLoaded(); err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

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

ensureManifestIsLoaded also needs to handle ctx.

if err != nil {
return nil, false, err
}
if ctx != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Drop this conditional please; ctx == nil is invalid.

@mfojtik
Copy link
Contributor Author

mfojtik commented Aug 1, 2017

@mtrmac all comments addressed

@TomSweeneyRedHat
Copy link
Member

@mfojtik looks like a rebase is needed.

@@ -150,7 +151,7 @@ func (s *dockerImageSource) getExternalBlob(urls []string) (io.ReadCloser, int64
err error
)
for _, url := range urls {
resp, err = s.c.makeRequestToResolvedURL("GET", url, nil, nil, -1, false)
resp, err = s.c.makeRequestToResolvedURL(context.Background(), "GET", url, nil, nil, -1, false)
Copy link
Collaborator

Choose a reason for hiding this comment

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

context.TODO(), not .Background(), everywhere in this file

@@ -226,7 +227,7 @@ func (s *openshiftImageSource) GetBlob(info types.BlobInfo) (io.ReadCloser, int6
return s.docker.GetBlob(info)
}

func (s *openshiftImageSource) GetSignatures() ([][]byte, error) {
func (s *openshiftImageSource) GetSignatures(ctx context.Context) ([][]byte, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

In the mean time we would still have unreliable API, that’s not great. I’ll take a stab at this.

(As for using the OpenShift client, that would be great (I extracting those thousand lines in openshift-copies.go was annoying and by now it’s probably pretty behind the original, and I do hate the duplication), but the two times this was attempted, it added 60? MB to the size of skopeo, which is just too much.)

@mfojtik mfojtik force-pushed the add-context branch 2 times, most recently from 00973d5 to 8305c27 Compare August 2, 2017 10:15
@mfojtik
Copy link
Contributor Author

mfojtik commented Aug 2, 2017

@mtrmac updated, PTAL

@TomSweeneyRedHat
Copy link
Member

LGTM fwiw.

@mtrmac
Copy link
Collaborator

mtrmac commented Aug 2, 2017

👍

@mfojtik Thanks; one last update after #320 , please.

Approved with PullApprove

mfojtik and others added 2 commits August 2, 2017 21:16
Signed-off-by: Michal Fojtik <mfojtik@redhat.com>
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
@mfojtik
Copy link
Contributor Author

mfojtik commented Aug 2, 2017

@mtrmac updated, lets wait for tests to pass

@mfojtik
Copy link
Contributor Author

mfojtik commented Aug 3, 2017

@runcom guess this one is now good for shipping

@runcom runcom merged commit dbd0a4c into containers:master Aug 3, 2017
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.

4 participants