Browse Source

integration-cli: move daemon stuff to its own file

Signed-off-by: Antonio Murdaca <runcom@redhat.com>
Antonio Murdaca 9 years ago
parent
commit
9a9e2bb61d
2 changed files with 457 additions and 437 deletions
  1. 457 0
      integration-cli/daemon.go
  2. 0 437
      integration-cli/docker_utils.go

+ 457 - 0
integration-cli/daemon.go

@@ -0,0 +1,457 @@
+package main
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+	"net/http"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/docker/docker/opts"
+	"github.com/docker/docker/pkg/integration/checker"
+	"github.com/docker/docker/pkg/ioutils"
+	"github.com/docker/docker/pkg/tlsconfig"
+	"github.com/docker/go-connections/sockets"
+	"github.com/go-check/check"
+)
+
+// Daemon represents a Docker daemon for the testing framework.
+type Daemon struct {
+	// Defaults to "daemon"
+	// Useful to set to --daemon or -d for checking backwards compatibility
+	Command     string
+	GlobalFlags []string
+
+	id                string
+	c                 *check.C
+	logFile           *os.File
+	folder            string
+	root              string
+	stdin             io.WriteCloser
+	stdout, stderr    io.ReadCloser
+	cmd               *exec.Cmd
+	storageDriver     string
+	wait              chan error
+	userlandProxy     bool
+	useDefaultHost    bool
+	useDefaultTLSHost bool
+}
+
+type clientConfig struct {
+	transport *http.Transport
+	scheme    string
+	addr      string
+}
+
+// NewDaemon returns a Daemon instance to be used for testing.
+// This will create a directory such as d123456789 in the folder specified by $DEST.
+// The daemon will not automatically start.
+func NewDaemon(c *check.C) *Daemon {
+	dest := os.Getenv("DEST")
+	c.Assert(dest, check.Not(check.Equals), "", check.Commentf("Please set the DEST environment variable"))
+
+	id := fmt.Sprintf("d%d", time.Now().UnixNano()%100000000)
+	dir := filepath.Join(dest, id)
+	daemonFolder, err := filepath.Abs(dir)
+	c.Assert(err, check.IsNil, check.Commentf("Could not make %q an absolute path", dir))
+	daemonRoot := filepath.Join(daemonFolder, "root")
+
+	c.Assert(os.MkdirAll(daemonRoot, 0755), check.IsNil, check.Commentf("Could not create daemon root %q", dir))
+
+	userlandProxy := true
+	if env := os.Getenv("DOCKER_USERLANDPROXY"); env != "" {
+		if val, err := strconv.ParseBool(env); err != nil {
+			userlandProxy = val
+		}
+	}
+
+	return &Daemon{
+		Command:       "daemon",
+		id:            id,
+		c:             c,
+		folder:        daemonFolder,
+		root:          daemonRoot,
+		storageDriver: os.Getenv("DOCKER_GRAPHDRIVER"),
+		userlandProxy: userlandProxy,
+	}
+}
+
+func (d *Daemon) getClientConfig() (*clientConfig, error) {
+	var (
+		transport *http.Transport
+		scheme    string
+		addr      string
+		proto     string
+	)
+	if d.useDefaultTLSHost {
+		option := &tlsconfig.Options{
+			CAFile:   "fixtures/https/ca.pem",
+			CertFile: "fixtures/https/client-cert.pem",
+			KeyFile:  "fixtures/https/client-key.pem",
+		}
+		tlsConfig, err := tlsconfig.Client(*option)
+		if err != nil {
+			return nil, err
+		}
+		transport = &http.Transport{
+			TLSClientConfig: tlsConfig,
+		}
+		addr = fmt.Sprintf("%s:%d", opts.DefaultHTTPHost, opts.DefaultTLSHTTPPort)
+		scheme = "https"
+		proto = "tcp"
+	} else if d.useDefaultHost {
+		addr = opts.DefaultUnixSocket
+		proto = "unix"
+		scheme = "http"
+		transport = &http.Transport{}
+	} else {
+		addr = filepath.Join(d.folder, "docker.sock")
+		proto = "unix"
+		scheme = "http"
+		transport = &http.Transport{}
+	}
+
+	d.c.Assert(sockets.ConfigureTransport(transport, proto, addr), check.IsNil)
+
+	return &clientConfig{
+		transport: transport,
+		scheme:    scheme,
+		addr:      addr,
+	}, nil
+}
+
+// Start will start the daemon and return once it is ready to receive requests.
+// You can specify additional daemon flags.
+func (d *Daemon) Start(args ...string) error {
+	logFile, err := os.OpenFile(filepath.Join(d.folder, "docker.log"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
+	d.c.Assert(err, check.IsNil, check.Commentf("[%s] Could not create %s/docker.log", d.id, d.folder))
+
+	return d.StartWithLogFile(logFile, args...)
+}
+
+// StartWithLogFile will start the daemon and attach its streams to a given file.
+func (d *Daemon) StartWithLogFile(out *os.File, providedArgs ...string) error {
+	dockerBinary, err := exec.LookPath(dockerBinary)
+	d.c.Assert(err, check.IsNil, check.Commentf("[%s] could not find docker binary in $PATH", d.id))
+
+	args := append(d.GlobalFlags,
+		d.Command,
+		"--graph", d.root,
+		"--pidfile", fmt.Sprintf("%s/docker.pid", d.folder),
+		fmt.Sprintf("--userland-proxy=%t", d.userlandProxy),
+	)
+	if !(d.useDefaultHost || d.useDefaultTLSHost) {
+		args = append(args, []string{"--host", d.sock()}...)
+	}
+	if root := os.Getenv("DOCKER_REMAP_ROOT"); root != "" {
+		args = append(args, []string{"--userns-remap", root}...)
+	}
+
+	// If we don't explicitly set the log-level or debug flag(-D) then
+	// turn on debug mode
+	foundLog := false
+	foundSd := false
+	for _, a := range providedArgs {
+		if strings.Contains(a, "--log-level") || strings.Contains(a, "-D") || strings.Contains(a, "--debug") {
+			foundLog = true
+		}
+		if strings.Contains(a, "--storage-driver") {
+			foundSd = true
+		}
+	}
+	if !foundLog {
+		args = append(args, "--debug")
+	}
+	if d.storageDriver != "" && !foundSd {
+		args = append(args, "--storage-driver", d.storageDriver)
+	}
+
+	args = append(args, providedArgs...)
+	d.cmd = exec.Command(dockerBinary, args...)
+
+	d.cmd.Stdout = out
+	d.cmd.Stderr = out
+	d.logFile = out
+
+	if err := d.cmd.Start(); err != nil {
+		return fmt.Errorf("[%s] could not start daemon container: %v", d.id, err)
+	}
+
+	wait := make(chan error)
+
+	go func() {
+		wait <- d.cmd.Wait()
+		d.c.Logf("[%s] exiting daemon", d.id)
+		close(wait)
+	}()
+
+	d.wait = wait
+
+	tick := time.Tick(500 * time.Millisecond)
+	// make sure daemon is ready to receive requests
+	startTime := time.Now().Unix()
+	for {
+		d.c.Logf("[%s] waiting for daemon to start", d.id)
+		if time.Now().Unix()-startTime > 5 {
+			// After 5 seconds, give up
+			return fmt.Errorf("[%s] Daemon exited and never started", d.id)
+		}
+		select {
+		case <-time.After(2 * time.Second):
+			return fmt.Errorf("[%s] timeout: daemon does not respond", d.id)
+		case <-tick:
+			clientConfig, err := d.getClientConfig()
+			if err != nil {
+				return err
+			}
+
+			client := &http.Client{
+				Transport: clientConfig.transport,
+			}
+
+			req, err := http.NewRequest("GET", "/_ping", nil)
+			d.c.Assert(err, check.IsNil, check.Commentf("[%s] could not create new request", d.id))
+			req.URL.Host = clientConfig.addr
+			req.URL.Scheme = clientConfig.scheme
+			resp, err := client.Do(req)
+			if err != nil {
+				continue
+			}
+			if resp.StatusCode != http.StatusOK {
+				d.c.Logf("[%s] received status != 200 OK: %s", d.id, resp.Status)
+			}
+			d.c.Logf("[%s] daemon started", d.id)
+			d.root, err = d.queryRootDir()
+			if err != nil {
+				return fmt.Errorf("[%s] error querying daemon for root directory: %v", d.id, err)
+			}
+			return nil
+		}
+	}
+}
+
+// StartWithBusybox will first start the daemon with Daemon.Start()
+// then save the busybox image from the main daemon and load it into this Daemon instance.
+func (d *Daemon) StartWithBusybox(arg ...string) error {
+	if err := d.Start(arg...); err != nil {
+		return err
+	}
+	return d.LoadBusybox()
+}
+
+// Stop will send a SIGINT every second and wait for the daemon to stop.
+// If it timeouts, a SIGKILL is sent.
+// Stop will not delete the daemon directory. If a purged daemon is needed,
+// instantiate a new one with NewDaemon.
+func (d *Daemon) Stop() error {
+	if d.cmd == nil || d.wait == nil {
+		return errors.New("daemon not started")
+	}
+
+	defer func() {
+		d.logFile.Close()
+		d.cmd = nil
+	}()
+
+	i := 1
+	tick := time.Tick(time.Second)
+
+	if err := d.cmd.Process.Signal(os.Interrupt); err != nil {
+		return fmt.Errorf("could not send signal: %v", err)
+	}
+out1:
+	for {
+		select {
+		case err := <-d.wait:
+			return err
+		case <-time.After(15 * time.Second):
+			// time for stopping jobs and run onShutdown hooks
+			d.c.Log("timeout")
+			break out1
+		}
+	}
+
+out2:
+	for {
+		select {
+		case err := <-d.wait:
+			return err
+		case <-tick:
+			i++
+			if i > 4 {
+				d.c.Logf("tried to interrupt daemon for %d times, now try to kill it", i)
+				break out2
+			}
+			d.c.Logf("Attempt #%d: daemon is still running with pid %d", i, d.cmd.Process.Pid)
+			if err := d.cmd.Process.Signal(os.Interrupt); err != nil {
+				return fmt.Errorf("could not send signal: %v", err)
+			}
+		}
+	}
+
+	if err := d.cmd.Process.Kill(); err != nil {
+		d.c.Logf("Could not kill daemon: %v", err)
+		return err
+	}
+
+	return nil
+}
+
+// Restart will restart the daemon by first stopping it and then starting it.
+func (d *Daemon) Restart(arg ...string) error {
+	d.Stop()
+	// in the case of tests running a user namespace-enabled daemon, we have resolved
+	// d.root to be the actual final path of the graph dir after the "uid.gid" of
+	// remapped root is added--we need to subtract it from the path before calling
+	// start or else we will continue making subdirectories rather than truly restarting
+	// with the same location/root:
+	if root := os.Getenv("DOCKER_REMAP_ROOT"); root != "" {
+		d.root = filepath.Dir(d.root)
+	}
+	return d.Start(arg...)
+}
+
+// LoadBusybox will load the stored busybox into a newly started daemon
+func (d *Daemon) LoadBusybox() error {
+	bb := filepath.Join(d.folder, "busybox.tar")
+	if _, err := os.Stat(bb); err != nil {
+		if !os.IsNotExist(err) {
+			return fmt.Errorf("unexpected error on busybox.tar stat: %v", err)
+		}
+		// saving busybox image from main daemon
+		if err := exec.Command(dockerBinary, "save", "--output", bb, "busybox:latest").Run(); err != nil {
+			return fmt.Errorf("could not save busybox image: %v", err)
+		}
+	}
+	// loading busybox image to this daemon
+	if out, err := d.Cmd("load", "--input", bb); err != nil {
+		return fmt.Errorf("could not load busybox image: %s", out)
+	}
+	if err := os.Remove(bb); err != nil {
+		d.c.Logf("could not remove %s: %v", bb, err)
+	}
+	return nil
+}
+
+func (d *Daemon) queryRootDir() (string, error) {
+	// update daemon root by asking /info endpoint (to support user
+	// namespaced daemon with root remapped uid.gid directory)
+	clientConfig, err := d.getClientConfig()
+	if err != nil {
+		return "", err
+	}
+
+	client := &http.Client{
+		Transport: clientConfig.transport,
+	}
+
+	req, err := http.NewRequest("GET", "/info", nil)
+	if err != nil {
+		return "", err
+	}
+	req.Header.Set("Content-Type", "application/json")
+	req.URL.Host = clientConfig.addr
+	req.URL.Scheme = clientConfig.scheme
+
+	resp, err := client.Do(req)
+	if err != nil {
+		return "", err
+	}
+	body := ioutils.NewReadCloserWrapper(resp.Body, func() error {
+		return resp.Body.Close()
+	})
+
+	type Info struct {
+		DockerRootDir string
+	}
+	var b []byte
+	var i Info
+	b, err = readBody(body)
+	if err == nil && resp.StatusCode == 200 {
+		// read the docker root dir
+		if err = json.Unmarshal(b, &i); err == nil {
+			return i.DockerRootDir, nil
+		}
+	}
+	return "", err
+}
+
+func (d *Daemon) sock() string {
+	return fmt.Sprintf("unix://%s/docker.sock", d.folder)
+}
+
+func (d *Daemon) waitRun(contID string) error {
+	args := []string{"--host", d.sock()}
+	return waitInspectWithArgs(contID, "{{.State.Running}}", "true", 10*time.Second, args...)
+}
+
+func (d *Daemon) getBaseDeviceSize(c *check.C) int64 {
+	infoCmdOutput, _, err := runCommandPipelineWithOutput(
+		exec.Command(dockerBinary, "-H", d.sock(), "info"),
+		exec.Command("grep", "Base Device Size"),
+	)
+	c.Assert(err, checker.IsNil)
+	basesizeSlice := strings.Split(infoCmdOutput, ":")
+	basesize := strings.Trim(basesizeSlice[1], " ")
+	basesize = strings.Trim(basesize, "\n")[:len(basesize)-3]
+	basesizeFloat, err := strconv.ParseFloat(strings.Trim(basesize, " "), 64)
+	c.Assert(err, checker.IsNil)
+	basesizeBytes := int64(basesizeFloat) * (1024 * 1024 * 1024)
+	return basesizeBytes
+}
+
+// Cmd will execute a docker CLI command against this Daemon.
+// Example: d.Cmd("version") will run docker -H unix://path/to/unix.sock version
+func (d *Daemon) Cmd(name string, arg ...string) (string, error) {
+	args := []string{"--host", d.sock(), name}
+	args = append(args, arg...)
+	c := exec.Command(dockerBinary, args...)
+	b, err := c.CombinedOutput()
+	return string(b), err
+}
+
+// CmdWithArgs will execute a docker CLI command against a daemon with the
+// given additional arguments
+func (d *Daemon) CmdWithArgs(daemonArgs []string, name string, arg ...string) (string, error) {
+	args := append(daemonArgs, name)
+	args = append(args, arg...)
+	c := exec.Command(dockerBinary, args...)
+	b, err := c.CombinedOutput()
+	return string(b), err
+}
+
+// LogFileName returns the path the the daemon's log file
+func (d *Daemon) LogFileName() string {
+	return d.logFile.Name()
+}
+
+func (d *Daemon) getIDByName(name string) (string, error) {
+	return d.inspectFieldWithError(name, "Id")
+}
+
+func (d *Daemon) inspectFilter(name, filter string) (string, error) {
+	format := fmt.Sprintf("{{%s}}", filter)
+	out, err := d.Cmd("inspect", "-f", format, name)
+	if err != nil {
+		return "", fmt.Errorf("failed to inspect %s: %s", name, out)
+	}
+	return strings.TrimSpace(out), nil
+}
+
+func (d *Daemon) inspectFieldWithError(name, field string) (string, error) {
+	return d.inspectFilter(name, fmt.Sprintf(".%s", field))
+}
+
+func (d *Daemon) findContainerIP(id string) string {
+	out, err := d.Cmd("inspect", fmt.Sprintf("--format='{{ .NetworkSettings.Networks.bridge.IPAddress }}'"), id)
+	if err != nil {
+		d.c.Log(err)
+	}
+	return strings.Trim(out, " \r\n'")
+}

+ 0 - 437
integration-cli/docker_utils.go

@@ -25,11 +25,9 @@ import (
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/pkg/httputils"
 	"github.com/docker/docker/pkg/httputils"
 	"github.com/docker/docker/pkg/integration"
 	"github.com/docker/docker/pkg/integration"
-	"github.com/docker/docker/pkg/integration/checker"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/stringutils"
 	"github.com/docker/docker/pkg/stringutils"
 	"github.com/docker/engine-api/types"
 	"github.com/docker/engine-api/types"
-	"github.com/docker/go-connections/sockets"
 	"github.com/docker/go-connections/tlsconfig"
 	"github.com/docker/go-connections/tlsconfig"
 	"github.com/docker/go-units"
 	"github.com/docker/go-units"
 	"github.com/go-check/check"
 	"github.com/go-check/check"
@@ -102,391 +100,6 @@ func init() {
 	}
 	}
 }
 }
 
 
