github.com/endocode/docker@v1.4.2-0.20160113120958-46eb4700391e/api/client/utils.go (about)

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