github.com/fabiokung/docker@v0.11.2-0.20170222101415-4534dcd49497/cli/compose/convert/compose.go (about) 1 package convert 2 3 import ( 4 "io/ioutil" 5 6 "github.com/docker/docker/api/types" 7 networktypes "github.com/docker/docker/api/types/network" 8 "github.com/docker/docker/api/types/swarm" 9 composetypes "github.com/docker/docker/cli/compose/types" 10 ) 11 12 const ( 13 // LabelNamespace is the label used to track stack resources 14 LabelNamespace = "com.docker.stack.namespace" 15 ) 16 17 // Namespace mangles names by prepending the name 18 type Namespace struct { 19 name string 20 } 21 22 // Scope prepends the namespace to a name 23 func (n Namespace) Scope(name string) string { 24 return n.name + "_" + name 25 } 26 27 // Name returns the name of the namespace 28 func (n Namespace) Name() string { 29 return n.name 30 } 31 32 // NewNamespace returns a new Namespace for scoping of names 33 func NewNamespace(name string) Namespace { 34 return Namespace{name: name} 35 } 36 37 // AddStackLabel returns labels with the namespace label added 38 func AddStackLabel(namespace Namespace, labels map[string]string) map[string]string { 39 if labels == nil { 40 labels = make(map[string]string) 41 } 42 labels[LabelNamespace] = namespace.name 43 return labels 44 } 45 46 type networkMap map[string]composetypes.NetworkConfig 47 48 // Networks from the compose-file type to the engine API type 49 func Networks(namespace Namespace, networks networkMap, servicesNetworks map[string]struct{}) (map[string]types.NetworkCreate, []string) { 50 if networks == nil { 51 networks = make(map[string]composetypes.NetworkConfig) 52 } 53 54 externalNetworks := []string{} 55 result := make(map[string]types.NetworkCreate) 56 for internalName := range servicesNetworks { 57 network := networks[internalName] 58 if network.External.External { 59 externalNetworks = append(externalNetworks, network.External.Name) 60 continue 61 } 62 63 createOpts := types.NetworkCreate{ 64 Labels: AddStackLabel(namespace, network.Labels), 65 Driver: network.Driver, 66 Options: network.DriverOpts, 67 Internal: network.Internal, 68 Attachable: network.Attachable, 69 } 70 71 if network.Ipam.Driver != "" || len(network.Ipam.Config) > 0 { 72 createOpts.IPAM = &networktypes.IPAM{} 73 } 74 75 if network.Ipam.Driver != "" { 76 createOpts.IPAM.Driver = network.Ipam.Driver 77 } 78 for _, ipamConfig := range network.Ipam.Config { 79 config := networktypes.IPAMConfig{ 80 Subnet: ipamConfig.Subnet, 81 } 82 createOpts.IPAM.Config = append(createOpts.IPAM.Config, config) 83 } 84 result[internalName] = createOpts 85 } 86 87 return result, externalNetworks 88 } 89 90 // Secrets converts secrets from the Compose type to the engine API type 91 func Secrets(namespace Namespace, secrets map[string]composetypes.SecretConfig) ([]swarm.SecretSpec, error) { 92 result := []swarm.SecretSpec{} 93 for name, secret := range secrets { 94 if secret.External.External { 95 continue 96 } 97 98 data, err := ioutil.ReadFile(secret.File) 99 if err != nil { 100 return nil, err 101 } 102 103 result = append(result, swarm.SecretSpec{ 104 Annotations: swarm.Annotations{ 105 Name: namespace.Scope(name), 106 Labels: AddStackLabel(namespace, secret.Labels), 107 }, 108 Data: data, 109 }) 110 } 111 return result, nil 112 }