container.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. package convert
  2. import (
  3. "fmt"
  4. "strings"
  5. "github.com/Sirupsen/logrus"
  6. container "github.com/docker/docker/api/types/container"
  7. mounttypes "github.com/docker/docker/api/types/mount"
  8. types "github.com/docker/docker/api/types/swarm"
  9. swarmapi "github.com/docker/swarmkit/api"
  10. gogotypes "github.com/gogo/protobuf/types"
  11. )
  12. func containerSpecFromGRPC(c *swarmapi.ContainerSpec) types.ContainerSpec {
  13. containerSpec := types.ContainerSpec{
  14. Image: c.Image,
  15. Labels: c.Labels,
  16. Command: c.Command,
  17. Args: c.Args,
  18. Hostname: c.Hostname,
  19. Env: c.Env,
  20. Dir: c.Dir,
  21. User: c.User,
  22. Groups: c.Groups,
  23. TTY: c.TTY,
  24. OpenStdin: c.OpenStdin,
  25. ReadOnly: c.ReadOnly,
  26. Hosts: c.Hosts,
  27. Secrets: secretReferencesFromGRPC(c.Secrets),
  28. }
  29. if c.DNSConfig != nil {
  30. containerSpec.DNSConfig = &types.DNSConfig{
  31. Nameservers: c.DNSConfig.Nameservers,
  32. Search: c.DNSConfig.Search,
  33. Options: c.DNSConfig.Options,
  34. }
  35. }
  36. // Mounts
  37. for _, m := range c.Mounts {
  38. mount := mounttypes.Mount{
  39. Target: m.Target,
  40. Source: m.Source,
  41. Type: mounttypes.Type(strings.ToLower(swarmapi.Mount_MountType_name[int32(m.Type)])),
  42. ReadOnly: m.ReadOnly,
  43. }
  44. if m.BindOptions != nil {
  45. mount.BindOptions = &mounttypes.BindOptions{
  46. Propagation: mounttypes.Propagation(strings.ToLower(swarmapi.Mount_BindOptions_MountPropagation_name[int32(m.BindOptions.Propagation)])),
  47. }
  48. }
  49. if m.VolumeOptions != nil {
  50. mount.VolumeOptions = &mounttypes.VolumeOptions{
  51. NoCopy: m.VolumeOptions.NoCopy,
  52. Labels: m.VolumeOptions.Labels,
  53. }
  54. if m.VolumeOptions.DriverConfig != nil {
  55. mount.VolumeOptions.DriverConfig = &mounttypes.Driver{
  56. Name: m.VolumeOptions.DriverConfig.Name,
  57. Options: m.VolumeOptions.DriverConfig.Options,
  58. }
  59. }
  60. }
  61. if m.TmpfsOptions != nil {
  62. mount.TmpfsOptions = &mounttypes.TmpfsOptions{
  63. SizeBytes: m.TmpfsOptions.SizeBytes,
  64. Mode: m.TmpfsOptions.Mode,
  65. }
  66. }
  67. containerSpec.Mounts = append(containerSpec.Mounts, mount)
  68. }
  69. if c.StopGracePeriod != nil {
  70. grace, _ := gogotypes.DurationFromProto(c.StopGracePeriod)
  71. containerSpec.StopGracePeriod = &grace
  72. }
  73. if c.Healthcheck != nil {
  74. containerSpec.Healthcheck = healthConfigFromGRPC(c.Healthcheck)
  75. }
  76. return containerSpec
  77. }
  78. func secretReferencesToGRPC(sr []*types.SecretReference) []*swarmapi.SecretReference {
  79. refs := make([]*swarmapi.SecretReference, 0, len(sr))
  80. for _, s := range sr {
  81. ref := &swarmapi.SecretReference{
  82. SecretID: s.SecretID,
  83. SecretName: s.SecretName,
  84. }
  85. if s.File != nil {
  86. ref.Target = &swarmapi.SecretReference_File{
  87. File: &swarmapi.SecretReference_FileTarget{
  88. Name: s.File.Name,
  89. UID: s.File.UID,
  90. GID: s.File.GID,
  91. Mode: s.File.Mode,
  92. },
  93. }
  94. }
  95. refs = append(refs, ref)
  96. }
  97. return refs
  98. }
  99. func secretReferencesFromGRPC(sr []*swarmapi.SecretReference) []*types.SecretReference {
  100. refs := make([]*types.SecretReference, 0, len(sr))
  101. for _, s := range sr {
  102. target := s.GetFile()
  103. if target == nil {
  104. // not a file target
  105. logrus.Warnf("secret target not a file: secret=%s", s.SecretID)
  106. continue
  107. }
  108. refs = append(refs, &types.SecretReference{
  109. File: &types.SecretReferenceFileTarget{
  110. Name: target.Name,
  111. UID: target.UID,
  112. GID: target.GID,
  113. Mode: target.Mode,
  114. },
  115. SecretID: s.SecretID,
  116. SecretName: s.SecretName,
  117. })
  118. }
  119. return refs
  120. }
  121. func containerToGRPC(c types.ContainerSpec) (*swarmapi.ContainerSpec, error) {
  122. containerSpec := &swarmapi.ContainerSpec{
  123. Image: c.Image,
  124. Labels: c.Labels,
  125. Command: c.Command,
  126. Args: c.Args,
  127. Hostname: c.Hostname,
  128. Env: c.Env,
  129. Dir: c.Dir,
  130. User: c.User,
  131. Groups: c.Groups,
  132. TTY: c.TTY,
  133. OpenStdin: c.OpenStdin,
  134. ReadOnly: c.ReadOnly,
  135. Hosts: c.Hosts,
  136. Secrets: secretReferencesToGRPC(c.Secrets),
  137. }
  138. if c.DNSConfig != nil {
  139. containerSpec.DNSConfig = &swarmapi.ContainerSpec_DNSConfig{
  140. Nameservers: c.DNSConfig.Nameservers,
  141. Search: c.DNSConfig.Search,
  142. Options: c.DNSConfig.Options,
  143. }
  144. }
  145. if c.StopGracePeriod != nil {
  146. containerSpec.StopGracePeriod = gogotypes.DurationProto(*c.StopGracePeriod)
  147. }
  148. // Mounts
  149. for _, m := range c.Mounts {
  150. mount := swarmapi.Mount{
  151. Target: m.Target,
  152. Source: m.Source,
  153. ReadOnly: m.ReadOnly,
  154. }
  155. if mountType, ok := swarmapi.Mount_MountType_value[strings.ToUpper(string(m.Type))]; ok {
  156. mount.Type = swarmapi.Mount_MountType(mountType)
  157. } else if string(m.Type) != "" {
  158. return nil, fmt.Errorf("invalid MountType: %q", m.Type)
  159. }
  160. if m.BindOptions != nil {
  161. if mountPropagation, ok := swarmapi.Mount_BindOptions_MountPropagation_value[strings.ToUpper(string(m.BindOptions.Propagation))]; ok {
  162. mount.BindOptions = &swarmapi.Mount_BindOptions{Propagation: swarmapi.Mount_BindOptions_MountPropagation(mountPropagation)}
  163. } else if string(m.BindOptions.Propagation) != "" {
  164. return nil, fmt.Errorf("invalid MountPropagation: %q", m.BindOptions.Propagation)
  165. }
  166. }
  167. if m.VolumeOptions != nil {
  168. mount.VolumeOptions = &swarmapi.Mount_VolumeOptions{
  169. NoCopy: m.VolumeOptions.NoCopy,
  170. Labels: m.VolumeOptions.Labels,
  171. }
  172. if m.VolumeOptions.DriverConfig != nil {
  173. mount.VolumeOptions.DriverConfig = &swarmapi.Driver{
  174. Name: m.VolumeOptions.DriverConfig.Name,
  175. Options: m.VolumeOptions.DriverConfig.Options,
  176. }
  177. }
  178. }
  179. if m.TmpfsOptions != nil {
  180. mount.TmpfsOptions = &swarmapi.Mount_TmpfsOptions{
  181. SizeBytes: m.TmpfsOptions.SizeBytes,
  182. Mode: m.TmpfsOptions.Mode,
  183. }
  184. }
  185. containerSpec.Mounts = append(containerSpec.Mounts, mount)
  186. }
  187. if c.Healthcheck != nil {
  188. containerSpec.Healthcheck = healthConfigToGRPC(c.Healthcheck)
  189. }
  190. return containerSpec, nil
  191. }
  192. func healthConfigFromGRPC(h *swarmapi.HealthConfig) *container.HealthConfig {
  193. interval, _ := gogotypes.DurationFromProto(h.Interval)
  194. timeout, _ := gogotypes.DurationFromProto(h.Timeout)
  195. return &container.HealthConfig{
  196. Test: h.Test,
  197. Interval: interval,
  198. Timeout: timeout,
  199. Retries: int(h.Retries),
  200. }
  201. }
  202. func healthConfigToGRPC(h *container.HealthConfig) *swarmapi.HealthConfig {
  203. return &swarmapi.HealthConfig{
  204. Test: h.Test,
  205. Interval: gogotypes.DurationProto(h.Interval),
  206. Timeout: gogotypes.DurationProto(h.Timeout),
  207. Retries: int32(h.Retries),
  208. }
  209. }