-// Daemon represents a Docker daemon for the testing framework.
-type Daemon struct {
-	// Defaults to "daemon"
-	// Useful to set to --daemon or -d for checking backwards compatibility
-	Command     string
-	GlobalFlags []string
-
-	id                string
-	c                 *check.C
-	logFile           *os.File
-	folder            string
-	root              string
-	stdin             io.WriteCloser
-	stdout, stderr    io.ReadCloser
-	cmd               *exec.Cmd
-	storageDriver     string
-	wait              chan error
-	userlandProxy     bool
-	useDefaultHost    bool
-	useDefaultTLSHost bool
-}
-
-type clientConfig struct {
-	transport *http.Transport
-	scheme    string
-	addr      string
-}
-
-// NewDaemon returns a Daemon instance to be used for testing.
-// This will create a directory such as d123456789 in the folder specified by $DEST.
-// The daemon will not automatically start.
-func NewDaemon(c *check.C) *Daemon {
-	dest := os.Getenv("DEST")
-	c.Assert(dest, check.Not(check.Equals), "", check.Commentf("Please set the DEST environment variable"))
-
-	id := fmt.Sprintf("d%d", time.Now().UnixNano()%100000000)
-	dir := filepath.Join(dest, id)
-	daemonFolder, err := filepath.Abs(dir)
-	c.Assert(err, check.IsNil, check.Commentf("Could not make %q an absolute path", dir))
-	daemonRoot := filepath.Join(daemonFolder, "root")
-
-	c.Assert(os.MkdirAll(daemonRoot, 0755), check.IsNil, check.Commentf("Could not create daemon root %q", dir))
-
-	userlandProxy := true
-	if env := os.Getenv("DOCKER_USERLANDPROXY"); env != "" {
-		if val, err := strconv.ParseBool(env); err != nil {
-			userlandProxy = val
-		}
-	}
-
-	return &Daemon{
-		Command:       "daemon",
-		id:            id,
-		c:             c,
-		folder:        daemonFolder,
-		root:          daemonRoot,
-		storageDriver: os.Getenv("DOCKER_GRAPHDRIVER"),
-		userlandProxy: userlandProxy,
-	}
-}
-
-func (d *Daemon) getClientConfig() (*clientConfig, error) {
-	var (
-		transport *http.Transport
-		scheme    string
-		addr      string
-		proto     string
-	)
-	if d.useDefaultTLSHost {
-		option := &tlsconfig.Options{
-			CAFile:   "fixtures/https/ca.pem",
-			CertFile: "fixtures/https/client-cert.pem",
-			KeyFile:  "fixtures/https/client-key.pem",
-		}
-		tlsConfig, err := tlsconfig.Client(*option)
-		if err != nil {
-			return nil, err
-		}
-		transport = &http.Transport{
-			TLSClientConfig: tlsConfig,
-		}
-		addr = fmt.Sprintf("%s:%d", opts.DefaultHTTPHost, opts.DefaultTLSHTTPPort)
-		scheme = "https"
-		proto = "tcp"
-	} else if d.useDefaultHost {
-		addr = opts.DefaultUnixSocket
-		proto = "unix"
-		scheme = "http"
-		transport = &http.Transport{}
-	} else {
-		addr = filepath.Join(d.folder, "docker.sock")
-		proto = "unix"
-		scheme = "http"
-		transport = &http.Transport{}
-	}
-
-	d.c.Assert(sockets.ConfigureTransport(transport, proto, addr), check.IsNil)
-
-	return &clientConfig{
-		transport: transport,
-		scheme:    scheme,
-		addr:      addr,
-	}, nil
-}
-
-// Start will start the daemon and return once it is ready to receive requests.
-// You can specify additional daemon flags.
-func (d *Daemon) Start(args ...string) error {
-	logFile, err := os.OpenFile(filepath.Join(d.folder, "docker.log"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
-	d.c.Assert(err, check.IsNil, check.Commentf("[%s] Could not create %s/docker.log", d.id, d.folder))
-
-	return d.StartWithLogFile(logFile, args...)
-}
-
-// StartWithLogFile will start the daemon and attach its streams to a given file.
-func (d *Daemon) StartWithLogFile(out *os.File, providedArgs ...string) error {
-	dockerBinary, err := exec.LookPath(dockerBinary)
-	d.c.Assert(err, check.IsNil, check.Commentf("[%s] could not find docker binary in $PATH", d.id))
-
-	args := append(d.GlobalFlags,
-		d.Command,
-		"--graph", d.root,
-		"--pidfile", fmt.Sprintf("%s/docker.pid", d.folder),
-		fmt.Sprintf("--userland-proxy=%t", d.userlandProxy),
-	)
-	if !(d.useDefaultHost || d.useDefaultTLSHost) {
-		args = append(args, []string{"--host", d.sock()}...)
-	}
-	if root := os.Getenv("DOCKER_REMAP_ROOT"); root != "" {
-		args = append(args, []string{"--userns-remap", root}...)
-	}
-
-	// If we don't explicitly set the log-level or debug flag(-D) then
-	// turn on debug mode
-	foundLog := false
-	foundSd := false
-	for _, a := range providedArgs {
-		if strings.Contains(a, "--log-level") || strings.Contains(a, "-D") || strings.Contains(a, "--debug") {
-			foundLog = true
-		}
-		if strings.Contains(a, "--storage-driver") {
-			foundSd = true
-		}
-	}
-	if !foundLog {
-		args = append(args, "--debug")
-	}
-	if d.storageDriver != "" && !foundSd {
-		args = append(args, "--storage-driver", d.storageDriver)
-	}
-
-	args = append(args, providedArgs...)
-	d.cmd = exec.Command(dockerBinary, args...)
-
-	d.cmd.Stdout = out
-	d.cmd.Stderr = out
-	d.logFile = out
-
-	if err := d.cmd.Start(); err != nil {
-		return fmt.Errorf("[%s] could not start daemon container: %v", d.id, err)
-	}
-
-	wait := make(chan error)
-
-	go func() {
-		wait <- d.cmd.Wait()
-		d.c.Logf("[%s] exiting daemon", d.id)
-		close(wait)
-	}()
-
-	d.wait = wait
-
-	tick := time.Tick(500 * time.Millisecond)
-	// make sure daemon is ready to receive requests
-	startTime := time.Now().Unix()
-	for {
-		d.c.Logf("[%s] waiting for daemon to start", d.id)
-		if time.Now().Unix()-startTime > 5 {
-			// After 5 seconds, give up
-			return fmt.Errorf("[%s] Daemon exited and never started", d.id)
-		}
-		select {
-		case <-time.After(2 * time.Second):
-			return fmt.Errorf("[%s] timeout: daemon does not respond", d.id)
-		case <-tick:
-			clientConfig, err := d.getClientConfig()
-			if err != nil {
-				return err
-			}
-
-			client := &http.Client{
-				Transport: clientConfig.transport,
-			}
-
-			req, err := http.NewRequest("GET", "/_ping", nil)
-			d.c.Assert(err, check.IsNil, check.Commentf("[%s] could not create new request", d.id))
-			req.URL.Host = clientConfig.addr
-			req.URL.Scheme = clientConfig.scheme
-			resp, err := client.Do(req)
-			if err != nil {
-				continue
-			}
-			if resp.StatusCode != http.StatusOK {
-				d.c.Logf("[%s] received status != 200 OK: %s", d.id, resp.Status)
-			}
-			d.c.Logf("[%s] daemon started", d.id)
-			d.root, err = d.queryRootDir()
-			if err != nil {
-				return fmt.Errorf("[%s] error querying daemon for root directory: %v", d.id, err)
-			}
-			return nil
-		}
-	}
-}
-
-// StartWithBusybox will first start the daemon with Daemon.Start()
-// then save the busybox image from the main daemon and load it into this Daemon instance.
-func (d *Daemon) StartWithBusybox(arg ...string) error {
-	if err := d.Start(arg...); err != nil {
-		return err
-	}
-	return d.LoadBusybox()
-}
-
-// Stop will send a SIGINT every second and wait for the daemon to stop.
-// If it timeouts, a SIGKILL is sent.
-// Stop will not delete the daemon directory. If a purged daemon is needed,
-// instantiate a new one with NewDaemon.
-func (d *Daemon) Stop() error {
-	if d.cmd == nil || d.wait == nil {
-		return errors.New("daemon not started")
-	}
-
-	defer func() {
-		d.logFile.Close()
-		d.cmd = nil
-	}()
-
-	i := 1
-	tick := time.Tick(time.Second)
-
-	if err := d.cmd.Process.Signal(os.Interrupt); err != nil {
-		return fmt.Errorf("could not send signal: %v", err)
-	}
-out1:
-	for {
-		select {
-		case err := <-d.wait:
-			return err
-		case <-time.After(15 * time.Second):
-			// time for stopping jobs and run onShutdown hooks
-			d.c.Log("timeout")
-			break out1
-		}
-	}
-
-out2:
-	for {
-		select {
-		case err := <-d.wait:
-			return err
-		case <-tick:
-			i++
-			if i > 4 {
-				d.c.Logf("tried to interrupt daemon for %d times, now try to kill it", i)
-				break out2
-			}
-			d.c.Logf("Attempt #%d: daemon is still running with pid %d", i, d.cmd.Process.Pid)
-			if err := d.cmd.Process.Signal(os.Interrupt); err != nil {
-				return fmt.Errorf("could not send signal: %v", err)
-			}
-		}
-	}
-
-	if err := d.cmd.Process.Kill(); err != nil {
-		d.c.Logf("Could not kill daemon: %v", err)
-		return err
-	}
-
-	return nil
-}
-
-// Restart will restart the daemon by first stopping it and then starting it.
-func (d *Daemon) Restart(arg ...string) error {
-	d.Stop()
-	// in the case of tests running a user namespace-enabled daemon, we have resolved
-	// d.root to be the actual final path of the graph dir after the "uid.gid" of
-	// remapped root is added--we need to subtract it from the path before calling
-	// start or else we will continue making subdirectories rather than truly restarting
-	// with the same location/root:
-	if root := os.Getenv("DOCKER_REMAP_ROOT"); root != "" {
-		d.root = filepath.Dir(d.root)
-	}
-	return d.Start(arg...)
-}
-
-// LoadBusybox will load the stored busybox into a newly started daemon
-func (d *Daemon) LoadBusybox() error {
-	bb := filepath.Join(d.folder, "busybox.tar")
-	if _, err := os.Stat(bb); err != nil {
-		if !os.IsNotExist(err) {
-			return fmt.Errorf("unexpected error on busybox.tar stat: %v", err)
-		}
-		// saving busybox image from main daemon
-		if err := exec.Command(dockerBinary, "save", "--output", bb, "busybox:latest").Run(); err != nil {
-			return fmt.Errorf("could not save busybox image: %v", err)
-		}
-	}
-	// loading busybox image to this daemon
-	if out, err := d.Cmd("load", "--input", bb); err != nil {
-		return fmt.Errorf("could not load busybox image: %s", out)
-	}
-	if err := os.Remove(bb); err != nil {
-		d.c.Logf("could not remove %s: %v", bb, err)
-	}
-	return nil
-}
-
-func (d *Daemon) queryRootDir() (string, error) {
-	// update daemon root by asking /info endpoint (to support user
-	// namespaced daemon with root remapped uid.gid directory)
-	clientConfig, err := d.getClientConfig()
-	if err != nil {
-		return "", err
-	}
-
-	client := &http.Client{
-		Transport: clientConfig.transport,
-	}
-
-	req, err := http.NewRequest("GET", "/info", nil)
-	if err != nil {
-		return "", err
-	}
-	req.Header.Set("Content-Type", "application/json")
-	req.URL.Host = clientConfig.addr
-	req.URL.Scheme = clientConfig.scheme
-
-	resp, err := client.Do(req)
-	if err != nil {
-		return "", err
-	}
-	body := ioutils.NewReadCloserWrapper(resp.Body, func() error {
-		return resp.Body.Close()
-	})
-
-	type Info struct {
-		DockerRootDir string
-	}
-	var b []byte
-	var i Info
-	b, err = readBody(body)
-	if err == nil && resp.StatusCode == 200 {
-		// read the docker root dir
-		if err = json.Unmarshal(b, &i); err == nil {
-			return i.DockerRootDir, nil
-		}
-	}
-	return "", err
-}
-
-func (d *Daemon) sock() string {
-	return fmt.Sprintf("unix://%s/docker.sock", d.folder)
-}
-
-func (d *Daemon) waitRun(contID string) error {
-	args := []string{"--host", d.sock()}
-	return waitInspectWithArgs(contID, "{{.State.Running}}", "true", 10*time.Second, args...)
-}
-
-func (d *Daemon) getBaseDeviceSize(c *check.C) int64 {
-	infoCmdOutput, _, err := runCommandPipelineWithOutput(
-		exec.Command(dockerBinary, "-H", d.sock(), "info"),
-		exec.Command("grep", "Base Device Size"),
-	)
-	c.Assert(err, checker.IsNil)
-	basesizeSlice := strings.Split(infoCmdOutput, ":")
-	basesize := strings.Trim(basesizeSlice[1], " ")
-	basesize = strings.Trim(basesize, "\n")[:len(basesize)-3]
-	basesizeFloat, err := strconv.ParseFloat(strings.Trim(basesize, " "), 64)
-	c.Assert(err, checker.IsNil)
-	basesizeBytes := int64(basesizeFloat) * (1024 * 1024 * 1024)
-	return basesizeBytes
-}
-
 func convertBasesize(basesizeBytes int64) (int64, error) {
 func convertBasesize(basesizeBytes int64) (int64, error) {
 	basesize := units.HumanSize(float64(basesizeBytes))
 	basesize := units.HumanSize(float64(basesizeBytes))
 	basesize = strings.Trim(basesize, " ")[:len(basesize)-3]
 	basesize = strings.Trim(basesize, " ")[:len(basesize)-3]
@@ -497,48 +110,6 @@ func convertBasesize(basesizeBytes int64) (int64, error) {
 	return int64(basesizeFloat) * 1024 * 1024 * 1024, nil
 	return int64(basesizeFloat) * 1024 * 1024 * 1024, nil
 }
 }
 
 
-// Cmd will execute a docker CLI command against this Daemon.
-// Example: d.Cmd("version") will run docker -H unix://path/to/unix.sock version
-func (d *Daemon) Cmd(name string, arg ...string) (string, error) {
-	args := []string{"--host", d.sock(), name}
-	args = append(args, arg...)
-	c := exec.Command(dockerBinary, args...)
-	b, err := c.CombinedOutput()
-	return string(b), err
-}
-
-// CmdWithArgs will execute a docker CLI command against a daemon with the
-// given additional arguments
-func (d *Daemon) CmdWithArgs(daemonArgs []string, name string, arg ...string) (string, error) {
-	args := append(daemonArgs, name)
-	args = append(args, arg...)
-	c := exec.Command(dockerBinary, args...)
-	b, err := c.CombinedOutput()
-	return string(b), err
-}
-
-// LogFileName returns the path the the daemon's log file
-func (d *Daemon) LogFileName() string {
-	return d.logFile.Name()
-}
-
-func (d *Daemon) getIDByName(name string) (string, error) {
-	return d.inspectFieldWithError(name, "Id")
-}
-
-func (d *Daemon) inspectFilter(name, filter string) (string, error) {
-	format := fmt.Sprintf("{{%s}}", filter)
-	out, err := d.Cmd("inspect", "-f", format, name)
-	if err != nil {
-		return "", fmt.Errorf("failed to inspect %s: %s", name, out)
-	}
-	return strings.TrimSpace(out), nil
-}
-
-func (d *Daemon) inspectFieldWithError(name, field string) (string, error) {
-	return d.inspectFilter(name, fmt.Sprintf(".%s", field))
-}
-
 func daemonHost() string {
 func daemonHost() string {
 	daemonURLStr := "unix://" + opts.DefaultUnixSocket
 	daemonURLStr := "unix://" + opts.DefaultUnixSocket
 	if daemonHostVar := os.Getenv("DOCKER_HOST"); daemonHostVar != "" {
 	if daemonHostVar := os.Getenv("DOCKER_HOST"); daemonHostVar != "" {
@@ -972,14 +543,6 @@ func findContainerIP(c *check.C, id string, network string) string {
 	return strings.Trim(out, " \r\n'")
 	return strings.Trim(out, " \r\n'")
 }
 }
 
 
-func (d *Daemon) findContainerIP(id string) string {
-	out, err := d.Cmd("inspect", fmt.Sprintf("--format='{{ .NetworkSettings.Networks.bridge.IPAddress }}'"), id)
-	if err != nil {
-		d.c.Log(err)
-	}
-	return strings.Trim(out, " \r\n'")
-}
-
 func getContainerCount() (int, error) {
 func getContainerCount() (int, error) {
 	const containers = "Containers:"
 	const containers = "Containers:"