utils.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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. indexServer := registry.GetAuthConfigKey(index)
  34. authConfig, err := cli.configureAuth("", "", "", indexServer)
  35. if err != nil {
  36. return "", err
  37. }
  38. return encodeAuthToBase64(authConfig)
  39. }
  40. }
  41. func (cli *DockerCli) resizeTty(id string, isExec bool) {
  42. height, width := cli.getTtySize()
  43. if height == 0 && width == 0 {
  44. return
  45. }
  46. options := types.ResizeOptions{
  47. ID: id,
  48. Height: height,
  49. Width: width,
  50. }
  51. var err error
  52. if isExec {
  53. err = cli.client.ContainerExecResize(options)
  54. } else {
  55. err = cli.client.ContainerResize(options)
  56. }
  57. if err != nil {
  58. logrus.Debugf("Error resize: %s", err)
  59. }
  60. }
  61. // getExitCode perform an inspect on the container. It returns
  62. // the running state and the exit code.
  63. func getExitCode(cli *DockerCli, containerID string) (bool, int, error) {
  64. c, err := cli.client.ContainerInspect(containerID)
  65. if err != nil {
  66. // If we can't connect, then the daemon probably died.
  67. if err != client.ErrConnectionFailed {
  68. return false, -1, err
  69. }
  70. return false, -1, nil
  71. }
  72. return c.State.Running, c.State.ExitCode, nil
  73. }
  74. // getExecExitCode perform an inspect on the exec command. It returns
  75. // the running state and the exit code.
  76. func getExecExitCode(cli *DockerCli, execID string) (bool, int, error) {
  77. resp, err := cli.client.ContainerExecInspect(execID)
  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. return resp.Running, resp.ExitCode, nil
  86. }
  87. func (cli *DockerCli) monitorTtySize(id string, isExec bool) error {
  88. cli.resizeTty(id, isExec)
  89. if runtime.GOOS == "windows" {
  90. go func() {
  91. prevH, prevW := cli.getTtySize()
  92. for {
  93. time.Sleep(time.Millisecond * 250)
  94. h, w := cli.getTtySize()
  95. if prevW != w || prevH != h {
  96. cli.resizeTty(id, isExec)
  97. }
  98. prevH = h
  99. prevW = w
  100. }
  101. }()
  102. } else {
  103. sigchan := make(chan os.Signal, 1)
  104. gosignal.Notify(sigchan, signal.SIGWINCH)
  105. go func() {
  106. for range sigchan {
  107. cli.resizeTty(id, isExec)
  108. }
  109. }()
  110. }
  111. return nil
  112. }
  113. func (cli *DockerCli) getTtySize() (int, int) {
  114. if !cli.isTerminalOut {
  115. return 0, 0
  116. }
  117. ws, err := term.GetWinsize(cli.outFd)
  118. if err != nil {
  119. logrus.Debugf("Error getting size: %s", err)
  120. if ws == nil {
  121. return 0, 0
  122. }
  123. }
  124. return int(ws.Height), int(ws.Width)
  125. }