github.com/uppal0016/docker_new@v0.0.0-20240123060250-1c98be13ac2c/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  // 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  	return w.Config, hc, w.NetworkingConfig, nil
    66  }
    67  
    68  // validateVolumesAndBindSettings validates each of the volumes and bind settings
    69  // passed by the caller to ensure they are valid.
    70  func validateVolumesAndBindSettings(c *container.Config, hc *container.HostConfig) error {
    71  
    72  	// Ensure all volumes and binds are valid.
    73  	for spec := range c.Volumes {
    74  		if _, err := volume.ParseMountSpec(spec, hc.VolumeDriver); err != nil {
    75  			return fmt.Errorf("Invalid volume spec %q: %v", spec, err)
    76  		}
    77  	}
    78  	for _, spec := range hc.Binds {
    79  		if _, err := volume.ParseMountSpec(spec, hc.VolumeDriver); err != nil {
    80  			return fmt.Errorf("Invalid bind mount spec %q: %v", spec, err)
    81  		}
    82  	}
    83  
    84  	return nil
    85  }