Forráskód Böngészése

Implement docker login with standalone client lib.

Signed-off-by: David Calavera <david.calavera@gmail.com>
David Calavera 9 éve
szülő
commit
b36531db60
3 módosított fájl, 54 hozzáadás és 30 törlés
  1. 17 11
      api/client/lib/errors.go
  2. 28 0
      api/client/lib/login.go
  3. 9 19
      api/client/login.go

+ 17 - 11
api/client/lib/errors.go

@@ -12,20 +12,26 @@ func (i imageNotFoundError) Error() string {
 	return fmt.Sprintf("Image not found: %s", i.imageID)
 }
 
-// ImageNotFound returns the ID of the image not found on the docker host.
-func (i imageNotFoundError) ImageIDNotFound() string {
-	return i.imageID
+// IsImageNotFound returns true if the error is caused
+// when an image is not found in the docker host.
+func IsErrImageNotFound(err error) bool {
+	_, ok := err.(imageNotFoundError)
+	return ok
 }
 
-// ImageNotFound is an interface that describes errors caused
-// when an image is not found in the docker host.
-type ImageNotFound interface {
-	ImageIDNotFound() string
+// unauthorizedError represents an authorization error in a remote registry.
+type unauthorizedError struct {
+	cause error
 }
 
-// IsImageNotFound returns true when the error is caused
-// when an image is not found in the docker host.
-func IsErrImageNotFound(err error) bool {
-	_, ok := err.(ImageNotFound)
+// Error returns a string representation of an unauthorizedError
+func (u unauthorizedError) Error() string {
+	return u.cause.Error()
+}
+
+// IsUnauthorized returns true if the error is caused
+// when an the remote registry authentication fails
+func IsErrUnauthorized(err error) bool {
+	_, ok := err.(unauthorizedError)
 	return ok
 }

+ 28 - 0
api/client/lib/login.go

@@ -0,0 +1,28 @@
+package lib
+
+import (
+	"encoding/json"
+	"net/http"
+	"net/url"
+
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/cliconfig"
+)
+
+// RegistryLogin authenticates the docker server with a given docker registry.
+// It returns UnauthorizerError when the authentication fails.
+func (cli *Client) RegistryLogin(auth cliconfig.AuthConfig) (types.AuthResponse, error) {
+	resp, err := cli.POST("/auth", url.Values{}, auth, nil)
+
+	if resp != nil && resp.statusCode == http.StatusUnauthorized {
+		return types.AuthResponse{}, unauthorizedError{err}
+	}
+	if err != nil {
+		return types.AuthResponse{}, err
+	}
+	defer resp.body.Close()
+
+	var response types.AuthResponse
+	err = json.NewDecoder(resp.body).Decode(&response)
+	return response, err
+}

+ 9 - 19
api/client/login.go

@@ -2,14 +2,13 @@ package client
 
 import (
 	"bufio"
-	"encoding/json"
 	"fmt"
 	"io"
 	"os"
 	"runtime"
 	"strings"
 
-	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/api/client/lib"
 	Cli "github.com/docker/docker/cli"
 	"github.com/docker/docker/cliconfig"
 	flag "github.com/docker/docker/pkg/mflag"
@@ -120,24 +119,15 @@ func (cli *DockerCli) CmdLogin(args ...string) error {
 	authconfig.ServerAddress = serverAddress
 	cli.configFile.AuthConfigs[serverAddress] = authconfig
 
-	serverResp, err := cli.call("POST", "/auth", cli.configFile.AuthConfigs[serverAddress], nil)
-	if serverResp.statusCode == 401 {
-		delete(cli.configFile.AuthConfigs, serverAddress)
-		if err2 := cli.configFile.Save(); err2 != nil {
-			fmt.Fprintf(cli.out, "WARNING: could not save config file: %v\n", err2)
-		}
-		return err
-	}
+	auth := cli.configFile.AuthConfigs[serverAddress]
+	response, err := cli.client.RegistryLogin(auth)
 	if err != nil {
-		return err
-	}
-
-	defer serverResp.body.Close()
-
-	var response types.AuthResponse
-	if err := json.NewDecoder(serverResp.body).Decode(&response); err != nil {
-		// Upon error, remove entry
-		delete(cli.configFile.AuthConfigs, serverAddress)
+		if lib.IsErrUnauthorized(err) {
+			delete(cli.configFile.AuthConfigs, serverAddress)
+			if err2 := cli.configFile.Save(); err2 != nil {
+				fmt.Fprintf(cli.out, "WARNING: could not save config file: %v\n", err2)
+			}
+		}
 		return err
 	}