Browse code

Merge pull request #42639 from thaJeztah/system_info_clean

pkg/sysinfo: assorted cleanup/refactoring for handling warnings and logging

Justin Cormack authored on 2021/07/19 23:17:07
Showing 19 changed files
... ...
@@ -212,7 +212,12 @@ type Info struct {
212 212
 	SecurityOptions     []string
213 213
 	ProductLicense      string               `json:",omitempty"`
214 214
 	DefaultAddressPools []NetworkAddressPool `json:",omitempty"`
215
-	Warnings            []string
215
+
216
+	// Warnings contains a slice of warnings that occurred  while collecting
217
+	// system information. These warnings are intended to be informational
218
+	// messages for the user, and are not intended to be parsed / used for
219
+	// other purposes, as they do not have a fixed format.
220
+	Warnings []string
216 221
 }
217 222
 
218 223
 // KeyValue holds a key/value pair
... ...
@@ -478,14 +478,14 @@ func warnOnDeprecatedConfigOptions(config *config.Config) {
478 478
 func initRouter(opts routerOptions) {
479 479
 	decoder := runconfig.ContainerDecoder{
480 480
 		GetSysInfo: func() *sysinfo.SysInfo {
481
-			return opts.daemon.RawSysInfo(true)
481
+			return opts.daemon.RawSysInfo()
482 482
 		},
483 483
 	}
484 484
 
485 485
 	routers := []router.Router{
486 486
 		// we need to add the checkpoint router before the container router or the DELETE gets masked
487 487
 		checkpointrouter.NewRouter(opts.daemon, decoder),
488
-		container.NewRouter(opts.daemon, decoder, opts.daemon.RawSysInfo(true).CgroupUnified),
488
+		container.NewRouter(opts.daemon, decoder, opts.daemon.RawSysInfo().CgroupUnified),
489 489
 		image.NewRouter(opts.daemon.ImageService()),
490 490
 		systemrouter.NewRouter(opts.daemon, opts.cluster, opts.buildkit, opts.features),
491 491
 		volume.NewRouter(opts.daemon.VolumesService()),
... ...
@@ -1050,7 +1050,10 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
1050 1050
 		return nil, err
1051 1051
 	}
1052 1052
 
1053
-	sysInfo := d.RawSysInfo(false)
1053
+	sysInfo := d.RawSysInfo()
1054
+	for _, w := range sysInfo.Warnings {
1055
+		logrus.Warn(w)
1056
+	}
1054 1057
 	// Check if Devices cgroup is mounted, it is hard requirement for container security,
1055 1058
 	// on Linux.
1056 1059
 	if runtime.GOOS == "linux" && !sysInfo.CgroupDevicesEnabled && !userns.RunningInUserNS() {
... ...
@@ -666,7 +666,7 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.
666 666
 	if hostConfig == nil {
667 667
 		return nil, nil
668 668
 	}
669
-	sysInfo := daemon.RawSysInfo(true)
669
+	sysInfo := daemon.RawSysInfo()
670 670
 
671 671
 	w, err := verifyPlatformContainerResources(&hostConfig.Resources, sysInfo, update)
672 672
 
... ...
@@ -1718,14 +1718,14 @@ func (daemon *Daemon) setupSeccompProfile() error {
1718 1718
 }
1719 1719
 
1720 1720
 // RawSysInfo returns *sysinfo.SysInfo .
1721
-func (daemon *Daemon) RawSysInfo(quiet bool) *sysinfo.SysInfo {
1721
+func (daemon *Daemon) RawSysInfo() *sysinfo.SysInfo {
1722 1722
 	var siOpts []sysinfo.Opt
1723 1723
 	if daemon.getCgroupDriver() == cgroupSystemdDriver {
1724 1724
 		if euid := os.Getenv("ROOTLESSKIT_PARENT_EUID"); euid != "" {
1725 1725
 			siOpts = append(siOpts, sysinfo.WithCgroup2GroupPath("/user.slice/user-"+euid+".slice"))
1726 1726
 		}
1727 1727
 	}
1728
-	return sysinfo.New(quiet, siOpts...)
1728
+	return sysinfo.New(siOpts...)
1729 1729
 }
1730 1730
 
1731 1731
 func recursiveUnmount(target string) error {
... ...
@@ -13,6 +13,6 @@ func setupResolvConf(config *config.Config) {
13 13
 }
14 14
 
15 15
 // RawSysInfo returns *sysinfo.SysInfo .
16
-func (daemon *Daemon) RawSysInfo(quiet bool) *sysinfo.SysInfo {
17
-	return sysinfo.New(quiet)
16
+func (daemon *Daemon) RawSysInfo() *sysinfo.SysInfo {
17
+	return sysinfo.New()
18 18
 }
... ...
@@ -652,6 +652,6 @@ func setupResolvConf(config *config.Config) {
652 652
 }
653 653
 
654 654
 // RawSysInfo returns *sysinfo.SysInfo .
655
-func (daemon *Daemon) RawSysInfo(quiet bool) *sysinfo.SysInfo {
656
-	return sysinfo.New(quiet)
655
+func (daemon *Daemon) RawSysInfo() *sysinfo.SysInfo {
656
+	return sysinfo.New()
657 657
 }
... ...
@@ -30,7 +30,7 @@ import (
30 30
 func (daemon *Daemon) SystemInfo() *types.Info {
31 31
 	defer metrics.StartTimer(hostInfoFunctions.WithValues("system_info"))()
32 32
 
33
-	sysInfo := daemon.RawSysInfo(true)
33
+	sysInfo := daemon.RawSysInfo()
34 34
 	cRunning, cPaused, cStopped := stateCtr.get()
35 35
 
36 36
 	v := &types.Info{
... ...
@@ -824,7 +824,7 @@ func WithCgroups(daemon *Daemon, c *container.Container) coci.SpecOpts {
824 824
 		}
825 825
 
826 826
 		// FIXME this is very expensive way to check if cpu rt is supported
827
-		sysInfo := daemon.RawSysInfo(true)
827
+		sysInfo := daemon.RawSysInfo()
828 828
 		if !sysInfo.CPURealtime {
829 829
 			return errors.New("daemon-scoped cpu-rt-period and cpu-rt-runtime are not supported by the kernel")
830 830
 		}
... ...
@@ -699,7 +699,7 @@ func (s *DockerSuite) TestRunSwapLessThanMemoryLimit(c *testing.T) {
699 699
 func (s *DockerSuite) TestRunInvalidCpusetCpusFlagValue(c *testing.T) {
700 700
 	testRequires(c, cgroupCpuset, testEnv.IsLocalDaemon)
701 701
 
702
-	sysInfo := sysinfo.New(true)
702
+	sysInfo := sysinfo.New()
703 703
 	cpus, err := parsers.ParseUintList(sysInfo.Cpus)
704 704
 	assert.NilError(c, err)
705 705
 	var invalid int
... ...
@@ -718,7 +718,7 @@ func (s *DockerSuite) TestRunInvalidCpusetCpusFlagValue(c *testing.T) {
718 718
 func (s *DockerSuite) TestRunInvalidCpusetMemsFlagValue(c *testing.T) {
719 719
 	testRequires(c, cgroupCpuset)
720 720
 
721
-	sysInfo := sysinfo.New(true)
721
+	sysInfo := sysinfo.New()
722 722
 	mems, err := parsers.ParseUintList(sysInfo.Mems)
723 723
 	assert.NilError(c, err)
724 724
 	var invalid int
... ...
@@ -84,6 +84,6 @@ func overlayFSSupported() bool {
84 84
 
85 85
 func init() {
86 86
 	if testEnv.IsLocalDaemon() {
87
-		SysInfo = sysinfo.New(true)
87
+		SysInfo = sysinfo.New()
88 88
 	}
89 89
 }
... ...
@@ -12,58 +12,46 @@ import (
12 12
 	"github.com/sirupsen/logrus"
13 13
 )
14 14
 
15
-type infoCollectorV2 func(info *SysInfo, controllers map[string]struct{}, dirPath string) (warnings []string)
16
-
17
-func newV2(quiet bool, opts *opts) *SysInfo {
18
-	var warnings []string
15
+func newV2(options ...Opt) *SysInfo {
19 16
 	sysInfo := &SysInfo{
20 17
 		CgroupUnified: true,
18
+		cg2GroupPath:  "/",
21 19
 	}
22
-	g := opts.cg2GroupPath
23
-	if g == "" {
24
-		g = "/"
20
+	for _, o := range options {
21
+		o(sysInfo)
22
+	}
23
+
24
+	ops := []infoCollector{
25
+		applyNetworkingInfo,
26
+		applyAppArmorInfo,
27
+		applySeccompInfo,
28
+		applyCgroupNsInfo,
25 29
 	}
26
-	m, err := cgroupsV2.LoadManager("/sys/fs/cgroup", g)
30
+
31
+	m, err := cgroupsV2.LoadManager("/sys/fs/cgroup", sysInfo.cg2GroupPath)
27 32
 	if err != nil {
28 33
 		logrus.Warn(err)
29 34
 	} else {
30
-		controllersM := make(map[string]struct{})
35
+		sysInfo.cg2Controllers = make(map[string]struct{})
31 36
 		controllers, err := m.Controllers()
32 37
 		if err != nil {
33 38
 			logrus.Warn(err)
34 39
 		}
35 40
 		for _, c := range controllers {
36
-			controllersM[c] = struct{}{}
41
+			sysInfo.cg2Controllers[c] = struct{}{}
37 42
 		}
38
-		opsV2 := []infoCollectorV2{
43
+		ops = append(ops,
39 44
 			applyMemoryCgroupInfoV2,
40 45
 			applyCPUCgroupInfoV2,
41 46
 			applyIOCgroupInfoV2,
42 47
 			applyCPUSetCgroupInfoV2,
43 48
 			applyPIDSCgroupInfoV2,
44 49
 			applyDevicesCgroupInfoV2,
45
-		}
46
-		dirPath := path.Join("/sys/fs/cgroup", path.Clean(g))
47
-		for _, o := range opsV2 {
48
-			w := o(sysInfo, controllersM, dirPath)
49
-			warnings = append(warnings, w...)
50
-		}
50
+		)
51 51
 	}
52 52
 
53
-	ops := []infoCollector{
54
-		applyNetworkingInfo,
55
-		applyAppArmorInfo,
56
-		applySeccompInfo,
57
-		applyCgroupNsInfo,
58
-	}
59 53
 	for _, o := range ops {
60
-		w := o(sysInfo, nil)
61
-		warnings = append(warnings, w...)
62
-	}
63
-	if !quiet {
64
-		for _, w := range warnings {
65
-			logrus.Warn(w)
66
-		}
54
+		o(sysInfo)
67 55
 	}
68 56
 	return sysInfo
69 57
 }
... ...
@@ -86,11 +74,10 @@ func getSwapLimitV2() bool {
86 86
 	return true
87 87
 }
88 88
 
89
-func applyMemoryCgroupInfoV2(info *SysInfo, controllers map[string]struct{}, _ string) []string {
90
-	var warnings []string
91
-	if _, ok := controllers["memory"]; !ok {
92
-		warnings = append(warnings, "Unable to find memory controller")
93
-		return warnings
89
+func applyMemoryCgroupInfoV2(info *SysInfo) {
90
+	if _, ok := info.cg2Controllers["memory"]; !ok {
91
+		info.Warnings = append(info.Warnings, "Unable to find memory controller")
92
+		return
94 93
 	}
95 94
 
96 95
 	info.MemoryLimit = true
... ...
@@ -100,26 +87,22 @@ func applyMemoryCgroupInfoV2(info *SysInfo, controllers map[string]struct{}, _ s
100 100
 	info.MemorySwappiness = false
101 101
 	info.KernelMemory = false
102 102
 	info.KernelMemoryTCP = false
103
-	return warnings
104 103
 }
105 104
 
106
-func applyCPUCgroupInfoV2(info *SysInfo, controllers map[string]struct{}, _ string) []string {
107
-	var warnings []string
108
-	if _, ok := controllers["cpu"]; !ok {
109
-		warnings = append(warnings, "Unable to find cpu controller")
110
-		return warnings
105
+func applyCPUCgroupInfoV2(info *SysInfo) {
106
+	if _, ok := info.cg2Controllers["cpu"]; !ok {
107
+		info.Warnings = append(info.Warnings, "Unable to find cpu controller")
108
+		return
111 109
 	}
112 110
 	info.CPUShares = true
113 111
 	info.CPUCfs = true
114 112
 	info.CPURealtime = false
115
-	return warnings
116 113
 }
117 114
 
118
-func applyIOCgroupInfoV2(info *SysInfo, controllers map[string]struct{}, _ string) []string {
119
-	var warnings []string
120
-	if _, ok := controllers["io"]; !ok {
121
-		warnings = append(warnings, "Unable to find io controller")
122
-		return warnings
115
+func applyIOCgroupInfoV2(info *SysInfo) {
116
+	if _, ok := info.cg2Controllers["io"]; !ok {
117
+		info.Warnings = append(info.Warnings, "Unable to find io controller")
118
+		return
123 119
 	}
124 120
 
125 121
 	info.BlkioWeight = true
... ...
@@ -128,42 +111,36 @@ func applyIOCgroupInfoV2(info *SysInfo, controllers map[string]struct{}, _ strin
128 128
 	info.BlkioWriteBpsDevice = true
129 129
 	info.BlkioReadIOpsDevice = true
130 130
 	info.BlkioWriteIOpsDevice = true
131
-	return warnings
132 131
 }
133 132
 
134
-func applyCPUSetCgroupInfoV2(info *SysInfo, controllers map[string]struct{}, dirPath string) []string {
135
-	var warnings []string
136
-	if _, ok := controllers["cpuset"]; !ok {
137
-		warnings = append(warnings, "Unable to find cpuset controller")
138
-		return warnings
133
+func applyCPUSetCgroupInfoV2(info *SysInfo) {
134
+	if _, ok := info.cg2Controllers["cpuset"]; !ok {
135
+		info.Warnings = append(info.Warnings, "Unable to find cpuset controller")
136
+		return
139 137
 	}
140 138
 	info.Cpuset = true
141 139
 
142
-	cpus, err := ioutil.ReadFile(path.Join(dirPath, "cpuset.cpus.effective"))
140
+	cpus, err := ioutil.ReadFile(path.Join("/sys/fs/cgroup", info.cg2GroupPath, "cpuset.cpus.effective"))
143 141
 	if err != nil {
144
-		return warnings
142
+		return
145 143
 	}
146 144
 	info.Cpus = strings.TrimSpace(string(cpus))
147 145
 
148
-	mems, err := ioutil.ReadFile(path.Join(dirPath, "cpuset.mems.effective"))
146
+	mems, err := ioutil.ReadFile(path.Join("/sys/fs/cgroup", info.cg2GroupPath, "cpuset.mems.effective"))
149 147
 	if err != nil {
150
-		return warnings
148
+		return
151 149
 	}
152 150
 	info.Mems = strings.TrimSpace(string(mems))
153
-	return warnings
154 151
 }
155 152
 
156
-func applyPIDSCgroupInfoV2(info *SysInfo, controllers map[string]struct{}, _ string) []string {
157
-	var warnings []string
158
-	if _, ok := controllers["pids"]; !ok {
159
-		warnings = append(warnings, "Unable to find pids controller")
160
-		return warnings
153
+func applyPIDSCgroupInfoV2(info *SysInfo) {
154
+	if _, ok := info.cg2Controllers["pids"]; !ok {
155
+		info.Warnings = append(info.Warnings, "Unable to find pids controller")
156
+		return
161 157
 	}
162 158
 	info.PidsLimit = true
163
-	return warnings
164 159
 }
165 160
 
166
-func applyDevicesCgroupInfoV2(info *SysInfo, controllers map[string]struct{}, _ string) []string {
161
+func applyDevicesCgroupInfoV2(info *SysInfo) {
167 162
 	info.CgroupDevicesEnabled = !userns.RunningInUserNS()
168
-	return nil
169 163
 }
... ...
@@ -2,6 +2,9 @@ package sysinfo // import "github.com/docker/docker/pkg/sysinfo"
2 2
 
3 3
 import "github.com/docker/docker/pkg/parsers"
4 4
 
5
+// Opt for New().
6
+type Opt func(info *SysInfo)
7
+
5 8
 // SysInfo stores information about which features a kernel supports.
6 9
 // TODO Windows: Factor out platform specific capabilities.
7 10
 type SysInfo struct {
... ...
@@ -33,6 +36,23 @@ type SysInfo struct {
33 33
 
34 34
 	// Whether the cgroup is in unified mode (v2).
35 35
 	CgroupUnified bool
36
+
37
+	// Warnings contains a slice of warnings that occurred  while collecting
38
+	// system information. These warnings are intended to be informational
39
+	// messages for the user, and can either be logged or returned to the
40
+	// client; they are not intended to be parsed / used for other purposes,
41
+	// and do not have a fixed format.
42
+	Warnings []string
43
+
44
+	// cgMounts is the list of cgroup v1 mount paths, indexed by subsystem, to
45
+	// inspect availability of subsystems.
46
+	cgMounts map[string]string
47
+
48
+	// cg2GroupPath is the cgroup v2 group path to inspect availability of the controllers.
49
+	cg2GroupPath string
50
+
51
+	// cg2Controllers is an index of available cgroup v2 controllers.
52
+	cg2Controllers map[string]struct{}
36 53
 }
37 54
 
38 55
 type cgroupMemInfo struct {
... ...
@@ -28,14 +28,7 @@ func findCgroupMountpoints() (map[string]string, error) {
28 28
 	return mps, nil
29 29
 }
30 30
 
31
-type infoCollector func(info *SysInfo, cgMounts map[string]string) (warnings []string)
32
-
33
-type opts struct {
34
-	cg2GroupPath string
35
-}
36
-
37
-// Opt for New().
38
-type Opt func(*opts)
31
+type infoCollector func(info *SysInfo)
39 32
 
40 33
 // WithCgroup2GroupPath specifies the cgroup v2 group path to inspect availability
41 34
 // of the controllers.
... ...
@@ -44,172 +37,158 @@ type Opt func(*opts)
44 44
 //
45 45
 // e.g. g = "/user.slice/user-1000.slice/user@1000.service"
46 46
 func WithCgroup2GroupPath(g string) Opt {
47
-	return func(o *opts) {
48
-		o.cg2GroupPath = path.Clean(g)
47
+	return func(o *SysInfo) {
48
+		if p := path.Clean(g); p != "" {
49
+			o.cg2GroupPath = p
50
+		}
49 51
 	}
50 52
 }
51 53
 
52 54
 // New returns a new SysInfo, using the filesystem to detect which features
53
-// the kernel supports. If `quiet` is `false` warnings are printed in logs
54
-// whenever an error occurs or misconfigurations are present.
55
-func New(quiet bool, options ...Opt) *SysInfo {
56
-	var opts opts
57
-	for _, o := range options {
58
-		o(&opts)
59
-	}
55
+// the kernel supports.
56
+func New(options ...Opt) *SysInfo {
60 57
 	if cdcgroups.Mode() == cdcgroups.Unified {
61
-		return newV2(quiet, &opts)
58
+		return newV2(options...)
59
+	}
60
+	return newV1()
61
+}
62
+
63
+func newV1() *SysInfo {
64
+	var (
65
+		err     error
66
+		sysInfo = &SysInfo{}
67
+	)
68
+
69
+	ops := []infoCollector{
70
+		applyNetworkingInfo,
71
+		applyAppArmorInfo,
72
+		applySeccompInfo,
73
+		applyCgroupNsInfo,
62 74
 	}
63 75
 
64
-	var ops []infoCollector
65
-	var warnings []string
66
-	sysInfo := &SysInfo{}
67
-	cgMounts, err := findCgroupMountpoints()
76
+	sysInfo.cgMounts, err = findCgroupMountpoints()
68 77
 	if err != nil {
69 78
 		logrus.Warn(err)
70 79
 	} else {
71
-		ops = append(ops, []infoCollector{
80
+		ops = append(ops,
72 81
 			applyMemoryCgroupInfo,
73 82
 			applyCPUCgroupInfo,
74 83
 			applyBlkioCgroupInfo,
75 84
 			applyCPUSetCgroupInfo,
76 85
 			applyPIDSCgroupInfo,
77 86
 			applyDevicesCgroupInfo,
78
-		}...)
87
+		)
79 88
 	}
80 89
 
81
-	ops = append(ops, []infoCollector{
82
-		applyNetworkingInfo,
83
-		applyAppArmorInfo,
84
-		applySeccompInfo,
85
-		applyCgroupNsInfo,
86
-	}...)
87
-
88 90
 	for _, o := range ops {
89
-		w := o(sysInfo, cgMounts)
90
-		warnings = append(warnings, w...)
91
-	}
92
-	if !quiet {
93
-		for _, w := range warnings {
94
-			logrus.Warn(w)
95
-		}
91
+		o(sysInfo)
96 92
 	}
97 93
 	return sysInfo
98 94
 }
99 95
 
100 96
 // applyMemoryCgroupInfo adds the memory cgroup controller information to the info.
101
-func applyMemoryCgroupInfo(info *SysInfo, cgMounts map[string]string) []string {
102
-	var warnings []string
103
-	mountPoint, ok := cgMounts["memory"]
97
+func applyMemoryCgroupInfo(info *SysInfo) {
98
+	mountPoint, ok := info.cgMounts["memory"]
104 99
 	if !ok {
105
-		warnings = append(warnings, "Your kernel does not support cgroup memory limit")
106
-		return warnings
100
+		info.Warnings = append(info.Warnings, "Your kernel does not support cgroup memory limit")
101
+		return
107 102
 	}
108 103
 	info.MemoryLimit = ok
109 104
 
110 105
 	info.SwapLimit = cgroupEnabled(mountPoint, "memory.memsw.limit_in_bytes")
111 106
 	if !info.SwapLimit {
112
-		warnings = append(warnings, "Your kernel does not support swap memory limit")
107
+		info.Warnings = append(info.Warnings, "Your kernel does not support swap memory limit")
113 108
 	}
114 109
 	info.MemoryReservation = cgroupEnabled(mountPoint, "memory.soft_limit_in_bytes")
115 110
 	if !info.MemoryReservation {
116
-		warnings = append(warnings, "Your kernel does not support memory reservation")
111
+		info.Warnings = append(info.Warnings, "Your kernel does not support memory reservation")
117 112
 	}
118 113
 	info.OomKillDisable = cgroupEnabled(mountPoint, "memory.oom_control")
119 114
 	if !info.OomKillDisable {
120
-		warnings = append(warnings, "Your kernel does not support oom control")
115
+		info.Warnings = append(info.Warnings, "Your kernel does not support oom control")
121 116
 	}
122 117
 	info.MemorySwappiness = cgroupEnabled(mountPoint, "memory.swappiness")
123 118
 	if !info.MemorySwappiness {
124
-		warnings = append(warnings, "Your kernel does not support memory swappiness")
119
+		info.Warnings = append(info.Warnings, "Your kernel does not support memory swappiness")
125 120
 	}
126 121
 	info.KernelMemory = cgroupEnabled(mountPoint, "memory.kmem.limit_in_bytes")
127 122
 	if !info.KernelMemory {
128
-		warnings = append(warnings, "Your kernel does not support kernel memory limit")
123
+		info.Warnings = append(info.Warnings, "Your kernel does not support kernel memory limit")
129 124
 	}
130 125
 	info.KernelMemoryTCP = cgroupEnabled(mountPoint, "memory.kmem.tcp.limit_in_bytes")
131 126
 	if !info.KernelMemoryTCP {
132
-		warnings = append(warnings, "Your kernel does not support kernel memory TCP limit")
127
+		info.Warnings = append(info.Warnings, "Your kernel does not support kernel memory TCP limit")
133 128
 	}
134
-
135
-	return warnings
136 129
 }
137 130
 
138 131
 // applyCPUCgroupInfo adds the cpu cgroup controller information to the info.
139
-func applyCPUCgroupInfo(info *SysInfo, cgMounts map[string]string) []string {
140
-	var warnings []string
141
-	mountPoint, ok := cgMounts["cpu"]
132
+func applyCPUCgroupInfo(info *SysInfo) {
133
+	mountPoint, ok := info.cgMounts["cpu"]
142 134
 	if !ok {
143
-		warnings = append(warnings, "Unable to find cpu cgroup in mounts")
144
-		return warnings
135
+		info.Warnings = append(info.Warnings, "Unable to find cpu cgroup in mounts")
136
+		return
145 137
 	}
146 138
 
147 139
 	info.CPUShares = cgroupEnabled(mountPoint, "cpu.shares")
148 140
 	if !info.CPUShares {
149
-		warnings = append(warnings, "Your kernel does not support CPU shares")
141
+		info.Warnings = append(info.Warnings, "Your kernel does not support CPU shares")
150 142
 	}
151 143
 
152 144
 	info.CPUCfs = cgroupEnabled(mountPoint, "cpu.cfs_quota_us")
153 145
 	if !info.CPUCfs {
154
-		warnings = append(warnings, "Your kernel does not support CPU CFS scheduler")
146
+		info.Warnings = append(info.Warnings, "Your kernel does not support CPU CFS scheduler")
155 147
 	}
156 148
 
157 149
 	info.CPURealtime = cgroupEnabled(mountPoint, "cpu.rt_period_us")
158 150
 	if !info.CPURealtime {
159
-		warnings = append(warnings, "Your kernel does not support CPU realtime scheduler")
151
+		info.Warnings = append(info.Warnings, "Your kernel does not support CPU realtime scheduler")
160 152
 	}
161
-
162
-	return warnings
163 153
 }
164 154
 
165 155
 // applyBlkioCgroupInfo adds the blkio cgroup controller information to the info.
166
-func applyBlkioCgroupInfo(info *SysInfo, cgMounts map[string]string) []string {
167
-	var warnings []string
168
-	mountPoint, ok := cgMounts["blkio"]
156
+func applyBlkioCgroupInfo(info *SysInfo) {
157
+	mountPoint, ok := info.cgMounts["blkio"]
169 158
 	if !ok {
170
-		warnings = append(warnings, "Unable to find blkio cgroup in mounts")
171
-		return warnings
159
+		info.Warnings = append(info.Warnings, "Unable to find blkio cgroup in mounts")
160
+		return
172 161
 	}
173 162
 
174 163
 	info.BlkioWeight = cgroupEnabled(mountPoint, "blkio.weight")
175 164
 	if !info.BlkioWeight {
176
-		warnings = append(warnings, "Your kernel does not support cgroup blkio weight")
165
+		info.Warnings = append(info.Warnings, "Your kernel does not support cgroup blkio weight")
177 166
 	}
178 167
 
179 168
 	info.BlkioWeightDevice = cgroupEnabled(mountPoint, "blkio.weight_device")
180 169
 	if !info.BlkioWeightDevice {
181
-		warnings = append(warnings, "Your kernel does not support cgroup blkio weight_device")
170
+		info.Warnings = append(info.Warnings, "Your kernel does not support cgroup blkio weight_device")
182 171
 	}
183 172
 
184 173
 	info.BlkioReadBpsDevice = cgroupEnabled(mountPoint, "blkio.throttle.read_bps_device")
185 174
 	if !info.BlkioReadBpsDevice {
186
-		warnings = append(warnings, "Your kernel does not support cgroup blkio throttle.read_bps_device")
175
+		info.Warnings = append(info.Warnings, "Your kernel does not support cgroup blkio throttle.read_bps_device")
187 176
 	}
188 177
 
189 178
 	info.BlkioWriteBpsDevice = cgroupEnabled(mountPoint, "blkio.throttle.write_bps_device")
190 179
 	if !info.BlkioWriteBpsDevice {
191
-		warnings = append(warnings, "Your kernel does not support cgroup blkio throttle.write_bps_device")
180
+		info.Warnings = append(info.Warnings, "Your kernel does not support cgroup blkio throttle.write_bps_device")
192 181
 	}
193 182
 	info.BlkioReadIOpsDevice = cgroupEnabled(mountPoint, "blkio.throttle.read_iops_device")
194 183
 	if !info.BlkioReadIOpsDevice {
195
-		warnings = append(warnings, "Your kernel does not support cgroup blkio throttle.read_iops_device")
184
+		info.Warnings = append(info.Warnings, "Your kernel does not support cgroup blkio throttle.read_iops_device")
196 185
 	}
197 186
 
198 187
 	info.BlkioWriteIOpsDevice = cgroupEnabled(mountPoint, "blkio.throttle.write_iops_device")
199 188
 	if !info.BlkioWriteIOpsDevice {
200
-		warnings = append(warnings, "Your kernel does not support cgroup blkio throttle.write_iops_device")
189
+		info.Warnings = append(info.Warnings, "Your kernel does not support cgroup blkio throttle.write_iops_device")
201 190
 	}
202
-
203
-	return warnings
204 191
 }
205 192
 
206 193
 // applyCPUSetCgroupInfo adds the cpuset cgroup controller information to the info.
207
-func applyCPUSetCgroupInfo(info *SysInfo, cgMounts map[string]string) []string {
208
-	var warnings []string
209
-	mountPoint, ok := cgMounts["cpuset"]
194
+func applyCPUSetCgroupInfo(info *SysInfo) {
195
+	mountPoint, ok := info.cgMounts["cpuset"]
210 196
 	if !ok {
211
-		warnings = append(warnings, "Unable to find cpuset cgroup in mounts")
212
-		return warnings
197
+		info.Warnings = append(info.Warnings, "Unable to find cpuset cgroup in mounts")
198
+		return
213 199
 	}
214 200
 	info.Cpuset = ok
215 201
 
... ...
@@ -217,66 +196,54 @@ func applyCPUSetCgroupInfo(info *SysInfo, cgMounts map[string]string) []string {
217 217
 
218 218
 	cpus, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.cpus"))
219 219
 	if err != nil {
220
-		return warnings
220
+		return
221 221
 	}
222 222
 	info.Cpus = strings.TrimSpace(string(cpus))
223 223
 
224 224
 	mems, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.mems"))
225 225
 	if err != nil {
226
-		return warnings
226
+		return
227 227
 	}
228 228
 	info.Mems = strings.TrimSpace(string(mems))
229
-
230
-	return warnings
231 229
 }
232 230
 
233 231
 // applyPIDSCgroupInfo adds whether the pids cgroup controller is available to the info.
234
-func applyPIDSCgroupInfo(info *SysInfo, cgMounts map[string]string) []string {
235
-	var warnings []string
236
-	_, ok := cgMounts["pids"]
232
+func applyPIDSCgroupInfo(info *SysInfo) {
233
+	_, ok := info.cgMounts["pids"]
237 234
 	if !ok {
238
-		warnings = append(warnings, "Unable to find pids cgroup in mounts")
239
-		return warnings
235
+		info.Warnings = append(info.Warnings, "Unable to find pids cgroup in mounts")
236
+		return
240 237
 	}
241 238
 	info.PidsLimit = true
242
-	return warnings
243 239
 }
244 240
 
245 241
 // applyDevicesCgroupInfo adds whether the devices cgroup controller is available to the info.
246
-func applyDevicesCgroupInfo(info *SysInfo, cgMounts map[string]string) []string {
247
-	var warnings []string
248
-	_, ok := cgMounts["devices"]
242
+func applyDevicesCgroupInfo(info *SysInfo) {
243
+	_, ok := info.cgMounts["devices"]
249 244
 	info.CgroupDevicesEnabled = ok
250
-	return warnings
251 245
 }
252 246
 
253 247
 // applyNetworkingInfo adds networking information to the info.
254
-func applyNetworkingInfo(info *SysInfo, _ map[string]string) []string {
255
-	var warnings []string
248
+func applyNetworkingInfo(info *SysInfo) {
256 249
 	info.IPv4ForwardingDisabled = !readProcBool("/proc/sys/net/ipv4/ip_forward")
257 250
 	info.BridgeNFCallIPTablesDisabled = !readProcBool("/proc/sys/net/bridge/bridge-nf-call-iptables")
258 251
 	info.BridgeNFCallIP6TablesDisabled = !readProcBool("/proc/sys/net/bridge/bridge-nf-call-ip6tables")
259
-	return warnings
260 252
 }
261 253
 
262 254
 // applyAppArmorInfo adds whether AppArmor is enabled to the info.
263
-func applyAppArmorInfo(info *SysInfo, _ map[string]string) []string {
264
-	var warnings []string
255
+func applyAppArmorInfo(info *SysInfo) {
265 256
 	if _, err := os.Stat("/sys/kernel/security/apparmor"); !os.IsNotExist(err) {
266 257
 		if _, err := ioutil.ReadFile("/sys/kernel/security/apparmor/profiles"); err == nil {
267 258
 			info.AppArmor = true
268 259
 		}
269 260
 	}
270
-	return warnings
271 261
 }
272 262
 
273 263
 // applyCgroupNsInfo adds whether cgroupns is enabled to the info.
274
-func applyCgroupNsInfo(info *SysInfo, _ map[string]string) []string {
275
-	var warnings []string
264
+func applyCgroupNsInfo(info *SysInfo) {
276 265
 	if _, err := os.Stat("/proc/self/ns/cgroup"); !os.IsNotExist(err) {
277 266
 		info.CgroupNamespaces = true
278 267
 	}
279
-	return warnings
280 268
 }
281 269
 
282 270
 var (
... ...
@@ -285,8 +252,7 @@ var (
285 285
 )
286 286
 
287 287
 // applySeccompInfo checks if Seccomp is supported, via CONFIG_SECCOMP.
288
-func applySeccompInfo(info *SysInfo, _ map[string]string) []string {
289
-	var warnings []string
288
+func applySeccompInfo(info *SysInfo) {
290 289
 	seccompOnce.Do(func() {
291 290
 		// Check if Seccomp is supported, via CONFIG_SECCOMP.
292 291
 		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 {
297 297
 		}
298 298
 	})
299 299
 	info.Seccomp = seccompEnabled
300
-	return warnings
301 300
 }
302 301
 
303 302
 func cgroupEnabled(mountPoint, name string) bool {
... ...
@@ -55,11 +55,7 @@ func TestCgroupEnabled(t *testing.T) {
55 55
 }
56 56
 
57 57
 func TestNew(t *testing.T) {
58
-	sysInfo := New(false)
59
-	assert.Assert(t, sysInfo != nil)
60
-	checkSysInfo(t, sysInfo)
61
-
62
-	sysInfo = New(true)
58
+	sysInfo := New()
63 59
 	assert.Assert(t, sysInfo != nil)
64 60
 	checkSysInfo(t, sysInfo)
65 61
 }
... ...
@@ -79,20 +75,20 @@ func checkSysInfo(t *testing.T, sysInfo *SysInfo) {
79 79
 func TestNewAppArmorEnabled(t *testing.T) {
80 80
 	// Check if AppArmor is supported. then it must be TRUE , else FALSE
81 81
 	if _, err := os.Stat("/sys/kernel/security/apparmor"); err != nil {
82
-		t.Skip("App Armor Must be Enabled")
82
+		t.Skip("AppArmor Must be Enabled")
83 83
 	}
84 84
 
85
-	sysInfo := New(true)
85
+	sysInfo := New()
86 86
 	assert.Assert(t, sysInfo.AppArmor)
87 87
 }
88 88
 
89 89
 func TestNewAppArmorDisabled(t *testing.T) {
90 90
 	// Check if AppArmor is supported. then it must be TRUE , else FALSE
91 91
 	if _, err := os.Stat("/sys/kernel/security/apparmor"); !os.IsNotExist(err) {
92
-		t.Skip("App Armor Must be Disabled")
92
+		t.Skip("AppArmor Must be Disabled")
93 93
 	}
94 94
 
95
-	sysInfo := New(true)
95
+	sysInfo := New()
96 96
 	assert.Assert(t, !sysInfo.AppArmor)
97 97
 }
98 98
 
... ...
@@ -102,7 +98,7 @@ func TestNewCgroupNamespacesEnabled(t *testing.T) {
102 102
 		t.Skip("cgroup namespaces must be enabled")
103 103
 	}
104 104
 
105
-	sysInfo := New(true)
105
+	sysInfo := New()
106 106
 	assert.Assert(t, sysInfo.CgroupNamespaces)
107 107
 }
108 108
 
... ...
@@ -112,7 +108,7 @@ func TestNewCgroupNamespacesDisabled(t *testing.T) {
112 112
 		t.Skip("cgroup namespaces must be disabled")
113 113
 	}
114 114
 
115
-	sysInfo := New(true)
115
+	sysInfo := New()
116 116
 	assert.Assert(t, !sysInfo.CgroupNamespaces)
117 117
 }
118 118
 
119 119
new file mode 100644
... ...
@@ -0,0 +1,8 @@
0
+// +build !linux
1
+
2
+package sysinfo // import "github.com/docker/docker/pkg/sysinfo"
3
+
4
+// New returns an empty SysInfo for non linux for now.
5
+func New(options ...Opt) *SysInfo {
6
+	return &SysInfo{}
7
+}
0 8
deleted file mode 100644
... ...
@@ -1,14 +0,0 @@
1
-// +build !linux,!windows
2
-
3
-package sysinfo // import "github.com/docker/docker/pkg/sysinfo"
4
-
5
-type opts struct{}
6
-
7
-// Opt for New().
8
-type Opt func(*opts)
9
-
10
-// New returns an empty SysInfo for non linux for now.
11
-func New(quiet bool, options ...Opt) *SysInfo {
12
-	sysInfo := &SysInfo{}
13
-	return sysInfo
14
-}
15 1
deleted file mode 100644
... ...
@@ -1,12 +0,0 @@
1
-package sysinfo // import "github.com/docker/docker/pkg/sysinfo"
2
-
3
-type opts struct{}
4
-
5
-// Opt for New().
6
-type Opt func(*opts)
7
-
8
-// New returns an empty SysInfo for windows for now.
9
-func New(quiet bool, options ...Opt) *SysInfo {
10
-	sysInfo := &SysInfo{}
11
-	return sysInfo
12
-}
... ...
@@ -21,7 +21,7 @@ func (r ContainerDecoder) DecodeConfig(src io.Reader) (*container.Config, *conta
21 21
 	if r.GetSysInfo != nil {
22 22
 		si = r.GetSysInfo()
23 23
 	} else {
24
-		si = sysinfo.New(true)
24
+		si = sysinfo.New()
25 25
 	}
26 26
 
27 27
 	return decodeContainerConfig(src, si)
... ...
@@ -47,7 +47,7 @@ func TestDecodeContainerConfig(t *testing.T) {
47 47
 			t.Fatal(err)
48 48
 		}
49 49
 
50
-		c, h, _, err := decodeContainerConfig(bytes.NewReader(b), sysinfo.New(true))
50
+		c, h, _, err := decodeContainerConfig(bytes.NewReader(b), sysinfo.New())
51 51
 		if err != nil {
52 52
 			t.Fatal(fmt.Errorf("Error parsing %s: %v", f, err))
53 53
 		}
... ...
@@ -131,5 +131,5 @@ func callDecodeContainerConfigIsolation(isolation string) (*container.Config, *c
131 131
 	if b, err = json.Marshal(w); err != nil {
132 132
 		return nil, nil, nil, fmt.Errorf("Error on marshal %s", err.Error())
133 133
 	}
134
-	return decodeContainerConfig(bytes.NewReader(b), sysinfo.New(true))
134
+	return decodeContainerConfig(bytes.NewReader(b), sysinfo.New())
135 135
 }