Browse Source

Add context.RequestID to event stream

This PR adds a "request ID" to each event generated, the 'docker events'
stream now looks like this:

```
2015-09-10T15:02:50.000000000-07:00 [reqid: c01e3534ddca] de7c5d4ca927253cf4e978ee9c4545161e406e9b5a14617efb52c658b249174a: (from ubuntu) create
```
Note the `[reqID: c01e3534ddca]` part, that's new.

Each HTTP request will generate its own unique ID. So, if you do a
`docker build` you'll see a series of events all with the same reqID.
This allow for log processing tools to determine which events are all related
to the same http request.

I didn't propigate the context to all possible funcs in the daemon,
I decided to just do the ones that needed it in order to get the reqID
into the events. I'd like to have people review this direction first, and
if we're ok with it then I'll make sure we're consistent about when
we pass around the context - IOW, make sure that all funcs at the same level
have a context passed in even if they don't call the log funcs - this will
ensure we're consistent w/o passing it around for all calls unnecessarily.

ping @icecrime @calavera @crosbymichael

Signed-off-by: Doug Davis <dug@us.ibm.com>
Doug Davis 9 years ago
parent
commit
26b1064967
68 changed files with 737 additions and 565 deletions
  1. 22 22
      api/server/container.go
  2. 4 4
      api/server/copy.go
  3. 2 2
      api/server/daemon.go
  4. 4 4
      api/server/exec.go
  5. 14 14
      api/server/image.go
  6. 3 3
      api/server/inspect.go
  7. 8 6
      api/server/server.go
  8. 6 2
      api/server/server_experimental_unix.go
  9. 5 1
      api/server/server_stub.go
  10. 3 2
      api/server/server_unix.go
  11. 3 2
      api/server/server_windows.go
  12. 4 4
      api/server/volume.go
  13. 42 41
      builder/dispatchers.go
  14. 9 8
      builder/evaluator.go
  15. 30 29
      builder/internals.go
  16. 11 10
      builder/job.go
  17. 25 24
      daemon/archive.go
  18. 7 6
      daemon/attach.go
  19. 6 3
      daemon/changes.go
  20. 5 4
      daemon/commit.go
  21. 59 57
      daemon/container.go
  22. 28 27
      daemon/container_unix.go
  23. 6 5
      daemon/container_windows.go
  24. 17 16
      daemon/create.go
  25. 42 44
      daemon/daemon.go
  26. 14 9
      daemon/daemon_test.go
  27. 8 7
      daemon/daemon_unix.go
  28. 4 3
      daemon/daemon_windows.go
  29. 13 11
      daemon/delete.go
  30. 4 2
      daemon/events/events.go
  31. 8 4
      daemon/events/events_test.go
  32. 11 10
      daemon/exec.go
  33. 4 3
      daemon/execdriver/driver.go
  34. 4 3
      daemon/execdriver/lxc/driver.go
  35. 5 4
      daemon/execdriver/native/create.go
  36. 4 3
      daemon/execdriver/native/driver.go
  37. 3 2
      daemon/execdriver/native/exec.go
  38. 3 2
      daemon/execdriver/windows/exec.go
  39. 3 2
      daemon/execdriver/windows/run.go
  40. 4 3
      daemon/export.go
  41. 41 40
      daemon/image_delete.go
  42. 7 6
      daemon/info.go
  43. 11 10
      daemon/inspect.go
  44. 7 4
      daemon/inspect_unix.go
  45. 6 3
      daemon/inspect_windows.go
  46. 9 5
      daemon/kill.go
  47. 24 23
      daemon/list.go
  48. 2 1
      daemon/logs.go
  49. 11 10
      daemon/monitor.go
  50. 4 3
      daemon/pause.go
  51. 6 5
      daemon/rename.go
  52. 8 4
      daemon/resize.go
  53. 4 3
      daemon/restart.go
  54. 6 5
      daemon/start.go
  55. 3 2
      daemon/stats.go
  56. 4 3
      daemon/stop.go
  57. 5 4
      daemon/top_unix.go
  58. 2 1
      daemon/top_windows.go
  59. 4 3
      daemon/unpause.go
  60. 3 2
      daemon/volumes_unix.go
  61. 2 1
      daemon/volumes_windows.go
  62. 7 3
      daemon/wait.go
  63. 15 9
      docker/daemon.go
  64. 3 2
      graph/import.go
  65. 3 2
      graph/pull.go
  66. 3 2
      graph/push.go
  67. 76 1
      integration-cli/docker_cli_events_test.go
  68. 4 0
      pkg/jsonmessage/jsonmessage.go

+ 22 - 22
api/server/container.go

@@ -45,7 +45,7 @@ func (s *Server) getContainersJSON(ctx context.Context, w http.ResponseWriter, r
 		config.Limit = limit
 		config.Limit = limit
 	}
 	}
 
 
-	containers, err := s.daemon.Containers(config)
+	containers, err := s.daemon.Containers(ctx, config)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -83,7 +83,7 @@ func (s *Server) getContainersStats(ctx context.Context, w http.ResponseWriter,
 		Version:   version,
 		Version:   version,
 	}
 	}
 
 
-	return s.daemon.ContainerStats(vars["name"], config)
+	return s.daemon.ContainerStats(ctx, vars["name"], config)
 }
 }
 
 
 func (s *Server) getContainersLogs(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 func (s *Server) getContainersLogs(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
@@ -118,7 +118,7 @@ func (s *Server) getContainersLogs(ctx context.Context, w http.ResponseWriter, r
 		closeNotifier = notifier.CloseNotify()
 		closeNotifier = notifier.CloseNotify()
 	}
 	}
 
 
-	c, err := s.daemon.Get(vars["name"])
+	c, err := s.daemon.Get(ctx, vars["name"])
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -140,7 +140,7 @@ func (s *Server) getContainersLogs(ctx context.Context, w http.ResponseWriter, r
 		Stop:       closeNotifier,
 		Stop:       closeNotifier,
 	}
 	}
 
 
-	if err := s.daemon.ContainerLogs(c, logsConfig); err != nil {
+	if err := s.daemon.ContainerLogs(ctx, c, logsConfig); err != nil {
 		// The client may be expecting all of the data we're sending to
 		// The client may be expecting all of the data we're sending to
 		// be multiplexed, so send it through OutStream, which will
 		// be multiplexed, so send it through OutStream, which will
 		// have been set up to handle that if needed.
 		// have been set up to handle that if needed.
@@ -155,7 +155,7 @@ func (s *Server) getContainersExport(ctx context.Context, w http.ResponseWriter,
 		return fmt.Errorf("Missing parameter")
 		return fmt.Errorf("Missing parameter")
 	}
 	}
 
 
-	return s.daemon.ContainerExport(vars["name"], w)
+	return s.daemon.ContainerExport(ctx, vars["name"], w)
 }
 }
 
 
 func (s *Server) postContainersStart(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 func (s *Server) postContainersStart(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
@@ -183,7 +183,7 @@ func (s *Server) postContainersStart(ctx context.Context, w http.ResponseWriter,
 		hostConfig = c
 		hostConfig = c
 	}
 	}
 
 
-	if err := s.daemon.ContainerStart(vars["name"], hostConfig); err != nil {
+	if err := s.daemon.ContainerStart(ctx, vars["name"], hostConfig); err != nil {
 		return err
 		return err
 	}
 	}
 	w.WriteHeader(http.StatusNoContent)
 	w.WriteHeader(http.StatusNoContent)
@@ -200,7 +200,7 @@ func (s *Server) postContainersStop(ctx context.Context, w http.ResponseWriter,
 
 
 	seconds, _ := strconv.Atoi(r.Form.Get("t"))
 	seconds, _ := strconv.Atoi(r.Form.Get("t"))
 
 
-	if err := s.daemon.ContainerStop(vars["name"], seconds); err != nil {
+	if err := s.daemon.ContainerStop(ctx, vars["name"], seconds); err != nil {
 		return err
 		return err
 	}
 	}
 	w.WriteHeader(http.StatusNoContent)
 	w.WriteHeader(http.StatusNoContent)
@@ -227,7 +227,7 @@ func (s *Server) postContainersKill(ctx context.Context, w http.ResponseWriter,
 		}
 		}
 	}
 	}
 
 
-	if err := s.daemon.ContainerKill(name, uint64(sig)); err != nil {
+	if err := s.daemon.ContainerKill(ctx, name, uint64(sig)); err != nil {
 		theErr, isDerr := err.(errcode.ErrorCoder)
 		theErr, isDerr := err.(errcode.ErrorCoder)
 		isStopped := isDerr && theErr.ErrorCode() == derr.ErrorCodeNotRunning
 		isStopped := isDerr && theErr.ErrorCode() == derr.ErrorCodeNotRunning
 
 
@@ -254,7 +254,7 @@ func (s *Server) postContainersRestart(ctx context.Context, w http.ResponseWrite
 
 
 	timeout, _ := strconv.Atoi(r.Form.Get("t"))
 	timeout, _ := strconv.Atoi(r.Form.Get("t"))
 
 
-	if err := s.daemon.ContainerRestart(vars["name"], timeout); err != nil {
+	if err := s.daemon.ContainerRestart(ctx, vars["name"], timeout); err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -271,7 +271,7 @@ func (s *Server) postContainersPause(ctx context.Context, w http.ResponseWriter,
 		return err
 		return err
 	}
 	}
 
 
-	if err := s.daemon.ContainerPause(vars["name"]); err != nil {
+	if err := s.daemon.ContainerPause(ctx, vars["name"]); err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -288,7 +288,7 @@ func (s *Server) postContainersUnpause(ctx context.Context, w http.ResponseWrite
 		return err
 		return err
 	}
 	}
 
 
-	if err := s.daemon.ContainerUnpause(vars["name"]); err != nil {
+	if err := s.daemon.ContainerUnpause(ctx, vars["name"]); err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -302,7 +302,7 @@ func (s *Server) postContainersWait(ctx context.Context, w http.ResponseWriter,
 		return fmt.Errorf("Missing parameter")
 		return fmt.Errorf("Missing parameter")
 	}
 	}
 
 
-	status, err := s.daemon.ContainerWait(vars["name"], -1*time.Second)
+	status, err := s.daemon.ContainerWait(ctx, vars["name"], -1*time.Second)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -317,7 +317,7 @@ func (s *Server) getContainersChanges(ctx context.Context, w http.ResponseWriter
 		return fmt.Errorf("Missing parameter")
 		return fmt.Errorf("Missing parameter")
 	}
 	}
 
 
-	changes, err := s.daemon.ContainerChanges(vars["name"])
+	changes, err := s.daemon.ContainerChanges(ctx, vars["name"])
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -334,7 +334,7 @@ func (s *Server) getContainersTop(ctx context.Context, w http.ResponseWriter, r
 		return err
 		return err
 	}
 	}
 
 
-	procList, err := s.daemon.ContainerTop(vars["name"], r.Form.Get("ps_args"))
+	procList, err := s.daemon.ContainerTop(ctx, vars["name"], r.Form.Get("ps_args"))
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -352,7 +352,7 @@ func (s *Server) postContainerRename(ctx context.Context, w http.ResponseWriter,
 
 
 	name := vars["name"]
 	name := vars["name"]
 	newName := r.Form.Get("name")
 	newName := r.Form.Get("name")
-	if err := s.daemon.ContainerRename(name, newName); err != nil {
+	if err := s.daemon.ContainerRename(ctx, name, newName); err != nil {
 		return err
 		return err
 	}
 	}
 	w.WriteHeader(http.StatusNoContent)
 	w.WriteHeader(http.StatusNoContent)
@@ -378,7 +378,7 @@ func (s *Server) postContainersCreate(ctx context.Context, w http.ResponseWriter
 	version := ctx.Version()
 	version := ctx.Version()
 	adjustCPUShares := version.LessThan("1.19")
 	adjustCPUShares := version.LessThan("1.19")
 
 
-	container, warnings, err := s.daemon.ContainerCreate(name, config, hostConfig, adjustCPUShares)
+	container, warnings, err := s.daemon.ContainerCreate(ctx, name, config, hostConfig, adjustCPUShares)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -404,7 +404,7 @@ func (s *Server) deleteContainers(ctx context.Context, w http.ResponseWriter, r
 		RemoveLink:   boolValue(r, "link"),
 		RemoveLink:   boolValue(r, "link"),
 	}
 	}
 
 
-	if err := s.daemon.ContainerRm(name, config); err != nil {
+	if err := s.daemon.ContainerRm(ctx, name, config); err != nil {
 		// Force a 404 for the empty string
 		// Force a 404 for the empty string
 		if strings.Contains(strings.ToLower(err.Error()), "prefix can't be empty") {
 		if strings.Contains(strings.ToLower(err.Error()), "prefix can't be empty") {
 			return fmt.Errorf("no such id: \"\"")
 			return fmt.Errorf("no such id: \"\"")
@@ -434,7 +434,7 @@ func (s *Server) postContainersResize(ctx context.Context, w http.ResponseWriter
 		return err
 		return err
 	}
 	}
 
 
-	return s.daemon.ContainerResize(vars["name"], height, width)
+	return s.daemon.ContainerResize(ctx, vars["name"], height, width)
 }
 }
 
 
 func (s *Server) postContainersAttach(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 func (s *Server) postContainersAttach(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
@@ -446,7 +446,7 @@ func (s *Server) postContainersAttach(ctx context.Context, w http.ResponseWriter
 	}
 	}
 	containerName := vars["name"]
 	containerName := vars["name"]
 
 
-	if !s.daemon.Exists(containerName) {
+	if !s.daemon.Exists(ctx, containerName) {
 		return derr.ErrorCodeNoSuchContainer.WithArgs(containerName)
 		return derr.ErrorCodeNoSuchContainer.WithArgs(containerName)
 	}
 	}
 
 
@@ -472,7 +472,7 @@ func (s *Server) postContainersAttach(ctx context.Context, w http.ResponseWriter
 		Stream:    boolValue(r, "stream"),
 		Stream:    boolValue(r, "stream"),
 	}
 	}
 
 
-	if err := s.daemon.ContainerAttachWithLogs(containerName, attachWithLogsConfig); err != nil {
+	if err := s.daemon.ContainerAttachWithLogs(ctx, containerName, attachWithLogsConfig); err != nil {
 		fmt.Fprintf(outStream, "Error attaching: %s\n", err)
 		fmt.Fprintf(outStream, "Error attaching: %s\n", err)
 	}
 	}
 
 
@@ -488,7 +488,7 @@ func (s *Server) wsContainersAttach(ctx context.Context, w http.ResponseWriter,
 	}
 	}
 	containerName := vars["name"]
 	containerName := vars["name"]
 
 
-	if !s.daemon.Exists(containerName) {
+	if !s.daemon.Exists(ctx, containerName) {
 		return derr.ErrorCodeNoSuchContainer.WithArgs(containerName)
 		return derr.ErrorCodeNoSuchContainer.WithArgs(containerName)
 	}
 	}
 
 
@@ -503,7 +503,7 @@ func (s *Server) wsContainersAttach(ctx context.Context, w http.ResponseWriter,
 			Stream:    boolValue(r, "stream"),
 			Stream:    boolValue(r, "stream"),
 		}
 		}
 
 
-		if err := s.daemon.ContainerWsAttachWithLogs(containerName, wsAttachWithLogsConfig); err != nil {
+		if err := s.daemon.ContainerWsAttachWithLogs(ctx, containerName, wsAttachWithLogsConfig); err != nil {
 			logrus.Errorf("Error attaching websocket: %s", err)
 			logrus.Errorf("Error attaching websocket: %s", err)
 		}
 		}
 	})
 	})

+ 4 - 4
api/server/copy.go

@@ -32,7 +32,7 @@ func (s *Server) postContainersCopy(ctx context.Context, w http.ResponseWriter,
 		return fmt.Errorf("Path cannot be empty")
 		return fmt.Errorf("Path cannot be empty")
 	}
 	}
 
 
-	data, err := s.daemon.ContainerCopy(vars["name"], cfg.Resource)
+	data, err := s.daemon.ContainerCopy(ctx, vars["name"], cfg.Resource)
 	if err != nil {
 	if err != nil {
 		if strings.Contains(strings.ToLower(err.Error()), "no such id") {
 		if strings.Contains(strings.ToLower(err.Error()), "no such id") {
 			w.WriteHeader(http.StatusNotFound)
 			w.WriteHeader(http.StatusNotFound)
@@ -74,7 +74,7 @@ func (s *Server) headContainersArchive(ctx context.Context, w http.ResponseWrite
 		return err
 		return err
 	}
 	}
 
 
-	stat, err := s.daemon.ContainerStatPath(v.name, v.path)
+	stat, err := s.daemon.ContainerStatPath(ctx, v.name, v.path)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -88,7 +88,7 @@ func (s *Server) getContainersArchive(ctx context.Context, w http.ResponseWriter
 		return err
 		return err
 	}
 	}
 
 
-	tarArchive, stat, err := s.daemon.ContainerArchivePath(v.name, v.path)
+	tarArchive, stat, err := s.daemon.ContainerArchivePath(ctx, v.name, v.path)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -111,5 +111,5 @@ func (s *Server) putContainersArchive(ctx context.Context, w http.ResponseWriter
 	}
 	}
 
 
 	noOverwriteDirNonDir := boolValue(r, "noOverwriteDirNonDir")
 	noOverwriteDirNonDir := boolValue(r, "noOverwriteDirNonDir")
-	return s.daemon.ContainerExtractToDir(v.name, v.path, noOverwriteDirNonDir, r.Body)
+	return s.daemon.ContainerExtractToDir(ctx, v.name, v.path, noOverwriteDirNonDir, r.Body)
 }
 }

+ 2 - 2
api/server/daemon.go

@@ -45,7 +45,7 @@ func (s *Server) getVersion(ctx context.Context, w http.ResponseWriter, r *http.
 }
 }
 
 
 func (s *Server) getInfo(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 func (s *Server) getInfo(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
-	info, err := s.daemon.SystemInfo()
+	info, err := s.daemon.SystemInfo(ctx)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -120,7 +120,7 @@ func (s *Server) getEvents(ctx context.Context, w http.ResponseWriter, r *http.R
 	enc := json.NewEncoder(outStream)
 	enc := json.NewEncoder(outStream)
 
 
 	getContainerID := func(cn string) string {
 	getContainerID := func(cn string) string {
-		c, err := d.Get(cn)
+		c, err := d.Get(ctx, cn)
 		if err != nil {
 		if err != nil {
 			return ""
 			return ""
 		}
 		}

+ 4 - 4
api/server/exec.go

@@ -19,7 +19,7 @@ func (s *Server) getExecByID(ctx context.Context, w http.ResponseWriter, r *http
 		return fmt.Errorf("Missing parameter 'id'")
 		return fmt.Errorf("Missing parameter 'id'")
 	}
 	}
 
 
-	eConfig, err := s.daemon.ContainerExecInspect(vars["id"])
+	eConfig, err := s.daemon.ContainerExecInspect(ctx, vars["id"])
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -47,7 +47,7 @@ func (s *Server) postContainerExecCreate(ctx context.Context, w http.ResponseWri
 	}
 	}
 
 
 	// Register an instance of Exec in container.
 	// Register an instance of Exec in container.
-	id, err := s.daemon.ContainerExecCreate(execConfig)
+	id, err := s.daemon.ContainerExecCreate(ctx, execConfig)
 	if err != nil {
 	if err != nil {
 		logrus.Errorf("Error setting up exec command in container %s: %s", name, err)
 		logrus.Errorf("Error setting up exec command in container %s: %s", name, err)
 		return err
 		return err
@@ -100,7 +100,7 @@ func (s *Server) postContainerExecStart(ctx context.Context, w http.ResponseWrit
 	}
 	}
 
 
 	// Now run the user process in container.
 	// Now run the user process in container.
-	if err := s.daemon.ContainerExecStart(execName, stdin, stdout, stderr); err != nil {
+	if err := s.daemon.ContainerExecStart(ctx, execName, stdin, stdout, stderr); err != nil {
 		fmt.Fprintf(outStream, "Error running exec in container: %v\n", err)
 		fmt.Fprintf(outStream, "Error running exec in container: %v\n", err)
 	}
 	}
 	return nil
 	return nil
@@ -123,5 +123,5 @@ func (s *Server) postContainerExecResize(ctx context.Context, w http.ResponseWri
 		return err
 		return err
 	}
 	}
 
 
-	return s.daemon.ContainerExecResize(vars["name"], height, width)
+	return s.daemon.ContainerExecResize(ctx, vars["name"], height, width)
 }
 }

+ 14 - 14
api/server/image.go

@@ -55,7 +55,7 @@ func (s *Server) postCommit(ctx context.Context, w http.ResponseWriter, r *http.
 		Config:  c,
 		Config:  c,
 	}
 	}
 
 
-	imgID, err := builder.Commit(cname, s.daemon, commitCfg)
+	imgID, err := builder.Commit(ctx, cname, s.daemon, commitCfg)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -112,7 +112,7 @@ func (s *Server) postImagesCreate(ctx context.Context, w http.ResponseWriter, r
 			OutStream:   output,
 			OutStream:   output,
 		}
 		}
 
 
