diff --git a/api/types/types.go b/api/types/types.go index 9d31f70d64..d6017898d0 100644 --- a/api/types/types.go +++ b/api/types/types.go @@ -212,7 +212,12 @@ type Info struct { SecurityOptions []string ProductLicense string `json:",omitempty"` DefaultAddressPools []NetworkAddressPool `json:",omitempty"` - Warnings []string + + // Warnings contains a slice of warnings that occurred while collecting + // system information. These warnings are intended to be informational + // messages for the user, and are not intended to be parsed / used for + // other purposes, as they do not have a fixed format. + Warnings []string } // KeyValue holds a key/value pair diff --git a/cmd/dockerd/daemon.go b/cmd/dockerd/daemon.go index 1841253a06..842c948f8a 100644 --- a/cmd/dockerd/daemon.go +++ b/cmd/dockerd/daemon.go @@ -478,14 +478,14 @@ func warnOnDeprecatedConfigOptions(config *config.Config) { func initRouter(opts routerOptions) { decoder := runconfig.ContainerDecoder{ GetSysInfo: func() *sysinfo.SysInfo { - return opts.daemon.RawSysInfo(true) + return opts.daemon.RawSysInfo() }, } routers := []router.Router{ // we need to add the checkpoint router before the container router or the DELETE gets masked checkpointrouter.NewRouter(opts.daemon, decoder), - container.NewRouter(opts.daemon, decoder, opts.daemon.RawSysInfo(true).CgroupUnified), + container.NewRouter(opts.daemon, decoder, opts.daemon.RawSysInfo().CgroupUnified), image.NewRouter(opts.daemon.ImageService()), systemrouter.NewRouter(opts.daemon, opts.cluster, opts.buildkit, opts.features), volume.NewRouter(opts.daemon.VolumesService()), diff --git a/daemon/daemon.go b/daemon/daemon.go index e6c0425e02..ced869a380 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -1050,7 +1050,10 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S return nil, err } - sysInfo := d.RawSysInfo(false) + sysInfo := d.RawSysInfo() + for _, w := range sysInfo.Warnings { + logrus.Warn(w) + } // Check if Devices cgroup is mounted, it is hard requirement for container security, // on Linux. if runtime.GOOS == "linux" && !sysInfo.CgroupDevicesEnabled && !userns.RunningInUserNS() { diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go index 55f82ba839..51b7ad4b7b 100644 --- a/daemon/daemon_unix.go +++ b/daemon/daemon_unix.go @@ -666,7 +666,7 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes. if hostConfig == nil { return nil, nil } - sysInfo := daemon.RawSysInfo(true) + sysInfo := daemon.RawSysInfo() w, err := verifyPlatformContainerResources(&hostConfig.Resources, sysInfo, update) @@ -1718,14 +1718,14 @@ func (daemon *Daemon) setupSeccompProfile() error { } // RawSysInfo returns *sysinfo.SysInfo . -func (daemon *Daemon) RawSysInfo(quiet bool) *sysinfo.SysInfo { +func (daemon *Daemon) RawSysInfo() *sysinfo.SysInfo { var siOpts []sysinfo.Opt if daemon.getCgroupDriver() == cgroupSystemdDriver { if euid := os.Getenv("ROOTLESSKIT_PARENT_EUID"); euid != "" { siOpts = append(siOpts, sysinfo.WithCgroup2GroupPath("/user.slice/user-"+euid+".slice")) } } - return sysinfo.New(quiet, siOpts...) + return sysinfo.New(siOpts...) } func recursiveUnmount(target string) error { diff --git a/daemon/daemon_unsupported.go b/daemon/daemon_unsupported.go index 4c2476edcf..e8bebca3e4 100644 --- a/daemon/daemon_unsupported.go +++ b/daemon/daemon_unsupported.go @@ -13,6 +13,6 @@ func setupResolvConf(config *config.Config) { } // RawSysInfo returns *sysinfo.SysInfo . -func (daemon *Daemon) RawSysInfo(quiet bool) *sysinfo.SysInfo { - return sysinfo.New(quiet) +func (daemon *Daemon) RawSysInfo() *sysinfo.SysInfo { + return sysinfo.New() } diff --git a/daemon/daemon_windows.go b/daemon/daemon_windows.go index 76e3701f8a..a87f700bb0 100644 --- a/daemon/daemon_windows.go +++ b/daemon/daemon_windows.go @@ -652,6 +652,6 @@ func setupResolvConf(config *config.Config) { } // RawSysInfo returns *sysinfo.SysInfo . -func (daemon *Daemon) RawSysInfo(quiet bool) *sysinfo.SysInfo { - return sysinfo.New(quiet) +func (daemon *Daemon) RawSysInfo() *sysinfo.SysInfo { + return sysinfo.New() } diff --git a/daemon/info.go b/daemon/info.go index 15b78ebe1c..7c9f7e6ab8 100644 --- a/daemon/info.go +++ b/daemon/info.go @@ -30,7 +30,7 @@ import ( func (daemon *Daemon) SystemInfo() *types.Info { defer metrics.StartTimer(hostInfoFunctions.WithValues("system_info"))() - sysInfo := daemon.RawSysInfo(true) + sysInfo := daemon.RawSysInfo() cRunning, cPaused, cStopped := stateCtr.get() v := &types.Info{ diff --git a/daemon/oci_linux.go b/daemon/oci_linux.go index 6358450d37..a5720537b9 100644 --- a/daemon/oci_linux.go +++ b/daemon/oci_linux.go @@ -824,7 +824,7 @@ func WithCgroups(daemon *Daemon, c *container.Container) coci.SpecOpts { } // FIXME this is very expensive way to check if cpu rt is supported - sysInfo := daemon.RawSysInfo(true) + sysInfo := daemon.RawSysInfo() if !sysInfo.CPURealtime { return errors.New("daemon-scoped cpu-rt-period and cpu-rt-runtime are not supported by the kernel") } diff --git a/integration-cli/docker_cli_run_unix_test.go b/integration-cli/docker_cli_run_unix_test.go index 4670468b5e..f6915056cd 100644 --- a/integration-cli/docker_cli_run_unix_test.go +++ b/integration-cli/docker_cli_run_unix_test.go @@ -699,7 +699,7 @@ func (s *DockerSuite) TestRunSwapLessThanMemoryLimit(c *testing.T) { func (s *DockerSuite) TestRunInvalidCpusetCpusFlagValue(c *testing.T) { testRequires(c, cgroupCpuset, testEnv.IsLocalDaemon) - sysInfo := sysinfo.New(true) + sysInfo := sysinfo.New() cpus, err := parsers.ParseUintList(sysInfo.Cpus) assert.NilError(c, err) var invalid int @@ -718,7 +718,7 @@ func (s *DockerSuite) TestRunInvalidCpusetCpusFlagValue(c *testing.T) { func (s *DockerSuite) TestRunInvalidCpusetMemsFlagValue(c *testing.T) { testRequires(c, cgroupCpuset) - sysInfo := sysinfo.New(true) + sysInfo := sysinfo.New() mems, err := parsers.ParseUintList(sysInfo.Mems) assert.NilError(c, err) var invalid int diff --git a/integration-cli/requirements_unix_test.go b/integration-cli/requirements_unix_test.go index 8c75b26424..7086966a66 100644 --- a/integration-cli/requirements_unix_test.go +++ b/integration-cli/requirements_unix_test.go @@ -84,6 +84,6 @@ func overlayFSSupported() bool { func init() { if testEnv.IsLocalDaemon() { - SysInfo = sysinfo.New(true) + SysInfo = sysinfo.New() } } diff --git a/pkg/sysinfo/cgroup2_linux.go b/pkg/sysinfo/cgroup2_linux.go index 1ea3cd51d9..e62769a6ee 100644 --- a/pkg/sysinfo/cgroup2_linux.go +++ b/pkg/sysinfo/cgroup2_linux.go @@ -12,42 +12,13 @@ import ( "github.com/sirupsen/logrus" ) -type infoCollectorV2 func(info *SysInfo, controllers map[string]struct{}, dirPath string) (warnings []string) - -func newV2(quiet bool, opts *opts) *SysInfo { - var warnings []string +func newV2(options ...Opt) *SysInfo { sysInfo := &SysInfo{ CgroupUnified: true, + cg2GroupPath: "/", } - g := opts.cg2GroupPath - if g == "" { - g = "/" - } - m, err := cgroupsV2.LoadManager("/sys/fs/cgroup", g) - if err != nil { - logrus.Warn(err) - } else { - controllersM := make(map[string]struct{}) - controllers, err := m.Controllers() - if err != nil { - logrus.Warn(err) - } - for _, c := range controllers { - controllersM[c] = struct{}{} - } - opsV2 := []infoCollectorV2{ - applyMemoryCgroupInfoV2, - applyCPUCgroupInfoV2, - applyIOCgroupInfoV2, - applyCPUSetCgroupInfoV2, - applyPIDSCgroupInfoV2, - applyDevicesCgroupInfoV2, - } - dirPath := path.Join("/sys/fs/cgroup", path.Clean(g)) - for _, o := range opsV2 { - w := o(sysInfo, controllersM, dirPath) - warnings = append(warnings, w...) - } + for _, o := range options { + o(sysInfo) } ops := []infoCollector{ @@ -56,14 +27,31 @@ func newV2(quiet bool, opts *opts) *SysInfo { applySeccompInfo, applyCgroupNsInfo, } - for _, o := range ops { - w := o(sysInfo, nil) - warnings = append(warnings, w...) - } - if !quiet { - for _, w := range warnings { - logrus.Warn(w) + + m, err := cgroupsV2.LoadManager("/sys/fs/cgroup", sysInfo.cg2GroupPath) + if err != nil { + logrus.Warn(err) + } else { + sysInfo.cg2Controllers = make(map[string]struct{}) + controllers, err := m.Controllers() + if err != nil { + logrus.Warn(err) } + for _, c := range controllers { + sysInfo.cg2Controllers[c] = struct{}{} + } + ops = append(ops, + applyMemoryCgroupInfoV2, + applyCPUCgroupInfoV2, + applyIOCgroupInfoV2, + applyCPUSetCgroupInfoV2, + applyPIDSCgroupInfoV2, + applyDevicesCgroupInfoV2, + ) + } + + for _, o := range ops { + o(sysInfo) } return sysInfo } @@ -86,11 +74,10 @@ func getSwapLimitV2() bool { return true } -func applyMemoryCgroupInfoV2(info *SysInfo, controllers map[string]struct{}, _ string) []string { - var warnings []string - if _, ok := controllers["memory"]; !ok { - warnings = append(warnings, "Unable to find memory controller") - return warnings +func applyMemoryCgroupInfoV2(info *SysInfo) { + if _, ok := info.cg2Controllers["memory"]; !ok { + info.Warnings = append(info.Warnings, "Unable to find memory controller") + return } info.MemoryLimit = true @@ -100,26 +87,22 @@ func applyMemoryCgroupInfoV2(info *SysInfo, controllers map[string]struct{}, _ s info.MemorySwappiness = false info.KernelMemory = false info.KernelMemoryTCP = false - return warnings } -func applyCPUCgroupInfoV2(info *SysInfo, controllers map[string]struct{}, _ string) []string { - var warnings []string - if _, ok := controllers["cpu"]; !ok { - warnings = append(warnings, "Unable to find cpu controller") - return warnings +func applyCPUCgroupInfoV2(info *SysInfo) { + if _, ok := info.cg2Controllers["cpu"]; !ok { + info.Warnings = append(info.Warnings, "Unable to find cpu controller") + return } info.CPUShares = true info.CPUCfs = true info.CPURealtime = false - return warnings } -func applyIOCgroupInfoV2(info *SysInfo, controllers map[string]struct{}, _ string) []string { - var warnings []string - if _, ok := controllers["io"]; !ok { - warnings = append(warnings, "Unable to find io controller") - return warnings +func applyIOCgroupInfoV2(info *SysInfo) { + if _, ok := info.cg2Controllers["io"]; !ok { + info.Warnings = append(info.Warnings, "Unable to find io controller") + return } info.BlkioWeight = true @@ -128,42 +111,36 @@ func applyIOCgroupInfoV2(info *SysInfo, controllers map[string]struct{}, _ strin info.BlkioWriteBpsDevice = true info.BlkioReadIOpsDevice = true info.BlkioWriteIOpsDevice = true - return warnings } -func applyCPUSetCgroupInfoV2(info *SysInfo, controllers map[string]struct{}, dirPath string) []string { - var warnings []string - if _, ok := controllers["cpuset"]; !ok { - warnings = append(warnings, "Unable to find cpuset controller") - return warnings +func applyCPUSetCgroupInfoV2(info *SysInfo) { + if _, ok := info.cg2Controllers["cpuset"]; !ok { + info.Warnings = append(info.Warnings, "Unable to find cpuset controller") + return } info.Cpuset = true - cpus, err := ioutil.ReadFile(path.Join(dirPath, "cpuset.cpus.effective")) + cpus, err := ioutil.ReadFile(path.Join("/sys/fs/cgroup", info.cg2GroupPath, "cpuset.cpus.effective")) if err != nil { - return warnings + return } info.Cpus = strings.TrimSpace(string(cpus)) - mems, err := ioutil.ReadFile(path.Join(dirPath, "cpuset.mems.effective")) + mems, err := ioutil.ReadFile(path.Join("/sys/fs/cgroup", info.cg2GroupPath, "cpuset.mems.effective")) if err != nil { - return warnings + return } info.Mems = strings.TrimSpace(string(mems)) - return warnings } -func applyPIDSCgroupInfoV2(info *SysInfo, controllers map[string]struct{}, _ string) []string { - var warnings []string - if _, ok := controllers["pids"]; !ok { - warnings = append(warnings, "Unable to find pids controller") - return warnings +func applyPIDSCgroupInfoV2(info *SysInfo) { + if _, ok := info.cg2Controllers["pids"]; !ok { + info.Warnings = append(info.Warnings, "Unable to find pids controller") + return } info.PidsLimit = true - return warnings } -func applyDevicesCgroupInfoV2(info *SysInfo, controllers map[string]struct{}, _ string) []string { +func applyDevicesCgroupInfoV2(info *SysInfo) { info.CgroupDevicesEnabled = !userns.RunningInUserNS() - return nil } diff --git a/pkg/sysinfo/sysinfo.go b/pkg/sysinfo/sysinfo.go index 6e4b16847a..ac8a417581 100644 --- a/pkg/sysinfo/sysinfo.go +++ b/pkg/sysinfo/sysinfo.go @@ -2,6 +2,9 @@ package sysinfo // import "github.com/docker/docker/pkg/sysinfo" import "github.com/docker/docker/pkg/parsers" +// Opt for New(). +type Opt func(info *SysInfo) + // SysInfo stores information about which features a kernel supports. // TODO Windows: Factor out platform specific capabilities. type SysInfo struct { @@ -33,6 +36,23 @@ type SysInfo struct { // Whether the cgroup is in unified mode (v2). CgroupUnified bool + + // Warnings contains a slice of warnings that occurred while collecting + // system information. These warnings are intended to be informational + // messages for the user, and can either be logged or returned to the + // client; they are not intended to be parsed / used for other purposes, + // and do not have a fixed format. + Warnings []string + + // cgMounts is the list of cgroup v1 mount paths, indexed by subsystem, to + // inspect availability of subsystems. + cgMounts map[string]string + + // cg2GroupPath is the cgroup v2 group path to inspect availability of the controllers. + cg2GroupPath string + + // cg2Controllers is an index of available cgroup v2 controllers. + cg2Controllers map[string]struct{} } type cgroupMemInfo struct { diff --git a/pkg/sysinfo/sysinfo_linux.go b/pkg/sysinfo/sysinfo_linux.go index 42709a4d35..f4a8f32443 100644 --- a/pkg/sysinfo/sysinfo_linux.go +++ b/pkg/sysinfo/sysinfo_linux.go @@ -28,14 +28,7 @@ func findCgroupMountpoints() (map[string]string, error) { return mps, nil } -type infoCollector func(info *SysInfo, cgMounts map[string]string) (warnings []string) - -type opts struct { - cg2GroupPath string -} - -// Opt for New(). -type Opt func(*opts) +type infoCollector func(info *SysInfo) // WithCgroup2GroupPath specifies the cgroup v2 group path to inspect availability // of the controllers. @@ -44,172 +37,158 @@ type Opt func(*opts) // // e.g. g = "/user.slice/user-1000.slice/user@1000.service" func WithCgroup2GroupPath(g string) Opt { - return func(o *opts) { - o.cg2GroupPath = path.Clean(g) + return func(o *SysInfo) { + if p := path.Clean(g); p != "" { + o.cg2GroupPath = p + } } } // New returns a new SysInfo, using the filesystem to detect which features -// the kernel supports. If `quiet` is `false` warnings are printed in logs -// whenever an error occurs or misconfigurations are present. -func New(quiet bool, options ...Opt) *SysInfo { - var opts opts - for _, o := range options { - o(&opts) - } +// the kernel supports. +func New(options ...Opt) *SysInfo { if cdcgroups.Mode() == cdcgroups.Unified { - return newV2(quiet, &opts) + return newV2(options...) + } + return newV1() +} + +func newV1() *SysInfo { + var ( + err error + sysInfo = &SysInfo{} + ) + + ops := []infoCollector{ + applyNetworkingInfo, + applyAppArmorInfo, + applySeccompInfo, + applyCgroupNsInfo, } - var ops []infoCollector - var warnings []string - sysInfo := &SysInfo{} - cgMounts, err := findCgroupMountpoints() + sysInfo.cgMounts, err = findCgroupMountpoints() if err != nil { logrus.Warn(err) } else { - ops = append(ops, []infoCollector{ + ops = append(ops, applyMemoryCgroupInfo, applyCPUCgroupInfo, applyBlkioCgroupInfo, applyCPUSetCgroupInfo, applyPIDSCgroupInfo, applyDevicesCgroupInfo, - }...) + ) } - ops = append(ops, []infoCollector{ - applyNetworkingInfo, - applyAppArmorInfo, - applySeccompInfo, - applyCgroupNsInfo, - }...) - for _, o := range ops { - w := o(sysInfo, cgMounts) - warnings = append(warnings, w...) - } - if !quiet { - for _, w := range warnings { - logrus.Warn(w) - } + o(sysInfo) } return sysInfo } // applyMemoryCgroupInfo adds the memory cgroup controller information to the info. -func applyMemoryCgroupInfo(info *SysInfo, cgMounts map[string]string) []string { - var warnings []string - mountPoint, ok := cgMounts["memory"] +func applyMemoryCgroupInfo(info *SysInfo) { + mountPoint, ok := info.cgMounts["memory"] if !ok { - warnings = append(warnings, "Your kernel does not support cgroup memory limit") - return warnings + info.Warnings = append(info.Warnings, "Your kernel does not support cgroup memory limit") + return } info.MemoryLimit = ok info.SwapLimit = cgroupEnabled(mountPoint, "memory.memsw.limit_in_bytes") if !info.SwapLimit { - warnings = append(warnings, "Your kernel does not support swap memory limit") + info.Warnings = append(info.Warnings, "Your kernel does not support swap memory limit") } info.MemoryReservation = cgroupEnabled(mountPoint, "memory.soft_limit_in_bytes") if !info.MemoryReservation { - warnings = append(warnings, "Your kernel does not support memory reservation") + info.Warnings = append(info.Warnings, "Your kernel does not support memory reservation") } info.OomKillDisable = cgroupEnabled(mountPoint, "memory.oom_control") if !info.OomKillDisable { - warnings = append(warnings, "Your kernel does not support oom control") + info.Warnings = append(info.Warnings, "Your kernel does not support oom control") } info.MemorySwappiness = cgroupEnabled(mountPoint, "memory.swappiness") if !info.MemorySwappiness { - warnings = append(warnings, "Your kernel does not support memory swappiness") + info.Warnings = append(info.Warnings, "Your kernel does not support memory swappiness") } info.KernelMemory = cgroupEnabled(mountPoint, "memory.kmem.limit_in_bytes") if !info.KernelMemory { - warnings = append(warnings, "Your kernel does not support kernel memory limit") + info.Warnings = append(info.Warnings, "Your kernel does not support kernel memory limit") } info.KernelMemoryTCP = cgroupEnabled(mountPoint, "memory.kmem.tcp.limit_in_bytes") if !info.KernelMemoryTCP { - warnings = append(warnings, "Your kernel does not support kernel memory TCP limit") + info.Warnings = append(info.Warnings, "Your kernel does not support kernel memory TCP limit") } - - return warnings } // applyCPUCgroupInfo adds the cpu cgroup controller information to the info. -func applyCPUCgroupInfo(info *SysInfo, cgMounts map[string]string) []string { - var warnings []string - mountPoint, ok := cgMounts["cpu"] +func applyCPUCgroupInfo(info *SysInfo) { + mountPoint, ok := info.cgMounts["cpu"] if !ok { - warnings = append(warnings, "Unable to find cpu cgroup in mounts") - return warnings + info.Warnings = append(info.Warnings, "Unable to find cpu cgroup in mounts") + return } info.CPUShares = cgroupEnabled(mountPoint, "cpu.shares") if !info.CPUShares { - warnings = append(warnings, "Your kernel does not support CPU shares") + info.Warnings = append(info.Warnings, "Your kernel does not support CPU shares") } info.CPUCfs = cgroupEnabled(mountPoint, "cpu.cfs_quota_us") if !info.CPUCfs { - warnings = append(warnings, "Your kernel does not support CPU CFS scheduler") + info.Warnings = append(info.Warnings, "Your kernel does not support CPU CFS scheduler") } info.CPURealtime = cgroupEnabled(mountPoint, "cpu.rt_period_us") if !info.CPURealtime { - warnings = append(warnings, "Your kernel does not support CPU realtime scheduler") + info.Warnings = append(info.Warnings, "Your kernel does not support CPU realtime scheduler") } - - return warnings } // applyBlkioCgroupInfo adds the blkio cgroup controller information to the info. -func applyBlkioCgroupInfo(info *SysInfo, cgMounts map[string]string) []string { - var warnings []string - mountPoint, ok := cgMounts["blkio"] +func applyBlkioCgroupInfo(info *SysInfo) { + mountPoint, ok := info.cgMounts["blkio"] if !ok { - warnings = append(warnings, "Unable to find blkio cgroup in mounts") - return warnings + info.Warnings = append(info.Warnings, "Unable to find blkio cgroup in mounts") + return } info.BlkioWeight = cgroupEnabled(mountPoint, "blkio.weight") if !info.BlkioWeight { - warnings = append(warnings, "Your kernel does not support cgroup blkio weight") + info.Warnings = append(info.Warnings, "Your kernel does not support cgroup blkio weight") } info.BlkioWeightDevice = cgroupEnabled(mountPoint, "blkio.weight_device") if !info.BlkioWeightDevice { - warnings = append(warnings, "Your kernel does not support cgroup blkio weight_device") + info.Warnings = append(info.Warnings, "Your kernel does not support cgroup blkio weight_device") } info.BlkioReadBpsDevice = cgroupEnabled(mountPoint, "blkio.throttle.read_bps_device") if !info.BlkioReadBpsDevice { - warnings = append(warnings, "Your kernel does not support cgroup blkio throttle.read_bps_device") + info.Warnings = append(info.Warnings, "Your kernel does not support cgroup blkio throttle.read_bps_device") } info.BlkioWriteBpsDevice = cgroupEnabled(mountPoint, "blkio.throttle.write_bps_device") if !info.BlkioWriteBpsDevice { - warnings = append(warnings, "Your kernel does not support cgroup blkio throttle.write_bps_device") + info.Warnings = append(info.Warnings, "Your kernel does not support cgroup blkio throttle.write_bps_device") } info.BlkioReadIOpsDevice = cgroupEnabled(mountPoint, "blkio.throttle.read_iops_device") if !info.BlkioReadIOpsDevice { - warnings = append(warnings, "Your kernel does not support cgroup blkio throttle.read_iops_device") + info.Warnings = append(info.Warnings, "Your kernel does not support cgroup blkio throttle.read_iops_device") } info.BlkioWriteIOpsDevice = cgroupEnabled(mountPoint, "blkio.throttle.write_iops_device") if !info.BlkioWriteIOpsDevice { - warnings = append(warnings, "Your kernel does not support cgroup blkio throttle.write_iops_device") + info.Warnings = append(info.Warnings, "Your kernel does not support cgroup blkio throttle.write_iops_device") } - - return warnings } // applyCPUSetCgroupInfo adds the cpuset cgroup controller information to the info. -func applyCPUSetCgroupInfo(info *SysInfo, cgMounts map[string]string) []string { - var warnings []string - mountPoint, ok := cgMounts["cpuset"] +func applyCPUSetCgroupInfo(info *SysInfo) { + mountPoint, ok := info.cgMounts["cpuset"] if !ok { - warnings = append(warnings, "Unable to find cpuset cgroup in mounts") - return warnings + info.Warnings = append(info.Warnings, "Unable to find cpuset cgroup in mounts") + return } info.Cpuset = ok @@ -217,66 +196,54 @@ func applyCPUSetCgroupInfo(info *SysInfo, cgMounts map[string]string) []string { cpus, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.cpus")) if err != nil { - return warnings + return } info.Cpus = strings.TrimSpace(string(cpus)) mems, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.mems")) if err != nil { - return warnings + return } info.Mems = strings.TrimSpace(string(mems)) - - return warnings } // applyPIDSCgroupInfo adds whether the pids cgroup controller is available to the info. -func applyPIDSCgroupInfo(info *SysInfo, cgMounts map[string]string) []string { - var warnings []string - _, ok := cgMounts["pids"] +func applyPIDSCgroupInfo(info *SysInfo) { + _, ok := info.cgMounts["pids"] if !ok { - warnings = append(warnings, "Unable to find pids cgroup in mounts") - return warnings + info.Warnings = append(info.Warnings, "Unable to find pids cgroup in mounts") + return } info.PidsLimit = true - return warnings } // applyDevicesCgroupInfo adds whether the devices cgroup controller is available to the info. -func applyDevicesCgroupInfo(info *SysInfo, cgMounts map[string]string) []string { - var warnings []string - _, ok := cgMounts["devices"] +func applyDevicesCgroupInfo(info *SysInfo) { + _, ok := info.cgMounts["devices"] info.CgroupDevicesEnabled = ok - return warnings } // applyNetworkingInfo adds networking information to the info. -func applyNetworkingInfo(info *SysInfo, _ map[string]string) []string { - var warnings []string +func applyNetworkingInfo(info *SysInfo) { info.IPv4ForwardingDisabled = !readProcBool("/proc/sys/net/ipv4/ip_forward") info.BridgeNFCallIPTablesDisabled = !readProcBool("/proc/sys/net/bridge/bridge-nf-call-iptables") info.BridgeNFCallIP6TablesDisabled = !readProcBool("/proc/sys/net/bridge/bridge-nf-call-ip6tables") - return warnings } // applyAppArmorInfo adds whether AppArmor is enabled to the info. -func applyAppArmorInfo(info *SysInfo, _ map[string]string) []string { - var warnings []string +func applyAppArmorInfo(info *SysInfo) { if _, err := os.Stat("/sys/kernel/security/apparmor"); !os.IsNotExist(err) { if _, err := ioutil.ReadFile("/sys/kernel/security/apparmor/profiles"); err == nil { info.AppArmor = true } } - return warnings } // applyCgroupNsInfo adds whether cgroupns is enabled to the info. -func applyCgroupNsInfo(info *SysInfo, _ map[string]string) []string { - var warnings []string +func applyCgroupNsInfo(info *SysInfo) { if _, err := os.Stat("/proc/self/ns/cgroup"); !os.IsNotExist(err) { info.CgroupNamespaces = true } - return warnings } var ( @@ -285,8 +252,7 @@ var ( ) // applySeccompInfo checks if Seccomp is supported, via CONFIG_SECCOMP. -func applySeccompInfo(info *SysInfo, _ map[string]string) []string { - var warnings []string +func applySeccompInfo(info *SysInfo) { seccompOnce.Do(func() { // Check if Seccomp is supported, via CONFIG_SECCOMP. if err := unix.Prctl(unix.PR_GET_SECCOMP, 0, 0, 0, 0); err != unix.EINVAL { @@ -297,7 +263,6 @@ func applySeccompInfo(info *SysInfo, _ map[string]string) []string { } }) info.Seccomp = seccompEnabled - return warnings } func cgroupEnabled(mountPoint, name string) bool { diff --git a/pkg/sysinfo/sysinfo_linux_test.go b/pkg/sysinfo/sysinfo_linux_test.go index aa557c9230..3f4e684e3a 100644 --- a/pkg/sysinfo/sysinfo_linux_test.go +++ b/pkg/sysinfo/sysinfo_linux_test.go @@ -55,11 +55,7 @@ func TestCgroupEnabled(t *testing.T) { } func TestNew(t *testing.T) { - sysInfo := New(false) - assert.Assert(t, sysInfo != nil) - checkSysInfo(t, sysInfo) - - sysInfo = New(true) + sysInfo := New() assert.Assert(t, sysInfo != nil) checkSysInfo(t, sysInfo) } @@ -79,20 +75,20 @@ func checkSysInfo(t *testing.T, sysInfo *SysInfo) { func TestNewAppArmorEnabled(t *testing.T) { // Check if AppArmor is supported. then it must be TRUE , else FALSE if _, err := os.Stat("/sys/kernel/security/apparmor"); err != nil { - t.Skip("App Armor Must be Enabled") + t.Skip("AppArmor Must be Enabled") } - sysInfo := New(true) + sysInfo := New() assert.Assert(t, sysInfo.AppArmor) } func TestNewAppArmorDisabled(t *testing.T) { // Check if AppArmor is supported. then it must be TRUE , else FALSE if _, err := os.Stat("/sys/kernel/security/apparmor"); !os.IsNotExist(err) { - t.Skip("App Armor Must be Disabled") + t.Skip("AppArmor Must be Disabled") } - sysInfo := New(true) + sysInfo := New() assert.Assert(t, !sysInfo.AppArmor) } @@ -102,7 +98,7 @@ func TestNewCgroupNamespacesEnabled(t *testing.T) { t.Skip("cgroup namespaces must be enabled") } - sysInfo := New(true) + sysInfo := New() assert.Assert(t, sysInfo.CgroupNamespaces) } @@ -112,7 +108,7 @@ func TestNewCgroupNamespacesDisabled(t *testing.T) { t.Skip("cgroup namespaces must be disabled") } - sysInfo := New(true) + sysInfo := New() assert.Assert(t, !sysInfo.CgroupNamespaces) } diff --git a/pkg/sysinfo/sysinfo_other.go b/pkg/sysinfo/sysinfo_other.go new file mode 100644 index 0000000000..8ccc7d79bc --- /dev/null +++ b/pkg/sysinfo/sysinfo_other.go @@ -0,0 +1,8 @@ +// +build !linux + +package sysinfo // import "github.com/docker/docker/pkg/sysinfo" + +// New returns an empty SysInfo for non linux for now. +func New(options ...Opt) *SysInfo { + return &SysInfo{} +} diff --git a/pkg/sysinfo/sysinfo_unix.go b/pkg/sysinfo/sysinfo_unix.go deleted file mode 100644 index 47a131bc87..0000000000 --- a/pkg/sysinfo/sysinfo_unix.go +++ /dev/null @@ -1,14 +0,0 @@ -// +build !linux,!windows - -package sysinfo // import "github.com/docker/docker/pkg/sysinfo" - -type opts struct{} - -// Opt for New(). -type Opt func(*opts) - -// New returns an empty SysInfo for non linux for now. -func New(quiet bool, options ...Opt) *SysInfo { - sysInfo := &SysInfo{} - return sysInfo -} diff --git a/pkg/sysinfo/sysinfo_windows.go b/pkg/sysinfo/sysinfo_windows.go deleted file mode 100644 index 372e84af54..0000000000 --- a/pkg/sysinfo/sysinfo_windows.go +++ /dev/null @@ -1,12 +0,0 @@ -package sysinfo // import "github.com/docker/docker/pkg/sysinfo" - -type opts struct{} - -// Opt for New(). -type Opt func(*opts) - -// New returns an empty SysInfo for windows for now. -func New(quiet bool, options ...Opt) *SysInfo { - sysInfo := &SysInfo{} - return sysInfo -} diff --git a/runconfig/config.go b/runconfig/config.go index 3d435f54ae..41f953ac14 100644 --- a/runconfig/config.go +++ b/runconfig/config.go @@ -21,7 +21,7 @@ func (r ContainerDecoder) DecodeConfig(src io.Reader) (*container.Config, *conta if r.GetSysInfo != nil { si = r.GetSysInfo() } else { - si = sysinfo.New(true) + si = sysinfo.New() } return decodeContainerConfig(src, si) diff --git a/runconfig/config_test.go b/runconfig/config_test.go index 8b316e66e7..a2dc64ed0d 100644 --- a/runconfig/config_test.go +++ b/runconfig/config_test.go @@ -47,7 +47,7 @@ func TestDecodeContainerConfig(t *testing.T) { t.Fatal(err) } - c, h, _, err := decodeContainerConfig(bytes.NewReader(b), sysinfo.New(true)) + c, h, _, err := decodeContainerConfig(bytes.NewReader(b), sysinfo.New()) if err != nil { t.Fatal(fmt.Errorf("Error parsing %s: %v", f, err)) } @@ -131,5 +131,5 @@ func callDecodeContainerConfigIsolation(isolation string) (*container.Config, *c if b, err = json.Marshal(w); err != nil { return nil, nil, nil, fmt.Errorf("Error on marshal %s", err.Error()) } - return decodeContainerConfig(bytes.NewReader(b), sysinfo.New(true)) + return decodeContainerConfig(bytes.NewReader(b), sysinfo.New()) }