github.com/jiasir/docker@v1.3.3-0.20170609024000-252e610103e7/daemon/cluster/convert/container.go (about)

     1  package convert
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/Sirupsen/logrus"
     9  	container "github.com/docker/docker/api/types/container"
    10  	mounttypes "github.com/docker/docker/api/types/mount"
    11  	types "github.com/docker/docker/api/types/swarm"
    12  	swarmapi "github.com/docker/swarmkit/api"
    13  	gogotypes "github.com/gogo/protobuf/types"
    14  )
    15  
    16  func containerSpecFromGRPC(c *swarmapi.ContainerSpec) types.ContainerSpec {
    17  	containerSpec := types.ContainerSpec{
    18  		Image:      c.Image,
    19  		Labels:     c.Labels,
    20  		Command:    c.Command,
    21  		Args:       c.Args,
    22  		Hostname:   c.Hostname,
    23  		Env:        c.Env,
    24  		Dir:        c.Dir,
    25  		User:       c.User,
    26  		Groups:     c.Groups,
    27  		StopSignal: c.StopSignal,
    28  		TTY:        c.TTY,
    29  		OpenStdin:  c.OpenStdin,
    30  		ReadOnly:   c.ReadOnly,
    31  		Hosts:      c.Hosts,
    32  		Secrets:    secretReferencesFromGRPC(c.Secrets),
    33  		Configs:    configReferencesFromGRPC(c.Configs),
    34  	}
    35  
    36  	if c.DNSConfig != nil {
    37  		containerSpec.DNSConfig = &types.DNSConfig{
    38  			Nameservers: c.DNSConfig.Nameservers,
    39  			Search:      c.DNSConfig.Search,
    40  			Options:     c.DNSConfig.Options,
    41  		}
    42  	}
    43  
    44  	// Privileges
    45  	if c.Privileges != nil {
    46  		containerSpec.Privileges = &types.Privileges{}
    47  
    48  		if c.Privileges.CredentialSpec != nil {
    49  			containerSpec.Privileges.CredentialSpec = &types.CredentialSpec{}
    50  			switch c.Privileges.CredentialSpec.Source.(type) {
    51  			case *swarmapi.Privileges_CredentialSpec_File:
    52  				containerSpec.Privileges.CredentialSpec.File = c.Privileges.CredentialSpec.GetFile()
    53  			case *swarmapi.Privileges_CredentialSpec_Registry:
    54  				containerSpec.Privileges.CredentialSpec.Registry = c.Privileges.CredentialSpec.GetRegistry()
    55  			}
    56  		}
    57  
    58  		if c.Privileges.SELinuxContext != nil {
    59  			containerSpec.Privileges.SELinuxContext = &types.SELinuxContext{
    60  				Disable: c.Privileges.SELinuxContext.Disable,
    61  				User:    c.Privileges.SELinuxContext.User,
    62  				Type:    c.Privileges.SELinuxContext.Type,
    63  				Role:    c.Privileges.SELinuxContext.Role,
    64  				Level:   c.Privileges.SELinuxContext.Level,
    65  			}
    66  		}
    67  	}
    68  
    69  	// Mounts
    70  	for _, m := range c.Mounts {
    71  		mount := mounttypes.Mount{
    72  			Target:   m.Target,
    73  			Source:   m.Source,
    74  			Type:     mounttypes.Type(strings.ToLower(swarmapi.Mount_MountType_name[int32(m.Type)])),
    75  			ReadOnly: m.ReadOnly,
    76  		}
    77  
    78  		if m.BindOptions != nil {
    79  			mount.BindOptions = &mounttypes.BindOptions{
    80  				Propagation: mounttypes.Propagation(strings.ToLower(swarmapi.Mount_BindOptions_MountPropagation_name[int32(m.BindOptions.Propagation)])),
    81  			}
    82  		}
    83  
    84  		if m.VolumeOptions != nil {
    85  			mount.VolumeOptions = &mounttypes.VolumeOptions{
    86  				NoCopy: m.VolumeOptions.NoCopy,
    87  				Labels: m.VolumeOptions.Labels,
    88  			}
    89  			if m.VolumeOptions.DriverConfig != nil {
    90  				mount.VolumeOptions.DriverConfig = &mounttypes.Driver{
    91  					Name:    m.VolumeOptions.DriverConfig.Name,
    92  					Options: m.VolumeOptions.DriverConfig.Options,
    93  				}
    94  			}
    95  		}
    96  
    97  		if m.TmpfsOptions != nil {
    98  			mount.TmpfsOptions = &mounttypes.TmpfsOptions{
    99  				SizeBytes: m.TmpfsOptions.SizeBytes,
   100  				Mode:      m.TmpfsOptions.Mode,
   101  			}
   102  		}
   103  		containerSpec.Mounts = append(containerSpec.Mounts, mount)
   104  	}
   105  
   106  	if c.StopGracePeriod != nil {
   107  		grace, _ := gogotypes.DurationFromProto(c.StopGracePeriod)
   108  		containerSpec.StopGracePeriod = &grace
   109  	}
   110  
   111  	if c.Healthcheck != nil {
   112  		containerSpec.Healthcheck = healthConfigFromGRPC(c.Healthcheck)
   113  	}
   114  
   115  	return containerSpec
   116  }
   117  
   118  func secretReferencesToGRPC(sr []*types.SecretReference) []*swarmapi.SecretReference {
   119  	refs := make([]*swarmapi.SecretReference, 0, len(sr))
   120  	for _, s := range sr {
   121  		ref := &swarmapi.SecretReference{
   122  			SecretID:   s.SecretID,
   123  			SecretName: s.SecretName,
   124  		}
   125  		if s.File != nil {
   126  			ref.Target = &swarmapi.SecretReference_File{
   127  				File: &swarmapi.FileTarget{
   128  					Name: s.File.Name,
   129  					UID:  s.File.UID,
   130  					GID:  s.File.GID,
   131  					Mode: s.File.Mode,
   132  				},
   133  			}
   134  		}
   135  
   136  		refs = append(refs, ref)
   137  	}
   138  
   139  	return refs
   140  }
   141  
   142  func secretReferencesFromGRPC(sr []*swarmapi.SecretReference) []*types.SecretReference {
   143  	refs := make([]*types.SecretReference, 0, len(sr))
   144  	for _, s := range sr {
   145  		target := s.GetFile()
   146  		if target == nil {
   147  			// not a file target
   148  			logrus.Warnf("secret target not a file: secret=%s", s.SecretID)
   149  			continue
   150  		}
   151  		refs = append(refs, &types.SecretReference{
   152  			File: &types.SecretReferenceFileTarget{
   153  				Name: target.Name,
   154  				UID:  target.UID,
   155  				GID:  target.GID,
   156  				Mode: target.Mode,
   157  			},
   158  			SecretID:   s.SecretID,
   159  			SecretName: s.SecretName,
   160  		})
   161  	}
   162  
   163  	return refs
   164  }
   165  
   166  func configReferencesToGRPC(sr []*types.ConfigReference) []*swarmapi.ConfigReference {
   167  	refs := make([]*swarmapi.ConfigReference, 0, len(sr))
   168  	for _, s := range sr {
   169  		ref := &swarmapi.ConfigReference{
   170  			ConfigID:   s.ConfigID,
   171  			ConfigName: s.ConfigName,
   172  		}
   173  		if s.File != nil {
   174  			ref.Target = &swarmapi.ConfigReference_File{
   175  				File: &swarmapi.FileTarget{
   176  					Name: s.File.Name,
   177  					UID:  s.File.UID,
   178  					GID:  s.File.GID,
   179  					Mode: s.File.Mode,
   180  				},
   181  			}
   182  		}
   183  
   184  		refs = append(refs, ref)
   185  	}
   186  
   187  	return refs
   188  }
   189  
   190  func configReferencesFromGRPC(sr []*swarmapi.ConfigReference) []*types.ConfigReference {
   191  	refs := make([]*types.ConfigReference, 0, len(sr))
   192  	for _, s := range sr {
   193  		target := s.GetFile()
   194  		if target == nil {
   195  			// not a file target
   196  			logrus.Warnf("config target not a file: config=%s", s.ConfigID)
   197  			continue
   198  		}
   199  		refs = append(refs, &types.ConfigReference{
   200  			File: &types.ConfigReferenceFileTarget{
   201  				Name: target.Name,
   202  				UID:  target.UID,
   203  				GID:  target.GID,
   204  				Mode: target.Mode,
   205  			},
   206  			ConfigID:   s.ConfigID,
   207  			ConfigName: s.ConfigName,
   208  		})
   209  	}
   210  
   211  	return refs
   212  }
   213  
   214  func containerToGRPC(c types.ContainerSpec) (*swarmapi.ContainerSpec, error) {
   215  	containerSpec := &swarmapi.ContainerSpec{
   216  		Image:      c.Image,
   217  		Labels:     c.Labels,
   218  		Command:    c.Command,
   219  		Args:       c.Args,
   220  		Hostname:   c.Hostname,
   221  		Env:        c.Env,
   222  		Dir:        c.Dir,
   223  		User:       c.User,
   224  		Groups:     c.Groups,
   225  		StopSignal: c.StopSignal,
   226  		TTY:        c.TTY,
   227  		OpenStdin:  c.OpenStdin,
   228  		ReadOnly:   c.ReadOnly,
   229  		Hosts:      c.Hosts,
   230  		Secrets:    secretReferencesToGRPC(c.Secrets),
   231  		Configs:    configReferencesToGRPC(c.Configs),
   232  	}
   233  
   234  	if c.DNSConfig != nil {
   235  		containerSpec.DNSConfig = &swarmapi.ContainerSpec_DNSConfig{
   236  			Nameservers: c.DNSConfig.Nameservers,
   237  			Search:      c.DNSConfig.Search,
   238  			Options:     c.DNSConfig.Options,
   239  		}
   240  	}
   241  
   242  	if c.StopGracePeriod != nil {
   243  		containerSpec.StopGracePeriod = gogotypes.DurationProto(*c.StopGracePeriod)
   244  	}
   245  
   246  	// Privileges
   247  	if c.Privileges != nil {
   248  		containerSpec.Privileges = &swarmapi.Privileges{}
   249  
   250  		if c.Privileges.CredentialSpec != nil {
   251  			containerSpec.Privileges.CredentialSpec = &swarmapi.Privileges_CredentialSpec{}
   252  
   253  			if c.Privileges.CredentialSpec.File != "" && c.Privileges.CredentialSpec.Registry != "" {
   254  				return nil, errors.New("cannot specify both \"file\" and \"registry\" credential specs")
   255  			}
   256  			if c.Privileges.CredentialSpec.File != "" {
   257  				containerSpec.Privileges.CredentialSpec.Source = &swarmapi.Privileges_CredentialSpec_File{
   258  					File: c.Privileges.CredentialSpec.File,
   259  				}
   260  			} else if c.Privileges.CredentialSpec.Registry != "" {
   261  				containerSpec.Privileges.CredentialSpec.Source = &swarmapi.Privileges_CredentialSpec_Registry{
   262  					Registry: c.Privileges.CredentialSpec.Registry,
   263  				}
   264  			} else {
   265  				return nil, errors.New("must either provide \"file\" or \"registry\" for credential spec")
   266  			}
   267  		}
   268  
   269  		if c.Privileges.SELinuxContext != nil {
   270  			containerSpec.Privileges.SELinuxContext = &swarmapi.Privileges_SELinuxContext{
   271  				Disable: c.Privileges.SELinuxContext.Disable,
   272  				User:    c.Privileges.SELinuxContext.User,
   273  				Type:    c.Privileges.SELinuxContext.Type,
   274  				Role:    c.Privileges.SELinuxContext.Role,
   275  				Level:   c.Privileges.SELinuxContext.Level,
   276  			}
   277  		}
   278  	}
   279  
   280  	// Mounts
   281  	for _, m := range c.Mounts {
   282  		mount := swarmapi.Mount{
   283  			Target:   m.Target,
   284  			Source:   m.Source,
   285  			ReadOnly: m.ReadOnly,
   286  		}
   287  
   288  		if mountType, ok := swarmapi.Mount_MountType_value[strings.ToUpper(string(m.Type))]; ok {
   289  			mount.Type = swarmapi.Mount_MountType(mountType)
   290  		} else if string(m.Type) != "" {
   291  			return nil, fmt.Errorf("invalid MountType: %q", m.Type)
   292  		}
   293  
   294  		if m.BindOptions != nil {
   295  			if mountPropagation, ok := swarmapi.Mount_BindOptions_MountPropagation_value[strings.ToUpper(string(m.BindOptions.Propagation))]; ok {
   296  				mount.BindOptions = &swarmapi.Mount_BindOptions{Propagation: swarmapi.Mount_BindOptions_MountPropagation(mountPropagation)}
   297  			} else if string(m.BindOptions.Propagation) != "" {
   298  				return nil, fmt.Errorf("invalid MountPropagation: %q", m.BindOptions.Propagation)
   299  			}
   300  		}
   301  
   302  		if m.VolumeOptions != nil {
   303  			mount.VolumeOptions = &swarmapi.Mount_VolumeOptions{
   304  				NoCopy: m.VolumeOptions.NoCopy,
   305  				Labels: m.VolumeOptions.Labels,
   306  			}
   307  			if m.VolumeOptions.DriverConfig != nil {
   308  				mount.VolumeOptions.DriverConfig = &swarmapi.Driver{
   309  					Name:    m.VolumeOptions.DriverConfig.Name,
   310  					Options: m.VolumeOptions.DriverConfig.Options,
   311  				}
   312  			}
   313  		}
   314  
   315  		if m.TmpfsOptions != nil {
   316  			mount.TmpfsOptions = &swarmapi.Mount_TmpfsOptions{
   317  				SizeBytes: m.TmpfsOptions.SizeBytes,
   318  				Mode:      m.TmpfsOptions.Mode,
   319  			}
   320  		}
   321  
   322  		containerSpec.Mounts = append(containerSpec.Mounts, mount)
   323  	}
   324  
   325  	if c.Healthcheck != nil {
   326  		containerSpec.Healthcheck = healthConfigToGRPC(c.Healthcheck)
   327  	}
   328  
   329  	return containerSpec, nil
   330  }
   331  
   332  func healthConfigFromGRPC(h *swarmapi.HealthConfig) *container.HealthConfig {
   333  	interval, _ := gogotypes.DurationFromProto(h.Interval)
   334  	timeout, _ := gogotypes.DurationFromProto(h.Timeout)
   335  	startPeriod, _ := gogotypes.DurationFromProto(h.StartPeriod)
   336  	return &container.HealthConfig{
   337  		Test:        h.Test,
   338  		Interval:    interval,
   339  		Timeout:     timeout,
   340  		Retries:     int(h.Retries),
   341  		StartPeriod: startPeriod,
   342  	}
   343  }
   344  
   345  func healthConfigToGRPC(h *container.HealthConfig) *swarmapi.HealthConfig {
   346  	return &swarmapi.HealthConfig{
   347  		Test:        h.Test,
   348  		Interval:    gogotypes.DurationProto(h.Interval),
   349  		Timeout:     gogotypes.DurationProto(h.Timeout),
   350  		Retries:     int32(h.Retries),
   351  		StartPeriod: gogotypes.DurationProto(h.StartPeriod),
   352  	}
   353  }