service.go 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. package convert
  2. import (
  3. "fmt"
  4. "strings"
  5. "github.com/docker/docker/pkg/namesgenerator"
  6. types "github.com/docker/engine-api/types/swarm"
  7. swarmapi "github.com/docker/swarmkit/api"
  8. "github.com/docker/swarmkit/protobuf/ptypes"
  9. )
  10. // ServiceFromGRPC converts a grpc Service to a Service.
  11. func ServiceFromGRPC(s swarmapi.Service) types.Service {
  12. spec := s.Spec
  13. containerConfig := spec.Task.Runtime.(*swarmapi.TaskSpec_Container).Container
  14. networks := make([]types.NetworkAttachmentConfig, 0, len(spec.Networks))
  15. for _, n := range spec.Networks {
  16. networks = append(networks, types.NetworkAttachmentConfig{Target: n.Target, Aliases: n.Aliases})
  17. }
  18. service := types.Service{
  19. ID: s.ID,
  20. Spec: types.ServiceSpec{
  21. TaskTemplate: types.TaskSpec{
  22. ContainerSpec: containerSpecFromGRPC(containerConfig),
  23. Resources: resourcesFromGRPC(s.Spec.Task.Resources),
  24. RestartPolicy: restartPolicyFromGRPC(s.Spec.Task.Restart),
  25. Placement: placementFromGRPC(s.Spec.Task.Placement),
  26. LogDriver: driverFromGRPC(s.Spec.Task.LogDriver),
  27. },
  28. Networks: networks,
  29. EndpointSpec: endpointSpecFromGRPC(s.Spec.Endpoint),
  30. },
  31. Endpoint: endpointFromGRPC(s.Endpoint),
  32. }
  33. // Meta
  34. service.Version.Index = s.Meta.Version.Index
  35. service.CreatedAt, _ = ptypes.Timestamp(s.Meta.CreatedAt)
  36. service.UpdatedAt, _ = ptypes.Timestamp(s.Meta.UpdatedAt)
  37. // Annotations
  38. service.Spec.Name = s.Spec.Annotations.Name
  39. service.Spec.Labels = s.Spec.Annotations.Labels
  40. // UpdateConfig
  41. if s.Spec.Update != nil {
  42. service.Spec.UpdateConfig = &types.UpdateConfig{
  43. Parallelism: s.Spec.Update.Parallelism,
  44. }
  45. service.Spec.UpdateConfig.Delay, _ = ptypes.Duration(&s.Spec.Update.Delay)
  46. switch s.Spec.Update.FailureAction {
  47. case swarmapi.UpdateConfig_PAUSE:
  48. service.Spec.UpdateConfig.FailureAction = types.UpdateFailureActionPause
  49. case swarmapi.UpdateConfig_CONTINUE:
  50. service.Spec.UpdateConfig.FailureAction = types.UpdateFailureActionContinue
  51. }
  52. }
  53. // Mode
  54. switch t := s.Spec.GetMode().(type) {
  55. case *swarmapi.ServiceSpec_Global:
  56. service.Spec.Mode.Global = &types.GlobalService{}
  57. case *swarmapi.ServiceSpec_Replicated:
  58. service.Spec.Mode.Replicated = &types.ReplicatedService{
  59. Replicas: &t.Replicated.Replicas,
  60. }
  61. }
  62. // UpdateStatus
  63. service.UpdateStatus = types.UpdateStatus{}
  64. if s.UpdateStatus != nil {
  65. switch s.UpdateStatus.State {
  66. case swarmapi.UpdateStatus_UPDATING:
  67. service.UpdateStatus.State = types.UpdateStateUpdating
  68. case swarmapi.UpdateStatus_PAUSED:
  69. service.UpdateStatus.State = types.UpdateStatePaused
  70. case swarmapi.UpdateStatus_COMPLETED:
  71. service.UpdateStatus.State = types.UpdateStateCompleted
  72. }
  73. service.UpdateStatus.StartedAt, _ = ptypes.Timestamp(s.UpdateStatus.StartedAt)
  74. service.UpdateStatus.CompletedAt, _ = ptypes.Timestamp(s.UpdateStatus.CompletedAt)
  75. service.UpdateStatus.Message = s.UpdateStatus.Message
  76. }
  77. return service
  78. }
  79. // ServiceSpecToGRPC converts a ServiceSpec to a grpc ServiceSpec.
  80. func ServiceSpecToGRPC(s types.ServiceSpec) (swarmapi.ServiceSpec, error) {
  81. name := s.Name
  82. if name == "" {
  83. name = namesgenerator.GetRandomName(0)
  84. }
  85. networks := make([]*swarmapi.ServiceSpec_NetworkAttachmentConfig, 0, len(s.Networks))
  86. for _, n := range s.Networks {
  87. networks = append(networks, &swarmapi.ServiceSpec_NetworkAttachmentConfig{Target: n.Target, Aliases: n.Aliases})
  88. }
  89. spec := swarmapi.ServiceSpec{
  90. Annotations: swarmapi.Annotations{
  91. Name: name,
  92. Labels: s.Labels,
  93. },
  94. Task: swarmapi.TaskSpec{
  95. Resources: resourcesToGRPC(s.TaskTemplate.Resources),
  96. LogDriver: driverToGRPC(s.TaskTemplate.LogDriver),
  97. },
  98. Networks: networks,
  99. }
  100. containerSpec, err := containerToGRPC(s.TaskTemplate.ContainerSpec)
  101. if err != nil {
  102. return swarmapi.ServiceSpec{}, err
  103. }
  104. spec.Task.Runtime = &swarmapi.TaskSpec_Container{Container: containerSpec}
  105. restartPolicy, err := restartPolicyToGRPC(s.TaskTemplate.RestartPolicy)
  106. if err != nil {
  107. return swarmapi.ServiceSpec{}, err
  108. }
  109. spec.Task.Restart = restartPolicy
  110. if s.TaskTemplate.Placement != nil {
  111. spec.Task.Placement = &swarmapi.Placement{
  112. Constraints: s.TaskTemplate.Placement.Constraints,
  113. }
  114. }
  115. if s.UpdateConfig != nil {
  116. var failureAction swarmapi.UpdateConfig_FailureAction
  117. switch s.UpdateConfig.FailureAction {
  118. case types.UpdateFailureActionPause, "":
  119. failureAction = swarmapi.UpdateConfig_PAUSE
  120. case types.UpdateFailureActionContinue:
  121. failureAction = swarmapi.UpdateConfig_CONTINUE
  122. default:
  123. return swarmapi.ServiceSpec{}, fmt.Errorf("unrecongized update failure action %s", s.UpdateConfig.FailureAction)
  124. }
  125. spec.Update = &swarmapi.UpdateConfig{
  126. Parallelism: s.UpdateConfig.Parallelism,
  127. Delay: *ptypes.DurationProto(s.UpdateConfig.Delay),
  128. FailureAction: failureAction,
  129. }
  130. }
  131. if s.EndpointSpec != nil {
  132. if s.EndpointSpec.Mode != "" &&
  133. s.EndpointSpec.Mode != types.ResolutionModeVIP &&
  134. s.EndpointSpec.Mode != types.ResolutionModeDNSRR {
  135. return swarmapi.ServiceSpec{}, fmt.Errorf("invalid resolution mode: %q", s.EndpointSpec.Mode)
  136. }
  137. spec.Endpoint = &swarmapi.EndpointSpec{}
  138. spec.Endpoint.Mode = swarmapi.EndpointSpec_ResolutionMode(swarmapi.EndpointSpec_ResolutionMode_value[strings.ToUpper(string(s.EndpointSpec.Mode))])
  139. for _, portConfig := range s.EndpointSpec.Ports {
  140. spec.Endpoint.Ports = append(spec.Endpoint.Ports, &swarmapi.PortConfig{
  141. Name: portConfig.Name,
  142. Protocol: swarmapi.PortConfig_Protocol(swarmapi.PortConfig_Protocol_value[strings.ToUpper(string(portConfig.Protocol))]),
  143. TargetPort: portConfig.TargetPort,
  144. PublishedPort: portConfig.PublishedPort,
  145. })
  146. }
  147. }
  148. //Mode
  149. if s.Mode.Global != nil {
  150. spec.Mode = &swarmapi.ServiceSpec_Global{
  151. Global: &swarmapi.GlobalService{},
  152. }
  153. } else if s.Mode.Replicated != nil && s.Mode.Replicated.Replicas != nil {
  154. spec.Mode = &swarmapi.ServiceSpec_Replicated{
  155. Replicated: &swarmapi.ReplicatedService{Replicas: *s.Mode.Replicated.Replicas},
  156. }
  157. } else {
  158. spec.Mode = &swarmapi.ServiceSpec_Replicated{
  159. Replicated: &swarmapi.ReplicatedService{Replicas: 1},
  160. }
  161. }
  162. return spec, nil
  163. }
  164. func resourcesFromGRPC(res *swarmapi.ResourceRequirements) *types.ResourceRequirements {
  165. var resources *types.ResourceRequirements
  166. if res != nil {
  167. resources = &types.ResourceRequirements{}
  168. if res.Limits != nil {
  169. resources.Limits = &types.Resources{
  170. NanoCPUs: res.Limits.NanoCPUs,
  171. MemoryBytes: res.Limits.MemoryBytes,
  172. }
  173. }
  174. if res.Reservations != nil {
  175. resources.Reservations = &types.Resources{
  176. NanoCPUs: res.Reservations.NanoCPUs,
  177. MemoryBytes: res.Reservations.MemoryBytes,
  178. }
  179. }
  180. }
  181. return resources
  182. }
  183. func resourcesToGRPC(res *types.ResourceRequirements) *swarmapi.ResourceRequirements {
  184. var reqs *swarmapi.ResourceRequirements
  185. if res != nil {
  186. reqs = &swarmapi.ResourceRequirements{}
  187. if res.Limits != nil {
  188. reqs.Limits = &swarmapi.Resources{
  189. NanoCPUs: res.Limits.NanoCPUs,
  190. MemoryBytes: res.Limits.MemoryBytes,
  191. }
  192. }
  193. if res.Reservations != nil {
  194. reqs.Reservations = &swarmapi.Resources{
  195. NanoCPUs: res.Reservations.NanoCPUs,
  196. MemoryBytes: res.Reservations.MemoryBytes,
  197. }
  198. }
  199. }
  200. return reqs
  201. }
  202. func restartPolicyFromGRPC(p *swarmapi.RestartPolicy) *types.RestartPolicy {
  203. var rp *types.RestartPolicy
  204. if p != nil {
  205. rp = &types.RestartPolicy{}
  206. rp.Condition = types.RestartPolicyCondition(strings.ToLower(p.Condition.String()))
  207. if p.Delay != nil {
  208. delay, _ := ptypes.Duration(p.Delay)
  209. rp.Delay = &delay
  210. }
  211. if p.Window != nil {
  212. window, _ := ptypes.Duration(p.Window)
  213. rp.Window = &window
  214. }
  215. rp.MaxAttempts = &p.MaxAttempts
  216. }
  217. return rp
  218. }
  219. func restartPolicyToGRPC(p *types.RestartPolicy) (*swarmapi.RestartPolicy, error) {
  220. var rp *swarmapi.RestartPolicy
  221. if p != nil {
  222. rp = &swarmapi.RestartPolicy{}
  223. sanatizedCondition := strings.ToUpper(strings.Replace(string(p.Condition), "-", "_", -1))
  224. if condition, ok := swarmapi.RestartPolicy_RestartCondition_value[sanatizedCondition]; ok {
  225. rp.Condition = swarmapi.RestartPolicy_RestartCondition(condition)
  226. } else if string(p.Condition) == "" {
  227. rp.Condition = swarmapi.RestartOnAny
  228. } else {
  229. return nil, fmt.Errorf("invalid RestartCondition: %q", p.Condition)
  230. }
  231. if p.Delay != nil {
  232. rp.Delay = ptypes.DurationProto(*p.Delay)
  233. }
  234. if p.Window != nil {
  235. rp.Window = ptypes.DurationProto(*p.Window)
  236. }
  237. if p.MaxAttempts != nil {
  238. rp.MaxAttempts = *p.MaxAttempts
  239. }
  240. }
  241. return rp, nil
  242. }
  243. func placementFromGRPC(p *swarmapi.Placement) *types.Placement {
  244. var r *types.Placement
  245. if p != nil {
  246. r = &types.Placement{}
  247. r.Constraints = p.Constraints
  248. }
  249. return r
  250. }
  251. func driverFromGRPC(p *swarmapi.Driver) *types.Driver {
  252. if p == nil {
  253. return nil
  254. }
  255. return &types.Driver{
  256. Name: p.Name,
  257. Options: p.Options,
  258. }
  259. }
  260. func driverToGRPC(p *types.Driver) *swarmapi.Driver {
  261. if p == nil {
  262. return nil
  263. }
  264. return &swarmapi.Driver{
  265. Name: p.Name,
  266. Options: p.Options,
  267. }
  268. }