github.com/vieux/docker@v0.6.3-0.20161004191708-e097c2a938c7/runconfig/config.go (about)

     1  package runconfig
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  
     8  	"github.com/docker/docker/api/types/container"
     9  	networktypes "github.com/docker/docker/api/types/network"
    10  	"github.com/docker/docker/volume"
    11  )
    12  
    13  // ContainerDecoder implements httputils.ContainerDecoder
    14  // calling DecodeContainerConfig.
    15  type ContainerDecoder struct{}
    16  
    17  // DecodeConfig makes ContainerDecoder to implement httputils.ContainerDecoder
    18  func (r ContainerDecoder) DecodeConfig(src io.Reader) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig, error) {
    19  	return DecodeContainerConfig(src)
    20  }
    21  
    22  // DecodeHostConfig makes ContainerDecoder to implement httputils.ContainerDecoder
    23  func (r ContainerDecoder) DecodeHostConfig(src io.Reader) (*container.HostConfig, error) {
    24  	return DecodeHostConfig(src)
    25  }
    26  
    27  // DecodeContainerConfig decodes a json encoded config into a ContainerConfigWrapper
    28  // struct and returns both a Config and a HostConfig struct
    29  // Be aware this function is not checking whether the resulted structs are nil,
    30  // it's your business to do so
    31  func DecodeContainerConfig(src io.Reader) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig, error) {
    32  	var w ContainerConfigWrapper
    33  
    34  	decoder := json.NewDecoder(src)
    35  	if err := decoder.Decode(&w); err != nil {
    36  		return nil, nil, nil, err
    37  	}
    38  
    39  	hc := w.getHostConfig()
    40  
    41  	// Perform platform-specific processing of Volumes and Binds.
    42  	if w.Config != nil && hc != nil {
    43  
    44  		// Initialize the volumes map if currently nil
    45  		if w.Config.Volumes == nil {
    46  			w.Config.Volumes = make(map[string]struct{})
    47  		}
    48  
    49  		// Now validate all the volumes and binds
    50  		if err := validateVolumesAndBindSettings(w.Config, hc); err != nil {
    51  			return nil, nil, nil, err
    52  		}
    53  	}
    54  
    55  	// Certain parameters need daemon-side validation that cannot be done
    56  	// on the client, as only the daemon knows what is valid for the platform.
    57  	if err := ValidateNetMode(w.Config, hc); err != nil {
    58  		return nil, nil, nil, err
    59  	}
    60  
    61  	// Validate isolation
    62  	if err := ValidateIsolation(hc); err != nil {
    63  		return nil, nil, nil, err
    64  	}
    65  
    66  	// Validate QoS
    67  	if err := ValidateQoS(hc); err != nil {
    68  		return nil, nil, nil, err
    69  	}
    70  	return w.Config, hc, w.NetworkingConfig, nil
    71  }
    72  
    73  // validateVolumesAndBindSettings validates each of the volumes and bind settings
    74  // passed by the caller to ensure they are valid.
    75  func validateVolumesAndBindSettings(c *container.Config, hc *container.HostConfig) error {
    76  	if len(hc.Mounts) > 0 {
    77  		if len(hc.Binds) > 0 {
    78  			return conflictError(fmt.Errorf("must not specify both Binds and Mounts"))
    79  		}
    80  
    81  		if len(c.Volumes) > 0 {
    82  			return conflictError(fmt.Errorf("must not specify both Volumes and Mounts"))
    83  		}
    84  
    85  		if len(hc.VolumeDriver) > 0 {
    86  			return conflictError(fmt.Errorf("must not specify both VolumeDriver and Mounts"))
    87  		}
    88  	}
    89  
    90  	// Ensure all volumes and binds are valid.
    91  	for spec := range c.Volumes {
    92  		if _, err := volume.ParseMountRaw(spec, hc.VolumeDriver); err != nil {
    93  			return fmt.Errorf("invalid volume spec %q: %v", spec, err)
    94  		}
    95  	}
    96  	for _, spec := range hc.Binds {
    97  		if _, err := volume.ParseMountRaw(spec, hc.VolumeDriver); err != nil {
    98  			return fmt.Errorf("invalid bind mount spec %q: %v", spec, err)
    99  		}
   100  	}
   101  
   102  	return nil
   103  }