소스 검색

Merge pull request #20699 from calavera/remove_static_error_declarations

Remove static errors from errors package.
David Calavera 9 년 전
부모
커밋
df2b74188e
67개의 변경된 파일452개의 추가작업 그리고 1626개의 파일을 삭제
  1. 9 12
      api/client/run.go
  2. 69 0
      api/server/httputils/errors.go
  3. 0 74
      api/server/httputils/httputils.go
  4. 10 3
      api/server/middleware/version.go
  5. 2 2
      api/server/middleware/version_test.go
  6. 1 3
      api/server/router/build/build_routes.go
  7. 11 8
      api/server/router/container/container_routes.go
  8. 2 3
      api/server/router/container/exec.go
  9. 0 1
      api/server/router/image/backend.go
  10. 0 5
      api/server/router/image/image_routes.go
  11. 0 2
      api/server/router/network/backend.go
  12. 7 25
      api/server/router/network/network.go
  13. 1 2
      api/server/server.go
  14. 29 18
      builder/dockerfile/dispatchers.go
  15. 2 10
      container/container.go
  16. 11 7
      container/container_unix.go
  17. 4 5
      container/monitor.go
  18. 5 5
      container/state.go
  19. 4 3
      daemon/attach.go
  20. 20 15
      daemon/container_operations_unix.go
  21. 5 5
      daemon/container_operations_windows.go
  22. 4 3
      daemon/create.go
  23. 2 2
      daemon/create_unix.go
  24. 9 7
      daemon/daemon.go
  25. 4 5
      daemon/daemon_unix.go
  26. 12 14
      daemon/delete.go
  27. 1 3
      daemon/delete_test.go
  28. 35 4
      daemon/errors.go
  29. 17 15
      daemon/exec.go
  30. 2 2
      daemon/exec/exec.go
  31. 1 2
      daemon/execdriver/native/create.go
  32. 3 3
      daemon/export.go
  33. 3 2
      daemon/image_delete.go
  34. 4 5
      daemon/kill.go
  35. 4 4
      daemon/logs.go
  36. 2 2
      daemon/mounts.go
  37. 4 2
      daemon/network.go
  38. 6 5
      daemon/pause.go
  39. 3 3
      daemon/rename.go
  40. 2 6
      daemon/resize.go
  41. 3 2
      daemon/restart.go
  42. 7 5
      daemon/start.go
  43. 4 4
      daemon/stats_collector_unix.go
  44. 6 3
      daemon/stop.go
  45. 6 6
      daemon/top_unix.go
  46. 3 2
      daemon/top_windows.go
  47. 5 4
      daemon/unpause.go
  48. 8 7
      daemon/update.go
  49. 2 2
      daemon/volumes.go
  50. 2 2
      daemon/volumes_windows.go
  51. 9 3
      docker/daemon.go
  52. 0 58
      errors/README.md
  53. 0 93
      errors/builder.go
  54. 0 1013
      errors/daemon.go
  55. 0 6
      errors/error.go
  56. 41 0
      errors/errors.go
  57. 0 20
      errors/image.go
  58. 0 45
      errors/server.go
  59. 1 1
      integration-cli/docker_api_containers_test.go
  60. 1 1
      integration-cli/docker_cli_run_test.go
  61. 0 20
      utils/utils.go
  62. 11 5
      volume/local/local.go
  63. 13 5
      volume/volume.go
  64. 2 2
      volume/volume_propagation_linux_test.go
  65. 2 2
      volume/volume_test.go
  66. 8 10
      volume/volume_unix.go
  67. 8 8
      volume/volume_windows.go

+ 9 - 12
api/client/run.go

