Просмотр исходного кода

Merge pull request #23265 from vdemeester/migrate-login-logout-to-cobra

Use spf13/cobra for docker login and docker logout
Alexander Morozov 9 лет назад
Родитель
Сommit
a502158d8a

+ 0 - 2
api/client/commands.go

@@ -7,8 +7,6 @@ func (cli *DockerCli) Command(name string) func(...string) error {
 		"exec":    cli.CmdExec,
 		"info":    cli.CmdInfo,
 		"inspect": cli.CmdInspect,
-		"login":   cli.CmdLogin,
-		"logout":  cli.CmdLogout,
 		"ps":      cli.CmdPs,
 		"pull":    cli.CmdPull,
 		"push":    cli.CmdPush,

+ 44 - 0
api/client/credentials.go

@@ -0,0 +1,44 @@
+package client
+
+import (
+	"github.com/docker/docker/cliconfig/configfile"
+	"github.com/docker/docker/cliconfig/credentials"
+	"github.com/docker/engine-api/types"
+)
+
+// GetCredentials loads the user credentials from a credentials store.
+// The store is determined by the config file settings.
+func GetCredentials(c *configfile.ConfigFile, serverAddress string) (types.AuthConfig, error) {
+	s := LoadCredentialsStore(c)
+	return s.Get(serverAddress)
+}
+
+// GetAllCredentials loads all credentials from a credentials store.
+// The store is determined by the config file settings.
+func GetAllCredentials(c *configfile.ConfigFile) (map[string]types.AuthConfig, error) {
+	s := LoadCredentialsStore(c)
+	return s.GetAll()
+}
+
+// StoreCredentials saves the user credentials in a credentials store.
+// The store is determined by the config file settings.
+func StoreCredentials(c *configfile.ConfigFile, auth types.AuthConfig) error {
+	s := LoadCredentialsStore(c)
+	return s.Store(auth)
+}
+
+// EraseCredentials removes the user credentials from a credentials store.
+// The store is determined by the config file settings.
+func EraseCredentials(c *configfile.ConfigFile, serverAddress string) error {
+	s := LoadCredentialsStore(c)
+	return s.Erase(serverAddress)
+}
+
+// LoadCredentialsStore initializes a new credentials store based
+// in the settings provided in the configuration file.
+func LoadCredentialsStore(c *configfile.ConfigFile) credentials.Store {
+	if c.CredentialsStore != "" {
+		return credentials.NewNativeStore(c)
+	}
+	return credentials.NewFileStore(c)
+}

+ 2 - 2
api/client/image/search.go

@@ -52,8 +52,8 @@ func NewSearchCommand(dockerCli *client.DockerCli) *cobra.Command {
 	flags.BoolVar(&opts.automated, "automated", false, "Only show automated builds")
 	flags.UintVarP(&opts.stars, "stars", "s", 0, "Only displays with at least x stars")
 
-	flags.MarkDeprecated("automated", "Use --filter=automated=true instead")
-	flags.MarkDeprecated("stars", "Use --filter=stars=3 instead")
+	flags.MarkDeprecated("automated", "use --filter=automated=true instead")
+	flags.MarkDeprecated("stars", "use --filter=stars=3 instead")
 
 	return cmd
 }

+ 0 - 184
api/client/login.go

@@ -1,184 +0,0 @@
-package client
-
-import (
-	"bufio"
-	"fmt"
-	"io"
-	"os"
-	"runtime"
-	"strings"
-
-	"golang.org/x/net/context"
-
-	Cli "github.com/docker/docker/cli"
-	"github.com/docker/docker/cliconfig/configfile"
-	"github.com/docker/docker/cliconfig/credentials"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/term"
-	"github.com/docker/engine-api/types"
-)
-
-// CmdLogin logs in a user to a Docker registry service.
-//
-// If no server is specified, the user will be logged into or registered to the registry's index server.
-//
-// Usage: docker login SERVER
-func (cli *DockerCli) CmdLogin(args ...string) error {
-	cmd := Cli.Subcmd("login", []string{"[SERVER]"}, Cli.DockerCommands["login"].Description+".\nIf no server is specified, the default is defined by the daemon.", true)
-	cmd.Require(flag.Max, 1)
-
-	flUser := cmd.String([]string{"u", "-username"}, "", "Username")
-	flPassword := cmd.String([]string{"p", "-password"}, "", "Password")
-
-	// Deprecated in 1.11: Should be removed in docker 1.13
-	cmd.String([]string{"#e", "#-email"}, "", "Email")
-
-	cmd.ParseFlags(args, true)
-
-	// On Windows, force the use of the regular OS stdin stream. Fixes #14336/#14210
-	if runtime.GOOS == "windows" {
-		cli.in = os.Stdin
-	}
-
-	ctx := context.Background()
-	var serverAddress string
-	var isDefaultRegistry bool
-	if len(cmd.Args()) > 0 {
-		serverAddress = cmd.Arg(0)
-	} else {
-		serverAddress = cli.electAuthServer(ctx)
-		isDefaultRegistry = true
-	}
-	authConfig, err := cli.configureAuth(*flUser, *flPassword, serverAddress, isDefaultRegistry)
-	if err != nil {
-		return err
-	}
-	response, err := cli.client.RegistryLogin(ctx, authConfig)
-	if err != nil {
-		return err
-	}
-	if response.IdentityToken != "" {
-		authConfig.Password = ""
-		authConfig.IdentityToken = response.IdentityToken
-	}
-	if err := storeCredentials(cli.configFile, authConfig); err != nil {
-		return fmt.Errorf("Error saving credentials: %v", err)
-	}
-
-	if response.Status != "" {
-		fmt.Fprintln(cli.out, response.Status)
-	}
-	return nil
-}
-
-func (cli *DockerCli) promptWithDefault(prompt string, configDefault string) {
-	if configDefault == "" {
-		fmt.Fprintf(cli.out, "%s: ", prompt)
-	} else {
-		fmt.Fprintf(cli.out, "%s (%s): ", prompt, configDefault)
-	}
-}
-
-func (cli *DockerCli) configureAuth(flUser, flPassword, serverAddress string, isDefaultRegistry bool) (types.AuthConfig, error) {
-	authconfig, err := getCredentials(cli.configFile, serverAddress)
-	if err != nil {
-		return authconfig, err
-	}
-
-	// Some links documenting this:
-	// - https://code.google.com/archive/p/mintty/issues/56
-	// - https://github.com/docker/docker/issues/15272
-	// - https://mintty.github.io/ (compatibility)
-	// Linux will hit this if you attempt `cat | docker login`, and Windows
-	// will hit this if you attempt docker login from mintty where stdin
-	// is a pipe, not a character based console.
-	if flPassword == "" && !cli.isTerminalIn {
-		return authconfig, fmt.Errorf("Error: Cannot perform an interactive logon from a non TTY device")
-	}
-
-	authconfig.Username = strings.TrimSpace(authconfig.Username)
-
-	if flUser = strings.TrimSpace(flUser); flUser == "" {
-		if isDefaultRegistry {
-			// if this is a defauly registry (docker hub), then display the following message.
-			fmt.Fprintln(cli.out, "Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.")
-		}
-		cli.promptWithDefault("Username", authconfig.Username)
-		flUser = readInput(cli.in, cli.out)
-		flUser = strings.TrimSpace(flUser)
-		if flUser == "" {
-			flUser = authconfig.Username
-		}
-	}
-	if flUser == "" {
-		return authconfig, fmt.Errorf("Error: Non-null Username Required")
-	}
-	if flPassword == "" {
-		oldState, err := term.SaveState(cli.inFd)
-		if err != nil {
-			return authconfig, err
-		}
-		fmt.Fprintf(cli.out, "Password: ")
-		term.DisableEcho(cli.inFd, oldState)
-
-		flPassword = readInput(cli.in, cli.out)
-		fmt.Fprint(cli.out, "\n")
-
-		term.RestoreTerminal(cli.inFd, oldState)
-		if flPassword == "" {
-			return authconfig, fmt.Errorf("Error: Password Required")
-		}
-	}
-
-	authconfig.Username = flUser
-	authconfig.Password = flPassword
-	authconfig.ServerAddress = serverAddress
-	authconfig.IdentityToken = ""
-
-	return authconfig, nil
-}
-
-func readInput(in io.Reader, out io.Writer) string {
-	reader := bufio.NewReader(in)
-	line, _, err := reader.ReadLine()
-	if err != nil {
-		fmt.Fprintln(out, err.Error())
-		os.Exit(1)
-	}
-	return string(line)
-}
-
-// getCredentials loads the user credentials from a credentials store.
-// The store is determined by the config file settings.
-func getCredentials(c *configfile.ConfigFile, serverAddress string) (types.AuthConfig, error) {
-	s := loadCredentialsStore(c)
-	return s.Get(serverAddress)
-}
-
-func getAllCredentials(c *configfile.ConfigFile) (map[string]types.AuthConfig, error) {
-	s := loadCredentialsStore(c)
-	return s.GetAll()
-}
-
-// storeCredentials saves the user credentials in a credentials store.
-// The store is determined by the config file settings.
-func storeCredentials(c *configfile.ConfigFile, auth types.AuthConfig) error {
-	s := loadCredentialsStore(c)
-	return s.Store(auth)
-}
-
-// eraseCredentials removes the user credentials from a credentials store.
-// The store is determined by the config file settings.
-func eraseCredentials(c *configfile.ConfigFile, serverAddress string) error {
-	s := loadCredentialsStore(c)
-	return s.Erase(serverAddress)
-}
-
-// loadCredentialsStore initializes a new credentials store based
-// in the settings provided in the configuration file.
-func loadCredentialsStore(c *configfile.ConfigFile) credentials.Store {
-	if c.CredentialsStore != "" {
-		return credentials.NewNativeStore(c)
-	}
-	return credentials.NewFileStore(c)
-}

+ 0 - 43
api/client/logout.go

@@ -1,43 +0,0 @@
-package client
-
-import (
-	"fmt"
-
-	"golang.org/x/net/context"
-
-	Cli "github.com/docker/docker/cli"
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdLogout logs a user out from a Docker registry.
-//
-// If no server is specified, the user will be logged out from the registry's index server.
-//
-// Usage: docker logout [SERVER]
-func (cli *DockerCli) CmdLogout(args ...string) error {
-	cmd := Cli.Subcmd("logout", []string{"[SERVER]"}, Cli.DockerCommands["logout"].Description+".\nIf no server is specified, the default is defined by the daemon.", true)
-	cmd.Require(flag.Max, 1)
-
-	cmd.ParseFlags(args, true)
-
-	var serverAddress string
-	if len(cmd.Args()) > 0 {
-		serverAddress = cmd.Arg(0)
-	} else {
-		serverAddress = cli.electAuthServer(context.Background())
-	}
-
-	// check if we're logged in based on the records in the config file
-	// which means it couldn't have user/pass cause they may be in the creds store
-	if _, ok := cli.configFile.AuthConfigs[serverAddress]; !ok {
-		fmt.Fprintf(cli.out, "Not logged in to %s\n", serverAddress)
-		return nil
-	}
-
-	fmt.Fprintf(cli.out, "Remove login credentials for %s\n", serverAddress)
-	if err := eraseCredentials(cli.configFile, serverAddress); err != nil {
-		fmt.Fprintf(cli.out, "WARNING: could not erase credentials: %v\n", err)
-	}
-
-	return nil
-}

+ 159 - 0
api/client/registry.go

@@ -0,0 +1,159 @@
+package client
+
+import (
+	"bufio"
+	"encoding/base64"
+	"encoding/json"
+	"fmt"
+	"io"
+	"os"
+	"runtime"
+	"strings"
+
+	"golang.org/x/net/context"
+
+	"github.com/docker/docker/pkg/term"
+	"github.com/docker/docker/registry"
+	"github.com/docker/engine-api/types"
+	registrytypes "github.com/docker/engine-api/types/registry"
+)
+
+// ElectAuthServer returns the default registry to use (by asking the daemon)
+func (cli *DockerCli) ElectAuthServer(ctx context.Context) string {
+	// The daemon `/info` endpoint informs us of the default registry being
+	// used. This is essential in cross-platforms environment, where for
+	// example a Linux client might be interacting with a Windows daemon, hence
+	// the default registry URL might be Windows specific.
+	serverAddress := registry.IndexServer
+	if info, err := cli.client.Info(ctx); err != nil {
+		fmt.Fprintf(cli.out, "Warning: failed to get default registry endpoint from daemon (%v). Using system default: %s\n", err, serverAddress)
+	} else {
+		serverAddress = info.IndexServerAddress
+	}
+	return serverAddress
+}
+
+// EncodeAuthToBase64 serializes the auth configuration as JSON base64 payload
+func EncodeAuthToBase64(authConfig types.AuthConfig) (string, error) {
+	buf, err := json.Marshal(authConfig)
+	if err != nil {
+		return "", err
+	}
+	return base64.URLEncoding.EncodeToString(buf), nil
+}
+
+// RegistryAuthenticationPrivilegedFunc return a RequestPrivilegeFunc from the specified registry index info
+// for the given command.
+func (cli *DockerCli) RegistryAuthenticationPrivilegedFunc(index *registrytypes.IndexInfo, cmdName string) types.RequestPrivilegeFunc {
+	return func() (string, error) {
+		fmt.Fprintf(cli.out, "\nPlease login prior to %s:\n", cmdName)
+		indexServer := registry.GetAuthConfigKey(index)
+		authConfig, err := cli.ConfigureAuth("", "", indexServer, false)
+		if err != nil {
+			return "", err
+		}
+		return EncodeAuthToBase64(authConfig)
+	}
+}
+
+func (cli *DockerCli) promptWithDefault(prompt string, configDefault string) {
+	if configDefault == "" {
+		fmt.Fprintf(cli.out, "%s: ", prompt)
+	} else {
+		fmt.Fprintf(cli.out, "%s (%s): ", prompt, configDefault)
+	}
+}
+
+// ResolveAuthConfig is like registry.ResolveAuthConfig, but if using the
+// default index, it uses the default index name for the daemon's platform,
+// not the client's platform.
+func (cli *DockerCli) ResolveAuthConfig(ctx context.Context, index *registrytypes.IndexInfo) types.AuthConfig {
+	configKey := index.Name
+	if index.Official {
+		configKey = cli.ElectAuthServer(ctx)
+	}
+
+	a, _ := GetCredentials(cli.configFile, configKey)
+	return a
+}
+
+// RetrieveAuthConfigs return all credentials.
+func (cli *DockerCli) RetrieveAuthConfigs() map[string]types.AuthConfig {
+	acs, _ := GetAllCredentials(cli.configFile)
+	return acs
+}
+
+// ConfigureAuth returns an AuthConfig from the specified user, password and server.
+func (cli *DockerCli) ConfigureAuth(flUser, flPassword, serverAddress string, isDefaultRegistry bool) (types.AuthConfig, error) {
+	// On Windows, force the use of the regular OS stdin stream. Fixes #14336/#14210
+	if runtime.GOOS == "windows" {
+		cli.in = os.Stdin
+	}
+
+	authconfig, err := GetCredentials(cli.configFile, serverAddress)
+	if err != nil {
+		return authconfig, err
+	}
+
+	// Some links documenting this:
+	// - https://code.google.com/archive/p/mintty/issues/56
+	// - https://github.com/docker/docker/issues/15272
+	// - https://mintty.github.io/ (compatibility)
+	// Linux will hit this if you attempt `cat | docker login`, and Windows
+	// will hit this if you attempt docker login from mintty where stdin
+	// is a pipe, not a character based console.
+	if flPassword == "" && !cli.isTerminalIn {
+		return authconfig, fmt.Errorf("Error: Cannot perform an interactive logon from a non TTY device")
+	}
+
+	authconfig.Username = strings.TrimSpace(authconfig.Username)
+
+	if flUser = strings.TrimSpace(flUser); flUser == "" {
+		if isDefaultRegistry {
+			// if this is a defauly registry (docker hub), then display the following message.
+			fmt.Fprintln(cli.out, "Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.")
+		}
+		cli.promptWithDefault("Username", authconfig.Username)
+		flUser = readInput(cli.in, cli.out)
+		flUser = strings.TrimSpace(flUser)
+		if flUser == "" {
+			flUser = authconfig.Username
+		}
+	}
+	if flUser == "" {
+		return authconfig, fmt.Errorf("Error: Non-null Username Required")
+	}
+	if flPassword == "" {
+		oldState, err := term.SaveState(cli.inFd)
+		if err != nil {
+			return authconfig, err
+		}
+		fmt.Fprintf(cli.out, "Password: ")
+		term.DisableEcho(cli.inFd, oldState)
+
+		flPassword = readInput(cli.in, cli.out)
+		fmt.Fprint(cli.out, "\n")
+
+		term.RestoreTerminal(cli.inFd, oldState)
+		if flPassword == "" {
+			return authconfig, fmt.Errorf("Error: Password Required")
+		}
+	}
+
+	authconfig.Username = flUser
+	authconfig.Password = flPassword
+	authconfig.ServerAddress = serverAddress
+	authconfig.IdentityToken = ""
+
+	return authconfig, nil
+}
+
+func readInput(in io.Reader, out io.Writer) string {
+	reader := bufio.NewReader(in)
+	line, _, err := reader.ReadLine()
+	if err != nil {
+		fmt.Fprintln(out, err.Error())
+		os.Exit(1)
+	}
+	return string(line)
+}

+ 81 - 0
api/client/registry/login.go

@@ -0,0 +1,81 @@
+package registry
+
+import (
+	"fmt"
+
+	"golang.org/x/net/context"
+
+	"github.com/docker/docker/api/client"
+	"github.com/docker/docker/cli"
+	"github.com/spf13/cobra"
+)
+
+type loginOptions struct {
+	serverAddress string
+	user          string
+	password      string
+	email         string
+}
+
+// NewLoginCommand creates a new `docker login` command
+func NewLoginCommand(dockerCli *client.DockerCli) *cobra.Command {
+	var opts loginOptions
+
+	cmd := &cobra.Command{
+		Use:   "login [OPTIONS] [SERVER]",
+		Short: "Log in to a Docker registry.",
+		Long:  "Log in to a Docker registry.\nIf no server is specified, the default is defined by the daemon.",
+		Args:  cli.RequiresMaxArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			if len(args) > 0 {
+				opts.serverAddress = args[0]
+			}
+			return runLogin(dockerCli, opts)
+		},
+	}
+
+	flags := cmd.Flags()
+
+	flags.StringVarP(&opts.user, "username", "u", "", "Username")
+	flags.StringVarP(&opts.password, "password", "p", "", "Password")
+
+	// Deprecated in 1.11: Should be removed in docker 1.13
+	flags.StringVarP(&opts.email, "email", "e", "", "Email")
+	flags.MarkDeprecated("email", "will be removed in 1.13.")
+
+	return cmd
+}
+
+func runLogin(dockerCli *client.DockerCli, opts loginOptions) error {
+	ctx := context.Background()
+	clnt := dockerCli.Client()
+
+	var serverAddress string
+	var isDefaultRegistry bool
+	if opts.serverAddress != "" {
+		serverAddress = opts.serverAddress
+	} else {
+		serverAddress = dockerCli.ElectAuthServer(ctx)
+		isDefaultRegistry = true
+	}
+	authConfig, err := dockerCli.ConfigureAuth(opts.user, opts.password, serverAddress, isDefaultRegistry)
+	if err != nil {
+		return err
+	}
+	response, err := clnt.RegistryLogin(ctx, authConfig)
+	if err != nil {
+		return err
+	}
+	if response.IdentityToken != "" {
+		authConfig.Password = ""
+		authConfig.IdentityToken = response.IdentityToken
+	}
+	if err := client.StoreCredentials(dockerCli.ConfigFile(), authConfig); err != nil {
+		return fmt.Errorf("Error saving credentials: %v", err)
+	}
+
+	if response.Status != "" {
+		fmt.Fprintln(dockerCli.Out(), response.Status)
+	}
+	return nil
+}

+ 52 - 0
api/client/registry/logout.go

@@ -0,0 +1,52 @@
+package registry
+
+import (
+	"fmt"
+
+	"golang.org/x/net/context"
+
+	"github.com/docker/docker/api/client"
+	"github.com/docker/docker/cli"
+	"github.com/spf13/cobra"
+)
+
+// NewLogoutCommand creates a new `docker login` command
+func NewLogoutCommand(dockerCli *client.DockerCli) *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "logout [SERVER]",
+		Short: "Log out from a Docker registry.",
+		Long:  "Log out from a Docker registry.\nIf no server is specified, the default is defined by the daemon.",
+		Args:  cli.RequiresMaxArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			var serverAddress string
+			if len(args) > 0 {
+				serverAddress = args[0]
+			}
+			return runLogout(dockerCli, serverAddress)
+		},
+	}
+
+	return cmd
+}
+
+func runLogout(dockerCli *client.DockerCli, serverAddress string) error {
+	ctx := context.Background()
+
+	if serverAddress == "" {
+		serverAddress = dockerCli.ElectAuthServer(ctx)
+	}
+
+	// check if we're logged in based on the records in the config file
+	// which means it couldn't have user/pass cause they may be in the creds store
+	if _, ok := dockerCli.ConfigFile().AuthConfigs[serverAddress]; !ok {
+		fmt.Fprintf(dockerCli.Out(), "Not logged in to %s\n", serverAddress)
+		return nil
+	}
+
+	fmt.Fprintf(dockerCli.Out(), "Remove login credentials for %s\n", serverAddress)
+	if err := client.EraseCredentials(dockerCli.ConfigFile(), serverAddress); err != nil {
+		fmt.Fprintf(dockerCli.Out(), "WARNING: could not erase credentials: %v\n", err)
+	}
+
+	return nil
+}

