1package runconfig // import "github.com/docker/docker/runconfig"
2
3import (
4	"encoding/json"
5	"io"
6	"strings"
7
8	"github.com/docker/docker/api/types/container"
9)
10
11// DecodeHostConfig creates a HostConfig based on the specified Reader.
12// It assumes the content of the reader will be JSON, and decodes it.
13func decodeHostConfig(src io.Reader) (*container.HostConfig, error) {
14	decoder := json.NewDecoder(src)
15
16	var w ContainerConfigWrapper
17	if err := decoder.Decode(&w); err != nil {
18		return nil, err
19	}
20
21	hc := w.getHostConfig()
22	return hc, nil
23}
24
25// SetDefaultNetModeIfBlank changes the NetworkMode in a HostConfig structure
26// to default if it is not populated. This ensures backwards compatibility after
27// the validation of the network mode was moved from the docker CLI to the
28// docker daemon.
29func SetDefaultNetModeIfBlank(hc *container.HostConfig) {
30	if hc != nil {
31		if hc.NetworkMode == container.NetworkMode("") {
32			hc.NetworkMode = container.NetworkMode("default")
33		}
34	}
35}
36
37// validateNetContainerMode ensures that the various combinations of requested
38// network settings wrt container mode are valid.
39func validateNetContainerMode(c *container.Config, hc *container.HostConfig) error {
40	// We may not be passed a host config, such as in the case of docker commit
41	if hc == nil {
42		return nil
43	}
44	parts := strings.Split(string(hc.NetworkMode), ":")
45	if parts[0] == "container" {
46		if len(parts) < 2 || parts[1] == "" {
47			return validationError("Invalid network mode: invalid container format container:<name|id>")
48		}
49	}
50
51	if hc.NetworkMode.IsContainer() && c.Hostname != "" {
52		return ErrConflictNetworkHostname
53	}
54
55	if hc.NetworkMode.IsContainer() && len(hc.Links) > 0 {
56		return ErrConflictContainerNetworkAndLinks
57	}
58
59	if hc.NetworkMode.IsContainer() && len(hc.DNS) > 0 {
60		return ErrConflictNetworkAndDNS
61	}
62
63	if hc.NetworkMode.IsContainer() && len(hc.ExtraHosts) > 0 {
64		return ErrConflictNetworkHosts
65	}
66
67	if (hc.NetworkMode.IsContainer() || hc.NetworkMode.IsHost()) && c.MacAddress != "" {
68		return ErrConflictContainerNetworkAndMac
69	}
70
71	if hc.NetworkMode.IsContainer() && (len(hc.PortBindings) > 0 || hc.PublishAllPorts) {
72		return ErrConflictNetworkPublishPorts
73	}
74
75	if hc.NetworkMode.IsContainer() && len(c.ExposedPorts) > 0 {
76		return ErrConflictNetworkExposePorts
77	}
78	return nil
79}
80