github.com/containerd/nerdctl@v1.7.7/pkg/infoutil/infoutil_linux.go (about) 1 /* 2 Copyright The containerd Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package infoutil 18 19 import ( 20 "fmt" 21 "strings" 22 23 "github.com/containerd/cgroups/v3" 24 "github.com/containerd/nerdctl/pkg/apparmorutil" 25 "github.com/containerd/nerdctl/pkg/defaults" 26 "github.com/containerd/nerdctl/pkg/inspecttypes/dockercompat" 27 "github.com/containerd/nerdctl/pkg/rootlessutil" 28 "github.com/docker/docker/pkg/meminfo" 29 "github.com/docker/docker/pkg/sysinfo" 30 ) 31 32 const UnameO = "GNU/Linux" 33 34 func CgroupsVersion() string { 35 if cgroups.Mode() == cgroups.Unified { 36 return "2" 37 } 38 39 return "1" 40 } 41 42 func fulfillSecurityOptions(info *dockercompat.Info) { 43 if apparmorutil.CanApplyExistingProfile() { 44 info.SecurityOptions = append(info.SecurityOptions, "name=apparmor") 45 if rootlessutil.IsRootless() && !apparmorutil.CanApplySpecificExistingProfile(defaults.AppArmorProfileName) { 46 info.Warnings = append(info.Warnings, fmt.Sprintf(strings.TrimSpace(` 47 WARNING: AppArmor profile %q is not loaded. 48 Use 'sudo nerdctl apparmor load' if you prefer to use AppArmor with rootless mode. 49 This warning is negligible if you do not intend to use AppArmor.`), defaults.AppArmorProfileName)) 50 } 51 } 52 info.SecurityOptions = append(info.SecurityOptions, "name=seccomp,profile="+defaults.SeccompProfileName) 53 if defaults.CgroupnsMode() == "private" { 54 info.SecurityOptions = append(info.SecurityOptions, "name=cgroupns") 55 } 56 if rootlessutil.IsRootlessChild() { 57 info.SecurityOptions = append(info.SecurityOptions, "name=rootless") 58 } 59 } 60 61 // fulfillPlatformInfo fulfills cgroup and kernel info. 62 // 63 // fulfillPlatformInfo requires the following fields to be set: 64 // SecurityOptions, CgroupDriver, CgroupVersion 65 func fulfillPlatformInfo(info *dockercompat.Info) { 66 fulfillSecurityOptions(info) 67 mobySysInfo := mobySysInfo(info) 68 69 if info.CgroupDriver == "none" { 70 if info.CgroupVersion == "2" { 71 info.Warnings = append(info.Warnings, "WARNING: Running in rootless-mode without cgroups. Systemd is required to enable cgroups in rootless-mode.") 72 } else { 73 info.Warnings = append(info.Warnings, "WARNING: Running in rootless-mode without cgroups. To enable cgroups in rootless-mode, you need to boot the system in cgroup v2 mode.") 74 } 75 } else { 76 info.MemoryLimit = mobySysInfo.MemoryLimit 77 if !info.MemoryLimit { 78 info.Warnings = append(info.Warnings, "WARNING: No memory limit support") 79 } 80 info.SwapLimit = mobySysInfo.SwapLimit 81 if !info.SwapLimit { 82 info.Warnings = append(info.Warnings, "WARNING: No swap limit support") 83 } 84 info.CPUCfsPeriod = mobySysInfo.CPUCfs 85 if !info.CPUCfsPeriod { 86 info.Warnings = append(info.Warnings, "WARNING: No cpu cfs period support") 87 } 88 info.CPUCfsQuota = mobySysInfo.CPUCfs 89 if !info.CPUCfsQuota { 90 info.Warnings = append(info.Warnings, "WARNING: No cpu cfs quota support") 91 } 92 info.CPUShares = mobySysInfo.CPUShares 93 if !info.CPUShares { 94 info.Warnings = append(info.Warnings, "WARNING: No cpu shares support") 95 } 96 info.CPUSet = mobySysInfo.Cpuset 97 if !info.CPUSet { 98 info.Warnings = append(info.Warnings, "WARNING: No cpuset support") 99 } 100 info.PidsLimit = mobySysInfo.PidsLimit 101 if !info.PidsLimit { 102 info.Warnings = append(info.Warnings, "WARNING: No pids limit support") 103 } 104 info.OomKillDisable = mobySysInfo.OomKillDisable 105 if !info.OomKillDisable && info.CgroupVersion == "1" { 106 // no warning for cgroup v2 107 info.Warnings = append(info.Warnings, "WARNING: No oom kill disable support") 108 } 109 } 110 info.IPv4Forwarding = !mobySysInfo.IPv4ForwardingDisabled 111 if !info.IPv4Forwarding { 112 info.Warnings = append(info.Warnings, "WARNING: IPv4 forwarding is disabled") 113 } 114 info.BridgeNfIptables = !mobySysInfo.BridgeNFCallIPTablesDisabled 115 if !info.BridgeNfIptables { 116 info.Warnings = append(info.Warnings, "WARNING: bridge-nf-call-iptables is disabled") 117 } 118 info.BridgeNfIP6tables = !mobySysInfo.BridgeNFCallIP6TablesDisabled 119 if !info.BridgeNfIP6tables { 120 info.Warnings = append(info.Warnings, "WARNING: bridge-nf-call-ip6tables is disabled") 121 } 122 info.NCPU = sysinfo.NumCPU() 123 memLimit, err := meminfo.Read() 124 if err != nil { 125 info.Warnings = append(info.Warnings, fmt.Sprintf("failed to read mem info: %v", err)) 126 } else { 127 info.MemTotal = memLimit.MemTotal 128 } 129 } 130 131 func mobySysInfo(info *dockercompat.Info) *sysinfo.SysInfo { 132 var mobySysInfoOpts []sysinfo.Opt 133 if info.CgroupDriver == "systemd" && info.CgroupVersion == "2" && rootlessutil.IsRootless() { 134 g := fmt.Sprintf("/user.slice/user-%d.slice", rootlessutil.ParentEUID()) 135 mobySysInfoOpts = append(mobySysInfoOpts, sysinfo.WithCgroup2GroupPath(g)) 136 } 137 mobySysInfo := sysinfo.New(mobySysInfoOpts...) 138 return mobySysInfo 139 }