github.com/torfuzx/docker@v1.8.1/api/client/login.go (about) 1 package client 2 3 import ( 4 "bufio" 5 "encoding/json" 6 "fmt" 7 "io" 8 "os" 9 "strings" 10 11 "github.com/docker/docker/api/types" 12 Cli "github.com/docker/docker/cli" 13 "github.com/docker/docker/cliconfig" 14 flag "github.com/docker/docker/pkg/mflag" 15 "github.com/docker/docker/pkg/term" 16 "github.com/docker/docker/registry" 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]"}, "Register or log in to a Docker registry server, if no server is\nspecified \""+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 serverAddress := registry.IndexServer 37 if len(cmd.Args()) > 0 { 38 serverAddress = cmd.Arg(0) 39 } 40 41 promptDefault := func(prompt string, configDefault string) { 42 if configDefault == "" { 43 fmt.Fprintf(cli.out, "%s: ", prompt) 44 } else { 45 fmt.Fprintf(cli.out, "%s (%s): ", prompt, configDefault) 46 } 47 } 48 49 readInput := func(in io.Reader, out io.Writer) string { 50 reader := bufio.NewReader(in) 51 line, _, err := reader.ReadLine() 52 if err != nil { 53 fmt.Fprintln(out, err.Error()) 54 os.Exit(1) 55 } 56 return string(line) 57 } 58 59 authconfig, ok := cli.configFile.AuthConfigs[serverAddress] 60 if !ok { 61 authconfig = cliconfig.AuthConfig{} 62 } 63 64 if username == "" { 65 promptDefault("Username", authconfig.Username) 66 username = readInput(cli.in, cli.out) 67 username = strings.Trim(username, " ") 68 if username == "" { 69 username = authconfig.Username 70 } 71 } 72 // Assume that a different username means they may not want to use 73 // the password or email from the config file, so prompt them 74 if username != authconfig.Username { 75 if password == "" { 76 oldState, err := term.SaveState(cli.inFd) 77 if err != nil { 78 return err 79 } 80 fmt.Fprintf(cli.out, "Password: ") 81 term.DisableEcho(cli.inFd, oldState) 82 83 password = readInput(cli.in, cli.out) 84 fmt.Fprint(cli.out, "\n") 85 86 term.RestoreTerminal(cli.inFd, oldState) 87 if password == "" { 88 return fmt.Errorf("Error : Password Required") 89 } 90 } 91 92 if email == "" { 93 promptDefault("Email", authconfig.Email) 94 email = readInput(cli.in, cli.out) 95 if email == "" { 96 email = authconfig.Email 97 } 98 } 99 } else { 100 // However, if they don't override the username use the 101 // password or email from the cmd line if specified. IOW, allow 102 // then to change/override them. And if not specified, just 103 // use what's in the config file 104 if password == "" { 105 password = authconfig.Password 106 } 107 if email == "" { 108 email = authconfig.Email 109 } 110 } 111 authconfig.Username = username 112 authconfig.Password = password 113 authconfig.Email = email 114 authconfig.ServerAddress = serverAddress 115 cli.configFile.AuthConfigs[serverAddress] = authconfig 116 117 serverResp, err := cli.call("POST", "/auth", cli.configFile.AuthConfigs[serverAddress], nil) 118 if serverResp.statusCode == 401 { 119 delete(cli.configFile.AuthConfigs, serverAddress) 120 if err2 := cli.configFile.Save(); err2 != nil { 121 fmt.Fprintf(cli.out, "WARNING: could not save config file: %v\n", err2) 122 } 123 return err 124 } 125 if err != nil { 126 return err 127 } 128 129 defer serverResp.body.Close() 130 131 var response types.AuthResponse 132 if err := json.NewDecoder(serverResp.body).Decode(&response); err != nil { 133 // Upon error, remove entry 134 delete(cli.configFile.AuthConfigs, serverAddress) 135 return err 136 } 137 138 if err := cli.configFile.Save(); err != nil { 139 return fmt.Errorf("Error saving config file: %v", err) 140 } 141 fmt.Fprintf(cli.out, "WARNING: login credentials saved in %s\n", cli.configFile.Filename()) 142 143 if response.Status != "" { 144 fmt.Fprintf(cli.out, "%s\n", response.Status) 145 } 146 return nil 147 }