utils.go 3.3 KB

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