Signed-off-by: David Calavera <david.calavera@gmail.com>
| ... | ... |
@@ -12,20 +12,26 @@ func (i imageNotFoundError) Error() string {
|
| 12 | 12 |
return fmt.Sprintf("Image not found: %s", i.imageID)
|
| 13 | 13 |
} |
| 14 | 14 |
|
| 15 |
-// ImageNotFound returns the ID of the image not found on the docker host. |
|
| 16 |
-func (i imageNotFoundError) ImageIDNotFound() string {
|
|
| 17 |
- return i.imageID |
|
| 15 |
+// IsImageNotFound returns true if the error is caused |
|
| 16 |
+// when an image is not found in the docker host. |
|
| 17 |
+func IsErrImageNotFound(err error) bool {
|
|
| 18 |
+ _, ok := err.(imageNotFoundError) |
|
| 19 |
+ return ok |
|
| 18 | 20 |
} |
| 19 | 21 |
|
| 20 |
-// ImageNotFound is an interface that describes errors caused |
|
| 21 |
-// when an image is not found in the docker host. |
|
| 22 |
-type ImageNotFound interface {
|
|
| 23 |
- ImageIDNotFound() string |
|
| 22 |
+// unauthorizedError represents an authorization error in a remote registry. |
|
| 23 |
+type unauthorizedError struct {
|
|
| 24 |
+ cause error |
|
| 24 | 25 |
} |
| 25 | 26 |
|
| 26 |
-// IsImageNotFound returns true when the error is caused |
|
| 27 |
-// when an image is not found in the docker host. |
|
| 28 |
-func IsErrImageNotFound(err error) bool {
|
|
| 29 |
- _, ok := err.(ImageNotFound) |
|
| 27 |
+// Error returns a string representation of an unauthorizedError |
|
| 28 |
+func (u unauthorizedError) Error() string {
|
|
| 29 |
+ return u.cause.Error() |
|
| 30 |
+} |
|
| 31 |
+ |
|
| 32 |
+// IsUnauthorized returns true if the error is caused |
|
| 33 |
+// when an the remote registry authentication fails |
|
| 34 |
+func IsErrUnauthorized(err error) bool {
|
|
| 35 |
+ _, ok := err.(unauthorizedError) |
|
| 30 | 36 |
return ok |
| 31 | 37 |
} |
| 32 | 38 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,28 @@ |
| 0 |
+package lib |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "encoding/json" |
|
| 4 |
+ "net/http" |
|
| 5 |
+ "net/url" |
|
| 6 |
+ |
|
| 7 |
+ "github.com/docker/docker/api/types" |
|
| 8 |
+ "github.com/docker/docker/cliconfig" |
|
| 9 |
+) |
|
| 10 |
+ |
|
| 11 |
+// RegistryLogin authenticates the docker server with a given docker registry. |
|
| 12 |
+// It returns UnauthorizerError when the authentication fails. |
|
| 13 |
+func (cli *Client) RegistryLogin(auth cliconfig.AuthConfig) (types.AuthResponse, error) {
|
|
| 14 |
+ resp, err := cli.POST("/auth", url.Values{}, auth, nil)
|
|
| 15 |
+ |
|
| 16 |
+ if resp != nil && resp.statusCode == http.StatusUnauthorized {
|
|
| 17 |
+ return types.AuthResponse{}, unauthorizedError{err}
|
|
| 18 |
+ } |
|
| 19 |
+ if err != nil {
|
|
| 20 |
+ return types.AuthResponse{}, err
|
|
| 21 |
+ } |
|
| 22 |
+ defer resp.body.Close() |
|
| 23 |
+ |
|
| 24 |
+ var response types.AuthResponse |
|
| 25 |
+ err = json.NewDecoder(resp.body).Decode(&response) |
|
| 26 |
+ return response, err |
|
| 27 |
+} |
| ... | ... |
@@ -2,14 +2,13 @@ package client |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"bufio" |
| 5 |
- "encoding/json" |
|
| 6 | 5 |
"fmt" |
| 7 | 6 |
"io" |
| 8 | 7 |
"os" |
| 9 | 8 |
"runtime" |
| 10 | 9 |
"strings" |
| 11 | 10 |
|
| 12 |
- "github.com/docker/docker/api/types" |
|
| 11 |
+ "github.com/docker/docker/api/client/lib" |
|
| 13 | 12 |
Cli "github.com/docker/docker/cli" |
| 14 | 13 |
"github.com/docker/docker/cliconfig" |
| 15 | 14 |
flag "github.com/docker/docker/pkg/mflag" |
| ... | ... |
@@ -120,24 +119,15 @@ func (cli *DockerCli) CmdLogin(args ...string) error {
|
| 120 | 120 |
authconfig.ServerAddress = serverAddress |
| 121 | 121 |
cli.configFile.AuthConfigs[serverAddress] = authconfig |
| 122 | 122 |
|
| 123 |
- serverResp, err := cli.call("POST", "/auth", cli.configFile.AuthConfigs[serverAddress], nil)
|
|
| 124 |
- if serverResp.statusCode == 401 {
|
|
| 125 |
- delete(cli.configFile.AuthConfigs, serverAddress) |
|
| 126 |
- if err2 := cli.configFile.Save(); err2 != nil {
|
|
| 127 |
- fmt.Fprintf(cli.out, "WARNING: could not save config file: %v\n", err2) |
|
| 128 |
- } |
|
| 129 |
- return err |
|
| 130 |
- } |
|
| 123 |
+ auth := cli.configFile.AuthConfigs[serverAddress] |
|
| 124 |
+ response, err := cli.client.RegistryLogin(auth) |
|
| 131 | 125 |
if err != nil {
|
| 132 |
- return err |
|
| 133 |
- } |
|
| 134 |
- |
|
| 135 |
- defer serverResp.body.Close() |
|
| 136 |
- |
|
| 137 |
- var response types.AuthResponse |
|
| 138 |
- if err := json.NewDecoder(serverResp.body).Decode(&response); err != nil {
|
|
| 139 |
- // Upon error, remove entry |
|
| 140 |
- delete(cli.configFile.AuthConfigs, serverAddress) |
|
| 126 |
+ if lib.IsErrUnauthorized(err) {
|
|
| 127 |
+ delete(cli.configFile.AuthConfigs, serverAddress) |
|
| 128 |
+ if err2 := cli.configFile.Save(); err2 != nil {
|
|
| 129 |
+ fmt.Fprintf(cli.out, "WARNING: could not save config file: %v\n", err2) |
|
| 130 |
+ } |
|
| 131 |
+ } |
|
| 141 | 132 |
return err |
| 142 | 133 |
} |
| 143 | 134 |
|