| // +build !windows |
| |
| package daemon // import "github.com/docker/docker/testutil/daemon" |
| |
| import ( |
| "fmt" |
| "os" |
| "os/exec" |
| "path/filepath" |
| "strings" |
| "syscall" |
| "testing" |
| |
| "github.com/moby/sys/mount" |
| "golang.org/x/sys/unix" |
| "gotest.tools/v3/assert" |
| ) |
| |
| // cleanupMount unmounts the daemon root directory, or logs a message if |
| // unmounting failed. |
| func cleanupMount(t testing.TB, d *Daemon) { |
| t.Helper() |
| if err := mount.Unmount(d.Root); err != nil { |
| d.log.Logf("[%s] unable to unmount daemon root (%s): %v", d.id, d.Root, err) |
| } |
| } |
| |
| func cleanupNetworkNamespace(t testing.TB, d *Daemon) { |
| t.Helper() |
| // Cleanup network namespaces in the exec root of this |
| // daemon because this exec root is specific to this |
| // daemon instance and has no chance of getting |
| // cleaned up when a new daemon is instantiated with a |
| // new exec root. |
| netnsPath := filepath.Join(d.execRoot, "netns") |
| filepath.Walk(netnsPath, func(path string, info os.FileInfo, err error) error { |
| if err := unix.Unmount(path, unix.MNT_DETACH); err != nil && err != unix.EINVAL && err != unix.ENOENT { |
| t.Logf("[%s] unmount of %s failed: %v", d.id, path, err) |
| } |
| os.Remove(path) |
| return nil |
| }) |
| } |
| |
| // CgroupNamespace returns the cgroup namespace the daemon is running in |
| func (d *Daemon) CgroupNamespace(t testing.TB) string { |
| link, err := os.Readlink(fmt.Sprintf("/proc/%d/ns/cgroup", d.Pid())) |
| assert.NilError(t, err) |
| |
| return strings.TrimSpace(link) |
| } |
| |
| // SignalDaemonDump sends a signal to the daemon to write a dump file |
| func SignalDaemonDump(pid int) { |
| unix.Kill(pid, unix.SIGQUIT) |
| } |
| |
| func signalDaemonReload(pid int) error { |
| return unix.Kill(pid, unix.SIGHUP) |
| } |
| |
| func setsid(cmd *exec.Cmd) { |
| if cmd.SysProcAttr == nil { |
| cmd.SysProcAttr = &syscall.SysProcAttr{} |
| } |
| cmd.SysProcAttr.Setsid = true |
| } |