github.com/rumpl/bof@v23.0.0-rc.2+incompatible/runconfig/config.go (about)

     1  package runconfig // import "github.com/docker/docker/runconfig"
     2  
     3  import (
     4  	"encoding/json"
     5  	"io"
     6  
     7  	"github.com/docker/docker/api/types/container"
     8  	networktypes "github.com/docker/docker/api/types/network"
     9  	"github.com/docker/docker/pkg/sysinfo"
    10  )
    11  
    12  // ContainerDecoder implements httputils.ContainerDecoder
    13  // calling DecodeContainerConfig.
    14  type ContainerDecoder struct {
    15  	GetSysInfo func() *sysinfo.SysInfo
    16  }
    17  
    18  // DecodeConfig makes ContainerDecoder to implement httputils.ContainerDecoder
    19  func (r ContainerDecoder) DecodeConfig(src io.Reader) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig, error) {
    20  	var si *sysinfo.SysInfo
    21  	if r.GetSysInfo != nil {
    22  		si = r.GetSysInfo()
    23  	} else {
    24  		si = sysinfo.New()
    25  	}
    26  
    27  	return decodeContainerConfig(src, si)
    28  }
    29  
    30  // DecodeHostConfig makes ContainerDecoder to implement httputils.ContainerDecoder
    31  func (r ContainerDecoder) DecodeHostConfig(src io.Reader) (*container.HostConfig, error) {
    32  	return decodeHostConfig(src)
    33  }
    34  
    35  // decodeContainerConfig decodes a json encoded config into a ContainerConfigWrapper
    36  // struct and returns both a Config and a HostConfig struct, and performs some
    37  // validation. Certain parameters need daemon-side validation that cannot be done
    38  // on the client, as only the daemon knows what is valid for the platform.
    39  // Be aware this function is not checking whether the resulted structs are nil,
    40  // it's your business to do so
    41  func decodeContainerConfig(src io.Reader, si *sysinfo.SysInfo) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig, error) {
    42  	var w ContainerConfigWrapper
    43  	if err := loadJSON(src, &w); err != nil {
    44  		return nil, nil, nil, err
    45  	}
    46  
    47  	hc := w.getHostConfig()
    48  	if hc == nil {
    49  		// We may not be passed a host config, such as in the case of docker commit
    50  		return w.Config, hc, w.NetworkingConfig, nil
    51  	}
    52  	if err := validateNetMode(w.Config, hc); err != nil {
    53  		return nil, nil, nil, err
    54  	}
    55  	if err := validateIsolation(hc); err != nil {
    56  		return nil, nil, nil, err
    57  	}
    58  	if err := validateQoS(hc); err != nil {
    59  		return nil, nil, nil, err
    60  	}
    61  	if err := validateResources(hc, si); err != nil {
    62  		return nil, nil, nil, err
    63  	}
    64  	if err := validatePrivileged(hc); err != nil {
    65  		return nil, nil, nil, err
    66  	}
    67  	if err := validateReadonlyRootfs(hc); err != nil {
    68  		return nil, nil, nil, err
    69  	}
    70  	if w.Config != nil && w.Config.Volumes == nil {
    71  		w.Config.Volumes = make(map[string]struct{})
    72  	}
    73  	return w.Config, hc, w.NetworkingConfig, nil
    74  }
    75  
    76  // loadJSON is similar to api/server/httputils.ReadJSON()
    77  func loadJSON(src io.Reader, out interface{}) error {
    78  	dec := json.NewDecoder(src)
    79  	if err := dec.Decode(&out); err != nil {
    80  		if err == io.EOF {
    81  			return validationError("invalid JSON: got EOF while reading request body")
    82  		}
    83  		return validationError("invalid JSON: " + err.Error())
    84  	}
    85  	if dec.More() {
    86  		return validationError("unexpected content after JSON")
    87  	}
    88  	return nil
    89  }