+ 1 - 61
api/client/utils.go

@@ -1,8 +1,6 @@
 package client
 
 import (
-	"encoding/base64"
-	"encoding/json"
 	"fmt"
 	"io"
 	"io/ioutil"
@@ -17,49 +15,10 @@ import (
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/signal"
 	"github.com/docker/docker/pkg/term"
-	"github.com/docker/docker/registry"
 	"github.com/docker/engine-api/client"
 	"github.com/docker/engine-api/types"
-	registrytypes "github.com/docker/engine-api/types/registry"
 )
 
-func (cli *DockerCli) electAuthServer(ctx context.Context) string {
-	// The daemon `/info` endpoint informs us of the default registry being
-	// used. This is essential in cross-platforms environment, where for
-	// example a Linux client might be interacting with a Windows daemon, hence
-	// the default registry URL might be Windows specific.
-	serverAddress := registry.IndexServer
-	if info, err := cli.client.Info(ctx); err != nil {
-		fmt.Fprintf(cli.out, "Warning: failed to get default registry endpoint from daemon (%v). Using system default: %s\n", err, serverAddress)
-	} else {
-		serverAddress = info.IndexServerAddress
-	}
-	return serverAddress
-}
-
-// EncodeAuthToBase64 serializes the auth configuration as JSON base64 payload
-func EncodeAuthToBase64(authConfig types.AuthConfig) (string, error) {
-	buf, err := json.Marshal(authConfig)
-	if err != nil {
-		return "", err
-	}
-	return base64.URLEncoding.EncodeToString(buf), nil
-}
-
-// RegistryAuthenticationPrivilegedFunc return a RequestPrivilegeFunc from the specified registry index info
-// for the given command.
-func (cli *DockerCli) RegistryAuthenticationPrivilegedFunc(index *registrytypes.IndexInfo, cmdName string) types.RequestPrivilegeFunc {
-	return func() (string, error) {
-		fmt.Fprintf(cli.out, "\nPlease login prior to %s:\n", cmdName)
-		indexServer := registry.GetAuthConfigKey(index)
-		authConfig, err := cli.configureAuth("", "", indexServer, false)
-		if err != nil {
-			return "", err
-		}
-		return EncodeAuthToBase64(authConfig)
-	}
-}
-
 func (cli *DockerCli) resizeTty(ctx context.Context, id string, isExec bool) {
 	height, width := cli.GetTtySize()
 	cli.ResizeTtyTo(ctx, id, height, width, isExec)
@@ -174,26 +133,7 @@ func CopyToFile(outfile string, r io.Reader) error {
 	return nil
 }
 
-// ResolveAuthConfig is like registry.ResolveAuthConfig, but if using the
-// default index, it uses the default index name for the daemon's platform,
-// not the client's platform.
-func (cli *DockerCli) ResolveAuthConfig(ctx context.Context, index *registrytypes.IndexInfo) types.AuthConfig {
-	configKey := index.Name
-	if index.Official {
-		configKey = cli.electAuthServer(ctx)
-	}
-
-	a, _ := getCredentials(cli.configFile, configKey)
-	return a
-}
-
-// RetrieveAuthConfigs return all credentials.
-func (cli *DockerCli) RetrieveAuthConfigs() map[string]types.AuthConfig {
-	acs, _ := getAllCredentials(cli.configFile)
-	return acs
-}
-
-// ForwardAllSignals forwards signals to the container
+// ForwardAllSignals forwards signals to the contianer
 // TODO: this can be unexported again once all container commands are under
 // api/client/container
 func (cli *DockerCli) ForwardAllSignals(ctx context.Context, cid string) chan os.Signal {

+ 3 - 0
cli/cobraadaptor/adaptor.go

@@ -5,6 +5,7 @@ import (
 	"github.com/docker/docker/api/client/container"
 	"github.com/docker/docker/api/client/image"
 	"github.com/docker/docker/api/client/network"
+	"github.com/docker/docker/api/client/registry"
 	"github.com/docker/docker/api/client/system"
 	"github.com/docker/docker/api/client/volume"
 	"github.com/docker/docker/cli"
@@ -65,6 +66,8 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor {
 		image.NewTagCommand(dockerCli),
 		network.NewNetworkCommand(dockerCli),
 		system.NewEventsCommand(dockerCli),
+		registry.NewLoginCommand(dockerCli),
+		registry.NewLogoutCommand(dockerCli),
 		system.NewVersionCommand(dockerCli),
 		volume.NewVolumeCommand(dockerCli),
 	)

+ 0 - 2
cli/usage.go

@@ -12,8 +12,6 @@ var DockerCommandUsage = []Command{
 	{"exec", "Run a command in a running container"},
 	{"info", "Display system-wide information"},
 	{"inspect", "Return low-level information on a container or image"},
-	{"login", "Log in to a Docker registry"},
-	{"logout", "Log out from a Docker registry"},
 	{"ps", "List containers"},
 	{"pull", "Pull an image or a repository from a registry"},
 	{"push", "Push an image or a repository to a registry"},