@@ -11,7 +11,6 @@ import (
 
 	"github.com/Sirupsen/logrus"
 	Cli "github.com/docker/docker/cli"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/pkg/promise"
 	"github.com/docker/docker/pkg/signal"
@@ -21,6 +20,11 @@ import (
 	"github.com/docker/libnetwork/resolvconf/dns"
 )
 
+const (
+	errCmdNotFound          = "Container command not found or does not exist."
+	errCmdCouldNotBeInvoked = "Container command could not be invoked."
+)
+
 func (cid *cidFile) Close() error {
 	cid.file.Close()
 
@@ -46,20 +50,13 @@ func (cid *cidFile) Write(id string) error {
 // return 125 for generic docker daemon failures
 func runStartContainerErr(err error) error {
 	trimmedErr := strings.Trim(err.Error(), "Error response from daemon: ")
-	statusError := Cli.StatusError{}
-	derrCmdNotFound := derr.ErrorCodeCmdNotFound.Message()
-	derrCouldNotInvoke := derr.ErrorCodeCmdCouldNotBeInvoked.Message()
-	derrNoSuchImage := derr.ErrorCodeNoSuchImageHash.Message()
-	derrNoSuchImageTag := derr.ErrorCodeNoSuchImageTag.Message()
+	statusError := Cli.StatusError{StatusCode: 125}
+
 	switch trimmedErr {
-	case derrCmdNotFound:
+	case errCmdNotFound:
 		statusError = Cli.StatusError{StatusCode: 127}
-	case derrCouldNotInvoke:
+	case errCmdCouldNotBeInvoked:
 		statusError = Cli.StatusError{StatusCode: 126}
-	case derrNoSuchImage, derrNoSuchImageTag:
-		statusError = Cli.StatusError{StatusCode: 125}
-	default:
-		statusError = Cli.StatusError{StatusCode: 125}
 	}
 	return statusError
 }

+ 69 - 0
api/server/httputils/errors.go

@@ -0,0 +1,69 @@
+package httputils
+
+import (
+	"net/http"
+	"strings"
+
+	"github.com/Sirupsen/logrus"
+)
+
+// httpStatusError is an interface
+// that errors with custom status codes
+// implement to tell the api layer
+// which response status to set.
+type httpStatusError interface {
+	HTTPErrorStatusCode() int
+}
+
+// inputValidationError is an interface
+// that errors generated by invalid
+// inputs can implement to tell the
+// api layer to set a 400 status code
+// in the response.
+type inputValidationError interface {
+	IsValidationError() bool
+}
+
+// WriteError decodes a specific docker error and sends it in the response.
+func WriteError(w http.ResponseWriter, err error) {
+	if err == nil || w == nil {
+		logrus.WithFields(logrus.Fields{"error": err, "writer": w}).Error("unexpected HTTP error handling")
+		return
+	}
+
+	var statusCode int
+	errMsg := err.Error()
+
+	switch e := err.(type) {
+	case httpStatusError:
+		statusCode = e.HTTPErrorStatusCode()
+	case inputValidationError:
+		statusCode = http.StatusBadRequest
+	default:
+		// FIXME: this is brittle and should not be necessary, but we still need to identify if
+		// there are errors falling back into this logic.
+		// If we need to differentiate between different possible error types,
+		// we should create appropriate error types that implement the httpStatusError interface.
+		errStr := strings.ToLower(errMsg)
+		for keyword, status := range map[string]int{
+			"not found":             http.StatusNotFound,
+			"no such":               http.StatusNotFound,
+			"bad parameter":         http.StatusBadRequest,
+			"conflict":              http.StatusConflict,
+			"impossible":            http.StatusNotAcceptable,
+			"wrong login/password":  http.StatusUnauthorized,
+			"hasn't been activated": http.StatusForbidden,
+		} {
+			if strings.Contains(errStr, keyword) {
+				statusCode = status
+				break
+			}
+		}
+	}
+
+	if statusCode == 0 {
+		statusCode = http.StatusInternalServerError
+	}
+
+	http.Error(w, errMsg, statusCode)
+}

+ 0 - 74
api/server/httputils/httputils.go

@@ -9,8 +9,6 @@ import (
 
 	"golang.org/x/net/context"
 
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/distribution/registry/api/errcode"
 	"github.com/docker/docker/api"
 	"github.com/docker/docker/pkg/version"
 )
@@ -85,78 +83,6 @@ func ParseMultipartForm(r *http.Request) error {
 	return nil
 }
 
-// WriteError decodes a specific docker error and sends it in the response.
-func WriteError(w http.ResponseWriter, err error) {
-	if err == nil || w == nil {
-		logrus.WithFields(logrus.Fields{"error": err, "writer": w}).Error("unexpected HTTP error handling")
-		return
-	}
-
-	statusCode := http.StatusInternalServerError
-	errMsg := err.Error()
-
-	// Based on the type of error we get we need to process things
-	// slightly differently to extract the error message.
-	// In the 'errcode.*' cases there are two different type of
-	// error that could be returned. errocode.ErrorCode is the base
-	// type of error object - it is just an 'int' that can then be
-	// used as the look-up key to find the message. errorcode.Error
-	// extends errorcode.Error by adding error-instance specific
-	// data, like 'details' or variable strings to be inserted into
-	// the message.
-	//
-	// Ideally, we should just be able to call err.Error() for all
-	// cases but the errcode package doesn't support that yet.
-	//
-	// Additionally, in both errcode cases, there might be an http
-	// status code associated with it, and if so use it.
-	switch err.(type) {
-	case errcode.ErrorCode:
-		daError, _ := err.(errcode.ErrorCode)
-		statusCode = daError.Descriptor().HTTPStatusCode
-		errMsg = daError.Message()
-
-	case errcode.Error:
-		// For reference, if you're looking for a particular error
-		// then you can do something like :
-		//   import ( derr "github.com/docker/docker/errors" )
-		//   if daError.ErrorCode() == derr.ErrorCodeNoSuchContainer { ... }
-
-		daError, _ := err.(errcode.Error)
-		statusCode = daError.ErrorCode().Descriptor().HTTPStatusCode
-		errMsg = daError.Message
-
-	default:
-		// This part of will be removed once we've
-		// converted everything over to use the errcode package
-
-		// FIXME: this is brittle and should not be necessary.
-		// If we need to differentiate between different possible error types,
-		// we should create appropriate error types with clearly defined meaning
-		errStr := strings.ToLower(err.Error())
-		for keyword, status := range map[string]int{
-			"not found":             http.StatusNotFound,
-			"no such":               http.StatusNotFound,
-			"bad parameter":         http.StatusBadRequest,
-			"conflict":              http.StatusConflict,
-			"impossible":            http.StatusNotAcceptable,
-			"wrong login/password":  http.StatusUnauthorized,
-			"hasn't been activated": http.StatusForbidden,
-		} {
-			if strings.Contains(errStr, keyword) {
-				statusCode = status
-				break
-			}
-		}
-	}
-
-	if statusCode == 0 {
-		statusCode = http.StatusInternalServerError
-	}
-
-	http.Error(w, errMsg, statusCode)
-}
-
 // WriteJSON writes the value v to the http response stream as json with standard json encoding.
 func WriteJSON(w http.ResponseWriter, code int, v interface{}) error {
 	w.Header().Set("Content-Type", "application/json")

+ 10 - 3
api/server/middleware/version.go

@@ -6,11 +6,18 @@ import (
 	"runtime"
 
 	"github.com/docker/docker/api/server/httputils"
-	"github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/version"
 	"golang.org/x/net/context"
 )
 
+type badRequestError struct {
+	error
+}
+
+func (badRequestError) HTTPErrorStatusCode() int {
+	return http.StatusBadRequest
+}
+
 // NewVersionMiddleware creates a new Version middleware.
 func NewVersionMiddleware(versionCheck string, defaultVersion, minVersion version.Version) Middleware {
 	serverVersion := version.Version(versionCheck)
@@ -23,10 +30,10 @@ func NewVersionMiddleware(versionCheck string, defaultVersion, minVersion versio
 			}
 
 			if apiVersion.GreaterThan(defaultVersion) {
-				return errors.ErrorCodeNewerClientVersion.WithArgs(apiVersion, defaultVersion)
+				return badRequestError{fmt.Errorf("client is newer than server (client API version: %s, server API version: %s)", apiVersion, defaultVersion)}
 			}
 			if apiVersion.LessThan(minVersion) {
-				return errors.ErrorCodeOldClientVersion.WithArgs(apiVersion, minVersion)
+				return badRequestError{fmt.Errorf("client version %s is too old. Minimum supported API version is %s, please upgrade your client to a newer version", apiVersion, minVersion)}
 			}
 
 			header := fmt.Sprintf("Docker/%s (%s)", serverVersion, runtime.GOOS)

+ 2 - 2
api/server/middleware/version_test.go

@@ -53,12 +53,12 @@ func TestVersionMiddlewareWithErrors(t *testing.T) {
 	err := h(ctx, resp, req, vars)
 
 	if !strings.Contains(err.Error(), "client version 0.1 is too old. Minimum supported API version is 1.2.0") {
-		t.Fatalf("Expected ErrorCodeOldClientVersion, got %v", err)
+		t.Fatalf("Expected too old client error, got %v", err)
 	}
 
 	vars["version"] = "100000"
 	err = h(ctx, resp, req, vars)
 	if !strings.Contains(err.Error(), "client is newer than server") {
-		t.Fatalf("Expected ErrorCodeNewerClientVersion, got %v", err)
+		t.Fatalf("Expected client newer than server error, got %v", err)
 	}
 }

+ 1 - 3
api/server/router/build/build_routes.go

@@ -4,7 +4,6 @@ import (
 	"bytes"
 	"encoding/base64"
 	"encoding/json"
-	"errors"
 	"fmt"
 	"io"
 	"net/http"
@@ -17,7 +16,6 @@ import (
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/progress"
 	"github.com/docker/docker/pkg/streamformatter"
-	"github.com/docker/docker/utils"
 	"github.com/docker/engine-api/types"
 	"github.com/docker/engine-api/types/container"
 	"github.com/docker/go-units"
@@ -117,7 +115,7 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
 		if !output.Flushed() {
 			return err
 		}
-		_, err = w.Write(sf.FormatError(errors.New(utils.GetErrorMessage(err))))
+		_, err = w.Write(sf.FormatError(err))
 		if err != nil {
 			logrus.Warnf("could not write error response: %v", err)
 		}

+ 11 - 8
api/server/router/container/container_routes.go

@@ -11,15 +11,12 @@ import (
 	"time"
 
 	"github.com/Sirupsen/logrus"
-	"github.com/docker/distribution/registry/api/errcode"
 	"github.com/docker/docker/api/server/httputils"
 	"github.com/docker/docker/api/types/backend"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/signal"
 	"github.com/docker/docker/pkg/term"
 	"github.com/docker/docker/runconfig"
-	"github.com/docker/docker/utils"
 	"github.com/docker/engine-api/types"
 	"github.com/docker/engine-api/types/container"
 	"github.com/docker/engine-api/types/filters"
@@ -126,7 +123,7 @@ func (s *containerRouter) getContainersLogs(ctx context.Context, w http.Response
 			// The client may be expecting all of the data we're sending to
 			// be multiplexed, so send it through OutStream, which will
 			// have been set up to handle that if needed.
-			fmt.Fprintf(logsConfig.OutStream, "Error running logs job: %s\n", utils.GetErrorMessage(err))
+			fmt.Fprintf(logsConfig.OutStream, "Error running logs job: %v\n", err)
 		default:
 			return err
 		}
@@ -182,6 +179,10 @@ func (s *containerRouter) postContainersStop(ctx context.Context, w http.Respons
 	return nil
 }
 
+type errContainerIsRunning interface {
+	ContainerIsRunning() bool
+}
+
 func (s *containerRouter) postContainersKill(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	if err := httputils.ParseForm(r); err != nil {
 		return err
@@ -199,15 +200,17 @@ func (s *containerRouter) postContainersKill(ctx context.Context, w http.Respons
 	}
 
 	if err := s.backend.ContainerKill(name, uint64(sig)); err != nil {
-		theErr, isDerr := err.(errcode.ErrorCoder)
-		isStopped := isDerr && theErr.ErrorCode() == derr.ErrorCodeNotRunning
+		var isStopped bool
+		if e, ok := err.(errContainerIsRunning); ok {
+			isStopped = !e.ContainerIsRunning()
+		}
 
 		// Return error that's not caused because the container is stopped.
 		// Return error if the container is not running and the api is >= 1.20
 		// to keep backwards compatibility.
 		version := httputils.VersionFromContext(ctx)
 		if version.GreaterThanOrEqualTo("1.20") || !isStopped {
-			return fmt.Errorf("Cannot kill container %s: %v", name, utils.GetErrorMessage(err))
+			return fmt.Errorf("Cannot kill container %s: %v", name, err)
 		}
 	}
 
@@ -430,7 +433,7 @@ func (s *containerRouter) postContainersAttach(ctx context.Context, w http.Respo
 
 	hijacker, ok := w.(http.Hijacker)
 	if !ok {
-		return derr.ErrorCodeNoHijackConnection.WithArgs(containerName)
+		return fmt.Errorf("error attaching to container %s, hijack connection missing", containerName)
 	}
 
 	setupStreams := func() (io.ReadCloser, io.Writer, io.Writer, error) {

+ 2 - 3
api/server/router/container/exec.go

@@ -10,7 +10,6 @@ import (
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/server/httputils"
 	"github.com/docker/docker/pkg/stdcopy"
-	"github.com/docker/docker/utils"
 	"github.com/docker/engine-api/types"
 	"golang.org/x/net/context"
 )
@@ -46,7 +45,7 @@ func (s *containerRouter) postContainerExecCreate(ctx context.Context, w http.Re
 	// Register an instance of Exec in container.
 	id, err := s.backend.ContainerExecCreate(execConfig)
 	if err != nil {
-		logrus.Errorf("Error setting up exec command in container %s: %s", name, utils.GetErrorMessage(err))
+		logrus.Errorf("Error setting up exec command in container %s: %v", name, err)
 		return err
 	}
 
@@ -113,7 +112,7 @@ func (s *containerRouter) postContainerExecStart(ctx context.Context, w http.Res
 		if execStartCheck.Detach {
 			return err
 		}
-		logrus.Errorf("Error running exec in container: %v\n", utils.GetErrorMessage(err))
+		logrus.Errorf("Error running exec in container: %v\n", err)
 	}
 	return nil
 }

+ 0 - 1
api/server/router/image/backend.go

@@ -20,7 +20,6 @@ type Backend interface {
 
 type containerBackend interface {
 	Commit(name string, config *types.ContainerCommitConfig) (imageID string, err error)
-	Exists(containerName string) bool
 }
 
 type imageBackend interface {

+ 0 - 5
api/server/router/image/image_routes.go

@@ -14,7 +14,6 @@ import (
 	"github.com/docker/distribution/registry/api/errcode"
 	"github.com/docker/docker/api/server/httputils"
 	"github.com/docker/docker/builder/dockerfile"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/streamformatter"
 	"github.com/docker/docker/reference"
@@ -49,10 +48,6 @@ func (s *imageRouter) postCommit(ctx context.Context, w http.ResponseWriter, r *
 		c = &container.Config{}
 	}
 
-	if !s.backend.Exists(cname) {
-		return derr.ErrorCodeNoSuchContainer.WithArgs(cname)
-	}
-
 	newConfig, err := dockerfile.BuildFromConfig(c, r.Form["changes"])
 	if err != nil {
 		return err

+ 0 - 2
api/server/router/network/backend.go

@@ -8,8 +8,6 @@ import (
 // Backend is all the methods that need to be implemented
 // to provide network specific functionality.
 type Backend interface {
-	NetworkControllerEnabled() bool
-
 	FindNetwork(idName string) (libnetwork.Network, error)
 	GetNetworkByName(idName string) (libnetwork.Network, error)
 	GetNetworksByID(partialID string) []libnetwork.Network

+ 7 - 25
api/server/router/network/network.go

@@ -1,13 +1,6 @@
 package network
 
-import (
-	"net/http"
-
-	"github.com/docker/docker/api/server/httputils"
-	"github.com/docker/docker/api/server/router"
-	"github.com/docker/docker/errors"
-	"golang.org/x/net/context"
-)
+import "github.com/docker/docker/api/server/router"
 
 // networkRouter is a router to talk with the network controller
 type networkRouter struct {
@@ -32,24 +25,13 @@ func (r *networkRouter) Routes() []router.Route {
 func (r *networkRouter) initRoutes() {
 	r.routes = []router.Route{
 		// GET
-		router.NewGetRoute("/networks", r.controllerEnabledMiddleware(r.getNetworksList)),
-		router.NewGetRoute("/networks/{id:.*}", r.controllerEnabledMiddleware(r.getNetwork)),
+		router.NewGetRoute("/networks", r.getNetworksList),
+		router.NewGetRoute("/networks/{id:.*}", r.getNetwork),
 		// POST
-		router.NewPostRoute("/networks/create", r.controllerEnabledMiddleware(r.postNetworkCreate)),
-		router.NewPostRoute("/networks/{id:.*}/connect", r.controllerEnabledMiddleware(r.postNetworkConnect)),
-		router.NewPostRoute("/networks/{id:.*}/disconnect", r.controllerEnabledMiddleware(r.postNetworkDisconnect)),
+		router.NewPostRoute("/networks/create", r.postNetworkCreate),
+		router.NewPostRoute("/networks/{id:.*}/connect", r.postNetworkConnect),
+		router.NewPostRoute("/networks/{id:.*}/disconnect", r.postNetworkDisconnect),
 		// DELETE
-		router.NewDeleteRoute("/networks/{id:.*}", r.controllerEnabledMiddleware(r.deleteNetwork)),
-	}
-}
-
-func (r *networkRouter) controllerEnabledMiddleware(handler httputils.APIFunc) httputils.APIFunc {
-	if r.backend.NetworkControllerEnabled() {
-		return handler
+		router.NewDeleteRoute("/networks/{id:.*}", r.deleteNetwork),
 	}
-	return networkControllerDisabled
-}
-
-func networkControllerDisabled(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
-	return errors.ErrorNetworkControllerNotEnabled.WithArgs()
 }

+ 1 - 2
api/server/server.go

@@ -10,7 +10,6 @@ import (
 	"github.com/docker/docker/api/server/httputils"
 	"github.com/docker/docker/api/server/router"
 	"github.com/docker/docker/pkg/authorization"
-	"github.com/docker/docker/utils"
 	"github.com/gorilla/mux"
 	"golang.org/x/net/context"
 )
@@ -134,7 +133,7 @@ func (s *Server) makeHTTPHandler(handler httputils.APIFunc) http.HandlerFunc {
 		}
 
 		if err := handlerFunc(ctx, w, r, vars); err != nil {
-			logrus.Errorf("Handler for %s %s returned error: %s", r.Method, r.URL.Path, utils.GetErrorMessage(err))
+			logrus.Errorf("Handler for %s %s returned error: %v", r.Method, r.URL.Path, err)
 			httputils.WriteError(w, err)
 		}
 	}

+ 29 - 18
builder/dockerfile/dispatchers.go

@@ -19,7 +19,6 @@ import (
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api"
 	"github.com/docker/docker/builder"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/signal"
 	"github.com/docker/docker/pkg/system"
 	runconfigopts "github.com/docker/docker/runconfig/opts"
@@ -40,12 +39,12 @@ func nullDispatch(b *Builder, args []string, attributes map[string]bool, origina
 //
 func env(b *Builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) == 0 {
-		return derr.ErrorCodeAtLeastOneArg.WithArgs("ENV")
+		return errAtLeastOneArgument("ENV")
 	}
 
 	if len(args)%2 != 0 {
 		// should never get here, but just in case
-		return derr.ErrorCodeTooManyArgs.WithArgs("ENV")
+		return errTooManyArguments("ENV")
 	}
 
 	if err := b.flags.Parse(); err != nil {
@@ -99,7 +98,7 @@ func env(b *Builder, args []string, attributes map[string]bool, original string)
 // Sets the maintainer metadata.
 func maintainer(b *Builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) != 1 {
-		return derr.ErrorCodeExactlyOneArg.WithArgs("MAINTAINER")
+		return errExactlyOneArgument("MAINTAINER")
 	}
 
 	if err := b.flags.Parse(); err != nil {
@@ -116,11 +115,11 @@ func maintainer(b *Builder, args []string, attributes map[string]bool, original
 //
 func label(b *Builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) == 0 {
-		return derr.ErrorCodeAtLeastOneArg.WithArgs("LABEL")
+		return errAtLeastOneArgument("LABEL")
 	}
 	if len(args)%2 != 0 {
 		// should never get here, but just in case
-		return derr.ErrorCodeTooManyArgs.WithArgs("LABEL")
+		return errTooManyArguments("LABEL")
 	}
 
 	if err := b.flags.Parse(); err != nil {
@@ -152,7 +151,7 @@ func label(b *Builder, args []string, attributes map[string]bool, original strin
 //
 func add(b *Builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) < 2 {
-		return derr.ErrorCodeAtLeastTwoArgs.WithArgs("ADD")
+		return errAtLeastOneArgument("ADD")
 	}
 
 	if err := b.flags.Parse(); err != nil {
@@ -168,7 +167,7 @@ func add(b *Builder, args []string, attributes map[string]bool, original string)
 //
 func dispatchCopy(b *Builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) < 2 {
-		return derr.ErrorCodeAtLeastTwoArgs.WithArgs("COPY")
+		return errAtLeastOneArgument("COPY")
 	}
 
 	if err := b.flags.Parse(); err != nil {
@@ -184,7 +183,7 @@ func dispatchCopy(b *Builder, args []string, attributes map[string]bool, origina
 //
 func from(b *Builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) != 1 {
-		return derr.ErrorCodeExactlyOneArg.WithArgs("FROM")
+		return errExactlyOneArgument("FROM")
 	}
 
 	if err := b.flags.Parse(); err != nil {
@@ -233,7 +232,7 @@ func from(b *Builder, args []string, attributes map[string]bool, original string
 //
 func onbuild(b *Builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) == 0 {
-		return derr.ErrorCodeAtLeastOneArg.WithArgs("ONBUILD")
+		return errAtLeastOneArgument("ONBUILD")
 	}
 
 	if err := b.flags.Parse(); err != nil {
@@ -243,9 +242,9 @@ func onbuild(b *Builder, args []string, attributes map[string]bool, original str
 	triggerInstruction := strings.ToUpper(strings.TrimSpace(args[0]))
 	switch triggerInstruction {
 	case "ONBUILD":
-		return derr.ErrorCodeChainOnBuild
+		return fmt.Errorf("Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed")
 	case "MAINTAINER", "FROM":
-		return derr.ErrorCodeBadOnBuildCmd.WithArgs(triggerInstruction)
+		return fmt.Errorf("%s isn't allowed as an ONBUILD trigger", triggerInstruction)
 	}
 
 	original = regexp.MustCompile(`(?i)^\s*ONBUILD\s*`).ReplaceAllString(original, "")
@@ -260,7 +259,7 @@ func onbuild(b *Builder, args []string, attributes map[string]bool, original str
 //
 func workdir(b *Builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) != 1 {
-		return derr.ErrorCodeExactlyOneArg.WithArgs("WORKDIR")
+		return errExactlyOneArgument("WORKDIR")
 	}
 
 	if err := b.flags.Parse(); err != nil {
@@ -293,7 +292,7 @@ func workdir(b *Builder, args []string, attributes map[string]bool, original str
 //
 func run(b *Builder, args []string, attributes map[string]bool, original string) error {
 	if b.image == "" && !b.noBaseImage {
-		return derr.ErrorCodeMissingFrom
+		return fmt.Errorf("Please provide a source image with `from` prior to run")
 	}
 
 	if err := b.flags.Parse(); err != nil {
@@ -491,7 +490,7 @@ func expose(b *Builder, args []string, attributes map[string]bool, original stri
 	portsTab := args
 
 	if len(args) == 0 {
-		return derr.ErrorCodeAtLeastOneArg.WithArgs("EXPOSE")
+		return errAtLeastOneArgument("EXPOSE")
 	}
 
 	if err := b.flags.Parse(); err != nil {
@@ -530,7 +529,7 @@ func expose(b *Builder, args []string, attributes map[string]bool, original stri
 //
 func user(b *Builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) != 1 {
-		return derr.ErrorCodeExactlyOneArg.WithArgs("USER")
+		return errExactlyOneArgument("USER")
 	}
 
 	if err := b.flags.Parse(); err != nil {
@@ -547,7 +546,7 @@ func user(b *Builder, args []string, attributes map[string]bool, original string
 //
 func volume(b *Builder, args []string, attributes map[string]bool, original string) error {
 	if len(args) == 0 {
-		return derr.ErrorCodeAtLeastOneArg.WithArgs("VOLUME")
+		return errAtLeastOneArgument("VOLUME")
 	}
 
 	if err := b.flags.Parse(); err != nil {
@@ -560,7 +559,7 @@ func volume(b *Builder, args []string, attributes map[string]bool, original stri
 	for _, v := range args {
 		v = strings.TrimSpace(v)
 		if v == "" {
-			return derr.ErrorCodeVolumeEmpty
+			return fmt.Errorf("Volume specified can not be an empty string")
 		}
 		b.runConfig.Volumes[v] = struct{}{}
 	}
@@ -631,3 +630,15 @@ func arg(b *Builder, args []string, attributes map[string]bool, original string)
 
 	return b.commit("", b.runConfig.Cmd, fmt.Sprintf("ARG %s", arg))
 }
+
+func errAtLeastOneArgument(command string) error {
+	return fmt.Errorf("%s requires at least one argument", command)
+}
+
+func errExactlyOneArgument(command string) error {
+	return fmt.Errorf("%s requires exactly one argument", command)
+}
+
+func errTooManyArguments(command string) error {
+	return fmt.Errorf("Bad input to %s, too many arguments", command)
+}

+ 2 - 10
container/container.go

@@ -16,7 +16,6 @@ import (
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/daemon/logger/jsonfilelog"
 	"github.com/docker/docker/daemon/network"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/layer"
 	"github.com/docker/docker/pkg/promise"
@@ -199,7 +198,7 @@ func (container *Container) SetupWorkingDirectory() error {
 	if err := system.MkdirAll(pth, 0755); err != nil {
 		pthInfo, err2 := os.Stat(pth)
 		if err2 == nil && pthInfo != nil && !pthInfo.IsDir() {
-			return derr.ErrorCodeNotADir.WithArgs(container.Config.WorkingDir)
+			return fmt.Errorf("Cannot mkdir: %s is not a directory", container.Config.WorkingDir)
 		}
 
 		return err
@@ -277,13 +276,6 @@ func (container *Container) ConfigPath() (string, error) {
 	return container.GetRootResourcePath(configFileName)
 }
 
-func validateID(id string) error {
-	if id == "" {
-		return derr.ErrorCodeEmptyID
-	}
-	return nil
-}
-
 // Returns true if the container exposes a certain port
 func (container *Container) exposes(p nat.Port) bool {
 	_, exists := container.Config.ExposedPorts[p]
@@ -307,7 +299,7 @@ func (container *Container) GetLogConfig(defaultConfig containertypes.LogConfig)
 func (container *Container) StartLogger(cfg containertypes.LogConfig) (logger.Logger, error) {
 	c, err := logger.GetLogDriver(cfg.Type)
 	if err != nil {
-		return nil, derr.ErrorCodeLoggingFactory.WithArgs(err)
+		return nil, fmt.Errorf("Failed to get logging factory: %v", err)
 	}
 	ctx := logger.Context{
 		Config:              cfg.Config,

+ 11 - 7
container/container_unix.go

@@ -14,7 +14,6 @@ import (
 
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/execdriver"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/chrootarchive"
 	"github.com/docker/docker/pkg/symlink"
 	"github.com/docker/docker/pkg/system"
@@ -34,6 +33,11 @@ import (
 // DefaultSHMSize is the default size (64MB) of the SHM which will be mounted in the container
 const DefaultSHMSize int64 = 67108864
 
+var (
+	errInvalidEndpoint = fmt.Errorf("invalid endpoint while building port map info")
+	errInvalidNetwork  = fmt.Errorf("invalid network settings while building port map info")
+)
+
 // Container holds the fields specific to unixen implementations.
 // See CommonContainer for standard fields common to all containers.
 type Container struct {
@@ -116,12 +120,12 @@ func (container *Container) GetEndpointInNetwork(n libnetwork.Network) (libnetwo
 
 func (container *Container) buildPortMapInfo(ep libnetwork.Endpoint) error {
 	if ep == nil {
-		return derr.ErrorCodeEmptyEndpoint
+		return errInvalidEndpoint
 	}
 
 	networkSettings := container.NetworkSettings
 	if networkSettings == nil {
-		return derr.ErrorCodeEmptyNetwork
+		return errInvalidNetwork
 	}
 
 	if len(networkSettings.Ports) == 0 {
@@ -151,7 +155,7 @@ func getEndpointPortMapInfo(ep libnetwork.Endpoint) (nat.PortMap, error) {
 			for _, tp := range exposedPorts {
 				natPort, err := nat.NewPort(tp.Proto.String(), strconv.Itoa(int(tp.Port)))
 				if err != nil {
-					return pm, derr.ErrorCodeParsingPort.WithArgs(tp.Port, err)
+					return pm, fmt.Errorf("Error parsing Port value(%v):%v", tp.Port, err)
 				}
 				pm[natPort] = nil
 			}
@@ -195,12 +199,12 @@ func getSandboxPortMapInfo(sb libnetwork.Sandbox) nat.PortMap {
 // BuildEndpointInfo sets endpoint-related fields on container.NetworkSettings based on the provided network and endpoint.
 func (container *Container) BuildEndpointInfo(n libnetwork.Network, ep libnetwork.Endpoint) error {
 	if ep == nil {
-		return derr.ErrorCodeEmptyEndpoint
+		return errInvalidEndpoint
 	}
 
 	networkSettings := container.NetworkSettings
 	if networkSettings == nil {
-		return derr.ErrorCodeEmptyNetwork
+		return errInvalidNetwork
 	}
 
 	epInfo := ep.Info()
@@ -377,7 +381,7 @@ func (container *Container) BuildCreateEndpointOptions(n libnetwork.Network, epC
 				portStart, portEnd, err = newP.Range()
 			}
 			if err != nil {
-				return nil, derr.ErrorCodeHostPort.WithArgs(binding[i].HostPort, err)
+				return nil, fmt.Errorf("Error parsing HostPort value(%s):%v", binding[i].HostPort, err)
 			}
 			pbCopy.HostPort = uint16(portStart)
 			pbCopy.HostPortEnd = uint16(portEnd)

+ 4 - 5
container/monitor.go

@@ -1,6 +1,7 @@
 package container
 
 import (
+	"fmt"
 	"io"
 	"os/exec"
 	"strings"
@@ -10,10 +11,8 @@ import (
 
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/execdriver"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/promise"
 	"github.com/docker/docker/pkg/stringid"
-	"github.com/docker/docker/utils"
 	"github.com/docker/engine-api/types/container"
 )
 
@@ -190,7 +189,7 @@ func (m *containerMonitor) start() error {
 				if m.container.RestartCount == 0 {
 					m.container.ExitCode = 127
 					m.resetContainer(false)
-					return derr.ErrorCodeCmdNotFound
+					return fmt.Errorf("Container command not found or does not exist.")
 				}
 			}
 			// set to 126 for container cmd can't be invoked errors
@@ -198,7 +197,7 @@ func (m *containerMonitor) start() error {
 				if m.container.RestartCount == 0 {
 					m.container.ExitCode = 126
 					m.resetContainer(false)
-					return derr.ErrorCodeCmdCouldNotBeInvoked
+					return fmt.Errorf("Container command could not be invoked.")
 				}
 			}
 
@@ -206,7 +205,7 @@ func (m *containerMonitor) start() error {
 				m.container.ExitCode = -1
 				m.resetContainer(false)
 
-				return derr.ErrorCodeCantStart.WithArgs(m.container.ID, utils.GetErrorMessage(err))
+				return fmt.Errorf("Cannot start container %s: %v", m.container.ID, err)
 			}
 
 			logrus.Errorf("Error running container: %s", err)

+ 5 - 5
container/state.go

@@ -6,7 +6,6 @@ import (
 	"time"
 
 	"github.com/docker/docker/daemon/execdriver"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/go-units"
 )
 
@@ -113,7 +112,7 @@ func wait(waitChan <-chan struct{}, timeout time.Duration) error {
 	}
 	select {
 	case <-time.After(timeout):
-		return derr.ErrorCodeTimedOut.WithArgs(timeout)
+		return fmt.Errorf("Timed out: %v", timeout)
 	case <-waitChan:
 		return nil
 	}
@@ -256,14 +255,15 @@ func (s *State) IsRestarting() bool {
 }
 
 // SetRemovalInProgress sets the container state as being removed.
-func (s *State) SetRemovalInProgress() error {
+// It returns true if the container was already in that state.
+func (s *State) SetRemovalInProgress() bool {
 	s.Lock()
 	defer s.Unlock()
 	if s.RemovalInProgress {
-		return derr.ErrorCodeAlreadyRemoving
+		return true
 	}
 	s.RemovalInProgress = true
-	return nil
+	return false
 }
 
 // ResetRemovalInProgress make the RemovalInProgress state to false.

+ 4 - 3
daemon/attach.go

@@ -9,7 +9,7 @@ import (
 	"github.com/docker/docker/api/types/backend"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/daemon/logger"
-	derr "github.com/docker/docker/errors"
+	"github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/stdcopy"
 )
 
@@ -17,10 +17,11 @@ import (
 func (daemon *Daemon) ContainerAttach(prefixOrName string, c *backend.ContainerAttachConfig) error {
 	container, err := daemon.GetContainer(prefixOrName)
 	if err != nil {
-		return derr.ErrorCodeNoSuchContainer.WithArgs(prefixOrName)
+		return err
 	}
 	if container.IsPaused() {
-		return derr.ErrorCodePausedContainer.WithArgs(prefixOrName)
+		err := fmt.Errorf("Container %s is paused. Unpause the container before attach", prefixOrName)
+		return errors.NewRequestConflictError(err)
 	}
 
 	inStream, outStream, errStream, err := c.GetStreams()

+ 20 - 15
daemon/container_operations_unix.go

@@ -17,7 +17,7 @@ import (
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/links"
 	"github.com/docker/docker/daemon/network"
-	derr "github.com/docker/docker/errors"
+	"github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/fileutils"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/mount"
@@ -45,7 +45,7 @@ func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]s
 
 	for linkAlias, child := range children {
 		if !child.IsRunning() {
-			return nil, derr.ErrorCodeLinkNotRunning.WithArgs(child.Name, linkAlias)
+			return nil, fmt.Errorf("Cannot link to a non running container: %s AS %s", child.Name, linkAlias)
 		}
 
 		childBridgeSettings := child.NetworkSettings.Networks["bridge"]
@@ -509,7 +509,7 @@ func (daemon *Daemon) updateNetwork(container *container.Container) error {
 
 	sb, err := ctrl.SandboxByID(sid)
 	if err != nil {
-		return derr.ErrorCodeNoSandbox.WithArgs(sid, err)
+		return fmt.Errorf("error locating sandbox id %s: %v", sid, err)
 	}
 
 	// Find if container is connected to the default bridge network
@@ -532,11 +532,11 @@ func (daemon *Daemon) updateNetwork(container *container.Container) error {
 
 	options, err := daemon.buildSandboxOptions(container, n)
 	if err != nil {
-		return derr.ErrorCodeNetworkUpdate.WithArgs(err)
+		return fmt.Errorf("Update network failed: %v", err)
 	}
 
 	if err := sb.Refresh(options...); err != nil {
-		return derr.ErrorCodeNetworkRefresh.WithArgs(sid, err)
+		return fmt.Errorf("Update network failed: Failure in refresh sandbox %s: %v", sid, err)
 	}
 
 	return nil
@@ -730,7 +730,7 @@ func (daemon *Daemon) updateNetworkConfig(container *container.Container, idOrNa
 func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings) error {
 	if !container.Running {
 		if container.RemovalInProgress || container.Dead {
-			return derr.ErrorCodeRemovalContainer.WithArgs(container.ID)
+			return errRemovalContainer(container.ID)
 		}
 		if _, err := daemon.updateNetworkConfig(container, idOrName, endpointConfig, true); err != nil {
 			return err
@@ -810,7 +810,7 @@ func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName
 	}
 
 	if err := container.UpdateJoinInfo(n, ep); err != nil {
-		return derr.ErrorCodeJoinInfo.WithArgs(err)
+		return fmt.Errorf("Updating join info failed: %v", err)
 	}
 
 	daemon.LogNetworkEventWithAttributes(n, "connect", map[string]string{"container": container.ID})
@@ -833,7 +833,7 @@ func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, n li
 	}
 	if !container.Running {
 		if container.RemovalInProgress || container.Dead {
-			return derr.ErrorCodeRemovalContainer.WithArgs(container.ID)
+			return errRemovalContainer(container.ID)
 		}
 		if _, ok := container.NetworkSettings.Networks[n.Name()]; ok {
 			delete(container.NetworkSettings.Networks, n.Name())
@@ -950,7 +950,7 @@ func (daemon *Daemon) setNetworkNamespaceKey(containerID string, pid int) error
 	search := libnetwork.SandboxContainerWalker(&sandbox, containerID)
 	daemon.netController.WalkSandboxes(search)
 	if sandbox == nil {
-		return derr.ErrorCodeNoSandbox.WithArgs(containerID, "no sandbox found")
+		return fmt.Errorf("error locating sandbox id %s: no sandbox found", containerID)
 	}
 
 	return sandbox.SetKey(path)
@@ -963,10 +963,10 @@ func (daemon *Daemon) getIpcContainer(container *container.Container) (*containe
 		return nil, err
 	}
 	if !c.IsRunning() {
-		return nil, derr.ErrorCodeIPCRunning.WithArgs(containerID)
+		return nil, fmt.Errorf("cannot join IPC of a non running container: %s", containerID)
 	}
 	if c.IsRestarting() {
-		return nil, derr.ErrorCodeContainerRestarting.WithArgs(containerID)
+		return nil, errContainerIsRestarting(container.ID)
 	}
 	return c, nil
 }
@@ -977,13 +977,14 @@ func (daemon *Daemon) getNetworkedContainer(containerID, connectedContainerID st
 		return nil, err
 	}
 	if containerID == nc.ID {
-		return nil, derr.ErrorCodeJoinSelf
+		return nil, fmt.Errorf("cannot join own network")
 	}
 	if !nc.IsRunning() {
-		return nil, derr.ErrorCodeJoinRunning.WithArgs(connectedContainerID)
+		err := fmt.Errorf("cannot join network of a non running container: %s", connectedContainerID)
+		return nil, errors.NewRequestConflictError(err)
 	}
 	if nc.IsRestarting() {
-		return nil, derr.ErrorCodeContainerRestarting.WithArgs(connectedContainerID)
+		return nil, errContainerIsRestarting(connectedContainerID)
 	}
 	return nc, nil
 }
@@ -1141,7 +1142,7 @@ func getDevicesFromPath(deviceMapping containertypes.DeviceMapping) (devs []*con
 		return devs, nil
 	}
 
-	return devs, derr.ErrorCodeDeviceInfo.WithArgs(deviceMapping.PathOnHost, err)
+	return devs, fmt.Errorf("error gathering device information while adding custom device %q: %s", deviceMapping.PathOnHost, err)
 }
 
 func mergeDevices(defaultDevices, userDevices []*configs.Device) []*configs.Device {
@@ -1172,3 +1173,7 @@ func isLinkable(child *container.Container) bool {
 	_, ok := child.NetworkSettings.Networks["bridge"]
 	return ok
 }
+
+func errRemovalContainer(containerID string) error {
+	return fmt.Errorf("Container %s is marked for removal and cannot be connected or disconnected to the network", containerID)
+}

+ 5 - 5
daemon/container_operations_windows.go

@@ -3,12 +3,12 @@
 package daemon
 
 import (
+	"fmt"
 	"strings"
 
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/execdriver/windows"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/layer"
 	networktypes "github.com/docker/engine-api/types/network"
 	"github.com/docker/libnetwork"
@@ -64,7 +64,7 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro
 			}
 		}
 	default:
-		return derr.ErrorCodeInvalidNetworkMode.WithArgs(c.HostConfig.NetworkMode)
+		return fmt.Errorf("invalid network mode: %s", c.HostConfig.NetworkMode)
 	}
 
 	// TODO Windows. More resource controls to be implemented later.
@@ -88,7 +88,7 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro
 	var layerPaths []string
 	img, err := daemon.imageStore.Get(c.ImageID)
 	if err != nil {
-		return derr.ErrorCodeGetGraph.WithArgs(c.ImageID, err)
+		return fmt.Errorf("Failed to graph.Get on ImageID %s - %s", c.ImageID, err)
 	}
 
 	if img.RootFS != nil && img.RootFS.Type == "layers+base" {
@@ -97,7 +97,7 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro
 			img.RootFS.DiffIDs = img.RootFS.DiffIDs[:i]
 			path, err := layer.GetLayerPath(daemon.layerStore, img.RootFS.ChainID())
 			if err != nil {
-				return derr.ErrorCodeGetLayer.WithArgs(err)
+				return fmt.Errorf("Failed to get layer path from graphdriver %s for ImageID %s - %s", daemon.layerStore, img.RootFS.ChainID(), err)
 			}
 			// Reverse order, expecting parent most first
 			layerPaths = append([]string{path}, layerPaths...)
@@ -106,7 +106,7 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro
 
 	m, err := c.RWLayer.Metadata()
 	if err != nil {
-		return derr.ErrorCodeGetLayerMetadata.WithArgs(err)
+		return fmt.Errorf("Failed to get layer metadata - %s", err)
 	}
 	layerFolder := m["dir"]
 

+ 4 - 3
daemon/create.go

@@ -1,9 +1,10 @@
 package daemon
 
 import (
+	"fmt"
+
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/container"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/layer"
 	"github.com/docker/docker/pkg/idtools"
@@ -18,7 +19,7 @@ import (
 // ContainerCreate creates a container.
 func (daemon *Daemon) ContainerCreate(params types.ContainerCreateConfig) (types.ContainerCreateResponse, error) {
 	if params.Config == nil {
-		return types.ContainerCreateResponse{}, derr.ErrorCodeEmptyConfig
+		return types.ContainerCreateResponse{}, fmt.Errorf("Config cannot be empty in order to create a container")
 	}
 
 	warnings, err := daemon.verifyContainerSettings(params.HostConfig, params.Config, false)
@@ -174,7 +175,7 @@ func (daemon *Daemon) VolumeCreate(name, driverName string, opts map[string]stri
 	v, err := daemon.volumes.Create(name, driverName, opts)
 	if err != nil {
 		if volumestore.IsNameConflict(err) {
-			return nil, derr.ErrorVolumeNameTaken.WithArgs(name)
+			return nil, fmt.Errorf("A volume named %s already exists. Choose a different volume name.", name)
 		}
 		return nil, err
 	}

+ 2 - 2
daemon/create_unix.go

@@ -3,12 +3,12 @@
 package daemon
 
 import (
+	"fmt"
 	"os"
 	"path/filepath"
 
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/container"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/stringid"
 	containertypes "github.com/docker/engine-api/types/container"
 	"github.com/opencontainers/runc/libcontainer/label"
@@ -41,7 +41,7 @@ func (daemon *Daemon) createContainerPlatformSpecificSettings(container *contain
 
 		stat, err := os.Stat(path)
 		if err == nil && !stat.IsDir() {
-			return derr.ErrorCodeMountOverFile.WithArgs(path)
+			return fmt.Errorf("cannot mount volume over existing file, file exists %s", path)
 		}
 
 		v, err := daemon.volumes.CreateWithRef(name, hostConfig.VolumeDriver, container.ID, nil)

+ 9 - 7
daemon/daemon.go

@@ -6,7 +6,6 @@
 package daemon
 
 import (
-	"errors"
 	"fmt"
 	"io"
 	"io/ioutil"
@@ -15,6 +14,7 @@ import (
 	"path"
 	"path/filepath"
 	"runtime"
+	"strings"
 	"sync"
 	"syscall"
 	"time"
@@ -28,6 +28,7 @@ import (
 	"github.com/docker/docker/daemon/exec"
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/daemon/execdriver/execdrivers"
+	"github.com/docker/docker/errors"
 	"github.com/docker/engine-api/types"
 	containertypes "github.com/docker/engine-api/types/container"
 	eventtypes "github.com/docker/engine-api/types/events"
@@ -43,7 +44,6 @@ import (
 	dmetadata "github.com/docker/docker/distribution/metadata"
 	"github.com/docker/docker/distribution/xfer"
 	"github.com/docker/docker/dockerversion"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/image/tarexport"
 	"github.com/docker/docker/layer"
@@ -90,7 +90,7 @@ var (
 	validContainerNameChars   = utils.RestrictedNameChars
 	validContainerNamePattern = utils.RestrictedNamePattern
 
-	errSystemNotSupported = errors.New("The Docker daemon is not supported on this platform.")
+	errSystemNotSupported = fmt.Errorf("The Docker daemon is not supported on this platform.")
 )
 
 // ErrImageDoesNotExist is error returned when no image can be found for a reference.
@@ -157,7 +157,8 @@ func (daemon *Daemon) GetContainer(prefixOrName string) (*container.Container, e
 	if indexError != nil {
 		// When truncindex defines an error type, use that instead
 		if indexError == truncindex.ErrNotExist {
-			return nil, derr.ErrorCodeNoSuchContainer.WithArgs(prefixOrName)
+			err := fmt.Errorf("No such container: %s", prefixOrName)
+			return nil, errors.NewRequestNotFoundError(err)
 		}
 		return nil, indexError
 	}
@@ -1211,7 +1212,7 @@ func (daemon *Daemon) ImageHistory(name string) ([]*types.ImageHistory, error) {
 
 		if !h.EmptyLayer {
 			if len(img.RootFS.DiffIDs) <= layerCounter {
-				return nil, errors.New("too many non-empty layers in History section")
+				return nil, fmt.Errorf("too many non-empty layers in History section")
 			}
 
 			rootFS.Append(img.RootFS.DiffIDs[layerCounter])
@@ -1499,7 +1500,8 @@ func (daemon *Daemon) verifyNetworkingConfig(nwConfig *networktypes.NetworkingCo
 	for k := range nwConfig.EndpointsConfig {
 		l = append(l, k)
 	}
-	return derr.ErrorCodeMultipleNetworkConnect.WithArgs(fmt.Sprintf("%v", l))
+	err := fmt.Errorf("Container cannot be connected to network endpoints: %s", strings.Join(l, ", "))
+	return errors.NewBadRequestError(err)
 }
 
 func configureVolumes(config *Config, rootUID, rootGID int) (*store.VolumeStore, error) {
@@ -1671,7 +1673,7 @@ func convertLnNetworkStats(name string, stats *lntypes.InterfaceStatistics) *lib
 
 func validateID(id string) error {
 	if id == "" {
-		return derr.ErrorCodeEmptyID
+		return fmt.Errorf("Invalid empty id")
 	}
 	return nil
 }

+ 4 - 5
daemon/daemon_unix.go

@@ -16,7 +16,6 @@ import (
 
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/container"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/layer"
 	"github.com/docker/docker/pkg/idtools"
@@ -312,17 +311,17 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi
 	}
 	cpusAvailable, err := sysInfo.IsCpusetCpusAvailable(resources.CpusetCpus)
 	if err != nil {
-		return warnings, derr.ErrorCodeInvalidCpusetCpus.WithArgs(resources.CpusetCpus)
+		return warnings, fmt.Errorf("Invalid value %s for cpuset cpus.", resources.CpusetCpus)
 	}
 	if !cpusAvailable {
-		return warnings, derr.ErrorCodeNotAvailableCpusetCpus.WithArgs(resources.CpusetCpus, sysInfo.Cpus)
+		return warnings, fmt.Errorf("Requested CPUs are not available - requested %s, available: %s.", resources.CpusetCpus, sysInfo.Cpus)
 	}
 	memsAvailable, err := sysInfo.IsCpusetMemsAvailable(resources.CpusetMems)
 	if err != nil {
-		return warnings, derr.ErrorCodeInvalidCpusetMems.WithArgs(resources.CpusetMems)
+		return warnings, fmt.Errorf("Invalid value %s for cpuset mems.", resources.CpusetMems)
 	}
 	if !memsAvailable {
-		return warnings, derr.ErrorCodeNotAvailableCpusetMems.WithArgs(resources.CpusetMems, sysInfo.Mems)
+		return warnings, fmt.Errorf("Requested memory nodes are not available - requested %s, available: %s.", resources.CpusetMems, sysInfo.Mems)
 	}
 
 	// blkio subsystem checks and adjustments

+ 12 - 14
daemon/delete.go

@@ -8,7 +8,7 @@ import (
 
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/container"
-	derr "github.com/docker/docker/errors"
+	"github.com/docker/docker/errors"
 	"github.com/docker/docker/layer"
 	volumestore "github.com/docker/docker/volume/store"
 	"github.com/docker/engine-api/types"
@@ -25,12 +25,8 @@ func (daemon *Daemon) ContainerRm(name string, config *types.ContainerRmConfig)
 	}
 
 	// Container state RemovalInProgress should be used to avoid races.
-	if err = container.SetRemovalInProgress(); err != nil {
-		if err == derr.ErrorCodeAlreadyRemoving {
-			// do not fail when the removal is in progress started by other request.
-			return nil
-		}
-		return derr.ErrorCodeRmState.WithArgs(container.ID, err)
+	if inProgress := container.SetRemovalInProgress(); inProgress {
+		return nil
 	}
 	defer container.ResetRemovalInProgress()
 
@@ -84,10 +80,11 @@ func (daemon *Daemon) rmLink(container *container.Container, name string) error
 func (daemon *Daemon) cleanupContainer(container *container.Container, forceRemove bool) (err error) {
 	if container.IsRunning() {
 		if !forceRemove {
-			return derr.ErrorCodeRmRunning.WithArgs(container.ID)
+			err := fmt.Errorf("You cannot remove a running container %s. Stop the container before attempting removal or use -f", container.ID)
+			return errors.NewRequestConflictError(err)
 		}
 		if err := daemon.Kill(container); err != nil {
-			return derr.ErrorCodeRmFailed.WithArgs(container.ID, err)
+			return fmt.Errorf("Could not kill running container %s, cannot remove - %v", container.ID, err)
 		}
 	}
 
@@ -123,17 +120,17 @@ func (daemon *Daemon) cleanupContainer(container *container.Container, forceRemo
 	}()
 
 	if err = os.RemoveAll(container.Root); err != nil {
-		return derr.ErrorCodeRmFS.WithArgs(container.ID, err)
+		return fmt.Errorf("Unable to remove filesystem for %v: %v", container.ID, err)
 	}
 
 	metadata, err := daemon.layerStore.ReleaseRWLayer(container.RWLayer)
 	layer.LogReleaseMetadata(metadata)
 	if err != nil && err != layer.ErrMountDoesNotExist {
-		return derr.ErrorCodeRmDriverFS.WithArgs(daemon.GraphDriverName(), container.ID, err)
+		return fmt.Errorf("Driver %s failed to remove root filesystem %s: %s", daemon.GraphDriverName(), container.ID, err)
 	}
 
 	if err = daemon.execDriver.Clean(container.ID); err != nil {
-		return derr.ErrorCodeRmExecDriver.WithArgs(container.ID, err)
+		return fmt.Errorf("Unable to remove execdriver data for %s: %s", container.ID, err)
 	}
 	return nil
 }
@@ -149,9 +146,10 @@ func (daemon *Daemon) VolumeRm(name string) error {
 
 	if err := daemon.volumes.Remove(v); err != nil {
 		if volumestore.IsInUse(err) {
-			return derr.ErrorCodeRmVolumeInUse.WithArgs(err)
+			err := fmt.Errorf("Unable to remove volume, volume still in use: %v", err)
+			return errors.NewRequestConflictError(err)
 		}
-		return derr.ErrorCodeRmVolume.WithArgs(name, err)
+		return fmt.Errorf("Error while removing volume %s: %v", name, err)
 	}
 	daemon.LogVolumeEvent(v.Name(), "destroy", map[string]string{"driver": v.DriverName()})
 	return nil

+ 1 - 3
daemon/delete_test.go

@@ -32,9 +32,7 @@ func TestContainerDoubleDelete(t *testing.T) {
 	daemon.containers.Add(container.ID, container)
 
 	// Mark the container as having a delete in progress
-	if err := container.SetRemovalInProgress(); err != nil {
-		t.Fatal(err)
-	}
+	container.SetRemovalInProgress()
 
 	// Try to remove the container when it's start is removalInProgress.
 	// It should ignore the container and not return an error.

+ 35 - 4
daemon/errors.go

@@ -1,26 +1,57 @@
 package daemon
 
 import (
+	"fmt"
 	"strings"
 
-	derr "github.com/docker/docker/errors"
+	"github.com/docker/docker/errors"
 	"github.com/docker/docker/reference"
 )
 
 func (d *Daemon) imageNotExistToErrcode(err error) error {
 	if dne, isDNE := err.(ErrImageDoesNotExist); isDNE {
 		if strings.Contains(dne.RefOrID, "@") {
-			return derr.ErrorCodeNoSuchImageHash.WithArgs(dne.RefOrID)
+			e := fmt.Errorf("No such image: %s", dne.RefOrID)
+			return errors.NewRequestNotFoundError(e)
 		}
 		tag := reference.DefaultTag
 		ref, err := reference.ParseNamed(dne.RefOrID)
 		if err != nil {
-			return derr.ErrorCodeNoSuchImageTag.WithArgs(dne.RefOrID, tag)
+			e := fmt.Errorf("No such image: %s:%s", dne.RefOrID, tag)
+			return errors.NewRequestNotFoundError(e)
 		}
 		if tagged, isTagged := ref.(reference.NamedTagged); isTagged {
 			tag = tagged.Tag()
 		}
-		return derr.ErrorCodeNoSuchImageTag.WithArgs(ref.Name(), tag)
+		e := fmt.Errorf("No such image: %s:%s", ref.Name(), tag)
+		return errors.NewRequestNotFoundError(e)
 	}
 	return err
 }
+
+type errNotRunning struct {
+	containerID string
+}
+
+func (e errNotRunning) Error() string {
+	return fmt.Sprintf("Container %s is not running", e.containerID)
+}
+
+func (e errNotRunning) ContainerIsRunning() bool {
+	return false
+}
+
+func errContainerIsRestarting(containerID string) error {
+	err := fmt.Errorf("Container %s is restarting, wait until the container is running", containerID)
+	return errors.NewRequestConflictError(err)
+}
+
+func errExecNotFound(id string) error {
+	err := fmt.Errorf("No such exec instance '%s' found in daemon", id)
+	return errors.NewRequestNotFoundError(err)
+}
+
+func errExecPaused(id string) error {
+	err := fmt.Errorf("Container %s is paused, unpause the container before exec", id)
+	return errors.NewRequestConflictError(err)
+}

+ 17 - 15
daemon/exec.go

@@ -1,6 +1,7 @@
 package daemon
 
 import (
+	"fmt"
 	"io"
 	"strings"
 	"time"
@@ -9,7 +10,7 @@ import (
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/daemon/exec"
 	"github.com/docker/docker/daemon/execdriver"
-	derr "github.com/docker/docker/errors"
+	"github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/pools"
 	"github.com/docker/docker/pkg/promise"
 	"github.com/docker/docker/pkg/term"
@@ -47,19 +48,19 @@ func (d *Daemon) getExecConfig(name string) (*exec.Config, error) {
 	if ec != nil {
 		if container := d.containers.Get(ec.ContainerID); container != nil {
 			if !container.IsRunning() {
-				return nil, derr.ErrorCodeContainerNotRunning.WithArgs(container.ID, container.State.String())
+				return nil, fmt.Errorf("Container %s is not running: %s", container.ID, container.State.String())
 			}
 			if container.IsPaused() {
-				return nil, derr.ErrorCodeExecPaused.WithArgs(container.ID)
+				return nil, errExecPaused(container.ID)
 			}
 			if container.IsRestarting() {
-				return nil, derr.ErrorCodeContainerRestarting.WithArgs(container.ID)
+				return nil, errContainerIsRestarting(container.ID)
 			}
 			return ec, nil
 		}
 	}
 
-	return nil, derr.ErrorCodeNoExecID.WithArgs(name)
+	return nil, errExecNotFound(name)
 }
 
 func (d *Daemon) unregisterExecCommand(container *container.Container, execConfig *exec.Config) {
@@ -74,13 +75,13 @@ func (d *Daemon) getActiveContainer(name string) (*container.Container, error) {
 	}
 
 	if !container.IsRunning() {
-		return nil, derr.ErrorCodeNotRunning.WithArgs(name)
+		return nil, errNotRunning{container.ID}
 	}
 	if container.IsPaused() {
-		return nil, derr.ErrorCodeExecPaused.WithArgs(name)
+		return nil, errExecPaused(name)
 	}
 	if container.IsRestarting() {
-		return nil, derr.ErrorCodeContainerRestarting.WithArgs(name)
+		return nil, errContainerIsRestarting(container.ID)
 	}
 	return container, nil
 }
@@ -137,18 +138,19 @@ func (d *Daemon) ContainerExecStart(name string, stdin io.ReadCloser, stdout io.
 
 	ec, err := d.getExecConfig(name)
 	if err != nil {
-		return derr.ErrorCodeNoExecID.WithArgs(name)
+		return errExecNotFound(name)
 	}
 
 	ec.Lock()
 	if ec.ExitCode != nil {
 		ec.Unlock()
-		return derr.ErrorCodeExecExited.WithArgs(ec.ID)
+		err := fmt.Errorf("Error: Exec command %s has already run", ec.ID)
+		return errors.NewRequestConflictError(err)
 	}
 
 	if ec.Running {
 		ec.Unlock()
-		return derr.ErrorCodeExecRunning.WithArgs(ec.ID)
+		return fmt.Errorf("Error: Exec command %s is already running", ec.ID)
 	}
 	ec.Running = true
 	ec.Unlock()
@@ -194,12 +196,12 @@ func (d *Daemon) ContainerExecStart(name string, stdin io.ReadCloser, stdout io.
 	select {
 	case err := <-attachErr:
 		if err != nil {
-			return derr.ErrorCodeExecAttach.WithArgs(err)
+			return fmt.Errorf("attach failed with error: %v", err)
 		}
 		return nil
 	case err := <-execErr:
 		if aErr := <-attachErr; aErr != nil && err == nil {
-			return derr.ErrorCodeExecAttach.WithArgs(aErr)
+			return fmt.Errorf("attach failed with error: %v", aErr)
 		}
 		if err == nil {
 			return nil
@@ -207,9 +209,9 @@ func (d *Daemon) ContainerExecStart(name string, stdin io.ReadCloser, stdout io.
 
 		// Maybe the container stopped while we were trying to exec
 		if !c.IsRunning() {
-			return derr.ErrorCodeExecContainerStopped
+			return fmt.Errorf("container stopped while running exec: %s", c.ID)
 		}
-		return derr.ErrorCodeExecCantRun.WithArgs(ec.ID, c.ID, err)
+		return fmt.Errorf("Cannot run exec command %s in container %s: %s", ec.ID, c.ID, err)
 	}
 }
 

+ 2 - 2
daemon/exec/exec.go

@@ -1,11 +1,11 @@
 package exec
 
 import (
+	"fmt"
 	"sync"
 	"time"
 
 	"github.com/docker/docker/daemon/execdriver"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/runconfig"
 )
@@ -116,7 +116,7 @@ func (c *Config) Resize(h, w int) error {
 	select {
 	case <-c.waitStart:
 	case <-time.After(time.Second):
-		return derr.ErrorCodeExecResize.WithArgs(c.ID)
+		return fmt.Errorf("Exec %s is not running, so it can not be resized.", c.ID)
 	}
 	return c.ProcessConfig.Terminal.Resize(h, w)
 }

+ 1 - 2
daemon/execdriver/native/create.go

@@ -9,7 +9,6 @@ import (
 	"syscall"
 
 	"github.com/docker/docker/daemon/execdriver"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/profiles/seccomp"
 
@@ -430,7 +429,7 @@ func (d *Driver) setupMounts(container *configs.Config, c *execdriver.Command) e
 	for _, m := range c.Mounts {
 		for _, cm := range container.Mounts {
 			if cm.Destination == m.Destination {
-				return derr.ErrorCodeMountDup.WithArgs(m.Destination)
+				return fmt.Errorf("Duplicate mount point '%s'", m.Destination)
 			}
 		}
 

+ 3 - 3
daemon/export.go

@@ -1,10 +1,10 @@
 package daemon
 
 import (
+	"fmt"
 	"io"
 
 	"github.com/docker/docker/container"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/ioutils"
 )
@@ -19,13 +19,13 @@ func (daemon *Daemon) ContainerExport(name string, out io.Writer) error {
 
 	data, err := daemon.containerExport(container)
 	if err != nil {
-		return derr.ErrorCodeExportFailed.WithArgs(name, err)
+		return fmt.Errorf("Error exporting container %s: %v", name, err)
 	}
 	defer data.Close()
 
 	// Stream the entire contents of the container (basically a volatile snapshot)
 	if _, err := io.Copy(out, data); err != nil {
-		return derr.ErrorCodeExportFailed.WithArgs(name, err)
+		return fmt.Errorf("Error exporting container %s: %v", name, err)
 	}
 	return nil
 }

+ 3 - 2
daemon/image_delete.go

@@ -5,7 +5,7 @@ import (
 	"strings"
 
 	"github.com/docker/docker/container"
-	derr "github.com/docker/docker/errors"
+	"github.com/docker/docker/errors"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/reference"
@@ -82,7 +82,8 @@ func (daemon *Daemon) ImageDelete(imageRef string, force, prune bool) ([]types.I
 				// this image would remain "dangling" and since
 				// we really want to avoid that the client must
 				// explicitly force its removal.
-				return nil, derr.ErrorCodeImgDelUsed.WithArgs(imageRef, stringid.TruncateID(container.ID), stringid.TruncateID(imgID.String()))
+				err := fmt.Errorf("conflict: unable to remove repository reference %q (must force) - container %s is using its referenced image %s", imageRef, stringid.TruncateID(container.ID), stringid.TruncateID(imgID.String()))
+				return nil, errors.NewRequestConflictError(err)
 			}
 		}
 

+ 4 - 5
daemon/kill.go

@@ -8,7 +8,6 @@ import (
 
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/container"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/signal"
 )
 
@@ -45,11 +44,11 @@ func (daemon *Daemon) killWithSignal(container *container.Container, sig int) er
 
 	// We could unpause the container for them rather than returning this error
 	if container.Paused {
-		return derr.ErrorCodeUnpauseContainer.WithArgs(container.ID)
+		return fmt.Errorf("Container %s is paused. Unpause the container before stopping", container.ID)
 	}
 
 	if !container.Running {
-		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
+		return errNotRunning{container.ID}
 	}
 
 	container.ExitOnNext()
@@ -62,7 +61,7 @@ func (daemon *Daemon) killWithSignal(container *container.Container, sig int) er
 	}
 
 	if err := daemon.kill(container, sig); err != nil {
-		return derr.ErrorCodeCantKill.WithArgs(container.ID, err)
+		return fmt.Errorf("Cannot kill container %s: %s", container.ID, err)
 	}
 
 	attributes := map[string]string{
@@ -75,7 +74,7 @@ func (daemon *Daemon) killWithSignal(container *container.Container, sig int) er
 // Kill forcefully terminates a container.
 func (daemon *Daemon) Kill(container *container.Container) error {
 	if !container.IsRunning() {
-		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
+		return errNotRunning{container.ID}
 	}
 
 	// 1. Send SIGKILL

+ 4 - 4
daemon/logs.go

@@ -1,6 +1,7 @@
 package daemon
 
 import (
+	"fmt"
 	"io"
 	"strconv"
 	"time"
@@ -10,7 +11,6 @@ import (
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/daemon/logger/jsonfilelog"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/stdcopy"
 	timetypes "github.com/docker/engine-api/types/time"
@@ -21,11 +21,11 @@ import (
 func (daemon *Daemon) ContainerLogs(containerName string, config *backend.ContainerLogsConfig, started chan struct{}) error {
 	container, err := daemon.GetContainer(containerName)
 	if err != nil {
-		return derr.ErrorCodeNoSuchContainer.WithArgs(containerName)
+		return err
 	}
 
 	if !(config.ShowStdout || config.ShowStderr) {
-		return derr.ErrorCodeNeedStream
+		return fmt.Errorf("You must choose at least one stream")
 	}
 
 	cLog, err := daemon.getLogger(container)
@@ -122,7 +122,7 @@ func (daemon *Daemon) StartLogging(container *container.Container) error {
 	}
 	l, err := container.StartLogger(cfg)
 	if err != nil {
-		return derr.ErrorCodeInitLogger.WithArgs(err)
+		return fmt.Errorf("Failed to initialize logging driver: %v", err)
 	}
 
 	copier := logger.NewCopier(container.ID, map[string]io.Reader{"stdout": container.StdoutPipe(), "stderr": container.StderrPipe()}, l)

+ 2 - 2
daemon/mounts.go

@@ -1,10 +1,10 @@
 package daemon
 
 import (
+	"fmt"
 	"strings"
 
 	"github.com/docker/docker/container"
-	derr "github.com/docker/docker/errors"
 	volumestore "github.com/docker/docker/volume/store"
 )
 
@@ -42,7 +42,7 @@ func (daemon *Daemon) removeMountPoints(container *container.Container, rm bool)
 		}
 	}
 	if len(rmErrors) > 0 {
-		return derr.ErrorCodeRemovingVolume.WithArgs(strings.Join(rmErrors, "\n"))
+		return fmt.Errorf("Error removing volumes:\n%v", strings.Join(rmErrors, "\n"))
 	}
 	return nil
 }

+ 4 - 2
daemon/network.go

@@ -3,9 +3,10 @@ package daemon
 import (
 	"fmt"
 	"net"
+	"net/http"
 	"strings"
 
-	derr "github.com/docker/docker/errors"
+	"github.com/docker/docker/errors"
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/engine-api/types/network"
 	"github.com/docker/libnetwork"
@@ -191,7 +192,8 @@ func (daemon *Daemon) DeleteNetwork(networkID string) error {
 	}
 
 	if runconfig.IsPreDefinedNetwork(nw.Name()) {
-		return derr.ErrorCodeCantDeletePredefinedNetwork.WithArgs(nw.Name())
+		err := fmt.Errorf("%s is a pre-defined network and cannot be removed", nw.Name())
+		return errors.NewErrorWithStatusCode(err, http.StatusForbidden)
 	}
 
 	if err := nw.Delete(); err != nil {

+ 6 - 5
daemon/pause.go

@@ -1,8 +1,9 @@
 package daemon
 
 import (
+	"fmt"
+
 	"github.com/docker/docker/container"
-	derr "github.com/docker/docker/errors"
 )
 
 // ContainerPause pauses a container
@@ -27,21 +28,21 @@ func (daemon *Daemon) containerPause(container *container.Container) error {
 
 	// We cannot Pause the container which is not running
 	if !container.Running {
-		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
+		return errNotRunning{container.ID}
 	}
 
 	// We cannot Pause the container which is already paused
 	if container.Paused {
-		return derr.ErrorCodeAlreadyPaused.WithArgs(container.ID)
+		return fmt.Errorf("Container %s is already paused", container.ID)
 	}
 
 	// We cannot Pause the container which is restarting
 	if container.Restarting {
-		return derr.ErrorCodeContainerRestarting.WithArgs(container.ID)
+		return errContainerIsRestarting(container.ID)
 	}
 
 	if err := daemon.execDriver.Pause(container.Command); err != nil {
-		return derr.ErrorCodeCantPause.WithArgs(container.ID, err)
+		return fmt.Errorf("Cannot pause container %s: %s", container.ID, err)
 	}
 	container.Paused = true
 	daemon.LogContainerEvent(container, "pause")

+ 3 - 3
daemon/rename.go

@@ -1,10 +1,10 @@
 package daemon
 
 import (
+	"fmt"
 	"strings"
 
 	"github.com/Sirupsen/logrus"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/libnetwork"
 )
 
@@ -18,7 +18,7 @@ func (daemon *Daemon) ContainerRename(oldName, newName string) error {
 	)
 
 	if oldName == "" || newName == "" {
-		return derr.ErrorCodeEmptyRename
+		return fmt.Errorf("Neither old nor new names may be empty")
 	}
 
 	container, err := daemon.GetContainer(oldName)
@@ -31,7 +31,7 @@ func (daemon *Daemon) ContainerRename(oldName, newName string) error {
 	container.Lock()
 	defer container.Unlock()
 	if newName, err = daemon.reserveName(container.ID, newName); err != nil {
-		return derr.ErrorCodeRenameTaken.WithArgs(err)
+		return fmt.Errorf("Error when allocating new name: %v", err)
 	}
 
 	container.Name = newName

+ 2 - 6
daemon/resize.go

@@ -1,10 +1,6 @@
 package daemon
 
-import (
-	"fmt"
-
-	derr "github.com/docker/docker/errors"
-)
+import "fmt"
 
 // ContainerResize changes the size of the TTY of the process running
 // in the container with the given name to the given height and width.
@@ -15,7 +11,7 @@ func (daemon *Daemon) ContainerResize(name string, height, width int) error {
 	}
 
 	if !container.IsRunning() {
-		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
+		return errNotRunning{container.ID}
 	}
 
 	if err = container.Resize(height, width); err == nil {

+ 3 - 2
daemon/restart.go

@@ -1,8 +1,9 @@
 package daemon
 
 import (
+	"fmt"
+
 	"github.com/docker/docker/container"
-	derr "github.com/docker/docker/errors"
 )
 
 // ContainerRestart stops and starts a container. It attempts to
@@ -17,7 +18,7 @@ func (daemon *Daemon) ContainerRestart(name string, seconds int) error {
 		return err
 	}
 	if err := daemon.containerRestart(container, seconds); err != nil {
-		return derr.ErrorCodeCantRestart.WithArgs(name, err)
+		return fmt.Errorf("Cannot restart container %s: %v", name, err)
 	}
 	return nil
 }

+ 7 - 5
daemon/start.go

@@ -2,11 +2,12 @@ package daemon
 
 import (
 	"fmt"
+	"net/http"
 	"runtime"
 
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/container"
-	derr "github.com/docker/docker/errors"
+	"github.com/docker/docker/errors"
 	"github.com/docker/docker/runconfig"
 	containertypes "github.com/docker/engine-api/types/container"
 )
@@ -19,11 +20,12 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *containertypes.Hos
 	}
 
 	if container.IsPaused() {
-		return derr.ErrorCodeStartPaused
+		return fmt.Errorf("Cannot start a paused container, try unpause instead.")
 	}
 
 	if container.IsRunning() {
-		return derr.ErrorCodeAlreadyStarted
+		err := fmt.Errorf("Container already started")
+		return errors.NewErrorWithStatusCode(err, http.StatusNotModified)
 	}
 
 	// Windows does not have the backwards compatibility issue here.
@@ -52,7 +54,7 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *containertypes.Hos
 		}
 	} else {
 		if hostConfig != nil {
-			return derr.ErrorCodeHostConfigStart
+			return fmt.Errorf("Supplying a hostconfig on start is not supported. It should be supplied on create")
 		}
 	}
 
@@ -88,7 +90,7 @@ func (daemon *Daemon) containerStart(container *container.Container) (err error)
 	}
 
 	if container.RemovalInProgress || container.Dead {
-		return derr.ErrorCodeContainerBeingRemoved
+		return fmt.Errorf("Container is marked for removal and cannot be started.")
 	}
 
 	// if we encounter an error during start we need to ensure that any other

+ 4 - 4
daemon/stats_collector_unix.go

@@ -4,6 +4,7 @@ package daemon
 
 import (
 	"bufio"
+	"fmt"
 	"os"
 	"strconv"
 	"strings"
@@ -13,7 +14,6 @@ import (
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/daemon/execdriver"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/pubsub"
 	"github.com/opencontainers/runc/libcontainer/system"
 )
@@ -163,13 +163,13 @@ func (s *statsCollector) getSystemCPUUsage() (uint64, error) {
 		switch parts[0] {
 		case "cpu":
 			if len(parts) < 8 {
-				return 0, derr.ErrorCodeBadCPUFields
+				return 0, fmt.Errorf("invalid number of cpu fields")
 			}
 			var totalClockTicks uint64
 			for _, i := range parts[1:8] {
 				v, err := strconv.ParseUint(i, 10, 64)
 				if err != nil {
-					return 0, derr.ErrorCodeBadCPUInt.WithArgs(i, err)
+					return 0, fmt.Errorf("Unable to convert value %s to int: %s", i, err)
 				}
 				totalClockTicks += v
 			}
@@ -177,5 +177,5 @@ func (s *statsCollector) getSystemCPUUsage() (uint64, error) {
 				s.clockTicksPerSecond, nil
 		}
 	}
-	return 0, derr.ErrorCodeBadStatFormat
+	return 0, fmt.Errorf("invalid stat format. Error trying to parse the '/proc/stat' file")
 }

+ 6 - 3
daemon/stop.go

@@ -1,11 +1,13 @@
 package daemon
 
 import (
+	"fmt"
+	"net/http"
 	"time"
 
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/container"
-	derr "github.com/docker/docker/errors"
+	"github.com/docker/docker/errors"
 )
 
 // ContainerStop looks for the given container and terminates it,
@@ -20,10 +22,11 @@ func (daemon *Daemon) ContainerStop(name string, seconds int) error {
 		return err
 	}
 	if !container.IsRunning() {
-		return derr.ErrorCodeStopped.WithArgs(name)
+		err := fmt.Errorf("Container %s is already stopped", name)
+		return errors.NewErrorWithStatusCode(err, http.StatusNotModified)
 	}
 	if err := daemon.containerStop(container, seconds); err != nil {
-		return derr.ErrorCodeCantStop.WithArgs(name, err)
+		return fmt.Errorf("Cannot stop container %s: %v", name, err)
 	}
 	return nil
 }

+ 6 - 6
daemon/top_unix.go

@@ -3,11 +3,11 @@
 package daemon
 
 import (
+	"fmt"
 	"os/exec"
 	"strconv"
 	"strings"
 
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/engine-api/types"
 )
 
@@ -27,11 +27,11 @@ func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.Container
 	}
 
 	if !container.IsRunning() {
-		return nil, derr.ErrorCodeNotRunning.WithArgs(name)
+		return nil, errNotRunning{container.ID}
 	}
 
 	if container.IsRestarting() {
-		return nil, derr.ErrorCodeContainerRestarting.WithArgs(name)
+		return nil, errContainerIsRestarting(container.ID)
 	}
 	pids, err := daemon.ExecutionDriver().GetPidsForContainer(container.ID)
 	if err != nil {
@@ -40,7 +40,7 @@ func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.Container
 
 	output, err := exec.Command("ps", strings.Split(psArgs, " ")...).Output()
 	if err != nil {
-		return nil, derr.ErrorCodePSError.WithArgs(err)
+		return nil, fmt.Errorf("Error running ps: %v", err)
 	}
 
 	procList := &types.ContainerProcessList{}
@@ -55,7 +55,7 @@ func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.Container
 		}
 	}
 	if pidIndex == -1 {
-		return nil, derr.ErrorCodeNoPID
+		return nil, fmt.Errorf("Couldn't find PID field in ps output")
 	}
 
 	// loop through the output and extract the PID from each line
@@ -66,7 +66,7 @@ func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.Container
 		fields := strings.Fields(line)
 		p, err := strconv.Atoi(fields[pidIndex])
 		if err != nil {
-			return nil, derr.ErrorCodeBadPID.WithArgs(fields[pidIndex], err)
+			return nil, fmt.Errorf("Unexpected pid '%s': %s", fields[pidIndex], err)
 		}
 
 		for _, pid := range pids {

+ 3 - 2
daemon/top_windows.go

@@ -1,11 +1,12 @@
 package daemon
 
 import (
-	derr "github.com/docker/docker/errors"
+	"fmt"
+
 	"github.com/docker/engine-api/types"
 )
 
 // ContainerTop is not supported on Windows and returns an error.
 func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.ContainerProcessList, error) {
-	return nil, derr.ErrorCodeNoTop
+	return nil, fmt.Errorf("Top is not supported on Windows")
 }

+ 5 - 4
daemon/unpause.go

@@ -1,8 +1,9 @@
 package daemon
 
 import (
+	"fmt"
+
 	"github.com/docker/docker/container"
-	derr "github.com/docker/docker/errors"
 )
 
 // ContainerUnpause unpauses a container
@@ -26,16 +27,16 @@ func (daemon *Daemon) containerUnpause(container *container.Container) error {
 
 	// We cannot unpause the container which is not running
 	if !container.Running {
-		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
+		return errNotRunning{container.ID}
 	}
 
 	// We cannot unpause the container which is not paused
 	if !container.Paused {
-		return derr.ErrorCodeNotPaused.WithArgs(container.ID)
+		return fmt.Errorf("Container %s is not paused", container.ID)
 	}
 
 	if err := daemon.execDriver.Unpause(container.Command); err != nil {
-		return derr.ErrorCodeCantUnpause.WithArgs(container.ID, err)
+		return fmt.Errorf("Cannot unpause container %s: %s", container.ID, err)
 	}
 
 	container.Paused = false

+ 8 - 7
daemon/update.go

@@ -4,7 +4,6 @@ import (
 	"fmt"
 	"time"
 
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/engine-api/types/container"
 )
 
@@ -57,18 +56,16 @@ func (daemon *Daemon) update(name string, hostConfig *container.HostConfig) erro
 	}()
 
 	if container.RemovalInProgress || container.Dead {
-		errMsg := fmt.Errorf("Container is marked for removal and cannot be \"update\".")
-		return derr.ErrorCodeCantUpdate.WithArgs(container.ID, errMsg)
+		return errCannotUpdate(container.ID, fmt.Errorf("Container is marked for removal and cannot be \"update\"."))
 	}
 
 	if container.IsRunning() && hostConfig.KernelMemory != 0 {
-		errMsg := fmt.Errorf("Can not update kernel memory to a running container, please stop it first.")
-		return derr.ErrorCodeCantUpdate.WithArgs(container.ID, errMsg)
+		return errCannotUpdate(container.ID, fmt.Errorf("Can not update kernel memory to a running container, please stop it first."))
 	}
 
 	if err := container.UpdateContainer(hostConfig); err != nil {
 		restoreConfig = true
-		return derr.ErrorCodeCantUpdate.WithArgs(container.ID, err.Error())
+		return errCannotUpdate(container.ID, err)
 	}
 
 	// if Restart Policy changed, we need to update container monitor
@@ -86,7 +83,7 @@ func (daemon *Daemon) update(name string, hostConfig *container.HostConfig) erro
 	if container.IsRunning() && !container.IsRestarting() {
 		if err := daemon.execDriver.Update(container.Command); err != nil {
 			restoreConfig = true
-			return derr.ErrorCodeCantUpdate.WithArgs(container.ID, err.Error())
+			return errCannotUpdate(container.ID, err)
 		}
 	}
 
@@ -94,3 +91,7 @@ func (daemon *Daemon) update(name string, hostConfig *container.HostConfig) erro
 
 	return nil
 }
+
+func errCannotUpdate(containerID string, err error) error {
+	return fmt.Errorf("Cannot update container %s: %v", containerID, err)
+}

+ 2 - 2
daemon/volumes.go

@@ -2,13 +2,13 @@ package daemon
 
 import (
 	"errors"
+	"fmt"
 	"os"
 	"path/filepath"
 	"strings"
 
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/daemon/execdriver"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/volume"
 	"github.com/docker/engine-api/types"
 	containertypes "github.com/docker/engine-api/types/container"
@@ -114,7 +114,7 @@ func (daemon *Daemon) registerMountPoints(container *container.Container, hostCo
 		}
 
 		if binds[bind.Destination] {
-			return derr.ErrorCodeMountDup.WithArgs(bind.Destination)
+			return fmt.Errorf("Duplicate mount point '%s'", bind.Destination)
 		}
 
 		if len(bind.Name) > 0 {

+ 2 - 2
daemon/volumes_windows.go

@@ -3,11 +3,11 @@
 package daemon
 
 import (
+	"fmt"
 	"sort"
 
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/daemon/execdriver"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/volume"
 )
 
@@ -27,7 +27,7 @@ func (daemon *Daemon) setupMounts(container *container.Container) ([]execdriver.
 			s = mount.Volume.Path()
 		}
 		if s == "" {
-			return nil, derr.ErrorCodeVolumeNoSourceForMount.WithArgs(mount.Name, mount.Driver, mount.Destination)
+			return nil, fmt.Errorf("No source for mount name '%s' driver %q destination '%s'", mount.Name, mount.Driver, mount.Destination)
 		}
 		mnts = append(mnts, execdriver.Mount{
 			Source:      s,

+ 9 - 3
docker/daemon.go

@@ -14,6 +14,7 @@ import (
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/uuid"
 	apiserver "github.com/docker/docker/api/server"
+	"github.com/docker/docker/api/server/router"
 	"github.com/docker/docker/api/server/router/build"
 	"github.com/docker/docker/api/server/router/container"
 	"github.com/docker/docker/api/server/router/image"
@@ -396,11 +397,16 @@ func loadDaemonCliConfig(config *daemon.Config, daemonFlags *flag.FlagSet, commo
 }
 
 func initRouter(s *apiserver.Server, d *daemon.Daemon) {
-	s.InitRouter(utils.IsDebugEnabled(),
+	routers := []router.Router{
 		container.NewRouter(d),
 		image.NewRouter(d),
-		network.NewRouter(d),
 		systemrouter.NewRouter(d),
 		volume.NewRouter(d),
-		build.NewRouter(dockerfile.NewBuildManager(d)))
+		build.NewRouter(dockerfile.NewBuildManager(d)),
+	}
+	if d.NetworkControllerEnabled() {
+		routers = append(routers, network.NewRouter(d))
+	}
+
+	s.InitRouter(utils.IsDebugEnabled(), routers...)
 }

+ 0 - 58
errors/README.md

@@ -1,58 +0,0 @@
-Docker 'errors' package
-=======================
-
-This package contains all of the error messages generated by the Docker
-engine that might be exposed via the Docker engine's REST API.
-
-Each top-level engine package will have its own file in this directory
-so that there's a clear grouping of errors, instead of just one big
-file. The errors for each package are defined here instead of within
-their respective package structure so that Docker CLI code that may need
-to import these error definition files will not need to know or understand
-the engine's package/directory structure. In other words, all they should
-need to do is import `.../docker/errors` and they will automatically
-pick up all Docker engine defined errors.  This also gives the engine
-developers the freedom to change the engine packaging structure (e.g. to
-CRUD packages) without worrying about breaking existing clients.
-
-These errors are defined using the 'errcode' package. The `errcode`  package
-allows for each error to be typed and include all information necessary to
-have further processing done on them if necessary.  In particular, each error
-includes:
-
-* Value - a unique string (in all caps) associated with this error.
-Typically, this string is the same name as the variable name of the error
-(w/o the `ErrorCode` text) but in all caps.
-
-* Message - the human readable sentence that will be displayed for this
-error. It can contain '%s' substitutions that allows for the code generating
-the error to specify values that will be inserted in the string prior to
-being displayed to the end-user. The `WithArgs()` function can be used to
-specify the insertion strings.  Note, the evaluation of the strings will be
-done at the time `WithArgs()` is called.
-
-* Description - additional human readable text to further explain the
-circumstances of the error situation.
-
-* HTTPStatusCode - when the error is returned back to a CLI, this value
-will be used to populate the HTTP status code. If not present the default
-value will be `StatusInternalServerError`, 500.
-
-Not all errors generated within the engine's executable will be propagated
-back to the engine's API layer. For example, it is expected that errors
-generated by vendored code (under `docker/vendor`) and packaged code
-(under `docker/pkg`) will be converted into errors defined by this package.
-
-When processing an errcode error, if you are looking for a particular
-error then you can do something like:
-
-```
-import derr "github.com/docker/docker/errors"
-
-...
-
-err := someFunc()
-if err.ErrorCode() == derr.ErrorCodeNoSuchContainer {
-	...
-}
-```

+ 0 - 93
errors/builder.go

@@ -1,93 +0,0 @@
-package errors
-
-// This file contains all of the errors that can be generated from the
-// docker/builder component.
-
-import (
-	"net/http"
-
-	"github.com/docker/distribution/registry/api/errcode"
-)
-
-var (
-	// ErrorCodeAtLeastOneArg is generated when the parser comes across a
-	// Dockerfile command that doesn't have any args.
-	ErrorCodeAtLeastOneArg = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "ATLEASTONEARG",
-		Message:        "%s requires at least one argument",
-		Description:    "The specified command requires at least one argument",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeExactlyOneArg is generated when the parser comes across a
-	// Dockerfile command that requires exactly one arg but got less/more.
-	ErrorCodeExactlyOneArg = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "EXACTLYONEARG",
-		Message:        "%s requires exactly one argument",
-		Description:    "The specified command requires exactly one argument",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeAtLeastTwoArgs is generated when the parser comes across a
-	// Dockerfile command that requires at least two args but got less.
-	ErrorCodeAtLeastTwoArgs = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "ATLEASTTWOARGS",
-		Message:        "%s requires at least two arguments",
-		Description:    "The specified command requires at least two arguments",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeTooManyArgs is generated when the parser comes across a
-	// Dockerfile command that has more args than it should
-	ErrorCodeTooManyArgs = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "TOOMANYARGS",
-		Message:        "Bad input to %s, too many args",
-		Description:    "The specified command was passed too many arguments",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeChainOnBuild is generated when the parser comes across a
-	// Dockerfile command that is trying to chain ONBUILD commands.
-	ErrorCodeChainOnBuild = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "CHAINONBUILD",
-		Message:        "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed",
-		Description:    "ONBUILD Dockerfile commands aren't allow on ONBUILD commands",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeBadOnBuildCmd is generated when the parser comes across a
-	// an ONBUILD Dockerfile command with an invalid trigger/command.
-	ErrorCodeBadOnBuildCmd = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "BADONBUILDCMD",
-		Message:        "%s isn't allowed as an ONBUILD trigger",
-		Description:    "The specified ONBUILD command isn't allowed",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeMissingFrom is generated when the Dockerfile is missing
-	// a FROM command.
-	ErrorCodeMissingFrom = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "MISSINGFROM",
-		Message:        "Please provide a source image with `from` prior to run",
-		Description:    "The Dockerfile is missing a FROM command",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeNotOnWindows is generated when the specified Dockerfile
-	// command is not supported on Windows.
-	ErrorCodeNotOnWindows = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NOTONWINDOWS",
-		Message:        "%s is not supported on Windows",
-		Description:    "The specified Dockerfile command is not supported on Windows",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeVolumeEmpty is generated when the specified Volume string
-	// is empty.
-	ErrorCodeVolumeEmpty = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "VOLUMEEMPTY",
-		Message:        "Volume specified can not be an empty string",
-		Description:    "The specified volume can not be an empty string",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-)

+ 0 - 1013
errors/daemon.go

@@ -1,1013 +0,0 @@
-package errors
-
-// This file contains all of the errors that can be generated from the
-// docker/daemon component.
-
-import (
-	"net/http"
-
-	"github.com/docker/distribution/registry/api/errcode"
-)
-
-var (
-	// ErrorCodeNoSuchContainer is generated when we look for a container by
-	// name or ID and we can't find it.
-	ErrorCodeNoSuchContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NOSUCHCONTAINER",
-		Message:        "No such container: %s",
-		Description:    "The specified container can not be found",
-		HTTPStatusCode: http.StatusNotFound,
-	})
-
-	// ErrorCodeUnregisteredContainer is generated when we try to load
-	// a storage driver for an unregistered container
-	ErrorCodeUnregisteredContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "UNREGISTEREDCONTAINER",
-		Message:        "Can't load storage driver for unregistered container %s",
-		Description:    "An attempt was made to load the storage driver for a container that is not registered with the daemon",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeContainerBeingRemoved is generated when an attempt to start
-	// a container is made but its in the process of being removed, or is dead.
-	ErrorCodeContainerBeingRemoved = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "CONTAINERBEINGREMOVED",
-		Message:        "Container is marked for removal and cannot be started.",
-		Description:    "An attempt was made to start a container that is in the process of being deleted",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeUnpauseContainer is generated when we attempt to stop a
-	// container but its paused.
-	ErrorCodeUnpauseContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "UNPAUSECONTAINER",
-		Message:        "Container %s is paused. Unpause the container before stopping",
-		Description:    "The specified container is paused, before it can be stopped it must be unpaused",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeRemovalContainer is generated when we attempt to connect or disconnect a
-	// container but it's marked for removal.
-	ErrorCodeRemovalContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "REMOVALCONTAINER",
-		Message:        "Container %s is marked for removal and cannot be connected or disconnected to the network",
-		Description:    "The specified container is marked for removal and cannot be connected or disconnected to the network",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodePausedContainer is generated when we attempt to attach a
-	// container but its paused.
-	ErrorCodePausedContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "CONTAINERPAUSED",
-		Message:        "Container %s is paused. Unpause the container before attach",
-		Description:    "The specified container is paused, unpause the container before attach",
-		HTTPStatusCode: http.StatusConflict,
-	})
-	// ErrorCodeAlreadyPaused is generated when we attempt to pause a
-	// container when its already paused.
-	ErrorCodeAlreadyPaused = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "ALREADYPAUSED",
-		Message:        "Container %s is already paused",
-		Description:    "The specified container is already in the paused state",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeNotPaused is generated when we attempt to unpause a
-	// container when its not paused.
-	ErrorCodeNotPaused = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NOTPAUSED",
-		Message:        "Container %s is not paused",
-		Description:    "The specified container can not be unpaused because it is not in a paused state",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeImageUnregContainer is generated when we attempt to get the
-	// image of an unknown/unregistered container.
-	ErrorCodeImageUnregContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "IMAGEUNREGCONTAINER",
-		Message:        "Can't get image of unregistered container",
-		Description:    "An attempt to retrieve the image of a container was made but the container is not registered",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeEmptyID is generated when an ID is the empty string.
-	ErrorCodeEmptyID = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "EMPTYID",
-		Message:        "Invalid empty id",
-		Description:    "An attempt was made to register a container but the container's ID can not be an empty string",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeLoggingFactory is generated when we could not load the
-	// log driver.
-	ErrorCodeLoggingFactory = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "LOGGINGFACTORY",
-		Message:        "Failed to get logging factory: %v",
-		Description:    "An attempt was made to register a container but the container's ID can not be an empty string",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeInitLogger is generated when we could not initialize
-	// the logging driver.
-	ErrorCodeInitLogger = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "INITLOGGER",
-		Message:        "Failed to initialize logging driver: %v",
-		Description:    "An error occurred while trying to initialize the logging driver",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeNotRunning is generated when we need to verify that
-	// a container is running, but its not.
-	ErrorCodeNotRunning = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NOTRUNNING",
-		Message:        "Container %s is not running",
-		Description:    "The specified action can not be taken due to the container not being in a running state",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeLinkNotRunning is generated when we try to link to a
-	// container that is not running.
-	ErrorCodeLinkNotRunning = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "LINKNOTRUNNING",
-		Message:        "Cannot link to a non running container: %s AS %s",
-		Description:    "An attempt was made to link to a container but the container is not in a running state",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeDeviceInfo is generated when there is an error while trying
-	// to get info about a custom device.
-	// container that is not running.
-	ErrorCodeDeviceInfo = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "DEVICEINFO",
-		Message:        "error gathering device information while adding custom device %q: %s",
-		Description:    "There was an error while trying to retrieve the information about a custom device",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeEmptyEndpoint is generated when the endpoint for a port
-	// map is nil.
-	ErrorCodeEmptyEndpoint = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "EMPTYENDPOINT",
-		Message:        "invalid endpoint while building port map info",
-		Description:    "The specified endpoint for the port mapping is empty",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeEmptyNetwork is generated when the networkSettings for a port
-	// map is nil.
-	ErrorCodeEmptyNetwork = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "EMPTYNETWORK",
-		Message:        "invalid network settings while building port map info",
-		Description:    "The specified endpoint for the port mapping is empty",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeParsingPort is generated when there is an error parsing
-	// a "port" string.
-	ErrorCodeParsingPort = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "PARSINGPORT",
-		Message:        "Error parsing Port value(%v):%v",
-		Description:    "There was an error while trying to parse the specified 'port' value",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeNoSandbox is generated when we can't find the specified
-	// sandbox(network) by ID.
-	ErrorCodeNoSandbox = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NOSANDBOX",
-		Message:        "error locating sandbox id %s: %v",
-		Description:    "There was an error trying to located the specified networking sandbox",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeNetworkUpdate is generated when there is an error while
-	// trying update a network/sandbox config.
-	ErrorCodeNetworkUpdate = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NETWORKUPDATE",
-		Message:        "Update network failed: %v",
-		Description:    "There was an error trying to update the configuration information of the specified network sandbox",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeNetworkRefresh is generated when there is an error while
-	// trying refresh a network/sandbox config.
-	ErrorCodeNetworkRefresh = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NETWORKREFRESH",
-		Message:        "Update network failed: Failure in refresh sandbox %s: %v",
-		Description:    "There was an error trying to refresh the configuration information of the specified network sandbox",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeHostPort is generated when there was an error while trying
-	// to parse a "host/port" string.
-	ErrorCodeHostPort = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "HOSTPORT",
-		Message:        "Error parsing HostPort value(%s):%v",
-		Description:    "There was an error trying to parse the specified 'HostPort' value",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeNetworkConflict is generated when we try to publish a service
-	// in network mode.
-	ErrorCodeNetworkConflict = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NETWORKCONFLICT",
-		Message:        "conflicting options: publishing a service and network mode",
-		Description:    "It is not possible to publish a service when it is in network mode",
-		HTTPStatusCode: http.StatusConflict,
-	})
-
-	// ErrorCodeJoinInfo is generated when we failed to update a container's
-	// join info.
-	ErrorCodeJoinInfo = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "JOININFO",
-		Message:        "Updating join info failed: %v",
-		Description:    "There was an error during an attempt update a container's join information",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeIPCRunning is generated when we try to join a container's
-	// IPC but it's not running.
-	ErrorCodeIPCRunning = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "IPCRUNNING",
-		Message:        "cannot join IPC of a non running container: %s",
-		Description:    "An attempt was made to join the IPC of a container, but the container is not running",
-		HTTPStatusCode: http.StatusConflict,
-	})
-
-	// ErrorCodeNotADir is generated when we try to create a directory
-	// but the path isn't a dir.
-	ErrorCodeNotADir = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NOTADIR",
-		Message:        "Cannot mkdir: %s is not a directory",
-		Description:    "An attempt was made create a directory, but the location in which it is being created is not a directory",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeParseContainer is generated when the reference to a
-	// container doesn't include a ":" (another container).
-	ErrorCodeParseContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "PARSECONTAINER",
-		Message:        "no container specified to join network",
-		Description:    "The specified reference to a container is missing a ':' as a separator between 'container' and 'name'/'id'",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeJoinSelf is generated when we try to network to ourselves.
-	ErrorCodeJoinSelf = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "JOINSELF",
-		Message:        "cannot join own network",
-		Description:    "An attempt was made to have a container join its own network",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeJoinRunning is generated when we try to network to ourselves.
-	ErrorCodeJoinRunning = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "JOINRUNNING",
-		Message:        "cannot join network of a non running container: %s",
-		Description:    "An attempt to join the network of a container, but that container isn't running",
-		HTTPStatusCode: http.StatusConflict,
-	})
-
-	// ErrorCodeModeNotContainer is generated when we try to network to
-	// another container but the mode isn't 'container'.
-	ErrorCodeModeNotContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "MODENOTCONTAINER",
-		Message:        "network mode not set to container",
-		Description:    "An attempt was made to connect to a container's network but the mode wasn't set to 'container'",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeRemovingVolume is generated when we try remove a mount
-	// point (volume) but fail.
-	ErrorCodeRemovingVolume = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "REMOVINGVOLUME",
-		Message:        "Error removing volumes:\n%v",
-		Description:    "There was an error while trying to remove the mount point (volume) of a container",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeInvalidNetworkMode is generated when an invalid network
-	// mode value is specified.
-	ErrorCodeInvalidNetworkMode = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "INVALIDNETWORKMODE",
-		Message:        "invalid network mode: %s",
-		Description:    "The specified networking mode is not valid",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeGetGraph is generated when there was an error while
-	// trying to find a graph/image.
-	ErrorCodeGetGraph = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "GETGRAPH",
-		Message:        "Failed to graph.Get on ImageID %s - %s",
-		Description:    "There was an error trying to retrieve the image for the specified image ID",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeGetLayer is generated when there was an error while
-	// trying to retrieve a particular layer of an image.
-	ErrorCodeGetLayer = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "GETLAYER",
-		Message:        "Failed to get layer path from graphdriver %s for ImageID %s - %s",
-		Description:    "There was an error trying to retrieve the layer of the specified image",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodePutLayer is generated when there was an error while
-	// trying to 'put' a particular layer of an image.
-	ErrorCodePutLayer = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "PUTLAYER",
-		Message:        "Failed to put layer path from graphdriver %s for ImageID %s - %s",
-		Description:    "There was an error trying to store a layer for the specified image",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeGetLayerMetadata is generated when there was an error while
-	// trying to retrieve the metadata of a layer of an image.
-	ErrorCodeGetLayerMetadata = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "GETLAYERMETADATA",
-		Message:        "Failed to get layer metadata - %s",
-		Description:    "There was an error trying to retrieve the metadata of a layer for the specified image",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeEmptyConfig is generated when the input config data
-	// is empty.
-	ErrorCodeEmptyConfig = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "EMPTYCONFIG",
-		Message:        "Config cannot be empty in order to create a container",
-		Description:    "While trying to create a container, the specified configuration information was empty",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeNoSuchImageHash is generated when we can't find the
-	// specified image by its hash
-	ErrorCodeNoSuchImageHash = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NOSUCHIMAGEHASH",
-		Message:        "No such image: %s",
-		Description:    "An attempt was made to find an image by its hash, but the lookup failed",
-		HTTPStatusCode: http.StatusNotFound,
-	})
-
-	// ErrorCodeNoSuchImageTag is generated when we can't find the
-	// specified image byt its name/tag.
-	ErrorCodeNoSuchImageTag = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NOSUCHIMAGETAG",
-		Message:        "No such image: %s:%s",
-		Description:    "An attempt was made to find an image by its name/tag, but the lookup failed",
-		HTTPStatusCode: http.StatusNotFound,
-	})
-
-	// ErrorCodeMountOverFile is generated when we try to mount a volume
-	// over an existing file (but not a dir).
-	ErrorCodeMountOverFile = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "MOUNTOVERFILE",
-		Message:        "cannot mount volume over existing file, file exists %s",
-		Description:    "An attempt was made to mount a volume at the same location as a pre-existing file",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeMountSetup is generated when we can't define a mount point
-	// due to the source and destination being undefined.
-	ErrorCodeMountSetup = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "MOUNTSETUP",
-		Message:        "Unable to setup mount point, neither source nor volume defined",
-		Description:    "An attempt was made to setup a mount point, but the source and destination are undefined",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeVolumeInvalidMode is generated when the mode of a volume/bind
-	// mount is invalid.
-	ErrorCodeVolumeInvalidMode = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "VOLUMEINVALIDMODE",
-		Message:        "invalid mode: %q",
-		Description:    "An invalid 'mode' was specified",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeVolumeInvalid is generated when the format fo the
-	// volume specification isn't valid.
-	ErrorCodeVolumeInvalid = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "VOLUMEINVALID",
-		Message:        "Invalid volume specification: '%s'",
-		Description:    "An invalid 'volume' was specified in the mount request",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeVolumeAbs is generated when path to a volume isn't absolute.
-	ErrorCodeVolumeAbs = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "VOLUMEABS",
-		Message:        "Invalid volume destination path: '%s' mount path must be absolute.",
-		Description:    "An invalid 'destination' path was specified in the mount request, it must be an absolute path",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeVolumeName is generated when the name of named volume isn't valid.
-	ErrorCodeVolumeName = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "VOLUME_NAME_INVALID",
-		Message:        "%q includes invalid characters for a local volume name, only %q are allowed",
-		Description:    "The name of volume is invalid",
-		HTTPStatusCode: http.StatusBadRequest,
-	})
-
-	// ErrorCodeVolumeSlash is generated when destination path to a volume is /
-	ErrorCodeVolumeSlash = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "VOLUMESLASH",
-		Message:        "Invalid specification: destination can't be '/' in '%s'",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeVolumeDestIsC is generated the destination is c: (Windows specific)
-	ErrorCodeVolumeDestIsC = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "VOLUMEDESTISC",
-		Message:        "Destination drive letter in '%s' cannot be c:",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeVolumeDestIsCRoot is generated the destination path is c:\ (Windows specific)
-	ErrorCodeVolumeDestIsCRoot = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "VOLUMEDESTISCROOT",
-		Message:        `Destination path in '%s' cannot be c:\`,
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeVolumeSourceNotFound is generated the source directory could not be found (Windows specific)
-	ErrorCodeVolumeSourceNotFound = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "VOLUMESOURCENOTFOUND",
-		Message:        "Source directory '%s' could not be found: %s",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeVolumeSourceNotDirectory is generated the source is not a directory (Windows specific)
-	ErrorCodeVolumeSourceNotDirectory = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "VOLUMESOURCENOTDIRECTORY",
-		Message:        "Source '%s' is not a directory",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeVolumeFromBlank is generated when path to a volume is blank.
-	ErrorCodeVolumeFromBlank = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "VOLUMEFROMBLANK",
-		Message:        "malformed volumes-from specification: %q",
-		Description:    "An invalid 'destination' path was specified in the mount request, it must not be blank",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeMountDup is generated when we try to mount two mounts points
-	// to the same path.
-	ErrorCodeMountDup = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "MOUNTDUP",
-		Message:        "Duplicate mount point '%s'",
-		Description:    "An attempt was made to mount a content but the specified destination location is already used in a previous mount",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeVolumeNoSourceForMount is generated when no source directory
-	// for a volume mount was found. (Windows specific)
-	ErrorCodeVolumeNoSourceForMount = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "VOLUMENOSOURCEFORMOUNT",
-		Message:        "No source for mount name '%s' driver %q destination '%s'",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeVolumeNameReservedWord is generated when the name in a volume
-	// uses a reserved word for filenames. (Windows specific)
-	ErrorCodeVolumeNameReservedWord = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "VOLUMENAMERESERVEDWORD",
-		Message:        "Volume name %q cannot be a reserved word for Windows filenames",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeCantPause is generated when there's an error while trying
-	// to pause a container.
-	ErrorCodeCantPause = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "CANTPAUSE",
-		Message:        "Cannot pause container %s: %s",
-		Description:    "An error occurred while trying to pause the specified container",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeCantUnpause is generated when there's an error while trying
-	// to unpause a container.
-	ErrorCodeCantUnpause = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "CANTUNPAUSE",
-		Message:        "Cannot unpause container %s: %s",
-		Description:    "An error occurred while trying to unpause the specified container",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeCantKill is generated when there's an error while trying
-	// to kill a container.
-	ErrorCodeCantKill = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "CANTKILL",
-		Message:        "Cannot kill container %s: %s",
-		Description:    "An error occurred while trying to kill the specified container",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeCantUpdate is generated when there's an error while trying
-	// to update a container.
-	ErrorCodeCantUpdate = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "CANTUPDATE",
-		Message:        "Cannot update container %s: %s",
-		Description:    "An error occurred while trying to update the specified container",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-	// ErrorCodePSError is generated when trying to run 'ps'.
-	ErrorCodePSError = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "PSError",
-		Message:        "Error running ps: %s",
-		Description:    "There was an error trying to run the 'ps' command in the specified container",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeNoPID is generated when looking for the PID field in the
-	// ps output.
-	ErrorCodeNoPID = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NOPID",
-		Message:        "Couldn't find PID field in ps output",
-		Description:    "There was no 'PID' field in the output of the 'ps' command that was executed",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeBadPID is generated when we can't convert a PID to an int.
-	ErrorCodeBadPID = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "BADPID",
-		Message:        "Unexpected pid '%s': %s",
-		Description:    "While trying to parse the output of the 'ps' command, the 'PID' field was not an integer",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeNoTop is generated when we try to run 'top' but can't
-	// because we're on windows.
-	ErrorCodeNoTop = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NOTOP",
-		Message:        "Top is not supported on Windows",
-		Description:    "The 'top' command is not supported on Windows",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeStopped is generated when we try to stop a container
-	// that is already stopped.
-	ErrorCodeStopped = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "STOPPED",
-		Message:        "Container %s is already stopped",
-		Description:    "An attempt was made to stop a container, but the container is already stopped",
-		HTTPStatusCode: http.StatusNotModified,
-	})
-
-	// ErrorCodeCantStop is generated when we try to stop a container
-	// but failed for some reason.
-	ErrorCodeCantStop = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "CANTSTOP",
-		Message:        "Cannot stop container %s: %s\n",
-		Description:    "An error occurred while tring to stop the specified container",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeBadCPUFields is generated when the number of CPU fields is
-	// less than 8.
-	ErrorCodeBadCPUFields = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "BADCPUFIELDS",
-		Message:        "invalid number of cpu fields",
-		Description:    "While reading the '/proc/stat' file, the number of 'cpu' fields is less than 8",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeBadCPUInt is generated the CPU field can't be parsed as an int.
-	ErrorCodeBadCPUInt = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "BADCPUINT",
-		Message:        "Unable to convert value %s to int: %s",
-		Description:    "While reading the '/proc/stat' file, the 'CPU' field could not be parsed as an integer",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeBadStatFormat is generated the output of the stat info
-	// isn't parseable.
-	ErrorCodeBadStatFormat = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "BADSTATFORMAT",
-		Message:        "invalid stat format",
-		Description:    "There was an error trying to parse the '/proc/stat' file",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeTimedOut is generated when a timer expires.
-	ErrorCodeTimedOut = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "TIMEDOUT",
-		Message:        "Timed out: %v",
-		Description:    "A timer expired",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeAlreadyRemoving is generated when we try to remove a
-	// container that is already being removed.
-	ErrorCodeAlreadyRemoving = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "ALREADYREMOVING",
-		Message:        "Status is already RemovalInProgress",
-		Description:    "An attempt to remove a container was made, but the container is already in the process of being removed",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeStartPaused is generated when we start a paused container.
-	ErrorCodeStartPaused = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "STARTPAUSED",
-		Message:        "Cannot start a paused container, try unpause instead.",
-		Description:    "An attempt to start a container was made, but the container is paused. Unpause it first",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeAlreadyStarted is generated when we try to start a container
-	// that is already running.
-	ErrorCodeAlreadyStarted = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "ALREADYSTARTED",
-		Message:        "Container already started",
-		Description:    "An attempt to start a container was made, but the container is already started",
-		HTTPStatusCode: http.StatusNotModified,
-	})
-
-	// ErrorCodeHostConfigStart is generated when a HostConfig is passed
-	// into the start command.
-	ErrorCodeHostConfigStart = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "HOSTCONFIGSTART",
-		Message:        "Supplying a hostconfig on start is not supported. It should be supplied on create",
-		Description:    "The 'start' command does not accept 'HostConfig' data, try using the 'create' command instead",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeCantRestart is generated when an error occurred while
-	// trying to restart a container.
-	ErrorCodeCantRestart = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "CANTRESTART",
-		Message:        "Cannot restart container %s: %s",
-		Description:    "There was an error while trying to restart a container",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeEmptyRename is generated when one of the names on a
-	// rename is empty.
-	ErrorCodeEmptyRename = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "EMPTYRENAME",
-		Message:        "Neither old nor new names may be empty",
-		Description:    "An attempt was made to rename a container but either the old or new names were blank",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeRenameTaken is generated when we try to rename but the
-	// new name isn't available.
-	ErrorCodeRenameTaken = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "RENAMETAKEN",
-		Message:        "Error when allocating new name: %s",
-		Description:    "The new name specified on the 'rename' command is already being used",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeRenameDelete is generated when we try to rename but
-	// failed trying to delete the old container.
-	ErrorCodeRenameDelete = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "RENAMEDELETE",
-		Message:        "Failed to delete container %q: %v",
-		Description:    "There was an error trying to delete the specified container",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodePauseError is generated when we try to pause a container
-	// but failed.
-	ErrorCodePauseError = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "PAUSEERROR",
-		Message:        "Cannot pause container %s: %s",
-		Description:    "There was an error trying to pause the specified container",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeNeedStream is generated when we try to stream a container's
-	// logs but no output stream was specified.
-	ErrorCodeNeedStream = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NEEDSTREAM",
-		Message:        "You must choose at least one stream",
-		Description:    "While trying to stream a container's logs, no output stream was specified",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeDanglingOne is generated when we try to specify more than one
-	// 'dangling' specifier.
-	ErrorCodeDanglingOne = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "DANLGINGONE",
-		Message:        "Conflict: cannot use more than 1 value for `dangling` filter",
-		Description:    "The specified 'dangling' filter may not have more than one value",
-		HTTPStatusCode: http.StatusConflict,
-	})
-
-	// ErrorCodeImgDelUsed is generated when we try to delete an image
-	// but it is being used.
-	ErrorCodeImgDelUsed = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "IMGDELUSED",
-		Message:        "conflict: unable to remove repository reference %q (must force) - container %s is using its referenced image %s",
-		Description:    "An attempt was made to delete an image but it is currently being used",
-		HTTPStatusCode: http.StatusConflict,
-	})
-
-	// ErrorCodeImgNoParent is generated when we try to find an image's
-	// parent but its not in the graph.
-	ErrorCodeImgNoParent = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "IMGNOPARENT",
-		Message:        "unable to get parent image: %v",
-		Description:    "There was an error trying to find an image's parent, it was not in the graph",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeExportFailed is generated when an export fails.
-	ErrorCodeExportFailed = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "EXPORTFAILED",
-		Message:        "%s: %s",
-		Description:    "There was an error during an export operation",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeExecResize is generated when we try to resize an exec
-	// but its not running.
-	ErrorCodeExecResize = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "EXECRESIZE",
-		Message:        "Exec %s is not running, so it can not be resized.",
-		Description:    "An attempt was made to resize an 'exec', but the 'exec' is not running",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeContainerNotRunning is generated when we try to get the info
-	// on an exec but the container is not running.
-	ErrorCodeContainerNotRunning = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "CONTAINERNOTRUNNING",
-		Message:        "Container %s is not running: %s",
-		Description:    "An attempt was made to retrieve the information about an 'exec' but the container is not running",
-		HTTPStatusCode: http.StatusConflict,
-	})
-
-	// ErrorCodeContainerRestarting is generated when an operation was made
-	// on a restarting container.
-	ErrorCodeContainerRestarting = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "CONTAINERRESTARTING",
-		Message:        "Container %s is restarting, wait until the container is running",
-		Description:    "An operation was made on a restarting container",
-		HTTPStatusCode: http.StatusConflict,
-	})
-
-	// ErrorCodeNoExecID is generated when we try to get the info
-	// on an exec but it can't be found.
-	ErrorCodeNoExecID = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NOEXECID",
-		Message:        "No such exec instance '%s' found in daemon",
-		Description:    "The specified 'exec' instance could not be found",
-		HTTPStatusCode: http.StatusNotFound,
-	})
-
-	// ErrorCodeExecPaused is generated when we try to start an exec
-	// but the container is paused.
-	ErrorCodeExecPaused = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "EXECPAUSED",
-		Message:        "Container %s is paused, unpause the container before exec",
-		Description:    "An attempt to start an 'exec' was made, but the owning container is paused",
-		HTTPStatusCode: http.StatusConflict,
-	})
-
-	// ErrorCodeExecRunning is generated when we try to start an exec
-	// but its already running.
-	ErrorCodeExecRunning = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "EXECRUNNING",
-		Message:        "Error: Exec command %s is already running",
-		Description:    "An attempt to start an 'exec' was made, but 'exec' is already running",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeExecExited is generated when we try to start an exec
-	// but its already running.
-	ErrorCodeExecExited = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "EXECEXITED",
-		Message:        "Error: Exec command %s has already run",
-		Description:    "An attempt to start an 'exec' was made, but 'exec' was already run",
-		HTTPStatusCode: http.StatusConflict,
-	})
-
-	// ErrorCodeExecCantRun is generated when we try to start an exec
-	// but it failed for some reason.
-	ErrorCodeExecCantRun = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "EXECCANTRUN",
-		Message:        "Cannot run exec command %s in container %s: %s",
-		Description:    "An attempt to start an 'exec' was made, but an error occurred",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeExecAttach is generated when we try to attach to an exec
-	// but failed.
-	ErrorCodeExecAttach = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "EXECATTACH",
-		Message:        "attach failed with error: %s",
-		Description:    "There was an error while trying to attach to an 'exec'",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeExecContainerStopped is generated when we try to start
-	// an exec but then the container stopped.
-	ErrorCodeExecContainerStopped = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "EXECCONTAINERSTOPPED",
-		Message:        "container stopped while running exec",
-		Description:    "An attempt was made to start an 'exec' but the owning container is in the 'stopped' state",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeDefaultName is generated when we try to delete the
-	// default name of a container.
-	ErrorCodeDefaultName = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "DEFAULTNAME",
-		Message:        "Conflict, cannot remove the default name of the container",
-		Description:    "An attempt to delete the default name of a container was made, but that is not allowed",
-		HTTPStatusCode: http.StatusConflict,
-	})
-
-	// ErrorCodeNoParent is generated when we try to delete a container
-	// but we can't find its parent image.
-	ErrorCodeNoParent = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NOPARENT",
-		Message:        "Cannot get parent %s for name %s",
-		Description:    "An attempt was made to delete a container but its parent image could not be found",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeCantDestroy is generated when we try to delete a container
-	// but failed for some reason.
-	ErrorCodeCantDestroy = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "CANTDESTROY",
-		Message:        "Cannot destroy container %s: %v",
-		Description:    "An attempt was made to delete a container but it failed",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeRmRunning is generated when we try to delete a container
-	// but its still running.
-	ErrorCodeRmRunning = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "RMRUNNING",
-		Message:        "You cannot remove a running container %s. Stop the container before attempting removal or use -f",
-		Description:    "An attempt was made to delete a container but the container is still running, try to either stop it first or use '-f'",
-		HTTPStatusCode: http.StatusConflict,
-	})
-
-	// ErrorCodeRmFailed is generated when we try to delete a container
-	// but it failed for some reason.
-	ErrorCodeRmFailed = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "RMFAILED",
-		Message:        "Could not kill running container %s, cannot remove - %v",
-		Description:    "An error occurred while trying to delete a running container",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeRmNotFound is generated when we try to delete a container
-	// but couldn't find it.
-	ErrorCodeRmNotFound = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "RMNOTFOUND",
-		Message:        "Could not kill running container, cannot remove - %v",
-		Description:    "An attempt to delete a container was made but the container could not be found",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeRmState is generated when we try to delete a container
-	// but couldn't set its state to RemovalInProgress.
-	ErrorCodeRmState = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "RMSTATE",
-		Message:        "Failed to set container %s state to RemovalInProgress: %s",
-		Description:    "An attempt to delete a container was made, but there as an error trying to set its state to 'RemovalInProgress'",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeRmDriverFS is generated when we try to delete a container
-	// but the driver failed to delete its filesystem.
-	ErrorCodeRmDriverFS = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "RMDRIVERFS",
-		Message:        "Driver %s failed to remove root filesystem %s: %s",
-		Description:    "While trying to delete a container, the driver failed to remove the root filesystem",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeRmFS is generated when we try to delete a container
-	// but failed deleting its filesystem.
-	ErrorCodeRmFS = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "RMFS",
-		Message:        "Unable to remove filesystem for %v: %v",
-		Description:    "While trying to delete a container, the driver failed to remove the filesystem",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeRmExecDriver is generated when we try to delete a container
-	// but failed deleting its exec driver data.
-	ErrorCodeRmExecDriver = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "RMEXECDRIVER",
-		Message:        "Unable to remove execdriver data for %s: %s",
-		Description:    "While trying to delete a container, there was an error trying to remove th exec driver data",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeRmVolumeInUse is generated when we try to delete a container
-	// but failed deleting a volume because its being used.
-	ErrorCodeRmVolumeInUse = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "RMVOLUMEINUSE",
-		Message:        "Conflict: %v",
-		Description:    "While trying to delete a container, one of its volumes is still being used",
-		HTTPStatusCode: http.StatusConflict,
-	})
-
-	// ErrorCodeRmVolume is generated when we try to delete a container
-	// but failed deleting a volume.
-	ErrorCodeRmVolume = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "RMVOLUME",
-		Message:        "Error while removing volume %s: %v",
-		Description:    "While trying to delete a container, there was an error trying to delete one of its volumes",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeInvalidCpusetCpus is generated when user provided cpuset CPUs
-	// are invalid.
-	ErrorCodeInvalidCpusetCpus = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "INVALIDCPUSETCPUS",
-		Message:        "Invalid value %s for cpuset cpus.",
-		Description:    "While verifying the container's 'HostConfig', CpusetCpus value was in an incorrect format",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeInvalidCpusetMems is generated when user provided cpuset mems
-	// are invalid.
-	ErrorCodeInvalidCpusetMems = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "INVALIDCPUSETMEMS",
-		Message:        "Invalid value %s for cpuset mems.",
-		Description:    "While verifying the container's 'HostConfig', CpusetMems value was in an incorrect format",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeNotAvailableCpusetCpus is generated when user provided cpuset
-	// CPUs aren't available in the container's cgroup.
-	ErrorCodeNotAvailableCpusetCpus = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NOTAVAILABLECPUSETCPUS",
-		Message:        "Requested CPUs are not available - requested %s, available: %s.",
-		Description:    "While verifying the container's 'HostConfig', cpuset CPUs provided aren't available in the container's cgroup available set",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeNotAvailableCpusetMems is generated when user provided cpuset
-	// memory nodes aren't available in the container's cgroup.
-	ErrorCodeNotAvailableCpusetMems = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NOTAVAILABLECPUSETMEMS",
-		Message:        "Requested memory nodes are not available - requested %s, available: %s.",
-		Description:    "While verifying the container's 'HostConfig', cpuset memory nodes provided aren't available in the container's cgroup available set",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorVolumeNameTaken is generated when an error occurred while
-	// trying to create a volume that has existed using different driver.
-	ErrorVolumeNameTaken = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "VOLUME_NAME_TAKEN",
-		Message:        "A volume named %s already exists. Choose a different volume name.",
-		Description:    "An attempt to create a volume using a driver but the volume already exists with a different driver",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeCmdNotFound is generated when container cmd can't start,
-	// container command not found error, exit code 127
-	ErrorCodeCmdNotFound = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "CMDNOTFOUND",
-		Message:        "Container command not found or does not exist.",
-		Description:    "Command could not be found, command does not exist",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeCmdCouldNotBeInvoked is generated when container cmd can't start,
-	// container command permission denied error, exit code 126
-	ErrorCodeCmdCouldNotBeInvoked = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "CMDCOULDNOTBEINVOKED",
-		Message:        "Container command could not be invoked.",
-		Description:    "Permission denied, cannot invoke command",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeCantStart is generated when container cmd can't start,
-	// for any reason other than above 2 errors
-	ErrorCodeCantStart = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "CANTSTART",
-		Message:        "Cannot start container %s: %s",
-		Description:    "There was an error while trying to start a container",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-
-	// ErrorCodeCantDeletePredefinedNetwork is generated when one of the predefined networks
-	// is attempted to be deleted.
-	ErrorCodeCantDeletePredefinedNetwork = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "CANT_DELETE_PREDEFINED_NETWORK",
-		Message:        "%s is a pre-defined network and cannot be removed",
-		Description:    "Engine's predefined networks cannot be deleted",
-		HTTPStatusCode: http.StatusForbidden,
-	})
-
-	// ErrorCodeMultipleNetworkConnect is generated when more than one network is passed
-	// when creating a container
-	ErrorCodeMultipleNetworkConnect = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "CANNOT_CONNECT_TO_MULTIPLE_NETWORKS",
-		Message:        "Container cannot be connected to %s",
-		Description:    "A container can only be connected to one network at the time",
-		HTTPStatusCode: http.StatusBadRequest,
-	})
-)

+ 0 - 6
errors/error.go

@@ -1,6 +0,0 @@
-package errors
-
-// This file contains all of the errors that can be generated from the
-// docker engine but are not tied to any specific top-level component.
-
-const errGroup = "engine"

+ 41 - 0
errors/errors.go

@@ -0,0 +1,41 @@
+package errors
+
+import "net/http"
+
+// apiError is an error wrapper that also
+// holds information about response status codes.
+type apiError struct {
+	error
+	statusCode int
+}
+
+// HTTPErrorStatusCode returns a status code.
+func (e apiError) HTTPErrorStatusCode() int {
+	return e.statusCode
+}
+
+// NewErrorWithStatusCode allows you to associate
+// a specific HTTP Status Code to an error.
+// The Server will take that code and set
+// it as the response status.
+func NewErrorWithStatusCode(err error, code int) error {
+	return apiError{err, code}
+}
+
+// NewBadRequestError creates a new API error
+// that has the 400 HTTP status code associated to it.
+func NewBadRequestError(err error) error {
+	return NewErrorWithStatusCode(err, http.StatusBadRequest)
+}
+
+// NewRequestNotFoundError creates a new API error
+// that has the 404 HTTP status code associated to it.
+func NewRequestNotFoundError(err error) error {
+	return NewErrorWithStatusCode(err, http.StatusNotFound)
+}
+
+// NewRequestConflictError creates a new API error
+// that has the 409 HTTP status code associated to it.
+func NewRequestConflictError(err error) error {
+	return NewErrorWithStatusCode(err, http.StatusConflict)
+}

+ 0 - 20
errors/image.go

@@ -1,20 +0,0 @@
-package errors
-
-// This file contains all of the errors that can be generated from the
-// docker/image component.
-
-import (
-	"net/http"
-
-	"github.com/docker/distribution/registry/api/errcode"
-)
-
-var (
-	// ErrorCodeInvalidImageID is generated when image id specified is incorrectly formatted.
-	ErrorCodeInvalidImageID = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "INVALIDIMAGEID",
-		Message:        "image ID '%s' is invalid ",
-		Description:    "The specified image id is incorrectly formatted",
-		HTTPStatusCode: http.StatusInternalServerError,
-	})
-)

+ 0 - 45
errors/server.go

@@ -1,45 +0,0 @@
-package errors
-
-import (
-	"net/http"
-
-	"github.com/docker/distribution/registry/api/errcode"
-)
-
-var (
-	// ErrorCodeNewerClientVersion is generated when a request from a client
-	// specifies a higher version than the server supports.
-	ErrorCodeNewerClientVersion = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NEWERCLIENTVERSION",
-		Message:        "client is newer than server (client API version: %s, server API version: %s)",
-		Description:    "The client version is higher than the server version",
-		HTTPStatusCode: http.StatusBadRequest,
-	})
-
-	// ErrorCodeOldClientVersion is generated when a request from a client
-	// specifies a version lower than the minimum version supported by the server.
-	ErrorCodeOldClientVersion = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "OLDCLIENTVERSION",
-		Message:        "client version %s is too old. Minimum supported API version is %s, please upgrade your client to a newer version",
-		Description:    "The client version is too old for the server",
-		HTTPStatusCode: http.StatusBadRequest,
-	})
-
-	// ErrorNetworkControllerNotEnabled is generated when the networking stack in not enabled
-	// for certain platforms, like windows.
-	ErrorNetworkControllerNotEnabled = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "NETWORK_CONTROLLER_NOT_ENABLED",
-		Message:        "the network controller is not enabled for this platform",
-		Description:    "Docker's networking stack is disabled for this platform",
-		HTTPStatusCode: http.StatusNotFound,
-	})
-
-	// ErrorCodeNoHijackConnection is generated when a request tries to attach to a container
-	// but the connection to hijack is not provided.
-	ErrorCodeNoHijackConnection = errcode.Register(errGroup, errcode.ErrorDescriptor{
-		Value:          "HIJACK_CONNECTION_MISSING",
-		Message:        "error attaching to container %s, hijack connection missing",
-		Description:    "The caller didn't provide a connection to hijack",
-		HTTPStatusCode: http.StatusBadRequest,
-	})
-)

+ 1 - 1
integration-cli/docker_api_containers_test.go

@@ -643,7 +643,7 @@ func (s *DockerSuite) TestContainerApiCreateMultipleNetworksConfig(c *check.C) {
 	c.Assert(err, checker.IsNil)
 	c.Assert(status, checker.Equals, http.StatusBadRequest)
 	// network name order in error message is not deterministic
-	c.Assert(string(b), checker.Contains, "Container cannot be connected to [")
+	c.Assert(string(b), checker.Contains, "Container cannot be connected to network endpoints")
 	c.Assert(string(b), checker.Contains, "net1")
 	c.Assert(string(b), checker.Contains, "net2")
 	c.Assert(string(b), checker.Contains, "net3")

+ 1 - 1
integration-cli/docker_cli_run_test.go

@@ -463,7 +463,7 @@ func (s *DockerSuite) TestRunVolumesFromInReadWriteMode(c *check.C) {
 	dockerCmd(c, "run", "--name", "parent", "-v", volumeDir, "busybox", "true")
 	dockerCmd(c, "run", "--volumes-from", "parent:rw", "busybox", "touch", fileInVol)
 
-	if out, _, err := dockerCmdWithError("run", "--volumes-from", "parent:bar", "busybox", "touch", fileInVol); err == nil || !strings.Contains(out, `invalid mode: "bar"`) {
+	if out, _, err := dockerCmdWithError("run", "--volumes-from", "parent:bar", "busybox", "touch", fileInVol); err == nil || !strings.Contains(out, `invalid mode: bar`) {
 		c.Fatalf("running --volumes-from parent:bar should have failed with invalid mode: %q", out)
 	}
 

+ 0 - 20
utils/utils.go

@@ -7,7 +7,6 @@ import (
 	"runtime"
 	"strings"
 
-	"github.com/docker/distribution/registry/api/errcode"
 	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/stringid"
 )
@@ -86,22 +85,3 @@ func ReplaceOrAppendEnvValues(defaults, overrides []string) []string {
 
 	return defaults
 }
-
-// GetErrorMessage returns the human readable message associated with
-// the passed-in error. In some cases the default Error() func returns
-// something that is less than useful so based on its types this func
-// will go and get a better piece of text.
-func GetErrorMessage(err error) string {
-	switch err.(type) {
-	case errcode.Error:
-		e, _ := err.(errcode.Error)
-		return e.Message
-
-	case errcode.ErrorCode:
-		ec, _ := err.(errcode.ErrorCode)
-		return ec.Message()
-
-	default:
-		return err.Error()
-	}
-}

+ 11 - 5
volume/local/local.go

@@ -4,14 +4,12 @@
 package local
 
 import (
-	"errors"
 	"fmt"
 	"io/ioutil"
 	"os"
 	"path/filepath"
 	"sync"
 
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/utils"
 	"github.com/docker/docker/volume"
@@ -27,13 +25,21 @@ const (
 
 var (
 	// ErrNotFound is the typed error returned when the requested volume name can't be found
-	ErrNotFound = errors.New("volume not found")
+	ErrNotFound = fmt.Errorf("volume not found")
 	// volumeNameRegex ensures the name assigned for the volume is valid.
 	// This name is used to create the bind directory, so we need to avoid characters that
 	// would make the path to escape the root directory.
 	volumeNameRegex = utils.RestrictedVolumeNamePattern
 )
 
+type validationError struct {
+	error
+}
+
+func (validationError) IsValidationError() bool {
+	return true
+}
+
 // New instantiates a new Root instance with the provided scope. Scope
 // is the base path that the Root instance uses to store its
 // volumes. The base path is created here if it does not exist.
@@ -142,7 +148,7 @@ func (r *Root) Remove(v volume.Volume) error {
 
 	lv, ok := v.(*localVolume)
 	if !ok {
-		return errors.New("unknown volume type")
+		return fmt.Errorf("unknown volume type")
 	}
 
 	realPath, err := filepath.EvalSymlinks(lv.path)
@@ -188,7 +194,7 @@ func (r *Root) Get(name string) (volume.Volume, error) {
 
 func (r *Root) validateName(name string) error {
 	if !volumeNameRegex.MatchString(name) {
-		return derr.ErrorCodeVolumeName.WithArgs(name, utils.RestrictedNameChars)
+		return validationError{fmt.Errorf("%q includes invalid characters for a local volume name, only %q are allowed", name, utils.RestrictedNameChars)}
 	}
 	return nil
 }

+ 13 - 5
volume/volume.go

@@ -1,12 +1,12 @@
 package volume
 
 import (
+	"fmt"
 	"os"
 	"runtime"
 	"strings"
 
 	"github.com/Sirupsen/logrus"
-	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/pkg/system"
 )
 
@@ -82,7 +82,7 @@ func (m *MountPoint) Setup() (string, error) {
 		}
 		return m.Source, nil
 	}
-	return "", derr.ErrorCodeMountSetup
+	return "", fmt.Errorf("Unable to setup mount point, neither source nor volume defined")
 }
 
 // Path returns the path of a volume in a mount point.
@@ -96,7 +96,7 @@ func (m *MountPoint) Path() string {
 // ParseVolumesFrom ensure that the supplied volumes-from is valid.
 func ParseVolumesFrom(spec string) (string, string, error) {
 	if len(spec) == 0 {
-		return "", "", derr.ErrorCodeVolumeFromBlank.WithArgs(spec)
+		return "", "", fmt.Errorf("malformed volumes-from specification: %s", spec)
 	}
 
 	specParts := strings.SplitN(spec, ":", 2)
@@ -106,15 +106,23 @@ func ParseVolumesFrom(spec string) (string, string, error) {
 	if len(specParts) == 2 {
 		mode = specParts[1]
 		if !ValidMountMode(mode) {
-			return "", "", derr.ErrorCodeVolumeInvalidMode.WithArgs(mode)
+			return "", "", errInvalidMode(mode)
 		}
 		// For now don't allow propagation properties while importing
 		// volumes from data container. These volumes will inherit
 		// the same propagation property as of the original volume
 		// in data container. This probably can be relaxed in future.
 		if HasPropagation(mode) {
-			return "", "", derr.ErrorCodeVolumeInvalidMode.WithArgs(mode)
+			return "", "", errInvalidMode(mode)
 		}
 	}
 	return id, mode, nil
 }
+
+func errInvalidMode(mode string) error {
+	return fmt.Errorf("invalid mode: %v", mode)
+}
+
+func errInvalidSpec(spec string) error {
+	return fmt.Errorf("Invalid volume specification: '%s'", spec)
+}

+ 2 - 2
volume/volume_propagation_linux_test.go

@@ -34,8 +34,8 @@ func TestParseMountSpecPropagation(t *testing.T) {
 		"/hostPath:/containerPath:ro,Z,rprivate",
 	}
 	invalid = map[string]string{
-		"/path:/path:ro,rshared,rslave":   `invalid mode: "ro,rshared,rslave"`,
-		"/path:/path:ro,z,rshared,rslave": `invalid mode: "ro,z,rshared,rslave"`,
+		"/path:/path:ro,rshared,rslave":   `invalid mode: ro,rshared,rslave`,
+		"/path:/path:ro,z,rshared,rslave": `invalid mode: ro,z,rshared,rslave`,
 		"/path:shared":                    "Invalid volume specification",
 		"/path:slave":                     "Invalid volume specification",
 		"/path:private":                   "Invalid volume specification",

+ 2 - 2
volume/volume_test.go

@@ -111,8 +111,8 @@ func TestParseMountSpec(t *testing.T) {
 			"/path:ro":        "Invalid volume specification",
 			"/rw:rw":          "Invalid volume specification",
 			"path:ro":         "Invalid volume specification",
-			"/path:/path:sw":  `invalid mode: "sw"`,
-			"/path:/path:rwz": `invalid mode: "rwz"`,
+			"/path:/path:sw":  `invalid mode: sw`,
+			"/path:/path:rwz": `invalid mode: rwz`,
 		}
 	}
 

+ 8 - 10
volume/volume_unix.go

@@ -6,8 +6,6 @@ import (
 	"fmt"
 	"path/filepath"
 	"strings"
-
-	derr "github.com/docker/docker/errors"
 )
 
 // read-write modes
@@ -47,12 +45,12 @@ func ParseMountSpec(spec, volumeDriver string) (*MountPoint, error) {
 		Propagation: DefaultPropagationMode,
 	}
 	if strings.Count(spec, ":") > 2 {
-		return nil, derr.ErrorCodeVolumeInvalid.WithArgs(spec)
+		return nil, errInvalidSpec(spec)
 	}
 
 	arr := strings.SplitN(spec, ":", 3)
 	if arr[0] == "" {
-		return nil, derr.ErrorCodeVolumeInvalid.WithArgs(spec)
+		return nil, errInvalidSpec(spec)
 	}
 
 	switch len(arr) {
@@ -63,7 +61,7 @@ func ParseMountSpec(spec, volumeDriver string) (*MountPoint, error) {
 		if isValid := ValidMountMode(arr[1]); isValid {
 			// Destination + Mode is not a valid volume - volumes
 			// cannot include a mode. eg /foo:rw
-			return nil, derr.ErrorCodeVolumeInvalid.WithArgs(spec)
+			return nil, errInvalidSpec(spec)
 		}
 		// Host Source Path or Name + Destination
 		mp.Source = arr[0]
@@ -74,23 +72,23 @@ func ParseMountSpec(spec, volumeDriver string) (*MountPoint, error) {
 		mp.Destination = arr[1]
 		mp.Mode = arr[2] // Mode field is used by SELinux to decide whether to apply label
 		if !ValidMountMode(mp.Mode) {
-			return nil, derr.ErrorCodeVolumeInvalidMode.WithArgs(mp.Mode)
+			return nil, errInvalidMode(mp.Mode)
 		}
 		mp.RW = ReadWrite(mp.Mode)
 		mp.Propagation = GetPropagation(mp.Mode)
 	default:
-		return nil, derr.ErrorCodeVolumeInvalid.WithArgs(spec)
+		return nil, errInvalidSpec(spec)
 	}
 
 	//validate the volumes destination path
 	mp.Destination = filepath.Clean(mp.Destination)
 	if !filepath.IsAbs(mp.Destination) {
-		return nil, derr.ErrorCodeVolumeAbs.WithArgs(mp.Destination)
+		return nil, fmt.Errorf("Invalid volume destination path: '%s' mount path must be absolute.", mp.Destination)
 	}
 
 	// Destination cannot be "/"
 	if mp.Destination == "/" {
-		return nil, derr.ErrorCodeVolumeSlash.WithArgs(spec)
+		return nil, fmt.Errorf("Invalid specification: destination can't be '/' in '%s'", spec)
 	}
 
 	name, source := ParseVolumeSource(mp.Source)
@@ -106,7 +104,7 @@ func ParseMountSpec(spec, volumeDriver string) (*MountPoint, error) {
 		// cleanup becomes an issue if container does not unmount
 		// submounts explicitly.
 		if HasPropagation(mp.Mode) {
-			return nil, derr.ErrorCodeVolumeInvalid.WithArgs(spec)
+			return nil, errInvalidSpec(spec)
 		}
 	} else {
 		mp.Source = filepath.Clean(source)

+ 8 - 8
volume/volume_windows.go

@@ -1,13 +1,13 @@
 package volume
 
 import (
+	"fmt"
 	"os"
 	"path/filepath"
 	"regexp"
 	"strings"
 
 	"github.com/Sirupsen/logrus"
-	derr "github.com/docker/docker/errors"
 )
 
 // read-write modes
@@ -96,7 +96,7 @@ func ParseMountSpec(spec string, volumeDriver string) (*MountPoint, error) {
 
 	// Must have something back
 	if len(match) == 0 {
-		return nil, derr.ErrorCodeVolumeInvalid.WithArgs(spec)
+		return nil, errInvalidSpec(spec)
 	}
 
 	// Pull out the sub expressions from the named capture groups
@@ -116,7 +116,7 @@ func ParseMountSpec(spec string, volumeDriver string) (*MountPoint, error) {
 
 	// Volumes cannot include an explicitly supplied mode eg c:\path:rw
 	if mp.Source == "" && mp.Destination != "" && matchgroups["mode"] != "" {
-		return nil, derr.ErrorCodeVolumeInvalid.WithArgs(spec)
+		return nil, errInvalidSpec(spec)
 	}
 
 	// Note: No need to check if destination is absolute as it must be by
@@ -125,14 +125,14 @@ func ParseMountSpec(spec string, volumeDriver string) (*MountPoint, error) {
 	if filepath.VolumeName(mp.Destination) == mp.Destination {
 		// Ensure the destination path, if a drive letter, is not the c drive
 		if strings.ToLower(mp.Destination) == "c:" {
-			return nil, derr.ErrorCodeVolumeDestIsC.WithArgs(spec)
+			return nil, fmt.Errorf("Destination drive letter in '%s' cannot be c:", spec)
 		}
 	} else {
 		// So we know the destination is a path, not drive letter. Clean it up.
 		mp.Destination = filepath.Clean(mp.Destination)
 		// Ensure the destination path, if a path, is not the c root directory
 		if strings.ToLower(mp.Destination) == `c:\` {
-			return nil, derr.ErrorCodeVolumeDestIsCRoot.WithArgs(spec)
+			return nil, fmt.Errorf(`Destination path in '%s' cannot be c:\`, spec)
 		}
 	}
 
@@ -163,10 +163,10 @@ func ParseMountSpec(spec string, volumeDriver string) (*MountPoint, error) {
 		var fi os.FileInfo
 		var err error
 		if fi, err = os.Stat(mp.Source); err != nil {
-			return nil, derr.ErrorCodeVolumeSourceNotFound.WithArgs(mp.Source, err)
+			return nil, fmt.Errorf("Source directory '%s' could not be found: %s", mp.Source, err)
 		}
 		if !fi.IsDir() {
-			return nil, derr.ErrorCodeVolumeSourceNotDirectory.WithArgs(mp.Source)
+			return nil, fmt.Errorf("Source '%s' is not a directory", mp.Source)
 		}
 	}
 
@@ -182,7 +182,7 @@ func IsVolumeNameValid(name string) (bool, error) {
 	}
 	nameExp = regexp.MustCompile(`^` + RXReservedNames + `$`)
 	if nameExp.MatchString(name) {
-		return false, derr.ErrorCodeVolumeNameReservedWord.WithArgs(name)
+		return false, fmt.Errorf("Volume name %q cannot be a reserved word for Windows filenames", name)
 	}
 	return true, nil
 }