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  }