github.com/ruphin/docker@v1.10.1/runconfig/config.go (about)

     1  package runconfig
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  
     8  	"github.com/docker/docker/volume"
     9  	"github.com/docker/engine-api/types/container"
    10  	networktypes "github.com/docker/engine-api/types/network"
    11  )
    12  
    13  // DecodeContainerConfig decodes a json encoded config into a ContainerConfigWrapper
    14  // struct and returns both a Config and an HostConfig struct
    15  // Be aware this function is not checking whether the resulted structs are nil,
    16  // it's your business to do so
    17  func DecodeContainerConfig(src io.Reader) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig, error) {
    18  	var w ContainerConfigWrapper
    19  
    20  	decoder := json.NewDecoder(src)
    21  	if err := decoder.Decode(&w); err != nil {
    22  		return nil, nil, nil, err
    23  	}
    24  
    25  	hc := w.getHostConfig()
    26  
    27  	// Perform platform-specific processing of Volumes and Binds.
    28  	if w.Config != nil && hc != nil {
    29  
    30  		// Initialize the volumes map if currently nil
    31  		if w.Config.Volumes == nil {
    32  			w.Config.Volumes = make(map[string]struct{})
    33  		}
    34  
    35  		// Now validate all the volumes and binds
    36  		if err := validateVolumesAndBindSettings(w.Config, hc); err != nil {
    37  			return nil, nil, nil, err
    38  		}
    39  	}
    40  
    41  	// Certain parameters need daemon-side validation that cannot be done
    42  	// on the client, as only the daemon knows what is valid for the platform.
    43  	if err := ValidateNetMode(w.Config, hc); err != nil {
    44  		return nil, nil, nil, err
    45  	}
    46  
    47  	// Validate the isolation level
    48  	if err := ValidateIsolationLevel(hc); err != nil {
    49  		return nil, nil, nil, err
    50  	}
    51  	return w.Config, hc, w.NetworkingConfig, nil
    52  }
    53  
    54  // validateVolumesAndBindSettings validates each of the volumes and bind settings
    55  // passed by the caller to ensure they are valid.
    56  func validateVolumesAndBindSettings(c *container.Config, hc *container.HostConfig) error {
    57  
    58  	// Ensure all volumes and binds are valid.
    59  	for spec := range c.Volumes {
    60  		if _, err := volume.ParseMountSpec(spec, hc.VolumeDriver); err != nil {
    61  			return fmt.Errorf("Invalid volume spec %q: %v", spec, err)
    62  		}
    63  	}
    64  	for _, spec := range hc.Binds {
    65  		if _, err := volume.ParseMountSpec(spec, hc.VolumeDriver); err != nil {
    66  			return fmt.Errorf("Invalid bind mount spec %q: %v", spec, err)
    67  		}
    68  	}
    69  
    70  	return nil
    71  }