github.com/ncdc/docker@v0.10.1-0.20160129113957-6c6729ef5b74/api/client/utils.go (about) 1 package client 2 3 import ( 4 "encoding/base64" 5 "encoding/json" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "os" 10 gosignal "os/signal" 11 "path/filepath" 12 "runtime" 13 "time" 14 15 "github.com/Sirupsen/logrus" 16 "github.com/docker/docker/pkg/signal" 17 "github.com/docker/docker/pkg/term" 18 "github.com/docker/docker/registry" 19 "github.com/docker/engine-api/client" 20 "github.com/docker/engine-api/types" 21 registrytypes "github.com/docker/engine-api/types/registry" 22 ) 23 24 // encodeAuthToBase64 serializes the auth configuration as JSON base64 payload 25 func encodeAuthToBase64(authConfig types.AuthConfig) (string, error) { 26 buf, err := json.Marshal(authConfig) 27 if err != nil { 28 return "", err 29 } 30 return base64.URLEncoding.EncodeToString(buf), nil 31 } 32 33 func (cli *DockerCli) encodeRegistryAuth(index *registrytypes.IndexInfo) (string, error) { 34 authConfig := registry.ResolveAuthConfig(cli.configFile.AuthConfigs, index) 35 return encodeAuthToBase64(authConfig) 36 } 37 38 func (cli *DockerCli) registryAuthenticationPrivilegedFunc(index *registrytypes.IndexInfo, cmdName string) client.RequestPrivilegeFunc { 39 return func() (string, error) { 40 fmt.Fprintf(cli.out, "\nPlease login prior to %s:\n", cmdName) 41 indexServer := registry.GetAuthConfigKey(index) 42 authConfig, err := cli.configureAuth("", "", "", indexServer) 43 if err != nil { 44 return "", err 45 } 46 return encodeAuthToBase64(authConfig) 47 } 48 } 49 50 func (cli *DockerCli) resizeTty(id string, isExec bool) { 51 height, width := cli.getTtySize() 52 if height == 0 && width == 0 { 53 return 54 } 55 56 options := types.ResizeOptions{ 57 ID: id, 58 Height: height, 59 Width: width, 60 } 61 62 var err error 63 if isExec { 64 err = cli.client.ContainerExecResize(options) 65 } else { 66 err = cli.client.ContainerResize(options) 67 } 68 69 if err != nil { 70 logrus.Debugf("Error resize: %s", err) 71 } 72 } 73 74 // getExitCode perform an inspect on the container. It returns 75 // the running state and the exit code. 76 func getExitCode(cli *DockerCli, containerID string) (bool, int, error) { 77 c, err := cli.client.ContainerInspect(containerID) 78 if err != nil { 79 // If we can't connect, then the daemon probably died. 80 if err != client.ErrConnectionFailed { 81 return false, -1, err 82 } 83 return false, -1, nil 84 } 85 86 return c.State.Running, c.State.ExitCode, nil 87 } 88 89 // getExecExitCode perform an inspect on the exec command. It returns 90 // the running state and the exit code. 91 func getExecExitCode(cli *DockerCli, execID string) (bool, int, error) { 92 resp, err := cli.client.ContainerExecInspect(execID) 93 if err != nil { 94 // If we can't connect, then the daemon probably died. 95 if err != client.ErrConnectionFailed { 96 return false, -1, err 97 } 98 return false, -1, nil 99 } 100 101 return resp.Running, resp.ExitCode, nil 102 } 103 104 func (cli *DockerCli) monitorTtySize(id string, isExec bool) error { 105 cli.resizeTty(id, isExec) 106 107 if runtime.GOOS == "windows" { 108 go func() { 109 prevH, prevW := cli.getTtySize() 110 for { 111 time.Sleep(time.Millisecond * 250) 112 h, w := cli.getTtySize() 113 114 if prevW != w || prevH != h { 115 cli.resizeTty(id, isExec) 116 } 117 prevH = h 118 prevW = w 119 } 120 }() 121 } else { 122 sigchan := make(chan os.Signal, 1) 123 gosignal.Notify(sigchan, signal.SIGWINCH) 124 go func() { 125 for range sigchan { 126 cli.resizeTty(id, isExec) 127 } 128 }() 129 } 130 return nil 131 } 132 133 func (cli *DockerCli) getTtySize() (int, int) { 134 if !cli.isTerminalOut { 135 return 0, 0 136 } 137 ws, err := term.GetWinsize(cli.outFd) 138 if err != nil { 139 logrus.Debugf("Error getting size: %s", err) 140 if ws == nil { 141 return 0, 0 142 } 143 } 144 return int(ws.Height), int(ws.Width) 145 } 146 147 func copyToFile(outfile string, r io.Reader) error { 148 tmpFile, err := ioutil.TempFile(filepath.Dir(outfile), ".docker_temp_") 149 if err != nil { 150 return err 151 } 152 153 tmpPath := tmpFile.Name() 154 155 _, err = io.Copy(tmpFile, r) 156 tmpFile.Close() 157 158 if err != nil { 159 os.Remove(tmpPath) 160 return err 161 } 162 163 if err = os.Rename(tmpPath, outfile); err != nil { 164 os.Remove(tmpPath) 165 return err 166 } 167 168 return nil 169 }