From fe891998672bbeb05b38bb301206de092548c7eb Mon Sep 17 00:00:00 2001 From: Qi Wang Date: Tue, 24 Sep 2019 15:26:23 -0400 Subject: [PATCH] return resp error message follow https://github.com/containers/image/pull/709 return and wrap http response message to show server-side error message. Signed-off-by: Qi Wang --- docker/docker_client.go | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/docker/docker_client.go b/docker/docker_client.go index d5662a030f..48504e6bbd 100644 --- a/docker/docker_client.go +++ b/docker/docker_client.go @@ -50,12 +50,19 @@ const ( var ( // ErrV1NotSupported is returned when we're trying to talk to a // docker V1 registry. - ErrV1NotSupported = errors.New("can't talk to a V1 docker registry") - // ErrUnauthorizedForCredentials is returned when the status code returned is 401 - ErrUnauthorizedForCredentials = errors.New("unable to retrieve auth token: invalid username/password") - systemPerHostCertDirPaths = [2]string{"/etc/containers/certs.d", "/etc/docker/certs.d"} + ErrV1NotSupported = errors.New("can't talk to a V1 docker registry") + systemPerHostCertDirPaths = [2]string{"/etc/containers/certs.d", "/etc/docker/certs.d"} ) +// ErrUnauthorizedForCredentials is returned when the status code returned is 401 +type ErrUnauthorizedForCredentials struct { // We only use a struct to allow a type assertion, without limiting the contents of the error otherwise. + Err error +} + +func (e ErrUnauthorizedForCredentials) Error() string { + return fmt.Sprintf("unable to retrieve auth token: invalid username/password: %s", e.Err.Error()) +} + // extensionSignature and extensionSignatureList come from github.com/openshift/origin/pkg/dockerregistry/server/signaturedispatcher.go: // signature represents a Docker image signature. type extensionSignature struct { @@ -271,14 +278,14 @@ func newDockerClient(sys *types.SystemContext, registry, reference string) (*doc // CheckAuth validates the credentials by attempting to log into the registry // returns an error if an error occurred while making the http request or the status code received was 401 func CheckAuth(ctx context.Context, sys *types.SystemContext, username, password, registry string) error { - client, err := newDockerClient(sys, registry, registry) + dockerClient, err := newDockerClient(sys, registry, registry) if err != nil { return errors.Wrapf(err, "error creating new docker client") } - client.username = username - client.password = password + dockerClient.username = username + dockerClient.password = password - resp, err := client.makeRequest(ctx, "GET", "/v2/", nil, nil, v2Auth, nil) + resp, err := dockerClient.makeRequest(ctx, "GET", "/v2/", nil, nil, v2Auth, nil) if err != nil { return err } @@ -288,7 +295,8 @@ func CheckAuth(ctx context.Context, sys *types.SystemContext, username, password case http.StatusOK: return nil case http.StatusUnauthorized: - return ErrUnauthorizedForCredentials + err := client.HandleErrorResponse(resp) + return ErrUnauthorizedForCredentials{Err: err} default: return errors.Errorf("error occured with status code %d (%s)", resp.StatusCode, http.StatusText(resp.StatusCode)) } @@ -535,7 +543,7 @@ func (c *dockerClient) getBearerToken(ctx context.Context, challenge challenge, case http.StatusUnauthorized: err := client.HandleErrorResponse(res) logrus.Debugf("Server response when trying to obtain an access token: \n%q", err.Error()) - return nil, ErrUnauthorizedForCredentials + return nil, ErrUnauthorizedForCredentials{Err: err} case http.StatusOK: break default: