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

Add retry import with no auth for IS if we get 401 error (public images case) #18012

Merged
merged 1 commit into from
Feb 8, 2018

Conversation

mjudeikis
Copy link
Contributor

If we try to import any image (even public ones) and we have a bad secret (wrong password or expired cloud token) in our project imports are failing.

This leads to all imports in the same project to fail with a random unclear error.
This could be fixed in RoundTripper and Smarter Authenticator. This might end up bigger change than this fix...

This fix just retries import with empty authentication.

If you know better place for this fix let me know :)

https://bugzilla.redhat.com/show_bug.cgi?id=1506175

@openshift-ci-robot openshift-ci-robot added the size/S Denotes a PR that changes 10-29 lines, ignoring generated files. label Jan 7, 2018
@mjudeikis
Copy link
Contributor Author

@bparees this one is other card you sent me. Fix works, but to solve this properly would require changes in either docker API in upstream (docker distribution library) or RT in k8s code... Both of them I dont feel taking on as a challenge :D

if image.Status.Code == http.StatusUnauthorized {
importCtx := importer.NewContext(r.transport, r.insecureTransport).WithCredentials(nil)
imports := r.importFn(importCtx)
if err := imports.Import(ctx.(gocontext.Context), isi, stream); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

one problem I see with this is if the image really is private, does this turn what was a legitimate 401 into a 404 error when you make the import call with no credentials? (because docker returns 404 for private registries?)

That is, if the scenario is: i'm trying to import from a private registry and I provide invalid credentials, previously I would get a proper 401 and know my credentials were (probably) wrong. Is that what will still happen with this change, or will I now see a 404 error and be confused?

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 did the bunch of tests and checking how this "awesome" docker registry API behaves and when we do this (spent way too much time on this...). This fix for me looked least intrusive and did the job.

I think your case is covered because it still gives 401 but it gives different error message so in importer.go it gets assigned different error message.

There is chance it might behave diferently if it will be used with non docker distribution based docker registry API's (Nexus in example) which will give different error messages. But in this case all our error handling logic is flawed.

The current behavior of our IS importer with private and public images with wrong secret:

-bash-4.4#  oc create secret docker-registry dummy-secret1 --docker-server=docker.io --docker-username=dummy1 --docker-password=dummy1 --docker-email==dummy1@example.com
secret "dummy-secret1" created    
##### PUBLIC IMAGE  
-bash-4.4# oc import-image example --from=openshift/hello-openshift --confirm

  ! error: Import failed (InternalError): Internal error occurred: Get https://registry-1.docker.io/v2/openshift/hello-openshift/manifests/latest: unauthorized: incorrect username or password
      Less than a second ago

error: tag latest failed: Internal error occurred: Get https://registry-1.docker.io/v2/openshift/hello-openshift/manifests/latest: unauthorized: incorrect username or password

##### PRIVATE IMAGE  
-bash-4.4# oc import-image example1 --from=mangirdas/kafka-producer:latest --confirm
The import completed with errors.

  ! error: Import failed (InternalError): Internal error occurred: Get https://registry-1.docker.io/v2/mangirdas/kafka-producer/manifests/latest: unauthorized: incorrect username or password
      Less than a second ago

error: tag latest failed: Internal error occurred: Get https://registry-1.docker.io/v2/mangirdas/kafka-producer/manifests/latest: unauthorized: incorrect username or password

With fix:

-bash-4.4#  oc create secret docker-registry dummy-secret1 --docker-server=docker.io --docker-username=dummy1 --docker-password=dummy1 --docker-email==dummy1@example.com                                          
secret "dummy-secret1" created  
##### PUBLIC IMAGE                                                                                                                                                                                     
-bash-4.4# oc import-image example --from=openshift/hello-openshift --confirm                                                                                                                                      
The import completed successfully.                                                                                                                                                                                 

latest                                              
  tagged from openshift/hello-openshift             

  * openshift/hello-openshift@sha256:1a7a40888035f95c10cde81f04c10aa5919a41766e4680452918fc5591d7b02a    
      Less than a second ago                        

##### PRIVATE IMAGE  
-bash-4.4# oc import-image example1 --from=mangirdas/kafka-producer:latest --confirm                     
The import completed with errors.                   

latest                                              
  tagged from mangirdas/kafka-producer:latest       

  ! error: Import failed (Unauthorized): you may not have access to the Docker image "mangirdas/kafka-producer:latest"                                                                                             
      Less than a second ago                        

error: tag latest failed: you may not have access to the Docker image "mangirdas/kafka-producer:latest"  

Without secret:

##### PUBLIC IMAGE  
-bash-4.4# oc import-image example --from=openshift/hello-openshift --confirm
The import completed successfully.

latest
  tagged from openshift/hello-openshift

  * openshift/hello-openshift@sha256:1a7a40888035f95c10cde81f04c10aa5919a41766e4680452918fc5591d7b02a
      Less than a second ago

PRIVATE IMAGE
-bash-4.4# oc import-image example1 --from=mangirdas/kafka-producer:latest --confirm

latest
  tagged from mangirdas/kafka-producer:latest

  ! error: Import failed (Unauthorized): you may not have access to the Docker image "mangirdas/kafka-producer:latest"
      Less than a second ago

error: tag latest failed: you may not have access to the Docker image "mangirdas/kafka-producer:latest"

My secret is OK but the image is in the private repo of other person account:

oc create secret docker-registry dummy-secret1 --docker-server=docker.io --docker-username=mangirdas --docker-password=dummy1 --docker-email=mangirdas@example.com

-bash-4.4# oc import-image example2 --from=juozasa/hellonode:latest --confirm

latest
  tagged from juozasa/hellonode:latest

  ! error: Import failed (Unauthorized): you may not have access to the Docker image "juozasa/hellonode:latest"
      Less than a second ago

error: tag latest failed: you may not have access to the Docker image "juozasa/hellonode:latest"

@bparees bparees self-assigned this Jan 10, 2018
@bparees
Copy link
Contributor

bparees commented Jan 10, 2018

awesome, thank you for the detailed summary of the behavior!
/lgtm

@openshift-ci-robot openshift-ci-robot added lgtm Indicates that a PR is ready to be merged. approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Jan 10, 2018
@mjudeikis
Copy link
Contributor Author

/retest

@mjudeikis
Copy link
Contributor Author

looks like my local dev env is out of sync with our build environment. Investigating where is delta and why I can see different run results.

@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

1 similar comment
@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

@mjudeikis
Copy link
Contributor Author

/retest

@bparees
Copy link
Contributor

bparees commented Jan 11, 2018

you've got a compile erorr:

pkg/image/registry/imagestreamimport/rest.go:215:17: undefined: importer.NewContext

@mjudeikis
Copy link
Contributor Author

Problem is "Works on my laptop" type one :) will try to align my dev env to test env... ETA - dunno. few days.

