diff --git a/components/engine/daemon/cluster/convert/network.go b/components/engine/daemon/cluster/convert/network.go index 44f5f56466..34660fc4ff 100644 --- a/components/engine/daemon/cluster/convert/network.go +++ b/components/engine/daemon/cluster/convert/network.go @@ -140,13 +140,13 @@ func swarmPortConfigToAPIPortConfig(portConfig *swarmapi.PortConfig) types.PortC func BasicNetworkFromGRPC(n swarmapi.Network) basictypes.NetworkResource { spec := n.Spec var ipam networktypes.IPAM - if spec.IPAM != nil { - if spec.IPAM.Driver != nil { - ipam.Driver = spec.IPAM.Driver.Name - ipam.Options = spec.IPAM.Driver.Options + if n.IPAM != nil { + if n.IPAM.Driver != nil { + ipam.Driver = n.IPAM.Driver.Name + ipam.Options = n.IPAM.Driver.Options } - ipam.Config = make([]networktypes.IPAMConfig, 0, len(spec.IPAM.Configs)) - for _, ic := range spec.IPAM.Configs { + ipam.Config = make([]networktypes.IPAMConfig, 0, len(n.IPAM.Configs)) + for _, ic := range n.IPAM.Configs { ipamConfig := networktypes.IPAMConfig{ Subnet: ic.Subnet, IPRange: ic.Range, diff --git a/components/engine/daemon/graphdriver/overlay/overlay.go b/components/engine/daemon/graphdriver/overlay/overlay.go index 2e0bec5bc4..6932e4df81 100644 --- a/components/engine/daemon/graphdriver/overlay/overlay.go +++ b/components/engine/daemon/graphdriver/overlay/overlay.go @@ -12,6 +12,7 @@ import ( "path" "path/filepath" "strconv" + "strings" "github.com/docker/docker/daemon/graphdriver" "github.com/docker/docker/daemon/graphdriver/copy" @@ -22,6 +23,7 @@ import ( "github.com/docker/docker/pkg/idtools" "github.com/docker/docker/pkg/locker" "github.com/docker/docker/pkg/mount" + "github.com/docker/docker/pkg/parsers" "github.com/docker/docker/pkg/system" "github.com/opencontainers/selinux/go-selinux/label" "github.com/sirupsen/logrus" @@ -95,6 +97,8 @@ func (d *naiveDiffDriverWithApply) ApplyDiff(id, parent string, diff io.Reader) // of that. This means all child images share file (but not directory) // data with the parent. +type overlayOptions struct{} + // Driver contains information about the home directory and the list of active mounts that are created using this driver. type Driver struct { home string @@ -115,6 +119,10 @@ func init() { // If an overlay filesystem is not supported over an existing filesystem then // error graphdriver.ErrIncompatibleFS is returned. func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) { + _, err := parseOptions(options) + if err != nil { + return nil, err + } if err := supportsOverlay(); err != nil { return nil, graphdriver.ErrNotSupported @@ -176,6 +184,22 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap return NaiveDiffDriverWithApply(d, uidMaps, gidMaps), nil } +func parseOptions(options []string) (*overlayOptions, error) { + o := &overlayOptions{} + for _, option := range options { + key, _, err := parsers.ParseKeyValueOpt(option) + if err != nil { + return nil, err + } + key = strings.ToLower(key) + switch key { + default: + return nil, fmt.Errorf("overlay: unknown option %s", key) + } + } + return o, nil +} + func supportsOverlay() error { // We can try to modprobe overlay first before looking at // proc/filesystems for when overlay is supported diff --git a/components/engine/daemon/logger/copier.go b/components/engine/daemon/logger/copier.go index ae86777f33..e24272fa6d 100644 --- a/components/engine/daemon/logger/copier.go +++ b/components/engine/daemon/logger/copier.go @@ -81,6 +81,7 @@ func (c *Copier) copySrc(name string, src io.Reader) { read, err := src.Read(buf[n:upto]) if err != nil { if err != io.EOF { + logReadsFailedCount.Inc(1) logrus.Errorf("Error scanning log stream: %s", err) return } @@ -120,6 +121,7 @@ func (c *Copier) copySrc(name string, src io.Reader) { } if logErr := c.dst.Log(msg); logErr != nil { + logWritesFailedCount.Inc(1) logrus.Errorf("Failed to log msg %q for logger %s: %s", msg.Line, c.dst.Name(), logErr) } } @@ -143,6 +145,7 @@ func (c *Copier) copySrc(name string, src io.Reader) { partialid = stringid.GenerateRandomID() ordinal = 1 firstPartial = false + totalPartialLogs.Inc(1) } else { msg.Timestamp = partialTS } @@ -151,6 +154,7 @@ func (c *Copier) copySrc(name string, src io.Reader) { hasMorePartial = true if logErr := c.dst.Log(msg); logErr != nil { + logWritesFailedCount.Inc(1) logrus.Errorf("Failed to log msg %q for logger %s: %s", msg.Line, c.dst.Name(), logErr) } p = 0 diff --git a/components/engine/daemon/logger/metrics.go b/components/engine/daemon/logger/metrics.go new file mode 100644 index 0000000000..b7dfd38ec2 --- /dev/null +++ b/components/engine/daemon/logger/metrics.go @@ -0,0 +1,21 @@ +package logger // import "github.com/docker/docker/daemon/logger" + +import ( + "github.com/docker/go-metrics" +) + +var ( + logWritesFailedCount metrics.Counter + logReadsFailedCount metrics.Counter + totalPartialLogs metrics.Counter +) + +func init() { + loggerMetrics := metrics.NewNamespace("logger", "", nil) + + logWritesFailedCount = loggerMetrics.NewCounter("log_write_operations_failed", "Number of log write operations that failed") + logReadsFailedCount = loggerMetrics.NewCounter("log_read_operations_failed", "Number of log reads from container stdio that failed") + totalPartialLogs = loggerMetrics.NewCounter("log_entries_size_greater_than_buffer", "Number of log entries which are larger than the log buffer") + + metrics.Register(loggerMetrics) +} diff --git a/components/engine/daemon/oci_linux.go b/components/engine/daemon/oci_linux.go index 766701a416..49ba0e13c3 100644 --- a/components/engine/daemon/oci_linux.go +++ b/components/engine/daemon/oci_linux.go @@ -527,7 +527,7 @@ func setMounts(daemon *Daemon, s *specs.Spec, c *container.Container, mounts []c // - /dev/shm, in case IpcMode is none. // While at it, also // - set size for /dev/shm from shmsize. - var defaultMounts []specs.Mount + defaultMounts := s.Mounts[:0] _, mountDev := userMounts["/dev"] for _, m := range s.Mounts { if _, ok := userMounts[m.Destination]; ok { diff --git a/components/engine/integration/network/inspect_test.go b/components/engine/integration/network/inspect_test.go index b728da9d23..e88d739fd9 100644 --- a/components/engine/integration/network/inspect_test.go +++ b/components/engine/integration/network/inspect_test.go @@ -162,9 +162,19 @@ func noTasks(client client.ServiceAPIClient) func(log poll.LogT) poll.Result { // Check to see if Service and Tasks info are part of the inspect verbose response func validNetworkVerbose(network types.NetworkResource, service string, instances uint64) bool { if service, ok := network.Services[service]; ok { - if len(service.Tasks) == int(instances) { - return true + if len(service.Tasks) != int(instances) { + return false } } - return false + + if network.IPAM.Config == nil { + return false + } + + for _, cfg := range network.IPAM.Config { + if cfg.Gateway == "" || cfg.Subnet == "" { + return false + } + } + return true } diff --git a/components/engine/internal/test/daemon/plugin.go b/components/engine/internal/test/daemon/plugin.go index fad9727161..9a7cc345ea 100644 --- a/components/engine/internal/test/daemon/plugin.go +++ b/components/engine/internal/test/daemon/plugin.go @@ -38,7 +38,7 @@ func (d *Daemon) PluginIsNotPresent(name string) func(poll.LogT) poll.Result { if err != nil { return poll.Error(err) } - return poll.Continue("plugin %q exists") + return poll.Continue("plugin %q exists", name) }) }