Browse code

Implement docker login with standalone client lib.

Signed-off-by: David Calavera <david.calavera@gmail.com>

David Calavera authored on 2015/12/04 09:12:35
Showing 3 changed files
... ...
@@ -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