diff --git a/api/types/types.go b/api/types/types.go index 9d31f70d6457a29be61d10c9b3a5782ca7b0c99d..d6017898d0ce95cb28c98d17529bf08781e6d8e6 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 1841253a061a6b2a6a2aad39ccf859b78cc35849..842c948f8a20e1e585dd343d650b0c801fdc90c1 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 e6c0425e02ebeec46eac6c66b0a5b86a9d3a3612..ced869a38000fae72b7c0c508864d9b2b2b542b6 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 55f82ba839a55610b8919b2f3e2341742d55ca4d..51b7ad4b7b1771b3a02f7187f3a51aed52ec7bdc 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 4c2476edcf486480027506b59c1f59d4d9e7b562..e8bebca3e41d53e732433ceeecc6b1401f86bfed 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 76e3701f8a0ff471b949eca8e2458619a3c35512..a87f700bb0702ca924969f32c861d4debdbdaad6 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 15b78ebe1cd5a060c5ee86cb1568a4856645fc77..7c9f7e6ab86f9458677d9e241532f351590da637 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 6358450d3788bf94621bbded84106fc5d1ba21e2..a5720537b9bcca251a7a77d29dd46023450120ad 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 4670468b5e16bba3d87bf32a66ec39b12b9b5efe..f6915056cd18cb7cdf2f5c531cfd23fc76a00f02 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 8c75b26424a9140025a434e7d804e1fb26c1df15..7086966a664933ad410afb13d77d1bd65d17a185 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 1ea3cd51d95cb8ea6b4d7ee9716a8b5d856471f3..e62769a6ee1b7715b14713b16bd40e8bbbbe1b53 100644 --- a/pkg/sysinfo/cgroup2_linux.go +++ b/pkg/sysinfo/cgroup2_linux.go @@ -12,58 +12,46 @@ 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 = "/" + for _, o := range options { + o(sysInfo) + } + + ops := []infoCollector{ + applyNetworkingInfo, + applyAppArmorInfo, + applySeccompInfo, + applyCgroupNsInfo, } - m, err := cgroupsV2.LoadManager("/sys/fs/cgroup", g) + + m, err := cgroupsV2.LoadManager("/sys/fs/cgroup", sysInfo.cg2GroupPath) if err != nil { logrus.Warn(err) } else { - controllersM := make(map[string]struct{}) + sysInfo.cg2Controllers = make(map[string]struct{}) controllers, err := m.Controllers() if err != nil { logrus.Warn(err) } for _, c := range controllers { - controllersM[c] = struct{}{} + sysInfo.cg2Controllers[c] = struct{}{} } - opsV2 := []infoCollectorV2{ + ops = append(ops, 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...) - } + ) } - ops := []infoCollector{ - applyNetworkingInfo, - applyAppArmorInfo, - applySeccompInfo, - applyCgroupNsInfo, - } for _, o := range ops { - w := o(sysInfo, nil) - warnings = append(warnings, w...) - } - if !quiet { - for _, w := range warnings { - logrus.Warn(w) - } + 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 6e4b16847ab981fe186bdb4c9529b12dd05a9080..ac8a41758136c2ff29c409151ab82704affce8fe 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 42709a4d353607bffdc86b453fa56b3f5dfd700e..f4a8f324433d831d102d190a7ae924b500f59255 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 aa557c9230be58d954abbcc3de8c81eb0621cb1a..3f4e684e3a5215cb6d44d9a25e23b921b4a8bf0a 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 0000000000000000000000000000000000000000..8ccc7d79bca825741394bd256877ed7bdd79ad59 --- /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 47a131bc878f83b81e8a81a239e1e0afd46fc94e..0000000000000000000000000000000000000000 --- 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 372e84af5402fc6141aa947ac205623562f7c191..0000000000000000000000000000000000000000 --- 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 3d435f54ae07be028d588cd13027999653f8e17a..41f953ac149a1d519ba0b39278db39dc400b5a98 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 8b316e66e7519974bb9551a53e8e13e81d48ce57..a2dc64ed0d7928edbefc86264c62a98d88078a20 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()) }