github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/runsc/config/config.go (about) 1 // Copyright 2020 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package config provides basic infrastructure to set configuration settings 16 // for runsc. The configuration is set by flags to the command line. They can 17 // also propagate to a different process using the same flags. 18 package config 19 20 import ( 21 "fmt" 22 23 "github.com/SagerNet/gvisor/pkg/refs" 24 "github.com/SagerNet/gvisor/pkg/sentry/watchdog" 25 ) 26 27 // Config holds configuration that is not part of the runtime spec. 28 // 29 // Follow these steps to add a new flag: 30 // 1. Create a new field in Config. 31 // 2. Add a field tag with the flag name 32 // 3. Register a new flag in flags.go, with name and description 33 // 4. Add any necessary validation into validate() 34 // 5. If adding an enum, follow the same pattern as FileAccessType 35 // 36 type Config struct { 37 // RootDir is the runtime root directory. 38 RootDir string `flag:"root"` 39 40 // Traceback changes the Go runtime's traceback level. 41 Traceback string `flag:"traceback"` 42 43 // Debug indicates that debug logging should be enabled. 44 Debug bool `flag:"debug"` 45 46 // LogFilename is the filename to log to, if not empty. 47 LogFilename string `flag:"log"` 48 49 // LogFormat is the log format. 50 LogFormat string `flag:"log-format"` 51 52 // DebugLog is the path to log debug information to, if not empty. 53 DebugLog string `flag:"debug-log"` 54 55 // PanicLog is the path to log GO's runtime messages, if not empty. 56 PanicLog string `flag:"panic-log"` 57 58 // CoverageReport is the path to write Go coverage information, if not empty. 59 CoverageReport string `flag:"coverage-report"` 60 61 // DebugLogFormat is the log format for debug. 62 DebugLogFormat string `flag:"debug-log-format"` 63 64 // FileAccess indicates how the root filesystem is accessed. 65 FileAccess FileAccessType `flag:"file-access"` 66 67 // FileAccessMounts indicates how non-root volumes are accessed. 68 FileAccessMounts FileAccessType `flag:"file-access-mounts"` 69 70 // Overlay is whether to wrap the root filesystem in an overlay. 71 Overlay bool `flag:"overlay"` 72 73 // Verity is whether there's one or more verity file system to mount. 74 Verity bool `flag:"verity"` 75 76 // FSGoferHostUDS enables the gofer to mount a host UDS. 77 FSGoferHostUDS bool `flag:"fsgofer-host-uds"` 78 79 // Network indicates what type of network to use. 80 Network NetworkType `flag:"network"` 81 82 // EnableRaw indicates whether raw sockets should be enabled. Raw 83 // sockets are disabled by stripping CAP_NET_RAW from the list of 84 // capabilities. 85 EnableRaw bool `flag:"net-raw"` 86 87 // HardwareGSO indicates that hardware segmentation offload is enabled. 88 HardwareGSO bool `flag:"gso"` 89 90 // SoftwareGSO indicates that software segmentation offload is enabled. 91 SoftwareGSO bool `flag:"software-gso"` 92 93 // TXChecksumOffload indicates that TX Checksum Offload is enabled. 94 TXChecksumOffload bool `flag:"tx-checksum-offload"` 95 96 // RXChecksumOffload indicates that RX Checksum Offload is enabled. 97 RXChecksumOffload bool `flag:"rx-checksum-offload"` 98 99 // QDisc indicates the type of queuening discipline to use by default 100 // for non-loopback interfaces. 101 QDisc QueueingDiscipline `flag:"qdisc"` 102 103 // LogPackets indicates that all network packets should be logged. 104 LogPackets bool `flag:"log-packets"` 105 106 // Platform is the platform to run on. 107 Platform string `flag:"platform"` 108 109 // Strace indicates that strace should be enabled. 110 Strace bool `flag:"strace"` 111 112 // StraceSyscalls is the set of syscalls to trace (comma-separated values). 113 // If StraceEnable is true and this string is empty, then all syscalls will 114 // be traced. 115 StraceSyscalls string `flag:"strace-syscalls"` 116 117 // StraceLogSize is the max size of data blobs to display. 118 StraceLogSize uint `flag:"strace-log-size"` 119 120 // DisableSeccomp indicates whether seccomp syscall filters should be 121 // disabled. Pardon the double negation, but default to enabled is important. 122 DisableSeccomp bool 123 124 // WatchdogAction sets what action the watchdog takes when triggered. 125 WatchdogAction watchdog.Action `flag:"watchdog-action"` 126 127 // PanicSignal registers signal handling that panics. Usually set to 128 // SIGUSR2(12) to troubleshoot hangs. -1 disables it. 129 PanicSignal int `flag:"panic-signal"` 130 131 // ProfileEnable is set to prepare the sandbox to be profiled. 132 ProfileEnable bool `flag:"profile"` 133 134 // RestoreFile is the path to the saved container image 135 RestoreFile string 136 137 // NumNetworkChannels controls the number of AF_PACKET sockets that map 138 // to the same underlying network device. This allows netstack to better 139 // scale for high throughput use cases. 140 NumNetworkChannels int `flag:"num-network-channels"` 141 142 // Rootless allows the sandbox to be started with a user that is not root. 143 // Defense in depth measures are weaker in rootless mode. Specifically, the 144 // sandbox and Gofer process run as root inside a user namespace with root 145 // mapped to the caller's user. 146 Rootless bool `flag:"rootless"` 147 148 // AlsoLogToStderr allows to send log messages to stderr. 149 AlsoLogToStderr bool `flag:"alsologtostderr"` 150 151 // ReferenceLeakMode sets reference leak check mode 152 ReferenceLeak refs.LeakMode `flag:"ref-leak-mode"` 153 154 // CPUNumFromQuota sets CPU number count to available CPU quota, using 155 // least integer value greater than or equal to quota. 156 // 157 // E.g. 0.2 CPU quota will result in 1, and 1.9 in 2. 158 CPUNumFromQuota bool `flag:"cpu-num-from-quota"` 159 160 // Enables VFS2. 161 VFS2 bool `flag:"vfs2"` 162 163 // Enables FUSE usage. 164 FUSE bool `flag:"fuse"` 165 166 // Allows overriding of flags in OCI annotations. 167 AllowFlagOverride bool `flag:"allow-flag-override"` 168 169 // Enables seccomp inside the sandbox. 170 OCISeccomp bool `flag:"oci-seccomp"` 171 172 // Mounts the cgroup filesystem backed by the sentry's cgroupfs. 173 Cgroupfs bool `flag:"cgroupfs"` 174 175 // TestOnlyAllowRunAsCurrentUserWithoutChroot should only be used in 176 // tests. It allows runsc to start the sandbox process as the current 177 // user, and without chrooting the sandbox process. This can be 178 // necessary in test environments that have limited capabilities. 179 TestOnlyAllowRunAsCurrentUserWithoutChroot bool `flag:"TESTONLY-unsafe-nonroot"` 180 181 // TestOnlyTestNameEnv should only be used in tests. It looks up for the 182 // test name in the container environment variables and adds it to the debug 183 // log file name. This is done to help identify the log with the test when 184 // multiple tests are run in parallel, since there is no way to pass 185 // parameters to the runtime from docker. 186 TestOnlyTestNameEnv string `flag:"TESTONLY-test-name-env"` 187 } 188 189 func (c *Config) validate() error { 190 if c.FileAccess == FileAccessShared && c.Overlay { 191 return fmt.Errorf("overlay flag is incompatible with shared file access") 192 } 193 if c.NumNetworkChannels <= 0 { 194 return fmt.Errorf("num_network_channels must be > 0, got: %d", c.NumNetworkChannels) 195 } 196 return nil 197 } 198 199 // FileAccessType tells how the filesystem is accessed. 200 type FileAccessType int 201 202 const ( 203 // FileAccessExclusive gives the sandbox exclusive access over files and 204 // directories in the filesystem. No external modifications are permitted and 205 // can lead to undefined behavior. 206 // 207 // Exclusive filesystem access enables more aggressive caching and offers 208 // significantly better performance. This is the default mode for the root 209 // volume. 210 FileAccessExclusive FileAccessType = iota 211 212 // FileAccessShared is used for volumes that can have external changes. It 213 // requires revalidation on every filesystem access to detect external 214 // changes, and reduces the amount of caching that can be done. This is the 215 // default mode for non-root volumes. 216 FileAccessShared 217 ) 218 219 func fileAccessTypePtr(v FileAccessType) *FileAccessType { 220 return &v 221 } 222 223 // Set implements flag.Value. 224 func (f *FileAccessType) Set(v string) error { 225 switch v { 226 case "shared": 227 *f = FileAccessShared 228 case "exclusive": 229 *f = FileAccessExclusive 230 default: 231 return fmt.Errorf("invalid file access type %q", v) 232 } 233 return nil 234 } 235 236 // Get implements flag.Value. 237 func (f *FileAccessType) Get() interface{} { 238 return *f 239 } 240 241 // String implements flag.Value. 242 func (f FileAccessType) String() string { 243 switch f { 244 case FileAccessShared: 245 return "shared" 246 case FileAccessExclusive: 247 return "exclusive" 248 } 249 panic(fmt.Sprintf("Invalid file access type %d", f)) 250 } 251 252 // NetworkType tells which network stack to use. 253 type NetworkType int 254 255 const ( 256 // NetworkSandbox uses internal network stack, isolated from the host. 257 NetworkSandbox NetworkType = iota 258 259 // NetworkHost redirects network related syscalls to the host network. 260 NetworkHost 261 262 // NetworkNone sets up just loopback using netstack. 263 NetworkNone 264 ) 265 266 func networkTypePtr(v NetworkType) *NetworkType { 267 return &v 268 } 269 270 // Set implements flag.Value. 271 func (n *NetworkType) Set(v string) error { 272 switch v { 273 case "sandbox": 274 *n = NetworkSandbox 275 case "host": 276 *n = NetworkHost 277 case "none": 278 *n = NetworkNone 279 default: 280 return fmt.Errorf("invalid network type %q", v) 281 } 282 return nil 283 } 284 285 // Get implements flag.Value. 286 func (n *NetworkType) Get() interface{} { 287 return *n 288 } 289 290 // String implements flag.Value. 291 func (n NetworkType) String() string { 292 switch n { 293 case NetworkSandbox: 294 return "sandbox" 295 case NetworkHost: 296 return "host" 297 case NetworkNone: 298 return "none" 299 } 300 panic(fmt.Sprintf("Invalid network type %d", n)) 301 } 302 303 // QueueingDiscipline is used to specify the kind of Queueing Discipline to 304 // apply for a give FDBasedLink. 305 type QueueingDiscipline int 306 307 const ( 308 // QDiscNone disables any queueing for the underlying FD. 309 QDiscNone QueueingDiscipline = iota 310 311 // QDiscFIFO applies a simple fifo based queue to the underlying FD. 312 QDiscFIFO 313 ) 314 315 func queueingDisciplinePtr(v QueueingDiscipline) *QueueingDiscipline { 316 return &v 317 } 318 319 // Set implements flag.Value. 320 func (q *QueueingDiscipline) Set(v string) error { 321 switch v { 322 case "none": 323 *q = QDiscNone 324 case "fifo": 325 *q = QDiscFIFO 326 default: 327 return fmt.Errorf("invalid qdisc %q", v) 328 } 329 return nil 330 } 331 332 // Get implements flag.Value. 333 func (q *QueueingDiscipline) Get() interface{} { 334 return *q 335 } 336 337 // String implements flag.Value. 338 func (q QueueingDiscipline) String() string { 339 switch q { 340 case QDiscNone: 341 return "none" 342 case QDiscFIFO: 343 return "fifo" 344 } 345 panic(fmt.Sprintf("Invalid qdisc %d", q)) 346 } 347 348 func leakModePtr(v refs.LeakMode) *refs.LeakMode { 349 return &v 350 } 351 352 func watchdogActionPtr(v watchdog.Action) *watchdog.Action { 353 return &v 354 }