convert.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // +build local
  2. /*
  3. Copyright 2020 Docker Compose CLI authors
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.apache.org/licenses/LICENSE-2.0
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. */
  14. package local
  15. import (
  16. "fmt"
  17. "sort"
  18. "strconv"
  19. "strings"
  20. "time"
  21. compose "github.com/compose-spec/compose-go/types"
  22. "github.com/docker/docker/api/types"
  23. "github.com/docker/docker/api/types/container"
  24. "github.com/docker/go-connections/nat"
  25. "github.com/docker/compose-cli/api/containers"
  26. )
  27. func toRuntimeConfig(m *types.ContainerJSON) *containers.RuntimeConfig {
  28. if m.Config == nil {
  29. return nil
  30. }
  31. var env map[string]string
  32. if m.Config.Env != nil {
  33. env = make(map[string]string)
  34. for _, e := range m.Config.Env {
  35. tokens := strings.Split(e, "=")
  36. if len(tokens) != 2 {
  37. continue
  38. }
  39. env[tokens[0]] = tokens[1]
  40. }
  41. }
  42. var labels []string
  43. if m.Config.Labels != nil {
  44. for k, v := range m.Config.Labels {
  45. labels = append(labels, fmt.Sprintf("%s=%s", k, v))
  46. }
  47. }
  48. sort.Strings(labels)
  49. if env == nil &&
  50. labels == nil {
  51. return nil
  52. }
  53. return &containers.RuntimeConfig{
  54. Env: env,
  55. Labels: labels,
  56. }
  57. }
  58. func toHostConfig(m *types.ContainerJSON) *containers.HostConfig {
  59. if m.HostConfig == nil {
  60. return nil
  61. }
  62. return &containers.HostConfig{
  63. AutoRemove: m.HostConfig.AutoRemove,
  64. RestartPolicy: fromRestartPolicyName(m.HostConfig.RestartPolicy.Name),
  65. CPULimit: float64(m.HostConfig.Resources.NanoCPUs) / 1e9,
  66. MemoryLimit: uint64(m.HostConfig.Resources.Memory),
  67. }
  68. }
  69. func toPorts(ports []types.Port) []containers.Port {
  70. result := []containers.Port{}
  71. for _, port := range ports {
  72. result = append(result, containers.Port{
  73. ContainerPort: uint32(port.PrivatePort),
  74. HostPort: uint32(port.PublicPort),
  75. HostIP: port.IP,
  76. Protocol: port.Type,
  77. })
  78. }
  79. return result
  80. }
  81. func toMobyEnv(environment compose.MappingWithEquals) []string {
  82. var env []string
  83. for k, v := range environment {
  84. if v == nil {
  85. env = append(env, k)
  86. } else {
  87. env = append(env, fmt.Sprintf("%s=%s", k, *v))
  88. }
  89. }
  90. return env
  91. }
  92. func toMobyHealthCheck(check *compose.HealthCheckConfig) *container.HealthConfig {
  93. if check == nil {
  94. return nil
  95. }
  96. var (
  97. interval time.Duration
  98. timeout time.Duration
  99. period time.Duration
  100. retries int
  101. )
  102. if check.Interval != nil {
  103. interval = time.Duration(*check.Interval)
  104. }
  105. if check.Timeout != nil {
  106. timeout = time.Duration(*check.Timeout)
  107. }
  108. if check.StartPeriod != nil {
  109. period = time.Duration(*check.StartPeriod)
  110. }
  111. if check.Retries != nil {
  112. retries = int(*check.Retries)
  113. }
  114. return &container.HealthConfig{
  115. Test: check.Test,
  116. Interval: interval,
  117. Timeout: timeout,
  118. StartPeriod: period,
  119. Retries: retries,
  120. }
  121. }
  122. func toSeconds(d *compose.Duration) *int {
  123. if d == nil {
  124. return nil
  125. }
  126. s := int(time.Duration(*d).Seconds())
  127. return &s
  128. }
  129. func fromPorts(ports []containers.Port) (map[nat.Port]struct{}, map[nat.Port][]nat.PortBinding, error) {
  130. var (
  131. exposedPorts = make(map[nat.Port]struct{}, len(ports))
  132. bindings = make(map[nat.Port][]nat.PortBinding)
  133. )
  134. for _, port := range ports {
  135. p, err := nat.NewPort(port.Protocol, strconv.Itoa(int(port.ContainerPort)))
  136. if err != nil {
  137. return nil, nil, err
  138. }
  139. if _, exists := exposedPorts[p]; !exists {
  140. exposedPorts[p] = struct{}{}
  141. }
  142. portBinding := nat.PortBinding{
  143. HostIP: port.HostIP,
  144. HostPort: strconv.Itoa(int(port.HostPort)),
  145. }
  146. bslice, exists := bindings[p]
  147. if !exists {
  148. bslice = []nat.PortBinding{}
  149. }
  150. bindings[p] = append(bslice, portBinding)
  151. }
  152. return exposedPorts, bindings, nil
  153. }
  154. func fromRestartPolicyName(m string) string {
  155. switch m {
  156. case "always":
  157. return containers.RestartPolicyAny
  158. case "on-failure":
  159. return containers.RestartPolicyOnFailure
  160. case "no", "":
  161. fallthrough
  162. default:
  163. return containers.RestartPolicyNone
  164. }
  165. }
  166. func toRestartPolicy(p string) container.RestartPolicy {
  167. switch p {
  168. case containers.RestartPolicyAny:
  169. return container.RestartPolicy{Name: "always"}
  170. case containers.RestartPolicyOnFailure:
  171. return container.RestartPolicy{Name: "on-failure"}
  172. case containers.RestartPolicyNone:
  173. fallthrough
  174. default:
  175. return container.RestartPolicy{Name: "no"}
  176. }
  177. }