github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/pkg/namespaces/namespaces.go (about) 1 package namespaces 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 8 "github.com/containers/storage" 9 ) 10 11 const ( 12 bridgeType = "bridge" 13 containerType = "container" 14 defaultType = "default" 15 hostType = "host" 16 noneType = "none" 17 nsType = "ns" 18 podType = "pod" 19 privateType = "private" 20 shareableType = "shareable" 21 slirpType = "slirp4netns" 22 ) 23 24 // CgroupMode represents cgroup mode in the container. 25 type CgroupMode string 26 27 // IsHost indicates whether the container uses the host's cgroup. 28 func (n CgroupMode) IsHost() bool { 29 return n == hostType 30 } 31 32 // IsDefaultValue indicates whether the cgroup namespace has the default value. 33 func (n CgroupMode) IsDefaultValue() bool { 34 return n == "" 35 } 36 37 // IsNS indicates a cgroup namespace passed in by path (ns:<path>) 38 func (n CgroupMode) IsNS() bool { 39 return strings.HasPrefix(string(n), nsType) 40 } 41 42 // NS gets the path associated with a ns:<path> cgroup ns 43 func (n CgroupMode) NS() string { 44 parts := strings.SplitN(string(n), ":", 2) 45 if len(parts) > 1 { 46 return parts[1] 47 } 48 return "" 49 } 50 51 // IsContainer indicates whether the container uses a new cgroup namespace. 52 func (n CgroupMode) IsContainer() bool { 53 parts := strings.SplitN(string(n), ":", 2) 54 return len(parts) > 1 && parts[0] == containerType 55 } 56 57 // Container returns the name of the container whose cgroup namespace is going to be used. 58 func (n CgroupMode) Container() string { 59 parts := strings.SplitN(string(n), ":", 2) 60 if len(parts) > 1 && parts[0] == containerType { 61 return parts[1] 62 } 63 return "" 64 } 65 66 // IsPrivate indicates whether the container uses the a private cgroup. 67 func (n CgroupMode) IsPrivate() bool { 68 return n == privateType 69 } 70 71 // Valid indicates whether the Cgroup namespace is valid. 72 func (n CgroupMode) Valid() bool { 73 parts := strings.Split(string(n), ":") 74 switch mode := parts[0]; mode { 75 case "", hostType, privateType, nsType: 76 case containerType: 77 if len(parts) != 2 || parts[1] == "" { 78 return false 79 } 80 default: 81 return false 82 } 83 return true 84 } 85 86 // UsernsMode represents userns mode in the container. 87 type UsernsMode string 88 89 // IsHost indicates whether the container uses the host's userns. 90 func (n UsernsMode) IsHost() bool { 91 return n == hostType 92 } 93 94 // IsKeepID indicates whether container uses a mapping where the (uid, gid) on the host is lept inside of the namespace. 95 func (n UsernsMode) IsKeepID() bool { 96 return n == "keep-id" 97 } 98 99 // IsAuto indicates whether container uses the "auto" userns mode. 100 func (n UsernsMode) IsAuto() bool { 101 parts := strings.Split(string(n), ":") 102 return parts[0] == "auto" 103 } 104 105 // GetAutoOptions returns a AutoUserNsOptions with the settings to setup automatically 106 // a user namespace. 107 func (n UsernsMode) GetAutoOptions() (*storage.AutoUserNsOptions, error) { 108 parts := strings.SplitN(string(n), ":", 2) 109 if parts[0] != "auto" { 110 return nil, fmt.Errorf("wrong user namespace mode") 111 } 112 options := storage.AutoUserNsOptions{} 113 if len(parts) == 1 { 114 return &options, nil 115 } 116 for _, o := range strings.Split(parts[1], ",") { 117 v := strings.SplitN(o, "=", 2) 118 if len(v) != 2 { 119 return nil, fmt.Errorf("invalid option specified: %q", o) 120 } 121 switch v[0] { 122 case "size": 123 s, err := strconv.ParseUint(v[1], 10, 32) 124 if err != nil { 125 return nil, err 126 } 127 options.Size = uint32(s) 128 case "uidmapping": 129 mapping, err := storage.ParseIDMapping([]string{v[1]}, nil, "", "") 130 if err != nil { 131 return nil, err 132 } 133 options.AdditionalUIDMappings = append(options.AdditionalUIDMappings, mapping.UIDMap...) 134 case "gidmapping": 135 mapping, err := storage.ParseIDMapping(nil, []string{v[1]}, "", "") 136 if err != nil { 137 return nil, err 138 } 139 options.AdditionalGIDMappings = append(options.AdditionalGIDMappings, mapping.GIDMap...) 140 default: 141 return nil, fmt.Errorf("unknown option specified: %q", v[0]) 142 } 143 } 144 return &options, nil 145 } 146 147 // IsPrivate indicates whether the container uses the a private userns. 148 func (n UsernsMode) IsPrivate() bool { 149 return !(n.IsHost() || n.IsContainer()) 150 } 151 152 // Valid indicates whether the userns is valid. 153 func (n UsernsMode) Valid() bool { 154 parts := strings.Split(string(n), ":") 155 switch mode := parts[0]; mode { 156 case "", privateType, hostType, "keep-id", nsType, "auto": 157 case containerType: 158 if len(parts) != 2 || parts[1] == "" { 159 return false 160 } 161 default: 162 return false 163 } 164 return true 165 } 166 167 // IsNS indicates a userns namespace passed in by path (ns:<path>) 168 func (n UsernsMode) IsNS() bool { 169 return strings.HasPrefix(string(n), "ns:") 170 } 171 172 // NS gets the path associated with a ns:<path> userns ns 173 func (n UsernsMode) NS() string { 174 parts := strings.SplitN(string(n), ":", 2) 175 if len(parts) > 1 { 176 return parts[1] 177 } 178 return "" 179 } 180 181 // IsContainer indicates whether container uses a container userns. 182 func (n UsernsMode) IsContainer() bool { 183 parts := strings.SplitN(string(n), ":", 2) 184 return len(parts) > 1 && parts[0] == containerType 185 } 186 187 // Container is the id of the container which network this container is connected to. 188 func (n UsernsMode) Container() string { 189 parts := strings.SplitN(string(n), ":", 2) 190 if len(parts) > 1 && parts[0] == containerType { 191 return parts[1] 192 } 193 return "" 194 } 195 196 // UTSMode represents the UTS namespace of the container. 197 type UTSMode string 198 199 // IsPrivate indicates whether the container uses its private UTS namespace. 200 func (n UTSMode) IsPrivate() bool { 201 return !(n.IsHost()) 202 } 203 204 // IsHost indicates whether the container uses the host's UTS namespace. 205 func (n UTSMode) IsHost() bool { 206 return n == hostType 207 } 208 209 // IsContainer indicates whether the container uses a container's UTS namespace. 210 func (n UTSMode) IsContainer() bool { 211 parts := strings.SplitN(string(n), ":", 2) 212 return len(parts) > 1 && parts[0] == containerType 213 } 214 215 // Container returns the name of the container whose uts namespace is going to be used. 216 func (n UTSMode) Container() string { 217 parts := strings.SplitN(string(n), ":", 2) 218 if len(parts) > 1 && parts[0] == containerType { 219 return parts[1] 220 } 221 return "" 222 } 223 224 // Valid indicates whether the UTS namespace is valid. 225 func (n UTSMode) Valid() bool { 226 parts := strings.Split(string(n), ":") 227 switch mode := parts[0]; mode { 228 case "", privateType, hostType: 229 case containerType: 230 if len(parts) != 2 || parts[1] == "" { 231 return false 232 } 233 default: 234 return false 235 } 236 return true 237 } 238 239 // IpcMode represents the container ipc stack. 240 type IpcMode string 241 242 // IsPrivate indicates whether the container uses its own private ipc namespace which cannot be shared. 243 func (n IpcMode) IsPrivate() bool { 244 return n == privateType 245 } 246 247 // IsHost indicates whether the container shares the host's ipc namespace. 248 func (n IpcMode) IsHost() bool { 249 return n == hostType 250 } 251 252 // IsShareable indicates whether the container's ipc namespace can be shared with another container. 253 func (n IpcMode) IsShareable() bool { 254 return n == shareableType 255 } 256 257 // IsContainer indicates whether the container uses another container's ipc namespace. 258 func (n IpcMode) IsContainer() bool { 259 parts := strings.SplitN(string(n), ":", 2) 260 return len(parts) > 1 && parts[0] == containerType 261 } 262 263 // IsNone indicates whether container IpcMode is set to "none". 264 func (n IpcMode) IsNone() bool { 265 return n == noneType 266 } 267 268 // IsEmpty indicates whether container IpcMode is empty 269 func (n IpcMode) IsEmpty() bool { 270 return n == "" 271 } 272 273 // Valid indicates whether the ipc mode is valid. 274 func (n IpcMode) Valid() bool { 275 return n.IsEmpty() || n.IsNone() || n.IsPrivate() || n.IsHost() || n.IsShareable() || n.IsContainer() 276 } 277 278 // Container returns the name of the container ipc stack is going to be used. 279 func (n IpcMode) Container() string { 280 parts := strings.SplitN(string(n), ":", 2) 281 if len(parts) > 1 && parts[0] == containerType { 282 return parts[1] 283 } 284 return "" 285 } 286 287 // PidMode represents the pid namespace of the container. 288 type PidMode string 289 290 // IsPrivate indicates whether the container uses its own new pid namespace. 291 func (n PidMode) IsPrivate() bool { 292 return !(n.IsHost() || n.IsContainer()) 293 } 294 295 // IsHost indicates whether the container uses the host's pid namespace. 296 func (n PidMode) IsHost() bool { 297 return n == hostType 298 } 299 300 // IsContainer indicates whether the container uses a container's pid namespace. 301 func (n PidMode) IsContainer() bool { 302 parts := strings.SplitN(string(n), ":", 2) 303 return len(parts) > 1 && parts[0] == containerType 304 } 305 306 // Valid indicates whether the pid namespace is valid. 307 func (n PidMode) Valid() bool { 308 parts := strings.Split(string(n), ":") 309 switch mode := parts[0]; mode { 310 case "", privateType, hostType: 311 case containerType: 312 if len(parts) != 2 || parts[1] == "" { 313 return false 314 } 315 default: 316 return false 317 } 318 return true 319 } 320 321 // Container returns the name of the container whose pid namespace is going to be used. 322 func (n PidMode) Container() string { 323 parts := strings.SplitN(string(n), ":", 2) 324 if len(parts) > 1 && parts[0] == containerType { 325 return parts[1] 326 } 327 return "" 328 } 329 330 // NetworkMode represents the container network stack. 331 type NetworkMode string 332 333 // IsNone indicates whether container isn't using a network stack. 334 func (n NetworkMode) IsNone() bool { 335 return n == noneType 336 } 337 338 // IsHost indicates whether the container uses the host's network stack. 339 func (n NetworkMode) IsHost() bool { 340 return n == hostType 341 } 342 343 // IsDefault indicates whether container uses the default network stack. 344 func (n NetworkMode) IsDefault() bool { 345 return n == defaultType 346 } 347 348 // IsPrivate indicates whether container uses its private network stack. 349 func (n NetworkMode) IsPrivate() bool { 350 return !(n.IsHost() || n.IsContainer()) 351 } 352 353 // IsContainer indicates whether container uses a container network stack. 354 func (n NetworkMode) IsContainer() bool { 355 parts := strings.SplitN(string(n), ":", 2) 356 return len(parts) > 1 && parts[0] == containerType 357 } 358 359 // Container is the id of the container which network this container is connected to. 360 func (n NetworkMode) Container() string { 361 parts := strings.SplitN(string(n), ":", 2) 362 if len(parts) > 1 && parts[0] == containerType { 363 return parts[1] 364 } 365 return "" 366 } 367 368 //UserDefined indicates user-created network 369 func (n NetworkMode) UserDefined() string { 370 if n.IsUserDefined() { 371 return string(n) 372 } 373 return "" 374 } 375 376 // IsBridge indicates whether container uses the bridge network stack 377 func (n NetworkMode) IsBridge() bool { 378 return n == bridgeType 379 } 380 381 // IsSlirp4netns indicates if we are running a rootless network stack 382 func (n NetworkMode) IsSlirp4netns() bool { 383 return n == slirpType 384 } 385 386 // IsNS indicates a network namespace passed in by path (ns:<path>) 387 func (n NetworkMode) IsNS() bool { 388 return strings.HasPrefix(string(n), nsType) 389 } 390 391 // NS gets the path associated with a ns:<path> network ns 392 func (n NetworkMode) NS() string { 393 parts := strings.SplitN(string(n), ":", 2) 394 if len(parts) > 1 { 395 return parts[1] 396 } 397 return "" 398 } 399 400 // IsPod returns whether the network refers to pod networking 401 func (n NetworkMode) IsPod() bool { 402 return n == podType 403 } 404 405 // IsUserDefined indicates user-created network 406 func (n NetworkMode) IsUserDefined() bool { 407 return !n.IsDefault() && !n.IsBridge() && !n.IsHost() && !n.IsNone() && !n.IsContainer() && !n.IsSlirp4netns() && !n.IsNS() 408 }