daemon_unix.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. // +build daemon
  2. package main
  3. import (
  4. "os"
  5. "os/exec"
  6. "path/filepath"
  7. "syscall"
  8. )
  9. // CmdDaemon execs dockerd with the same flags
  10. func (p DaemonProxy) CmdDaemon(args ...string) error {
  11. // Special case for handling `docker help daemon`. When pkg/mflag is removed
  12. // we can support this on the daemon side, but that is not possible with
  13. // pkg/mflag because it uses os.Exit(1) instead of returning an error on
  14. // unexpected args.
  15. if len(args) == 0 || args[0] != "--help" {
  16. // Use os.Args[1:] so that "global" args are passed to dockerd
  17. args = stripDaemonArg(os.Args[1:])
  18. }
  19. binaryPath, err := findDaemonBinary()
  20. if err != nil {
  21. return err
  22. }
  23. return syscall.Exec(
  24. binaryPath,
  25. append([]string{daemonBinary}, args...),
  26. os.Environ())
  27. }
  28. // findDaemonBinary looks for the path to the dockerd binary starting with
  29. // the directory of the current executable (if one exists) and followed by $PATH
  30. func findDaemonBinary() (string, error) {
  31. execDirname := filepath.Dir(os.Args[0])
  32. if execDirname != "" {
  33. binaryPath := filepath.Join(execDirname, daemonBinary)
  34. if _, err := os.Stat(binaryPath); err == nil {
  35. return binaryPath, nil
  36. }
  37. }
  38. return exec.LookPath(daemonBinary)
  39. }
  40. // stripDaemonArg removes the `daemon` argument from the list
  41. func stripDaemonArg(args []string) []string {
  42. for i, arg := range args {
  43. if arg == "daemon" {
  44. return append(args[:i], args[i+1:]...)
  45. }
  46. }
  47. return args
  48. }