github.com/dnephin/dobi@v0.15.0/config/mount.go (about)

     1  package config
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/dnephin/configtf"
     7  	pth "github.com/dnephin/configtf/path"
     8  	"github.com/dnephin/dobi/utils/fs"
     9  )
    10  
    11  // MountConfig A **mount** resource creates a host bind mount or named volume
    12  // mount.
    13  // name: mount
    14  // example: A mount named ``source`` that mounts the current host directory as
    15  // ``/app/code`` in the container.
    16  //
    17  // .. code-block:: yaml
    18  //
    19  //     mount=source:
    20  //         bind: .
    21  //         path: /app/code
    22  //
    23  //     mount=named:
    24  //         name: app-data
    25  //         path: /data
    26  //
    27  type MountConfig struct {
    28  	// Bind The host path to create and mount. This field supports expansion of
    29  	// `~` to the current users home directory.
    30  	Bind string
    31  	// Path The container path of the mount
    32  	Path string `config:"required"`
    33  	// Name The name of a named volume
    34  	Name string
    35  	// ReadOnly Set the mount to be read-only
    36  	ReadOnly bool
    37  	// File When true create an empty file instead of a directory
    38  	File bool
    39  	// Mode The file mode to set on the host file or directory when it is
    40  	// created.
    41  	// default: ``0755`` *(for directories)*, ``0644`` *(for files)*
    42  	Mode int `config:"validate"`
    43  	Annotations
    44  }
    45  
    46  // Dependencies returns an empty list, Mount resources have no dependencies
    47  func (c *MountConfig) Dependencies() []string {
    48  	return []string{}
    49  }
    50  
    51  // Validate checks that all fields have acceptable values
    52  func (c *MountConfig) Validate(path pth.Path, config *Config) *pth.Error {
    53  	switch {
    54  	case c.Bind != "" && c.Name != "":
    55  		return pth.Errorf(path, "\"name\" and \"bind\" can not be used together")
    56  	case c.Bind == "" && c.Name == "":
    57  		return pth.Errorf(path, "One of \"name\" or \"bind\" must be set")
    58  	case c.Name != "" && c.Mode != 0:
    59  		return pth.Errorf(path, "\"mode\" can not be used with named volumes")
    60  	case c.Name != "" && c.File:
    61  		return pth.Errorf(path, "\"file\" can not be used with named volumes")
    62  	}
    63  	return nil
    64  }
    65  
    66  // ValidateMode validates Mode and sets a default
    67  func (c *MountConfig) ValidateMode() error {
    68  	if c.Mode != 0 || c.Name != "" {
    69  		return nil
    70  	}
    71  	switch c.File {
    72  	case true:
    73  		c.Mode = 0644
    74  	default:
    75  		c.Mode = 0755
    76  	}
    77  	return nil
    78  }
    79  
    80  func (c *MountConfig) String() string {
    81  	var mount string
    82  	switch {
    83  	case c.File:
    84  		mount = fmt.Sprintf("file %q", c.Bind)
    85  	case c.Name != "":
    86  		mount = "named volume"
    87  	default:
    88  		mount = fmt.Sprintf("directory %q", c.Bind)
    89  	}
    90  	return fmt.Sprintf("Create %s to be mounted at %q", mount, c.Path)
    91  }
    92  
    93  // IsBind returns true if the mount is a bind mount to a host directory
    94  func (c *MountConfig) IsBind() bool {
    95  	return c.Bind != ""
    96  }
    97  
    98  // Resolve resolves variables in the resource
    99  func (c *MountConfig) Resolve(resolver Resolver) (Resource, error) {
   100  	conf := *c
   101  	var err error
   102  	conf.Path, err = resolver.Resolve(c.Path)
   103  	if err != nil {
   104  		return &conf, err
   105  	}
   106  	conf.Name, err = resolver.Resolve(c.Name)
   107  	if err != nil {
   108  		return &conf, err
   109  	}
   110  	bind, err := resolver.Resolve(c.Bind)
   111  	if err != nil {
   112  		return &conf, err
   113  	}
   114  	conf.Bind, err = fs.ExpandUser(bind)
   115  	return &conf, err
   116  }
   117  
   118  func mountFromConfig(name string, values map[string]interface{}) (Resource, error) {
   119  	mount := &MountConfig{}
   120  	return mount, configtf.Transform(name, values, mount)
   121  }
   122  
   123  func init() {
   124  	RegisterResource("mount", mountFromConfig)
   125  }