github.com/m3db/m3@v1.5.0/src/integration/resources/docker/common.go (about)

     1  // Copyright (c) 2020 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package docker
    22  
    23  import (
    24  	"errors"
    25  	"fmt"
    26  
    27  	"github.com/m3db/m3/src/x/instrument"
    28  
    29  	"github.com/ory/dockertest/v3"
    30  	dc "github.com/ory/dockertest/v3/docker"
    31  )
    32  
    33  var (
    34  	networkName = "d-test"
    35  	volumeName  = "d-test"
    36  
    37  	errClosed = errors.New("container has been closed")
    38  )
    39  
    40  // ResourceOptions returns options for creating
    41  // a Resource.
    42  type ResourceOptions struct {
    43  	OverrideDefaults bool
    44  	Source           string
    45  	ContainerName    string
    46  	Image            Image
    47  	PortList         []int
    48  	// Mounts creates mounts in the container that map back to a resource
    49  	// on the host system.
    50  	Mounts []string
    51  	// TmpfsMounts creates mounts to the container's temporary file system
    52  	TmpfsMounts    []string
    53  	InstrumentOpts instrument.Options
    54  }
    55  
    56  // NB: this will fill unset fields with given default values.
    57  func (o ResourceOptions) withDefaults(
    58  	defaultOpts ResourceOptions) ResourceOptions {
    59  	if o.OverrideDefaults {
    60  		return o
    61  	}
    62  
    63  	if len(o.Source) == 0 {
    64  		o.Source = defaultOpts.Source
    65  	}
    66  
    67  	if len(o.ContainerName) == 0 {
    68  		o.ContainerName = defaultOpts.ContainerName
    69  	}
    70  
    71  	if o.Image == (Image{}) {
    72  		o.Image = defaultOpts.Image
    73  	}
    74  
    75  	if len(o.PortList) == 0 {
    76  		o.PortList = defaultOpts.PortList
    77  	}
    78  
    79  	if len(o.TmpfsMounts) == 0 {
    80  		o.TmpfsMounts = defaultOpts.TmpfsMounts
    81  	}
    82  
    83  	if len(o.Mounts) == 0 {
    84  		o.Mounts = defaultOpts.Mounts
    85  	}
    86  
    87  	if o.InstrumentOpts == nil {
    88  		o.InstrumentOpts = defaultOpts.InstrumentOpts
    89  	}
    90  
    91  	return o
    92  }
    93  
    94  func newOptions(name string) *dockertest.RunOptions {
    95  	return &dockertest.RunOptions{
    96  		Name:      name,
    97  		NetworkID: networkName,
    98  	}
    99  }
   100  
   101  func useImage(opts *dockertest.RunOptions, image Image) *dockertest.RunOptions {
   102  	opts.Repository = image.Name
   103  	opts.Tag = image.Tag
   104  	return opts
   105  }
   106  
   107  // SetupNetwork sets up a network within docker.
   108  func SetupNetwork(pool *dockertest.Pool) error {
   109  	networks, err := pool.Client.ListNetworks()
   110  	if err != nil {
   111  		return err
   112  	}
   113  
   114  	for _, n := range networks {
   115  		if n.Name == networkName {
   116  			if err := pool.Client.RemoveNetwork(networkName); err != nil {
   117  				return err
   118  			}
   119  
   120  			break
   121  		}
   122  	}
   123  
   124  	_, err = pool.Client.CreateNetwork(dc.CreateNetworkOptions{Name: networkName})
   125  	return err
   126  }
   127  
   128  func setupVolume(pool *dockertest.Pool) error {
   129  	volumes, err := pool.Client.ListVolumes(dc.ListVolumesOptions{})
   130  	if err != nil {
   131  		return err
   132  	}
   133  
   134  	for _, v := range volumes {
   135  		if volumeName == v.Name {
   136  			if err := pool.Client.RemoveVolume(volumeName); err != nil {
   137  				return err
   138  			}
   139  
   140  			break
   141  		}
   142  	}
   143  
   144  	_, err = pool.Client.CreateVolume(dc.CreateVolumeOptions{
   145  		Name: volumeName,
   146  	})
   147  
   148  	return err
   149  }
   150  
   151  func exposePorts(
   152  	opts *dockertest.RunOptions,
   153  	portList []int,
   154  ) *dockertest.RunOptions {
   155  	ports := make(map[dc.Port][]dc.PortBinding, len(portList))
   156  	for _, p := range portList {
   157  		port := fmt.Sprintf("%d", p)
   158  
   159  		portRepresentation := dc.Port(fmt.Sprintf("%s/tcp", port))
   160  		binding := dc.PortBinding{HostIP: "0.0.0.0", HostPort: port}
   161  		entry, found := ports[portRepresentation]
   162  		if !found {
   163  			entry = []dc.PortBinding{binding}
   164  		} else {
   165  			entry = append(entry, binding)
   166  		}
   167  
   168  		ports[portRepresentation] = entry
   169  	}
   170  
   171  	opts.PortBindings = ports
   172  	return opts
   173  }