github.com/endocode/docker@v1.4.2-0.20160113120958-46eb4700391e/api/client/login.go (about) 1 package client 2 3 import ( 4 "bufio" 5 "fmt" 6 "io" 7 "os" 8 "runtime" 9 "strings" 10 11 Cli "github.com/docker/docker/cli" 12 flag "github.com/docker/docker/pkg/mflag" 13 "github.com/docker/docker/pkg/term" 14 "github.com/docker/docker/registry" 15 "github.com/docker/engine-api/client" 16 "github.com/docker/engine-api/types" 17 ) 18 19 // CmdLogin logs in or registers a user to a Docker registry service. 20 // 21 // If no server is specified, the user will be logged into or registered to the registry's index server. 22 // 23 // Usage: docker login SERVER 24 func (cli *DockerCli) CmdLogin(args ...string) error { 25 cmd := Cli.Subcmd("login", []string{"[SERVER]"}, Cli.DockerCommands["login"].Description+".\nIf no server is specified \""+registry.IndexServer+"\" is the default.", true) 26 cmd.Require(flag.Max, 1) 27 28 var username, password, email string 29 30 cmd.StringVar(&username, []string{"u", "-username"}, "", "Username") 31 cmd.StringVar(&password, []string{"p", "-password"}, "", "Password") 32 cmd.StringVar(&email, []string{"e", "-email"}, "", "Email") 33 34 cmd.ParseFlags(args, true) 35 36 // On Windows, force the use of the regular OS stdin stream. Fixes #14336/#14210 37 if runtime.GOOS == "windows" { 38 cli.in = os.Stdin 39 } 40 41 serverAddress := registry.IndexServer 42 if len(cmd.Args()) > 0 { 43 serverAddress = cmd.Arg(0) 44 } 45 46 promptDefault := func(prompt string, configDefault string) { 47 if configDefault == "" { 48 fmt.Fprintf(cli.out, "%s: ", prompt) 49 } else { 50 fmt.Fprintf(cli.out, "%s (%s): ", prompt, configDefault) 51 } 52 } 53 54 readInput := func(in io.Reader, out io.Writer) string { 55 reader := bufio.NewReader(in) 56 line, _, err := reader.ReadLine() 57 if err != nil { 58 fmt.Fprintln(out, err.Error()) 59 os.Exit(1) 60 } 61 return string(line) 62 } 63 64 authconfig, ok := cli.configFile.AuthConfigs[serverAddress] 65 if !ok { 66 authconfig = types.AuthConfig{} 67 } 68 69 if username == "" { 70 promptDefault("Username", authconfig.Username) 71 username = readInput(cli.in, cli.out) 72 username = strings.TrimSpace(username) 73 if username == "" { 74 username = authconfig.Username 75 } 76 } 77 // Assume that a different username means they may not want to use 78 // the password or email from the config file, so prompt them 79 if username != authconfig.Username { 80 if password == "" { 81 oldState, err := term.SaveState(cli.inFd) 82 if err != nil { 83 return err 84 } 85 fmt.Fprintf(cli.out, "Password: ") 86 term.DisableEcho(cli.inFd, oldState) 87 88 password = readInput(cli.in, cli.out) 89 fmt.Fprint(cli.out, "\n") 90 91 term.RestoreTerminal(cli.inFd, oldState) 92 if password == "" { 93 return fmt.Errorf("Error : Password Required") 94 } 95 } 96 97 if email == "" { 98 promptDefault("Email", authconfig.Email) 99 email = readInput(cli.in, cli.out) 100 if email == "" { 101 email = authconfig.Email 102 } 103 } 104 } else { 105 // However, if they don't override the username use the 106 // password or email from the cmd line if specified. IOW, allow 107 // then to change/override them. And if not specified, just 108 // use what's in the config file 109 if password == "" { 110 password = authconfig.Password 111 } 112 if email == "" { 113 email = authconfig.Email 114 } 115 } 116 authconfig.Username = username 117 authconfig.Password = password 118 authconfig.Email = email 119 authconfig.ServerAddress = serverAddress 120 cli.configFile.AuthConfigs[serverAddress] = authconfig 121 122 auth := cli.configFile.AuthConfigs[serverAddress] 123 response, err := cli.client.RegistryLogin(auth) 124 if err != nil { 125 if client.IsErrUnauthorized(err) { 126 delete(cli.configFile.AuthConfigs, serverAddress) 127 if err2 := cli.configFile.Save(); err2 != nil { 128 fmt.Fprintf(cli.out, "WARNING: could not save config file: %v\n", err2) 129 } 130 } 131 return err 132 } 133 134 if err := cli.configFile.Save(); err != nil { 135 return fmt.Errorf("Error saving config file: %v", err) 136 } 137 fmt.Fprintf(cli.out, "WARNING: login credentials saved in %s\n", cli.configFile.Filename()) 138 139 if response.Status != "" { 140 fmt.Fprintf(cli.out, "%s\n", response.Status) 141 } 142 return nil 143 }