requirements_unix.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // +build !windows
  2. package main
  3. import (
  4. "bytes"
  5. "io/ioutil"
  6. "os/exec"
  7. "strings"
  8. "github.com/docker/docker/pkg/parsers/kernel"
  9. "github.com/docker/docker/pkg/sysinfo"
  10. )
  11. var (
  12. // SysInfo stores information about which features a kernel supports.
  13. SysInfo *sysinfo.SysInfo
  14. cpuCfsPeriod = testRequirement{
  15. func() bool {
  16. return SysInfo.CPUCfsPeriod
  17. },
  18. "Test requires an environment that supports cgroup cfs period.",
  19. }
  20. cpuCfsQuota = testRequirement{
  21. func() bool {
  22. return SysInfo.CPUCfsQuota
  23. },
  24. "Test requires an environment that supports cgroup cfs quota.",
  25. }
  26. cpuShare = testRequirement{
  27. func() bool {
  28. return SysInfo.CPUShares
  29. },
  30. "Test requires an environment that supports cgroup cpu shares.",
  31. }
  32. oomControl = testRequirement{
  33. func() bool {
  34. return SysInfo.OomKillDisable
  35. },
  36. "Test requires Oom control enabled.",
  37. }
  38. pidsLimit = testRequirement{
  39. func() bool {
  40. return SysInfo.PidsLimit
  41. },
  42. "Test requires pids limit enabled.",
  43. }
  44. kernelMemorySupport = testRequirement{
  45. func() bool {
  46. return SysInfo.KernelMemory
  47. },
  48. "Test requires an environment that supports cgroup kernel memory.",
  49. }
  50. memoryLimitSupport = testRequirement{
  51. func() bool {
  52. return SysInfo.MemoryLimit
  53. },
  54. "Test requires an environment that supports cgroup memory limit.",
  55. }
  56. memoryReservationSupport = testRequirement{
  57. func() bool {
  58. return SysInfo.MemoryReservation
  59. },
  60. "Test requires an environment that supports cgroup memory reservation.",
  61. }
  62. swapMemorySupport = testRequirement{
  63. func() bool {
  64. return SysInfo.SwapLimit
  65. },
  66. "Test requires an environment that supports cgroup swap memory limit.",
  67. }
  68. memorySwappinessSupport = testRequirement{
  69. func() bool {
  70. return SysInfo.MemorySwappiness
  71. },
  72. "Test requires an environment that supports cgroup memory swappiness.",
  73. }
  74. blkioWeight = testRequirement{
  75. func() bool {
  76. return SysInfo.BlkioWeight
  77. },
  78. "Test requires an environment that supports blkio weight.",
  79. }
  80. cgroupCpuset = testRequirement{
  81. func() bool {
  82. return SysInfo.Cpuset
  83. },
  84. "Test requires an environment that supports cgroup cpuset.",
  85. }
  86. seccompEnabled = testRequirement{
  87. func() bool {
  88. return supportsSeccomp && SysInfo.Seccomp
  89. },
  90. "Test requires that seccomp support be enabled in the daemon.",
  91. }
  92. bridgeNfIptables = testRequirement{
  93. func() bool {
  94. return !SysInfo.BridgeNFCallIPTablesDisabled
  95. },
  96. "Test requires that bridge-nf-call-iptables support be enabled in the daemon.",
  97. }
  98. bridgeNfIP6tables = testRequirement{
  99. func() bool {
  100. return !SysInfo.BridgeNFCallIP6TablesDisabled
  101. },
  102. "Test requires that bridge-nf-call-ip6tables support be enabled in the daemon.",
  103. }
  104. unprivilegedUsernsClone = testRequirement{
  105. func() bool {
  106. content, err := ioutil.ReadFile("/proc/sys/kernel/unprivileged_userns_clone")
  107. if err == nil && strings.Contains(string(content), "0") {
  108. return false
  109. }
  110. return true
  111. },
  112. "Test cannot be run with 'sysctl kernel.unprivileged_userns_clone' = 0",
  113. }
  114. ambientCapabilities = testRequirement{
  115. func() bool {
  116. content, err := ioutil.ReadFile("/proc/self/status")
  117. if err == nil && strings.Contains(string(content), "CapAmb:") {
  118. return true
  119. }
  120. return false
  121. },
  122. "Test cannot be run without a kernel (4.3+) supporting ambient capabilities",
  123. }
  124. overlayFSSupported = testRequirement{
  125. func() bool {
  126. cmd := exec.Command(dockerBinary, "run", "--rm", "busybox", "/bin/sh", "-c", "cat /proc/filesystems")
  127. out, err := cmd.CombinedOutput()
  128. if err != nil {
  129. return false
  130. }
  131. return bytes.Contains(out, []byte("overlay\n"))
  132. },
  133. "Test cannot be run without suppport for overlayfs",
  134. }
  135. overlay2Supported = testRequirement{
  136. func() bool {
  137. if !overlayFSSupported.Condition() {
  138. return false
  139. }
  140. daemonV, err := kernel.ParseRelease(daemonKernelVersion)
  141. if err != nil {
  142. return false
  143. }
  144. requiredV := kernel.VersionInfo{Kernel: 4}
  145. return kernel.CompareKernelVersion(*daemonV, requiredV) > -1
  146. },
  147. "Test cannot be run without overlay2 support (kernel 4.0+)",
  148. }
  149. )
  150. func init() {
  151. SysInfo = sysinfo.New(true)
  152. }