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 }