DockerCLI/cli/command/registry/login.go

108 lines
2.7 KiB
Go

package registry
import (
"fmt"
"io/ioutil"
"strings"
"golang.org/x/net/context"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/docker/registry"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
type loginOptions struct {
serverAddress string
user string
password string
passwordStdin bool
}
// NewLoginCommand creates a new `docker login` command
func NewLoginCommand(dockerCli command.Cli) *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")
flags.BoolVarP(&opts.passwordStdin, "password-stdin", "", false, "Take the password from stdin")
return cmd
}
func runLogin(dockerCli command.Cli, opts loginOptions) error {
ctx := context.Background()
clnt := dockerCli.Client()
if opts.password != "" {
fmt.Fprintln(dockerCli.Err(), "WARNING! Using --password via the CLI is insecure. Use --password-stdin.")
if opts.passwordStdin {
return errors.New("--password and --password-stdin are mutually exclusive")
}
}
if opts.passwordStdin {
if opts.user == "" {
return errors.New("Must provide --username with --password-stdin")
}
contents, err := ioutil.ReadAll(dockerCli.In())
if err != nil {
return err
}
opts.password = strings.TrimSuffix(string(contents), "\n")
opts.password = strings.TrimSuffix(opts.password, "\r")
}
var (
serverAddress string
authServer = command.ElectAuthServer(ctx, dockerCli)
)
if opts.serverAddress != "" && opts.serverAddress != registry.DefaultNamespace {
serverAddress = opts.serverAddress
} else {
serverAddress = authServer
}
isDefaultRegistry := serverAddress == authServer
authConfig, err := command.ConfigureAuth(dockerCli, 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 := dockerCli.ConfigFile().GetCredentialsStore(serverAddress).Store(authConfig); err != nil {
return errors.Errorf("Error saving credentials: %v", err)
}
if response.Status != "" {
fmt.Fprintln(dockerCli.Out(), response.Status)
}
return nil
}