浏览代码

Merge pull request #42725 from thaJeztah/runconfig_simplify

runconfig: decodeContainerConfig() return early if there's no HostConfig
Akihiro Suda 3 年之前
父节点
当前提交
02016803f0
共有 5 个文件被更改,包括 22 次插入95 次删除
  1. 10 26
      runconfig/config.go
  2. 1 1
      runconfig/config_unix.go
  3. 4 14
      runconfig/hostconfig.go
  4. 3 27
      runconfig/hostconfig_unix.go
  5. 4 27
      runconfig/hostconfig_windows.go

+ 10 - 26
runconfig/config.go

@@ -33,58 +33,42 @@ func (r ContainerDecoder) DecodeHostConfig(src io.Reader) (*container.HostConfig
 }
 
 // decodeContainerConfig decodes a json encoded config into a ContainerConfigWrapper
-// struct and returns both a Config and a HostConfig struct
+// struct and returns both a Config and a HostConfig struct, and performs some
+// validation. Certain parameters need daemon-side validation that cannot be done
+// on the client, as only the daemon knows what is valid for the platform.
 // Be aware this function is not checking whether the resulted structs are nil,
 // it's your business to do so
 func decodeContainerConfig(src io.Reader, si *sysinfo.SysInfo) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig, error) {
 	var w ContainerConfigWrapper
-
-	decoder := json.NewDecoder(src)
-	if err := decoder.Decode(&w); err != nil {
+	if err := json.NewDecoder(src).Decode(&w); err != nil {
 		return nil, nil, nil, err
 	}
 
 	hc := w.getHostConfig()
-
-	// Perform platform-specific processing of Volumes and Binds.
-	if w.Config != nil && hc != nil {
-
-		// Initialize the volumes map if currently nil
-		if w.Config.Volumes == nil {
-			w.Config.Volumes = make(map[string]struct{})
-		}
+	if hc == nil {
+		// We may not be passed a host config, such as in the case of docker commit
+		return w.Config, hc, w.NetworkingConfig, nil
 	}
-
-	// Certain parameters need daemon-side validation that cannot be done
-	// on the client, as only the daemon knows what is valid for the platform.
 	if err := validateNetMode(w.Config, hc); err != nil {
 		return nil, nil, nil, err
 	}
-
-	// Validate isolation
 	if err := validateIsolation(hc); err != nil {
 		return nil, nil, nil, err
 	}
-
-	// Validate QoS
 	if err := validateQoS(hc); err != nil {
 		return nil, nil, nil, err
 	}
-
-	// Validate Resources
 	if err := validateResources(hc, si); err != nil {
 		return nil, nil, nil, err
 	}
-
-	// Validate Privileged
 	if err := validatePrivileged(hc); err != nil {
 		return nil, nil, nil, err
 	}
-
-	// Validate ReadonlyRootfs
 	if err := validateReadonlyRootfs(hc); err != nil {
 		return nil, nil, nil, err
 	}
-
+	if w.Config != nil && w.Config.Volumes == nil {
+		w.Config.Volumes = make(map[string]struct{})
+	}
 	return w.Config, hc, w.NetworkingConfig, nil
 }

+ 1 - 1
runconfig/config_unix.go

@@ -25,7 +25,7 @@ func (w *ContainerConfigWrapper) getHostConfig() *container.HostConfig {
 
 	if hc == nil && w.InnerHostConfig != nil {
 		hc = w.InnerHostConfig
-	} else if w.InnerHostConfig != nil {
+	} else if hc != nil && w.InnerHostConfig != nil {
 		if hc.Memory != 0 && w.InnerHostConfig.Memory == 0 {
 			w.InnerHostConfig.Memory = hc.Memory
 		}

+ 4 - 14
runconfig/hostconfig.go

@@ -11,15 +11,11 @@ import (
 // DecodeHostConfig creates a HostConfig based on the specified Reader.
 // It assumes the content of the reader will be JSON, and decodes it.
 func decodeHostConfig(src io.Reader) (*container.HostConfig, error) {
-	decoder := json.NewDecoder(src)
-
 	var w ContainerConfigWrapper
-	if err := decoder.Decode(&w); err != nil {
+	if err := json.NewDecoder(src).Decode(&w); err != nil {
 		return nil, err
 	}
-
-	hc := w.getHostConfig()
-	return hc, nil
+	return w.getHostConfig(), nil
 }
 
 // SetDefaultNetModeIfBlank changes the NetworkMode in a HostConfig structure
@@ -27,20 +23,14 @@ func decodeHostConfig(src io.Reader) (*container.HostConfig, error) {
 // the validation of the network mode was moved from the docker CLI to the
 // docker daemon.
 func SetDefaultNetModeIfBlank(hc *container.HostConfig) {
-	if hc != nil {
-		if hc.NetworkMode == container.NetworkMode("") {
-			hc.NetworkMode = container.NetworkMode("default")
-		}
+	if hc != nil && hc.NetworkMode == "" {
+		hc.NetworkMode = "default"
 	}
 }
 
 // validateNetContainerMode ensures that the various combinations of requested
 // network settings wrt container mode are valid.
 func validateNetContainerMode(c *container.Config, hc *container.HostConfig) error {
-	// We may not be passed a host config, such as in the case of docker commit
-	if hc == nil {
-		return nil
-	}
 	parts := strings.Split(string(hc.NetworkMode), ":")
 	if parts[0] == "container" {
 		if len(parts) < 2 || parts[1] == "" {

+ 3 - 27
runconfig/hostconfig_unix.go

@@ -14,7 +14,7 @@ import (
 // DefaultDaemonNetworkMode returns the default network stack the daemon should
 // use.
 func DefaultDaemonNetworkMode() container.NetworkMode {
-	return container.NetworkMode("bridge")
+	return "bridge"
 }
 
 // IsPreDefinedNetwork indicates if a network is predefined by the daemon
@@ -26,24 +26,16 @@ func IsPreDefinedNetwork(network string) bool {
 // validateNetMode ensures that the various combinations of requested
 // network settings are valid.
 func validateNetMode(c *container.Config, hc *container.HostConfig) error {
-	// We may not be passed a host config, such as in the case of docker commit
-	if hc == nil {
-		return nil
-	}
-
 	err := validateNetContainerMode(c, hc)
 	if err != nil {
 		return err
 	}
-
 	if hc.UTSMode.IsHost() && c.Hostname != "" {
 		return ErrConflictUTSHostname
 	}
-
 	if hc.NetworkMode.IsHost() && len(hc.Links) > 0 {
 		return ErrConflictHostNetworkAndLinks
 	}
-
 	return nil
 }
 
@@ -51,10 +43,6 @@ func validateNetMode(c *container.Config, hc *container.HostConfig) error {
 // isolation in the hostconfig structure. Linux only supports "default"
 // which is LXC container isolation
 func validateIsolation(hc *container.HostConfig) error {
-	// We may not be passed a host config, such as in the case of docker commit
-	if hc == nil {
-		return nil
-	}
 	if !hc.Isolation.IsValid() {
 		return fmt.Errorf("Invalid isolation: %q - %s only supports 'default'", hc.Isolation, runtime.GOOS)
 	}
@@ -63,15 +51,9 @@ func validateIsolation(hc *container.HostConfig) error {
 
 // validateQoS performs platform specific validation of the QoS settings
 func validateQoS(hc *container.HostConfig) error {
-	// We may not be passed a host config, such as in the case of docker commit
-	if hc == nil {
-		return nil
-	}
-
 	if hc.IOMaximumBandwidth != 0 {
 		return fmt.Errorf("Invalid QoS settings: %s does not support configuration of maximum bandwidth", runtime.GOOS)
 	}
-
 	if hc.IOMaximumIOps != 0 {
 		return fmt.Errorf("Invalid QoS settings: %s does not support configuration of maximum IOPs", runtime.GOOS)
 	}
@@ -81,15 +63,9 @@ func validateQoS(hc *container.HostConfig) error {
 // validateResources performs platform specific validation of the resource settings
 // cpu-rt-runtime and cpu-rt-period can not be greater than their parent, cpu-rt-runtime requires sys_nice
 func validateResources(hc *container.HostConfig, si *sysinfo.SysInfo) error {
-	// We may not be passed a host config, such as in the case of docker commit
-	if hc == nil {
-		return nil
-	}
-
 	if (hc.Resources.CPURealtimePeriod != 0 || hc.Resources.CPURealtimeRuntime != 0) && !si.CPURealtime {
 		return fmt.Errorf("Your kernel does not support CPU real-time scheduler")
 	}
-
 	if hc.Resources.CPURealtimePeriod != 0 && hc.Resources.CPURealtimeRuntime != 0 && hc.Resources.CPURealtimeRuntime > hc.Resources.CPURealtimePeriod {
 		return fmt.Errorf("cpu real-time runtime cannot be higher than cpu real-time period")
 	}
@@ -97,11 +73,11 @@ func validateResources(hc *container.HostConfig, si *sysinfo.SysInfo) error {
 }
 
 // validatePrivileged performs platform specific validation of the Privileged setting
-func validatePrivileged(hc *container.HostConfig) error {
+func validatePrivileged(_ *container.HostConfig) error {
 	return nil
 }
 
 // validateReadonlyRootfs performs platform specific validation of the ReadonlyRootfs setting
-func validateReadonlyRootfs(hc *container.HostConfig) error {
+func validateReadonlyRootfs(_ *container.HostConfig) error {
 	return nil
 }

+ 4 - 27
runconfig/hostconfig_windows.go

@@ -10,7 +10,7 @@ import (
 // DefaultDaemonNetworkMode returns the default network stack the daemon should
 // use.
 func DefaultDaemonNetworkMode() container.NetworkMode {
-	return container.NetworkMode("nat")
+	return "nat"
 }
 
 // IsPreDefinedNetwork indicates if a network is predefined by the daemon
@@ -21,19 +21,12 @@ func IsPreDefinedNetwork(network string) bool {
 // validateNetMode ensures that the various combinations of requested
 // network settings are valid.
 func validateNetMode(c *container.Config, hc *container.HostConfig) error {
-	if hc == nil {
-		return nil
-	}
-
-	err := validateNetContainerMode(c, hc)
-	if err != nil {
+	if err := validateNetContainerMode(c, hc); err != nil {
 		return err
 	}
-
 	if hc.NetworkMode.IsContainer() && hc.Isolation.IsHyperV() {
 		return fmt.Errorf("Using the network stack of another container is not supported while using Hyper-V Containers")
 	}
-
 	return nil
 }
 
@@ -41,10 +34,6 @@ func validateNetMode(c *container.Config, hc *container.HostConfig) error {
 // isolation in the hostconfig structure. Windows supports 'default' (or
 // blank), 'process', or 'hyperv'.
 func validateIsolation(hc *container.HostConfig) error {
-	// We may not be passed a host config, such as in the case of docker commit
-	if hc == nil {
-		return nil
-	}
 	if !hc.Isolation.IsValid() {
 		return fmt.Errorf("Invalid isolation: %q. Windows supports 'default', 'process', or 'hyperv'", hc.Isolation)
 	}
@@ -52,16 +41,12 @@ func validateIsolation(hc *container.HostConfig) error {
 }
 
 // validateQoS performs platform specific validation of the Qos settings
-func validateQoS(hc *container.HostConfig) error {
+func validateQoS(_ *container.HostConfig) error {
 	return nil
 }
 
 // validateResources performs platform specific validation of the resource settings
-func validateResources(hc *container.HostConfig, si *sysinfo.SysInfo) error {
-	// We may not be passed a host config, such as in the case of docker commit
-	if hc == nil {
-		return nil
-	}
+func validateResources(hc *container.HostConfig, _ *sysinfo.SysInfo) error {
 	if hc.Resources.CPURealtimePeriod != 0 {
 		return fmt.Errorf("Windows does not support CPU real-time period")
 	}
@@ -73,10 +58,6 @@ func validateResources(hc *container.HostConfig, si *sysinfo.SysInfo) error {
 
 // validatePrivileged performs platform specific validation of the Privileged setting
 func validatePrivileged(hc *container.HostConfig) error {
-	// We may not be passed a host config, such as in the case of docker commit
-	if hc == nil {
-		return nil
-	}
 	if hc.Privileged {
 		return fmt.Errorf("Windows does not support privileged mode")
 	}
@@ -85,10 +66,6 @@ func validatePrivileged(hc *container.HostConfig) error {
 
 // validateReadonlyRootfs performs platform specific validation of the ReadonlyRootfs setting
 func validateReadonlyRootfs(hc *container.HostConfig) error {
-	// We may not be passed a host config, such as in the case of docker commit
-	if hc == nil {
-		return nil
-	}
 	if hc.ReadonlyRootfs {
 		return fmt.Errorf("Windows does not support root filesystem in read-only mode")
 	}