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  }