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