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  }