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