@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

2 similar comments
@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

@bparees
Copy link
Contributor

bparees commented Jan 12, 2018

@mjudeikis i think the importer package was just restructured. Do a rebase from master.

@mjudeikis
Copy link
Contributor Author

Thanks @bparees will do on the weekend or today in the evening... . Sev1 on the client site... "Life of the consultant..." :'(

@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

1 similar comment
@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

@openshift-merge-robot openshift-merge-robot removed the lgtm Indicates that a PR is ready to be merged. label Jan 13, 2018
@mjudeikis mjudeikis force-pushed the bugzilla_1506175 branch 2 times, most recently from ae8d1be to 43054c7 Compare January 14, 2018 16:29
// check imported images status. If we get authentication error (401), try import same image without authentication.
// Docker registry gives 401 on public images if you have wrong secret in your secret list.
for _, image := range isi.Status.Images {
if image.Status.Reason == metav1.StatusReasonUnauthorized && strings.Contains(image.Status.Message, "incorrect username or password") {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I dont check for the specific message this breaks 'TestImageStreamImportAuthenticated` test. I still need to understand which behavior of the test I break and if this is the change for the test or change for logic. For now, by adding this it makes the test pass and at the same time solves the bug.

Copy link
Contributor

Choose a reason for hiding this comment

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

this sort of check is definitely fragile, i'd prefer to understand what might need to change about the test over adding this contains check.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we can put this on hold for now as I need to find few days to investigate this more.

Copy link
Contributor

Choose a reason for hiding this comment

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

i'd still like to revisit this, but it's an improvement for now so i'm going to merge.

@mjudeikis
Copy link
Contributor Author

/hold

@openshift-ci-robot openshift-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jan 15, 2018
@mjudeikis
Copy link
Contributor Author

will try to do some work this week and let you know on Monday. Got stuck with our awesome storage offering these days.

@mjudeikis
Copy link
Contributor Author

/retest

@mjudeikis
Copy link
Contributor Author

/retest extended_conformance_gce

@bparees
Copy link
Contributor

bparees commented Feb 7, 2018

/lgtm

@mjudeikis you can /hold cancel if you're happy with this.

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Feb 7, 2018
@mjudeikis
Copy link
Contributor Author

@bparees I dont know what changes form the first view, but after rebase tests passes. Will check the code base, but It might be harder to find :)

The only thing which I would like to add this to make a little bit more cleaner error message.
Consider a use case:

  1. I have the wrong secret for my image (token or password expire).
  2. Try import, import will fail, so logic will default to try "unauthenticated".
  3. Import will image will fail due "secure image".

So now user see a message that cant access image as its secure, and no "hints" to check secret.

Suggested message flow to construct error messages:

  1. If Image got "wrong passwod" and later tried unauthenticated and failed too I give something like:
    err := fmt.Errorf("Image import failed using secret with incorrect username or password error. Defaulting to unauthenticated import. \n Failed import with error %v", err)

Still testing this is "chain of actions is even possible in real world"...

@bparees
Copy link
Contributor

bparees commented Feb 7, 2018

you're right. even if we try to import via unauthenticated, if we fail, we should return the original error we got when we tried via authentication, i think.

@mjudeikis
Copy link
Contributor Author

the only change was now to use previous error message form image status field where its being saved.
return nil, kapierrors.NewInternalError(fmt.Errorf(image.Status.Message))

@mjudeikis
Copy link
Contributor Author

/hold cancel

@openshift-ci-robot openshift-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Feb 7, 2018
importCtx := registryclient.NewContext(r.transport, r.insecureTransport).WithCredentials(nil)
imports := r.importFn(importCtx)
if err := imports.Import(ctx.(gocontext.Context), isi, stream); err != nil {
return nil, kapierrors.NewInternalError(fmt.Errorf(image.Status.Message))
Copy link
Contributor

Choose a reason for hiding this comment

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

on further analysis i don't think this is correct. "err" will still be nil, even if the import failed due to credentials, no?

just as the credentials import check above expects err to be nil even if the import was disallowed by auth.

So you're turning a more serious error that occurred during import, into a credential message. I don't think that's right.

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 overthinking this... I think let's leave previous error. Standart error when image credentials are wrong is for private image is:

! error: Import failed (Unauthorized): you may not have access to the Docker image "docker.io/juozasa/hellonode:latest"                                                                                          
      Less than a second ago      

Only when public image is being imported it gives the wrong password when trying with auth header. So only in this case (as much as I manage to test all possible cases), it defaults to this condition. Its just how docker distribution api behaves...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

or we can concatenate both errors to one string but I would better keep it simple... previous way.

Copy link
Contributor

Choose a reason for hiding this comment

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

i agree the error should be returned as is.

i'm less clear on what image.status.message is going to end up being in this case (where you provided invalid credentials and the image is not public, but we tried to access it with nil credentials)?

@openshift-merge-robot openshift-merge-robot removed the lgtm Indicates that a PR is ready to be merged. label Feb 7, 2018
@openshift-ci-robot
Copy link

openshift-ci-robot commented Feb 7, 2018

@mjudeikis: The following test failed, say /retest to rerun them all:

Test name Commit Details Rerun command
ci/openshift-jenkins/extended_conformance_gce 43054c7 link /test extended_conformance_gce

Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@openshift-ci-robot openshift-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/S Denotes a PR that changes 10-29 lines, ignoring generated files. labels Feb 8, 2018
…authentication. This is to eliminate case when we try pull public images with wrong/expired secret and it blocks all imports
@mjudeikis
Copy link
Contributor Author

Status now. I confirm that cases 2-3 got passed to "second loop to retry without a secret" and got old messages defaulted back after failure.
Private image with wrong secret:

 oc import-image example2 --from=docker.io/juozasa/hellonode:latest --confirm
The import completed with errors.

  ! error: Import failed (Unauthorized): incorrect username or password for image "docker.io/juozasa/hellonode:latest"
      Less than a second ago

error: tag latest failed: incorrect username or password for image "docker.io/juozasa/hellonode:latest"

Private image from different API:

[root@default origin]# oc import-image kafka-producer --from=quay.io/mangirdas/docker-debug-container --confirm                                                                                                    
                                                                                                                                                                                                   
latest                                                                                                                                                                                                             
  tagged from quay.io/mangirdas/docker-debug-container                                                                                                                                                             
                                                                                                                                                                                                                   
  ! error: Import failed (InternalError): Internal error occurred: Get https://quay.io/v2/mangirdas/docker-debug-container/manifests/latest: unauthorized: Invalid Username or Password
      Less than a second ago

Public image when we have a wrong secret:

oc import-image example --from=openshift/hello-openshift --confirm                
The import completed successfully.                  
  * openshift/hello-openshift@sha256:a1a35c43bf529df887dedbc63e85d62914de1df4f3b29f72422db0d06327aee2    
      Less than a second ago               

@mjudeikis
Copy link
Contributor Author

Did some more advanced use case test:
IS where one image is public, other is private:

apiVersion: v1                                                      
kind: ImageStream                                                   
metadata:                                                           
  annotations:                                                      
    openshift.io/display-name: Test                                                                                                                                                                                                                                             
  name: test-is                                                     
spec:                                                               
  lookupPolicy:                                                     
    local: false                                                    
  tags:                                                             
  - annotations:                                                    
      description: test1                                            
      iconClass: icon-datavirt                                      
      openshift.io/display-name: test1                                                                                                  
      tags: test                                                    
      version: "latest"                                             
    from:                                                           
      kind: DockerImage                                             
      name: docker.io/juozasa/hellonode:latest                                                                                          
    generation: 2                                                   
    importPolicy: {}                                                
    name: "1.0"                                                     
    referencePolicy:                                                
      type: Source                                                  
  - annotations:                                                    
      description: test1                                            
      iconClass: icon-datavirt                                      
      openshift.io/display-name: test2                              
      tags: test                                                    
      version: "latest"                                             
    from:                                                           
      kind: DockerImage                                             
      name: docker.io/openshift/hello-openshift                     
    generation: 2                                                   
    importPolicy: {}                                                
    name: "latest"                                                  
    referencePolicy:                                                
      type: Source                                                                                                                      
status:                                                             
  dockerImageRepository: ""  

Before code:

[root@default ~]# oc describe is test-is                                                                                                                                                                                                                                        
Name:                   test-is                                                                                                                                                                                                                                                 
Namespace:              import-images                                                                                                                                                                                                                                           
Created:                49 seconds ago                                                                                                                                                                                                                                          
Labels:                 <none>                                                                                                                                                                                                                                                  
Annotations:            openshift.io/display-name=Test                                                                                                                                                                                                                          
                        openshift.io/image.dockerRepositoryCheck=2018-02-08T10:45:40Z                                                                                                                                                                                           
Docker Pull Spec:       172.30.11.158:5000/import-images/test-is                                                                                                                                                                                                                
Image Lookup:           local=false                                                                                                                                                                                                                                             
Unique Images:          0                                                                                                                                                                                                                                                       
Tags:                   2                                                                                                                                                                                                                                                       
                                                                                                                                                                                                                                                                                
latest                                                                                                                                                                                                                                                                          
  tagged from docker.io/openshift/hello-openshift                                                                                                                                                                                                                               
                                                                                                                                                                                                                                                                                
  test1                                                                                                                                                                                                                                                                         
  Tags: test                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                
  ! error: Import failed (Unauthorized): incorrect username or password for image "docker.io/openshift/hello-openshift:latest"                                                                                                                                                  
      1 second ago                                                                                                                                                                                                                                                              

1.0                                                                 
  tagged from docker.io/juozasa/hellonode:latest                    

  test1                                                             
  Tags: test                                                        

  ! error: Import failed (Unauthorized): incorrect username or password for image "docker.io/juozasa/hellonode:latest"                  
      1 second ago                         

after code:

[root@default ~]# oc describe is test-is
Name:                   test-is
Namespace:              import-images
Created:                About a minute ago
Labels:                 <none>
Annotations:            openshift.io/display-name=Test
                        openshift.io/image.dockerRepositoryCheck=2018-02-08T10:49:07Z
Docker Pull Spec:       172.30.113.250:5000/import-images/test-is
Image Lookup:           local=false
Unique Images:          1
Tags:                   2

latest
  tagged from docker.io/openshift/hello-openshift

  test1
  Tags: test

  * docker.io/openshift/hello-openshift@sha256:a1a35c43bf529df887dedbc63e85d62914de1df4f3b29f72422db0d06327aee2
      42 seconds ago

1.0
  tagged from docker.io/juozasa/hellonode:latest

  test1
  Tags: test

  ! error: Import failed (Unauthorized): incorrect username or password for image "docker.io/juozasa/hellonode:latest"
      42 seconds ago

@mjudeikis
Copy link
Contributor Author

/hold
Not sure if approved label merges automatically, so putting this until review done.

@openshift-ci-robot openshift-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Feb 8, 2018
@bparees
Copy link
Contributor

bparees commented Feb 8, 2018

/hold cancel
the approved label does not, it needs a lgtm label(and an approved label) to merge.
/lgtm

@openshift-ci-robot openshift-ci-robot added lgtm Indicates that a PR is ready to be merged. and removed do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. labels Feb 8, 2018
@openshift-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: bparees, mjudeikis

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these OWNERS Files:

You can indicate your approval by writing /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

@openshift-merge-robot
Copy link
Contributor

Automatic merge from submit-queue.

@openshift-merge-robot openshift-merge-robot merged commit f90b369 into openshift:master Feb 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. retest-not-required size/M Denotes a PR that changes 30-99 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants