github.com/olljanat/moby@v1.13.1/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 converts networks from the compose-file type to the engine API type
    49  func Networks(
    50  	namespace Namespace,
    51  	networks networkMap,
    52  	servicesNetworks map[string]struct{},
    53  ) (map[string]types.NetworkCreate, []string) {
    54  	if networks == nil {
    55  		networks = make(map[string]composetypes.NetworkConfig)
    56  	}
    57  
    58  	externalNetworks := []string{}
    59  	result := make(map[string]types.NetworkCreate)
    60  
    61  	for internalName := range servicesNetworks {
    62  		network := networks[internalName]
    63  		if network.External.External {
    64  			externalNetworks = append(externalNetworks, network.External.Name)
    65  			continue
    66  		}
    67  
    68  		createOpts := types.NetworkCreate{
    69  			Labels:   AddStackLabel(namespace, network.Labels),
    70  			Driver:   network.Driver,
    71  			Options:  network.DriverOpts,
    72  			Internal: network.Internal,
    73  		}
    74  
    75  		if network.Ipam.Driver != "" || len(network.Ipam.Config) > 0 {
    76  			createOpts.IPAM = &networktypes.IPAM{}
    77  		}
    78  
    79  		if network.Ipam.Driver != "" {
    80  			createOpts.IPAM.Driver = network.Ipam.Driver
    81  		}
    82  		for _, ipamConfig := range network.Ipam.Config {
    83  			config := networktypes.IPAMConfig{
    84  				Subnet: ipamConfig.Subnet,
    85  			}
    86  			createOpts.IPAM.Config = append(createOpts.IPAM.Config, config)
    87  		}
    88  		result[internalName] = createOpts
    89  	}
    90  
    91  	return result, externalNetworks
    92  }
    93  
    94  // Secrets converts secrets from the Compose type to the engine API type
    95  func Secrets(namespace Namespace, secrets map[string]composetypes.SecretConfig) ([]swarm.SecretSpec, error) {
    96  	result := []swarm.SecretSpec{}
    97  	for name, secret := range secrets {
    98  		if secret.External.External {
    99  			continue
   100  		}
   101  
   102  		data, err := ioutil.ReadFile(secret.File)
   103  		if err != nil {
   104  			return nil, err
   105  		}
   106  
   107  		result = append(result, swarm.SecretSpec{
   108  			Annotations: swarm.Annotations{
   109  				Name:   namespace.Scope(name),
   110  				Labels: AddStackLabel(namespace, secret.Labels),
   111  			},
   112  			Data: data,
   113  		})
   114  	}
   115  	return result, nil
   116  }