(path string)
| 495 | } |
| 496 | |
| 497 | func supportsIDMap(path string) bool { |
| 498 | treeFD, err := unix.OpenTree(-1, path, uint(unix.OPEN_TREE_CLONE|unix.OPEN_TREE_CLOEXEC)) |
| 499 | if err != nil { |
| 500 | return false |
| 501 | } |
| 502 | defer unix.Close(treeFD) |
| 503 | |
| 504 | // We want to test if idmap mounts are supported. |
| 505 | // So we use just some random mapping, it doesn't really matter which one. |
| 506 | // For the helper command, we just need something that is alive while we |
| 507 | // test this, a sleep 5 will do it. |
| 508 | cmd := exec.Command("sleep", "5") |
| 509 | cmd.SysProcAttr = &syscall.SysProcAttr{ |
| 510 | Cloneflags: syscall.CLONE_NEWUSER, |
| 511 | UidMappings: []syscall.SysProcIDMap{{ContainerID: 0, HostID: 65536, Size: 65536}}, |
| 512 | GidMappings: []syscall.SysProcIDMap{{ContainerID: 0, HostID: 65536, Size: 65536}}, |
| 513 | } |
| 514 | if err := cmd.Start(); err != nil { |
| 515 | return false |
| 516 | } |
| 517 | defer func() { |
| 518 | _ = cmd.Process.Kill() |
| 519 | _ = cmd.Wait() |
| 520 | }() |
| 521 | |
| 522 | usernsFD := fmt.Sprintf("/proc/%d/ns/user", cmd.Process.Pid) |
| 523 | var usernsFile *os.File |
| 524 | if usernsFile, err = os.Open(usernsFD); err != nil { |
| 525 | return false |
| 526 | } |
| 527 | defer usernsFile.Close() |
| 528 | |
| 529 | attr := unix.MountAttr{ |
| 530 | Attr_set: unix.MOUNT_ATTR_IDMAP, |
| 531 | Userns_fd: uint64(usernsFile.Fd()), |
| 532 | } |
| 533 | if err := unix.MountSetattr(treeFD, "", unix.AT_EMPTY_PATH, &attr); err != nil { |
| 534 | return false |
| 535 | } |
| 536 | |
| 537 | return true |
| 538 | } |
| 539 | |
| 540 | func TestBuildIDMappedPaths(t *testing.T) { |
| 541 | testCases := []struct { |
no test coverage detected
searching dependent graphs…