-		err = s.daemon.Repositories().Pull(image, tag, imagePullConfig)
+		err = s.daemon.Repositories(ctx).Pull(ctx, image, tag, imagePullConfig)
 	} else { //import
 	} else { //import
 		if tag == "" {
 		if tag == "" {
 			repo, tag = parsers.ParseRepositoryTag(repo)
 			repo, tag = parsers.ParseRepositoryTag(repo)
@@ -124,12 +124,12 @@ func (s *Server) postImagesCreate(ctx context.Context, w http.ResponseWriter, r
 		// generated from the download to be available to the output
 		// generated from the download to be available to the output
 		// stream processing below
 		// stream processing below
 		var newConfig *runconfig.Config
 		var newConfig *runconfig.Config
-		newConfig, err = builder.BuildFromConfig(s.daemon, &runconfig.Config{}, r.Form["changes"])
+		newConfig, err = builder.BuildFromConfig(ctx, s.daemon, &runconfig.Config{}, r.Form["changes"])
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
 
 
-		err = s.daemon.Repositories().Import(src, repo, tag, message, r.Body, output, newConfig)
+		err = s.daemon.Repositories(ctx).Import(ctx, src, repo, tag, message, r.Body, output, newConfig)
 	}
 	}
 	if err != nil {
 	if err != nil {
 		if !output.Flushed() {
 		if !output.Flushed() {
@@ -184,7 +184,7 @@ func (s *Server) postImagesPush(ctx context.Context, w http.ResponseWriter, r *h
 
 
 	w.Header().Set("Content-Type", "application/json")
 	w.Header().Set("Content-Type", "application/json")
 
 
-	if err := s.daemon.Repositories().Push(name, imagePushConfig); err != nil {
+	if err := s.daemon.Repositories(ctx).Push(ctx, name, imagePushConfig); err != nil {
 		if !output.Flushed() {
 		if !output.Flushed() {
 			return err
 			return err
 		}
 		}
@@ -212,7 +212,7 @@ func (s *Server) getImagesGet(ctx context.Context, w http.ResponseWriter, r *htt
 		names = r.Form["names"]
 		names = r.Form["names"]
 	}
 	}
 
 
-	if err := s.daemon.Repositories().ImageExport(names, output); err != nil {
+	if err := s.daemon.Repositories(ctx).ImageExport(names, output); err != nil {
 		if !output.Flushed() {
 		if !output.Flushed() {
 			return err
 			return err
 		}
 		}
@@ -223,7 +223,7 @@ func (s *Server) getImagesGet(ctx context.Context, w http.ResponseWriter, r *htt
 }
 }
 
 
 func (s *Server) postImagesLoad(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 func (s *Server) postImagesLoad(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
-	return s.daemon.Repositories().Load(r.Body, w)
+	return s.daemon.Repositories(ctx).Load(r.Body, w)
 }
 }
 
 
 func (s *Server) deleteImages(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 func (s *Server) deleteImages(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
@@ -243,7 +243,7 @@ func (s *Server) deleteImages(ctx context.Context, w http.ResponseWriter, r *htt
 	force := boolValue(r, "force")
 	force := boolValue(r, "force")
 	prune := !boolValue(r, "noprune")
 	prune := !boolValue(r, "noprune")
 
 
-	list, err := s.daemon.ImageDelete(name, force, prune)
+	list, err := s.daemon.ImageDelete(ctx, name, force, prune)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -256,7 +256,7 @@ func (s *Server) getImagesByName(ctx context.Context, w http.ResponseWriter, r *
 		return fmt.Errorf("Missing parameter")
 		return fmt.Errorf("Missing parameter")
 	}
 	}
 
 
-	imageInspect, err := s.daemon.Repositories().Lookup(vars["name"])
+	imageInspect, err := s.daemon.Repositories(ctx).Lookup(vars["name"])
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -346,7 +346,7 @@ func (s *Server) postBuild(ctx context.Context, w http.ResponseWriter, r *http.R
 		}()
 		}()
 	}
 	}
 
 
-	if err := builder.Build(s.daemon, buildConfig); err != nil {
+	if err := builder.Build(ctx, s.daemon, buildConfig); err != nil {
 		// Do not write the error in the http output if it's still empty.
 		// Do not write the error in the http output if it's still empty.
 		// This prevents from writing a 200(OK) when there is an interal error.
 		// This prevents from writing a 200(OK) when there is an interal error.
 		if !output.Flushed() {
 		if !output.Flushed() {
@@ -364,7 +364,7 @@ func (s *Server) getImagesJSON(ctx context.Context, w http.ResponseWriter, r *ht
 	}
 	}
 
 
 	// FIXME: The filter parameter could just be a match filter
 	// FIXME: The filter parameter could just be a match filter
-	images, err := s.daemon.Repositories().Images(r.Form.Get("filters"), r.Form.Get("filter"), boolValue(r, "all"))
+	images, err := s.daemon.Repositories(ctx).Images(r.Form.Get("filters"), r.Form.Get("filter"), boolValue(r, "all"))
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -378,7 +378,7 @@ func (s *Server) getImagesHistory(ctx context.Context, w http.ResponseWriter, r
 	}
 	}
 
 
 	name := vars["name"]
 	name := vars["name"]
-	history, err := s.daemon.Repositories().History(name)
+	history, err := s.daemon.Repositories(ctx).History(name)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -398,10 +398,10 @@ func (s *Server) postImagesTag(ctx context.Context, w http.ResponseWriter, r *ht
 	tag := r.Form.Get("tag")
 	tag := r.Form.Get("tag")
 	force := boolValue(r, "force")
 	force := boolValue(r, "force")
 	name := vars["name"]
 	name := vars["name"]
-	if err := s.daemon.Repositories().Tag(repo, tag, name, force); err != nil {
+	if err := s.daemon.Repositories(ctx).Tag(repo, tag, name, force); err != nil {
 		return err
 		return err
 	}
 	}
-	s.daemon.EventsService.Log("tag", utils.ImageReference(repo, tag), "")
+	s.daemon.EventsService.Log(ctx, "tag", utils.ImageReference(repo, tag), "")
 	w.WriteHeader(http.StatusCreated)
 	w.WriteHeader(http.StatusCreated)
 	return nil
 	return nil
 }
 }

+ 3 - 3
api/server/inspect.go

@@ -20,11 +20,11 @@ func (s *Server) getContainersByName(ctx context.Context, w http.ResponseWriter,
 
 
 	switch {
 	switch {
 	case version.LessThan("1.20"):
 	case version.LessThan("1.20"):
-		json, err = s.daemon.ContainerInspectPre120(vars["name"])
+		json, err = s.daemon.ContainerInspectPre120(ctx, vars["name"])
 	case version.Equal("1.20"):
 	case version.Equal("1.20"):
-		json, err = s.daemon.ContainerInspect120(vars["name"])
+		json, err = s.daemon.ContainerInspect120(ctx, vars["name"])
 	default:
 	default:
-		json, err = s.daemon.ContainerInspect(vars["name"])
+		json, err = s.daemon.ContainerInspect(ctx, vars["name"])
 	}
 	}
 
 
 	if err != nil {
 	if err != nil {

+ 8 - 6
api/server/server.go

@@ -18,6 +18,7 @@ import (
 	"github.com/docker/docker/context"
 	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/pkg/sockets"
 	"github.com/docker/docker/pkg/sockets"
+	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/utils"
 	"github.com/docker/docker/utils"
 )
 )
 
 
@@ -41,12 +42,12 @@ type Server struct {
 }
 }
 
 
 // New returns a new instance of the server based on the specified configuration.
 // New returns a new instance of the server based on the specified configuration.
-func New(cfg *Config) *Server {
+func New(ctx context.Context, cfg *Config) *Server {
 	srv := &Server{
 	srv := &Server{
 		cfg:   cfg,
 		cfg:   cfg,
 		start: make(chan struct{}),
 		start: make(chan struct{}),
 	}
 	}
-	srv.router = createRouter(srv)
+	srv.router = createRouter(ctx, srv)
 	return srv
 	return srv
 }
 }
 
 
@@ -290,7 +291,7 @@ func (s *Server) initTCPSocket(addr string) (l net.Listener, err error) {
 	return
 	return
 }
 }
 
 
-func (s *Server) makeHTTPHandler(localMethod string, localRoute string, localHandler HTTPAPIFunc) http.HandlerFunc {
+func (s *Server) makeHTTPHandler(ctx context.Context, localMethod string, localRoute string, localHandler HTTPAPIFunc) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 	return func(w http.ResponseWriter, r *http.Request) {
 		// log the handler generation
 		// log the handler generation
 		logrus.Debugf("Calling %s %s", localMethod, localRoute)
 		logrus.Debugf("Calling %s %s", localMethod, localRoute)
@@ -302,7 +303,8 @@ func (s *Server) makeHTTPHandler(localMethod string, localRoute string, localHan
 		// apply to all requests. Data that is specific to the
 		// apply to all requests. Data that is specific to the
 		// immediate function being called should still be passed
 		// immediate function being called should still be passed
 		// as 'args' on the function call.
 		// as 'args' on the function call.
-		ctx := context.Background()
+		reqID := stringid.TruncateID(stringid.GenerateNonCryptoID())
+		ctx = context.WithValue(ctx, context.RequestID, reqID)
 		handlerFunc := s.handleWithGlobalMiddlewares(localHandler)
 		handlerFunc := s.handleWithGlobalMiddlewares(localHandler)
 
 
 		if err := handlerFunc(ctx, w, r, mux.Vars(r)); err != nil {
 		if err := handlerFunc(ctx, w, r, mux.Vars(r)); err != nil {
@@ -314,7 +316,7 @@ func (s *Server) makeHTTPHandler(localMethod string, localRoute string, localHan
 
 
 // createRouter initializes the main router the server uses.
 // createRouter initializes the main router the server uses.
 // we keep enableCors just for legacy usage, need to be removed in the future
 // we keep enableCors just for legacy usage, need to be removed in the future
-func createRouter(s *Server) *mux.Router {
+func createRouter(ctx context.Context, s *Server) *mux.Router {
 	r := mux.NewRouter()
 	r := mux.NewRouter()
 	if os.Getenv("DEBUG") != "" {
 	if os.Getenv("DEBUG") != "" {
 		profilerSetup(r, "/debug/")
 		profilerSetup(r, "/debug/")
@@ -394,7 +396,7 @@ func createRouter(s *Server) *mux.Router {
 			localMethod := method
 			localMethod := method
 
 
 			// build the handler function
 			// build the handler function
-			f := s.makeHTTPHandler(localMethod, localRoute, localFct)
+			f := s.makeHTTPHandler(ctx, localMethod, localRoute, localFct)
 
 
 			// add the new route
 			// add the new route
 			if localRoute == "" {
 			if localRoute == "" {

+ 6 - 2
api/server/server_experimental_unix.go

@@ -2,8 +2,12 @@
 
 
 package server
 package server
 
 
-func (s *Server) registerSubRouter() {
-	httpHandler := s.daemon.NetworkAPIRouter()
+import (
+	"github.com/docker/docker/context"
+)
+
+func (s *Server) registerSubRouter(ctx context.Context) {
+	httpHandler := s.daemon.NetworkAPIRouter(ctx)
 
 
 	subrouter := s.router.PathPrefix("/v{version:[0-9.]+}/networks").Subrouter()
 	subrouter := s.router.PathPrefix("/v{version:[0-9.]+}/networks").Subrouter()
 	subrouter.Methods("GET", "POST", "PUT", "DELETE").HandlerFunc(httpHandler)
 	subrouter.Methods("GET", "POST", "PUT", "DELETE").HandlerFunc(httpHandler)

+ 5 - 1
api/server/server_stub.go

@@ -2,5 +2,9 @@
 
 
 package server
 package server
 
 
-func (s *Server) registerSubRouter() {
+import (
+	"github.com/docker/docker/context"
+)
+
+func (s *Server) registerSubRouter(ctx context.Context) {
 }
 }

+ 3 - 2
api/server/server_unix.go

@@ -8,6 +8,7 @@ import (
 	"net/http"
 	"net/http"
 	"strconv"
 	"strconv"
 
 
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/pkg/sockets"
 	"github.com/docker/docker/pkg/sockets"
 	"github.com/docker/libnetwork/portallocator"
 	"github.com/docker/libnetwork/portallocator"
@@ -63,10 +64,10 @@ func (s *Server) newServer(proto, addr string) ([]serverCloser, error) {
 // AcceptConnections allows clients to connect to the API server.
 // AcceptConnections allows clients to connect to the API server.
 // Referenced Daemon is notified about this server, and waits for the
 // Referenced Daemon is notified about this server, and waits for the
 // daemon acknowledgement before the incoming connections are accepted.
 // daemon acknowledgement before the incoming connections are accepted.
-func (s *Server) AcceptConnections(d *daemon.Daemon) {
+func (s *Server) AcceptConnections(ctx context.Context, d *daemon.Daemon) {
 	// Tell the init daemon we are accepting requests
 	// Tell the init daemon we are accepting requests
 	s.daemon = d
 	s.daemon = d
-	s.registerSubRouter()
+	s.registerSubRouter(ctx)
 	go systemdDaemon.SdNotify("READY=1")
 	go systemdDaemon.SdNotify("READY=1")
 	// close the lock so the listeners start accepting connections
 	// close the lock so the listeners start accepting connections
 	select {
 	select {

+ 3 - 2
api/server/server_windows.go

@@ -7,6 +7,7 @@ import (
 	"net"
 	"net"
 	"net/http"
 	"net/http"
 
 
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/daemon"
 )
 )
 
 
@@ -42,9 +43,9 @@ func (s *Server) newServer(proto, addr string) ([]serverCloser, error) {
 }
 }
 
 
 // AcceptConnections allows router to start listening for the incoming requests.
 // AcceptConnections allows router to start listening for the incoming requests.
-func (s *Server) AcceptConnections(d *daemon.Daemon) {
+func (s *Server) AcceptConnections(ctx context.Context, d *daemon.Daemon) {
 	s.daemon = d
 	s.daemon = d
-	s.registerSubRouter()
+	s.registerSubRouter(ctx)
 	// close the lock so the listeners start accepting connections
 	// close the lock so the listeners start accepting connections
 	select {
 	select {
 	case <-s.start:
 	case <-s.start:

+ 4 - 4
api/server/volume.go

@@ -13,7 +13,7 @@ func (s *Server) getVolumesList(ctx context.Context, w http.ResponseWriter, r *h
 		return err
 		return err
 	}
 	}
 
 
-	volumes, err := s.daemon.Volumes(r.Form.Get("filters"))
+	volumes, err := s.daemon.Volumes(ctx, r.Form.Get("filters"))
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -25,7 +25,7 @@ func (s *Server) getVolumeByName(ctx context.Context, w http.ResponseWriter, r *
 		return err
 		return err
 	}
 	}
 
 
-	v, err := s.daemon.VolumeInspect(vars["name"])
+	v, err := s.daemon.VolumeInspect(ctx, vars["name"])
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -46,7 +46,7 @@ func (s *Server) postVolumesCreate(ctx context.Context, w http.ResponseWriter, r
 		return err
 		return err
 	}
 	}
 
 
-	volume, err := s.daemon.VolumeCreate(req.Name, req.Driver, req.DriverOpts)
+	volume, err := s.daemon.VolumeCreate(ctx, req.Name, req.Driver, req.DriverOpts)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -57,7 +57,7 @@ func (s *Server) deleteVolumes(ctx context.Context, w http.ResponseWriter, r *ht
 	if err := parseForm(r); err != nil {
 	if err := parseForm(r); err != nil {
 		return err
 		return err
 	}
 	}
-	if err := s.daemon.VolumeRm(vars["name"]); err != nil {
+	if err := s.daemon.VolumeRm(ctx, vars["name"]); err != nil {
 		return err
 		return err
 	}
 	}
 	w.WriteHeader(http.StatusNoContent)
 	w.WriteHeader(http.StatusNoContent)

+ 42 - 41
builder/dispatchers.go

@@ -18,6 +18,7 @@ import (
 	"strings"
 	"strings"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
+	"github.com/docker/docker/context"
 	derr "github.com/docker/docker/errors"
 	derr "github.com/docker/docker/errors"
 	flag "github.com/docker/docker/pkg/mflag"
 	flag "github.com/docker/docker/pkg/mflag"
 	"github.com/docker/docker/pkg/nat"
 	"github.com/docker/docker/pkg/nat"
@@ -43,7 +44,7 @@ func nullDispatch(b *builder, args []string, attributes map[string]bool, origina
 // Sets the environment variable foo to bar, also makes interpolation
 // Sets the environment variable foo to bar, also makes interpolation
 // in the dockerfile available from the next statement on via ${foo}.
 // in the dockerfile available from the next statement on via ${foo}.
 //
 //
-func env(b *builder, args []string, attributes map[string]bool, original string) error {
+func env(ctx context.Context, b *builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) == 0 {
 	if len(args) == 0 {
 		return derr.ErrorCodeAtLeastOneArg.WithArgs("ENV")
 		return derr.ErrorCodeAtLeastOneArg.WithArgs("ENV")
 	}
 	}
@@ -96,13 +97,13 @@ func env(b *builder, args []string, attributes map[string]bool, original string)
 		j++
 		j++
 	}
 	}
 
 
-	return b.commit("", b.Config.Cmd, commitStr)
+	return b.commit(ctx, "", b.Config.Cmd, commitStr)
 }
 }
 
 
 // MAINTAINER some text <maybe@an.email.address>
 // MAINTAINER some text <maybe@an.email.address>
 //
 //
 // Sets the maintainer metadata.
 // Sets the maintainer metadata.
-func maintainer(b *builder, args []string, attributes map[string]bool, original string) error {
+func maintainer(ctx context.Context, b *builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) != 1 {
 	if len(args) != 1 {
 		return derr.ErrorCodeExactlyOneArg.WithArgs("MAINTAINER")
 		return derr.ErrorCodeExactlyOneArg.WithArgs("MAINTAINER")
 	}
 	}
@@ -112,14 +113,14 @@ func maintainer(b *builder, args []string, attributes map[string]bool, original
 	}
 	}
 
 
 	b.maintainer = args[0]
 	b.maintainer = args[0]
-	return b.commit("", b.Config.Cmd, fmt.Sprintf("MAINTAINER %s", b.maintainer))
+	return b.commit(ctx, "", b.Config.Cmd, fmt.Sprintf("MAINTAINER %s", b.maintainer))
 }
 }
 
 
 // LABEL some json data describing the image
 // LABEL some json data describing the image
 //
 //
 // Sets the Label variable foo to bar,
 // Sets the Label variable foo to bar,
 //
 //
-func label(b *builder, args []string, attributes map[string]bool, original string) error {
+func label(ctx context.Context, b *builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) == 0 {
 	if len(args) == 0 {
 		return derr.ErrorCodeAtLeastOneArg.WithArgs("LABEL")
 		return derr.ErrorCodeAtLeastOneArg.WithArgs("LABEL")
 	}
 	}
@@ -147,7 +148,7 @@ func label(b *builder, args []string, attributes map[string]bool, original strin
 		b.Config.Labels[args[j]] = args[j+1]
 		b.Config.Labels[args[j]] = args[j+1]
 		j++
 		j++
 	}
 	}
-	return b.commit("", b.Config.Cmd, commitStr)
+	return b.commit(ctx, "", b.Config.Cmd, commitStr)
 }
 }
 
 
 // ADD foo /path
 // ADD foo /path
@@ -155,7 +156,7 @@ func label(b *builder, args []string, attributes map[string]bool, original strin
 // Add the file 'foo' to '/path'. Tarball and Remote URL (git, http) handling
 // Add the file 'foo' to '/path'. Tarball and Remote URL (git, http) handling
 // exist here. If you do not wish to have this automatic handling, use COPY.
 // exist here. If you do not wish to have this automatic handling, use COPY.
 //
 //
-func add(b *builder, args []string, attributes map[string]bool, original string) error {
+func add(ctx context.Context, b *builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) < 2 {
 	if len(args) < 2 {
 		return derr.ErrorCodeAtLeastTwoArgs.WithArgs("ADD")
 		return derr.ErrorCodeAtLeastTwoArgs.WithArgs("ADD")
 	}
 	}
@@ -164,14 +165,14 @@ func add(b *builder, args []string, attributes map[string]bool, original string)
 		return err
 		return err
 	}
 	}
 
 
-	return b.runContextCommand(args, true, true, "ADD")
+	return b.runContextCommand(ctx, args, true, true, "ADD")
 }
 }
 
 
 // COPY foo /path
 // COPY foo /path
 //
 //
 // Same as 'ADD' but without the tar and remote url handling.
 // Same as 'ADD' but without the tar and remote url handling.
 //
 //
-func dispatchCopy(b *builder, args []string, attributes map[string]bool, original string) error {
+func dispatchCopy(ctx context.Context, b *builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) < 2 {
 	if len(args) < 2 {
 		return derr.ErrorCodeAtLeastTwoArgs.WithArgs("COPY")
 		return derr.ErrorCodeAtLeastTwoArgs.WithArgs("COPY")
 	}
 	}
@@ -180,14 +181,14 @@ func dispatchCopy(b *builder, args []string, attributes map[string]bool, origina
 		return err
 		return err
 	}
 	}
 
 
-	return b.runContextCommand(args, false, false, "COPY")
+	return b.runContextCommand(ctx, args, false, false, "COPY")
 }
 }
 
 
 // FROM imagename
 // FROM imagename
 //
 //
 // This sets the image the dockerfile will build on top of.
 // This sets the image the dockerfile will build on top of.
 //
 //
-func from(b *builder, args []string, attributes map[string]bool, original string) error {
+func from(ctx context.Context, b *builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) != 1 {
 	if len(args) != 1 {
 		return derr.ErrorCodeExactlyOneArg.WithArgs("FROM")
 		return derr.ErrorCodeExactlyOneArg.WithArgs("FROM")
 	}
 	}
@@ -208,16 +209,16 @@ func from(b *builder, args []string, attributes map[string]bool, original string
 		return nil
 		return nil
 	}
 	}
 
 
-	image, err := b.Daemon.Repositories().LookupImage(name)
+	image, err := b.Daemon.Repositories(ctx).LookupImage(name)
 	if b.Pull {
 	if b.Pull {
-		image, err = b.pullImage(name)
+		image, err = b.pullImage(ctx, name)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}
 	if err != nil {
 	if err != nil {
-		if b.Daemon.Graph().IsNotExist(err, name) {
-			image, err = b.pullImage(name)
+		if b.Daemon.Graph(ctx).IsNotExist(err, name) {
+			image, err = b.pullImage(ctx, name)
 		}
 		}
 
 
 		// note that the top level err will still be !nil here if IsNotExist is
 		// note that the top level err will still be !nil here if IsNotExist is
@@ -227,7 +228,7 @@ func from(b *builder, args []string, attributes map[string]bool, original string
 		}
 		}
 	}
 	}
 
 
-	return b.processImageFrom(image)
+	return b.processImageFrom(ctx, image)
 }
 }
 
 
 // ONBUILD RUN echo yo
 // ONBUILD RUN echo yo
@@ -239,7 +240,7 @@ func from(b *builder, args []string, attributes map[string]bool, original string
 // special cases. search for 'OnBuild' in internals.go for additional special
 // special cases. search for 'OnBuild' in internals.go for additional special
 // cases.
 // cases.
 //
 //
-func onbuild(b *builder, args []string, attributes map[string]bool, original string) error {
+func onbuild(ctx context.Context, b *builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) == 0 {
 	if len(args) == 0 {
 		return derr.ErrorCodeAtLeastOneArg.WithArgs("ONBUILD")
 		return derr.ErrorCodeAtLeastOneArg.WithArgs("ONBUILD")
 	}
 	}
@@ -259,14 +260,14 @@ func onbuild(b *builder, args []string, attributes map[string]bool, original str
 	original = regexp.MustCompile(`(?i)^\s*ONBUILD\s*`).ReplaceAllString(original, "")
 	original = regexp.MustCompile(`(?i)^\s*ONBUILD\s*`).ReplaceAllString(original, "")
 
 
 	b.Config.OnBuild = append(b.Config.OnBuild, original)
 	b.Config.OnBuild = append(b.Config.OnBuild, original)
-	return b.commit("", b.Config.Cmd, fmt.Sprintf("ONBUILD %s", original))
+	return b.commit(ctx, "", b.Config.Cmd, fmt.Sprintf("ONBUILD %s", original))
 }
 }
 
 
 // WORKDIR /tmp
 // WORKDIR /tmp
 //
 //
 // Set the working directory for future RUN/CMD/etc statements.
 // Set the working directory for future RUN/CMD/etc statements.
 //
 //
-func workdir(b *builder, args []string, attributes map[string]bool, original string) error {
+func workdir(ctx context.Context, b *builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) != 1 {
 	if len(args) != 1 {
 		return derr.ErrorCodeExactlyOneArg.WithArgs("WORKDIR")
 		return derr.ErrorCodeExactlyOneArg.WithArgs("WORKDIR")
 	}
 	}
@@ -286,7 +287,7 @@ func workdir(b *builder, args []string, attributes map[string]bool, original str
 
 
 	b.Config.WorkingDir = workdir
 	b.Config.WorkingDir = workdir
 
 
-	return b.commit("", b.Config.Cmd, fmt.Sprintf("WORKDIR %v", workdir))
+	return b.commit(ctx, "", b.Config.Cmd, fmt.Sprintf("WORKDIR %v", workdir))
 }
 }
 
 
 // RUN some command yo
 // RUN some command yo
@@ -299,7 +300,7 @@ func workdir(b *builder, args []string, attributes map[string]bool, original str
 // RUN echo hi          # cmd /S /C echo hi   (Windows)
 // RUN echo hi          # cmd /S /C echo hi   (Windows)
 // RUN [ "echo", "hi" ] # echo hi
 // RUN [ "echo", "hi" ] # echo hi
 //
 //
-func run(b *builder, args []string, attributes map[string]bool, original string) error {
+func run(ctx context.Context, b *builder, args []string, attributes map[string]bool, original string) error {
 	if b.image == "" && !b.noBaseImage {
 	if b.image == "" && !b.noBaseImage {
 		return derr.ErrorCodeMissingFrom
 		return derr.ErrorCodeMissingFrom
 	}
 	}
@@ -380,7 +381,7 @@ func run(b *builder, args []string, attributes map[string]bool, original string)
 	}
 	}
 
 
 	b.Config.Cmd = saveCmd
 	b.Config.Cmd = saveCmd
-	hit, err := b.probeCache()
+	hit, err := b.probeCache(ctx)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -395,17 +396,17 @@ func run(b *builder, args []string, attributes map[string]bool, original string)
 
 
 	logrus.Debugf("[BUILDER] Command to be executed: %v", b.Config.Cmd)
 	logrus.Debugf("[BUILDER] Command to be executed: %v", b.Config.Cmd)
 
 
-	c, err := b.create()
+	c, err := b.create(ctx)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
 	// Ensure that we keep the container mounted until the commit
 	// Ensure that we keep the container mounted until the commit
 	// to avoid unmounting and then mounting directly again
 	// to avoid unmounting and then mounting directly again
-	c.Mount()
-	defer c.Unmount()
+	c.Mount(ctx)
+	defer c.Unmount(ctx)
 
 
-	err = b.run(c)
+	err = b.run(ctx, c)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -415,7 +416,7 @@ func run(b *builder, args []string, attributes map[string]bool, original string)
 	// properly match it.
 	// properly match it.
 	b.Config.Env = env
 	b.Config.Env = env
 	b.Config.Cmd = saveCmd
 	b.Config.Cmd = saveCmd
-	if err := b.commit(c.ID, cmd, "run"); err != nil {
+	if err := b.commit(ctx, c.ID, cmd, "run"); err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -427,7 +428,7 @@ func run(b *builder, args []string, attributes map[string]bool, original string)
 // Set the default command to run in the container (which may be empty).
 // Set the default command to run in the container (which may be empty).
 // Argument handling is the same as RUN.
 // Argument handling is the same as RUN.
 //
 //
-func cmd(b *builder, args []string, attributes map[string]bool, original string) error {
+func cmd(ctx context.Context, b *builder, args []string, attributes map[string]bool, original string) error {
 	if err := b.BuilderFlags.Parse(); err != nil {
 	if err := b.BuilderFlags.Parse(); err != nil {
 		return err
 		return err
 	}
 	}
@@ -444,7 +445,7 @@ func cmd(b *builder, args []string, attributes map[string]bool, original string)
 
 
 	b.Config.Cmd = stringutils.NewStrSlice(cmdSlice...)
 	b.Config.Cmd = stringutils.NewStrSlice(cmdSlice...)
 
 
-	if err := b.commit("", b.Config.Cmd, fmt.Sprintf("CMD %q", cmdSlice)); err != nil {
+	if err := b.commit(ctx, "", b.Config.Cmd, fmt.Sprintf("CMD %q", cmdSlice)); err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -463,7 +464,7 @@ func cmd(b *builder, args []string, attributes map[string]bool, original string)
 // Handles command processing similar to CMD and RUN, only b.Config.Entrypoint
 // Handles command processing similar to CMD and RUN, only b.Config.Entrypoint
 // is initialized at NewBuilder time instead of through argument parsing.
 // is initialized at NewBuilder time instead of through argument parsing.
 //
 //
-func entrypoint(b *builder, args []string, attributes map[string]bool, original string) error {
+func entrypoint(ctx context.Context, b *builder, args []string, attributes map[string]bool, original string) error {
 	if err := b.BuilderFlags.Parse(); err != nil {
 	if err := b.BuilderFlags.Parse(); err != nil {
 		return err
 		return err
 	}
 	}
@@ -492,7 +493,7 @@ func entrypoint(b *builder, args []string, attributes map[string]bool, original
 		b.Config.Cmd = nil
 		b.Config.Cmd = nil
 	}
 	}
 
 
-	if err := b.commit("", b.Config.Cmd, fmt.Sprintf("ENTRYPOINT %q", b.Config.Entrypoint)); err != nil {
+	if err := b.commit(ctx, "", b.Config.Cmd, fmt.Sprintf("ENTRYPOINT %q", b.Config.Entrypoint)); err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -504,7 +505,7 @@ func entrypoint(b *builder, args []string, attributes map[string]bool, original
 // Expose ports for links and port mappings. This all ends up in
 // Expose ports for links and port mappings. This all ends up in
 // b.Config.ExposedPorts for runconfig.
 // b.Config.ExposedPorts for runconfig.
 //
 //
-func expose(b *builder, args []string, attributes map[string]bool, original string) error {
+func expose(ctx context.Context, b *builder, args []string, attributes map[string]bool, original string) error {
 	portsTab := args
 	portsTab := args
 
 
 	if len(args) == 0 {
 	if len(args) == 0 {
@@ -537,7 +538,7 @@ func expose(b *builder, args []string, attributes map[string]bool, original stri
 		i++
 		i++
 	}
 	}
 	sort.Strings(portList)
 	sort.Strings(portList)
-	return b.commit("", b.Config.Cmd, fmt.Sprintf("EXPOSE %s", strings.Join(portList, " ")))
+	return b.commit(ctx, "", b.Config.Cmd, fmt.Sprintf("EXPOSE %s", strings.Join(portList, " ")))
 }
 }
 
 
 // USER foo
 // USER foo
@@ -545,7 +546,7 @@ func expose(b *builder, args []string, attributes map[string]bool, original stri
 // Set the user to 'foo' for future commands and when running the
 // Set the user to 'foo' for future commands and when running the
 // ENTRYPOINT/CMD at container run time.
 // ENTRYPOINT/CMD at container run time.
 //
 //
-func user(b *builder, args []string, attributes map[string]bool, original string) error {
+func user(ctx context.Context, b *builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) != 1 {
 	if len(args) != 1 {
 		return derr.ErrorCodeExactlyOneArg.WithArgs("USER")
 		return derr.ErrorCodeExactlyOneArg.WithArgs("USER")
 	}
 	}
@@ -555,14 +556,14 @@ func user(b *builder, args []string, attributes map[string]bool, original string
 	}
 	}
 
 
 	b.Config.User = args[0]
 	b.Config.User = args[0]
-	return b.commit("", b.Config.Cmd, fmt.Sprintf("USER %v", args))
+	return b.commit(ctx, "", b.Config.Cmd, fmt.Sprintf("USER %v", args))
 }
 }
 
 
 // VOLUME /foo
 // VOLUME /foo
 //
 //
 // Expose the volume /foo for use. Will also accept the JSON array form.
 // Expose the volume /foo for use. Will also accept the JSON array form.
 //
 //
-func volume(b *builder, args []string, attributes map[string]bool, original string) error {
+func volume(ctx context.Context, b *builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) == 0 {
 	if len(args) == 0 {
 		return derr.ErrorCodeAtLeastOneArg.WithArgs("VOLUME")
 		return derr.ErrorCodeAtLeastOneArg.WithArgs("VOLUME")
 	}
 	}
@@ -581,7 +582,7 @@ func volume(b *builder, args []string, attributes map[string]bool, original stri
 		}
 		}
 		b.Config.Volumes[v] = struct{}{}
 		b.Config.Volumes[v] = struct{}{}
 	}
 	}
-	if err := b.commit("", b.Config.Cmd, fmt.Sprintf("VOLUME %v", args)); err != nil {
+	if err := b.commit(ctx, "", b.Config.Cmd, fmt.Sprintf("VOLUME %v", args)); err != nil {
 		return err
 		return err
 	}
 	}
 	return nil
 	return nil
@@ -590,7 +591,7 @@ func volume(b *builder, args []string, attributes map[string]bool, original stri
 // STOPSIGNAL signal
 // STOPSIGNAL signal
 //
 //
 // Set the signal that will be used to kill the container.
 // Set the signal that will be used to kill the container.
-func stopSignal(b *builder, args []string, attributes map[string]bool, original string) error {
+func stopSignal(ctx context.Context, b *builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) != 1 {
 	if len(args) != 1 {
 		return fmt.Errorf("STOPSIGNAL requires exactly one argument")
 		return fmt.Errorf("STOPSIGNAL requires exactly one argument")
 	}
 	}
@@ -602,7 +603,7 @@ func stopSignal(b *builder, args []string, attributes map[string]bool, original
 	}
 	}
 
 
 	b.Config.StopSignal = sig
 	b.Config.StopSignal = sig
-	return b.commit("", b.Config.Cmd, fmt.Sprintf("STOPSIGNAL %v", args))
+	return b.commit(ctx, "", b.Config.Cmd, fmt.Sprintf("STOPSIGNAL %v", args))
 }
 }
 
 
 // ARG name[=value]
 // ARG name[=value]
@@ -610,7 +611,7 @@ func stopSignal(b *builder, args []string, attributes map[string]bool, original
 // Adds the variable foo to the trusted list of variables that can be passed
 // Adds the variable foo to the trusted list of variables that can be passed
 // to builder using the --build-arg flag for expansion/subsitution or passing to 'run'.
 // to builder using the --build-arg flag for expansion/subsitution or passing to 'run'.
 // Dockerfile author may optionally set a default value of this variable.
 // Dockerfile author may optionally set a default value of this variable.
-func arg(b *builder, args []string, attributes map[string]bool, original string) error {
+func arg(ctx context.Context, b *builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) != 1 {
 	if len(args) != 1 {
 		return fmt.Errorf("ARG requires exactly one argument definition")
 		return fmt.Errorf("ARG requires exactly one argument definition")
 	}
 	}
@@ -646,5 +647,5 @@ func arg(b *builder, args []string, attributes map[string]bool, original string)
 		b.buildArgs[name] = value
 		b.buildArgs[name] = value
 	}
 	}
 
 
-	return b.commit("", b.Config.Cmd, fmt.Sprintf("ARG %s", arg))
+	return b.commit(ctx, "", b.Config.Cmd, fmt.Sprintf("ARG %s", arg))
 }
 }

+ 9 - 8
builder/evaluator.go

@@ -32,6 +32,7 @@ import (
 	"github.com/docker/docker/builder/command"
 	"github.com/docker/docker/builder/command"
 	"github.com/docker/docker/builder/parser"
 	"github.com/docker/docker/builder/parser"
 	"github.com/docker/docker/cliconfig"
 	"github.com/docker/docker/cliconfig"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/pkg/fileutils"
 	"github.com/docker/docker/pkg/fileutils"
 	"github.com/docker/docker/pkg/streamformatter"
 	"github.com/docker/docker/pkg/streamformatter"
@@ -57,10 +58,10 @@ var replaceEnvAllowed = map[string]struct{}{
 	command.Arg:        {},
 	command.Arg:        {},
 }
 }
 
 
-var evaluateTable map[string]func(*builder, []string, map[string]bool, string) error
+var evaluateTable map[string]func(context.Context, *builder, []string, map[string]bool, string) error
 
 
 func init() {
 func init() {
-	evaluateTable = map[string]func(*builder, []string, map[string]bool, string) error{
+	evaluateTable = map[string]func(context.Context, *builder, []string, map[string]bool, string) error{
 		command.Env:        env,
 		command.Env:        env,
 		command.Label:      label,
 		command.Label:      label,
 		command.Maintainer: maintainer,
 		command.Maintainer: maintainer,
@@ -158,7 +159,7 @@ type builder struct {
 //   processing.
 //   processing.
 // * Print a happy message and return the image ID.
 // * Print a happy message and return the image ID.
 //
 //
-func (b *builder) Run(context io.Reader) (string, error) {
+func (b *builder) Run(ctx context.Context, context io.Reader) (string, error) {
 	if err := b.readContext(context); err != nil {
 	if err := b.readContext(context); err != nil {
 		return "", err
 		return "", err
 	}
 	}
@@ -187,15 +188,15 @@ func (b *builder) Run(context io.Reader) (string, error) {
 		default:
 		default:
 			// Not cancelled yet, keep going...
 			// Not cancelled yet, keep going...
 		}
 		}
-		if err := b.dispatch(i, n); err != nil {
+		if err := b.dispatch(ctx, i, n); err != nil {
 			if b.ForceRemove {
 			if b.ForceRemove {
-				b.clearTmp()
+				b.clearTmp(ctx)
 			}
 			}
 			return "", err
 			return "", err
 		}
 		}
 		fmt.Fprintf(b.OutStream, " ---> %s\n", stringid.TruncateID(b.image))
 		fmt.Fprintf(b.OutStream, " ---> %s\n", stringid.TruncateID(b.image))
 		if b.Remove {
 		if b.Remove {
-			b.clearTmp()
+			b.clearTmp(ctx)
 		}
 		}
 	}
 	}
 
 
@@ -311,7 +312,7 @@ func (b *builder) isBuildArgAllowed(arg string) bool {
 // such as `RUN` in ONBUILD RUN foo. There is special case logic in here to
 // such as `RUN` in ONBUILD RUN foo. There is special case logic in here to
 // deal with that, at least until it becomes more of a general concern with new
 // deal with that, at least until it becomes more of a general concern with new
 // features.
 // features.
-func (b *builder) dispatch(stepN int, ast *parser.Node) error {
+func (b *builder) dispatch(ctx context.Context, stepN int, ast *parser.Node) error {
 	cmd := ast.Value
 	cmd := ast.Value
 
 
 	// To ensure the user is give a decent error message if the platform
 	// To ensure the user is give a decent error message if the platform
@@ -404,7 +405,7 @@ func (b *builder) dispatch(stepN int, ast *parser.Node) error {
 	if f, ok := evaluateTable[cmd]; ok {
 	if f, ok := evaluateTable[cmd]; ok {
 		b.BuilderFlags = NewBFlags()
 		b.BuilderFlags = NewBFlags()
 		b.BuilderFlags.Args = flags
 		b.BuilderFlags.Args = flags
-		return f(b, strList, attrs, original)
+		return f(ctx, b, strList, attrs, original)
 	}
 	}
 
 
 	return fmt.Errorf("Unknown instruction: %s", strings.ToUpper(cmd))
 	return fmt.Errorf("Unknown instruction: %s", strings.ToUpper(cmd))

+ 30 - 29
builder/internals.go

@@ -22,6 +22,7 @@ import (
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/builder/parser"
 	"github.com/docker/docker/builder/parser"
 	"github.com/docker/docker/cliconfig"
 	"github.com/docker/docker/cliconfig"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/graph"
 	"github.com/docker/docker/graph"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/image"
@@ -75,7 +76,7 @@ func (b *builder) readContext(context io.Reader) (err error) {
 	return
 	return
 }
 }
 
 
-func (b *builder) commit(id string, autoCmd *stringutils.StrSlice, comment string) error {
+func (b *builder) commit(ctx context.Context, id string, autoCmd *stringutils.StrSlice, comment string) error {
 	if b.disableCommit {
 	if b.disableCommit {
 		return nil
 		return nil
 	}
 	}
@@ -92,7 +93,7 @@ func (b *builder) commit(id string, autoCmd *stringutils.StrSlice, comment strin
 		}
 		}
 		defer func(cmd *stringutils.StrSlice) { b.Config.Cmd = cmd }(cmd)
 		defer func(cmd *stringutils.StrSlice) { b.Config.Cmd = cmd }(cmd)
 
 
-		hit, err := b.probeCache()
+		hit, err := b.probeCache(ctx)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
@@ -100,18 +101,18 @@ func (b *builder) commit(id string, autoCmd *stringutils.StrSlice, comment strin
 			return nil
 			return nil
 		}
 		}
 
 
-		container, err := b.create()
+		container, err := b.create(ctx)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
 		id = container.ID
 		id = container.ID
 
 
-		if err := container.Mount(); err != nil {
+		if err := container.Mount(ctx); err != nil {
 			return err
 			return err
 		}
 		}
-		defer container.Unmount()
+		defer container.Unmount(ctx)
 	}
 	}
-	container, err := b.Daemon.Get(id)
+	container, err := b.Daemon.Get(ctx, id)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -127,11 +128,11 @@ func (b *builder) commit(id string, autoCmd *stringutils.StrSlice, comment strin
 	}
 	}
 
 
 	// Commit the container
 	// Commit the container
-	image, err := b.Daemon.Commit(container, commitCfg)
+	image, err := b.Daemon.Commit(ctx, container, commitCfg)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	b.Daemon.Graph().Retain(b.id, image.ID)
+	b.Daemon.Graph(ctx).Retain(b.id, image.ID)
 	b.activeImages = append(b.activeImages, image.ID)
 	b.activeImages = append(b.activeImages, image.ID)
 	b.image = image.ID
 	b.image = image.ID
 	return nil
 	return nil
@@ -145,7 +146,7 @@ type copyInfo struct {
 	tmpDir     string
 	tmpDir     string
 }
 }
 
 
-func (b *builder) runContextCommand(args []string, allowRemote bool, allowDecompression bool, cmdName string) error {
+func (b *builder) runContextCommand(ctx context.Context, args []string, allowRemote bool, allowDecompression bool, cmdName string) error {
 	if b.context == nil {
 	if b.context == nil {
 		return fmt.Errorf("No context given. Impossible to use %s", cmdName)
 		return fmt.Errorf("No context given. Impossible to use %s", cmdName)
 	}
 	}
@@ -223,7 +224,7 @@ func (b *builder) runContextCommand(args []string, allowRemote bool, allowDecomp
 	}
 	}
 	defer func(cmd *stringutils.StrSlice) { b.Config.Cmd = cmd }(cmd)
 	defer func(cmd *stringutils.StrSlice) { b.Config.Cmd = cmd }(cmd)
 
 
-	hit, err := b.probeCache()
+	hit, err := b.probeCache(ctx)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -232,16 +233,16 @@ func (b *builder) runContextCommand(args []string, allowRemote bool, allowDecomp
 		return nil
 		return nil
 	}
 	}
 
 
-	container, _, err := b.Daemon.ContainerCreate("", b.Config, nil, true)
+	container, _, err := b.Daemon.ContainerCreate(ctx, "", b.Config, nil, true)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 	b.TmpContainers[container.ID] = struct{}{}
 	b.TmpContainers[container.ID] = struct{}{}
 
 
-	if err := container.Mount(); err != nil {
+	if err := container.Mount(ctx); err != nil {
 		return err
 		return err
 	}
 	}
-	defer container.Unmount()
+	defer container.Unmount(ctx)
 
 
 	for _, ci := range copyInfos {
 	for _, ci := range copyInfos {
 		if err := b.addContext(container, ci.origPath, ci.destPath, ci.decompress); err != nil {
 		if err := b.addContext(container, ci.origPath, ci.destPath, ci.decompress); err != nil {
@@ -249,7 +250,7 @@ func (b *builder) runContextCommand(args []string, allowRemote bool, allowDecomp
 		}
 		}
 	}
 	}
 
 
-	if err := b.commit(container.ID, cmd, fmt.Sprintf("%s %s in %s", cmdName, origPaths, dest)); err != nil {
+	if err := b.commit(ctx, container.ID, cmd, fmt.Sprintf("%s %s in %s", cmdName, origPaths, dest)); err != nil {
 		return err
 		return err
 	}
 	}
 	return nil
 	return nil
@@ -484,7 +485,7 @@ func containsWildcards(name string) bool {
 	return false
 	return false
 }
 }
 
 
-func (b *builder) pullImage(name string) (*image.Image, error) {
+func (b *builder) pullImage(ctx context.Context, name string) (*image.Image, error) {
 	remote, tag := parsers.ParseRepositoryTag(name)
 	remote, tag := parsers.ParseRepositoryTag(name)
 	if tag == "" {
 	if tag == "" {
 		tag = "latest"
 		tag = "latest"
@@ -510,11 +511,11 @@ func (b *builder) pullImage(name string) (*image.Image, error) {
 		OutStream:  ioutils.NopWriteCloser(b.OutOld),
 		OutStream:  ioutils.NopWriteCloser(b.OutOld),
 	}
 	}
 
 
-	if err := b.Daemon.Repositories().Pull(remote, tag, imagePullConfig); err != nil {
+	if err := b.Daemon.Repositories(ctx).Pull(ctx, remote, tag, imagePullConfig); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	image, err := b.Daemon.Repositories().LookupImage(name)
+	image, err := b.Daemon.Repositories(ctx).LookupImage(name)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -522,7 +523,7 @@ func (b *builder) pullImage(name string) (*image.Image, error) {
 	return image, nil
 	return image, nil
 }
 }
 
 
-func (b *builder) processImageFrom(img *image.Image) error {
+func (b *builder) processImageFrom(ctx context.Context, img *image.Image) error {
 	b.image = img.ID
 	b.image = img.ID
 
 
 	if img.Config != nil {
 	if img.Config != nil {
@@ -562,7 +563,7 @@ func (b *builder) processImageFrom(img *image.Image) error {
 				return fmt.Errorf("%s isn't allowed as an ONBUILD trigger", n.Value)
 				return fmt.Errorf("%s isn't allowed as an ONBUILD trigger", n.Value)
 			}
 			}
 
 
-			if err := b.dispatch(i, n); err != nil {
+			if err := b.dispatch(ctx, i, n); err != nil {
 				return err
 				return err
 			}
 			}
 		}
 		}
@@ -576,12 +577,12 @@ func (b *builder) processImageFrom(img *image.Image) error {
 // in the current server `b.Daemon`. If an image is found, probeCache returns
 // in the current server `b.Daemon`. If an image is found, probeCache returns
 // `(true, nil)`. If no image is found, it returns `(false, nil)`. If there
 // `(true, nil)`. If no image is found, it returns `(false, nil)`. If there
 // is any error, it returns `(false, err)`.
 // is any error, it returns `(false, err)`.
-func (b *builder) probeCache() (bool, error) {
+func (b *builder) probeCache(ctx context.Context) (bool, error) {
 	if !b.UtilizeCache || b.cacheBusted {
 	if !b.UtilizeCache || b.cacheBusted {
 		return false, nil
 		return false, nil
 	}
 	}
 
 
-	cache, err := b.Daemon.ImageGetCached(b.image, b.Config)
+	cache, err := b.Daemon.ImageGetCached(ctx, b.image, b.Config)
 	if err != nil {
 	if err != nil {
 		return false, err
 		return false, err
 	}
 	}
@@ -594,12 +595,12 @@ func (b *builder) probeCache() (bool, error) {
 	fmt.Fprintf(b.OutStream, " ---> Using cache\n")
 	fmt.Fprintf(b.OutStream, " ---> Using cache\n")
 	logrus.Debugf("[BUILDER] Use cached version")
 	logrus.Debugf("[BUILDER] Use cached version")
 	b.image = cache.ID
 	b.image = cache.ID
-	b.Daemon.Graph().Retain(b.id, cache.ID)
+	b.Daemon.Graph(ctx).Retain(b.id, cache.ID)
 	b.activeImages = append(b.activeImages, cache.ID)
 	b.activeImages = append(b.activeImages, cache.ID)
 	return true, nil
 	return true, nil
 }
 }
 
 
-func (b *builder) create() (*daemon.Container, error) {
+func (b *builder) create(ctx context.Context) (*daemon.Container, error) {
 	if b.image == "" && !b.noBaseImage {
 	if b.image == "" && !b.noBaseImage {
 		return nil, fmt.Errorf("Please provide a source image with `from` prior to run")
 		return nil, fmt.Errorf("Please provide a source image with `from` prior to run")
 	}
 	}
@@ -620,7 +621,7 @@ func (b *builder) create() (*daemon.Container, error) {
 	config := *b.Config
 	config := *b.Config
 
 
 	// Create the container
 	// Create the container
-	c, warnings, err := b.Daemon.ContainerCreate("", b.Config, hostConfig, true)
+	c, warnings, err := b.Daemon.ContainerCreate(ctx, "", b.Config, hostConfig, true)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -643,14 +644,14 @@ func (b *builder) create() (*daemon.Container, error) {
 	return c, nil
 	return c, nil
 }
 }
 
 
-func (b *builder) run(c *daemon.Container) error {
+func (b *builder) run(ctx context.Context, c *daemon.Container) error {
 	var errCh chan error
 	var errCh chan error
 	if b.Verbose {
 	if b.Verbose {
 		errCh = c.Attach(nil, b.OutStream, b.ErrStream)
 		errCh = c.Attach(nil, b.OutStream, b.ErrStream)
 	}
 	}
 
 
 	//start the container
 	//start the container
-	if err := c.Start(); err != nil {
+	if err := c.Start(ctx); err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -660,7 +661,7 @@ func (b *builder) run(c *daemon.Container) error {
 		select {
 		select {
 		case <-b.cancelled:
 		case <-b.cancelled:
 			logrus.Debugln("Build cancelled, killing container:", c.ID)
 			logrus.Debugln("Build cancelled, killing container:", c.ID)
-			c.Kill()
+			c.Kill(ctx)
 		case <-finished:
 		case <-finished:
 		}
 		}
 	}()
 	}()
@@ -791,13 +792,13 @@ func copyAsDirectory(source, destination string, destExisted bool) error {
 	return fixPermissions(source, destination, 0, 0, destExisted)
 	return fixPermissions(source, destination, 0, 0, destExisted)
 }
 }
 
 
-func (b *builder) clearTmp() {
+func (b *builder) clearTmp(ctx context.Context) {
 	for c := range b.TmpContainers {
 	for c := range b.TmpContainers {
 		rmConfig := &daemon.ContainerRmConfig{
 		rmConfig := &daemon.ContainerRmConfig{
 			ForceRemove:  true,
 			ForceRemove:  true,
 			RemoveVolume: true,
 			RemoveVolume: true,
 		}
 		}
-		if err := b.Daemon.ContainerRm(c, rmConfig); err != nil {
+		if err := b.Daemon.ContainerRm(ctx, c, rmConfig); err != nil {
 			fmt.Fprintf(b.OutStream, "Error removing intermediate container %s: %v\n", stringid.TruncateID(c), err)
 			fmt.Fprintf(b.OutStream, "Error removing intermediate container %s: %v\n", stringid.TruncateID(c), err)
 			return
 			return
 		}
 		}

+ 11 - 10
builder/job.go

@@ -14,6 +14,7 @@ import (
 	"github.com/docker/docker/api"
 	"github.com/docker/docker/api"
 	"github.com/docker/docker/builder/parser"
 	"github.com/docker/docker/builder/parser"
 	"github.com/docker/docker/cliconfig"
 	"github.com/docker/docker/cliconfig"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/graph/tags"
 	"github.com/docker/docker/graph/tags"
 	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/archive"
@@ -112,7 +113,7 @@ func NewBuildConfig() *Config {
 
 
 // Build is the main interface of the package, it gathers the Builder
 // Build is the main interface of the package, it gathers the Builder
 // struct and calls builder.Run() to do all the real build job.
 // struct and calls builder.Run() to do all the real build job.
-func Build(d *daemon.Daemon, buildConfig *Config) error {
+func Build(ctx context.Context, d *daemon.Daemon, buildConfig *Config) error {
 	var (
 	var (
 		repoName string
 		repoName string
 		tag      string
 		tag      string
@@ -229,15 +230,15 @@ func Build(d *daemon.Daemon, buildConfig *Config) error {
 	}
 	}
 
 
 	defer func() {
 	defer func() {
-		builder.Daemon.Graph().Release(builder.id, builder.activeImages...)
+		builder.Daemon.Graph(ctx).Release(builder.id, builder.activeImages...)
 	}()
 	}()
 
 
-	id, err := builder.Run(context)
+	id, err := builder.Run(ctx, context)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 	if repoName != "" {
 	if repoName != "" {
-		return d.Repositories().Tag(repoName, tag, id, true)
+		return d.Repositories(ctx).Tag(repoName, tag, id, true)
 	}
 	}
 	return nil
 	return nil
 }
 }
@@ -247,7 +248,7 @@ func Build(d *daemon.Daemon, buildConfig *Config) error {
 //
 //
 // - call parse.Parse() to get AST root from Dockerfile entries
 // - call parse.Parse() to get AST root from Dockerfile entries
 // - do build by calling builder.dispatch() to call all entries' handling routines
 // - do build by calling builder.dispatch() to call all entries' handling routines
-func BuildFromConfig(d *daemon.Daemon, c *runconfig.Config, changes []string) (*runconfig.Config, error) {
+func BuildFromConfig(ctx context.Context, d *daemon.Daemon, c *runconfig.Config, changes []string) (*runconfig.Config, error) {
 	ast, err := parser.Parse(bytes.NewBufferString(strings.Join(changes, "\n")))
 	ast, err := parser.Parse(bytes.NewBufferString(strings.Join(changes, "\n")))
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -269,7 +270,7 @@ func BuildFromConfig(d *daemon.Daemon, c *runconfig.Config, changes []string) (*
 	}
 	}
 
 
 	for i, n := range ast.Children {
 	for i, n := range ast.Children {
-		if err := builder.dispatch(i, n); err != nil {
+		if err := builder.dispatch(ctx, i, n); err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
 	}
 	}
@@ -289,8 +290,8 @@ type CommitConfig struct {
 }
 }
 
 
 // Commit will create a new image from a container's changes
 // Commit will create a new image from a container's changes
-func Commit(name string, d *daemon.Daemon, c *CommitConfig) (string, error) {
-	container, err := d.Get(name)
+func Commit(ctx context.Context, name string, d *daemon.Daemon, c *CommitConfig) (string, error) {
+	container, err := d.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return "", err
 		return "", err
 	}
 	}
@@ -304,7 +305,7 @@ func Commit(name string, d *daemon.Daemon, c *CommitConfig) (string, error) {
 		c.Config = &runconfig.Config{}
 		c.Config = &runconfig.Config{}
 	}
 	}
 
 
-	newConfig, err := BuildFromConfig(d, c.Config, c.Changes)
+	newConfig, err := BuildFromConfig(ctx, d, c.Config, c.Changes)
 	if err != nil {
 	if err != nil {
 		return "", err
 		return "", err
 	}
 	}
@@ -322,7 +323,7 @@ func Commit(name string, d *daemon.Daemon, c *CommitConfig) (string, error) {
 		Config:  newConfig,
 		Config:  newConfig,
 	}
 	}
 
 
-	img, err := d.Commit(container, commitCfg)
+	img, err := d.Commit(ctx, container, commitCfg)
 	if err != nil {
 	if err != nil {
 		return "", err
 		return "", err
 	}
 	}

+ 25 - 24
daemon/archive.go

@@ -8,6 +8,7 @@ import (
 	"strings"
 	"strings"
 
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/chrootarchive"
 	"github.com/docker/docker/pkg/chrootarchive"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/ioutils"
@@ -20,8 +21,8 @@ var ErrExtractPointNotDirectory = errors.New("extraction point is not a director
 
 
 // ContainerCopy performs a deprecated operation of archiving the resource at
 // ContainerCopy performs a deprecated operation of archiving the resource at
 // the specified path in the conatiner identified by the given name.
 // the specified path in the conatiner identified by the given name.
-func (daemon *Daemon) ContainerCopy(name string, res string) (io.ReadCloser, error) {
-	container, err := daemon.Get(name)
+func (daemon *Daemon) ContainerCopy(ctx context.Context, name string, res string) (io.ReadCloser, error) {
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -30,30 +31,30 @@ func (daemon *Daemon) ContainerCopy(name string, res string) (io.ReadCloser, err
 		res = res[1:]
 		res = res[1:]
 	}
 	}
 
 
-	return container.copy(res)
+	return container.copy(ctx, res)
 }
 }
 
 
 // ContainerStatPath stats the filesystem resource at the specified path in the
 // ContainerStatPath stats the filesystem resource at the specified path in the
 // container identified by the given name.
 // container identified by the given name.
-func (daemon *Daemon) ContainerStatPath(name string, path string) (stat *types.ContainerPathStat, err error) {
-	container, err := daemon.Get(name)
+func (daemon *Daemon) ContainerStatPath(ctx context.Context, name string, path string) (stat *types.ContainerPathStat, err error) {
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	return container.StatPath(path)
+	return container.StatPath(ctx, path)
 }
 }
 
 
 // ContainerArchivePath creates an archive of the filesystem resource at the
 // ContainerArchivePath creates an archive of the filesystem resource at the
 // specified path in the container identified by the given name. Returns a
 // specified path in the container identified by the given name. Returns a
 // tar archive of the resource and whether it was a directory or a single file.
 // tar archive of the resource and whether it was a directory or a single file.
-func (daemon *Daemon) ContainerArchivePath(name string, path string) (content io.ReadCloser, stat *types.ContainerPathStat, err error) {
-	container, err := daemon.Get(name)
+func (daemon *Daemon) ContainerArchivePath(ctx context.Context, name string, path string) (content io.ReadCloser, stat *types.ContainerPathStat, err error) {
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return nil, nil, err
 		return nil, nil, err
 	}
 	}
 
 
-	return container.ArchivePath(path)
+	return container.ArchivePath(ctx, path)
 }
 }
 
 
 // ContainerExtractToDir extracts the given archive to the specified location
 // ContainerExtractToDir extracts the given archive to the specified location
@@ -62,13 +63,13 @@ func (daemon *Daemon) ContainerArchivePath(name string, path string) (content io
 // be ErrExtractPointNotDirectory. If noOverwriteDirNonDir is true then it will
 // be ErrExtractPointNotDirectory. If noOverwriteDirNonDir is true then it will
 // be an error if unpacking the given content would cause an existing directory
 // be an error if unpacking the given content would cause an existing directory
 // to be replaced with a non-directory and vice versa.
 // to be replaced with a non-directory and vice versa.
-func (daemon *Daemon) ContainerExtractToDir(name, path string, noOverwriteDirNonDir bool, content io.Reader) error {
-	container, err := daemon.Get(name)
+func (daemon *Daemon) ContainerExtractToDir(ctx context.Context, name, path string, noOverwriteDirNonDir bool, content io.Reader) error {
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	return container.ExtractToDir(path, noOverwriteDirNonDir, content)
+	return container.ExtractToDir(ctx, path, noOverwriteDirNonDir, content)
 }
 }
 
 
 // resolvePath resolves the given path in the container to a resource on the
 // resolvePath resolves the given path in the container to a resource on the
@@ -133,14 +134,14 @@ func (container *Container) statPath(resolvedPath, absPath string) (stat *types.
 
 
 // StatPath stats the filesystem resource at the specified path in this
 // StatPath stats the filesystem resource at the specified path in this
 // container. Returns stat info about the resource.
 // container. Returns stat info about the resource.
-func (container *Container) StatPath(path string) (stat *types.ContainerPathStat, err error) {
+func (container *Container) StatPath(ctx context.Context, path string) (stat *types.ContainerPathStat, err error) {
 	container.Lock()
 	container.Lock()
 	defer container.Unlock()
 	defer container.Unlock()
 
 
-	if err = container.Mount(); err != nil {
+	if err = container.Mount(ctx); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	defer container.Unmount()
+	defer container.Unmount(ctx)
 
 
 	err = container.mountVolumes()
 	err = container.mountVolumes()
 	defer container.unmountVolumes(true)
 	defer container.unmountVolumes(true)
@@ -159,7 +160,7 @@ func (container *Container) StatPath(path string) (stat *types.ContainerPathStat
 // ArchivePath creates an archive of the filesystem resource at the specified
 // ArchivePath creates an archive of the filesystem resource at the specified
 // path in this container. Returns a tar archive of the resource and stat info
 // path in this container. Returns a tar archive of the resource and stat info
 // about the resource.
 // about the resource.
-func (container *Container) ArchivePath(path string) (content io.ReadCloser, stat *types.ContainerPathStat, err error) {
+func (container *Container) ArchivePath(ctx context.Context, path string) (content io.ReadCloser, stat *types.ContainerPathStat, err error) {
 	container.Lock()
 	container.Lock()
 
 
 	defer func() {
 	defer func() {
@@ -171,7 +172,7 @@ func (container *Container) ArchivePath(path string) (content io.ReadCloser, sta
 		}
 		}
 	}()
 	}()
 
 
-	if err = container.Mount(); err != nil {
+	if err = container.Mount(ctx); err != nil {
 		return nil, nil, err
 		return nil, nil, err
 	}
 	}
 
 
@@ -180,7 +181,7 @@ func (container *Container) ArchivePath(path string) (content io.ReadCloser, sta
 			// unmount any volumes
 			// unmount any volumes
 			container.unmountVolumes(true)
 			container.unmountVolumes(true)
 			// unmount the container's rootfs
 			// unmount the container's rootfs
-			container.Unmount()
+			container.Unmount(ctx)
 		}
 		}
 	}()
 	}()
 
 
@@ -214,12 +215,12 @@ func (container *Container) ArchivePath(path string) (content io.ReadCloser, sta
 	content = ioutils.NewReadCloserWrapper(data, func() error {
 	content = ioutils.NewReadCloserWrapper(data, func() error {
 		err := data.Close()
 		err := data.Close()
 		container.unmountVolumes(true)
 		container.unmountVolumes(true)
-		container.Unmount()
+		container.Unmount(ctx)
 		container.Unlock()
 		container.Unlock()
 		return err
 		return err
 	})
 	})
 
 
-	container.logEvent("archive-path")
+	container.logEvent(ctx, "archive-path")
 
 
 	return content, stat, nil
 	return content, stat, nil
 }
 }
@@ -230,14 +231,14 @@ func (container *Container) ArchivePath(path string) (content io.ReadCloser, sta
 // noOverwriteDirNonDir is true then it will be an error if unpacking the
 // noOverwriteDirNonDir is true then it will be an error if unpacking the
 // given content would cause an existing directory to be replaced with a non-
 // given content would cause an existing directory to be replaced with a non-
 // directory and vice versa.
 // directory and vice versa.
-func (container *Container) ExtractToDir(path string, noOverwriteDirNonDir bool, content io.Reader) (err error) {
+func (container *Container) ExtractToDir(ctx context.Context, path string, noOverwriteDirNonDir bool, content io.Reader) (err error) {
 	container.Lock()
 	container.Lock()
 	defer container.Unlock()
 	defer container.Unlock()
 
 
-	if err = container.Mount(); err != nil {
+	if err = container.Mount(ctx); err != nil {
 		return err
 		return err
 	}
 	}
-	defer container.Unmount()
+	defer container.Unmount(ctx)
 
 
 	err = container.mountVolumes()
 	err = container.mountVolumes()
 	defer container.unmountVolumes(true)
 	defer container.unmountVolumes(true)
@@ -318,7 +319,7 @@ func (container *Container) ExtractToDir(path string, noOverwriteDirNonDir bool,
 		return err
 		return err
 	}
 	}
 
 
-	container.logEvent("extract-to-dir")
+	container.logEvent(ctx, "extract-to-dir")
 
 
 	return nil
 	return nil
 }
 }

+ 7 - 6
daemon/attach.go

@@ -3,6 +3,7 @@ package daemon
 import (
 import (
 	"io"
 	"io"
 
 
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/pkg/stdcopy"
 	"github.com/docker/docker/pkg/stdcopy"
 )
 )
 
 
@@ -15,8 +16,8 @@ type ContainerAttachWithLogsConfig struct {
 }
 }
 
 
 // ContainerAttachWithLogs attaches to logs according to the config passed in. See ContainerAttachWithLogsConfig.
 // ContainerAttachWithLogs attaches to logs according to the config passed in. See ContainerAttachWithLogsConfig.
-func (daemon *Daemon) ContainerAttachWithLogs(prefixOrName string, c *ContainerAttachWithLogsConfig) error {
-	container, err := daemon.Get(prefixOrName)
+func (daemon *Daemon) ContainerAttachWithLogs(ctx context.Context, prefixOrName string, c *ContainerAttachWithLogsConfig) error {
+	container, err := daemon.Get(ctx, prefixOrName)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -43,7 +44,7 @@ func (daemon *Daemon) ContainerAttachWithLogs(prefixOrName string, c *ContainerA
 		stderr = errStream
 		stderr = errStream
 	}
 	}
 
 
-	return container.attachWithLogs(stdin, stdout, stderr, c.Logs, c.Stream)
+	return container.attachWithLogs(ctx, stdin, stdout, stderr, c.Logs, c.Stream)
 }
 }
 
 
 // ContainerWsAttachWithLogsConfig attach with websockets, since all
 // ContainerWsAttachWithLogsConfig attach with websockets, since all
@@ -55,10 +56,10 @@ type ContainerWsAttachWithLogsConfig struct {
 }
 }
 
 
 // ContainerWsAttachWithLogs websocket connection
 // ContainerWsAttachWithLogs websocket connection
-func (daemon *Daemon) ContainerWsAttachWithLogs(prefixOrName string, c *ContainerWsAttachWithLogsConfig) error {
-	container, err := daemon.Get(prefixOrName)
+func (daemon *Daemon) ContainerWsAttachWithLogs(ctx context.Context, prefixOrName string, c *ContainerWsAttachWithLogsConfig) error {
+	container, err := daemon.Get(ctx, prefixOrName)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	return container.attachWithLogs(c.InStream, c.OutStream, c.ErrStream, c.Logs, c.Stream)
+	return container.attachWithLogs(ctx, c.InStream, c.OutStream, c.ErrStream, c.Logs, c.Stream)
 }
 }

+ 6 - 3
daemon/changes.go

@@ -1,10 +1,13 @@
 package daemon
 package daemon
 
 
-import "github.com/docker/docker/pkg/archive"
+import (
+	"github.com/docker/docker/context"
+	"github.com/docker/docker/pkg/archive"
+)
 
 
 // ContainerChanges returns a list of container fs changes
 // ContainerChanges returns a list of container fs changes
-func (daemon *Daemon) ContainerChanges(name string) ([]archive.Change, error) {
-	container, err := daemon.Get(name)
+func (daemon *Daemon) ContainerChanges(ctx context.Context, name string) ([]archive.Change, error) {
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}

+ 5 - 4
daemon/commit.go

@@ -1,6 +1,7 @@
 package daemon
 package daemon
 
 
 import (
 import (
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/docker/runconfig"
 )
 )
@@ -18,10 +19,10 @@ type ContainerCommitConfig struct {
 
 
 // Commit creates a new filesystem image from the current state of a container.
 // Commit creates a new filesystem image from the current state of a container.
 // The image can optionally be tagged into a repository.
 // The image can optionally be tagged into a repository.
-func (daemon *Daemon) Commit(container *Container, c *ContainerCommitConfig) (*image.Image, error) {
+func (daemon *Daemon) Commit(ctx context.Context, container *Container, c *ContainerCommitConfig) (*image.Image, error) {
 	if c.Pause && !container.isPaused() {
 	if c.Pause && !container.isPaused() {
-		container.pause()
-		defer container.unpause()
+		container.pause(ctx)
+		defer container.unpause(ctx)
 	}
 	}
 
 
 	rwTar, err := container.exportContainerRw()
 	rwTar, err := container.exportContainerRw()
@@ -46,6 +47,6 @@ func (daemon *Daemon) Commit(container *Container, c *ContainerCommitConfig) (*i
 			return img, err
 			return img, err
 		}
 		}
 	}
 	}
-	container.logEvent("commit")
+	container.logEvent(ctx, "commit")
 	return img, nil
 	return img, nil
 }
 }

+ 59 - 57
daemon/container.go

@@ -15,6 +15,7 @@ import (
 	"github.com/opencontainers/runc/libcontainer/label"
 	"github.com/opencontainers/runc/libcontainer/label"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/daemon/logger/jsonfilelog"
 	"github.com/docker/docker/daemon/logger/jsonfilelog"
@@ -170,9 +171,10 @@ func (container *Container) writeHostConfig() error {
 	return ioutil.WriteFile(pth, data, 0666)
 	return ioutil.WriteFile(pth, data, 0666)
 }
 }
 
 
-func (container *Container) logEvent(action string) {
+func (container *Container) logEvent(ctx context.Context, action string) {
 	d := container.daemon
 	d := container.daemon
 	d.EventsService.Log(
 	d.EventsService.Log(
+		ctx,
 		action,
 		action,
 		container.ID,
 		container.ID,
 		container.Config.Image,
 		container.Config.Image,
@@ -238,7 +240,7 @@ func (container *Container) exportContainerRw() (archive.Archive, error) {
 // container needs, such as storage and networking, as well as links
 // container needs, such as storage and networking, as well as links
 // between containers. The container is left waiting for a signal to
 // between containers. The container is left waiting for a signal to
 // begin running.
 // begin running.
-func (container *Container) Start() (err error) {
+func (container *Container) Start(ctx context.Context) (err error) {
 	container.Lock()
 	container.Lock()
 	defer container.Unlock()
 	defer container.Unlock()
 
 
@@ -260,12 +262,12 @@ func (container *Container) Start() (err error) {
 				container.ExitCode = 128
 				container.ExitCode = 128
 			}
 			}
 			container.toDisk()
 			container.toDisk()
-			container.cleanup()
-			container.logEvent("die")
+			container.cleanup(ctx)
+			container.logEvent(ctx, "die")
 		}
 		}
 	}()
 	}()
 
 
-	if err := container.Mount(); err != nil {
+	if err := container.Mount(ctx); err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -273,10 +275,10 @@ func (container *Container) Start() (err error) {
 	// backwards API compatibility.
 	// backwards API compatibility.
 	container.hostConfig = runconfig.SetDefaultNetModeIfBlank(container.hostConfig)
 	container.hostConfig = runconfig.SetDefaultNetModeIfBlank(container.hostConfig)
 
 
-	if err := container.initializeNetworking(); err != nil {
+	if err := container.initializeNetworking(ctx); err != nil {
 		return err
 		return err
 	}
 	}
-	linkedEnv, err := container.setupLinkedContainers()
+	linkedEnv, err := container.setupLinkedContainers(ctx)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -284,7 +286,7 @@ func (container *Container) Start() (err error) {
 		return err
 		return err
 	}
 	}
 	env := container.createDaemonEnvironment(linkedEnv)
 	env := container.createDaemonEnvironment(linkedEnv)
-	if err := populateCommand(container, env); err != nil {
+	if err := populateCommand(ctx, container, env); err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -301,7 +303,7 @@ func (container *Container) Start() (err error) {
 	mounts = append(mounts, container.ipcMounts()...)
 	mounts = append(mounts, container.ipcMounts()...)
 
 
 	container.command.Mounts = mounts
 	container.command.Mounts = mounts
-	return container.waitForStart()
+	return container.waitForStart(ctx)
 }
 }
 
 
 // streamConfig.StdinPipe returns a WriteCloser which can be used to feed data
 // streamConfig.StdinPipe returns a WriteCloser which can be used to feed data
@@ -334,14 +336,14 @@ func (container *Container) isNetworkAllocated() bool {
 
 
 // cleanup releases any network resources allocated to the container along with any rules
 // cleanup releases any network resources allocated to the container along with any rules
 // around how containers are linked together.  It also unmounts the container's root filesystem.
 // around how containers are linked together.  It also unmounts the container's root filesystem.
-func (container *Container) cleanup() {
+func (container *Container) cleanup(ctx context.Context) {
 	container.releaseNetwork()
 	container.releaseNetwork()
 
 
 	if err := container.unmountIpcMounts(); err != nil {
 	if err := container.unmountIpcMounts(); err != nil {
 		logrus.Errorf("%s: Failed to umount ipc filesystems: %v", container.ID, err)
 		logrus.Errorf("%s: Failed to umount ipc filesystems: %v", container.ID, err)
 	}
 	}
 
 
-	if err := container.Unmount(); err != nil {
+	if err := container.Unmount(ctx); err != nil {
 		logrus.Errorf("%s: Failed to umount filesystem: %v", container.ID, err)
 		logrus.Errorf("%s: Failed to umount filesystem: %v", container.ID, err)
 	}
 	}
 
 
@@ -357,7 +359,7 @@ func (container *Container) cleanup() {
 // to send the signal. An error is returned if the container is paused
 // to send the signal. An error is returned if the container is paused
 // or not running, or if there is a problem returned from the
 // or not running, or if there is a problem returned from the
 // underlying kill command.
 // underlying kill command.
-func (container *Container) killSig(sig int) error {
+func (container *Container) killSig(ctx context.Context, sig int) error {
 	logrus.Debugf("Sending %d to %s", sig, container.ID)
 	logrus.Debugf("Sending %d to %s", sig, container.ID)
 	container.Lock()
 	container.Lock()
 	defer container.Unlock()
 	defer container.Unlock()
@@ -385,13 +387,13 @@ func (container *Container) killSig(sig int) error {
 	if err := container.daemon.kill(container, sig); err != nil {
 	if err := container.daemon.kill(container, sig); err != nil {
 		return err
 		return err
 	}
 	}
-	container.logEvent("kill")
+	container.logEvent(ctx, "kill")
 	return nil
 	return nil
 }
 }
 
 
 // Wrapper aroung killSig() suppressing "no such process" error.
 // Wrapper aroung killSig() suppressing "no such process" error.
-func (container *Container) killPossiblyDeadProcess(sig int) error {
-	err := container.killSig(sig)
+func (container *Container) killPossiblyDeadProcess(ctx context.Context, sig int) error {
+	err := container.killSig(ctx, sig)
 	if err == syscall.ESRCH {
 	if err == syscall.ESRCH {
 		logrus.Debugf("Cannot kill process (pid=%d) with signal %d: no such process.", container.getPID(), sig)
 		logrus.Debugf("Cannot kill process (pid=%d) with signal %d: no such process.", container.getPID(), sig)
 		return nil
 		return nil
@@ -399,7 +401,7 @@ func (container *Container) killPossiblyDeadProcess(sig int) error {
 	return err
 	return err
 }
 }
 
 
-func (container *Container) pause() error {
+func (container *Container) pause(ctx context.Context) error {
 	container.Lock()
 	container.Lock()
 	defer container.Unlock()
 	defer container.Unlock()
 
 
@@ -417,11 +419,11 @@ func (container *Container) pause() error {
 		return err
 		return err
 	}
 	}
 	container.Paused = true
 	container.Paused = true
-	container.logEvent("pause")
+	container.logEvent(ctx, "pause")
 	return nil
 	return nil
 }
 }
 
 
-func (container *Container) unpause() error {
+func (container *Container) unpause(ctx context.Context) error {
 	container.Lock()
 	container.Lock()
 	defer container.Unlock()
 	defer container.Unlock()
 
 
@@ -439,18 +441,18 @@ func (container *Container) unpause() error {
 		return err
 		return err
 	}
 	}
 	container.Paused = false
 	container.Paused = false
-	container.logEvent("unpause")
+	container.logEvent(ctx, "unpause")
 	return nil
 	return nil
 }
 }
 
 
 // Kill forcefully terminates a container.
 // Kill forcefully terminates a container.
-func (container *Container) Kill() error {
+func (container *Container) Kill(ctx context.Context) error {
 	if !container.IsRunning() {
 	if !container.IsRunning() {
 		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
 		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
 	}
 	}
 
 
 	// 1. Send SIGKILL
 	// 1. Send SIGKILL
-	if err := container.killPossiblyDeadProcess(int(syscall.SIGKILL)); err != nil {
+	if err := container.killPossiblyDeadProcess(ctx, int(syscall.SIGKILL)); err != nil {
 		// While normally we might "return err" here we're not going to
 		// While normally we might "return err" here we're not going to
 		// because if we can't stop the container by this point then
 		// because if we can't stop the container by this point then
 		// its probably because its already stopped. Meaning, between
 		// its probably because its already stopped. Meaning, between
@@ -484,15 +486,15 @@ func (container *Container) Kill() error {
 // process to exit. If a negative duration is given, Stop will wait
 // process to exit. If a negative duration is given, Stop will wait
 // for the initial signal forever. If the container is not running Stop returns
 // for the initial signal forever. If the container is not running Stop returns
 // immediately.
 // immediately.
-func (container *Container) Stop(seconds int) error {
+func (container *Container) Stop(ctx context.Context, seconds int) error {
 	if !container.IsRunning() {
 	if !container.IsRunning() {
 		return nil
 		return nil
 	}
 	}
 
 
 	// 1. Send a SIGTERM
 	// 1. Send a SIGTERM
-	if err := container.killPossiblyDeadProcess(container.stopSignal()); err != nil {
+	if err := container.killPossiblyDeadProcess(ctx, container.stopSignal()); err != nil {
 		logrus.Infof("Failed to send SIGTERM to the process, force killing")
 		logrus.Infof("Failed to send SIGTERM to the process, force killing")
-		if err := container.killPossiblyDeadProcess(9); err != nil {
+		if err := container.killPossiblyDeadProcess(ctx, 9); err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}
@@ -501,13 +503,13 @@ func (container *Container) Stop(seconds int) error {
 	if _, err := container.WaitStop(time.Duration(seconds) * time.Second); err != nil {
 	if _, err := container.WaitStop(time.Duration(seconds) * time.Second); err != nil {
 		logrus.Infof("Container %v failed to exit within %d seconds of SIGTERM - using the force", container.ID, seconds)
 		logrus.Infof("Container %v failed to exit within %d seconds of SIGTERM - using the force", container.ID, seconds)
 		// 3. If it doesn't, then send SIGKILL
 		// 3. If it doesn't, then send SIGKILL
-		if err := container.Kill(); err != nil {
+		if err := container.Kill(ctx); err != nil {
 			container.WaitStop(-1 * time.Second)
 			container.WaitStop(-1 * time.Second)
 			return err
 			return err
 		}
 		}
 	}
 	}
 
 
-	container.logEvent("stop")
+	container.logEvent(ctx, "stop")
 	return nil
 	return nil
 }
 }
 
 
@@ -515,61 +517,61 @@ func (container *Container) Stop(seconds int) error {
 // container. When stopping, wait for the given duration in seconds to
 // container. When stopping, wait for the given duration in seconds to
 // gracefully stop, before forcefully terminating the container. If
 // gracefully stop, before forcefully terminating the container. If
 // given a negative duration, wait forever for a graceful stop.
 // given a negative duration, wait forever for a graceful stop.
-func (container *Container) Restart(seconds int) error {
+func (container *Container) Restart(ctx context.Context, seconds int) error {
 	// Avoid unnecessarily unmounting and then directly mounting
 	// Avoid unnecessarily unmounting and then directly mounting
 	// the container when the container stops and then starts
 	// the container when the container stops and then starts
 	// again
 	// again
-	if err := container.Mount(); err == nil {
-		defer container.Unmount()
+	if err := container.Mount(ctx); err == nil {
+		defer container.Unmount(ctx)
 	}
 	}
 
 
-	if err := container.Stop(seconds); err != nil {
+	if err := container.Stop(ctx, seconds); err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	if err := container.Start(); err != nil {
+	if err := container.Start(ctx); err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	container.logEvent("restart")
+	container.logEvent(ctx, "restart")
 	return nil
 	return nil
 }
 }
 
 
 // Resize changes the TTY of the process running inside the container
 // Resize changes the TTY of the process running inside the container
 // to the given height and width. The container must be running.
 // to the given height and width. The container must be running.
-func (container *Container) Resize(h, w int) error {
+func (container *Container) Resize(ctx context.Context, h, w int) error {
 	if !container.IsRunning() {
 	if !container.IsRunning() {
 		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
 		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
 	}
 	}
 	if err := container.command.ProcessConfig.Terminal.Resize(h, w); err != nil {
 	if err := container.command.ProcessConfig.Terminal.Resize(h, w); err != nil {
 		return err
 		return err
 	}
 	}
-	container.logEvent("resize")
+	container.logEvent(ctx, "resize")
 	return nil
 	return nil
 }
 }
 
 
-func (container *Container) export() (archive.Archive, error) {
-	if err := container.Mount(); err != nil {
+func (container *Container) export(ctx context.Context) (archive.Archive, error) {
+	if err := container.Mount(ctx); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
 	archive, err := archive.Tar(container.basefs, archive.Uncompressed)
 	archive, err := archive.Tar(container.basefs, archive.Uncompressed)
 	if err != nil {
 	if err != nil {
-		container.Unmount()
+		container.Unmount(ctx)
 		return nil, err
 		return nil, err
 	}
 	}
 	arch := ioutils.NewReadCloserWrapper(archive, func() error {
 	arch := ioutils.NewReadCloserWrapper(archive, func() error {
 		err := archive.Close()
 		err := archive.Close()
-		container.Unmount()
+		container.Unmount(ctx)
 		return err
 		return err
 	})
 	})
-	container.logEvent("export")
+	container.logEvent(ctx, "export")
 	return arch, err
 	return arch, err
 }
 }
 
 
 // Mount sets container.basefs
 // Mount sets container.basefs
-func (container *Container) Mount() error {
-	return container.daemon.Mount(container)
+func (container *Container) Mount(ctx context.Context) error {
+	return container.daemon.Mount(ctx, container)
 }
 }
 
 
 func (container *Container) changes() ([]archive.Change, error) {
 func (container *Container) changes() ([]archive.Change, error) {
@@ -578,7 +580,7 @@ func (container *Container) changes() ([]archive.Change, error) {
 	return container.daemon.changes(container)
 	return container.daemon.changes(container)
 }
 }
 
 
-func (container *Container) getImage() (*image.Image, error) {
+func (container *Container) getImage(ctx context.Context) (*image.Image, error) {
 	if container.daemon == nil {
 	if container.daemon == nil {
 		return nil, derr.ErrorCodeImageUnregContainer
 		return nil, derr.ErrorCodeImageUnregContainer
 	}
 	}
@@ -587,7 +589,7 @@ func (container *Container) getImage() (*image.Image, error) {
 
 
 // Unmount asks the daemon to release the layered filesystems that are
 // Unmount asks the daemon to release the layered filesystems that are
 // mounted by the container.
 // mounted by the container.
-func (container *Container) Unmount() error {
+func (container *Container) Unmount(ctx context.Context) error {
 	return container.daemon.unmount(container)
 	return container.daemon.unmount(container)
 }
 }
 
 
@@ -612,7 +614,7 @@ func validateID(id string) error {
 	return nil
 	return nil
 }
 }
 
 
-func (container *Container) copy(resource string) (rc io.ReadCloser, err error) {
+func (container *Container) copy(ctx context.Context, resource string) (rc io.ReadCloser, err error) {
 	container.Lock()
 	container.Lock()
 
 
 	defer func() {
 	defer func() {
@@ -624,7 +626,7 @@ func (container *Container) copy(resource string) (rc io.ReadCloser, err error)
 		}
 		}
 	}()
 	}()
 
 
-	if err := container.Mount(); err != nil {
+	if err := container.Mount(ctx); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
@@ -633,7 +635,7 @@ func (container *Container) copy(resource string) (rc io.ReadCloser, err error)
 			// unmount any volumes
 			// unmount any volumes
 			container.unmountVolumes(true)
 			container.unmountVolumes(true)
 			// unmount the container's rootfs
 			// unmount the container's rootfs
-			container.Unmount()
+			container.Unmount(ctx)
 		}
 		}
 	}()
 	}()
 
 
@@ -669,11 +671,11 @@ func (container *Container) copy(resource string) (rc io.ReadCloser, err error)
 	reader := ioutils.NewReadCloserWrapper(archive, func() error {
 	reader := ioutils.NewReadCloserWrapper(archive, func() error {
 		err := archive.Close()
 		err := archive.Close()
 		container.unmountVolumes(true)
 		container.unmountVolumes(true)
-		container.Unmount()
+		container.Unmount(ctx)
 		container.Unlock()
 		container.Unlock()
 		return err
 		return err
 	})
 	})
-	container.logEvent("copy")
+	container.logEvent(ctx, "copy")
 	return reader, nil
 	return reader, nil
 }
 }
 
 
@@ -752,14 +754,14 @@ func (container *Container) startLogging() error {
 	return nil
 	return nil
 }
 }
 
 
-func (container *Container) waitForStart() error {
+func (container *Container) waitForStart(ctx context.Context) error {
 	container.monitor = newContainerMonitor(container, container.hostConfig.RestartPolicy)
 	container.monitor = newContainerMonitor(container, container.hostConfig.RestartPolicy)
 
 
 	// block until we either receive an error from the initial start of the container's
 	// block until we either receive an error from the initial start of the container's
 	// process or until the process is running in the container
 	// process or until the process is running in the container
 	select {
 	select {
 	case <-container.monitor.startSignal:
 	case <-container.monitor.startSignal:
-	case err := <-promise.Go(container.monitor.Start):
+	case err := <-promise.Go(func() error { return container.monitor.Start(ctx) }):
 		return err
 		return err
 	}
 	}
 
 
@@ -790,11 +792,11 @@ func (container *Container) getExecIDs() []string {
 	return container.execCommands.List()
 	return container.execCommands.List()
 }
 }
 
 
-func (container *Container) exec(ExecConfig *ExecConfig) error {
+func (container *Container) exec(ctx context.Context, ExecConfig *ExecConfig) error {
 	container.Lock()
 	container.Lock()
 	defer container.Unlock()
 	defer container.Unlock()
 
 
-	callback := func(processConfig *execdriver.ProcessConfig, pid int, chOOM <-chan struct{}) error {
+	callback := func(ctx context.Context, processConfig *execdriver.ProcessConfig, pid int, chOOM <-chan struct{}) error {
 		if processConfig.Tty {
 		if processConfig.Tty {
 			// The callback is called after the process Start()
 			// The callback is called after the process Start()
 			// so we are in the parent process. In TTY mode, stdin/out/err is the PtySlave
 			// so we are in the parent process. In TTY mode, stdin/out/err is the PtySlave
@@ -809,7 +811,7 @@ func (container *Container) exec(ExecConfig *ExecConfig) error {
 
 
 	// We use a callback here instead of a goroutine and an chan for
 	// We use a callback here instead of a goroutine and an chan for
 	// synchronization purposes
 	// synchronization purposes
-	cErr := promise.Go(func() error { return container.monitorExec(ExecConfig, callback) })
+	cErr := promise.Go(func() error { return container.monitorExec(ctx, ExecConfig, callback) })
 
 
 	// Exec should not return until the process is actually running
 	// Exec should not return until the process is actually running
 	select {
 	select {
@@ -821,13 +823,13 @@ func (container *Container) exec(ExecConfig *ExecConfig) error {
 	return nil
 	return nil
 }
 }
 
 
-func (container *Container) monitorExec(ExecConfig *ExecConfig, callback execdriver.DriverCallback) error {
+func (container *Container) monitorExec(ctx context.Context, ExecConfig *ExecConfig, callback execdriver.DriverCallback) error {
 	var (
 	var (
 		err      error
 		err      error
 		exitCode int
 		exitCode int
 	)
 	)
 	pipes := execdriver.NewPipes(ExecConfig.streamConfig.stdin, ExecConfig.streamConfig.stdout, ExecConfig.streamConfig.stderr, ExecConfig.OpenStdin)
 	pipes := execdriver.NewPipes(ExecConfig.streamConfig.stdin, ExecConfig.streamConfig.stdout, ExecConfig.streamConfig.stderr, ExecConfig.OpenStdin)
-	exitCode, err = container.daemon.Exec(container, ExecConfig, pipes, callback)
+	exitCode, err = container.daemon.Exec(ctx, container, ExecConfig, pipes, callback)
 	if err != nil {
 	if err != nil {
 		logrus.Errorf("Error running command in existing container %s: %s", container.ID, err)
 		logrus.Errorf("Error running command in existing container %s: %s", container.ID, err)
 	}
 	}
@@ -860,7 +862,7 @@ func (container *Container) Attach(stdin io.ReadCloser, stdout io.Writer, stderr
 	return attach(&container.streamConfig, container.Config.OpenStdin, container.Config.StdinOnce, container.Config.Tty, stdin, stdout, stderr)
 	return attach(&container.streamConfig, container.Config.OpenStdin, container.Config.StdinOnce, container.Config.Tty, stdin, stdout, stderr)
 }
 }
 
 
-func (container *Container) attachWithLogs(stdin io.ReadCloser, stdout, stderr io.Writer, logs, stream bool) error {
+func (container *Container) attachWithLogs(ctx context.Context, stdin io.ReadCloser, stdout, stderr io.Writer, logs, stream bool) error {
 	if logs {
 	if logs {
 		logDriver, err := container.getLogger()
 		logDriver, err := container.getLogger()
 		if err != nil {
 		if err != nil {
@@ -892,7 +894,7 @@ func (container *Container) attachWithLogs(stdin io.ReadCloser, stdout, stderr i
 		}
 		}
 	}
 	}
 
 
-	container.logEvent("attach")
+	container.logEvent(ctx, "attach")
 
 
 	//stream
 	//stream
 	if stream {
 	if stream {

+ 28 - 27
daemon/container_unix.go

@@ -15,6 +15,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/links"
 	"github.com/docker/docker/daemon/links"
 	"github.com/docker/docker/daemon/network"
 	"github.com/docker/docker/daemon/network"
@@ -77,12 +78,12 @@ func killProcessDirectly(container *Container) error {
 	return nil
 	return nil
 }
 }
 
 
-func (container *Container) setupLinkedContainers() ([]string, error) {
+func (container *Container) setupLinkedContainers(ctx context.Context) ([]string, error) {
 	var (
 	var (
 		env    []string
 		env    []string
 		daemon = container.daemon
 		daemon = container.daemon
 	)
 	)
-	children, err := daemon.children(container.Name)
+	children, err := daemon.children(ctx, container.Name)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -175,7 +176,7 @@ func getDevicesFromPath(deviceMapping runconfig.DeviceMapping) (devs []*configs.
 	return devs, derr.ErrorCodeDeviceInfo.WithArgs(deviceMapping.PathOnHost, err)
 	return devs, derr.ErrorCodeDeviceInfo.WithArgs(deviceMapping.PathOnHost, err)
 }
 }
 
 
-func populateCommand(c *Container, env []string) error {
+func populateCommand(ctx context.Context, c *Container, env []string) error {
 	var en *execdriver.Network
 	var en *execdriver.Network
 	if !c.Config.NetworkDisabled {
 	if !c.Config.NetworkDisabled {
 		en = &execdriver.Network{}
 		en = &execdriver.Network{}
@@ -185,7 +186,7 @@ func populateCommand(c *Container, env []string) error {
 
 
 		parts := strings.SplitN(string(c.hostConfig.NetworkMode), ":", 2)
 		parts := strings.SplitN(string(c.hostConfig.NetworkMode), ":", 2)
 		if parts[0] == "container" {
 		if parts[0] == "container" {
-			nc, err := c.getNetworkedContainer()
+			nc, err := c.getNetworkedContainer(ctx)
 			if err != nil {
 			if err != nil {
 				return err
 				return err
 			}
 			}
@@ -206,7 +207,7 @@ func populateCommand(c *Container, env []string) error {
 	}
 	}
 
 
 	if c.hostConfig.IpcMode.IsContainer() {
 	if c.hostConfig.IpcMode.IsContainer() {
-		ic, err := c.getIpcContainer()
+		ic, err := c.getIpcContainer(ctx)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
@@ -348,18 +349,18 @@ func mergeDevices(defaultDevices, userDevices []*configs.Device) []*configs.Devi
 }
 }
 
 
 // GetSize returns the real size & virtual size of the container.
 // GetSize returns the real size & virtual size of the container.
-func (container *Container) getSize() (int64, int64) {
+func (container *Container) getSize(ctx context.Context) (int64, int64) {
 	var (
 	var (
 		sizeRw, sizeRootfs int64
 		sizeRw, sizeRootfs int64
 		err                error
 		err                error
 		driver             = container.daemon.driver
 		driver             = container.daemon.driver
 	)
 	)
 
 
-	if err := container.Mount(); err != nil {
+	if err := container.Mount(ctx); err != nil {
 		logrus.Errorf("Failed to compute size of container rootfs %s: %s", container.ID, err)
 		logrus.Errorf("Failed to compute size of container rootfs %s: %s", container.ID, err)
 		return sizeRw, sizeRootfs
 		return sizeRw, sizeRootfs
 	}
 	}
-	defer container.Unmount()
+	defer container.Unmount(ctx)
 
 
 	initID := fmt.Sprintf("%s-init", container.ID)
 	initID := fmt.Sprintf("%s-init", container.ID)
 	sizeRw, err = driver.DiffSize(container.ID, initID)
 	sizeRw, err = driver.DiffSize(container.ID, initID)
@@ -411,7 +412,7 @@ func (container *Container) buildHostnameFile() error {
 	return ioutil.WriteFile(container.HostnamePath, []byte(container.Config.Hostname+"\n"), 0644)
 	return ioutil.WriteFile(container.HostnamePath, []byte(container.Config.Hostname+"\n"), 0644)
 }
 }
 
 
-func (container *Container) buildSandboxOptions() ([]libnetwork.SandboxOption, error) {
+func (container *Container) buildSandboxOptions(ctx context.Context) ([]libnetwork.SandboxOption, error) {
 	var (
 	var (
 		sboxOptions []libnetwork.SandboxOption
 		sboxOptions []libnetwork.SandboxOption
 		err         error
 		err         error
@@ -488,7 +489,7 @@ func (container *Container) buildSandboxOptions() ([]libnetwork.SandboxOption, e
 
 
 	var childEndpoints, parentEndpoints []string
 	var childEndpoints, parentEndpoints []string
 
 
-	children, err := container.daemon.children(container.Name)
+	children, err := container.daemon.children(ctx, container.Name)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -519,7 +520,7 @@ func (container *Container) buildSandboxOptions() ([]libnetwork.SandboxOption, e
 			continue
 			continue
 		}
 		}
 
 
-		c, err := container.daemon.Get(ref.ParentID)
+		c, err := container.daemon.Get(ctx, ref.ParentID)
 		if err != nil {
 		if err != nil {
 			logrus.Error(err)
 			logrus.Error(err)
 		}
 		}
@@ -678,7 +679,7 @@ func (container *Container) updateSandboxNetworkSettings(sb libnetwork.Sandbox)
 
 
 // UpdateNetwork is used to update the container's network (e.g. when linked containers
 // UpdateNetwork is used to update the container's network (e.g. when linked containers
 // get removed/unlinked).
 // get removed/unlinked).
-func (container *Container) updateNetwork() error {
+func (container *Container) updateNetwork(ctx context.Context) error {
 	ctrl := container.daemon.netController
 	ctrl := container.daemon.netController
 	sid := container.NetworkSettings.SandboxID
 	sid := container.NetworkSettings.SandboxID
 
 
@@ -687,7 +688,7 @@ func (container *Container) updateNetwork() error {
 		return derr.ErrorCodeNoSandbox.WithArgs(sid, err)
 		return derr.ErrorCodeNoSandbox.WithArgs(sid, err)
 	}
 	}
 
 
-	options, err := container.buildSandboxOptions()
+	options, err := container.buildSandboxOptions(ctx)
 	if err != nil {
 	if err != nil {
 		return derr.ErrorCodeNetworkUpdate.WithArgs(err)
 		return derr.ErrorCodeNetworkUpdate.WithArgs(err)
 	}
 	}
@@ -811,7 +812,7 @@ func createNetwork(controller libnetwork.NetworkController, dnet string, driver
 	return controller.NewNetwork(driver, dnet, createOptions...)
 	return controller.NewNetwork(driver, dnet, createOptions...)
 }
 }
 
 
-func (container *Container) secondaryNetworkRequired(primaryNetworkType string) bool {
+func (container *Container) secondaryNetworkRequired(ctx context.Context, primaryNetworkType string) bool {
 	switch primaryNetworkType {
 	switch primaryNetworkType {
 	case "bridge", "none", "host", "container":
 	case "bridge", "none", "host", "container":
 		return false
 		return false
@@ -830,7 +831,7 @@ func (container *Container) secondaryNetworkRequired(primaryNetworkType string)
 	return false
 	return false
 }
 }
 
 
-func (container *Container) allocateNetwork() error {
+func (container *Container) allocateNetwork(ctx context.Context) error {
 	mode := container.hostConfig.NetworkMode
 	mode := container.hostConfig.NetworkMode
 	controller := container.daemon.netController
 	controller := container.daemon.netController
 	if container.Config.NetworkDisabled || mode.IsContainer() {
 	if container.Config.NetworkDisabled || mode.IsContainer() {
@@ -864,21 +865,21 @@ func (container *Container) allocateNetwork() error {
 		service = strings.Replace(service, "/", "", -1)
 		service = strings.Replace(service, "/", "", -1)
 	}
 	}
 
 
-	if container.secondaryNetworkRequired(networkDriver) {
+	if container.secondaryNetworkRequired(ctx, networkDriver) {
 		// Configure Bridge as secondary network for port binding purposes
 		// Configure Bridge as secondary network for port binding purposes
-		if err := container.configureNetwork("bridge", service, "bridge", false); err != nil {
+		if err := container.configureNetwork(ctx, "bridge", service, "bridge", false); err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}
 
 
-	if err := container.configureNetwork(networkName, service, networkDriver, mode.IsDefault()); err != nil {
+	if err := container.configureNetwork(ctx, networkName, service, networkDriver, mode.IsDefault()); err != nil {
 		return err
 		return err
 	}
 	}
 
 
 	return container.writeHostConfig()
 	return container.writeHostConfig()
 }
 }
 
 
-func (container *Container) configureNetwork(networkName, service, networkDriver string, canCreateNetwork bool) error {
+func (container *Container) configureNetwork(ctx context.Context, networkName, service, networkDriver string, canCreateNetwork bool) error {
 	controller := container.daemon.netController
 	controller := container.daemon.netController
 
 
 	n, err := controller.NetworkByName(networkName)
 	n, err := controller.NetworkByName(networkName)
@@ -922,7 +923,7 @@ func (container *Container) configureNetwork(networkName, service, networkDriver
 		return false
 		return false
 	})
 	})
 	if sb == nil {
 	if sb == nil {
-		options, err := container.buildSandboxOptions()
+		options, err := container.buildSandboxOptions(ctx)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
@@ -945,12 +946,12 @@ func (container *Container) configureNetwork(networkName, service, networkDriver
 	return nil
 	return nil
 }
 }
 
 
-func (container *Container) initializeNetworking() error {
+func (container *Container) initializeNetworking(ctx context.Context) error {
 	var err error
 	var err error
 
 
 	if container.hostConfig.NetworkMode.IsContainer() {
 	if container.hostConfig.NetworkMode.IsContainer() {
 		// we need to get the hosts files from the container to join
 		// we need to get the hosts files from the container to join
-		nc, err := container.getNetworkedContainer()
+		nc, err := container.getNetworkedContainer(ctx)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
@@ -976,7 +977,7 @@ func (container *Container) initializeNetworking() error {
 
 
 	}
 	}
 
 
-	if err := container.allocateNetwork(); err != nil {
+	if err := container.allocateNetwork(ctx); err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -997,9 +998,9 @@ func (container *Container) setNetworkNamespaceKey(pid int) error {
 	return sandbox.SetKey(path)
 	return sandbox.SetKey(path)
 }
 }
 
 
-func (container *Container) getIpcContainer() (*Container, error) {
+func (container *Container) getIpcContainer(ctx context.Context) (*Container, error) {
 	containerID := container.hostConfig.IpcMode.Container()
 	containerID := container.hostConfig.IpcMode.Container()
-	c, err := container.daemon.Get(containerID)
+	c, err := container.daemon.Get(ctx, containerID)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -1035,14 +1036,14 @@ func (container *Container) setupWorkingDirectory() error {
 	return nil
 	return nil
 }
 }
 
 
-func (container *Container) getNetworkedContainer() (*Container, error) {
+func (container *Container) getNetworkedContainer(ctx context.Context) (*Container, error) {
 	parts := strings.SplitN(string(container.hostConfig.NetworkMode), ":", 2)
 	parts := strings.SplitN(string(container.hostConfig.NetworkMode), ":", 2)
 	switch parts[0] {
 	switch parts[0] {
 	case "container":
 	case "container":
 		if len(parts) != 2 {
 		if len(parts) != 2 {
 			return nil, derr.ErrorCodeParseContainer
 			return nil, derr.ErrorCodeParseContainer
 		}
 		}
-		nc, err := container.daemon.Get(parts[1])
+		nc, err := container.daemon.Get(ctx, parts[1])
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}

+ 6 - 5
daemon/container_windows.go

@@ -5,6 +5,7 @@ package daemon
 import (
 import (
 	"strings"
 	"strings"
 
 
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/execdriver"
 	derr "github.com/docker/docker/errors"
 	derr "github.com/docker/docker/errors"
 )
 )
@@ -25,7 +26,7 @@ func killProcessDirectly(container *Container) error {
 	return nil
 	return nil
 }
 }
 
 
-func (container *Container) setupLinkedContainers() ([]string, error) {
+func (container *Container) setupLinkedContainers(ctx context.Context) ([]string, error) {
 	return nil, nil
 	return nil, nil
 }
 }
 
 
@@ -34,7 +35,7 @@ func (container *Container) createDaemonEnvironment(linkedEnv []string) []string
 	return container.Config.Env
 	return container.Config.Env
 }
 }
 
 
-func (container *Container) initializeNetworking() error {
+func (container *Container) initializeNetworking(ctx context.Context) error {
 	return nil
 	return nil
 }
 }
 
 
@@ -42,7 +43,7 @@ func (container *Container) setupWorkingDirectory() error {
 	return nil
 	return nil
 }
 }
 
 
-func populateCommand(c *Container, env []string) error {
+func populateCommand(ctx context.Context, c *Container, env []string) error {
 	en := &execdriver.Network{
 	en := &execdriver.Network{
 		Interface: nil,
 		Interface: nil,
 	}
 	}
@@ -135,7 +136,7 @@ func populateCommand(c *Container, env []string) error {
 }
 }
 
 
 // GetSize returns real size & virtual size
 // GetSize returns real size & virtual size
-func (container *Container) getSize() (int64, int64) {
+func (container *Container) getSize(ctx context.Context) (int64, int64) {
 	// TODO Windows
 	// TODO Windows
 	return 0, 0
 	return 0, 0
 }
 }
@@ -150,7 +151,7 @@ func (container *Container) allocateNetwork() error {
 	return nil
 	return nil
 }
 }
 
 
-func (container *Container) updateNetwork() error {
+func (container *Container) updateNetwork(ctx context.Context) error {
 	return nil
 	return nil
 }
 }
 
 

+ 17 - 16
daemon/create.go

@@ -5,6 +5,7 @@ import (
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/context"
 	derr "github.com/docker/docker/errors"
 	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/graph/tags"
 	"github.com/docker/docker/graph/tags"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/image"
@@ -15,21 +16,21 @@ import (
 )
 )
 
 
 // ContainerCreate takes configs and creates a container.
 // ContainerCreate takes configs and creates a container.
-func (daemon *Daemon) ContainerCreate(name string, config *runconfig.Config, hostConfig *runconfig.HostConfig, adjustCPUShares bool) (*Container, []string, error) {
+func (daemon *Daemon) ContainerCreate(ctx context.Context, name string, config *runconfig.Config, hostConfig *runconfig.HostConfig, adjustCPUShares bool) (*Container, []string, error) {
 	if config == nil {
 	if config == nil {
 		return nil, nil, derr.ErrorCodeEmptyConfig
 		return nil, nil, derr.ErrorCodeEmptyConfig
 	}
 	}
 
 
-	warnings, err := daemon.verifyContainerSettings(hostConfig, config)
+	warnings, err := daemon.verifyContainerSettings(ctx, hostConfig, config)
 	if err != nil {
 	if err != nil {
 		return nil, warnings, err
 		return nil, warnings, err
 	}
 	}
 
 
 	daemon.adaptContainerSettings(hostConfig, adjustCPUShares)
 	daemon.adaptContainerSettings(hostConfig, adjustCPUShares)
 
 
-	container, buildWarnings, err := daemon.Create(config, hostConfig, name)
+	container, buildWarnings, err := daemon.Create(ctx, config, hostConfig, name)
 	if err != nil {
 	if err != nil {
-		if daemon.Graph().IsNotExist(err, config.Image) {
+		if daemon.Graph(ctx).IsNotExist(err, config.Image) {
 			if strings.Contains(config.Image, "@") {
 			if strings.Contains(config.Image, "@") {
 				return nil, warnings, derr.ErrorCodeNoSuchImageHash.WithArgs(config.Image)
 				return nil, warnings, derr.ErrorCodeNoSuchImageHash.WithArgs(config.Image)
 			}
 			}
@@ -48,7 +49,7 @@ func (daemon *Daemon) ContainerCreate(name string, config *runconfig.Config, hos
 }
 }
 
 
 // Create creates a new container from the given configuration with a given name.
 // Create creates a new container from the given configuration with a given name.
-func (daemon *Daemon) Create(config *runconfig.Config, hostConfig *runconfig.HostConfig, name string) (retC *Container, retS []string, retErr error) {
+func (daemon *Daemon) Create(ctx context.Context, config *runconfig.Config, hostConfig *runconfig.HostConfig, name string) (retC *Container, retS []string, retErr error) {
 	var (
 	var (
 		container *Container
 		container *Container
 		warnings  []string
 		warnings  []string
@@ -76,29 +77,29 @@ func (daemon *Daemon) Create(config *runconfig.Config, hostConfig *runconfig.Hos
 		hostConfig = &runconfig.HostConfig{}
 		hostConfig = &runconfig.HostConfig{}
 	}
 	}
 	if hostConfig.SecurityOpt == nil {
 	if hostConfig.SecurityOpt == nil {
-		hostConfig.SecurityOpt, err = daemon.generateSecurityOpt(hostConfig.IpcMode, hostConfig.PidMode)
+		hostConfig.SecurityOpt, err = daemon.generateSecurityOpt(ctx, hostConfig.IpcMode, hostConfig.PidMode)
 		if err != nil {
 		if err != nil {
 			return nil, nil, err
 			return nil, nil, err
 		}
 		}
 	}
 	}
-	if container, err = daemon.newContainer(name, config, imgID); err != nil {
+	if container, err = daemon.newContainer(ctx, name, config, imgID); err != nil {
 		return nil, nil, err
 		return nil, nil, err
 	}
 	}
 	defer func() {
 	defer func() {
 		if retErr != nil {
 		if retErr != nil {
-			if err := daemon.rm(container, false); err != nil {
+			if err := daemon.rm(ctx, container, false); err != nil {
 				logrus.Errorf("Clean up Error! Cannot destroy container %s: %v", container.ID, err)
 				logrus.Errorf("Clean up Error! Cannot destroy container %s: %v", container.ID, err)
 			}
 			}
 		}
 		}
 	}()
 	}()
 
 
-	if err := daemon.Register(container); err != nil {
+	if err := daemon.Register(ctx, container); err != nil {
 		return nil, nil, err
 		return nil, nil, err
 	}
 	}
 	if err := daemon.createRootfs(container); err != nil {
 	if err := daemon.createRootfs(container); err != nil {
 		return nil, nil, err
 		return nil, nil, err
 	}
 	}
-	if err := daemon.setHostConfig(container, hostConfig); err != nil {
+	if err := daemon.setHostConfig(ctx, container, hostConfig); err != nil {
 		return nil, nil, err
 		return nil, nil, err
 	}
 	}
 	defer func() {
 	defer func() {
@@ -108,10 +109,10 @@ func (daemon *Daemon) Create(config *runconfig.Config, hostConfig *runconfig.Hos
 			}
 			}
 		}
 		}
 	}()
 	}()
-	if err := container.Mount(); err != nil {
+	if err := container.Mount(ctx); err != nil {
 		return nil, nil, err
 		return nil, nil, err
 	}
 	}
-	defer container.Unmount()
+	defer container.Unmount(ctx)
 
 
 	if err := createContainerPlatformSpecificSettings(container, config, hostConfig, img); err != nil {
 	if err := createContainerPlatformSpecificSettings(container, config, hostConfig, img); err != nil {
 		return nil, nil, err
 		return nil, nil, err
@@ -121,16 +122,16 @@ func (daemon *Daemon) Create(config *runconfig.Config, hostConfig *runconfig.Hos
 		logrus.Errorf("Error saving new container to disk: %v", err)
 		logrus.Errorf("Error saving new container to disk: %v", err)
 		return nil, nil, err
 		return nil, nil, err
 	}
 	}
-	container.logEvent("create")
+	container.logEvent(ctx, "create")
 	return container, warnings, nil
 	return container, warnings, nil
 }
 }
 
 
-func (daemon *Daemon) generateSecurityOpt(ipcMode runconfig.IpcMode, pidMode runconfig.PidMode) ([]string, error) {
+func (daemon *Daemon) generateSecurityOpt(ctx context.Context, ipcMode runconfig.IpcMode, pidMode runconfig.PidMode) ([]string, error) {
 	if ipcMode.IsHost() || pidMode.IsHost() {
 	if ipcMode.IsHost() || pidMode.IsHost() {
 		return label.DisableSecOpt(), nil
 		return label.DisableSecOpt(), nil
 	}
 	}
 	if ipcContainer := ipcMode.Container(); ipcContainer != "" {
 	if ipcContainer := ipcMode.Container(); ipcContainer != "" {
-		c, err := daemon.Get(ipcContainer)
+		c, err := daemon.Get(ctx, ipcContainer)
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
@@ -142,7 +143,7 @@ func (daemon *Daemon) generateSecurityOpt(ipcMode runconfig.IpcMode, pidMode run
 
 
 // VolumeCreate creates a volume with the specified name, driver, and opts
 // VolumeCreate creates a volume with the specified name, driver, and opts
 // This is called directly from the remote API
 // This is called directly from the remote API
-func (daemon *Daemon) VolumeCreate(name, driverName string, opts map[string]string) (*types.Volume, error) {
+func (daemon *Daemon) VolumeCreate(ctx context.Context, name, driverName string, opts map[string]string) (*types.Volume, error) {
 	if name == "" {
 	if name == "" {
 		name = stringid.GenerateNonCryptoID()
 		name = stringid.GenerateNonCryptoID()
 	}
 	}

+ 42 - 44
daemon/daemon.go

@@ -20,6 +20,7 @@ import (
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api"
 	"github.com/docker/docker/api"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon/events"
 	"github.com/docker/docker/daemon/events"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/execdriver/execdrivers"
 	"github.com/docker/docker/daemon/execdriver/execdrivers"
@@ -127,14 +128,14 @@ type Daemon struct {
 //  - A partial container ID prefix (e.g. short ID) of any length that is
 //  - A partial container ID prefix (e.g. short ID) of any length that is
 //    unique enough to only return a single container object
 //    unique enough to only return a single container object
 //  If none of these searches succeed, an error is returned
 //  If none of these searches succeed, an error is returned
-func (daemon *Daemon) Get(prefixOrName string) (*Container, error) {
+func (daemon *Daemon) Get(ctx context.Context, prefixOrName string) (*Container, error) {
 	if containerByID := daemon.containers.Get(prefixOrName); containerByID != nil {
 	if containerByID := daemon.containers.Get(prefixOrName); containerByID != nil {
 		// prefix is an exact match to a full container ID
 		// prefix is an exact match to a full container ID
 		return containerByID, nil
 		return containerByID, nil
 	}
 	}
 
 
 	// GetByName will match only an exact name provided; we ignore errors
 	// GetByName will match only an exact name provided; we ignore errors
-	if containerByName, _ := daemon.GetByName(prefixOrName); containerByName != nil {
+	if containerByName, _ := daemon.GetByName(ctx, prefixOrName); containerByName != nil {
 		// prefix is an exact match to a full container Name
 		// prefix is an exact match to a full container Name
 		return containerByName, nil
 		return containerByName, nil
 	}
 	}
@@ -152,8 +153,8 @@ func (daemon *Daemon) Get(prefixOrName string) (*Container, error) {
 
 
 // Exists returns a true if a container of the specified ID or name exists,
 // Exists returns a true if a container of the specified ID or name exists,
 // false otherwise.
 // false otherwise.
-func (daemon *Daemon) Exists(id string) bool {
-	c, _ := daemon.Get(id)
+func (daemon *Daemon) Exists(ctx context.Context, id string) bool {
+	c, _ := daemon.Get(ctx, id)
 	return c != nil
 	return c != nil
 }
 }
 
 
@@ -178,8 +179,8 @@ func (daemon *Daemon) load(id string) (*Container, error) {
 }
 }
 
 
 // Register makes a container object usable by the daemon as <container.ID>
 // Register makes a container object usable by the daemon as <container.ID>
-func (daemon *Daemon) Register(container *Container) error {
-	if container.daemon != nil || daemon.Exists(container.ID) {
+func (daemon *Daemon) Register(ctx context.Context, container *Container) error {
+	if container.daemon != nil || daemon.Exists(ctx, container.ID) {
 		return fmt.Errorf("Container is already loaded")
 		return fmt.Errorf("Container is already loaded")
 	}
 	}
 	if err := validateID(container.ID); err != nil {
 	if err := validateID(container.ID); err != nil {
@@ -217,10 +218,7 @@ func (daemon *Daemon) Register(container *Container) error {
 		}
 		}
 		daemon.execDriver.Terminate(cmd)
 		daemon.execDriver.Terminate(cmd)
 
 
-		if err := container.unmountIpcMounts(); err != nil {
-			logrus.Errorf("%s: Failed to umount ipc filesystems: %v", container.ID, err)
-		}
-		if err := container.Unmount(); err != nil {
+		if err := container.Unmount(ctx); err != nil {
 			logrus.Debugf("unmount error %s", err)
 			logrus.Debugf("unmount error %s", err)
 		}
 		}
 		if err := container.toDiskLocking(); err != nil {
 		if err := container.toDiskLocking(); err != nil {
@@ -254,7 +252,7 @@ func (daemon *Daemon) ensureName(container *Container) error {
 	return nil
 	return nil
 }
 }
 
 
-func (daemon *Daemon) restore() error {
+func (daemon *Daemon) restore(ctx context.Context) error {
 	type cr struct {
 	type cr struct {
 		container  *Container
 		container  *Container
 		registered bool
 		registered bool
@@ -324,7 +322,7 @@ func (daemon *Daemon) restore() error {
 				}
 				}
 			}
 			}
 
 
-			if err := daemon.Register(container); err != nil {
+			if err := daemon.Register(ctx, container); err != nil {
 				logrus.Errorf("Failed to register container %s: %s", container.ID, err)
 				logrus.Errorf("Failed to register container %s: %s", container.ID, err)
 				// The container register failed should not be started.
 				// The container register failed should not be started.
 				return
 				return
@@ -335,7 +333,7 @@ func (daemon *Daemon) restore() error {
 			if daemon.configStore.AutoRestart && container.shouldRestart() {
 			if daemon.configStore.AutoRestart && container.shouldRestart() {
 				logrus.Debugf("Starting container %s", container.ID)
 				logrus.Debugf("Starting container %s", container.ID)
 
 
-				if err := container.Start(); err != nil {
+				if err := container.Start(ctx); err != nil {
 					logrus.Errorf("Failed to start container %s: %s", container.ID, err)
 					logrus.Errorf("Failed to start container %s: %s", container.ID, err)
 				}
 				}
 			}
 			}
@@ -365,7 +363,7 @@ func (daemon *Daemon) mergeAndVerifyConfig(config *runconfig.Config, img *image.
 	return nil
 	return nil
 }
 }
 
 
-func (daemon *Daemon) generateIDAndName(name string) (string, string, error) {
+func (daemon *Daemon) generateIDAndName(ctx context.Context, name string) (string, string, error) {
 	var (
 	var (
 		err error
 		err error
 		id  = stringid.GenerateNonCryptoID()
 		id  = stringid.GenerateNonCryptoID()
@@ -378,14 +376,14 @@ func (daemon *Daemon) generateIDAndName(name string) (string, string, error) {
 		return id, name, nil
 		return id, name, nil
 	}
 	}
 
 
-	if name, err = daemon.reserveName(id, name); err != nil {
+	if name, err = daemon.reserveName(ctx, id, name); err != nil {
 		return "", "", err
 		return "", "", err
 	}
 	}
 
 
 	return id, name, nil
 	return id, name, nil
 }
 }
 
 
-func (daemon *Daemon) reserveName(id, name string) (string, error) {
+func (daemon *Daemon) reserveName(ctx context.Context, id, name string) (string, error) {
 	if !validContainerNamePattern.MatchString(name) {
 	if !validContainerNamePattern.MatchString(name) {
 		return "", fmt.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars)
 		return "", fmt.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars)
 	}
 	}
@@ -399,7 +397,7 @@ func (daemon *Daemon) reserveName(id, name string) (string, error) {
 			return "", err
 			return "", err
 		}
 		}
 
 
-		conflictingContainer, err := daemon.GetByName(name)
+		conflictingContainer, err := daemon.GetByName(ctx, name)
 		if err != nil {
 		if err != nil {
 			if strings.Contains(err.Error(), "Could not find entity") {
 			if strings.Contains(err.Error(), "Could not find entity") {
 				return "", err
 				return "", err
@@ -469,12 +467,12 @@ func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint *stringutils.StrSlic
 	return entrypoint, args
 	return entrypoint, args
 }
 }
 
 
-func (daemon *Daemon) newContainer(name string, config *runconfig.Config, imgID string) (*Container, error) {
+func (daemon *Daemon) newContainer(ctx context.Context, name string, config *runconfig.Config, imgID string) (*Container, error) {
 	var (
 	var (
 		id  string
 		id  string
 		err error
 		err error
 	)
 	)
-	id, name, err = daemon.generateIDAndName(name)
+	id, name, err = daemon.generateIDAndName(ctx, name)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -511,7 +509,7 @@ func GetFullContainerName(name string) (string, error) {
 }
 }
 
 
 // GetByName returns a container given a name.
 // GetByName returns a container given a name.
-func (daemon *Daemon) GetByName(name string) (*Container, error) {
+func (daemon *Daemon) GetByName(ctx context.Context, name string) (*Container, error) {
 	fullName, err := GetFullContainerName(name)
 	fullName, err := GetFullContainerName(name)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -530,7 +528,7 @@ func (daemon *Daemon) GetByName(name string) (*Container, error) {
 // children returns all child containers of the container with the
 // children returns all child containers of the container with the
 // given name. The containers are returned as a map from the container
 // given name. The containers are returned as a map from the container
 // name to a pointer to Container.
 // name to a pointer to Container.
-func (daemon *Daemon) children(name string) (map[string]*Container, error) {
+func (daemon *Daemon) children(ctx context.Context, name string) (map[string]*Container, error) {
 	name, err := GetFullContainerName(name)
 	name, err := GetFullContainerName(name)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -538,7 +536,7 @@ func (daemon *Daemon) children(name string) (map[string]*Container, error) {
 	children := make(map[string]*Container)
 	children := make(map[string]*Container)
 
 
 	err = daemon.containerGraphDB.Walk(name, func(p string, e *graphdb.Entity) error {
 	err = daemon.containerGraphDB.Walk(name, func(p string, e *graphdb.Entity) error {
-		c, err := daemon.Get(e.ID())
+		c, err := daemon.Get(ctx, e.ID())
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
@@ -574,7 +572,7 @@ func (daemon *Daemon) registerLink(parent, child *Container, alias string) error
 
 
 // NewDaemon sets up everything for the daemon to be able to service
 // NewDaemon sets up everything for the daemon to be able to service
 // requests from the webserver.
 // requests from the webserver.
-func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemon, err error) {
+func NewDaemon(ctx context.Context, config *Config, registryService *registry.Service) (daemon *Daemon, err error) {
 	setDefaultMtu(config)
 	setDefaultMtu(config)
 
 
 	// Ensure we have compatible configuration options
 	// Ensure we have compatible configuration options
@@ -642,7 +640,7 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo
 	// Ensure the graph driver is shutdown at a later point
 	// Ensure the graph driver is shutdown at a later point
 	defer func() {
 	defer func() {
 		if err != nil {
 		if err != nil {
-			if err := d.Shutdown(); err != nil {
+			if err := d.Shutdown(ctx); err != nil {
 				logrus.Error(err)
 				logrus.Error(err)
 			}
 			}
 		}
 		}
@@ -776,7 +774,7 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo
 
 
 	go d.execCommandGC()
 	go d.execCommandGC()
 
 
-	if err := d.restore(); err != nil {
+	if err := d.restore(ctx); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
@@ -784,12 +782,12 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo
 }
 }
 
 
 // Shutdown stops the daemon.
 // Shutdown stops the daemon.
-func (daemon *Daemon) Shutdown() error {
+func (daemon *Daemon) Shutdown(ctx context.Context) error {
 	daemon.shutdown = true
 	daemon.shutdown = true
 	if daemon.containers != nil {
 	if daemon.containers != nil {
 		group := sync.WaitGroup{}
 		group := sync.WaitGroup{}
 		logrus.Debug("starting clean shutdown of all containers...")
 		logrus.Debug("starting clean shutdown of all containers...")
-		for _, container := range daemon.List() {
+		for _, container := range daemon.List(ctx) {
 			c := container
 			c := container
 			if c.IsRunning() {
 			if c.IsRunning() {
 				logrus.Debugf("stopping %s", c.ID)
 				logrus.Debugf("stopping %s", c.ID)
@@ -812,7 +810,7 @@ func (daemon *Daemon) Shutdown() error {
 							logrus.Debugf("sending SIGTERM to container %s with error: %v", c.ID, err)
 							logrus.Debugf("sending SIGTERM to container %s with error: %v", c.ID, err)
 							return
 							return
 						}
 						}
-						if err := c.unpause(); err != nil {
+						if err := c.unpause(ctx); err != nil {
 							logrus.Debugf("Failed to unpause container %s with error: %v", c.ID, err)
 							logrus.Debugf("Failed to unpause container %s with error: %v", c.ID, err)
 							return
 							return
 						}
 						}
@@ -827,7 +825,7 @@ func (daemon *Daemon) Shutdown() error {
 						}
 						}
 					} else {
 					} else {
 						// If container failed to exit in 10 seconds of SIGTERM, then using the force
 						// If container failed to exit in 10 seconds of SIGTERM, then using the force
-						if err := c.Stop(10); err != nil {
+						if err := c.Stop(ctx, 10); err != nil {
 							logrus.Errorf("Stop container %s with error: %v", c.ID, err)
 							logrus.Errorf("Stop container %s with error: %v", c.ID, err)
 						}
 						}
 					}
 					}
@@ -865,7 +863,7 @@ func (daemon *Daemon) Shutdown() error {
 
 
 // Mount sets container.basefs
 // Mount sets container.basefs
 // (is it not set coming in? why is it unset?)
 // (is it not set coming in? why is it unset?)
-func (daemon *Daemon) Mount(container *Container) error {
+func (daemon *Daemon) Mount(ctx context.Context, container *Container) error {
 	dir, err := daemon.driver.Get(container.ID, container.getMountLabel())
 	dir, err := daemon.driver.Get(container.ID, container.getMountLabel())
 	if err != nil {
 	if err != nil {
 		return fmt.Errorf("Error getting container %s from driver %s: %s", container.ID, daemon.driver, err)
 		return fmt.Errorf("Error getting container %s from driver %s: %s", container.ID, daemon.driver, err)
@@ -890,14 +888,14 @@ func (daemon *Daemon) unmount(container *Container) error {
 	return nil
 	return nil
 }
 }
 
 
-func (daemon *Daemon) run(c *Container, pipes *execdriver.Pipes, startCallback execdriver.DriverCallback) (execdriver.ExitStatus, error) {
+func (daemon *Daemon) run(ctx context.Context, c *Container, pipes *execdriver.Pipes, startCallback execdriver.DriverCallback) (execdriver.ExitStatus, error) {
 	hooks := execdriver.Hooks{
 	hooks := execdriver.Hooks{
 		Start: startCallback,
 		Start: startCallback,
 	}
 	}
-	hooks.PreStart = append(hooks.PreStart, func(processConfig *execdriver.ProcessConfig, pid int, chOOM <-chan struct{}) error {
+	hooks.PreStart = append(hooks.PreStart, func(ctx context.Context, processConfig *execdriver.ProcessConfig, pid int, chOOM <-chan struct{}) error {
 		return c.setNetworkNamespaceKey(pid)
 		return c.setNetworkNamespaceKey(pid)
 	})
 	})
-	return daemon.execDriver.Run(c.command, pipes, hooks)
+	return daemon.execDriver.Run(ctx, c.command, pipes, hooks)
 }
 }
 
 
 func (daemon *Daemon) kill(c *Container, sig int) error {
 func (daemon *Daemon) kill(c *Container, sig int) error {
@@ -964,12 +962,12 @@ func (daemon *Daemon) createRootfs(container *Container) error {
 // which need direct access to daemon.graph.
 // which need direct access to daemon.graph.
 // Once the tests switch to using engine and jobs, this method
 // Once the tests switch to using engine and jobs, this method
 // can go away.
 // can go away.
-func (daemon *Daemon) Graph() *graph.Graph {
+func (daemon *Daemon) Graph(ctx context.Context) *graph.Graph {
 	return daemon.graph
 	return daemon.graph
 }
 }
 
 
 // Repositories returns all repositories.
 // Repositories returns all repositories.
-func (daemon *Daemon) Repositories() *graph.TagStore {
+func (daemon *Daemon) Repositories(ctx context.Context) *graph.TagStore {
 	return daemon.repositories
 	return daemon.repositories
 }
 }
 
 
@@ -983,13 +981,13 @@ func (daemon *Daemon) systemInitPath() string {
 
 
 // GraphDriver returns the currently used driver for processing
 // GraphDriver returns the currently used driver for processing
 // container layers.
 // container layers.
-func (daemon *Daemon) GraphDriver() graphdriver.Driver {
+func (daemon *Daemon) GraphDriver(ctx context.Context) graphdriver.Driver {
 	return daemon.driver
 	return daemon.driver
 }
 }
 
 
 // ExecutionDriver returns the currently used driver for creating and
 // ExecutionDriver returns the currently used driver for creating and
 // starting execs in a container.
 // starting execs in a container.
-func (daemon *Daemon) ExecutionDriver() execdriver.Driver {
+func (daemon *Daemon) ExecutionDriver(ctx context.Context) execdriver.Driver {
 	return daemon.execDriver
 	return daemon.execDriver
 }
 }
 
 
@@ -1001,9 +999,9 @@ func (daemon *Daemon) containerGraph() *graphdb.Database {
 // of the image with imgID, that had the same config when it was
 // of the image with imgID, that had the same config when it was
 // created. nil is returned if a child cannot be found. An error is
 // created. nil is returned if a child cannot be found. An error is
 // returned if the parent image cannot be found.
 // returned if the parent image cannot be found.
-func (daemon *Daemon) ImageGetCached(imgID string, config *runconfig.Config) (*image.Image, error) {
+func (daemon *Daemon) ImageGetCached(ctx context.Context, imgID string, config *runconfig.Config) (*image.Image, error) {
 	// Retrieve all images
 	// Retrieve all images
-	images := daemon.Graph().Map()
+	images := daemon.Graph(ctx).Map()
 
 
 	// Store the tree in a map of map (map[parentId][childId])
 	// Store the tree in a map of map (map[parentId][childId])
 	imageMap := make(map[string]map[string]struct{})
 	imageMap := make(map[string]map[string]struct{})
@@ -1039,7 +1037,7 @@ func tempDir(rootDir string) (string, error) {
 	return tmpDir, system.MkdirAll(tmpDir, 0700)
 	return tmpDir, system.MkdirAll(tmpDir, 0700)
 }
 }
 
 
-func (daemon *Daemon) setHostConfig(container *Container, hostConfig *runconfig.HostConfig) error {
+func (daemon *Daemon) setHostConfig(ctx context.Context, container *Container, hostConfig *runconfig.HostConfig) error {
 	container.Lock()
 	container.Lock()
 	if err := parseSecurityOpt(container, hostConfig); err != nil {
 	if err := parseSecurityOpt(container, hostConfig); err != nil {
 		container.Unlock()
 		container.Unlock()
@@ -1049,14 +1047,14 @@ func (daemon *Daemon) setHostConfig(container *Container, hostConfig *runconfig.
 
 
 	// Do not lock while creating volumes since this could be calling out to external plugins
 	// Do not lock while creating volumes since this could be calling out to external plugins
 	// Don't want to block other actions, like `docker ps` because we're waiting on an external plugin
 	// Don't want to block other actions, like `docker ps` because we're waiting on an external plugin
-	if err := daemon.registerMountPoints(container, hostConfig); err != nil {
+	if err := daemon.registerMountPoints(ctx, container, hostConfig); err != nil {
 		return err
 		return err
 	}
 	}
 
 
 	container.Lock()
 	container.Lock()
 	defer container.Unlock()
 	defer container.Unlock()
 	// Register any links from the host config before starting the container
 	// Register any links from the host config before starting the container
-	if err := daemon.registerLinks(container, hostConfig); err != nil {
+	if err := daemon.registerLinks(ctx, container, hostConfig); err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -1094,7 +1092,7 @@ func getDefaultRouteMtu() (int, error) {
 
 
 // verifyContainerSettings performs validation of the hostconfig and config
 // verifyContainerSettings performs validation of the hostconfig and config
 // structures.
 // structures.
-func (daemon *Daemon) verifyContainerSettings(hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) {
+func (daemon *Daemon) verifyContainerSettings(ctx context.Context, hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) {
 
 
 	// First perform verification of settings common across all platforms.
 	// First perform verification of settings common across all platforms.
 	if config != nil {
 	if config != nil {
@@ -1131,7 +1129,7 @@ func (daemon *Daemon) verifyContainerSettings(hostConfig *runconfig.HostConfig,
 	}
 	}
 
 
 	// Now do platform-specific verification
 	// Now do platform-specific verification
-	return verifyPlatformContainerSettings(daemon, hostConfig, config)
+	return verifyPlatformContainerSettings(ctx, daemon, hostConfig, config)
 }
 }
 
 
 func configureVolumes(config *Config) (*store.VolumeStore, error) {
 func configureVolumes(config *Config) (*store.VolumeStore, error) {

+ 14 - 9
daemon/daemon_test.go

@@ -8,6 +8,7 @@ import (
 	"path/filepath"
 	"path/filepath"
 	"testing"
 	"testing"
 
 
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/pkg/graphdb"
 	"github.com/docker/docker/pkg/graphdb"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/pkg/truncindex"
 	"github.com/docker/docker/pkg/truncindex"
@@ -92,32 +93,34 @@ func TestGet(t *testing.T) {
 		containerGraphDB: graph,
 		containerGraphDB: graph,
 	}
 	}
 
 
-	if container, _ := daemon.Get("3cdbd1aa394fd68559fd1441d6eff2ab7c1e6363582c82febfaa8045df3bd8de"); container != c2 {
+	ctx := context.Background()
+
+	if container, _ := daemon.Get(ctx, "3cdbd1aa394fd68559fd1441d6eff2ab7c1e6363582c82febfaa8045df3bd8de"); container != c2 {
 		t.Fatal("Should explicitly match full container IDs")
 		t.Fatal("Should explicitly match full container IDs")
 	}
 	}
 
 
-	if container, _ := daemon.Get("75fb0b8009"); container != c4 {
+	if container, _ := daemon.Get(ctx, "75fb0b8009"); container != c4 {
 		t.Fatal("Should match a partial ID")
 		t.Fatal("Should match a partial ID")
 	}
 	}
 
 
-	if container, _ := daemon.Get("drunk_hawking"); container != c2 {
+	if container, _ := daemon.Get(ctx, "drunk_hawking"); container != c2 {
 		t.Fatal("Should match a full name")
 		t.Fatal("Should match a full name")
 	}
 	}
 
 
 	// c3.Name is a partial match for both c3.ID and c2.ID
 	// c3.Name is a partial match for both c3.ID and c2.ID
-	if c, _ := daemon.Get("3cdbd1aa"); c != c3 {
+	if c, _ := daemon.Get(ctx, "3cdbd1aa"); c != c3 {
 		t.Fatal("Should match a full name even though it collides with another container's ID")
 		t.Fatal("Should match a full name even though it collides with another container's ID")
 	}
 	}
 
 
-	if container, _ := daemon.Get("d22d69a2b896"); container != c5 {
+	if container, _ := daemon.Get(ctx, "d22d69a2b896"); container != c5 {
 		t.Fatal("Should match a container where the provided prefix is an exact match to the it's name, and is also a prefix for it's ID")
 		t.Fatal("Should match a container where the provided prefix is an exact match to the it's name, and is also a prefix for it's ID")
 	}
 	}
 
 
-	if _, err := daemon.Get("3cdbd1"); err == nil {
+	if _, err := daemon.Get(ctx, "3cdbd1"); err == nil {
 		t.Fatal("Should return an error when provided a prefix that partially matches multiple container ID's")
 		t.Fatal("Should return an error when provided a prefix that partially matches multiple container ID's")
 	}
 	}
 
 
-	if _, err := daemon.Get("nothing"); err == nil {
+	if _, err := daemon.Get(ctx, "nothing"); err == nil {
 		t.Fatal("Should return an error when provided a prefix that is neither a name or a partial match to an ID")
 		t.Fatal("Should return an error when provided a prefix that is neither a name or a partial match to an ID")
 	}
 	}
 
 
@@ -486,13 +489,15 @@ func TestRemoveLocalVolumesFollowingSymlinks(t *testing.T) {
 		t.Fatalf("Expected 1 volume mounted, was 0\n")
 		t.Fatalf("Expected 1 volume mounted, was 0\n")
 	}
 	}
 
 
+	ctx := context.Background()
+
 	m := c.MountPoints["/vol1"]
 	m := c.MountPoints["/vol1"]
-	_, err = daemon.VolumeCreate(m.Name, m.Driver, nil)
+	_, err = daemon.VolumeCreate(ctx, m.Name, m.Driver, nil)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	if err := daemon.VolumeRm(m.Name); err != nil {
+	if err := daemon.VolumeRm(ctx, m.Name); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 

+ 8 - 7
daemon/daemon_unix.go

@@ -13,6 +13,7 @@ import (
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/autogen/dockerversion"
 	"github.com/docker/docker/autogen/dockerversion"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/docker/docker/pkg/fileutils"
 	"github.com/docker/docker/pkg/fileutils"
 	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/pkg/parsers"
@@ -114,12 +115,12 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *runconfig.HostConfig, a
 
 
 // verifyPlatformContainerSettings performs platform-specific validation of the
 // verifyPlatformContainerSettings performs platform-specific validation of the
 // hostconfig and config structures.
 // hostconfig and config structures.
-func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) {
+func verifyPlatformContainerSettings(ctx context.Context, daemon *Daemon, hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) {
 	warnings := []string{}
 	warnings := []string{}
 	sysInfo := sysinfo.New(true)
 	sysInfo := sysinfo.New(true)
 
 
-	if hostConfig.LxcConf.Len() > 0 && !strings.Contains(daemon.ExecutionDriver().Name(), "lxc") {
-		return warnings, fmt.Errorf("Cannot use --lxc-conf with execdriver: %s", daemon.ExecutionDriver().Name())
+	if hostConfig.LxcConf.Len() > 0 && !strings.Contains(daemon.ExecutionDriver(ctx).Name(), "lxc") {
+		return warnings, fmt.Errorf("Cannot use --lxc-conf with execdriver: %s", daemon.ExecutionDriver(ctx).Name())
 	}
 	}
 
 
 	// memory subsystem checks and adjustments
 	// memory subsystem checks and adjustments
@@ -484,12 +485,12 @@ func setupInitLayer(initLayer string) error {
 
 
 // NetworkAPIRouter implements a feature for server-experimental,
 // NetworkAPIRouter implements a feature for server-experimental,
 // directly calling into libnetwork.
 // directly calling into libnetwork.
-func (daemon *Daemon) NetworkAPIRouter() func(w http.ResponseWriter, req *http.Request) {
+func (daemon *Daemon) NetworkAPIRouter(ctx context.Context) func(w http.ResponseWriter, req *http.Request) {
 	return nwapi.NewHTTPHandler(daemon.netController)
 	return nwapi.NewHTTPHandler(daemon.netController)
 }
 }
 
 
 // registerLinks writes the links to a file.
 // registerLinks writes the links to a file.
-func (daemon *Daemon) registerLinks(container *Container, hostConfig *runconfig.HostConfig) error {
+func (daemon *Daemon) registerLinks(ctx context.Context, container *Container, hostConfig *runconfig.HostConfig) error {
 	if hostConfig == nil || hostConfig.Links == nil {
 	if hostConfig == nil || hostConfig.Links == nil {
 		return nil
 		return nil
 	}
 	}
@@ -499,14 +500,14 @@ func (daemon *Daemon) registerLinks(container *Container, hostConfig *runconfig.
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
-		child, err := daemon.Get(name)
+		child, err := daemon.Get(ctx, name)
 		if err != nil {
 		if err != nil {
 			//An error from daemon.Get() means this name could not be found
 			//An error from daemon.Get() means this name could not be found
 			return fmt.Errorf("Could not get container for %s", name)
 			return fmt.Errorf("Could not get container for %s", name)
 		}
 		}
 		for child.hostConfig.NetworkMode.IsContainer() {
 		for child.hostConfig.NetworkMode.IsContainer() {
 			parts := strings.SplitN(string(child.hostConfig.NetworkMode), ":", 2)
 			parts := strings.SplitN(string(child.hostConfig.NetworkMode), ":", 2)
-			child, err = daemon.Get(parts[1])
+			child, err = daemon.Get(ctx, parts[1])
 			if err != nil {
 			if err != nil {
 				return fmt.Errorf("Could not get container for %s", parts[1])
 				return fmt.Errorf("Could not get container for %s", parts[1])
 			}
 			}

+ 4 - 3
daemon/daemon_windows.go

@@ -6,6 +6,7 @@ import (
 	"syscall"
 	"syscall"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/docker/docker/daemon/graphdriver"
 	// register the windows graph driver
 	// register the windows graph driver
 	_ "github.com/docker/docker/daemon/graphdriver/windows"
 	_ "github.com/docker/docker/daemon/graphdriver/windows"
@@ -47,7 +48,7 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *runconfig.HostConfig, a
 
 
 // verifyPlatformContainerSettings performs platform-specific validation of the
 // verifyPlatformContainerSettings performs platform-specific validation of the
 // hostconfig and config structures.
 // hostconfig and config structures.
-func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) {
+func verifyPlatformContainerSettings(ctx context.Context, daemon *Daemon, hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) {
 	return nil, nil
 	return nil, nil
 }
 }
 
 
@@ -104,7 +105,7 @@ func initNetworkController(config *Config) (libnetwork.NetworkController, error)
 
 
 // registerLinks sets up links between containers and writes the
 // registerLinks sets up links between containers and writes the
 // configuration out for persistence.
 // configuration out for persistence.
-func (daemon *Daemon) registerLinks(container *Container, hostConfig *runconfig.HostConfig) error {
+func (daemon *Daemon) registerLinks(ctx context.Context, container *Container, hostConfig *runconfig.HostConfig) error {
 	// TODO Windows. Factored out for network modes. There may be more
 	// TODO Windows. Factored out for network modes. There may be more
 	// refactoring required here.
 	// refactoring required here.
 
 
@@ -117,7 +118,7 @@ func (daemon *Daemon) registerLinks(container *Container, hostConfig *runconfig.
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
-		child, err := daemon.Get(name)
+		child, err := daemon.Get(ctx, name)
 		if err != nil {
 		if err != nil {
 			//An error from daemon.Get() means this name could not be found
 			//An error from daemon.Get() means this name could not be found
 			return fmt.Errorf("Could not get container for %s", name)
 			return fmt.Errorf("Could not get container for %s", name)

+ 13 - 11
daemon/delete.go

@@ -5,6 +5,8 @@ import (
 	"os"
 	"os"
 	"path"
 	"path"
 
 
+	"github.com/docker/docker/context"
+
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
 	derr "github.com/docker/docker/errors"
 	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/volume/store"
 	"github.com/docker/docker/volume/store"
@@ -19,8 +21,8 @@ type ContainerRmConfig struct {
 // is returned if the container is not found, or if the remove
 // is returned if the container is not found, or if the remove
 // fails. If the remove succeeds, the container name is released, and
 // fails. If the remove succeeds, the container name is released, and
 // network links are removed.
 // network links are removed.
-func (daemon *Daemon) ContainerRm(name string, config *ContainerRmConfig) error {
-	container, err := daemon.Get(name)
+func (daemon *Daemon) ContainerRm(ctx context.Context, name string, config *ContainerRmConfig) error {
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -43,9 +45,9 @@ func (daemon *Daemon) ContainerRm(name string, config *ContainerRmConfig) error
 			return err
 			return err
 		}
 		}
 
 
-		parentContainer, _ := daemon.Get(pe.ID())
+		parentContainer, _ := daemon.Get(ctx, pe.ID())
 		if parentContainer != nil {
 		if parentContainer != nil {
-			if err := parentContainer.updateNetwork(); err != nil {
+			if err := parentContainer.updateNetwork(ctx); err != nil {
 				logrus.Debugf("Could not update network to remove link %s: %v", n, err)
 				logrus.Debugf("Could not update network to remove link %s: %v", n, err)
 			}
 			}
 		}
 		}
@@ -53,7 +55,7 @@ func (daemon *Daemon) ContainerRm(name string, config *ContainerRmConfig) error
 		return nil
 		return nil
 	}
 	}
 
 
-	if err := daemon.rm(container, config.ForceRemove); err != nil {
+	if err := daemon.rm(ctx, container, config.ForceRemove); err != nil {
 		// return derr.ErrorCodeCantDestroy.WithArgs(name, utils.GetErrorMessage(err))
 		// return derr.ErrorCodeCantDestroy.WithArgs(name, utils.GetErrorMessage(err))
 		return err
 		return err
 	}
 	}
@@ -66,12 +68,12 @@ func (daemon *Daemon) ContainerRm(name string, config *ContainerRmConfig) error
 }
 }
 
 
 // Destroy unregisters a container from the daemon and cleanly removes its contents from the filesystem.
 // Destroy unregisters a container from the daemon and cleanly removes its contents from the filesystem.
-func (daemon *Daemon) rm(container *Container, forceRemove bool) (err error) {
+func (daemon *Daemon) rm(ctx context.Context, container *Container, forceRemove bool) (err error) {
 	if container.IsRunning() {
 	if container.IsRunning() {
 		if !forceRemove {
 		if !forceRemove {
 			return derr.ErrorCodeRmRunning
 			return derr.ErrorCodeRmRunning
 		}
 		}
-		if err := container.Kill(); err != nil {
+		if err := container.Kill(ctx); err != nil {
 			return derr.ErrorCodeRmFailed.WithArgs(err)
 			return derr.ErrorCodeRmFailed.WithArgs(err)
 		}
 		}
 	}
 	}
@@ -92,7 +94,7 @@ func (daemon *Daemon) rm(container *Container, forceRemove bool) (err error) {
 
 
 	defer container.resetRemovalInProgress()
 	defer container.resetRemovalInProgress()
 
 
-	if err = container.Stop(3); err != nil {
+	if err = container.Stop(ctx, 3); err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -113,7 +115,7 @@ func (daemon *Daemon) rm(container *Container, forceRemove bool) (err error) {
 			daemon.idIndex.Delete(container.ID)
 			daemon.idIndex.Delete(container.ID)
 			daemon.containers.Delete(container.ID)
 			daemon.containers.Delete(container.ID)
 			os.RemoveAll(container.root)
 			os.RemoveAll(container.root)
-			container.logEvent("destroy")
+			container.logEvent(ctx, "destroy")
 		}
 		}
 	}()
 	}()
 
 
@@ -142,14 +144,14 @@ func (daemon *Daemon) rm(container *Container, forceRemove bool) (err error) {
 	daemon.idIndex.Delete(container.ID)
 	daemon.idIndex.Delete(container.ID)
 	daemon.containers.Delete(container.ID)
 	daemon.containers.Delete(container.ID)
 
 
-	container.logEvent("destroy")
+	container.logEvent(ctx, "destroy")
 	return nil
 	return nil
 }
 }
 
 
 // VolumeRm removes the volume with the given name.
 // VolumeRm removes the volume with the given name.
 // If the volume is referenced by a container it is not removed
 // If the volume is referenced by a container it is not removed
 // This is called directly from the remote API
 // This is called directly from the remote API
-func (daemon *Daemon) VolumeRm(name string) error {
+func (daemon *Daemon) VolumeRm(ctx context.Context, name string) error {
 	v, err := daemon.volumes.Get(name)
 	v, err := daemon.volumes.Get(name)
 	if err != nil {
 	if err != nil {
 		return err
 		return err

+ 4 - 2
daemon/events/events.go

@@ -4,6 +4,8 @@ import (
 	"sync"
 	"sync"
 	"time"
 	"time"
 
 
+	"github.com/docker/docker/context"
+
 	"github.com/docker/docker/pkg/jsonmessage"
 	"github.com/docker/docker/pkg/jsonmessage"
 	"github.com/docker/docker/pkg/pubsub"
 	"github.com/docker/docker/pkg/pubsub"
 )
 )
@@ -44,9 +46,9 @@ func (e *Events) Evict(l chan interface{}) {
 
 
 // Log broadcasts event to listeners. Each listener has 100 millisecond for
 // Log broadcasts event to listeners. Each listener has 100 millisecond for
 // receiving event or it will be skipped.
 // receiving event or it will be skipped.
-func (e *Events) Log(action, id, from string) {
+func (e *Events) Log(ctx context.Context, action, id, from string) {
 	now := time.Now().UTC()
 	now := time.Now().UTC()
-	jm := &jsonmessage.JSONMessage{Status: action, ID: id, From: from, Time: now.Unix(), TimeNano: now.UnixNano()}
+	jm := &jsonmessage.JSONMessage{RequestID: ctx.RequestID(), Status: action, ID: id, From: from, Time: now.Unix(), TimeNano: now.UnixNano()}
 	e.mu.Lock()
 	e.mu.Lock()
 	if len(e.events) == cap(e.events) {
 	if len(e.events) == cap(e.events) {
 		// discard oldest event
 		// discard oldest event

+ 8 - 4
daemon/events/events_test.go

@@ -5,10 +5,12 @@ import (
 	"testing"
 	"testing"
 	"time"
 	"time"
 
 
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/pkg/jsonmessage"
 	"github.com/docker/docker/pkg/jsonmessage"
 )
 )
 
 
 func TestEventsLog(t *testing.T) {
 func TestEventsLog(t *testing.T) {
+	ctx := context.Background()
 	e := New()
 	e := New()
 	_, l1 := e.Subscribe()
 	_, l1 := e.Subscribe()
 	_, l2 := e.Subscribe()
 	_, l2 := e.Subscribe()
@@ -18,7 +20,7 @@ func TestEventsLog(t *testing.T) {
 	if count != 2 {
 	if count != 2 {
 		t.Fatalf("Must be 2 subscribers, got %d", count)
 		t.Fatalf("Must be 2 subscribers, got %d", count)
 	}
 	}
-	e.Log("test", "cont", "image")
+	e.Log(ctx, "test", "cont", "image")
 	select {
 	select {
 	case msg := <-l1:
 	case msg := <-l1:
 		jmsg, ok := msg.(*jsonmessage.JSONMessage)
 		jmsg, ok := msg.(*jsonmessage.JSONMessage)
@@ -64,13 +66,14 @@ func TestEventsLog(t *testing.T) {
 }
 }
 
 
 func TestEventsLogTimeout(t *testing.T) {
 func TestEventsLogTimeout(t *testing.T) {
+	ctx := context.Background()
 	e := New()
 	e := New()
 	_, l := e.Subscribe()
 	_, l := e.Subscribe()
 	defer e.Evict(l)
 	defer e.Evict(l)
 
 
 	c := make(chan struct{})
 	c := make(chan struct{})
 	go func() {
 	go func() {
-		e.Log("test", "cont", "image")
+		e.Log(ctx, "test", "cont", "image")
 		close(c)
 		close(c)
 	}()
 	}()
 
 
@@ -82,13 +85,14 @@ func TestEventsLogTimeout(t *testing.T) {
 }
 }
 
 
 func TestLogEvents(t *testing.T) {
 func TestLogEvents(t *testing.T) {
+	ctx := context.Background()
 	e := New()
 	e := New()
 
 
 	for i := 0; i < eventsLimit+16; i++ {
 	for i := 0; i < eventsLimit+16; i++ {
 		action := fmt.Sprintf("action_%d", i)
 		action := fmt.Sprintf("action_%d", i)
 		id := fmt.Sprintf("cont_%d", i)
 		id := fmt.Sprintf("cont_%d", i)
 		from := fmt.Sprintf("image_%d", i)
 		from := fmt.Sprintf("image_%d", i)
-		e.Log(action, id, from)
+		e.Log(ctx, action, id, from)
 	}
 	}
 	time.Sleep(50 * time.Millisecond)
 	time.Sleep(50 * time.Millisecond)
 	current, l := e.Subscribe()
 	current, l := e.Subscribe()
@@ -97,7 +101,7 @@ func TestLogEvents(t *testing.T) {
 		action := fmt.Sprintf("action_%d", num)
 		action := fmt.Sprintf("action_%d", num)
 		id := fmt.Sprintf("cont_%d", num)
 		id := fmt.Sprintf("cont_%d", num)
 		from := fmt.Sprintf("image_%d", num)
 		from := fmt.Sprintf("image_%d", num)
-		e.Log(action, id, from)
+		e.Log(ctx, action, id, from)
 	}
 	}
 	if len(e.events) != eventsLimit {
 	if len(e.events) != eventsLimit {
 		t.Fatalf("Must be %d events, got %d", eventsLimit, len(e.events))
 		t.Fatalf("Must be %d events, got %d", eventsLimit, len(e.events))

+ 11 - 10
daemon/exec.go

@@ -8,6 +8,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/execdriver"
 	derr "github.com/docker/docker/errors"
 	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/broadcastwriter"
 	"github.com/docker/docker/pkg/broadcastwriter"
@@ -117,8 +118,8 @@ func (d *Daemon) unregisterExecCommand(ExecConfig *ExecConfig) {
 	d.execCommands.Delete(ExecConfig.ID)
 	d.execCommands.Delete(ExecConfig.ID)
 }
 }
 
 
-func (d *Daemon) getActiveContainer(name string) (*Container, error) {
-	container, err := d.Get(name)
+func (d *Daemon) getActiveContainer(ctx context.Context, name string) (*Container, error) {
+	container, err := d.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -133,13 +134,13 @@ func (d *Daemon) getActiveContainer(name string) (*Container, error) {
 }
 }
 
 
 // ContainerExecCreate sets up an exec in a running container.
 // ContainerExecCreate sets up an exec in a running container.
-func (d *Daemon) ContainerExecCreate(config *runconfig.ExecConfig) (string, error) {
+func (d *Daemon) ContainerExecCreate(ctx context.Context, config *runconfig.ExecConfig) (string, error) {
 	// Not all drivers support Exec (LXC for example)
 	// Not all drivers support Exec (LXC for example)
 	if err := checkExecSupport(d.execDriver.Name()); err != nil {
 	if err := checkExecSupport(d.execDriver.Name()); err != nil {
 		return "", err
 		return "", err
 	}
 	}
 
 
-	container, err := d.getActiveContainer(config.Container)
+	container, err := d.getActiveContainer(ctx, config.Container)
 	if err != nil {
 	if err != nil {
 		return "", err
 		return "", err
 	}
 	}
@@ -174,14 +175,14 @@ func (d *Daemon) ContainerExecCreate(config *runconfig.ExecConfig) (string, erro
 
 
 	d.registerExecCommand(ExecConfig)
 	d.registerExecCommand(ExecConfig)
 
 
-	container.logEvent("exec_create: " + ExecConfig.ProcessConfig.Entrypoint + " " + strings.Join(ExecConfig.ProcessConfig.Arguments, " "))
+	container.logEvent(ctx, "exec_create: "+ExecConfig.ProcessConfig.Entrypoint+" "+strings.Join(ExecConfig.ProcessConfig.Arguments, " "))
 
 
 	return ExecConfig.ID, nil
 	return ExecConfig.ID, nil
 }
 }
 
 
 // ContainerExecStart starts a previously set up exec instance. The
 // ContainerExecStart starts a previously set up exec instance. The
 // std streams are set up.
 // std streams are set up.
-func (d *Daemon) ContainerExecStart(execName string, stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) error {
+func (d *Daemon) ContainerExecStart(ctx context.Context, execName string, stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) error {
 	var (
 	var (
 		cStdin           io.ReadCloser
 		cStdin           io.ReadCloser
 		cStdout, cStderr io.Writer
 		cStdout, cStderr io.Writer
@@ -207,7 +208,7 @@ func (d *Daemon) ContainerExecStart(execName string, stdin io.ReadCloser, stdout
 	logrus.Debugf("starting exec command %s in container %s", ExecConfig.ID, ExecConfig.Container.ID)
 	logrus.Debugf("starting exec command %s in container %s", ExecConfig.ID, ExecConfig.Container.ID)
 	container := ExecConfig.Container
 	container := ExecConfig.Container
 
 
-	container.logEvent("exec_start: " + ExecConfig.ProcessConfig.Entrypoint + " " + strings.Join(ExecConfig.ProcessConfig.Arguments, " "))
+	container.logEvent(ctx, "exec_start: "+ExecConfig.ProcessConfig.Entrypoint+" "+strings.Join(ExecConfig.ProcessConfig.Arguments, " "))
 
 
 	if ExecConfig.OpenStdin {
 	if ExecConfig.OpenStdin {
 		r, w := io.Pipe()
 		r, w := io.Pipe()
@@ -243,7 +244,7 @@ func (d *Daemon) ContainerExecStart(execName string, stdin io.ReadCloser, stdout
 	// the exitStatus) even after the cmd is done running.
 	// the exitStatus) even after the cmd is done running.
 
 
 	go func() {
 	go func() {
-		if err := container.exec(ExecConfig); err != nil {
+		if err := container.exec(ctx, ExecConfig); err != nil {
 			execErr <- derr.ErrorCodeExecCantRun.WithArgs(execName, container.ID, err)
 			execErr <- derr.ErrorCodeExecCantRun.WithArgs(execName, container.ID, err)
 		}
 		}
 	}()
 	}()
@@ -267,11 +268,11 @@ func (d *Daemon) ContainerExecStart(execName string, stdin io.ReadCloser, stdout
 }
 }
 
 
 // Exec calls the underlying exec driver to run
 // Exec calls the underlying exec driver to run
-func (d *Daemon) Exec(c *Container, ExecConfig *ExecConfig, pipes *execdriver.Pipes, startCallback execdriver.DriverCallback) (int, error) {
+func (d *Daemon) Exec(ctx context.Context, c *Container, ExecConfig *ExecConfig, pipes *execdriver.Pipes, startCallback execdriver.DriverCallback) (int, error) {
 	hooks := execdriver.Hooks{
 	hooks := execdriver.Hooks{
 		Start: startCallback,
 		Start: startCallback,
 	}
 	}
-	exitStatus, err := d.execDriver.Exec(c.command, ExecConfig.ProcessConfig, pipes, hooks)
+	exitStatus, err := d.execDriver.Exec(ctx, c.command, ExecConfig.ProcessConfig, pipes, hooks)
 
 
 	// On err, make sure we don't leave ExitCode at zero
 	// On err, make sure we don't leave ExitCode at zero
 	if err != nil && exitStatus == 0 {
 	if err != nil && exitStatus == 0 {

+ 4 - 3
daemon/execdriver/driver.go

@@ -7,6 +7,7 @@ import (
 	"time"
 	"time"
 
 
 	// TODO Windows: Factor out ulimit
 	// TODO Windows: Factor out ulimit
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/pkg/ulimit"
 	"github.com/docker/docker/pkg/ulimit"
 	"github.com/opencontainers/runc/libcontainer"
 	"github.com/opencontainers/runc/libcontainer"
 	"github.com/opencontainers/runc/libcontainer/configs"
 	"github.com/opencontainers/runc/libcontainer/configs"
@@ -29,7 +30,7 @@ var (
 // through PreStart, Start and PostStop events.
 // through PreStart, Start and PostStop events.
 // Callbacks are provided a processConfig pointer and the pid of the child.
 // Callbacks are provided a processConfig pointer and the pid of the child.
 // The channel will be used to notify the OOM events.
 // The channel will be used to notify the OOM events.
-type DriverCallback func(processConfig *ProcessConfig, pid int, chOOM <-chan struct{}) error
+type DriverCallback func(ctx context.Context, processConfig *ProcessConfig, pid int, chOOM <-chan struct{}) error
 
 
 // Hooks is a struct containing function pointers to callbacks
 // Hooks is a struct containing function pointers to callbacks
 // used by any execdriver implementation exploiting hooks capabilities
 // used by any execdriver implementation exploiting hooks capabilities
@@ -69,11 +70,11 @@ type ExitStatus struct {
 type Driver interface {
 type Driver interface {
 	// Run executes the process, blocks until the process exits and returns
 	// Run executes the process, blocks until the process exits and returns
 	// the exit code. It's the last stage on Docker side for running a container.
 	// the exit code. It's the last stage on Docker side for running a container.
-	Run(c *Command, pipes *Pipes, hooks Hooks) (ExitStatus, error)
+	Run(ctx context.Context, c *Command, pipes *Pipes, hooks Hooks) (ExitStatus, error)
 
 
 	// Exec executes the process in an existing container, blocks until the
 	// Exec executes the process in an existing container, blocks until the
 	// process exits and returns the exit code.
 	// process exits and returns the exit code.
-	Exec(c *Command, processConfig *ProcessConfig, pipes *Pipes, hooks Hooks) (int, error)
+	Exec(ctx context.Context, c *Command, processConfig *ProcessConfig, pipes *Pipes, hooks Hooks) (int, error)
 
 
 	// Kill sends signals to process in container.
 	// Kill sends signals to process in container.
 	Kill(c *Command, sig int) error
 	Kill(c *Command, sig int) error

+ 4 - 3
daemon/execdriver/lxc/driver.go

@@ -20,6 +20,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/pkg/stringutils"
 	"github.com/docker/docker/pkg/stringutils"
 	sysinfo "github.com/docker/docker/pkg/system"
 	sysinfo "github.com/docker/docker/pkg/system"
@@ -125,7 +126,7 @@ func killNetNsProc(proc *os.Process) {
 
 
 // Run implements the exec driver Driver interface,
 // Run implements the exec driver Driver interface,
 // it calls 'exec.Cmd' to launch lxc commands to run a container.
 // it calls 'exec.Cmd' to launch lxc commands to run a container.
-func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execdriver.Hooks) (execdriver.ExitStatus, error) {
+func (d *Driver) Run(ctx context.Context, c *execdriver.Command, pipes *execdriver.Pipes, hooks execdriver.Hooks) (execdriver.ExitStatus, error) {
 	var (
 	var (
 		term     execdriver.Terminal
 		term     execdriver.Terminal
 		err      error
 		err      error
@@ -329,7 +330,7 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd
 
 
 	if hooks.Start != nil {
 	if hooks.Start != nil {
 		logrus.Debugf("Invoking startCallback")
 		logrus.Debugf("Invoking startCallback")
-		hooks.Start(&c.ProcessConfig, pid, oomKillNotification)
+		hooks.Start(ctx, &c.ProcessConfig, pid, oomKillNotification)
 
 
 	}
 	}
 
 
@@ -871,7 +872,7 @@ func (t *TtyConsole) Close() error {
 
 
 // Exec implements the exec driver Driver interface,
 // Exec implements the exec driver Driver interface,
 // it is not implemented by lxc.
 // it is not implemented by lxc.
-func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, hooks execdriver.Hooks) (int, error) {
+func (d *Driver) Exec(ctx context.Context, c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, hooks execdriver.Hooks) (int, error) {
 	return -1, ErrExec
 	return -1, ErrExec
 }
 }
 
 

+ 5 - 4
daemon/execdriver/native/create.go

@@ -9,6 +9,7 @@ import (
 	"strings"
 	"strings"
 	"syscall"
 	"syscall"
 
 
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/opencontainers/runc/libcontainer/apparmor"
 	"github.com/opencontainers/runc/libcontainer/apparmor"
 	"github.com/opencontainers/runc/libcontainer/configs"
 	"github.com/opencontainers/runc/libcontainer/configs"
@@ -18,7 +19,7 @@ import (
 
 
 // createContainer populates and configures the container type with the
 // createContainer populates and configures the container type with the
 // data provided by the execdriver.Command
 // data provided by the execdriver.Command
-func (d *Driver) createContainer(c *execdriver.Command, hooks execdriver.Hooks) (*configs.Config, error) {
+func (d *Driver) createContainer(ctx context.Context, c *execdriver.Command, hooks execdriver.Hooks) (*configs.Config, error) {
 	container := execdriver.InitContainer(c)
 	container := execdriver.InitContainer(c)
 
 
 	if err := d.createIpc(container, c); err != nil {
 	if err := d.createIpc(container, c); err != nil {
@@ -33,7 +34,7 @@ func (d *Driver) createContainer(c *execdriver.Command, hooks execdriver.Hooks)
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	if err := d.createNetwork(container, c, hooks); err != nil {
+	if err := d.createNetwork(ctx, container, c, hooks); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
@@ -113,7 +114,7 @@ func generateIfaceName() (string, error) {
 	return "", errors.New("Failed to find name for new interface")
 	return "", errors.New("Failed to find name for new interface")
 }
 }
 
 
-func (d *Driver) createNetwork(container *configs.Config, c *execdriver.Command, hooks execdriver.Hooks) error {
+func (d *Driver) createNetwork(ctx context.Context, container *configs.Config, c *execdriver.Command, hooks execdriver.Hooks) error {
 	if c.Network == nil {
 	if c.Network == nil {
 		return nil
 		return nil
 	}
 	}
@@ -150,7 +151,7 @@ func (d *Driver) createNetwork(container *configs.Config, c *execdriver.Command,
 						// non-blocking and return the correct result when read.
 						// non-blocking and return the correct result when read.
 						chOOM := make(chan struct{})
 						chOOM := make(chan struct{})
 						close(chOOM)
 						close(chOOM)
-						if err := fnHook(&c.ProcessConfig, s.Pid, chOOM); err != nil {
+						if err := fnHook(ctx, &c.ProcessConfig, s.Pid, chOOM); err != nil {
 							return err
 							return err
 						}
 						}
 					}
 					}

+ 4 - 3
daemon/execdriver/native/driver.go

@@ -14,6 +14,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/pkg/pools"
 	"github.com/docker/docker/pkg/pools"
@@ -131,9 +132,9 @@ type execOutput struct {
 
 
 // Run implements the exec driver Driver interface,
 // Run implements the exec driver Driver interface,
 // it calls libcontainer APIs to run a container.
 // it calls libcontainer APIs to run a container.
-func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execdriver.Hooks) (execdriver.ExitStatus, error) {
+func (d *Driver) Run(ctx context.Context, c *execdriver.Command, pipes *execdriver.Pipes, hooks execdriver.Hooks) (execdriver.ExitStatus, error) {
 	// take the Command and populate the libcontainer.Config from it
 	// take the Command and populate the libcontainer.Config from it
-	container, err := d.createContainer(c, hooks)
+	container, err := d.createContainer(ctx, c, hooks)
 	if err != nil {
 	if err != nil {
 		return execdriver.ExitStatus{ExitCode: -1}, err
 		return execdriver.ExitStatus{ExitCode: -1}, err
 	}
 	}
@@ -174,7 +175,7 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd
 			p.Wait()
 			p.Wait()
 			return execdriver.ExitStatus{ExitCode: -1}, err
 			return execdriver.ExitStatus{ExitCode: -1}, err
 		}
 		}
-		hooks.Start(&c.ProcessConfig, pid, oom)
+		hooks.Start(ctx, &c.ProcessConfig, pid, oom)
 	}
 	}
 
 
 	waitF := p.Wait
 	waitF := p.Wait

+ 3 - 2
daemon/execdriver/native/exec.go

@@ -8,6 +8,7 @@ import (
 	"os/exec"
 	"os/exec"
 	"syscall"
 	"syscall"
 
 
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/opencontainers/runc/libcontainer"
 	"github.com/opencontainers/runc/libcontainer"
 	// Blank import 'nsenter' so that init in that package will call c
 	// Blank import 'nsenter' so that init in that package will call c
@@ -19,7 +20,7 @@ import (
 
 
 // Exec implements the exec driver Driver interface,
 // Exec implements the exec driver Driver interface,
 // it calls libcontainer APIs to execute a container.
 // it calls libcontainer APIs to execute a container.
-func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, hooks execdriver.Hooks) (int, error) {
+func (d *Driver) Exec(ctx context.Context, c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, hooks execdriver.Hooks) (int, error) {
 	active := d.activeContainers[c.ID]
 	active := d.activeContainers[c.ID]
 	if active == nil {
 	if active == nil {
 		return -1, fmt.Errorf("No active container exists with ID %s", c.ID)
 		return -1, fmt.Errorf("No active container exists with ID %s", c.ID)
@@ -57,7 +58,7 @@ func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessCo
 		// non-blocking and return the correct result when read.
 		// non-blocking and return the correct result when read.
 		chOOM := make(chan struct{})
 		chOOM := make(chan struct{})
 		close(chOOM)
 		close(chOOM)
-		hooks.Start(&c.ProcessConfig, pid, chOOM)
+		hooks.Start(ctx, &c.ProcessConfig, pid, chOOM)
 	}
 	}
 
 
 	ps, err := p.Wait()
 	ps, err := p.Wait()

+ 3 - 2
daemon/execdriver/windows/exec.go

@@ -7,12 +7,13 @@ import (
 	"fmt"
 	"fmt"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/microsoft/hcsshim"
 	"github.com/microsoft/hcsshim"
 )
 )
 
 
 // Exec implements the exec driver Driver interface.
 // Exec implements the exec driver Driver interface.
-func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, hooks execdriver.Hooks) (int, error) {
+func (d *Driver) Exec(ctx context.Context, c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, hooks execdriver.Hooks) (int, error) {
 
 
 	var (
 	var (
 		term     execdriver.Terminal
 		term     execdriver.Terminal
@@ -74,7 +75,7 @@ func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessCo
 		// non-blocking and return the correct result when read.
 		// non-blocking and return the correct result when read.
 		chOOM := make(chan struct{})
 		chOOM := make(chan struct{})
 		close(chOOM)
 		close(chOOM)
-		hooks.Start(&c.ProcessConfig, int(pid), chOOM)
+		hooks.Start(ctx, &c.ProcessConfig, int(pid), chOOM)
 	}
 	}
 
 
 	if exitCode, err = hcsshim.WaitForProcessInComputeSystem(c.ID, pid); err != nil {
 	if exitCode, err = hcsshim.WaitForProcessInComputeSystem(c.ID, pid); err != nil {

+ 3 - 2
daemon/execdriver/windows/run.go

@@ -15,6 +15,7 @@ import (
 	"syscall"
 	"syscall"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/microsoft/hcsshim"
 	"github.com/microsoft/hcsshim"
 )
 )
@@ -79,7 +80,7 @@ type containerInit struct {
 const defaultOwner = "docker"
 const defaultOwner = "docker"
 
 
 // Run implements the exec driver Driver interface
 // Run implements the exec driver Driver interface
-func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execdriver.Hooks) (execdriver.ExitStatus, error) {
+func (d *Driver) Run(ctx context.Context, c *execdriver.Command, pipes *execdriver.Pipes, hooks execdriver.Hooks) (execdriver.ExitStatus, error) {
 
 
 	var (
 	var (
 		term execdriver.Terminal
 		term execdriver.Terminal
@@ -298,7 +299,7 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd
 		// non-blocking and return the correct result when read.
 		// non-blocking and return the correct result when read.
 		chOOM := make(chan struct{})
 		chOOM := make(chan struct{})
 		close(chOOM)
 		close(chOOM)
-		hooks.Start(&c.ProcessConfig, int(pid), chOOM)
+		hooks.Start(ctx, &c.ProcessConfig, int(pid), chOOM)
 	}
 	}
 
 
 	var exitCode int32
 	var exitCode int32

+ 4 - 3
daemon/export.go

@@ -3,18 +3,19 @@ package daemon
 import (
 import (
 	"io"
 	"io"
 
 
+	"github.com/docker/docker/context"
 	derr "github.com/docker/docker/errors"
 	derr "github.com/docker/docker/errors"
 )
 )
 
 
 // ContainerExport writes the contents of the container to the given
 // ContainerExport writes the contents of the container to the given
 // writer. An error is returned if the container cannot be found.
 // writer. An error is returned if the container cannot be found.
-func (daemon *Daemon) ContainerExport(name string, out io.Writer) error {
-	container, err := daemon.Get(name)
+func (daemon *Daemon) ContainerExport(ctx context.Context, name string, out io.Writer) error {
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	data, err := container.export()
+	data, err := container.export(ctx)
 	if err != nil {
 	if err != nil {
 		return derr.ErrorCodeExportFailed.WithArgs(name, err)
 		return derr.ErrorCodeExportFailed.WithArgs(name, err)
 	}
 	}

+ 41 - 40
daemon/image_delete.go

@@ -5,6 +5,7 @@ import (
 	"strings"
 	"strings"
 
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/context"
 	derr "github.com/docker/docker/errors"
 	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/graph/tags"
 	"github.com/docker/docker/graph/tags"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/image"
@@ -50,10 +51,10 @@ import (
 // FIXME: remove ImageDelete's dependency on Daemon, then move to the graph
 // FIXME: remove ImageDelete's dependency on Daemon, then move to the graph
 // package. This would require that we no longer need the daemon to determine
 // package. This would require that we no longer need the daemon to determine
 // whether images are being used by a stopped or running container.
 // whether images are being used by a stopped or running container.
-func (daemon *Daemon) ImageDelete(imageRef string, force, prune bool) ([]types.ImageDelete, error) {
+func (daemon *Daemon) ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]types.ImageDelete, error) {
 	records := []types.ImageDelete{}
 	records := []types.ImageDelete{}
 
 
-	img, err := daemon.Repositories().LookupImage(imageRef)
+	img, err := daemon.Repositories(ctx).LookupImage(imageRef)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -64,8 +65,8 @@ func (daemon *Daemon) ImageDelete(imageRef string, force, prune bool) ([]types.I
 		// first. We can only remove this reference if either force is
 		// first. We can only remove this reference if either force is
 		// true, there are multiple repository references to this
 		// true, there are multiple repository references to this
 		// image, or there are no containers using the given reference.
 		// image, or there are no containers using the given reference.
-		if !(force || daemon.imageHasMultipleRepositoryReferences(img.ID)) {
-			if container := daemon.getContainerUsingImage(img.ID); container != nil {
+		if !(force || daemon.imageHasMultipleRepositoryReferences(ctx, img.ID)) {
+			if container := daemon.getContainerUsingImage(ctx, img.ID); container != nil {
 				// If we removed the repository reference then
 				// If we removed the repository reference then
 				// this image would remain "dangling" and since
 				// this image would remain "dangling" and since
 				// we really want to avoid that the client must
 				// we really want to avoid that the client must
@@ -74,14 +75,14 @@ func (daemon *Daemon) ImageDelete(imageRef string, force, prune bool) ([]types.I
 			}
 			}
 		}
 		}
 
 
-		parsedRef, err := daemon.removeImageRef(imageRef)
+		parsedRef, err := daemon.removeImageRef(ctx, imageRef)
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
 
 
 		untaggedRecord := types.ImageDelete{Untagged: parsedRef}
 		untaggedRecord := types.ImageDelete{Untagged: parsedRef}
 
 
-		daemon.EventsService.Log("untag", img.ID, "")
+		daemon.EventsService.Log(ctx, "untag", img.ID, "")
 		records = append(records, untaggedRecord)
 		records = append(records, untaggedRecord)
 
 
 		removedRepositoryRef = true
 		removedRepositoryRef = true
@@ -90,21 +91,21 @@ func (daemon *Daemon) ImageDelete(imageRef string, force, prune bool) ([]types.I
 		// repository reference to the image then we will want to
 		// repository reference to the image then we will want to
 		// remove that reference.
 		// remove that reference.
 		// FIXME: Is this the behavior we want?
 		// FIXME: Is this the behavior we want?
-		repoRefs := daemon.Repositories().ByID()[img.ID]
+		repoRefs := daemon.Repositories(ctx).ByID()[img.ID]
 		if len(repoRefs) == 1 {
 		if len(repoRefs) == 1 {
-			parsedRef, err := daemon.removeImageRef(repoRefs[0])
+			parsedRef, err := daemon.removeImageRef(ctx, repoRefs[0])
 			if err != nil {
 			if err != nil {
 				return nil, err
 				return nil, err
 			}
 			}
 
 
 			untaggedRecord := types.ImageDelete{Untagged: parsedRef}
 			untaggedRecord := types.ImageDelete{Untagged: parsedRef}
 
 
-			daemon.EventsService.Log("untag", img.ID, "")
+			daemon.EventsService.Log(ctx, "untag", img.ID, "")
 			records = append(records, untaggedRecord)
 			records = append(records, untaggedRecord)
 		}
 		}
 	}
 	}
 
 
-	return records, daemon.imageDeleteHelper(img, &records, force, prune, removedRepositoryRef)
+	return records, daemon.imageDeleteHelper(ctx, img, &records, force, prune, removedRepositoryRef)
 }
 }
 
 
 // isImageIDPrefix returns whether the given possiblePrefix is a prefix of the
 // isImageIDPrefix returns whether the given possiblePrefix is a prefix of the
@@ -115,14 +116,14 @@ func isImageIDPrefix(imageID, possiblePrefix string) bool {
 
 
 // imageHasMultipleRepositoryReferences returns whether there are multiple
 // imageHasMultipleRepositoryReferences returns whether there are multiple
 // repository references to the given imageID.
 // repository references to the given imageID.
-func (daemon *Daemon) imageHasMultipleRepositoryReferences(imageID string) bool {
-	return len(daemon.Repositories().ByID()[imageID]) > 1
+func (daemon *Daemon) imageHasMultipleRepositoryReferences(ctx context.Context, imageID string) bool {
+	return len(daemon.Repositories(ctx).ByID()[imageID]) > 1
 }
 }
 
 
 // getContainerUsingImage returns a container that was created using the given
 // getContainerUsingImage returns a container that was created using the given
 // imageID. Returns nil if there is no such container.
 // imageID. Returns nil if there is no such container.
-func (daemon *Daemon) getContainerUsingImage(imageID string) *Container {
-	for _, container := range daemon.List() {
+func (daemon *Daemon) getContainerUsingImage(ctx context.Context, imageID string) *Container {
+	for _, container := range daemon.List(ctx) {
 		if container.ImageID == imageID {
 		if container.ImageID == imageID {
 			return container
 			return container
 		}
 		}
@@ -136,7 +137,7 @@ func (daemon *Daemon) getContainerUsingImage(imageID string) *Container {
 // repositoryRef must not be an image ID but a repository name followed by an
 // repositoryRef must not be an image ID but a repository name followed by an
 // optional tag or digest reference. If tag or digest is omitted, the default
 // optional tag or digest reference. If tag or digest is omitted, the default
 // tag is used. Returns the resolved image reference and an error.
 // tag is used. Returns the resolved image reference and an error.
-func (daemon *Daemon) removeImageRef(repositoryRef string) (string, error) {
+func (daemon *Daemon) removeImageRef(ctx context.Context, repositoryRef string) (string, error) {
 	repository, ref := parsers.ParseRepositoryTag(repositoryRef)
 	repository, ref := parsers.ParseRepositoryTag(repositoryRef)
 	if ref == "" {
 	if ref == "" {
 		ref = tags.DefaultTag
 		ref = tags.DefaultTag
@@ -145,7 +146,7 @@ func (daemon *Daemon) removeImageRef(repositoryRef string) (string, error) {
 	// Ignore the boolean value returned, as far as we're concerned, this
 	// Ignore the boolean value returned, as far as we're concerned, this
 	// is an idempotent operation and it's okay if the reference didn't
 	// is an idempotent operation and it's okay if the reference didn't
 	// exist in the first place.
 	// exist in the first place.
-	_, err := daemon.Repositories().Delete(repository, ref)
+	_, err := daemon.Repositories(ctx).Delete(repository, ref)
 
 
 	return utils.ImageReference(repository, ref), err
 	return utils.ImageReference(repository, ref), err
 }
 }
@@ -155,18 +156,18 @@ func (daemon *Daemon) removeImageRef(repositoryRef string) (string, error) {
 // on the first encountered error. Removed references are logged to this
 // on the first encountered error. Removed references are logged to this
 // daemon's event service. An "Untagged" types.ImageDelete is added to the
 // daemon's event service. An "Untagged" types.ImageDelete is added to the
 // given list of records.
 // given list of records.
-func (daemon *Daemon) removeAllReferencesToImageID(imgID string, records *[]types.ImageDelete) error {
-	imageRefs := daemon.Repositories().ByID()[imgID]
+func (daemon *Daemon) removeAllReferencesToImageID(ctx context.Context, imgID string, records *[]types.ImageDelete) error {
+	imageRefs := daemon.Repositories(ctx).ByID()[imgID]
 
 
 	for _, imageRef := range imageRefs {
 	for _, imageRef := range imageRefs {
-		parsedRef, err := daemon.removeImageRef(imageRef)
+		parsedRef, err := daemon.removeImageRef(ctx, imageRef)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
 
 
 		untaggedRecord := types.ImageDelete{Untagged: parsedRef}
 		untaggedRecord := types.ImageDelete{Untagged: parsedRef}
 
 
-		daemon.EventsService.Log("untag", imgID, "")
+		daemon.EventsService.Log(ctx, "untag", imgID, "")
 		*records = append(*records, untaggedRecord)
 		*records = append(*records, untaggedRecord)
 	}
 	}
 
 
@@ -203,11 +204,11 @@ func (idc *imageDeleteConflict) Error() string {
 // conflict is encountered, it will be returned immediately without deleting
 // conflict is encountered, it will be returned immediately without deleting
 // the image. If quiet is true, any encountered conflicts will be ignored and
 // the image. If quiet is true, any encountered conflicts will be ignored and
 // the function will return nil immediately without deleting the image.
 // the function will return nil immediately without deleting the image.
-func (daemon *Daemon) imageDeleteHelper(img *image.Image, records *[]types.ImageDelete, force, prune, quiet bool) error {
+func (daemon *Daemon) imageDeleteHelper(ctx context.Context, img *image.Image, records *[]types.ImageDelete, force, prune, quiet bool) error {
 	// First, determine if this image has any conflicts. Ignore soft conflicts
 	// First, determine if this image has any conflicts. Ignore soft conflicts
 	// if force is true.
 	// if force is true.
-	if conflict := daemon.checkImageDeleteConflict(img, force); conflict != nil {
-		if quiet && !daemon.imageIsDangling(img) {
+	if conflict := daemon.checkImageDeleteConflict(ctx, img, force); conflict != nil {
+		if quiet && !daemon.imageIsDangling(ctx, img) {
 			// Ignore conflicts UNLESS the image is "dangling" in
 			// Ignore conflicts UNLESS the image is "dangling" in
 			// which case we want the user to know.
 			// which case we want the user to know.
 			return nil
 			return nil
@@ -219,15 +220,15 @@ func (daemon *Daemon) imageDeleteHelper(img *image.Image, records *[]types.Image
 	}
 	}
 
 
 	// Delete all repository tag/digest references to this image.
 	// Delete all repository tag/digest references to this image.
-	if err := daemon.removeAllReferencesToImageID(img.ID, records); err != nil {
+	if err := daemon.removeAllReferencesToImageID(ctx, img.ID, records); err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	if err := daemon.Graph().Delete(img.ID); err != nil {
+	if err := daemon.Graph(ctx).Delete(img.ID); err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	daemon.EventsService.Log("delete", img.ID, "")
+	daemon.EventsService.Log(ctx, "delete", img.ID, "")
 	*records = append(*records, types.ImageDelete{Deleted: img.ID})
 	*records = append(*records, types.ImageDelete{Deleted: img.ID})
 
 
 	if !prune || img.Parent == "" {
 	if !prune || img.Parent == "" {
@@ -237,14 +238,14 @@ func (daemon *Daemon) imageDeleteHelper(img *image.Image, records *[]types.Image
 	// We need to prune the parent image. This means delete it if there are
 	// We need to prune the parent image. This means delete it if there are
 	// no tags/digests referencing it and there are no containers using it (
 	// no tags/digests referencing it and there are no containers using it (
 	// either running or stopped).
 	// either running or stopped).
-	parentImg, err := daemon.Graph().Get(img.Parent)
+	parentImg, err := daemon.Graph(ctx).Get(img.Parent)
 	if err != nil {
 	if err != nil {
 		return derr.ErrorCodeImgNoParent.WithArgs(err)
 		return derr.ErrorCodeImgNoParent.WithArgs(err)
 	}
 	}
 
 
 	// Do not force prunings, but do so quietly (stopping on any encountered
 	// Do not force prunings, but do so quietly (stopping on any encountered
 	// conflicts).
 	// conflicts).
-	return daemon.imageDeleteHelper(parentImg, records, false, true, true)
+	return daemon.imageDeleteHelper(ctx, parentImg, records, false, true, true)
 }
 }
 
 
 // checkImageDeleteConflict determines whether there are any conflicts
 // checkImageDeleteConflict determines whether there are any conflicts
@@ -253,9 +254,9 @@ func (daemon *Daemon) imageDeleteHelper(img *image.Image, records *[]types.Image
 // using the image. A soft conflict is any tags/digest referencing the given
 // using the image. A soft conflict is any tags/digest referencing the given
 // image or any stopped container using the image. If ignoreSoftConflicts is
 // image or any stopped container using the image. If ignoreSoftConflicts is
 // true, this function will not check for soft conflict conditions.
 // true, this function will not check for soft conflict conditions.
-func (daemon *Daemon) checkImageDeleteConflict(img *image.Image, ignoreSoftConflicts bool) *imageDeleteConflict {
+func (daemon *Daemon) checkImageDeleteConflict(ctx context.Context, img *image.Image, ignoreSoftConflicts bool) *imageDeleteConflict {
 	// Check for hard conflicts first.
 	// Check for hard conflicts first.
-	if conflict := daemon.checkImageDeleteHardConflict(img); conflict != nil {
+	if conflict := daemon.checkImageDeleteHardConflict(ctx, img); conflict != nil {
 		return conflict
 		return conflict
 	}
 	}
 
 
@@ -265,12 +266,12 @@ func (daemon *Daemon) checkImageDeleteConflict(img *image.Image, ignoreSoftConfl
 		return nil
 		return nil
 	}
 	}
 
 
-	return daemon.checkImageDeleteSoftConflict(img)
+	return daemon.checkImageDeleteSoftConflict(ctx, img)
 }
 }
 
 
-func (daemon *Daemon) checkImageDeleteHardConflict(img *image.Image) *imageDeleteConflict {
+func (daemon *Daemon) checkImageDeleteHardConflict(ctx context.Context, img *image.Image) *imageDeleteConflict {
 	// Check if the image ID is being used by a pull or build.
 	// Check if the image ID is being used by a pull or build.
-	if daemon.Graph().IsHeld(img.ID) {
+	if daemon.Graph(ctx).IsHeld(img.ID) {
 		return &imageDeleteConflict{
 		return &imageDeleteConflict{
 			hard:    true,
 			hard:    true,
 			imgID:   img.ID,
 			imgID:   img.ID,
@@ -279,7 +280,7 @@ func (daemon *Daemon) checkImageDeleteHardConflict(img *image.Image) *imageDelet
 	}
 	}
 
 
 	// Check if the image has any descendent images.
 	// Check if the image has any descendent images.
-	if daemon.Graph().HasChildren(img) {
+	if daemon.Graph(ctx).HasChildren(img) {
 		return &imageDeleteConflict{
 		return &imageDeleteConflict{
 			hard:    true,
 			hard:    true,
 			imgID:   img.ID,
 			imgID:   img.ID,
@@ -288,7 +289,7 @@ func (daemon *Daemon) checkImageDeleteHardConflict(img *image.Image) *imageDelet
 	}
 	}
 
 
 	// Check if any running container is using the image.
 	// Check if any running container is using the image.
-	for _, container := range daemon.List() {
+	for _, container := range daemon.List(ctx) {
 		if !container.IsRunning() {
 		if !container.IsRunning() {
 			// Skip this until we check for soft conflicts later.
 			// Skip this until we check for soft conflicts later.
 			continue
 			continue
@@ -306,9 +307,9 @@ func (daemon *Daemon) checkImageDeleteHardConflict(img *image.Image) *imageDelet
 	return nil
 	return nil
 }
 }
 
 
-func (daemon *Daemon) checkImageDeleteSoftConflict(img *image.Image) *imageDeleteConflict {
+func (daemon *Daemon) checkImageDeleteSoftConflict(ctx context.Context, img *image.Image) *imageDeleteConflict {
 	// Check if any repository tags/digest reference this image.
 	// Check if any repository tags/digest reference this image.
-	if daemon.Repositories().HasReferences(img) {
+	if daemon.Repositories(ctx).HasReferences(img) {
 		return &imageDeleteConflict{
 		return &imageDeleteConflict{
 			imgID:   img.ID,
 			imgID:   img.ID,
 			message: "image is referenced in one or more repositories",
 			message: "image is referenced in one or more repositories",
@@ -316,7 +317,7 @@ func (daemon *Daemon) checkImageDeleteSoftConflict(img *image.Image) *imageDelet
 	}
 	}
 
 
 	// Check if any stopped containers reference this image.
 	// Check if any stopped containers reference this image.
-	for _, container := range daemon.List() {
+	for _, container := range daemon.List(ctx) {
 		if container.IsRunning() {
 		if container.IsRunning() {
 			// Skip this as it was checked above in hard conflict conditions.
 			// Skip this as it was checked above in hard conflict conditions.
 			continue
 			continue
@@ -336,6 +337,6 @@ func (daemon *Daemon) checkImageDeleteSoftConflict(img *image.Image) *imageDelet
 // imageIsDangling returns whether the given image is "dangling" which means
 // imageIsDangling returns whether the given image is "dangling" which means
 // that there are no repository references to the given image and it has no
 // that there are no repository references to the given image and it has no
 // child images.
 // child images.
-func (daemon *Daemon) imageIsDangling(img *image.Image) bool {
-	return !(daemon.Repositories().HasReferences(img) || daemon.Graph().HasChildren(img))
+func (daemon *Daemon) imageIsDangling(ctx context.Context, img *image.Image) bool {
+	return !(daemon.Repositories(ctx).HasReferences(img) || daemon.Graph(ctx).HasChildren(img))
 }
 }

+ 7 - 6
daemon/info.go

@@ -8,6 +8,7 @@ import (
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/autogen/dockerversion"
 	"github.com/docker/docker/autogen/dockerversion"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/pkg/fileutils"
 	"github.com/docker/docker/pkg/fileutils"
 	"github.com/docker/docker/pkg/parsers/kernel"
 	"github.com/docker/docker/pkg/parsers/kernel"
 	"github.com/docker/docker/pkg/parsers/operatingsystem"
 	"github.com/docker/docker/pkg/parsers/operatingsystem"
@@ -18,8 +19,8 @@ import (
 )
 )
 
 
 // SystemInfo returns information about the host server the daemon is running on.
 // SystemInfo returns information about the host server the daemon is running on.
-func (daemon *Daemon) SystemInfo() (*types.Info, error) {
-	images := daemon.Graph().Map()
+func (daemon *Daemon) SystemInfo(ctx context.Context) (*types.Info, error) {
+	images := daemon.Graph(ctx).Map()
 	var imgcount int
 	var imgcount int
 	if images == nil {
 	if images == nil {
 		imgcount = 0
 		imgcount = 0
@@ -65,10 +66,10 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) {
 
 
 	v := &types.Info{
 	v := &types.Info{
 		ID:                 daemon.ID,
 		ID:                 daemon.ID,
-		Containers:         len(daemon.List()),
+		Containers:         len(daemon.List(ctx)),
 		Images:             imgcount,
 		Images:             imgcount,
-		Driver:             daemon.GraphDriver().String(),
-		DriverStatus:       daemon.GraphDriver().Status(),
+		Driver:             daemon.GraphDriver(ctx).String(),
+		DriverStatus:       daemon.GraphDriver(ctx).Status(),
 		IPv4Forwarding:     !sysInfo.IPv4ForwardingDisabled,
 		IPv4Forwarding:     !sysInfo.IPv4ForwardingDisabled,
 		BridgeNfIptables:   !sysInfo.BridgeNfCallIptablesDisabled,
 		BridgeNfIptables:   !sysInfo.BridgeNfCallIptablesDisabled,
 		BridgeNfIP6tables:  !sysInfo.BridgeNfCallIP6tablesDisabled,
 		BridgeNfIP6tables:  !sysInfo.BridgeNfCallIP6tablesDisabled,
@@ -76,7 +77,7 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) {
 		NFd:                fileutils.GetTotalUsedFds(),
 		NFd:                fileutils.GetTotalUsedFds(),
 		NGoroutines:        runtime.NumGoroutine(),
 		NGoroutines:        runtime.NumGoroutine(),
 		SystemTime:         time.Now().Format(time.RFC3339Nano),
 		SystemTime:         time.Now().Format(time.RFC3339Nano),
-		ExecutionDriver:    daemon.ExecutionDriver().Name(),
+		ExecutionDriver:    daemon.ExecutionDriver(ctx).Name(),
 		LoggingDriver:      daemon.defaultLogConfig.Type,
 		LoggingDriver:      daemon.defaultLogConfig.Type,
 		NEventsListener:    daemon.EventsService.SubscribersCount(),
 		NEventsListener:    daemon.EventsService.SubscribersCount(),
 		KernelVersion:      kernelVersion,
 		KernelVersion:      kernelVersion,

+ 11 - 10
daemon/inspect.go

@@ -5,13 +5,14 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/context"
 )
 )
 
 
 // ContainerInspect returns low-level information about a
 // ContainerInspect returns low-level information about a
 // container. Returns an error if the container cannot be found, or if
 // container. Returns an error if the container cannot be found, or if
 // there is an error getting the data.
 // there is an error getting the data.
-func (daemon *Daemon) ContainerInspect(name string) (*types.ContainerJSON, error) {
-	container, err := daemon.Get(name)
+func (daemon *Daemon) ContainerInspect(ctx context.Context, name string) (*types.ContainerJSON, error) {
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -19,7 +20,7 @@ func (daemon *Daemon) ContainerInspect(name string) (*types.ContainerJSON, error
 	container.Lock()
 	container.Lock()
 	defer container.Unlock()
 	defer container.Unlock()
 
 
-	base, err := daemon.getInspectData(container)
+	base, err := daemon.getInspectData(ctx, container)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -30,8 +31,8 @@ func (daemon *Daemon) ContainerInspect(name string) (*types.ContainerJSON, error
 }
 }
 
 
 // ContainerInspect120 serializes the master version of a container into a json type.
 // ContainerInspect120 serializes the master version of a container into a json type.
-func (daemon *Daemon) ContainerInspect120(name string) (*types.ContainerJSON120, error) {
-	container, err := daemon.Get(name)
+func (daemon *Daemon) ContainerInspect120(ctx context.Context, name string) (*types.ContainerJSON120, error) {
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -39,7 +40,7 @@ func (daemon *Daemon) ContainerInspect120(name string) (*types.ContainerJSON120,
 	container.Lock()
 	container.Lock()
 	defer container.Unlock()
 	defer container.Unlock()
 
 
-	base, err := daemon.getInspectData(container)
+	base, err := daemon.getInspectData(ctx, container)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -53,11 +54,11 @@ func (daemon *Daemon) ContainerInspect120(name string) (*types.ContainerJSON120,
 	return &types.ContainerJSON120{base, mountPoints, config}, nil
 	return &types.ContainerJSON120{base, mountPoints, config}, nil
 }
 }
 
 
-func (daemon *Daemon) getInspectData(container *Container) (*types.ContainerJSONBase, error) {
+func (daemon *Daemon) getInspectData(ctx context.Context, container *Container) (*types.ContainerJSONBase, error) {
 	// make a copy to play with
 	// make a copy to play with
 	hostConfig := *container.hostConfig
 	hostConfig := *container.hostConfig
 
 
-	if children, err := daemon.children(container.Name); err == nil {
+	if children, err := daemon.children(ctx, container.Name); err == nil {
 		for linkAlias, child := range children {
 		for linkAlias, child := range children {
 			hostConfig.Links = append(hostConfig.Links, fmt.Sprintf("%s:%s", child.Name, linkAlias))
 			hostConfig.Links = append(hostConfig.Links, fmt.Sprintf("%s:%s", child.Name, linkAlias))
 		}
 		}
@@ -120,7 +121,7 @@ func (daemon *Daemon) getInspectData(container *Container) (*types.ContainerJSON
 
 
 // ContainerExecInspect returns low-level information about the exec
 // ContainerExecInspect returns low-level information about the exec
 // command. An error is returned if the exec cannot be found.
 // command. An error is returned if the exec cannot be found.
-func (daemon *Daemon) ContainerExecInspect(id string) (*ExecConfig, error) {
+func (daemon *Daemon) ContainerExecInspect(ctx context.Context, id string) (*ExecConfig, error) {
 	eConfig, err := daemon.getExecConfig(id)
 	eConfig, err := daemon.getExecConfig(id)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -130,7 +131,7 @@ func (daemon *Daemon) ContainerExecInspect(id string) (*ExecConfig, error) {
 
 
 // VolumeInspect looks up a volume by name. An error is returned if
 // VolumeInspect looks up a volume by name. An error is returned if
 // the volume cannot be found.
 // the volume cannot be found.
-func (daemon *Daemon) VolumeInspect(name string) (*types.Volume, error) {
+func (daemon *Daemon) VolumeInspect(ctx context.Context, name string) (*types.Volume, error) {
 	v, err := daemon.volumes.Get(name)
 	v, err := daemon.volumes.Get(name)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err

+ 7 - 4
daemon/inspect_unix.go

@@ -2,7 +2,10 @@
 
 
 package daemon
 package daemon
 
 
-import "github.com/docker/docker/api/types"
+import (
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/context"
+)
 
 
 // This sets platform-specific fields
 // This sets platform-specific fields
 func setPlatformSpecificContainerFields(container *Container, contJSONBase *types.ContainerJSONBase) *types.ContainerJSONBase {
 func setPlatformSpecificContainerFields(container *Container, contJSONBase *types.ContainerJSONBase) *types.ContainerJSONBase {
@@ -15,8 +18,8 @@ func setPlatformSpecificContainerFields(container *Container, contJSONBase *type
 }
 }
 
 
 // ContainerInspectPre120 gets containers for pre 1.20 APIs.
 // ContainerInspectPre120 gets containers for pre 1.20 APIs.
-func (daemon *Daemon) ContainerInspectPre120(name string) (*types.ContainerJSONPre120, error) {
-	container, err := daemon.Get(name)
+func (daemon *Daemon) ContainerInspectPre120(ctx context.Context, name string) (*types.ContainerJSONPre120, error) {
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -24,7 +27,7 @@ func (daemon *Daemon) ContainerInspectPre120(name string) (*types.ContainerJSONP
 	container.Lock()
 	container.Lock()
 	defer container.Unlock()
 	defer container.Unlock()
 
 
-	base, err := daemon.getInspectData(container)
+	base, err := daemon.getInspectData(ctx, container)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}

+ 6 - 3
daemon/inspect_windows.go

@@ -1,6 +1,9 @@
 package daemon
 package daemon
 
 
-import "github.com/docker/docker/api/types"
+import (
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/context"
+)
 
 
 // This sets platform-specific fields
 // This sets platform-specific fields
 func setPlatformSpecificContainerFields(container *Container, contJSONBase *types.ContainerJSONBase) *types.ContainerJSONBase {
 func setPlatformSpecificContainerFields(container *Container, contJSONBase *types.ContainerJSONBase) *types.ContainerJSONBase {
@@ -12,6 +15,6 @@ func addMountPoints(container *Container) []types.MountPoint {
 }
 }
 
 
 // ContainerInspectPre120 get containers for pre 1.20 APIs.
 // ContainerInspectPre120 get containers for pre 1.20 APIs.
-func (daemon *Daemon) ContainerInspectPre120(name string) (*types.ContainerJSON, error) {
-	return daemon.ContainerInspect(name)
+func (daemon *Daemon) ContainerInspectPre120(ctx context.Context, name string) (*types.ContainerJSON, error) {
+	return daemon.ContainerInspect(ctx, name)
 }
 }

+ 9 - 5
daemon/kill.go

@@ -1,25 +1,29 @@
 package daemon
 package daemon
 
 
-import "syscall"
+import (
+	"syscall"
+
+	"github.com/docker/docker/context"
+)
 
 
 // ContainerKill send signal to the container
 // ContainerKill send signal to the container
 // If no signal is given (sig 0), then Kill with SIGKILL and wait
 // If no signal is given (sig 0), then Kill with SIGKILL and wait
 // for the container to exit.
 // for the container to exit.
 // If a signal is given, then just send it to the container and return.
 // If a signal is given, then just send it to the container and return.
-func (daemon *Daemon) ContainerKill(name string, sig uint64) error {
-	container, err := daemon.Get(name)
+func (daemon *Daemon) ContainerKill(ctx context.Context, name string, sig uint64) error {
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
 	// If no signal is passed, or SIGKILL, perform regular Kill (SIGKILL + wait())
 	// If no signal is passed, or SIGKILL, perform regular Kill (SIGKILL + wait())
 	if sig == 0 || syscall.Signal(sig) == syscall.SIGKILL {
 	if sig == 0 || syscall.Signal(sig) == syscall.SIGKILL {
-		if err := container.Kill(); err != nil {
+		if err := container.Kill(ctx); err != nil {
 			return err
 			return err
 		}
 		}
 	} else {
 	} else {
 		// Otherwise, just send the requested signal
 		// Otherwise, just send the requested signal
-		if err := container.killSig(int(sig)); err != nil {
+		if err := container.killSig(ctx, int(sig)); err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}

+ 24 - 23
daemon/list.go

@@ -8,6 +8,7 @@ import (
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/context"
 	derr "github.com/docker/docker/errors"
 	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/pkg/graphdb"
 	"github.com/docker/docker/pkg/graphdb"
@@ -20,7 +21,7 @@ type iterationAction int
 
 
 // containerReducer represents a reducer for a container.
 // containerReducer represents a reducer for a container.
 // Returns the object to serialize by the api.
 // Returns the object to serialize by the api.
-type containerReducer func(*Container, *listContext) (*types.Container, error)
+type containerReducer func(context.Context, *Container, *listContext) (*types.Container, error)
 
 
 const (
 const (
 	// includeContainer is the action to include a container in the reducer.
 	// includeContainer is the action to include a container in the reducer.
@@ -35,7 +36,7 @@ const (
 var errStopIteration = errors.New("container list iteration stopped")
 var errStopIteration = errors.New("container list iteration stopped")
 
 
 // List returns an array of all containers registered in the daemon.
 // List returns an array of all containers registered in the daemon.
-func (daemon *Daemon) List() []*Container {
+func (daemon *Daemon) List(ctx context.Context) []*Container {
 	return daemon.containers.List()
 	return daemon.containers.List()
 }
 }
 
 
@@ -79,21 +80,21 @@ type listContext struct {
 }
 }
 
 
 // Containers returns the list of containers to show given the user's filtering.
 // Containers returns the list of containers to show given the user's filtering.
-func (daemon *Daemon) Containers(config *ContainersConfig) ([]*types.Container, error) {
-	return daemon.reduceContainers(config, daemon.transformContainer)
+func (daemon *Daemon) Containers(ctx context.Context, config *ContainersConfig) ([]*types.Container, error) {
+	return daemon.reduceContainers(ctx, config, daemon.transformContainer)
 }
 }
 
 
 // reduceContainer parses the user filtering and generates the list of containers to return based on a reducer.
 // reduceContainer parses the user filtering and generates the list of containers to return based on a reducer.
-func (daemon *Daemon) reduceContainers(config *ContainersConfig, reducer containerReducer) ([]*types.Container, error) {
+func (daemon *Daemon) reduceContainers(ctx context.Context, config *ContainersConfig, reducer containerReducer) ([]*types.Container, error) {
 	containers := []*types.Container{}
 	containers := []*types.Container{}
 
 
-	ctx, err := daemon.foldFilter(config)
+	fctx, err := daemon.foldFilter(ctx, config)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	for _, container := range daemon.List() {
-		t, err := daemon.reducePsContainer(container, ctx, reducer)
+	for _, container := range daemon.List(ctx) {
+		t, err := daemon.reducePsContainer(ctx, container, fctx, reducer)
 		if err != nil {
 		if err != nil {
 			if err != errStopIteration {
 			if err != errStopIteration {
 				return nil, err
 				return nil, err
@@ -102,19 +103,19 @@ func (daemon *Daemon) reduceContainers(config *ContainersConfig, reducer contain
 		}
 		}
 		if t != nil {
 		if t != nil {
 			containers = append(containers, t)
 			containers = append(containers, t)
-			ctx.idx++
+			fctx.idx++
 		}
 		}
 	}
 	}
 	return containers, nil
 	return containers, nil
 }
 }
 
 
 // reducePsContainer is the basic representation for a container as expected by the ps command.
 // reducePsContainer is the basic representation for a container as expected by the ps command.
-func (daemon *Daemon) reducePsContainer(container *Container, ctx *listContext, reducer containerReducer) (*types.Container, error) {
+func (daemon *Daemon) reducePsContainer(ctx context.Context, container *Container, lctx *listContext, reducer containerReducer) (*types.Container, error) {
 	container.Lock()
 	container.Lock()
 	defer container.Unlock()
 	defer container.Unlock()
 
 
 	// filter containers to return
 	// filter containers to return
-	action := includeContainerInList(container, ctx)
+	action := includeContainerInList(container, lctx)
 	switch action {
 	switch action {
 	case excludeContainer:
 	case excludeContainer:
 		return nil, nil
 		return nil, nil
@@ -123,11 +124,11 @@ func (daemon *Daemon) reducePsContainer(container *Container, ctx *listContext,
 	}
 	}
 
 
 	// transform internal container struct into api structs
 	// transform internal container struct into api structs
-	return reducer(container, ctx)
+	return reducer(ctx, container, lctx)
 }
 }
 
 
 // foldFilter generates the container filter based in the user's filtering options.
 // foldFilter generates the container filter based in the user's filtering options.
-func (daemon *Daemon) foldFilter(config *ContainersConfig) (*listContext, error) {
+func (daemon *Daemon) foldFilter(ctx context.Context, config *ContainersConfig) (*listContext, error) {
 	psFilters, err := filters.FromParam(config.Filters)
 	psFilters, err := filters.FromParam(config.Filters)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -159,11 +160,11 @@ func (daemon *Daemon) foldFilter(config *ContainersConfig) (*listContext, error)
 	var ancestorFilter bool
 	var ancestorFilter bool
 	if ancestors, ok := psFilters["ancestor"]; ok {
 	if ancestors, ok := psFilters["ancestor"]; ok {
 		ancestorFilter = true
 		ancestorFilter = true
-		byParents := daemon.Graph().ByParent()
+		byParents := daemon.Graph(ctx).ByParent()
 		// The idea is to walk the graph down the most "efficient" way.
 		// The idea is to walk the graph down the most "efficient" way.
 		for _, ancestor := range ancestors {
 		for _, ancestor := range ancestors {
 			// First, get the imageId of the ancestor filter (yay)
 			// First, get the imageId of the ancestor filter (yay)
-			image, err := daemon.Repositories().LookupImage(ancestor)
+			image, err := daemon.Repositories(ctx).LookupImage(ancestor)
 			if err != nil {
 			if err != nil {
 				logrus.Warnf("Error while looking up for image %v", ancestor)
 				logrus.Warnf("Error while looking up for image %v", ancestor)
 				continue
 				continue
@@ -185,14 +186,14 @@ func (daemon *Daemon) foldFilter(config *ContainersConfig) (*listContext, error)
 
 
 	var beforeCont, sinceCont *Container
 	var beforeCont, sinceCont *Container
 	if config.Before != "" {
 	if config.Before != "" {
-		beforeCont, err = daemon.Get(config.Before)
+		beforeCont, err = daemon.Get(ctx, config.Before)
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
 	}
 	}
 
 
 	if config.Since != "" {
 	if config.Since != "" {
-		sinceCont, err = daemon.Get(config.Since)
+		sinceCont, err = daemon.Get(ctx, config.Since)
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
@@ -286,13 +287,13 @@ func includeContainerInList(container *Container, ctx *listContext) iterationAct
 }
 }
 
 
 // transformContainer generates the container type expected by the docker ps command.
 // transformContainer generates the container type expected by the docker ps command.
-func (daemon *Daemon) transformContainer(container *Container, ctx *listContext) (*types.Container, error) {
+func (daemon *Daemon) transformContainer(ctx context.Context, container *Container, lctx *listContext) (*types.Container, error) {
 	newC := &types.Container{
 	newC := &types.Container{
 		ID:    container.ID,
 		ID:    container.ID,
-		Names: ctx.names[container.ID],
+		Names: lctx.names[container.ID],
 	}
 	}
 
 
-	img, err := daemon.Repositories().LookupImage(container.Config.Image)
+	img, err := daemon.Repositories(ctx).LookupImage(container.Config.Image)
 	if err != nil {
 	if err != nil {
 		// If the image can no longer be found by its original reference,
 		// If the image can no longer be found by its original reference,
 		// it makes sense to show the ID instead of a stale reference.
 		// it makes sense to show the ID instead of a stale reference.
@@ -349,8 +350,8 @@ func (daemon *Daemon) transformContainer(container *Container, ctx *listContext)
 		}
 		}
 	}
 	}
 
 
-	if ctx.Size {
-		sizeRw, sizeRootFs := container.getSize()
+	if lctx.Size {
+		sizeRw, sizeRootFs := container.getSize(ctx)
 		newC.SizeRw = sizeRw
 		newC.SizeRw = sizeRw
 		newC.SizeRootFs = sizeRootFs
 		newC.SizeRootFs = sizeRootFs
 	}
 	}
@@ -361,7 +362,7 @@ func (daemon *Daemon) transformContainer(container *Container, ctx *listContext)
 
 
 // Volumes lists known volumes, using the filter to restrict the range
 // Volumes lists known volumes, using the filter to restrict the range
 // of volumes returned.
 // of volumes returned.
-func (daemon *Daemon) Volumes(filter string) ([]*types.Volume, error) {
+func (daemon *Daemon) Volumes(ctx context.Context, filter string) ([]*types.Volume, error) {
 	var volumesOut []*types.Volume
 	var volumesOut []*types.Volume
 	volFilters, err := filters.FromParam(filter)
 	volFilters, err := filters.FromParam(filter)
 	if err != nil {
 	if err != nil {

+ 2 - 1
daemon/logs.go

@@ -6,6 +6,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/daemon/logger"
 	derr "github.com/docker/docker/errors"
 	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/stdcopy"
 	"github.com/docker/docker/pkg/stdcopy"
@@ -30,7 +31,7 @@ type ContainerLogsConfig struct {
 
 
 // ContainerLogs hooks up a container's stdout and stderr streams
 // ContainerLogs hooks up a container's stdout and stderr streams
 // configured with the given struct.
 // configured with the given struct.
-func (daemon *Daemon) ContainerLogs(container *Container, config *ContainerLogsConfig) error {
+func (daemon *Daemon) ContainerLogs(ctx context.Context, container *Container, config *ContainerLogsConfig) error {
 	if !(config.UseStdout || config.UseStderr) {
 	if !(config.UseStdout || config.UseStderr) {
 		return derr.ErrorCodeNeedStream
 		return derr.ErrorCodeNeedStream
 	}
 	}

+ 11 - 10
daemon/monitor.go

@@ -7,6 +7,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/docker/runconfig"
@@ -84,9 +85,9 @@ func (m *containerMonitor) ExitOnNext() {
 
 
 // Close closes the container's resources such as networking allocations and
 // Close closes the container's resources such as networking allocations and
 // unmounts the contatiner's root filesystem
 // unmounts the contatiner's root filesystem
-func (m *containerMonitor) Close() error {
+func (m *containerMonitor) Close(ctx context.Context) error {
 	// Cleanup networking and mounts
 	// Cleanup networking and mounts
-	m.container.cleanup()
+	m.container.cleanup(ctx)
 
 
 	// FIXME: here is race condition between two RUN instructions in Dockerfile
 	// FIXME: here is race condition between two RUN instructions in Dockerfile
 	// because they share same runconfig and change image. Must be fixed
 	// because they share same runconfig and change image. Must be fixed
@@ -101,7 +102,7 @@ func (m *containerMonitor) Close() error {
 }
 }
 
 
 // Start starts the containers process and monitors it according to the restart policy
 // Start starts the containers process and monitors it according to the restart policy
-func (m *containerMonitor) Start() error {
+func (m *containerMonitor) Start(ctx context.Context) error {
 	var (
 	var (
 		err        error
 		err        error
 		exitStatus execdriver.ExitStatus
 		exitStatus execdriver.ExitStatus
@@ -117,7 +118,7 @@ func (m *containerMonitor) Start() error {
 			m.container.setStopped(&exitStatus)
 			m.container.setStopped(&exitStatus)
 			defer m.container.Unlock()
 			defer m.container.Unlock()
 		}
 		}
-		m.Close()
+		m.Close(ctx)
 	}()
 	}()
 	// reset stopped flag
 	// reset stopped flag
 	if m.container.HasBeenManuallyStopped {
 	if m.container.HasBeenManuallyStopped {
@@ -138,11 +139,11 @@ func (m *containerMonitor) Start() error {
 
 
 		pipes := execdriver.NewPipes(m.container.stdin, m.container.stdout, m.container.stderr, m.container.Config.OpenStdin)
 		pipes := execdriver.NewPipes(m.container.stdin, m.container.stdout, m.container.stderr, m.container.Config.OpenStdin)
 
 
-		m.container.logEvent("start")
+		m.container.logEvent(ctx, "start")
 
 
 		m.lastStartTime = time.Now()
 		m.lastStartTime = time.Now()
 
 
-		if exitStatus, err = m.container.daemon.run(m.container, pipes, m.callback); err != nil {
+		if exitStatus, err = m.container.daemon.run(ctx, m.container, pipes, m.callback); err != nil {
 			// if we receive an internal error from the initial start of a container then lets
 			// if we receive an internal error from the initial start of a container then lets
 			// return it instead of entering the restart loop
 			// return it instead of entering the restart loop
 			if m.container.RestartCount == 0 {
 			if m.container.RestartCount == 0 {
@@ -162,7 +163,7 @@ func (m *containerMonitor) Start() error {
 
 
 		if m.shouldRestart(exitStatus.ExitCode) {
 		if m.shouldRestart(exitStatus.ExitCode) {
 			m.container.setRestarting(&exitStatus)
 			m.container.setRestarting(&exitStatus)
-			m.container.logEvent("die")
+			m.container.logEvent(ctx, "die")
 			m.resetContainer(true)
 			m.resetContainer(true)
 
 
 			// sleep with a small time increment between each restart to help avoid issues cased by quickly
 			// sleep with a small time increment between each restart to help avoid issues cased by quickly
@@ -177,7 +178,7 @@ func (m *containerMonitor) Start() error {
 			continue
 			continue
 		}
 		}
 
 
-		m.container.logEvent("die")
+		m.container.logEvent(ctx, "die")
 		m.resetContainer(true)
 		m.resetContainer(true)
 		return err
 		return err
 	}
 	}
@@ -245,11 +246,11 @@ func (m *containerMonitor) shouldRestart(exitCode int) bool {
 
 
 // callback ensures that the container's state is properly updated after we
 // callback ensures that the container's state is properly updated after we
 // received ack from the execution drivers
 // received ack from the execution drivers
-func (m *containerMonitor) callback(processConfig *execdriver.ProcessConfig, pid int, chOOM <-chan struct{}) error {
+func (m *containerMonitor) callback(ctx context.Context, processConfig *execdriver.ProcessConfig, pid int, chOOM <-chan struct{}) error {
 	go func() {
 	go func() {
 		_, ok := <-chOOM
 		_, ok := <-chOOM
 		if ok {
 		if ok {
-			m.container.logEvent("oom")
+			m.container.logEvent(ctx, "oom")
 		}
 		}
 	}()
 	}()
 
 

+ 4 - 3
daemon/pause.go

@@ -1,17 +1,18 @@
 package daemon
 package daemon
 
 
 import (
 import (
+	"github.com/docker/docker/context"
 	derr "github.com/docker/docker/errors"
 	derr "github.com/docker/docker/errors"
 )
 )
 
 
 // ContainerPause pauses a container
 // ContainerPause pauses a container
-func (daemon *Daemon) ContainerPause(name string) error {
-	container, err := daemon.Get(name)
+func (daemon *Daemon) ContainerPause(ctx context.Context, name string) error {
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	if err := container.pause(); err != nil {
+	if err := container.pause(ctx); err != nil {
 		return derr.ErrorCodePauseError.WithArgs(name, err)
 		return derr.ErrorCodePauseError.WithArgs(name, err)
 	}
 	}
 
 

+ 6 - 5
daemon/rename.go

@@ -1,18 +1,19 @@
 package daemon
 package daemon
 
 
 import (
 import (
+	"github.com/docker/docker/context"
 	derr "github.com/docker/docker/errors"
 	derr "github.com/docker/docker/errors"
 )
 )
 
 
 // ContainerRename changes the name of a container, using the oldName
 // ContainerRename changes the name of a container, using the oldName
 // to find the container. An error is returned if newName is already
 // to find the container. An error is returned if newName is already
 // reserved.
 // reserved.
-func (daemon *Daemon) ContainerRename(oldName, newName string) error {
+func (daemon *Daemon) ContainerRename(ctx context.Context, oldName, newName string) error {
 	if oldName == "" || newName == "" {
 	if oldName == "" || newName == "" {
 		return derr.ErrorCodeEmptyRename
 		return derr.ErrorCodeEmptyRename
 	}
 	}
 
 
-	container, err := daemon.Get(oldName)
+	container, err := daemon.Get(ctx, oldName)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -21,7 +22,7 @@ func (daemon *Daemon) ContainerRename(oldName, newName string) error {
 
 
 	container.Lock()
 	container.Lock()
 	defer container.Unlock()
 	defer container.Unlock()
-	if newName, err = daemon.reserveName(container.ID, newName); err != nil {
+	if newName, err = daemon.reserveName(ctx, container.ID, newName); err != nil {
 		return derr.ErrorCodeRenameTaken.WithArgs(err)
 		return derr.ErrorCodeRenameTaken.WithArgs(err)
 	}
 	}
 
 
@@ -29,7 +30,7 @@ func (daemon *Daemon) ContainerRename(oldName, newName string) error {
 
 
 	undo := func() {
 	undo := func() {
 		container.Name = oldName
 		container.Name = oldName
-		daemon.reserveName(container.ID, oldName)
+		daemon.reserveName(ctx, container.ID, oldName)
 		daemon.containerGraphDB.Delete(newName)
 		daemon.containerGraphDB.Delete(newName)
 	}
 	}
 
 
@@ -43,6 +44,6 @@ func (daemon *Daemon) ContainerRename(oldName, newName string) error {
 		return err
 		return err
 	}
 	}
 
 
-	container.logEvent("rename")
+	container.logEvent(ctx, "rename")
 	return nil
 	return nil
 }
 }

+ 8 - 4
daemon/resize.go

@@ -1,20 +1,24 @@
 package daemon
 package daemon
 
 
+import (
+	"github.com/docker/docker/context"
+)
+
 // ContainerResize changes the size of the TTY of the process running
 // ContainerResize changes the size of the TTY of the process running
 // in the container with the given name to the given height and width.
 // in the container with the given name to the given height and width.
-func (daemon *Daemon) ContainerResize(name string, height, width int) error {
-	container, err := daemon.Get(name)
+func (daemon *Daemon) ContainerResize(ctx context.Context, name string, height, width int) error {
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	return container.Resize(height, width)
+	return container.Resize(ctx, height, width)
 }
 }
 
 
 // ContainerExecResize changes the size of the TTY of the process
 // ContainerExecResize changes the size of the TTY of the process
 // running in the exec with the given name to the given height and
 // running in the exec with the given name to the given height and
 // width.
 // width.
-func (daemon *Daemon) ContainerExecResize(name string, height, width int) error {
+func (daemon *Daemon) ContainerExecResize(ctx context.Context, name string, height, width int) error {
 	ExecConfig, err := daemon.getExecConfig(name)
 	ExecConfig, err := daemon.getExecConfig(name)
 	if err != nil {
 	if err != nil {
 		return err
 		return err

+ 4 - 3
daemon/restart.go

@@ -1,6 +1,7 @@
 package daemon
 package daemon
 
 
 import (
 import (
+	"github.com/docker/docker/context"
 	derr "github.com/docker/docker/errors"
 	derr "github.com/docker/docker/errors"
 )
 )
 
 
@@ -10,12 +11,12 @@ import (
 // timeout, ContainerRestart will wait forever until a graceful
 // timeout, ContainerRestart will wait forever until a graceful
 // stop. Returns an error if the container cannot be found, or if
 // stop. Returns an error if the container cannot be found, or if
 // there is an underlying error at any stage of the restart.
 // there is an underlying error at any stage of the restart.
-func (daemon *Daemon) ContainerRestart(name string, seconds int) error {
-	container, err := daemon.Get(name)
+func (daemon *Daemon) ContainerRestart(ctx context.Context, name string, seconds int) error {
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	if err := container.Restart(seconds); err != nil {
+	if err := container.Restart(ctx, seconds); err != nil {
 		return derr.ErrorCodeCantRestart.WithArgs(name, err)
 		return derr.ErrorCodeCantRestart.WithArgs(name, err)
 	}
 	}
 	return nil
 	return nil

+ 6 - 5
daemon/start.go

@@ -3,14 +3,15 @@ package daemon
 import (
 import (
 	"runtime"
 	"runtime"
 
 
+	"github.com/docker/docker/context"
 	derr "github.com/docker/docker/errors"
 	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/docker/utils"
 	"github.com/docker/docker/utils"
 )
 )
 
 
 // ContainerStart starts a container.
 // ContainerStart starts a container.
-func (daemon *Daemon) ContainerStart(name string, hostConfig *runconfig.HostConfig) error {
-	container, err := daemon.Get(name)
+func (daemon *Daemon) ContainerStart(ctx context.Context, name string, hostConfig *runconfig.HostConfig) error {
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -28,7 +29,7 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *runconfig.HostConf
 		// This is kept for backward compatibility - hostconfig should be passed when
 		// This is kept for backward compatibility - hostconfig should be passed when
 		// creating a container, not during start.
 		// creating a container, not during start.
 		if hostConfig != nil {
 		if hostConfig != nil {
-			if err := daemon.setHostConfig(container, hostConfig); err != nil {
+			if err := daemon.setHostConfig(ctx, container, hostConfig); err != nil {
 				return err
 				return err
 			}
 			}
 		}
 		}
@@ -40,11 +41,11 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *runconfig.HostConf
 
 
 	// check if hostConfig is in line with the current system settings.
 	// check if hostConfig is in line with the current system settings.
 	// It may happen cgroups are umounted or the like.
 	// It may happen cgroups are umounted or the like.
-	if _, err = daemon.verifyContainerSettings(container.hostConfig, nil); err != nil {
+	if _, err = daemon.verifyContainerSettings(ctx, container.hostConfig, nil); err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	if err := container.Start(); err != nil {
+	if err := container.Start(ctx); err != nil {
 		return derr.ErrorCodeCantStart.WithArgs(name, utils.GetErrorMessage(err))
 		return derr.ErrorCodeCantStart.WithArgs(name, utils.GetErrorMessage(err))
 	}
 	}
 
 

+ 3 - 2
daemon/stats.go

@@ -5,6 +5,7 @@ import (
 	"io"
 	"io"
 
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/pkg/version"
 	"github.com/docker/docker/pkg/version"
 	"github.com/docker/libnetwork/osl"
 	"github.com/docker/libnetwork/osl"
@@ -22,9 +23,9 @@ type ContainerStatsConfig struct {
 
 
 // ContainerStats writes information about the container to the stream
 // ContainerStats writes information about the container to the stream
 // given in the config object.
 // given in the config object.
-func (daemon *Daemon) ContainerStats(prefixOrName string, config *ContainerStatsConfig) error {
+func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, config *ContainerStatsConfig) error {
 
 
-	container, err := daemon.Get(prefixOrName)
+	container, err := daemon.Get(ctx, prefixOrName)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}

+ 4 - 3
daemon/stop.go

@@ -1,6 +1,7 @@
 package daemon
 package daemon
 
 
 import (
 import (
+	"github.com/docker/docker/context"
 	derr "github.com/docker/docker/errors"
 	derr "github.com/docker/docker/errors"
 )
 )
 
 
@@ -10,15 +11,15 @@ import (
 // will wait for a graceful termination. An error is returned if the
 // will wait for a graceful termination. An error is returned if the
 // container is not found, is already stopped, or if there is a
 // container is not found, is already stopped, or if there is a
 // problem stopping the container.
 // problem stopping the container.
-func (daemon *Daemon) ContainerStop(name string, seconds int) error {
-	container, err := daemon.Get(name)
+func (daemon *Daemon) ContainerStop(ctx context.Context, name string, seconds int) error {
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 	if !container.IsRunning() {
 	if !container.IsRunning() {
 		return derr.ErrorCodeStopped
 		return derr.ErrorCodeStopped
 	}
 	}
-	if err := container.Stop(seconds); err != nil {
+	if err := container.Stop(ctx, seconds); err != nil {
 		return derr.ErrorCodeCantStop.WithArgs(name, err)
 		return derr.ErrorCodeCantStop.WithArgs(name, err)
 	}
 	}
 	return nil
 	return nil

+ 5 - 4
daemon/top_unix.go

@@ -8,6 +8,7 @@ import (
 	"strings"
 	"strings"
 
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/context"
 	derr "github.com/docker/docker/errors"
 	derr "github.com/docker/docker/errors"
 )
 )
 
 
@@ -16,12 +17,12 @@ import (
 // "-ef" if no args are given.  An error is returned if the container
 // "-ef" if no args are given.  An error is returned if the container
 // is not found, or is not running, or if there are any problems
 // is not found, or is not running, or if there are any problems
 // running ps, or parsing the output.
 // running ps, or parsing the output.
-func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.ContainerProcessList, error) {
+func (daemon *Daemon) ContainerTop(ctx context.Context, name string, psArgs string) (*types.ContainerProcessList, error) {
 	if psArgs == "" {
 	if psArgs == "" {
 		psArgs = "-ef"
 		psArgs = "-ef"
 	}
 	}
 
 
-	container, err := daemon.Get(name)
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -30,7 +31,7 @@ func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.Container
 		return nil, derr.ErrorCodeNotRunning.WithArgs(name)
 		return nil, derr.ErrorCodeNotRunning.WithArgs(name)
 	}
 	}
 
 
-	pids, err := daemon.ExecutionDriver().GetPidsForContainer(container.ID)
+	pids, err := daemon.ExecutionDriver(ctx).GetPidsForContainer(container.ID)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -76,6 +77,6 @@ func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.Container
 			}
 			}
 		}
 		}
 	}
 	}
-	container.logEvent("top")
+	container.logEvent(ctx, "top")
 	return procList, nil
 	return procList, nil
 }
 }

+ 2 - 1
daemon/top_windows.go

@@ -2,10 +2,11 @@ package daemon
 
 
 import (
 import (
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/context"
 	derr "github.com/docker/docker/errors"
 	derr "github.com/docker/docker/errors"
 )
 )
 
 
 // ContainerTop is not supported on Windows and returns an error.
 // ContainerTop is not supported on Windows and returns an error.
-func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.ContainerProcessList, error) {
+func (daemon *Daemon) ContainerTop(ctx context.Context, name string, psArgs string) (*types.ContainerProcessList, error) {
 	return nil, derr.ErrorCodeNoTop
 	return nil, derr.ErrorCodeNoTop
 }
 }

+ 4 - 3
daemon/unpause.go

@@ -1,17 +1,18 @@
 package daemon
 package daemon
 
 
 import (
 import (
+	"github.com/docker/docker/context"
 	derr "github.com/docker/docker/errors"
 	derr "github.com/docker/docker/errors"
 )
 )
 
 
 // ContainerUnpause unpauses a container
 // ContainerUnpause unpauses a container
-func (daemon *Daemon) ContainerUnpause(name string) error {
-	container, err := daemon.Get(name)
+func (daemon *Daemon) ContainerUnpause(ctx context.Context, name string) error {
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	if err := container.unpause(); err != nil {
+	if err := container.unpause(ctx); err != nil {
 		return derr.ErrorCodeCantUnpause.WithArgs(name, err)
 		return derr.ErrorCodeCantUnpause.WithArgs(name, err)
 	}
 	}
 
 

+ 3 - 2
daemon/volumes_unix.go

@@ -10,6 +10,7 @@ import (
 	"strings"
 	"strings"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/execdriver"
 	derr "github.com/docker/docker/errors"
 	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/system"
 	"github.com/docker/docker/pkg/system"
@@ -285,7 +286,7 @@ func parseVolumesFrom(spec string) (string, string, error) {
 // 1. Select the previously configured mount points for the containers, if any.
 // 1. Select the previously configured mount points for the containers, if any.
 // 2. Select the volumes mounted from another containers. Overrides previously configured mount point destination.
 // 2. Select the volumes mounted from another containers. Overrides previously configured mount point destination.
 // 3. Select the bind mounts set by the client. Overrides previously configured mount point destinations.
 // 3. Select the bind mounts set by the client. Overrides previously configured mount point destinations.
-func (daemon *Daemon) registerMountPoints(container *Container, hostConfig *runconfig.HostConfig) error {
+func (daemon *Daemon) registerMountPoints(ctx context.Context, container *Container, hostConfig *runconfig.HostConfig) error {
 	binds := map[string]bool{}
 	binds := map[string]bool{}
 	mountPoints := map[string]*mountPoint{}
 	mountPoints := map[string]*mountPoint{}
 
 
@@ -301,7 +302,7 @@ func (daemon *Daemon) registerMountPoints(container *Container, hostConfig *runc
 			return err
 			return err
 		}
 		}
 
 
-		c, err := daemon.Get(containerID)
+		c, err := daemon.Get(ctx, containerID)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}

+ 2 - 1
daemon/volumes_windows.go

@@ -3,6 +3,7 @@
 package daemon
 package daemon
 
 
 import (
 import (
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/docker/runconfig"
 )
 )
@@ -31,6 +32,6 @@ func (daemon *Daemon) verifyVolumesInfo(container *Container) error {
 // registerMountPoints initializes the container mount points with the
 // registerMountPoints initializes the container mount points with the
 // configured volumes and bind mounts. Windows does not support volumes or
 // configured volumes and bind mounts. Windows does not support volumes or
 // mount points.
 // mount points.
-func (daemon *Daemon) registerMountPoints(container *Container, hostConfig *runconfig.HostConfig) error {
+func (daemon *Daemon) registerMountPoints(ctx context.Context, container *Container, hostConfig *runconfig.HostConfig) error {
 	return nil
 	return nil
 }
 }

+ 7 - 3
daemon/wait.go

@@ -1,14 +1,18 @@
 package daemon
 package daemon
 
 
-import "time"
+import (
+	"time"
+
+	"github.com/docker/docker/context"
+)
 
 
 // ContainerWait stops processing until the given container is
 // ContainerWait stops processing until the given container is
 // stopped. If the container is not found, an error is returned. On a
 // stopped. If the container is not found, an error is returned. On a
 // successful stop, the exit code of the container is returned. On a
 // successful stop, the exit code of the container is returned. On a
 // timeout, an error is returned. If you want to wait forever, supply
 // timeout, an error is returned. If you want to wait forever, supply
 // a negative duration for the timeout.
 // a negative duration for the timeout.
-func (daemon *Daemon) ContainerWait(name string, timeout time.Duration) (int, error) {
-	container, err := daemon.Get(name)
+func (daemon *Daemon) ContainerWait(ctx context.Context, name string, timeout time.Duration) (int, error) {
+	container, err := daemon.Get(ctx, name)
 	if err != nil {
 	if err != nil {
 		return -1, err
 		return -1, err
 	}
 	}

+ 15 - 9
docker/daemon.go

@@ -17,6 +17,7 @@ import (
 	"github.com/docker/docker/autogen/dockerversion"
 	"github.com/docker/docker/autogen/dockerversion"
 	"github.com/docker/docker/cli"
 	"github.com/docker/docker/cli"
 	"github.com/docker/docker/cliconfig"
 	"github.com/docker/docker/cliconfig"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/opts"
@@ -150,6 +151,11 @@ func getGlobalFlag() (globalFlag *flag.Flag) {
 
 
 // CmdDaemon is the daemon command, called the raw arguments after `docker daemon`.
 // CmdDaemon is the daemon command, called the raw arguments after `docker daemon`.
 func (cli *DaemonCli) CmdDaemon(args ...string) error {
 func (cli *DaemonCli) CmdDaemon(args ...string) error {
+	// This may need to be made even more global - it all depends
+	// on whether we want the CLI to have a context object too.
+	// For now we'll leave it as a daemon-side object only.
+	ctx := context.Background()
+
 	// warn from uuid package when running the daemon
 	// warn from uuid package when running the daemon
 	uuid.Loggerf = logrus.Warnf
 	uuid.Loggerf = logrus.Warnf
 
 
@@ -224,7 +230,7 @@ func (cli *DaemonCli) CmdDaemon(args ...string) error {
 		serverConfig.TLSConfig = tlsConfig
 		serverConfig.TLSConfig = tlsConfig
 	}
 	}
 
 
-	api := apiserver.New(serverConfig)
+	api := apiserver.New(ctx, serverConfig)
 
 
 	// The serve API routine never exits unless an error occurs
 	// The serve API routine never exits unless an error occurs
 	// We need to start it as a goroutine and wait on it so
 	// We need to start it as a goroutine and wait on it so
@@ -245,7 +251,7 @@ func (cli *DaemonCli) CmdDaemon(args ...string) error {
 	cli.TrustKeyPath = commonFlags.TrustKey
 	cli.TrustKeyPath = commonFlags.TrustKey
 
 
 	registryService := registry.NewService(cli.registryOptions)
 	registryService := registry.NewService(cli.registryOptions)
-	d, err := daemon.NewDaemon(cli.Config, registryService)
+	d, err := daemon.NewDaemon(ctx, cli.Config, registryService)
 	if err != nil {
 	if err != nil {
 		if pfile != nil {
 		if pfile != nil {
 			if err := pfile.Remove(); err != nil {
 			if err := pfile.Remove(); err != nil {
@@ -260,14 +266,14 @@ func (cli *DaemonCli) CmdDaemon(args ...string) error {
 	logrus.WithFields(logrus.Fields{
 	logrus.WithFields(logrus.Fields{
 		"version":     dockerversion.VERSION,
 		"version":     dockerversion.VERSION,
 		"commit":      dockerversion.GITCOMMIT,
 		"commit":      dockerversion.GITCOMMIT,
-		"execdriver":  d.ExecutionDriver().Name(),
-		"graphdriver": d.GraphDriver().String(),
+		"execdriver":  d.ExecutionDriver(ctx).Name(),
+		"graphdriver": d.GraphDriver(ctx).String(),
 	}).Info("Docker daemon")
 	}).Info("Docker daemon")
 
 
 	signal.Trap(func() {
 	signal.Trap(func() {
 		api.Close()
 		api.Close()
 		<-serveAPIWait
 		<-serveAPIWait
-		shutdownDaemon(d, 15)
+		shutdownDaemon(ctx, d, 15)
 		if pfile != nil {
 		if pfile != nil {
 			if err := pfile.Remove(); err != nil {
 			if err := pfile.Remove(); err != nil {
 				logrus.Error(err)
 				logrus.Error(err)
@@ -277,12 +283,12 @@ func (cli *DaemonCli) CmdDaemon(args ...string) error {
 
 
 	// after the daemon is done setting up we can tell the api to start
 	// after the daemon is done setting up we can tell the api to start
 	// accepting connections with specified daemon
 	// accepting connections with specified daemon
-	api.AcceptConnections(d)
+	api.AcceptConnections(ctx, d)
 
 
 	// Daemon is fully initialized and handling API traffic
 	// Daemon is fully initialized and handling API traffic
 	// Wait for serve API to complete
 	// Wait for serve API to complete
 	errAPI := <-serveAPIWait
 	errAPI := <-serveAPIWait
-	shutdownDaemon(d, 15)
+	shutdownDaemon(ctx, d, 15)
 	if errAPI != nil {
 	if errAPI != nil {
 		if pfile != nil {
 		if pfile != nil {
 			if err := pfile.Remove(); err != nil {
 			if err := pfile.Remove(); err != nil {
@@ -297,10 +303,10 @@ func (cli *DaemonCli) CmdDaemon(args ...string) error {
 // shutdownDaemon just wraps daemon.Shutdown() to handle a timeout in case
 // shutdownDaemon just wraps daemon.Shutdown() to handle a timeout in case
 // d.Shutdown() is waiting too long to kill container or worst it's
 // d.Shutdown() is waiting too long to kill container or worst it's
 // blocked there
 // blocked there
-func shutdownDaemon(d *daemon.Daemon, timeout time.Duration) {
+func shutdownDaemon(ctx context.Context, d *daemon.Daemon, timeout time.Duration) {
 	ch := make(chan struct{})
 	ch := make(chan struct{})
 	go func() {
 	go func() {
-		d.Shutdown()
+		d.Shutdown(ctx)
 		close(ch)
 		close(ch)
 	}()
 	}()
 	select {
 	select {

+ 3 - 2
graph/import.go

@@ -5,6 +5,7 @@ import (
 	"net/http"
 	"net/http"
 	"net/url"
 	"net/url"
 
 
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/pkg/httputils"
 	"github.com/docker/docker/pkg/httputils"
 	"github.com/docker/docker/pkg/progressreader"
 	"github.com/docker/docker/pkg/progressreader"
 	"github.com/docker/docker/pkg/streamformatter"
 	"github.com/docker/docker/pkg/streamformatter"
@@ -16,7 +17,7 @@ import (
 // inConfig (if src is "-"), or from a URI specified in src. Progress output is
 // inConfig (if src is "-"), or from a URI specified in src. Progress output is
 // written to outStream. Repository and tag names can optionally be given in
 // written to outStream. Repository and tag names can optionally be given in
 // the repo and tag arguments, respectively.
 // the repo and tag arguments, respectively.
-func (s *TagStore) Import(src string, repo string, tag string, msg string, inConfig io.ReadCloser, outStream io.Writer, containerConfig *runconfig.Config) error {
+func (s *TagStore) Import(ctx context.Context, src string, repo string, tag string, msg string, inConfig io.ReadCloser, outStream io.Writer, containerConfig *runconfig.Config) error {
 	var (
 	var (
 		sf      = streamformatter.NewJSONStreamFormatter()
 		sf      = streamformatter.NewJSONStreamFormatter()
 		archive io.ReadCloser
 		archive io.ReadCloser
@@ -74,6 +75,6 @@ func (s *TagStore) Import(src string, repo string, tag string, msg string, inCon
 		logID = utils.ImageReference(logID, tag)
 		logID = utils.ImageReference(logID, tag)
 	}
 	}
 
 
-	s.eventsService.Log("import", logID, "")
+	s.eventsService.Log(ctx, "import", logID, "")
 	return nil
 	return nil
 }
 }

+ 3 - 2
graph/pull.go

@@ -6,6 +6,7 @@ import (
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/cliconfig"
 	"github.com/docker/docker/cliconfig"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/pkg/streamformatter"
 	"github.com/docker/docker/pkg/streamformatter"
 	"github.com/docker/docker/registry"
 	"github.com/docker/docker/registry"
 	"github.com/docker/docker/utils"
 	"github.com/docker/docker/utils"
@@ -62,7 +63,7 @@ func NewPuller(s *TagStore, endpoint registry.APIEndpoint, repoInfo *registry.Re
 
 
 // Pull initiates a pull operation. image is the repository name to pull, and
 // Pull initiates a pull operation. image is the repository name to pull, and
 // tag may be either empty, or indicate a specific tag to pull.
 // tag may be either empty, or indicate a specific tag to pull.
-func (s *TagStore) Pull(image string, tag string, imagePullConfig *ImagePullConfig) error {
+func (s *TagStore) Pull(ctx context.Context, image string, tag string, imagePullConfig *ImagePullConfig) error {
 	var sf = streamformatter.NewJSONStreamFormatter()
 	var sf = streamformatter.NewJSONStreamFormatter()
 
 
 	// Resolve the Repository name from fqn to RepositoryInfo
 	// Resolve the Repository name from fqn to RepositoryInfo
@@ -131,7 +132,7 @@ func (s *TagStore) Pull(image string, tag string, imagePullConfig *ImagePullConf
 
 
 		}
 		}
 
 
-		s.eventsService.Log("pull", logName, "")
+		s.eventsService.Log(ctx, "pull", logName, "")
 		return nil
 		return nil
 	}
 	}
 
 

+ 3 - 2
graph/push.go

@@ -7,6 +7,7 @@ import (
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/digest"
 	"github.com/docker/distribution/digest"
 	"github.com/docker/docker/cliconfig"
 	"github.com/docker/docker/cliconfig"
+	"github.com/docker/docker/context"
 	"github.com/docker/docker/pkg/streamformatter"
 	"github.com/docker/docker/pkg/streamformatter"
 	"github.com/docker/docker/registry"
 	"github.com/docker/docker/registry"
 )
 )
@@ -67,7 +68,7 @@ func (s *TagStore) NewPusher(endpoint registry.APIEndpoint, localRepo Repository
 }
 }
 
 
 // Push initiates a push operation on the repository named localName.
 // Push initiates a push operation on the repository named localName.
-func (s *TagStore) Push(localName string, imagePushConfig *ImagePushConfig) error {
+func (s *TagStore) Push(ctx context.Context, localName string, imagePushConfig *ImagePushConfig) error {
 	// FIXME: Allow to interrupt current push when new push of same image is done.
 	// FIXME: Allow to interrupt current push when new push of same image is done.
 
 
 	var sf = streamformatter.NewJSONStreamFormatter()
 	var sf = streamformatter.NewJSONStreamFormatter()
@@ -115,7 +116,7 @@ func (s *TagStore) Push(localName string, imagePushConfig *ImagePushConfig) erro
 
 
 		}
 		}
 
 
-		s.eventsService.Log("push", repoInfo.LocalName, "")
+		s.eventsService.Log(ctx, "push", repoInfo.LocalName, "")
 		return nil
 		return nil
 	}
 	}
 
 

+ 76 - 1
integration-cli/docker_cli_events_test.go

@@ -410,7 +410,7 @@ func (s *DockerSuite) TestEventsFilterContainer(c *check.C) {
 			}
 			}
 
 
 			// Check the id
 			// Check the id
-			parsedID := strings.TrimSuffix(e[1], ":")
+			parsedID := strings.TrimSuffix(e[3], ":")
 			if parsedID != id {
 			if parsedID != id {
 				return fmt.Errorf("expected event for container id %s: %s - parsed container id: %s", id, event, parsedID)
 				return fmt.Errorf("expected event for container id %s: %s - parsed container id: %s", id, event, parsedID)
 			}
 			}
@@ -686,3 +686,78 @@ func (s *DockerRegistrySuite) TestEventsImageFilterPush(c *check.C) {
 		c.Fatalf("Missing 'push' log event for image %s\n%s", repoName, out)
 		c.Fatalf("Missing 'push' log event for image %s\n%s", repoName, out)
 	}
 	}
 }
 }
+
+func (s *DockerSuite) TestEventsReqID(c *check.C) {
+	// Tests for the "[reqid: xxx]" field in Events
+	testRequires(c, DaemonIsLinux)
+
+	reqIDMatch := `[^ ]+ \[reqid: ([0-9a-z]{12})\] [0-9a-z]+: `
+	reqIDRE := regexp.MustCompile(reqIDMatch)
+
+	// Simple test just to make sure it works at all
+	dockerCmd(c, "create", "busybox", "true")
+
+	out, _ := dockerCmd(c, "events", "--since=0", "--until=0s")
+	events := strings.Split(strings.TrimSpace(out), "\n")
+
+	if len(events) == 0 {
+		c.Fatalf("Wrong # of events, should just be one, got:\n%v\n", events)
+	}
+
+	createEvent := events[len(events)-1]
+
+	matched, err := regexp.MatchString(reqIDMatch, createEvent)
+	if err != nil || !matched {
+		c.Fatalf("Error finding reqID in event: %v\n", createEvent)
+	}
+
+	reqID1 := reqIDRE.FindStringSubmatch(createEvent)[1]
+
+	// Now make sure another cmd doesn't get the same reqID
+	dockerCmd(c, "create", "busybox", "true")
+
+	out, _ = dockerCmd(c, "events", "--since=0", "--until=0s")
+	events = strings.Split(strings.TrimSpace(out), "\n")
+	createEvent = events[len(events)-1]
+
+	matched, err = regexp.MatchString(reqIDMatch, createEvent)
+	if err != nil || !matched {
+		c.Fatalf("Error finding reqID in event: %v\n", createEvent)
+	}
+
+	reqID2 := reqIDRE.FindStringSubmatch(createEvent)[1]
+
+	if reqID1 == reqID2 {
+		c.Fatalf("Should not have the same reqID(%s):\n%v\n", reqID1, createEvent)
+	}
+
+	// Now make sure a build **does** use the same reqID for all
+	// 4 events that are generated
+	_, err = buildImage("reqidimg", `
+		  FROM busybox
+		  RUN echo HI`, true)
+	if err != nil {
+		c.Fatalf("Couldn't create image: %q", err)
+	}
+
+	out, _ = dockerCmd(c, "events", "--since=0", "--until=0s")
+	events = strings.Split(strings.TrimSpace(out), "\n")
+
+	// Get last event's reqID - will use it to find other matching events
+	lastEvent := events[len(events)-1]
+	reqID := reqIDRE.FindStringSubmatch(lastEvent)[1]
+
+	// Find all events with this same reqID
+	eventList := []string{lastEvent}
+	for i := len(events) - 2; i >= 0; i-- {
+		tmpID := reqIDRE.FindStringSubmatch(events[i])[1]
+		if tmpID != reqID {
+			break
+		}
+		eventList = append(eventList, events[i])
+	}
+
+	if len(eventList) != 5 { // create, start, die, commit, destroy
+		c.Fatalf("Wrong # of matching events - should be 5:\n%q\n", eventList)
+	}
+}

+ 4 - 0
pkg/jsonmessage/jsonmessage.go

@@ -92,6 +92,7 @@ func (p *JSONProgress) String() string {
 // the created time, where it from, status, ID of the
 // the created time, where it from, status, ID of the
 // message. It's used for docker events.
 // message. It's used for docker events.
 type JSONMessage struct {
 type JSONMessage struct {
+	RequestID       string        `json:"reqid,omitempty"`
 	Stream          string        `json:"stream,omitempty"`
 	Stream          string        `json:"stream,omitempty"`
 	Status          string        `json:"status,omitempty"`
 	Status          string        `json:"status,omitempty"`
 	Progress        *JSONProgress `json:"progressDetail,omitempty"`
 	Progress        *JSONProgress `json:"progressDetail,omitempty"`
@@ -127,6 +128,9 @@ func (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error {
 	} else if jm.Time != 0 {
 	} else if jm.Time != 0 {
 		fmt.Fprintf(out, "%s ", time.Unix(jm.Time, 0).Format(timeutils.RFC3339NanoFixed))
 		fmt.Fprintf(out, "%s ", time.Unix(jm.Time, 0).Format(timeutils.RFC3339NanoFixed))
 	}
 	}
+	if jm.RequestID != "" {
+		fmt.Fprintf(out, "[reqid: %s] ", jm.RequestID)
+	}
 	if jm.ID != "" {
 	if jm.ID != "" {
 		fmt.Fprintf(out, "%s: ", jm.ID)
 		fmt.Fprintf(out, "%s: ", jm.ID)
 	}
 	}