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  }