Browse code

Merge pull request #20699 from calavera/remove_static_error_declarations

Remove static errors from errors package.

David Calavera authored on 2016/02/27 09:30:12
Showing 67 changed files
... ...
@@ -11,7 +11,6 @@ import (
11 11
 
12 12
 	"github.com/Sirupsen/logrus"
13 13
 	Cli "github.com/docker/docker/cli"
14
-	derr "github.com/docker/docker/errors"
15 14
 	"github.com/docker/docker/opts"
16 15
 	"github.com/docker/docker/pkg/promise"
17 16
 	"github.com/docker/docker/pkg/signal"
... ...
@@ -21,6 +20,11 @@ import (
21 21
 	"github.com/docker/libnetwork/resolvconf/dns"
22 22
 )
23 23
 
24
+const (
25
+	errCmdNotFound          = "Container command not found or does not exist."
26
+	errCmdCouldNotBeInvoked = "Container command could not be invoked."
27
+)
28
+
24 29
 func (cid *cidFile) Close() error {
25 30
 	cid.file.Close()
26 31
 
... ...
@@ -46,20 +50,13 @@ func (cid *cidFile) Write(id string) error {
46 46
 // return 125 for generic docker daemon failures
47 47
 func runStartContainerErr(err error) error {
48 48
 	trimmedErr := strings.Trim(err.Error(), "Error response from daemon: ")
49
-	statusError := Cli.StatusError{}
50
-	derrCmdNotFound := derr.ErrorCodeCmdNotFound.Message()
51
-	derrCouldNotInvoke := derr.ErrorCodeCmdCouldNotBeInvoked.Message()
52
-	derrNoSuchImage := derr.ErrorCodeNoSuchImageHash.Message()
53
-	derrNoSuchImageTag := derr.ErrorCodeNoSuchImageTag.Message()
49
+	statusError := Cli.StatusError{StatusCode: 125}
50
+
54 51
 	switch trimmedErr {
55
-	case derrCmdNotFound:
52
+	case errCmdNotFound:
56 53
 		statusError = Cli.StatusError{StatusCode: 127}
57
-	case derrCouldNotInvoke:
54
+	case errCmdCouldNotBeInvoked:
58 55
 		statusError = Cli.StatusError{StatusCode: 126}
59
-	case derrNoSuchImage, derrNoSuchImageTag:
60
-		statusError = Cli.StatusError{StatusCode: 125}
61
-	default:
62
-		statusError = Cli.StatusError{StatusCode: 125}
63 56
 	}
64 57
 	return statusError
65 58
 }
66 59
new file mode 100644
... ...
@@ -0,0 +1,69 @@
0
+package httputils
1
+
2
+import (
3
+	"net/http"
4
+	"strings"
5
+
6
+	"github.com/Sirupsen/logrus"
7
+)
8
+
9
+// httpStatusError is an interface
10
+// that errors with custom status codes
11
+// implement to tell the api layer
12
+// which response status to set.
13
+type httpStatusError interface {
14
+	HTTPErrorStatusCode() int
15
+}
16
+
17
+// inputValidationError is an interface
18
+// that errors generated by invalid
19
+// inputs can implement to tell the
20
+// api layer to set a 400 status code
21
+// in the response.
22
+type inputValidationError interface {
23
+	IsValidationError() bool
24
+}
25
+
26
+// WriteError decodes a specific docker error and sends it in the response.
27
+func WriteError(w http.ResponseWriter, err error) {
28
+	if err == nil || w == nil {
29
+		logrus.WithFields(logrus.Fields{"error": err, "writer": w}).Error("unexpected HTTP error handling")
30
+		return
31
+	}
32
+
33
+	var statusCode int
34
+	errMsg := err.Error()
35
+
36
+	switch e := err.(type) {
37
+	case httpStatusError:
38
+		statusCode = e.HTTPErrorStatusCode()
39
+	case inputValidationError:
40
+		statusCode = http.StatusBadRequest
41
+	default:
42
+		// FIXME: this is brittle and should not be necessary, but we still need to identify if
43
+		// there are errors falling back into this logic.
44
+		// If we need to differentiate between different possible error types,
45
+		// we should create appropriate error types that implement the httpStatusError interface.
46
+		errStr := strings.ToLower(errMsg)
47
+		for keyword, status := range map[string]int{
48
+			"not found":             http.StatusNotFound,
49
+			"no such":               http.StatusNotFound,
50
+			"bad parameter":         http.StatusBadRequest,
51
+			"conflict":              http.StatusConflict,
52
+			"impossible":            http.StatusNotAcceptable,
53
+			"wrong login/password":  http.StatusUnauthorized,
54
+			"hasn't been activated": http.StatusForbidden,
55
+		} {
56
+			if strings.Contains(errStr, keyword) {
57
+				statusCode = status
58
+				break
59
+			}
60
+		}
61
+	}
62
+
63
+	if statusCode == 0 {
64
+		statusCode = http.StatusInternalServerError
65
+	}
66
+
67
+	http.Error(w, errMsg, statusCode)
68
+}
... ...
@@ -9,8 +9,6 @@ import (
9 9
 
10 10
 	"golang.org/x/net/context"
11 11
 
12
-	"github.com/Sirupsen/logrus"
13
-	"github.com/docker/distribution/registry/api/errcode"
14 12
 	"github.com/docker/docker/api"
15 13
 	"github.com/docker/docker/pkg/version"
16 14
 )
... ...
@@ -85,78 +83,6 @@ func ParseMultipartForm(r *http.Request) error {
85 85
 	return nil
86 86
 }
87 87
 
88
-// WriteError decodes a specific docker error and sends it in the response.
89
-func WriteError(w http.ResponseWriter, err error) {
90
-	if err == nil || w == nil {
91
-		logrus.WithFields(logrus.Fields{"error": err, "writer": w}).Error("unexpected HTTP error handling")
92
-		return
93
-	}
94
-
95
-	statusCode := http.StatusInternalServerError
96
-	errMsg := err.Error()
97
-
98
-	// Based on the type of error we get we need to process things
99
-	// slightly differently to extract the error message.
100
-	// In the 'errcode.*' cases there are two different type of
101
-	// error that could be returned. errocode.ErrorCode is the base
102
-	// type of error object - it is just an 'int' that can then be
103
-	// used as the look-up key to find the message. errorcode.Error
104
-	// extends errorcode.Error by adding error-instance specific
105
-	// data, like 'details' or variable strings to be inserted into
106
-	// the message.
107
-	//
108
-	// Ideally, we should just be able to call err.Error() for all
109
-	// cases but the errcode package doesn't support that yet.
110
-	//
111
-	// Additionally, in both errcode cases, there might be an http
112
-	// status code associated with it, and if so use it.
113
-	switch err.(type) {
114
-	case errcode.ErrorCode:
115
-		daError, _ := err.(errcode.ErrorCode)
116
-		statusCode = daError.Descriptor().HTTPStatusCode
117
-		errMsg = daError.Message()
118
-
119
-	case errcode.Error:
120
-		// For reference, if you're looking for a particular error
121
-		// then you can do something like :
122
-		//   import ( derr "github.com/docker/docker/errors" )
123
-		//   if daError.ErrorCode() == derr.ErrorCodeNoSuchContainer { ... }
124
-
125
-		daError, _ := err.(errcode.Error)
126
-		statusCode = daError.ErrorCode().Descriptor().HTTPStatusCode
127
-		errMsg = daError.Message
128
-
129
-	default:
130
-		// This part of will be removed once we've
131
-		// converted everything over to use the errcode package
132
-
133
-		// FIXME: this is brittle and should not be necessary.
134
-		// If we need to differentiate between different possible error types,
135
-		// we should create appropriate error types with clearly defined meaning
136
-		errStr := strings.ToLower(err.Error())
137
-		for keyword, status := range map[string]int{
138
-			"not found":             http.StatusNotFound,
139
-			"no such":               http.StatusNotFound,
140
-			"bad parameter":         http.StatusBadRequest,
141
-			"conflict":              http.StatusConflict,
142
-			"impossible":            http.StatusNotAcceptable,
143
-			"wrong login/password":  http.StatusUnauthorized,
144
-			"hasn't been activated": http.StatusForbidden,
145
-		} {
146
-			if strings.Contains(errStr, keyword) {
147
-				statusCode = status
148
-				break
149
-			}
150
-		}
151
-	}
152
-
153
-	if statusCode == 0 {
154
-		statusCode = http.StatusInternalServerError
155
-	}
156
-
157
-	http.Error(w, errMsg, statusCode)
158
-}
159
-
160 88
 // WriteJSON writes the value v to the http response stream as json with standard json encoding.
161 89
 func WriteJSON(w http.ResponseWriter, code int, v interface{}) error {
162 90
 	w.Header().Set("Content-Type", "application/json")
... ...
@@ -6,11 +6,18 @@ import (
6 6
 	"runtime"
7 7
 
8 8
 	"github.com/docker/docker/api/server/httputils"
9
-	"github.com/docker/docker/errors"
10 9
 	"github.com/docker/docker/pkg/version"
11 10
 	"golang.org/x/net/context"
12 11
 )
13 12
 
13
+type badRequestError struct {
14
+	error
15
+}
16
+
17
+func (badRequestError) HTTPErrorStatusCode() int {
18
+	return http.StatusBadRequest
19
+}
20
+
14 21
 // NewVersionMiddleware creates a new Version middleware.
15 22
 func NewVersionMiddleware(versionCheck string, defaultVersion, minVersion version.Version) Middleware {
16 23
 	serverVersion := version.Version(versionCheck)
... ...
@@ -23,10 +30,10 @@ func NewVersionMiddleware(versionCheck string, defaultVersion, minVersion versio
23 23
 			}
24 24
 
25 25
 			if apiVersion.GreaterThan(defaultVersion) {
26
-				return errors.ErrorCodeNewerClientVersion.WithArgs(apiVersion, defaultVersion)
26
+				return badRequestError{fmt.Errorf("client is newer than server (client API version: %s, server API version: %s)", apiVersion, defaultVersion)}
27 27
 			}
28 28
 			if apiVersion.LessThan(minVersion) {
29
-				return errors.ErrorCodeOldClientVersion.WithArgs(apiVersion, minVersion)
29
+				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)}
30 30
 			}
31 31
 
32 32
 			header := fmt.Sprintf("Docker/%s (%s)", serverVersion, runtime.GOOS)
... ...
@@ -53,12 +53,12 @@ func TestVersionMiddlewareWithErrors(t *testing.T) {
53 53
 	err := h(ctx, resp, req, vars)
54 54
 
55 55
 	if !strings.Contains(err.Error(), "client version 0.1 is too old. Minimum supported API version is 1.2.0") {
56
-		t.Fatalf("Expected ErrorCodeOldClientVersion, got %v", err)
56
+		t.Fatalf("Expected too old client error, got %v", err)
57 57
 	}
58 58
 
59 59
 	vars["version"] = "100000"
60 60
 	err = h(ctx, resp, req, vars)
61 61
 	if !strings.Contains(err.Error(), "client is newer than server") {
62
-		t.Fatalf("Expected ErrorCodeNewerClientVersion, got %v", err)
62
+		t.Fatalf("Expected client newer than server error, got %v", err)
63 63
 	}
64 64
 }
... ...
@@ -4,7 +4,6 @@ import (
4 4
 	"bytes"
5 5
 	"encoding/base64"
6 6
 	"encoding/json"
7
-	"errors"
8 7
 	"fmt"
9 8
 	"io"
10 9
 	"net/http"
... ...
@@ -17,7 +16,6 @@ import (
17 17
 	"github.com/docker/docker/pkg/ioutils"
18 18
 	"github.com/docker/docker/pkg/progress"
19 19
 	"github.com/docker/docker/pkg/streamformatter"
20
-	"github.com/docker/docker/utils"
21 20
 	"github.com/docker/engine-api/types"
22 21
 	"github.com/docker/engine-api/types/container"
23 22
 	"github.com/docker/go-units"
... ...
@@ -117,7 +115,7 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
117 117
 		if !output.Flushed() {
118 118
 			return err
119 119
 		}
120
-		_, err = w.Write(sf.FormatError(errors.New(utils.GetErrorMessage(err))))
120
+		_, err = w.Write(sf.FormatError(err))
121 121
 		if err != nil {
122 122
 			logrus.Warnf("could not write error response: %v", err)
123 123
 		}
... ...
@@ -11,15 +11,12 @@ import (
11 11
 	"time"
12 12
 
13 13
 	"github.com/Sirupsen/logrus"
14
-	"github.com/docker/distribution/registry/api/errcode"
15 14
 	"github.com/docker/docker/api/server/httputils"
16 15
 	"github.com/docker/docker/api/types/backend"
17
-	derr "github.com/docker/docker/errors"
18 16
 	"github.com/docker/docker/pkg/ioutils"
19 17
 	"github.com/docker/docker/pkg/signal"
20 18
 	"github.com/docker/docker/pkg/term"
21 19
 	"github.com/docker/docker/runconfig"
22
-	"github.com/docker/docker/utils"
23 20
 	"github.com/docker/engine-api/types"
24 21
 	"github.com/docker/engine-api/types/container"
25 22
 	"github.com/docker/engine-api/types/filters"
... ...
@@ -126,7 +123,7 @@ func (s *containerRouter) getContainersLogs(ctx context.Context, w http.Response
126 126
 			// The client may be expecting all of the data we're sending to
127 127
 			// be multiplexed, so send it through OutStream, which will
128 128
 			// have been set up to handle that if needed.
129
-			fmt.Fprintf(logsConfig.OutStream, "Error running logs job: %s\n", utils.GetErrorMessage(err))
129
+			fmt.Fprintf(logsConfig.OutStream, "Error running logs job: %v\n", err)
130 130
 		default:
131 131
 			return err
132 132
 		}
... ...
@@ -182,6 +179,10 @@ func (s *containerRouter) postContainersStop(ctx context.Context, w http.Respons
182 182
 	return nil
183 183
 }
184 184
 
185
+type errContainerIsRunning interface {
186
+	ContainerIsRunning() bool
187
+}
188
+
185 189
 func (s *containerRouter) postContainersKill(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
186 190
 	if err := httputils.ParseForm(r); err != nil {
187 191
 		return err
... ...
@@ -199,15 +200,17 @@ func (s *containerRouter) postContainersKill(ctx context.Context, w http.Respons
199 199
 	}
200 200
 
201 201
 	if err := s.backend.ContainerKill(name, uint64(sig)); err != nil {
202
-		theErr, isDerr := err.(errcode.ErrorCoder)
203
-		isStopped := isDerr && theErr.ErrorCode() == derr.ErrorCodeNotRunning
202
+		var isStopped bool
203
+		if e, ok := err.(errContainerIsRunning); ok {
204
+			isStopped = !e.ContainerIsRunning()
205
+		}
204 206
 
205 207
 		// Return error that's not caused because the container is stopped.
206 208
 		// Return error if the container is not running and the api is >= 1.20
207 209
 		// to keep backwards compatibility.
208 210
 		version := httputils.VersionFromContext(ctx)
209 211
 		if version.GreaterThanOrEqualTo("1.20") || !isStopped {
210
-			return fmt.Errorf("Cannot kill container %s: %v", name, utils.GetErrorMessage(err))
212
+			return fmt.Errorf("Cannot kill container %s: %v", name, err)
211 213
 		}
212 214
 	}
213 215
 
... ...
@@ -430,7 +433,7 @@ func (s *containerRouter) postContainersAttach(ctx context.Context, w http.Respo
430 430
 
431 431
 	hijacker, ok := w.(http.Hijacker)
432 432
 	if !ok {
433
-		return derr.ErrorCodeNoHijackConnection.WithArgs(containerName)
433
+		return fmt.Errorf("error attaching to container %s, hijack connection missing", containerName)
434 434
 	}
435 435
 
436 436
 	setupStreams := func() (io.ReadCloser, io.Writer, io.Writer, error) {
... ...
@@ -10,7 +10,6 @@ import (
10 10
 	"github.com/Sirupsen/logrus"
11 11
 	"github.com/docker/docker/api/server/httputils"
12 12
 	"github.com/docker/docker/pkg/stdcopy"
13
-	"github.com/docker/docker/utils"
14 13
 	"github.com/docker/engine-api/types"
15 14
 	"golang.org/x/net/context"
16 15
 )
... ...
@@ -46,7 +45,7 @@ func (s *containerRouter) postContainerExecCreate(ctx context.Context, w http.Re
46 46
 	// Register an instance of Exec in container.
47 47
 	id, err := s.backend.ContainerExecCreate(execConfig)
48 48
 	if err != nil {
49
-		logrus.Errorf("Error setting up exec command in container %s: %s", name, utils.GetErrorMessage(err))
49
+		logrus.Errorf("Error setting up exec command in container %s: %v", name, err)
50 50
 		return err
51 51
 	}
52 52
 
... ...
@@ -113,7 +112,7 @@ func (s *containerRouter) postContainerExecStart(ctx context.Context, w http.Res
113 113
 		if execStartCheck.Detach {
114 114
 			return err
115 115
 		}
116
-		logrus.Errorf("Error running exec in container: %v\n", utils.GetErrorMessage(err))
116
+		logrus.Errorf("Error running exec in container: %v\n", err)
117 117
 	}
118 118
 	return nil
119 119
 }
... ...
@@ -20,7 +20,6 @@ type Backend interface {
20 20
 
21 21
 type containerBackend interface {
22 22
 	Commit(name string, config *types.ContainerCommitConfig) (imageID string, err error)
23
-	Exists(containerName string) bool
24 23
 }
25 24
 
26 25
 type imageBackend interface {
... ...
@@ -14,7 +14,6 @@ import (
14 14
 	"github.com/docker/distribution/registry/api/errcode"
15 15
 	"github.com/docker/docker/api/server/httputils"
16 16
 	"github.com/docker/docker/builder/dockerfile"
17
-	derr "github.com/docker/docker/errors"
18 17
 	"github.com/docker/docker/pkg/ioutils"
19 18
 	"github.com/docker/docker/pkg/streamformatter"
20 19
 	"github.com/docker/docker/reference"
... ...
@@ -49,10 +48,6 @@ func (s *imageRouter) postCommit(ctx context.Context, w http.ResponseWriter, r *
49 49
 		c = &container.Config{}
50 50
 	}
51 51
 
52
-	if !s.backend.Exists(cname) {
53
-		return derr.ErrorCodeNoSuchContainer.WithArgs(cname)
54
-	}
55
-
56 52
 	newConfig, err := dockerfile.BuildFromConfig(c, r.Form["changes"])
57 53
 	if err != nil {
58 54
 		return err
... ...
@@ -8,8 +8,6 @@ import (
8 8
 // Backend is all the methods that need to be implemented
9 9
 // to provide network specific functionality.
10 10
 type Backend interface {
11
-	NetworkControllerEnabled() bool
12
-
13 11
 	FindNetwork(idName string) (libnetwork.Network, error)
14 12
 	GetNetworkByName(idName string) (libnetwork.Network, error)
15 13
 	GetNetworksByID(partialID string) []libnetwork.Network
... ...
@@ -1,13 +1,6 @@
1 1
 package network
2 2
 
3
-import (
4
-	"net/http"
5
-
6
-	"github.com/docker/docker/api/server/httputils"
7
-	"github.com/docker/docker/api/server/router"
8
-	"github.com/docker/docker/errors"
9
-	"golang.org/x/net/context"
10
-)
3
+import "github.com/docker/docker/api/server/router"
11 4
 
12 5
 // networkRouter is a router to talk with the network controller
13 6
 type networkRouter struct {
... ...
@@ -32,24 +25,13 @@ func (r *networkRouter) Routes() []router.Route {
32 32
 func (r *networkRouter) initRoutes() {
33 33
 	r.routes = []router.Route{
34 34
 		// GET
35
-		router.NewGetRoute("/networks", r.controllerEnabledMiddleware(r.getNetworksList)),
36
-		router.NewGetRoute("/networks/{id:.*}", r.controllerEnabledMiddleware(r.getNetwork)),
35
+		router.NewGetRoute("/networks", r.getNetworksList),
36
+		router.NewGetRoute("/networks/{id:.*}", r.getNetwork),
37 37
 		// POST
38
-		router.NewPostRoute("/networks/create", r.controllerEnabledMiddleware(r.postNetworkCreate)),
39
-		router.NewPostRoute("/networks/{id:.*}/connect", r.controllerEnabledMiddleware(r.postNetworkConnect)),
40
-		router.NewPostRoute("/networks/{id:.*}/disconnect", r.controllerEnabledMiddleware(r.postNetworkDisconnect)),
38
+		router.NewPostRoute("/networks/create", r.postNetworkCreate),
39
+		router.NewPostRoute("/networks/{id:.*}/connect", r.postNetworkConnect),
40
+		router.NewPostRoute("/networks/{id:.*}/disconnect", r.postNetworkDisconnect),
41 41
 		// DELETE
42
-		router.NewDeleteRoute("/networks/{id:.*}", r.controllerEnabledMiddleware(r.deleteNetwork)),
43
-	}
44
-}
45
-
46
-func (r *networkRouter) controllerEnabledMiddleware(handler httputils.APIFunc) httputils.APIFunc {
47
-	if r.backend.NetworkControllerEnabled() {
48
-		return handler
42
+		router.NewDeleteRoute("/networks/{id:.*}", r.deleteNetwork),
49 43
 	}
50
-	return networkControllerDisabled
51
-}
52
-
53
-func networkControllerDisabled(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
54
-	return errors.ErrorNetworkControllerNotEnabled.WithArgs()
55 44
 }
... ...
@@ -10,7 +10,6 @@ import (
10 10
 	"github.com/docker/docker/api/server/httputils"
11 11
 	"github.com/docker/docker/api/server/router"
12 12
 	"github.com/docker/docker/pkg/authorization"
13
-	"github.com/docker/docker/utils"
14 13
 	"github.com/gorilla/mux"
15 14
 	"golang.org/x/net/context"
16 15
 )
... ...
@@ -134,7 +133,7 @@ func (s *Server) makeHTTPHandler(handler httputils.APIFunc) http.HandlerFunc {
134 134
 		}
135 135
 
136 136
 		if err := handlerFunc(ctx, w, r, vars); err != nil {
137
-			logrus.Errorf("Handler for %s %s returned error: %s", r.Method, r.URL.Path, utils.GetErrorMessage(err))
137
+			logrus.Errorf("Handler for %s %s returned error: %v", r.Method, r.URL.Path, err)
138 138
 			httputils.WriteError(w, err)
139 139
 		}
140 140
 	}
... ...
@@ -19,7 +19,6 @@ import (
19 19
 	"github.com/Sirupsen/logrus"
20 20
 	"github.com/docker/docker/api"
21 21
 	"github.com/docker/docker/builder"
22
-	derr "github.com/docker/docker/errors"
23 22
 	"github.com/docker/docker/pkg/signal"
24 23
 	"github.com/docker/docker/pkg/system"
25 24
 	runconfigopts "github.com/docker/docker/runconfig/opts"
... ...
@@ -40,12 +39,12 @@ func nullDispatch(b *Builder, args []string, attributes map[string]bool, origina
40 40
 //
41 41
 func env(b *Builder, args []string, attributes map[string]bool, original string) error {
42 42
 	if len(args) == 0 {
43
-		return derr.ErrorCodeAtLeastOneArg.WithArgs("ENV")
43
+		return errAtLeastOneArgument("ENV")
44 44
 	}
45 45
 
46 46
 	if len(args)%2 != 0 {
47 47
 		// should never get here, but just in case
48
-		return derr.ErrorCodeTooManyArgs.WithArgs("ENV")
48
+		return errTooManyArguments("ENV")
49 49
 	}
50 50
 
51 51
 	if err := b.flags.Parse(); err != nil {
... ...
@@ -99,7 +98,7 @@ func env(b *Builder, args []string, attributes map[string]bool, original string)
99 99
 // Sets the maintainer metadata.
100 100
 func maintainer(b *Builder, args []string, attributes map[string]bool, original string) error {
101 101
 	if len(args) != 1 {
102
-		return derr.ErrorCodeExactlyOneArg.WithArgs("MAINTAINER")
102
+		return errExactlyOneArgument("MAINTAINER")
103 103
 	}
104 104
 
105 105
 	if err := b.flags.Parse(); err != nil {
... ...
@@ -116,11 +115,11 @@ func maintainer(b *Builder, args []string, attributes map[string]bool, original
116 116
 //
117 117
 func label(b *Builder, args []string, attributes map[string]bool, original string) error {
118 118
 	if len(args) == 0 {
119
-		return derr.ErrorCodeAtLeastOneArg.WithArgs("LABEL")
119
+		return errAtLeastOneArgument("LABEL")
120 120
 	}
121 121
 	if len(args)%2 != 0 {
122 122
 		// should never get here, but just in case
123
-		return derr.ErrorCodeTooManyArgs.WithArgs("LABEL")
123
+		return errTooManyArguments("LABEL")
124 124
 	}
125 125
 
126 126
 	if err := b.flags.Parse(); err != nil {
... ...
@@ -152,7 +151,7 @@ func label(b *Builder, args []string, attributes map[string]bool, original strin
152 152
 //
153 153
 func add(b *Builder, args []string, attributes map[string]bool, original string) error {
154 154
 	if len(args) < 2 {
155
-		return derr.ErrorCodeAtLeastTwoArgs.WithArgs("ADD")
155
+		return errAtLeastOneArgument("ADD")
156 156
 	}
157 157
 
158 158
 	if err := b.flags.Parse(); err != nil {
... ...
@@ -168,7 +167,7 @@ func add(b *Builder, args []string, attributes map[string]bool, original string)
168 168
 //
169 169
 func dispatchCopy(b *Builder, args []string, attributes map[string]bool, original string) error {
170 170
 	if len(args) < 2 {
171
-		return derr.ErrorCodeAtLeastTwoArgs.WithArgs("COPY")
171
+		return errAtLeastOneArgument("COPY")
172 172
 	}
173 173
 
174 174
 	if err := b.flags.Parse(); err != nil {
... ...
@@ -184,7 +183,7 @@ func dispatchCopy(b *Builder, args []string, attributes map[string]bool, origina
184 184
 //
185 185
 func from(b *Builder, args []string, attributes map[string]bool, original string) error {
186 186
 	if len(args) != 1 {
187
-		return derr.ErrorCodeExactlyOneArg.WithArgs("FROM")
187
+		return errExactlyOneArgument("FROM")
188 188
 	}
189 189
 
190 190
 	if err := b.flags.Parse(); err != nil {
... ...
@@ -233,7 +232,7 @@ func from(b *Builder, args []string, attributes map[string]bool, original string
233 233
 //
234 234
 func onbuild(b *Builder, args []string, attributes map[string]bool, original string) error {
235 235
 	if len(args) == 0 {
236
-		return derr.ErrorCodeAtLeastOneArg.WithArgs("ONBUILD")
236
+		return errAtLeastOneArgument("ONBUILD")
237 237
 	}
238 238
 
239 239
 	if err := b.flags.Parse(); err != nil {
... ...
@@ -243,9 +242,9 @@ func onbuild(b *Builder, args []string, attributes map[string]bool, original str
243 243
 	triggerInstruction := strings.ToUpper(strings.TrimSpace(args[0]))
244 244
 	switch triggerInstruction {
245 245
 	case "ONBUILD":
246
-		return derr.ErrorCodeChainOnBuild
246
+		return fmt.Errorf("Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed")
247 247
 	case "MAINTAINER", "FROM":
248
-		return derr.ErrorCodeBadOnBuildCmd.WithArgs(triggerInstruction)
248
+		return fmt.Errorf("%s isn't allowed as an ONBUILD trigger", triggerInstruction)
249 249
 	}
250 250
 
251 251
 	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
260 260
 //
261 261
 func workdir(b *Builder, args []string, attributes map[string]bool, original string) error {
262 262
 	if len(args) != 1 {
263
-		return derr.ErrorCodeExactlyOneArg.WithArgs("WORKDIR")
263
+		return errExactlyOneArgument("WORKDIR")
264 264
 	}
265 265
 
266 266
 	if err := b.flags.Parse(); err != nil {
... ...
@@ -293,7 +292,7 @@ func workdir(b *Builder, args []string, attributes map[string]bool, original str
293 293
 //
294 294
 func run(b *Builder, args []string, attributes map[string]bool, original string) error {
295 295
 	if b.image == "" && !b.noBaseImage {
296
-		return derr.ErrorCodeMissingFrom
296
+		return fmt.Errorf("Please provide a source image with `from` prior to run")
297 297
 	}
298 298
 
299 299
 	if err := b.flags.Parse(); err != nil {
... ...
@@ -491,7 +490,7 @@ func expose(b *Builder, args []string, attributes map[string]bool, original stri
491 491
 	portsTab := args
492 492
 
493 493
 	if len(args) == 0 {
494
-		return derr.ErrorCodeAtLeastOneArg.WithArgs("EXPOSE")
494
+		return errAtLeastOneArgument("EXPOSE")
495 495
 	}
496 496
 
497 497
 	if err := b.flags.Parse(); err != nil {
... ...
@@ -530,7 +529,7 @@ func expose(b *Builder, args []string, attributes map[string]bool, original stri
530 530
 //
531 531
 func user(b *Builder, args []string, attributes map[string]bool, original string) error {
532 532
 	if len(args) != 1 {
533
-		return derr.ErrorCodeExactlyOneArg.WithArgs("USER")
533
+		return errExactlyOneArgument("USER")
534 534
 	}
535 535
 
536 536
 	if err := b.flags.Parse(); err != nil {
... ...
@@ -547,7 +546,7 @@ func user(b *Builder, args []string, attributes map[string]bool, original string
547 547
 //
548 548
 func volume(b *Builder, args []string, attributes map[string]bool, original string) error {
549 549
 	if len(args) == 0 {
550
-		return derr.ErrorCodeAtLeastOneArg.WithArgs("VOLUME")
550
+		return errAtLeastOneArgument("VOLUME")
551 551
 	}
552 552
 
553 553
 	if err := b.flags.Parse(); err != nil {
... ...
@@ -560,7 +559,7 @@ func volume(b *Builder, args []string, attributes map[string]bool, original stri
560 560
 	for _, v := range args {
561 561
 		v = strings.TrimSpace(v)
562 562
 		if v == "" {
563
-			return derr.ErrorCodeVolumeEmpty
563
+			return fmt.Errorf("Volume specified can not be an empty string")
564 564
 		}
565 565
 		b.runConfig.Volumes[v] = struct{}{}
566 566
 	}
... ...
@@ -631,3 +630,15 @@ func arg(b *Builder, args []string, attributes map[string]bool, original string)
631 631
 
632 632
 	return b.commit("", b.runConfig.Cmd, fmt.Sprintf("ARG %s", arg))
633 633
 }
634
+
635
+func errAtLeastOneArgument(command string) error {
636
+	return fmt.Errorf("%s requires at least one argument", command)
637
+}
638
+
639
+func errExactlyOneArgument(command string) error {
640
+	return fmt.Errorf("%s requires exactly one argument", command)
641
+}
642
+
643
+func errTooManyArguments(command string) error {
644
+	return fmt.Errorf("Bad input to %s, too many arguments", command)
645
+}
... ...
@@ -16,7 +16,6 @@ import (
16 16
 	"github.com/docker/docker/daemon/logger"
17 17
 	"github.com/docker/docker/daemon/logger/jsonfilelog"
18 18
 	"github.com/docker/docker/daemon/network"
19
-	derr "github.com/docker/docker/errors"
20 19
 	"github.com/docker/docker/image"
21 20
 	"github.com/docker/docker/layer"
22 21
 	"github.com/docker/docker/pkg/promise"
... ...
@@ -199,7 +198,7 @@ func (container *Container) SetupWorkingDirectory() error {
199 199
 	if err := system.MkdirAll(pth, 0755); err != nil {
200 200
 		pthInfo, err2 := os.Stat(pth)
201 201
 		if err2 == nil && pthInfo != nil && !pthInfo.IsDir() {
202
-			return derr.ErrorCodeNotADir.WithArgs(container.Config.WorkingDir)
202
+			return fmt.Errorf("Cannot mkdir: %s is not a directory", container.Config.WorkingDir)
203 203
 		}
204 204
 
205 205
 		return err
... ...
@@ -277,13 +276,6 @@ func (container *Container) ConfigPath() (string, error) {
277 277
 	return container.GetRootResourcePath(configFileName)
278 278
 }
279 279
 
280
-func validateID(id string) error {
281
-	if id == "" {
282
-		return derr.ErrorCodeEmptyID
283
-	}
284
-	return nil
285
-}
286
-
287 280
 // Returns true if the container exposes a certain port
288 281
 func (container *Container) exposes(p nat.Port) bool {
289 282
 	_, exists := container.Config.ExposedPorts[p]
... ...
@@ -307,7 +299,7 @@ func (container *Container) GetLogConfig(defaultConfig containertypes.LogConfig)
307 307
 func (container *Container) StartLogger(cfg containertypes.LogConfig) (logger.Logger, error) {
308 308
 	c, err := logger.GetLogDriver(cfg.Type)
309 309
 	if err != nil {
310
-		return nil, derr.ErrorCodeLoggingFactory.WithArgs(err)
310
+		return nil, fmt.Errorf("Failed to get logging factory: %v", err)
311 311
 	}
312 312
 	ctx := logger.Context{
313 313
 		Config:              cfg.Config,
... ...
@@ -14,7 +14,6 @@ import (
14 14
 
15 15
 	"github.com/Sirupsen/logrus"
16 16
 	"github.com/docker/docker/daemon/execdriver"
17
-	derr "github.com/docker/docker/errors"
18 17
 	"github.com/docker/docker/pkg/chrootarchive"
19 18
 	"github.com/docker/docker/pkg/symlink"
20 19
 	"github.com/docker/docker/pkg/system"
... ...
@@ -34,6 +33,11 @@ import (
34 34
 // DefaultSHMSize is the default size (64MB) of the SHM which will be mounted in the container
35 35
 const DefaultSHMSize int64 = 67108864
36 36
 
37
+var (
38
+	errInvalidEndpoint = fmt.Errorf("invalid endpoint while building port map info")
39
+	errInvalidNetwork  = fmt.Errorf("invalid network settings while building port map info")
40
+)
41
+
37 42
 // Container holds the fields specific to unixen implementations.
38 43
 // See CommonContainer for standard fields common to all containers.
39 44
 type Container struct {
... ...
@@ -116,12 +120,12 @@ func (container *Container) GetEndpointInNetwork(n libnetwork.Network) (libnetwo
116 116
 
117 117
 func (container *Container) buildPortMapInfo(ep libnetwork.Endpoint) error {
118 118
 	if ep == nil {
119
-		return derr.ErrorCodeEmptyEndpoint
119
+		return errInvalidEndpoint
120 120
 	}
121 121
 
122 122
 	networkSettings := container.NetworkSettings
123 123
 	if networkSettings == nil {
124
-		return derr.ErrorCodeEmptyNetwork
124
+		return errInvalidNetwork
125 125
 	}
126 126
 
127 127
 	if len(networkSettings.Ports) == 0 {
... ...
@@ -151,7 +155,7 @@ func getEndpointPortMapInfo(ep libnetwork.Endpoint) (nat.PortMap, error) {
151 151
 			for _, tp := range exposedPorts {
152 152
 				natPort, err := nat.NewPort(tp.Proto.String(), strconv.Itoa(int(tp.Port)))
153 153
 				if err != nil {
154
-					return pm, derr.ErrorCodeParsingPort.WithArgs(tp.Port, err)
154
+					return pm, fmt.Errorf("Error parsing Port value(%v):%v", tp.Port, err)
155 155
 				}
156 156
 				pm[natPort] = nil
157 157
 			}
... ...
@@ -195,12 +199,12 @@ func getSandboxPortMapInfo(sb libnetwork.Sandbox) nat.PortMap {
195 195
 // BuildEndpointInfo sets endpoint-related fields on container.NetworkSettings based on the provided network and endpoint.
196 196
 func (container *Container) BuildEndpointInfo(n libnetwork.Network, ep libnetwork.Endpoint) error {
197 197
 	if ep == nil {
198
-		return derr.ErrorCodeEmptyEndpoint
198
+		return errInvalidEndpoint
199 199
 	}
200 200
 
201 201
 	networkSettings := container.NetworkSettings
202 202
 	if networkSettings == nil {
203
-		return derr.ErrorCodeEmptyNetwork
203
+		return errInvalidNetwork
204 204
 	}
205 205
 
206 206
 	epInfo := ep.Info()
... ...
@@ -377,7 +381,7 @@ func (container *Container) BuildCreateEndpointOptions(n libnetwork.Network, epC
377 377
 				portStart, portEnd, err = newP.Range()
378 378
 			}
379 379
 			if err != nil {
380
-				return nil, derr.ErrorCodeHostPort.WithArgs(binding[i].HostPort, err)
380
+				return nil, fmt.Errorf("Error parsing HostPort value(%s):%v", binding[i].HostPort, err)
381 381
 			}
382 382
 			pbCopy.HostPort = uint16(portStart)
383 383
 			pbCopy.HostPortEnd = uint16(portEnd)
... ...
@@ -1,6 +1,7 @@
1 1
 package container
2 2
 
3 3
 import (
4
+	"fmt"
4 5
 	"io"
5 6
 	"os/exec"
6 7
 	"strings"
... ...
@@ -10,10 +11,8 @@ import (
10 10
 
11 11
 	"github.com/Sirupsen/logrus"
12 12
 	"github.com/docker/docker/daemon/execdriver"
13
-	derr "github.com/docker/docker/errors"
14 13
 	"github.com/docker/docker/pkg/promise"
15 14
 	"github.com/docker/docker/pkg/stringid"
16
-	"github.com/docker/docker/utils"
17 15
 	"github.com/docker/engine-api/types/container"
18 16
 )
19 17
 
... ...
@@ -190,7 +189,7 @@ func (m *containerMonitor) start() error {
190 190
 				if m.container.RestartCount == 0 {
191 191
 					m.container.ExitCode = 127
192 192
 					m.resetContainer(false)
193
-					return derr.ErrorCodeCmdNotFound
193
+					return fmt.Errorf("Container command not found or does not exist.")
194 194
 				}
195 195
 			}
196 196
 			// set to 126 for container cmd can't be invoked errors
... ...
@@ -198,7 +197,7 @@ func (m *containerMonitor) start() error {
198 198
 				if m.container.RestartCount == 0 {
199 199
 					m.container.ExitCode = 126
200 200
 					m.resetContainer(false)
201
-					return derr.ErrorCodeCmdCouldNotBeInvoked
201
+					return fmt.Errorf("Container command could not be invoked.")
202 202
 				}
203 203
 			}
204 204
 
... ...
@@ -206,7 +205,7 @@ func (m *containerMonitor) start() error {
206 206
 				m.container.ExitCode = -1
207 207
 				m.resetContainer(false)
208 208
 
209
-				return derr.ErrorCodeCantStart.WithArgs(m.container.ID, utils.GetErrorMessage(err))
209
+				return fmt.Errorf("Cannot start container %s: %v", m.container.ID, err)
210 210
 			}
211 211
 
212 212
 			logrus.Errorf("Error running container: %s", err)
... ...
@@ -6,7 +6,6 @@ import (
6 6
 	"time"
7 7
 
8 8
 	"github.com/docker/docker/daemon/execdriver"
9
-	derr "github.com/docker/docker/errors"
10 9
 	"github.com/docker/go-units"
11 10
 )
12 11
 
... ...
@@ -113,7 +112,7 @@ func wait(waitChan <-chan struct{}, timeout time.Duration) error {
113 113
 	}
114 114
 	select {
115 115
 	case <-time.After(timeout):
116
-		return derr.ErrorCodeTimedOut.WithArgs(timeout)
116
+		return fmt.Errorf("Timed out: %v", timeout)
117 117
 	case <-waitChan:
118 118
 		return nil
119 119
 	}
... ...
@@ -256,14 +255,15 @@ func (s *State) IsRestarting() bool {
256 256
 }
257 257
 
258 258
 // SetRemovalInProgress sets the container state as being removed.
259
-func (s *State) SetRemovalInProgress() error {
259
+// It returns true if the container was already in that state.
260
+func (s *State) SetRemovalInProgress() bool {
260 261
 	s.Lock()
261 262
 	defer s.Unlock()
262 263
 	if s.RemovalInProgress {
263
-		return derr.ErrorCodeAlreadyRemoving
264
+		return true
264 265
 	}
265 266
 	s.RemovalInProgress = true
266
-	return nil
267
+	return false
267 268
 }
268 269
 
269 270
 // ResetRemovalInProgress make the RemovalInProgress state to false.
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"github.com/docker/docker/api/types/backend"
10 10
 	"github.com/docker/docker/container"
11 11
 	"github.com/docker/docker/daemon/logger"
12
-	derr "github.com/docker/docker/errors"
12
+	"github.com/docker/docker/errors"
13 13
 	"github.com/docker/docker/pkg/stdcopy"
14 14
 )
15 15
 
... ...
@@ -17,10 +17,11 @@ import (
17 17
 func (daemon *Daemon) ContainerAttach(prefixOrName string, c *backend.ContainerAttachConfig) error {
18 18
 	container, err := daemon.GetContainer(prefixOrName)
19 19
 	if err != nil {
20
-		return derr.ErrorCodeNoSuchContainer.WithArgs(prefixOrName)
20
+		return err
21 21
 	}
22 22
 	if container.IsPaused() {
23
-		return derr.ErrorCodePausedContainer.WithArgs(prefixOrName)
23
+		err := fmt.Errorf("Container %s is paused. Unpause the container before attach", prefixOrName)
24
+		return errors.NewRequestConflictError(err)
24 25
 	}
25 26
 
26 27
 	inStream, outStream, errStream, err := c.GetStreams()
... ...
@@ -17,7 +17,7 @@ import (
17 17
 	"github.com/docker/docker/daemon/execdriver"
18 18
 	"github.com/docker/docker/daemon/links"
19 19
 	"github.com/docker/docker/daemon/network"
20
-	derr "github.com/docker/docker/errors"
20
+	"github.com/docker/docker/errors"
21 21
 	"github.com/docker/docker/pkg/fileutils"
22 22
 	"github.com/docker/docker/pkg/idtools"
23 23
 	"github.com/docker/docker/pkg/mount"
... ...
@@ -45,7 +45,7 @@ func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]s
45 45
 
46 46
 	for linkAlias, child := range children {
47 47
 		if !child.IsRunning() {
48
-			return nil, derr.ErrorCodeLinkNotRunning.WithArgs(child.Name, linkAlias)
48
+			return nil, fmt.Errorf("Cannot link to a non running container: %s AS %s", child.Name, linkAlias)
49 49
 		}
50 50
 
51 51
 		childBridgeSettings := child.NetworkSettings.Networks["bridge"]
... ...
@@ -509,7 +509,7 @@ func (daemon *Daemon) updateNetwork(container *container.Container) error {
509 509
 
510 510
 	sb, err := ctrl.SandboxByID(sid)
511 511
 	if err != nil {
512
-		return derr.ErrorCodeNoSandbox.WithArgs(sid, err)
512
+		return fmt.Errorf("error locating sandbox id %s: %v", sid, err)
513 513
 	}
514 514
 
515 515
 	// Find if container is connected to the default bridge network
... ...
@@ -532,11 +532,11 @@ func (daemon *Daemon) updateNetwork(container *container.Container) error {
532 532
 
533 533
 	options, err := daemon.buildSandboxOptions(container, n)
534 534
 	if err != nil {
535
-		return derr.ErrorCodeNetworkUpdate.WithArgs(err)
535
+		return fmt.Errorf("Update network failed: %v", err)
536 536
 	}
537 537
 
538 538
 	if err := sb.Refresh(options...); err != nil {
539
-		return derr.ErrorCodeNetworkRefresh.WithArgs(sid, err)
539
+		return fmt.Errorf("Update network failed: Failure in refresh sandbox %s: %v", sid, err)
540 540
 	}
541 541
 
542 542
 	return nil
... ...
@@ -730,7 +730,7 @@ func (daemon *Daemon) updateNetworkConfig(container *container.Container, idOrNa
730 730
 func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings) error {
731 731
 	if !container.Running {
732 732
 		if container.RemovalInProgress || container.Dead {
733
-			return derr.ErrorCodeRemovalContainer.WithArgs(container.ID)
733
+			return errRemovalContainer(container.ID)
734 734
 		}
735 735
 		if _, err := daemon.updateNetworkConfig(container, idOrName, endpointConfig, true); err != nil {
736 736
 			return err
... ...
@@ -810,7 +810,7 @@ func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName
810 810
 	}
811 811
 
812 812
 	if err := container.UpdateJoinInfo(n, ep); err != nil {
813
-		return derr.ErrorCodeJoinInfo.WithArgs(err)
813
+		return fmt.Errorf("Updating join info failed: %v", err)
814 814
 	}
815 815
 
816 816
 	daemon.LogNetworkEventWithAttributes(n, "connect", map[string]string{"container": container.ID})
... ...
@@ -833,7 +833,7 @@ func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, n li
833 833
 	}
834 834
 	if !container.Running {
835 835
 		if container.RemovalInProgress || container.Dead {
836
-			return derr.ErrorCodeRemovalContainer.WithArgs(container.ID)
836
+			return errRemovalContainer(container.ID)
837 837
 		}
838 838
 		if _, ok := container.NetworkSettings.Networks[n.Name()]; ok {
839 839
 			delete(container.NetworkSettings.Networks, n.Name())
... ...
@@ -950,7 +950,7 @@ func (daemon *Daemon) setNetworkNamespaceKey(containerID string, pid int) error
950 950
 	search := libnetwork.SandboxContainerWalker(&sandbox, containerID)
951 951
 	daemon.netController.WalkSandboxes(search)
952 952
 	if sandbox == nil {
953
-		return derr.ErrorCodeNoSandbox.WithArgs(containerID, "no sandbox found")
953
+		return fmt.Errorf("error locating sandbox id %s: no sandbox found", containerID)
954 954
 	}
955 955
 
956 956
 	return sandbox.SetKey(path)
... ...
@@ -963,10 +963,10 @@ func (daemon *Daemon) getIpcContainer(container *container.Container) (*containe
963 963
 		return nil, err
964 964
 	}
965 965
 	if !c.IsRunning() {
966
-		return nil, derr.ErrorCodeIPCRunning.WithArgs(containerID)
966
+		return nil, fmt.Errorf("cannot join IPC of a non running container: %s", containerID)
967 967
 	}
968 968
 	if c.IsRestarting() {
969
-		return nil, derr.ErrorCodeContainerRestarting.WithArgs(containerID)
969
+		return nil, errContainerIsRestarting(container.ID)
970 970
 	}
971 971
 	return c, nil
972 972
 }
... ...
@@ -977,13 +977,14 @@ func (daemon *Daemon) getNetworkedContainer(containerID, connectedContainerID st
977 977
 		return nil, err
978 978
 	}
979 979
 	if containerID == nc.ID {
980
-		return nil, derr.ErrorCodeJoinSelf
980
+		return nil, fmt.Errorf("cannot join own network")
981 981
 	}
982 982
 	if !nc.IsRunning() {
983
-		return nil, derr.ErrorCodeJoinRunning.WithArgs(connectedContainerID)
983
+		err := fmt.Errorf("cannot join network of a non running container: %s", connectedContainerID)
984
+		return nil, errors.NewRequestConflictError(err)
984 985
 	}
985 986
 	if nc.IsRestarting() {
986
-		return nil, derr.ErrorCodeContainerRestarting.WithArgs(connectedContainerID)
987
+		return nil, errContainerIsRestarting(connectedContainerID)
987 988
 	}
988 989
 	return nc, nil
989 990
 }
... ...
@@ -1141,7 +1142,7 @@ func getDevicesFromPath(deviceMapping containertypes.DeviceMapping) (devs []*con
1141 1141
 		return devs, nil
1142 1142
 	}
1143 1143
 
1144
-	return devs, derr.ErrorCodeDeviceInfo.WithArgs(deviceMapping.PathOnHost, err)
1144
+	return devs, fmt.Errorf("error gathering device information while adding custom device %q: %s", deviceMapping.PathOnHost, err)
1145 1145
 }
1146 1146
 
1147 1147
 func mergeDevices(defaultDevices, userDevices []*configs.Device) []*configs.Device {
... ...
@@ -1172,3 +1173,7 @@ func isLinkable(child *container.Container) bool {
1172 1172
 	_, ok := child.NetworkSettings.Networks["bridge"]
1173 1173
 	return ok
1174 1174
 }
1175
+
1176
+func errRemovalContainer(containerID string) error {
1177
+	return fmt.Errorf("Container %s is marked for removal and cannot be connected or disconnected to the network", containerID)
1178
+}
... ...
@@ -3,12 +3,12 @@
3 3
 package daemon
4 4
 
5 5
 import (
6
+	"fmt"
6 7
 	"strings"
7 8
 
8 9
 	"github.com/docker/docker/container"
9 10
 	"github.com/docker/docker/daemon/execdriver"
10 11
 	"github.com/docker/docker/daemon/execdriver/windows"
11
-	derr "github.com/docker/docker/errors"
12 12
 	"github.com/docker/docker/layer"
13 13
 	networktypes "github.com/docker/engine-api/types/network"
14 14
 	"github.com/docker/libnetwork"
... ...
@@ -64,7 +64,7 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro
64 64
 			}
65 65
 		}
66 66
 	default:
67
-		return derr.ErrorCodeInvalidNetworkMode.WithArgs(c.HostConfig.NetworkMode)
67
+		return fmt.Errorf("invalid network mode: %s", c.HostConfig.NetworkMode)
68 68
 	}
69 69
 
70 70
 	// TODO Windows. More resource controls to be implemented later.
... ...
@@ -88,7 +88,7 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro
88 88
 	var layerPaths []string
89 89
 	img, err := daemon.imageStore.Get(c.ImageID)
90 90
 	if err != nil {
91
-		return derr.ErrorCodeGetGraph.WithArgs(c.ImageID, err)
91
+		return fmt.Errorf("Failed to graph.Get on ImageID %s - %s", c.ImageID, err)
92 92
 	}
93 93
 
94 94
 	if img.RootFS != nil && img.RootFS.Type == "layers+base" {
... ...
@@ -97,7 +97,7 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro
97 97
 			img.RootFS.DiffIDs = img.RootFS.DiffIDs[:i]
98 98
 			path, err := layer.GetLayerPath(daemon.layerStore, img.RootFS.ChainID())
99 99
 			if err != nil {
100
-				return derr.ErrorCodeGetLayer.WithArgs(err)
100
+				return fmt.Errorf("Failed to get layer path from graphdriver %s for ImageID %s - %s", daemon.layerStore, img.RootFS.ChainID(), err)
101 101
 			}
102 102
 			// Reverse order, expecting parent most first
103 103
 			layerPaths = append([]string{path}, layerPaths...)
... ...
@@ -106,7 +106,7 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro
106 106
 
107 107
 	m, err := c.RWLayer.Metadata()
108 108
 	if err != nil {
109
-		return derr.ErrorCodeGetLayerMetadata.WithArgs(err)
109
+		return fmt.Errorf("Failed to get layer metadata - %s", err)
110 110
 	}
111 111
 	layerFolder := m["dir"]
112 112
 
... ...
@@ -1,9 +1,10 @@
1 1
 package daemon
2 2
 
3 3
 import (
4
+	"fmt"
5
+
4 6
 	"github.com/Sirupsen/logrus"
5 7
 	"github.com/docker/docker/container"
6
-	derr "github.com/docker/docker/errors"
7 8
 	"github.com/docker/docker/image"
8 9
 	"github.com/docker/docker/layer"
9 10
 	"github.com/docker/docker/pkg/idtools"
... ...
@@ -18,7 +19,7 @@ import (
18 18
 // ContainerCreate creates a container.
19 19
 func (daemon *Daemon) ContainerCreate(params types.ContainerCreateConfig) (types.ContainerCreateResponse, error) {
20 20
 	if params.Config == nil {
21
-		return types.ContainerCreateResponse{}, derr.ErrorCodeEmptyConfig
21
+		return types.ContainerCreateResponse{}, fmt.Errorf("Config cannot be empty in order to create a container")
22 22
 	}
23 23
 
24 24
 	warnings, err := daemon.verifyContainerSettings(params.HostConfig, params.Config, false)
... ...
@@ -174,7 +175,7 @@ func (daemon *Daemon) VolumeCreate(name, driverName string, opts map[string]stri
174 174
 	v, err := daemon.volumes.Create(name, driverName, opts)
175 175
 	if err != nil {
176 176
 		if volumestore.IsNameConflict(err) {
177
-			return nil, derr.ErrorVolumeNameTaken.WithArgs(name)
177
+			return nil, fmt.Errorf("A volume named %s already exists. Choose a different volume name.", name)
178 178
 		}
179 179
 		return nil, err
180 180
 	}
... ...
@@ -3,12 +3,12 @@
3 3
 package daemon
4 4
 
5 5
 import (
6
+	"fmt"
6 7
 	"os"
7 8
 	"path/filepath"
8 9
 
9 10
 	"github.com/Sirupsen/logrus"
10 11
 	"github.com/docker/docker/container"
11
-	derr "github.com/docker/docker/errors"
12 12
 	"github.com/docker/docker/pkg/stringid"
13 13
 	containertypes "github.com/docker/engine-api/types/container"
14 14
 	"github.com/opencontainers/runc/libcontainer/label"
... ...
@@ -41,7 +41,7 @@ func (daemon *Daemon) createContainerPlatformSpecificSettings(container *contain
41 41
 
42 42
 		stat, err := os.Stat(path)
43 43
 		if err == nil && !stat.IsDir() {
44
-			return derr.ErrorCodeMountOverFile.WithArgs(path)
44
+			return fmt.Errorf("cannot mount volume over existing file, file exists %s", path)
45 45
 		}
46 46
 
47 47
 		v, err := daemon.volumes.CreateWithRef(name, hostConfig.VolumeDriver, container.ID, nil)
... ...
@@ -6,7 +6,6 @@
6 6
 package daemon
7 7
 
8 8
 import (
9
-	"errors"
10 9
 	"fmt"
11 10
 	"io"
12 11
 	"io/ioutil"
... ...
@@ -15,6 +14,7 @@ import (
15 15
 	"path"
16 16
 	"path/filepath"
17 17
 	"runtime"
18
+	"strings"
18 19
 	"sync"
19 20
 	"syscall"
20 21
 	"time"
... ...
@@ -28,6 +28,7 @@ import (
28 28
 	"github.com/docker/docker/daemon/exec"
29 29
 	"github.com/docker/docker/daemon/execdriver"
30 30
 	"github.com/docker/docker/daemon/execdriver/execdrivers"
31
+	"github.com/docker/docker/errors"
31 32
 	"github.com/docker/engine-api/types"
32 33
 	containertypes "github.com/docker/engine-api/types/container"
33 34
 	eventtypes "github.com/docker/engine-api/types/events"
... ...
@@ -43,7 +44,6 @@ import (
43 43
 	dmetadata "github.com/docker/docker/distribution/metadata"
44 44
 	"github.com/docker/docker/distribution/xfer"
45 45
 	"github.com/docker/docker/dockerversion"
46
-	derr "github.com/docker/docker/errors"
47 46
 	"github.com/docker/docker/image"
48 47
 	"github.com/docker/docker/image/tarexport"
49 48
 	"github.com/docker/docker/layer"
... ...
@@ -90,7 +90,7 @@ var (
90 90
 	validContainerNameChars   = utils.RestrictedNameChars
91 91
 	validContainerNamePattern = utils.RestrictedNamePattern
92 92
 
93
-	errSystemNotSupported = errors.New("The Docker daemon is not supported on this platform.")
93
+	errSystemNotSupported = fmt.Errorf("The Docker daemon is not supported on this platform.")
94 94
 )
95 95
 
96 96
 // 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
157 157
 	if indexError != nil {
158 158
 		// When truncindex defines an error type, use that instead
159 159
 		if indexError == truncindex.ErrNotExist {
160
-			return nil, derr.ErrorCodeNoSuchContainer.WithArgs(prefixOrName)
160
+			err := fmt.Errorf("No such container: %s", prefixOrName)
161
+			return nil, errors.NewRequestNotFoundError(err)
161 162
 		}
162 163
 		return nil, indexError
163 164
 	}
... ...
@@ -1211,7 +1212,7 @@ func (daemon *Daemon) ImageHistory(name string) ([]*types.ImageHistory, error) {
1211 1211
 
1212 1212
 		if !h.EmptyLayer {
1213 1213
 			if len(img.RootFS.DiffIDs) <= layerCounter {
1214
-				return nil, errors.New("too many non-empty layers in History section")
1214
+				return nil, fmt.Errorf("too many non-empty layers in History section")
1215 1215
 			}
1216 1216
 
1217 1217
 			rootFS.Append(img.RootFS.DiffIDs[layerCounter])
... ...
@@ -1499,7 +1500,8 @@ func (daemon *Daemon) verifyNetworkingConfig(nwConfig *networktypes.NetworkingCo
1499 1499
 	for k := range nwConfig.EndpointsConfig {
1500 1500
 		l = append(l, k)
1501 1501
 	}
1502
-	return derr.ErrorCodeMultipleNetworkConnect.WithArgs(fmt.Sprintf("%v", l))
1502
+	err := fmt.Errorf("Container cannot be connected to network endpoints: %s", strings.Join(l, ", "))
1503
+	return errors.NewBadRequestError(err)
1503 1504
 }
1504 1505
 
1505 1506
 func configureVolumes(config *Config, rootUID, rootGID int) (*store.VolumeStore, error) {
... ...
@@ -1671,7 +1673,7 @@ func convertLnNetworkStats(name string, stats *lntypes.InterfaceStatistics) *lib
1671 1671
 
1672 1672
 func validateID(id string) error {
1673 1673
 	if id == "" {
1674
-		return derr.ErrorCodeEmptyID
1674
+		return fmt.Errorf("Invalid empty id")
1675 1675
 	}
1676 1676
 	return nil
1677 1677
 }
... ...
@@ -16,7 +16,6 @@ import (
16 16
 
17 17
 	"github.com/Sirupsen/logrus"
18 18
 	"github.com/docker/docker/container"
19
-	derr "github.com/docker/docker/errors"
20 19
 	"github.com/docker/docker/image"
21 20
 	"github.com/docker/docker/layer"
22 21
 	"github.com/docker/docker/pkg/idtools"
... ...
@@ -312,17 +311,17 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi
312 312
 	}
313 313
 	cpusAvailable, err := sysInfo.IsCpusetCpusAvailable(resources.CpusetCpus)
314 314
 	if err != nil {
315
-		return warnings, derr.ErrorCodeInvalidCpusetCpus.WithArgs(resources.CpusetCpus)
315
+		return warnings, fmt.Errorf("Invalid value %s for cpuset cpus.", resources.CpusetCpus)
316 316
 	}
317 317
 	if !cpusAvailable {
318
-		return warnings, derr.ErrorCodeNotAvailableCpusetCpus.WithArgs(resources.CpusetCpus, sysInfo.Cpus)
318
+		return warnings, fmt.Errorf("Requested CPUs are not available - requested %s, available: %s.", resources.CpusetCpus, sysInfo.Cpus)
319 319
 	}
320 320
 	memsAvailable, err := sysInfo.IsCpusetMemsAvailable(resources.CpusetMems)
321 321
 	if err != nil {
322
-		return warnings, derr.ErrorCodeInvalidCpusetMems.WithArgs(resources.CpusetMems)
322
+		return warnings, fmt.Errorf("Invalid value %s for cpuset mems.", resources.CpusetMems)
323 323
 	}
324 324
 	if !memsAvailable {
325
-		return warnings, derr.ErrorCodeNotAvailableCpusetMems.WithArgs(resources.CpusetMems, sysInfo.Mems)
325
+		return warnings, fmt.Errorf("Requested memory nodes are not available - requested %s, available: %s.", resources.CpusetMems, sysInfo.Mems)
326 326
 	}
327 327
 
328 328
 	// blkio subsystem checks and adjustments
... ...
@@ -8,7 +8,7 @@ import (
8 8
 
9 9
 	"github.com/Sirupsen/logrus"
10 10
 	"github.com/docker/docker/container"
11
-	derr "github.com/docker/docker/errors"
11
+	"github.com/docker/docker/errors"
12 12
 	"github.com/docker/docker/layer"
13 13
 	volumestore "github.com/docker/docker/volume/store"
14 14
 	"github.com/docker/engine-api/types"
... ...
@@ -25,12 +25,8 @@ func (daemon *Daemon) ContainerRm(name string, config *types.ContainerRmConfig)
25 25
 	}
26 26
 
27 27
 	// Container state RemovalInProgress should be used to avoid races.
28
-	if err = container.SetRemovalInProgress(); err != nil {
29
-		if err == derr.ErrorCodeAlreadyRemoving {
30
-			// do not fail when the removal is in progress started by other request.
31
-			return nil
32
-		}
33
-		return derr.ErrorCodeRmState.WithArgs(container.ID, err)
28
+	if inProgress := container.SetRemovalInProgress(); inProgress {
29
+		return nil
34 30
 	}
35 31
 	defer container.ResetRemovalInProgress()
36 32
 
... ...
@@ -84,10 +80,11 @@ func (daemon *Daemon) rmLink(container *container.Container, name string) error
84 84
 func (daemon *Daemon) cleanupContainer(container *container.Container, forceRemove bool) (err error) {
85 85
 	if container.IsRunning() {
86 86
 		if !forceRemove {
87
-			return derr.ErrorCodeRmRunning.WithArgs(container.ID)
87
+			err := fmt.Errorf("You cannot remove a running container %s. Stop the container before attempting removal or use -f", container.ID)
88
+			return errors.NewRequestConflictError(err)
88 89
 		}
89 90
 		if err := daemon.Kill(container); err != nil {
90
-			return derr.ErrorCodeRmFailed.WithArgs(container.ID, err)
91
+			return fmt.Errorf("Could not kill running container %s, cannot remove - %v", container.ID, err)
91 92
 		}
92 93
 	}
93 94
 
... ...
@@ -123,17 +120,17 @@ func (daemon *Daemon) cleanupContainer(container *container.Container, forceRemo
123 123
 	}()
124 124
 
125 125
 	if err = os.RemoveAll(container.Root); err != nil {
126
-		return derr.ErrorCodeRmFS.WithArgs(container.ID, err)
126
+		return fmt.Errorf("Unable to remove filesystem for %v: %v", container.ID, err)
127 127
 	}
128 128
 
129 129
 	metadata, err := daemon.layerStore.ReleaseRWLayer(container.RWLayer)
130 130
 	layer.LogReleaseMetadata(metadata)
131 131
 	if err != nil && err != layer.ErrMountDoesNotExist {
132
-		return derr.ErrorCodeRmDriverFS.WithArgs(daemon.GraphDriverName(), container.ID, err)
132
+		return fmt.Errorf("Driver %s failed to remove root filesystem %s: %s", daemon.GraphDriverName(), container.ID, err)
133 133
 	}
134 134
 
135 135
 	if err = daemon.execDriver.Clean(container.ID); err != nil {
136
-		return derr.ErrorCodeRmExecDriver.WithArgs(container.ID, err)
136
+		return fmt.Errorf("Unable to remove execdriver data for %s: %s", container.ID, err)
137 137
 	}
138 138
 	return nil
139 139
 }
... ...
@@ -149,9 +146,10 @@ func (daemon *Daemon) VolumeRm(name string) error {
149 149
 
150 150
 	if err := daemon.volumes.Remove(v); err != nil {
151 151
 		if volumestore.IsInUse(err) {
152
-			return derr.ErrorCodeRmVolumeInUse.WithArgs(err)
152
+			err := fmt.Errorf("Unable to remove volume, volume still in use: %v", err)
153
+			return errors.NewRequestConflictError(err)
153 154
 		}
154
-		return derr.ErrorCodeRmVolume.WithArgs(name, err)
155
+		return fmt.Errorf("Error while removing volume %s: %v", name, err)
155 156
 	}
156 157
 	daemon.LogVolumeEvent(v.Name(), "destroy", map[string]string{"driver": v.DriverName()})
157 158
 	return nil
... ...
@@ -32,9 +32,7 @@ func TestContainerDoubleDelete(t *testing.T) {
32 32
 	daemon.containers.Add(container.ID, container)
33 33
 
34 34
 	// Mark the container as having a delete in progress
35
-	if err := container.SetRemovalInProgress(); err != nil {
36
-		t.Fatal(err)
37
-	}
35
+	container.SetRemovalInProgress()
38 36
 
39 37
 	// Try to remove the container when it's start is removalInProgress.
40 38
 	// It should ignore the container and not return an error.
... ...
@@ -1,26 +1,57 @@
1 1
 package daemon
2 2
 
3 3
 import (
4
+	"fmt"
4 5
 	"strings"
5 6
 
6
-	derr "github.com/docker/docker/errors"
7
+	"github.com/docker/docker/errors"
7 8
 	"github.com/docker/docker/reference"
8 9
 )
9 10
 
10 11
 func (d *Daemon) imageNotExistToErrcode(err error) error {
11 12
 	if dne, isDNE := err.(ErrImageDoesNotExist); isDNE {
12 13
 		if strings.Contains(dne.RefOrID, "@") {
13
-			return derr.ErrorCodeNoSuchImageHash.WithArgs(dne.RefOrID)
14
+			e := fmt.Errorf("No such image: %s", dne.RefOrID)
15
+			return errors.NewRequestNotFoundError(e)
14 16
 		}
15 17
 		tag := reference.DefaultTag
16 18
 		ref, err := reference.ParseNamed(dne.RefOrID)
17 19
 		if err != nil {
18
-			return derr.ErrorCodeNoSuchImageTag.WithArgs(dne.RefOrID, tag)
20
+			e := fmt.Errorf("No such image: %s:%s", dne.RefOrID, tag)
21
+			return errors.NewRequestNotFoundError(e)
19 22
 		}
20 23
 		if tagged, isTagged := ref.(reference.NamedTagged); isTagged {
21 24
 			tag = tagged.Tag()
22 25
 		}
23
-		return derr.ErrorCodeNoSuchImageTag.WithArgs(ref.Name(), tag)
26
+		e := fmt.Errorf("No such image: %s:%s", ref.Name(), tag)
27
+		return errors.NewRequestNotFoundError(e)
24 28
 	}
25 29
 	return err
26 30
 }
31
+
32
+type errNotRunning struct {
33
+	containerID string
34
+}
35
+
36
+func (e errNotRunning) Error() string {
37
+	return fmt.Sprintf("Container %s is not running", e.containerID)
38
+}
39
+
40
+func (e errNotRunning) ContainerIsRunning() bool {
41
+	return false
42
+}
43
+
44
+func errContainerIsRestarting(containerID string) error {
45
+	err := fmt.Errorf("Container %s is restarting, wait until the container is running", containerID)
46
+	return errors.NewRequestConflictError(err)
47
+}
48
+
49
+func errExecNotFound(id string) error {
50
+	err := fmt.Errorf("No such exec instance '%s' found in daemon", id)
51
+	return errors.NewRequestNotFoundError(err)
52
+}
53
+
54
+func errExecPaused(id string) error {
55
+	err := fmt.Errorf("Container %s is paused, unpause the container before exec", id)
56
+	return errors.NewRequestConflictError(err)
57
+}
... ...
@@ -1,6 +1,7 @@
1 1
 package daemon
2 2
 
3 3
 import (
4
+	"fmt"
4 5
 	"io"
5 6
 	"strings"
6 7
 	"time"
... ...
@@ -9,7 +10,7 @@ import (
9 9
 	"github.com/docker/docker/container"
10 10
 	"github.com/docker/docker/daemon/exec"
11 11
 	"github.com/docker/docker/daemon/execdriver"
12
-	derr "github.com/docker/docker/errors"
12
+	"github.com/docker/docker/errors"
13 13
 	"github.com/docker/docker/pkg/pools"
14 14
 	"github.com/docker/docker/pkg/promise"
15 15
 	"github.com/docker/docker/pkg/term"
... ...
@@ -47,19 +48,19 @@ func (d *Daemon) getExecConfig(name string) (*exec.Config, error) {
47 47
 	if ec != nil {
48 48
 		if container := d.containers.Get(ec.ContainerID); container != nil {
49 49
 			if !container.IsRunning() {
50
-				return nil, derr.ErrorCodeContainerNotRunning.WithArgs(container.ID, container.State.String())
50
+				return nil, fmt.Errorf("Container %s is not running: %s", container.ID, container.State.String())
51 51
 			}
52 52
 			if container.IsPaused() {
53
-				return nil, derr.ErrorCodeExecPaused.WithArgs(container.ID)
53
+				return nil, errExecPaused(container.ID)
54 54
 			}
55 55
 			if container.IsRestarting() {
56
-				return nil, derr.ErrorCodeContainerRestarting.WithArgs(container.ID)
56
+				return nil, errContainerIsRestarting(container.ID)
57 57
 			}
58 58
 			return ec, nil
59 59
 		}
60 60
 	}
61 61
 
62
-	return nil, derr.ErrorCodeNoExecID.WithArgs(name)
62
+	return nil, errExecNotFound(name)
63 63
 }
64 64
 
65 65
 func (d *Daemon) unregisterExecCommand(container *container.Container, execConfig *exec.Config) {
... ...
@@ -74,13 +75,13 @@ func (d *Daemon) getActiveContainer(name string) (*container.Container, error) {
74 74
 	}
75 75
 
76 76
 	if !container.IsRunning() {
77
-		return nil, derr.ErrorCodeNotRunning.WithArgs(name)
77
+		return nil, errNotRunning{container.ID}
78 78
 	}
79 79
 	if container.IsPaused() {
80
-		return nil, derr.ErrorCodeExecPaused.WithArgs(name)
80
+		return nil, errExecPaused(name)
81 81
 	}
82 82
 	if container.IsRestarting() {
83
-		return nil, derr.ErrorCodeContainerRestarting.WithArgs(name)
83
+		return nil, errContainerIsRestarting(container.ID)
84 84
 	}
85 85
 	return container, nil
86 86
 }
... ...
@@ -137,18 +138,19 @@ func (d *Daemon) ContainerExecStart(name string, stdin io.ReadCloser, stdout io.
137 137
 
138 138
 	ec, err := d.getExecConfig(name)
139 139
 	if err != nil {
140
-		return derr.ErrorCodeNoExecID.WithArgs(name)
140
+		return errExecNotFound(name)
141 141
 	}
142 142
 
143 143
 	ec.Lock()
144 144
 	if ec.ExitCode != nil {
145 145
 		ec.Unlock()
146
-		return derr.ErrorCodeExecExited.WithArgs(ec.ID)
146
+		err := fmt.Errorf("Error: Exec command %s has already run", ec.ID)
147
+		return errors.NewRequestConflictError(err)
147 148
 	}
148 149
 
149 150
 	if ec.Running {
150 151
 		ec.Unlock()
151
-		return derr.ErrorCodeExecRunning.WithArgs(ec.ID)
152
+		return fmt.Errorf("Error: Exec command %s is already running", ec.ID)
152 153
 	}
153 154
 	ec.Running = true
154 155
 	ec.Unlock()
... ...
@@ -194,12 +196,12 @@ func (d *Daemon) ContainerExecStart(name string, stdin io.ReadCloser, stdout io.
194 194
 	select {
195 195
 	case err := <-attachErr:
196 196
 		if err != nil {
197
-			return derr.ErrorCodeExecAttach.WithArgs(err)
197
+			return fmt.Errorf("attach failed with error: %v", err)
198 198
 		}
199 199
 		return nil
200 200
 	case err := <-execErr:
201 201
 		if aErr := <-attachErr; aErr != nil && err == nil {
202
-			return derr.ErrorCodeExecAttach.WithArgs(aErr)
202
+			return fmt.Errorf("attach failed with error: %v", aErr)
203 203
 		}
204 204
 		if err == nil {
205 205
 			return nil
... ...
@@ -207,9 +209,9 @@ func (d *Daemon) ContainerExecStart(name string, stdin io.ReadCloser, stdout io.
207 207
 
208 208
 		// Maybe the container stopped while we were trying to exec
209 209
 		if !c.IsRunning() {
210
-			return derr.ErrorCodeExecContainerStopped
210
+			return fmt.Errorf("container stopped while running exec: %s", c.ID)
211 211
 		}
212
-		return derr.ErrorCodeExecCantRun.WithArgs(ec.ID, c.ID, err)
212
+		return fmt.Errorf("Cannot run exec command %s in container %s: %s", ec.ID, c.ID, err)
213 213
 	}
214 214
 }
215 215
 
... ...
@@ -1,11 +1,11 @@
1 1
 package exec
2 2
 
3 3
 import (
4
+	"fmt"
4 5
 	"sync"
5 6
 	"time"
6 7
 
7 8
 	"github.com/docker/docker/daemon/execdriver"
8
-	derr "github.com/docker/docker/errors"
9 9
 	"github.com/docker/docker/pkg/stringid"
10 10
 	"github.com/docker/docker/runconfig"
11 11
 )
... ...
@@ -116,7 +116,7 @@ func (c *Config) Resize(h, w int) error {
116 116
 	select {
117 117
 	case <-c.waitStart:
118 118
 	case <-time.After(time.Second):
119
-		return derr.ErrorCodeExecResize.WithArgs(c.ID)
119
+		return fmt.Errorf("Exec %s is not running, so it can not be resized.", c.ID)
120 120
 	}
121 121
 	return c.ProcessConfig.Terminal.Resize(h, w)
122 122
 }
... ...
@@ -9,7 +9,6 @@ import (
9 9
 	"syscall"
10 10
 
11 11
 	"github.com/docker/docker/daemon/execdriver"
12
-	derr "github.com/docker/docker/errors"
13 12
 	"github.com/docker/docker/pkg/mount"
14 13
 	"github.com/docker/docker/profiles/seccomp"
15 14
 
... ...
@@ -430,7 +429,7 @@ func (d *Driver) setupMounts(container *configs.Config, c *execdriver.Command) e
430 430
 	for _, m := range c.Mounts {
431 431
 		for _, cm := range container.Mounts {
432 432
 			if cm.Destination == m.Destination {
433
-				return derr.ErrorCodeMountDup.WithArgs(m.Destination)
433
+				return fmt.Errorf("Duplicate mount point '%s'", m.Destination)
434 434
 			}
435 435
 		}
436 436
 
... ...
@@ -1,10 +1,10 @@
1 1
 package daemon
2 2
 
3 3
 import (
4
+	"fmt"
4 5
 	"io"
5 6
 
6 7
 	"github.com/docker/docker/container"
7
-	derr "github.com/docker/docker/errors"
8 8
 	"github.com/docker/docker/pkg/archive"
9 9
 	"github.com/docker/docker/pkg/ioutils"
10 10
 )
... ...
@@ -19,13 +19,13 @@ func (daemon *Daemon) ContainerExport(name string, out io.Writer) error {
19 19
 
20 20
 	data, err := daemon.containerExport(container)
21 21
 	if err != nil {
22
-		return derr.ErrorCodeExportFailed.WithArgs(name, err)
22
+		return fmt.Errorf("Error exporting container %s: %v", name, err)
23 23
 	}
24 24
 	defer data.Close()
25 25
 
26 26
 	// Stream the entire contents of the container (basically a volatile snapshot)
27 27
 	if _, err := io.Copy(out, data); err != nil {
28
-		return derr.ErrorCodeExportFailed.WithArgs(name, err)
28
+		return fmt.Errorf("Error exporting container %s: %v", name, err)
29 29
 	}
30 30
 	return nil
31 31
 }
... ...
@@ -5,7 +5,7 @@ import (
5 5
 	"strings"
6 6
 
7 7
 	"github.com/docker/docker/container"
8
-	derr "github.com/docker/docker/errors"
8
+	"github.com/docker/docker/errors"
9 9
 	"github.com/docker/docker/image"
10 10
 	"github.com/docker/docker/pkg/stringid"
11 11
 	"github.com/docker/docker/reference"
... ...
@@ -82,7 +82,8 @@ func (daemon *Daemon) ImageDelete(imageRef string, force, prune bool) ([]types.I
82 82
 				// this image would remain "dangling" and since
83 83
 				// we really want to avoid that the client must
84 84
 				// explicitly force its removal.
85
-				return nil, derr.ErrorCodeImgDelUsed.WithArgs(imageRef, stringid.TruncateID(container.ID), stringid.TruncateID(imgID.String()))
85
+				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()))
86
+				return nil, errors.NewRequestConflictError(err)
86 87
 			}
87 88
 		}
88 89
 
... ...
@@ -8,7 +8,6 @@ import (
8 8
 
9 9
 	"github.com/Sirupsen/logrus"
10 10
 	"github.com/docker/docker/container"
11
-	derr "github.com/docker/docker/errors"
12 11
 	"github.com/docker/docker/pkg/signal"
13 12
 )
14 13
 
... ...
@@ -45,11 +44,11 @@ func (daemon *Daemon) killWithSignal(container *container.Container, sig int) er
45 45
 
46 46
 	// We could unpause the container for them rather than returning this error
47 47
 	if container.Paused {
48
-		return derr.ErrorCodeUnpauseContainer.WithArgs(container.ID)
48
+		return fmt.Errorf("Container %s is paused. Unpause the container before stopping", container.ID)
49 49
 	}
50 50
 
51 51
 	if !container.Running {
52
-		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
52
+		return errNotRunning{container.ID}
53 53
 	}
54 54
 
55 55
 	container.ExitOnNext()
... ...
@@ -62,7 +61,7 @@ func (daemon *Daemon) killWithSignal(container *container.Container, sig int) er
62 62
 	}
63 63
 
64 64
 	if err := daemon.kill(container, sig); err != nil {
65
-		return derr.ErrorCodeCantKill.WithArgs(container.ID, err)
65
+		return fmt.Errorf("Cannot kill container %s: %s", container.ID, err)
66 66
 	}
67 67
 
68 68
 	attributes := map[string]string{
... ...
@@ -75,7 +74,7 @@ func (daemon *Daemon) killWithSignal(container *container.Container, sig int) er
75 75
 // Kill forcefully terminates a container.
76 76
 func (daemon *Daemon) Kill(container *container.Container) error {
77 77
 	if !container.IsRunning() {
78
-		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
78
+		return errNotRunning{container.ID}
79 79
 	}
80 80
 
81 81
 	// 1. Send SIGKILL
... ...
@@ -1,6 +1,7 @@
1 1
 package daemon
2 2
 
3 3
 import (
4
+	"fmt"
4 5
 	"io"
5 6
 	"strconv"
6 7
 	"time"
... ...
@@ -10,7 +11,6 @@ import (
10 10
 	"github.com/docker/docker/container"
11 11
 	"github.com/docker/docker/daemon/logger"
12 12
 	"github.com/docker/docker/daemon/logger/jsonfilelog"
13
-	derr "github.com/docker/docker/errors"
14 13
 	"github.com/docker/docker/pkg/ioutils"
15 14
 	"github.com/docker/docker/pkg/stdcopy"
16 15
 	timetypes "github.com/docker/engine-api/types/time"
... ...
@@ -21,11 +21,11 @@ import (
21 21
 func (daemon *Daemon) ContainerLogs(containerName string, config *backend.ContainerLogsConfig, started chan struct{}) error {
22 22
 	container, err := daemon.GetContainer(containerName)
23 23
 	if err != nil {
24
-		return derr.ErrorCodeNoSuchContainer.WithArgs(containerName)
24
+		return err
25 25
 	}
26 26
 
27 27
 	if !(config.ShowStdout || config.ShowStderr) {
28
-		return derr.ErrorCodeNeedStream
28
+		return fmt.Errorf("You must choose at least one stream")
29 29
 	}
30 30
 
31 31
 	cLog, err := daemon.getLogger(container)
... ...
@@ -122,7 +122,7 @@ func (daemon *Daemon) StartLogging(container *container.Container) error {
122 122
 	}
123 123
 	l, err := container.StartLogger(cfg)
124 124
 	if err != nil {
125
-		return derr.ErrorCodeInitLogger.WithArgs(err)
125
+		return fmt.Errorf("Failed to initialize logging driver: %v", err)
126 126
 	}
127 127
 
128 128
 	copier := logger.NewCopier(container.ID, map[string]io.Reader{"stdout": container.StdoutPipe(), "stderr": container.StderrPipe()}, l)
... ...
@@ -1,10 +1,10 @@
1 1
 package daemon
2 2
 
3 3
 import (
4
+	"fmt"
4 5
 	"strings"
5 6
 
6 7
 	"github.com/docker/docker/container"
7
-	derr "github.com/docker/docker/errors"
8 8
 	volumestore "github.com/docker/docker/volume/store"
9 9
 )
10 10
 
... ...
@@ -42,7 +42,7 @@ func (daemon *Daemon) removeMountPoints(container *container.Container, rm bool)
42 42
 		}
43 43
 	}
44 44
 	if len(rmErrors) > 0 {
45
-		return derr.ErrorCodeRemovingVolume.WithArgs(strings.Join(rmErrors, "\n"))
45
+		return fmt.Errorf("Error removing volumes:\n%v", strings.Join(rmErrors, "\n"))
46 46
 	}
47 47
 	return nil
48 48
 }
... ...
@@ -3,9 +3,10 @@ package daemon
3 3
 import (
4 4
 	"fmt"
5 5
 	"net"
6
+	"net/http"
6 7
 	"strings"
7 8
 
8
-	derr "github.com/docker/docker/errors"
9
+	"github.com/docker/docker/errors"
9 10
 	"github.com/docker/docker/runconfig"
10 11
 	"github.com/docker/engine-api/types/network"
11 12
 	"github.com/docker/libnetwork"
... ...
@@ -191,7 +192,8 @@ func (daemon *Daemon) DeleteNetwork(networkID string) error {
191 191
 	}
192 192
 
193 193
 	if runconfig.IsPreDefinedNetwork(nw.Name()) {
194
-		return derr.ErrorCodeCantDeletePredefinedNetwork.WithArgs(nw.Name())
194
+		err := fmt.Errorf("%s is a pre-defined network and cannot be removed", nw.Name())
195
+		return errors.NewErrorWithStatusCode(err, http.StatusForbidden)
195 196
 	}
196 197
 
197 198
 	if err := nw.Delete(); err != nil {
... ...
@@ -1,8 +1,9 @@
1 1
 package daemon
2 2
 
3 3
 import (
4
+	"fmt"
5
+
4 6
 	"github.com/docker/docker/container"
5
-	derr "github.com/docker/docker/errors"
6 7
 )
7 8
 
8 9
 // ContainerPause pauses a container
... ...
@@ -27,21 +28,21 @@ func (daemon *Daemon) containerPause(container *container.Container) error {
27 27
 
28 28
 	// We cannot Pause the container which is not running
29 29
 	if !container.Running {
30
-		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
30
+		return errNotRunning{container.ID}
31 31
 	}
32 32
 
33 33
 	// We cannot Pause the container which is already paused
34 34
 	if container.Paused {
35
-		return derr.ErrorCodeAlreadyPaused.WithArgs(container.ID)
35
+		return fmt.Errorf("Container %s is already paused", container.ID)
36 36
 	}
37 37
 
38 38
 	// We cannot Pause the container which is restarting
39 39
 	if container.Restarting {
40
-		return derr.ErrorCodeContainerRestarting.WithArgs(container.ID)
40
+		return errContainerIsRestarting(container.ID)
41 41
 	}
42 42
 
43 43
 	if err := daemon.execDriver.Pause(container.Command); err != nil {
44
-		return derr.ErrorCodeCantPause.WithArgs(container.ID, err)
44
+		return fmt.Errorf("Cannot pause container %s: %s", container.ID, err)
45 45
 	}
46 46
 	container.Paused = true
47 47
 	daemon.LogContainerEvent(container, "pause")
... ...
@@ -1,10 +1,10 @@
1 1
 package daemon
2 2
 
3 3
 import (
4
+	"fmt"
4 5
 	"strings"
5 6
 
6 7
 	"github.com/Sirupsen/logrus"
7
-	derr "github.com/docker/docker/errors"
8 8
 	"github.com/docker/libnetwork"
9 9
 )
10 10
 
... ...
@@ -18,7 +18,7 @@ func (daemon *Daemon) ContainerRename(oldName, newName string) error {
18 18
 	)
19 19
 
20 20
 	if oldName == "" || newName == "" {
21
-		return derr.ErrorCodeEmptyRename
21
+		return fmt.Errorf("Neither old nor new names may be empty")
22 22
 	}
23 23
 
24 24
 	container, err := daemon.GetContainer(oldName)
... ...
@@ -31,7 +31,7 @@ func (daemon *Daemon) ContainerRename(oldName, newName string) error {
31 31
 	container.Lock()
32 32
 	defer container.Unlock()
33 33
 	if newName, err = daemon.reserveName(container.ID, newName); err != nil {
34
-		return derr.ErrorCodeRenameTaken.WithArgs(err)
34
+		return fmt.Errorf("Error when allocating new name: %v", err)
35 35
 	}
36 36
 
37 37
 	container.Name = newName
... ...
@@ -1,10 +1,6 @@
1 1
 package daemon
2 2
 
3
-import (
4
-	"fmt"
5
-
6
-	derr "github.com/docker/docker/errors"
7
-)
3
+import "fmt"
8 4
 
9 5
 // ContainerResize changes the size of the TTY of the process running
10 6
 // 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 {
15 15
 	}
16 16
 
17 17
 	if !container.IsRunning() {
18
-		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
18
+		return errNotRunning{container.ID}
19 19
 	}
20 20
 
21 21
 	if err = container.Resize(height, width); err == nil {
... ...
@@ -1,8 +1,9 @@
1 1
 package daemon
2 2
 
3 3
 import (
4
+	"fmt"
5
+
4 6
 	"github.com/docker/docker/container"
5
-	derr "github.com/docker/docker/errors"
6 7
 )
7 8
 
8 9
 // ContainerRestart stops and starts a container. It attempts to
... ...
@@ -17,7 +18,7 @@ func (daemon *Daemon) ContainerRestart(name string, seconds int) error {
17 17
 		return err
18 18
 	}
19 19
 	if err := daemon.containerRestart(container, seconds); err != nil {
20
-		return derr.ErrorCodeCantRestart.WithArgs(name, err)
20
+		return fmt.Errorf("Cannot restart container %s: %v", name, err)
21 21
 	}
22 22
 	return nil
23 23
 }
... ...
@@ -2,11 +2,12 @@ package daemon
2 2
 
3 3
 import (
4 4
 	"fmt"
5
+	"net/http"
5 6
 	"runtime"
6 7
 
7 8
 	"github.com/Sirupsen/logrus"
8 9
 	"github.com/docker/docker/container"
9
-	derr "github.com/docker/docker/errors"
10
+	"github.com/docker/docker/errors"
10 11
 	"github.com/docker/docker/runconfig"
11 12
 	containertypes "github.com/docker/engine-api/types/container"
12 13
 )
... ...
@@ -19,11 +20,12 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *containertypes.Hos
19 19
 	}
20 20
 
21 21
 	if container.IsPaused() {
22
-		return derr.ErrorCodeStartPaused
22
+		return fmt.Errorf("Cannot start a paused container, try unpause instead.")
23 23
 	}
24 24
 
25 25
 	if container.IsRunning() {
26
-		return derr.ErrorCodeAlreadyStarted
26
+		err := fmt.Errorf("Container already started")
27
+		return errors.NewErrorWithStatusCode(err, http.StatusNotModified)
27 28
 	}
28 29
 
29 30
 	// Windows does not have the backwards compatibility issue here.
... ...
@@ -52,7 +54,7 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *containertypes.Hos
52 52
 		}
53 53
 	} else {
54 54
 		if hostConfig != nil {
55
-			return derr.ErrorCodeHostConfigStart
55
+			return fmt.Errorf("Supplying a hostconfig on start is not supported. It should be supplied on create")
56 56
 		}
57 57
 	}
58 58
 
... ...
@@ -88,7 +90,7 @@ func (daemon *Daemon) containerStart(container *container.Container) (err error)
88 88
 	}
89 89
 
90 90
 	if container.RemovalInProgress || container.Dead {
91
-		return derr.ErrorCodeContainerBeingRemoved
91
+		return fmt.Errorf("Container is marked for removal and cannot be started.")
92 92
 	}
93 93
 
94 94
 	// if we encounter an error during start we need to ensure that any other
... ...
@@ -4,6 +4,7 @@ package daemon
4 4
 
5 5
 import (
6 6
 	"bufio"
7
+	"fmt"
7 8
 	"os"
8 9
 	"strconv"
9 10
 	"strings"
... ...
@@ -13,7 +14,6 @@ import (
13 13
 	"github.com/Sirupsen/logrus"
14 14
 	"github.com/docker/docker/container"
15 15
 	"github.com/docker/docker/daemon/execdriver"
16
-	derr "github.com/docker/docker/errors"
17 16
 	"github.com/docker/docker/pkg/pubsub"
18 17
 	"github.com/opencontainers/runc/libcontainer/system"
19 18
 )
... ...
@@ -163,13 +163,13 @@ func (s *statsCollector) getSystemCPUUsage() (uint64, error) {
163 163
 		switch parts[0] {
164 164
 		case "cpu":
165 165
 			if len(parts) < 8 {
166
-				return 0, derr.ErrorCodeBadCPUFields
166
+				return 0, fmt.Errorf("invalid number of cpu fields")
167 167
 			}
168 168
 			var totalClockTicks uint64
169 169
 			for _, i := range parts[1:8] {
170 170
 				v, err := strconv.ParseUint(i, 10, 64)
171 171
 				if err != nil {
172
-					return 0, derr.ErrorCodeBadCPUInt.WithArgs(i, err)
172
+					return 0, fmt.Errorf("Unable to convert value %s to int: %s", i, err)
173 173
 				}
174 174
 				totalClockTicks += v
175 175
 			}
... ...
@@ -177,5 +177,5 @@ func (s *statsCollector) getSystemCPUUsage() (uint64, error) {
177 177
 				s.clockTicksPerSecond, nil
178 178
 		}
179 179
 	}
180
-	return 0, derr.ErrorCodeBadStatFormat
180
+	return 0, fmt.Errorf("invalid stat format. Error trying to parse the '/proc/stat' file")
181 181
 }
... ...
@@ -1,11 +1,13 @@
1 1
 package daemon
2 2
 
3 3
 import (
4
+	"fmt"
5
+	"net/http"
4 6
 	"time"
5 7
 
6 8
 	"github.com/Sirupsen/logrus"
7 9
 	"github.com/docker/docker/container"
8
-	derr "github.com/docker/docker/errors"
10
+	"github.com/docker/docker/errors"
9 11
 )
10 12
 
11 13
 // ContainerStop looks for the given container and terminates it,
... ...
@@ -20,10 +22,11 @@ func (daemon *Daemon) ContainerStop(name string, seconds int) error {
20 20
 		return err
21 21
 	}
22 22
 	if !container.IsRunning() {
23
-		return derr.ErrorCodeStopped.WithArgs(name)
23
+		err := fmt.Errorf("Container %s is already stopped", name)
24
+		return errors.NewErrorWithStatusCode(err, http.StatusNotModified)
24 25
 	}
25 26
 	if err := daemon.containerStop(container, seconds); err != nil {
26
-		return derr.ErrorCodeCantStop.WithArgs(name, err)
27
+		return fmt.Errorf("Cannot stop container %s: %v", name, err)
27 28
 	}
28 29
 	return nil
29 30
 }
... ...
@@ -3,11 +3,11 @@
3 3
 package daemon
4 4
 
5 5
 import (
6
+	"fmt"
6 7
 	"os/exec"
7 8
 	"strconv"
8 9
 	"strings"
9 10
 
10
-	derr "github.com/docker/docker/errors"
11 11
 	"github.com/docker/engine-api/types"
12 12
 )
13 13
 
... ...
@@ -27,11 +27,11 @@ func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.Container
27 27
 	}
28 28
 
29 29
 	if !container.IsRunning() {
30
-		return nil, derr.ErrorCodeNotRunning.WithArgs(name)
30
+		return nil, errNotRunning{container.ID}
31 31
 	}
32 32
 
33 33
 	if container.IsRestarting() {
34
-		return nil, derr.ErrorCodeContainerRestarting.WithArgs(name)
34
+		return nil, errContainerIsRestarting(container.ID)
35 35
 	}
36 36
 	pids, err := daemon.ExecutionDriver().GetPidsForContainer(container.ID)
37 37
 	if err != nil {
... ...
@@ -40,7 +40,7 @@ func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.Container
40 40
 
41 41
 	output, err := exec.Command("ps", strings.Split(psArgs, " ")...).Output()
42 42
 	if err != nil {
43
-		return nil, derr.ErrorCodePSError.WithArgs(err)
43
+		return nil, fmt.Errorf("Error running ps: %v", err)
44 44
 	}
45 45
 
46 46
 	procList := &types.ContainerProcessList{}
... ...
@@ -55,7 +55,7 @@ func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.Container
55 55
 		}
56 56
 	}
57 57
 	if pidIndex == -1 {
58
-		return nil, derr.ErrorCodeNoPID
58
+		return nil, fmt.Errorf("Couldn't find PID field in ps output")
59 59
 	}
60 60
 
61 61
 	// 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
66 66
 		fields := strings.Fields(line)
67 67
 		p, err := strconv.Atoi(fields[pidIndex])
68 68
 		if err != nil {
69
-			return nil, derr.ErrorCodeBadPID.WithArgs(fields[pidIndex], err)
69
+			return nil, fmt.Errorf("Unexpected pid '%s': %s", fields[pidIndex], err)
70 70
 		}
71 71
 
72 72
 		for _, pid := range pids {
... ...
@@ -1,11 +1,12 @@
1 1
 package daemon
2 2
 
3 3
 import (
4
-	derr "github.com/docker/docker/errors"
4
+	"fmt"
5
+
5 6
 	"github.com/docker/engine-api/types"
6 7
 )
7 8
 
8 9
 // ContainerTop is not supported on Windows and returns an error.
9 10
 func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.ContainerProcessList, error) {
10
-	return nil, derr.ErrorCodeNoTop
11
+	return nil, fmt.Errorf("Top is not supported on Windows")
11 12
 }
... ...
@@ -1,8 +1,9 @@
1 1
 package daemon
2 2
 
3 3
 import (
4
+	"fmt"
5
+
4 6
 	"github.com/docker/docker/container"
5
-	derr "github.com/docker/docker/errors"
6 7
 )
7 8
 
8 9
 // ContainerUnpause unpauses a container
... ...
@@ -26,16 +27,16 @@ func (daemon *Daemon) containerUnpause(container *container.Container) error {
26 26
 
27 27
 	// We cannot unpause the container which is not running
28 28
 	if !container.Running {
29
-		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
29
+		return errNotRunning{container.ID}
30 30
 	}
31 31
 
32 32
 	// We cannot unpause the container which is not paused
33 33
 	if !container.Paused {
34
-		return derr.ErrorCodeNotPaused.WithArgs(container.ID)
34
+		return fmt.Errorf("Container %s is not paused", container.ID)
35 35
 	}
36 36
 
37 37
 	if err := daemon.execDriver.Unpause(container.Command); err != nil {
38
-		return derr.ErrorCodeCantUnpause.WithArgs(container.ID, err)
38
+		return fmt.Errorf("Cannot unpause container %s: %s", container.ID, err)
39 39
 	}
40 40
 
41 41
 	container.Paused = false
... ...
@@ -4,7 +4,6 @@ import (
4 4
 	"fmt"
5 5
 	"time"
6 6
 
7
-	derr "github.com/docker/docker/errors"
8 7
 	"github.com/docker/engine-api/types/container"
9 8
 )
10 9
 
... ...
@@ -57,18 +56,16 @@ func (daemon *Daemon) update(name string, hostConfig *container.HostConfig) erro
57 57
 	}()
58 58
 
59 59
 	if container.RemovalInProgress || container.Dead {
60
-		errMsg := fmt.Errorf("Container is marked for removal and cannot be \"update\".")
61
-		return derr.ErrorCodeCantUpdate.WithArgs(container.ID, errMsg)
60
+		return errCannotUpdate(container.ID, fmt.Errorf("Container is marked for removal and cannot be \"update\"."))
62 61
 	}
63 62
 
64 63
 	if container.IsRunning() && hostConfig.KernelMemory != 0 {
65
-		errMsg := fmt.Errorf("Can not update kernel memory to a running container, please stop it first.")
66
-		return derr.ErrorCodeCantUpdate.WithArgs(container.ID, errMsg)
64
+		return errCannotUpdate(container.ID, fmt.Errorf("Can not update kernel memory to a running container, please stop it first."))
67 65
 	}
68 66
 
69 67
 	if err := container.UpdateContainer(hostConfig); err != nil {
70 68
 		restoreConfig = true
71
-		return derr.ErrorCodeCantUpdate.WithArgs(container.ID, err.Error())
69
+		return errCannotUpdate(container.ID, err)
72 70
 	}
73 71
 
74 72
 	// if Restart Policy changed, we need to update container monitor
... ...
@@ -86,7 +83,7 @@ func (daemon *Daemon) update(name string, hostConfig *container.HostConfig) erro
86 86
 	if container.IsRunning() && !container.IsRestarting() {
87 87
 		if err := daemon.execDriver.Update(container.Command); err != nil {
88 88
 			restoreConfig = true
89
-			return derr.ErrorCodeCantUpdate.WithArgs(container.ID, err.Error())
89
+			return errCannotUpdate(container.ID, err)
90 90
 		}
91 91
 	}
92 92
 
... ...
@@ -94,3 +91,7 @@ func (daemon *Daemon) update(name string, hostConfig *container.HostConfig) erro
94 94
 
95 95
 	return nil
96 96
 }
97
+
98
+func errCannotUpdate(containerID string, err error) error {
99
+	return fmt.Errorf("Cannot update container %s: %v", containerID, err)
100
+}
... ...
@@ -2,13 +2,13 @@ package daemon
2 2
 
3 3
 import (
4 4
 	"errors"
5
+	"fmt"
5 6
 	"os"
6 7
 	"path/filepath"
7 8
 	"strings"
8 9
 
9 10
 	"github.com/docker/docker/container"
10 11
 	"github.com/docker/docker/daemon/execdriver"
11
-	derr "github.com/docker/docker/errors"
12 12
 	"github.com/docker/docker/volume"
13 13
 	"github.com/docker/engine-api/types"
14 14
 	containertypes "github.com/docker/engine-api/types/container"
... ...
@@ -114,7 +114,7 @@ func (daemon *Daemon) registerMountPoints(container *container.Container, hostCo
114 114
 		}
115 115
 
116 116
 		if binds[bind.Destination] {
117
-			return derr.ErrorCodeMountDup.WithArgs(bind.Destination)
117
+			return fmt.Errorf("Duplicate mount point '%s'", bind.Destination)
118 118
 		}
119 119
 
120 120
 		if len(bind.Name) > 0 {
... ...
@@ -3,11 +3,11 @@
3 3
 package daemon
4 4
 
5 5
 import (
6
+	"fmt"
6 7
 	"sort"
7 8
 
8 9
 	"github.com/docker/docker/container"
9 10
 	"github.com/docker/docker/daemon/execdriver"
10
-	derr "github.com/docker/docker/errors"
11 11
 	"github.com/docker/docker/volume"
12 12
 )
13 13
 
... ...
@@ -27,7 +27,7 @@ func (daemon *Daemon) setupMounts(container *container.Container) ([]execdriver.
27 27
 			s = mount.Volume.Path()
28 28
 		}
29 29
 		if s == "" {
30
-			return nil, derr.ErrorCodeVolumeNoSourceForMount.WithArgs(mount.Name, mount.Driver, mount.Destination)
30
+			return nil, fmt.Errorf("No source for mount name '%s' driver %q destination '%s'", mount.Name, mount.Driver, mount.Destination)
31 31
 		}
32 32
 		mnts = append(mnts, execdriver.Mount{
33 33
 			Source:      s,
... ...
@@ -14,6 +14,7 @@ import (
14 14
 	"github.com/Sirupsen/logrus"
15 15
 	"github.com/docker/distribution/uuid"
16 16
 	apiserver "github.com/docker/docker/api/server"
17
+	"github.com/docker/docker/api/server/router"
17 18
 	"github.com/docker/docker/api/server/router/build"
18 19
 	"github.com/docker/docker/api/server/router/container"
19 20
 	"github.com/docker/docker/api/server/router/image"
... ...
@@ -396,11 +397,16 @@ func loadDaemonCliConfig(config *daemon.Config, daemonFlags *flag.FlagSet, commo
396 396
 }
397 397
 
398 398
 func initRouter(s *apiserver.Server, d *daemon.Daemon) {
399
-	s.InitRouter(utils.IsDebugEnabled(),
399
+	routers := []router.Router{
400 400
 		container.NewRouter(d),
401 401
 		image.NewRouter(d),
402
-		network.NewRouter(d),
403 402
 		systemrouter.NewRouter(d),
404 403
 		volume.NewRouter(d),
405
-		build.NewRouter(dockerfile.NewBuildManager(d)))
404
+		build.NewRouter(dockerfile.NewBuildManager(d)),
405
+	}
406
+	if d.NetworkControllerEnabled() {
407
+		routers = append(routers, network.NewRouter(d))
408
+	}
409
+
410
+	s.InitRouter(utils.IsDebugEnabled(), routers...)
406 411
 }
407 412
deleted file mode 100644
... ...
@@ -1,58 +0,0 @@
1
-Docker 'errors' package
2
-=======================
3
-
4
-This package contains all of the error messages generated by the Docker
5
-engine that might be exposed via the Docker engine's REST API.
6
-
7
-Each top-level engine package will have its own file in this directory
8
-so that there's a clear grouping of errors, instead of just one big
9
-file. The errors for each package are defined here instead of within
10
-their respective package structure so that Docker CLI code that may need
11
-to import these error definition files will not need to know or understand
12
-the engine's package/directory structure. In other words, all they should
13
-need to do is import `.../docker/errors` and they will automatically
14
-pick up all Docker engine defined errors.  This also gives the engine
15
-developers the freedom to change the engine packaging structure (e.g. to
16
-CRUD packages) without worrying about breaking existing clients.
17
-
18
-These errors are defined using the 'errcode' package. The `errcode`  package
19
-allows for each error to be typed and include all information necessary to
20
-have further processing done on them if necessary.  In particular, each error
21
-includes:
22
-
23
-* Value - a unique string (in all caps) associated with this error.
24
-Typically, this string is the same name as the variable name of the error
25
-(w/o the `ErrorCode` text) but in all caps.
26
-
27
-* Message - the human readable sentence that will be displayed for this
28
-error. It can contain '%s' substitutions that allows for the code generating
29
-the error to specify values that will be inserted in the string prior to
30
-being displayed to the end-user. The `WithArgs()` function can be used to
31
-specify the insertion strings.  Note, the evaluation of the strings will be
32
-done at the time `WithArgs()` is called.
33
-
34
-* Description - additional human readable text to further explain the
35
-circumstances of the error situation.
36
-
37
-* HTTPStatusCode - when the error is returned back to a CLI, this value
38
-will be used to populate the HTTP status code. If not present the default
39
-value will be `StatusInternalServerError`, 500.
40
-
41
-Not all errors generated within the engine's executable will be propagated
42
-back to the engine's API layer. For example, it is expected that errors
43
-generated by vendored code (under `docker/vendor`) and packaged code
44
-(under `docker/pkg`) will be converted into errors defined by this package.
45
-
46
-When processing an errcode error, if you are looking for a particular
47
-error then you can do something like:
48
-
49
-```
50
-import derr "github.com/docker/docker/errors"
51
-
52
-...
53
-
54
-err := someFunc()
55
-if err.ErrorCode() == derr.ErrorCodeNoSuchContainer {
56
-	...
57
-}
58
-```
59 1
deleted file mode 100644
... ...
@@ -1,93 +0,0 @@
1
-package errors
2
-
3
-// This file contains all of the errors that can be generated from the
4
-// docker/builder component.
5
-
6
-import (
7
-	"net/http"
8
-
9
-	"github.com/docker/distribution/registry/api/errcode"
10
-)
11
-
12
-var (
13
-	// ErrorCodeAtLeastOneArg is generated when the parser comes across a
14
-	// Dockerfile command that doesn't have any args.
15
-	ErrorCodeAtLeastOneArg = errcode.Register(errGroup, errcode.ErrorDescriptor{
16
-		Value:          "ATLEASTONEARG",
17
-		Message:        "%s requires at least one argument",
18
-		Description:    "The specified command requires at least one argument",
19
-		HTTPStatusCode: http.StatusInternalServerError,
20
-	})
21
-
22
-	// ErrorCodeExactlyOneArg is generated when the parser comes across a
23
-	// Dockerfile command that requires exactly one arg but got less/more.
24
-	ErrorCodeExactlyOneArg = errcode.Register(errGroup, errcode.ErrorDescriptor{
25
-		Value:          "EXACTLYONEARG",
26
-		Message:        "%s requires exactly one argument",
27
-		Description:    "The specified command requires exactly one argument",
28
-		HTTPStatusCode: http.StatusInternalServerError,
29
-	})
30
-
31
-	// ErrorCodeAtLeastTwoArgs is generated when the parser comes across a
32
-	// Dockerfile command that requires at least two args but got less.
33
-	ErrorCodeAtLeastTwoArgs = errcode.Register(errGroup, errcode.ErrorDescriptor{
34
-		Value:          "ATLEASTTWOARGS",
35
-		Message:        "%s requires at least two arguments",
36
-		Description:    "The specified command requires at least two arguments",
37
-		HTTPStatusCode: http.StatusInternalServerError,
38
-	})
39
-
40
-	// ErrorCodeTooManyArgs is generated when the parser comes across a
41
-	// Dockerfile command that has more args than it should
42
-	ErrorCodeTooManyArgs = errcode.Register(errGroup, errcode.ErrorDescriptor{
43
-		Value:          "TOOMANYARGS",
44
-		Message:        "Bad input to %s, too many args",
45
-		Description:    "The specified command was passed too many arguments",
46
-		HTTPStatusCode: http.StatusInternalServerError,
47
-	})
48
-
49
-	// ErrorCodeChainOnBuild is generated when the parser comes across a
50
-	// Dockerfile command that is trying to chain ONBUILD commands.
51
-	ErrorCodeChainOnBuild = errcode.Register(errGroup, errcode.ErrorDescriptor{
52
-		Value:          "CHAINONBUILD",
53
-		Message:        "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed",
54
-		Description:    "ONBUILD Dockerfile commands aren't allow on ONBUILD commands",
55
-		HTTPStatusCode: http.StatusInternalServerError,
56
-	})
57
-
58
-	// ErrorCodeBadOnBuildCmd is generated when the parser comes across a
59
-	// an ONBUILD Dockerfile command with an invalid trigger/command.
60
-	ErrorCodeBadOnBuildCmd = errcode.Register(errGroup, errcode.ErrorDescriptor{
61
-		Value:          "BADONBUILDCMD",
62
-		Message:        "%s isn't allowed as an ONBUILD trigger",
63
-		Description:    "The specified ONBUILD command isn't allowed",
64
-		HTTPStatusCode: http.StatusInternalServerError,
65
-	})
66
-
67
-	// ErrorCodeMissingFrom is generated when the Dockerfile is missing
68
-	// a FROM command.
69
-	ErrorCodeMissingFrom = errcode.Register(errGroup, errcode.ErrorDescriptor{
70
-		Value:          "MISSINGFROM",
71
-		Message:        "Please provide a source image with `from` prior to run",
72
-		Description:    "The Dockerfile is missing a FROM command",
73
-		HTTPStatusCode: http.StatusInternalServerError,
74
-	})
75
-
76
-	// ErrorCodeNotOnWindows is generated when the specified Dockerfile
77
-	// command is not supported on Windows.
78
-	ErrorCodeNotOnWindows = errcode.Register(errGroup, errcode.ErrorDescriptor{
79
-		Value:          "NOTONWINDOWS",
80
-		Message:        "%s is not supported on Windows",
81
-		Description:    "The specified Dockerfile command is not supported on Windows",
82
-		HTTPStatusCode: http.StatusInternalServerError,
83
-	})
84
-
85
-	// ErrorCodeVolumeEmpty is generated when the specified Volume string
86
-	// is empty.
87
-	ErrorCodeVolumeEmpty = errcode.Register(errGroup, errcode.ErrorDescriptor{
88
-		Value:          "VOLUMEEMPTY",
89
-		Message:        "Volume specified can not be an empty string",
90
-		Description:    "The specified volume can not be an empty string",
91
-		HTTPStatusCode: http.StatusInternalServerError,
92
-	})
93
-)
94 1
deleted file mode 100644
... ...
@@ -1,1013 +0,0 @@
1
-package errors
2
-
3
-// This file contains all of the errors that can be generated from the
4
-// docker/daemon component.
5
-
6
-import (
7
-	"net/http"
8
-
9
-	"github.com/docker/distribution/registry/api/errcode"
10
-)
11
-
12
-var (
13
-	// ErrorCodeNoSuchContainer is generated when we look for a container by
14
-	// name or ID and we can't find it.
15
-	ErrorCodeNoSuchContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
16
-		Value:          "NOSUCHCONTAINER",
17
-		Message:        "No such container: %s",
18
-		Description:    "The specified container can not be found",
19
-		HTTPStatusCode: http.StatusNotFound,
20
-	})
21
-
22
-	// ErrorCodeUnregisteredContainer is generated when we try to load
23
-	// a storage driver for an unregistered container
24
-	ErrorCodeUnregisteredContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
25
-		Value:          "UNREGISTEREDCONTAINER",
26
-		Message:        "Can't load storage driver for unregistered container %s",
27
-		Description:    "An attempt was made to load the storage driver for a container that is not registered with the daemon",
28
-		HTTPStatusCode: http.StatusInternalServerError,
29
-	})
30
-
31
-	// ErrorCodeContainerBeingRemoved is generated when an attempt to start
32
-	// a container is made but its in the process of being removed, or is dead.
33
-	ErrorCodeContainerBeingRemoved = errcode.Register(errGroup, errcode.ErrorDescriptor{
34
-		Value:          "CONTAINERBEINGREMOVED",
35
-		Message:        "Container is marked for removal and cannot be started.",
36
-		Description:    "An attempt was made to start a container that is in the process of being deleted",
37
-		HTTPStatusCode: http.StatusInternalServerError,
38
-	})
39
-
40
-	// ErrorCodeUnpauseContainer is generated when we attempt to stop a
41
-	// container but its paused.
42
-	ErrorCodeUnpauseContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
43
-		Value:          "UNPAUSECONTAINER",
44
-		Message:        "Container %s is paused. Unpause the container before stopping",
45
-		Description:    "The specified container is paused, before it can be stopped it must be unpaused",
46
-		HTTPStatusCode: http.StatusInternalServerError,
47
-	})
48
-
49
-	// ErrorCodeRemovalContainer is generated when we attempt to connect or disconnect a
50
-	// container but it's marked for removal.
51
-	ErrorCodeRemovalContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
52
-		Value:          "REMOVALCONTAINER",
53
-		Message:        "Container %s is marked for removal and cannot be connected or disconnected to the network",
54
-		Description:    "The specified container is marked for removal and cannot be connected or disconnected to the network",
55
-		HTTPStatusCode: http.StatusInternalServerError,
56
-	})
57
-
58
-	// ErrorCodePausedContainer is generated when we attempt to attach a
59
-	// container but its paused.
60
-	ErrorCodePausedContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
61
-		Value:          "CONTAINERPAUSED",
62
-		Message:        "Container %s is paused. Unpause the container before attach",
63
-		Description:    "The specified container is paused, unpause the container before attach",
64
-		HTTPStatusCode: http.StatusConflict,
65
-	})
66
-	// ErrorCodeAlreadyPaused is generated when we attempt to pause a
67
-	// container when its already paused.
68
-	ErrorCodeAlreadyPaused = errcode.Register(errGroup, errcode.ErrorDescriptor{
69
-		Value:          "ALREADYPAUSED",
70
-		Message:        "Container %s is already paused",
71
-		Description:    "The specified container is already in the paused state",
72
-		HTTPStatusCode: http.StatusInternalServerError,
73
-	})
74
-
75
-	// ErrorCodeNotPaused is generated when we attempt to unpause a
76
-	// container when its not paused.
77
-	ErrorCodeNotPaused = errcode.Register(errGroup, errcode.ErrorDescriptor{
78
-		Value:          "NOTPAUSED",
79
-		Message:        "Container %s is not paused",
80
-		Description:    "The specified container can not be unpaused because it is not in a paused state",
81
-		HTTPStatusCode: http.StatusInternalServerError,
82
-	})
83
-
84
-	// ErrorCodeImageUnregContainer is generated when we attempt to get the
85
-	// image of an unknown/unregistered container.
86
-	ErrorCodeImageUnregContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
87
-		Value:          "IMAGEUNREGCONTAINER",
88
-		Message:        "Can't get image of unregistered container",
89
-		Description:    "An attempt to retrieve the image of a container was made but the container is not registered",
90
-		HTTPStatusCode: http.StatusInternalServerError,
91
-	})
92
-
93
-	// ErrorCodeEmptyID is generated when an ID is the empty string.
94
-	ErrorCodeEmptyID = errcode.Register(errGroup, errcode.ErrorDescriptor{
95
-		Value:          "EMPTYID",
96
-		Message:        "Invalid empty id",
97
-		Description:    "An attempt was made to register a container but the container's ID can not be an empty string",
98
-		HTTPStatusCode: http.StatusInternalServerError,
99
-	})
100
-
101
-	// ErrorCodeLoggingFactory is generated when we could not load the
102
-	// log driver.
103
-	ErrorCodeLoggingFactory = errcode.Register(errGroup, errcode.ErrorDescriptor{
104
-		Value:          "LOGGINGFACTORY",
105
-		Message:        "Failed to get logging factory: %v",
106
-		Description:    "An attempt was made to register a container but the container's ID can not be an empty string",
107
-		HTTPStatusCode: http.StatusInternalServerError,
108
-	})
109
-
110
-	// ErrorCodeInitLogger is generated when we could not initialize
111
-	// the logging driver.
112
-	ErrorCodeInitLogger = errcode.Register(errGroup, errcode.ErrorDescriptor{
113
-		Value:          "INITLOGGER",
114
-		Message:        "Failed to initialize logging driver: %v",
115
-		Description:    "An error occurred while trying to initialize the logging driver",
116
-		HTTPStatusCode: http.StatusInternalServerError,
117
-	})
118
-
119
-	// ErrorCodeNotRunning is generated when we need to verify that
120
-	// a container is running, but its not.
121
-	ErrorCodeNotRunning = errcode.Register(errGroup, errcode.ErrorDescriptor{
122
-		Value:          "NOTRUNNING",
123
-		Message:        "Container %s is not running",
124
-		Description:    "The specified action can not be taken due to the container not being in a running state",
125
-		HTTPStatusCode: http.StatusInternalServerError,
126
-	})
127
-
128
-	// ErrorCodeLinkNotRunning is generated when we try to link to a
129
-	// container that is not running.
130
-	ErrorCodeLinkNotRunning = errcode.Register(errGroup, errcode.ErrorDescriptor{
131
-		Value:          "LINKNOTRUNNING",
132
-		Message:        "Cannot link to a non running container: %s AS %s",
133
-		Description:    "An attempt was made to link to a container but the container is not in a running state",
134
-		HTTPStatusCode: http.StatusInternalServerError,
135
-	})
136
-
137
-	// ErrorCodeDeviceInfo is generated when there is an error while trying
138
-	// to get info about a custom device.
139
-	// container that is not running.
140
-	ErrorCodeDeviceInfo = errcode.Register(errGroup, errcode.ErrorDescriptor{
141
-		Value:          "DEVICEINFO",
142
-		Message:        "error gathering device information while adding custom device %q: %s",
143
-		Description:    "There was an error while trying to retrieve the information about a custom device",
144
-		HTTPStatusCode: http.StatusInternalServerError,
145
-	})
146
-
147
-	// ErrorCodeEmptyEndpoint is generated when the endpoint for a port
148
-	// map is nil.
149
-	ErrorCodeEmptyEndpoint = errcode.Register(errGroup, errcode.ErrorDescriptor{
150
-		Value:          "EMPTYENDPOINT",
151
-		Message:        "invalid endpoint while building port map info",
152
-		Description:    "The specified endpoint for the port mapping is empty",
153
-		HTTPStatusCode: http.StatusInternalServerError,
154
-	})
155
-
156
-	// ErrorCodeEmptyNetwork is generated when the networkSettings for a port
157
-	// map is nil.
158
-	ErrorCodeEmptyNetwork = errcode.Register(errGroup, errcode.ErrorDescriptor{
159
-		Value:          "EMPTYNETWORK",
160
-		Message:        "invalid network settings while building port map info",
161
-		Description:    "The specified endpoint for the port mapping is empty",
162
-		HTTPStatusCode: http.StatusInternalServerError,
163
-	})
164
-
165
-	// ErrorCodeParsingPort is generated when there is an error parsing
166
-	// a "port" string.
167
-	ErrorCodeParsingPort = errcode.Register(errGroup, errcode.ErrorDescriptor{
168
-		Value:          "PARSINGPORT",
169
-		Message:        "Error parsing Port value(%v):%v",
170
-		Description:    "There was an error while trying to parse the specified 'port' value",
171
-		HTTPStatusCode: http.StatusInternalServerError,
172
-	})
173
-
174
-	// ErrorCodeNoSandbox is generated when we can't find the specified
175
-	// sandbox(network) by ID.
176
-	ErrorCodeNoSandbox = errcode.Register(errGroup, errcode.ErrorDescriptor{
177
-		Value:          "NOSANDBOX",
178
-		Message:        "error locating sandbox id %s: %v",
179
-		Description:    "There was an error trying to located the specified networking sandbox",
180
-		HTTPStatusCode: http.StatusInternalServerError,
181
-	})
182
-
183
-	// ErrorCodeNetworkUpdate is generated when there is an error while
184
-	// trying update a network/sandbox config.
185
-	ErrorCodeNetworkUpdate = errcode.Register(errGroup, errcode.ErrorDescriptor{
186
-		Value:          "NETWORKUPDATE",
187
-		Message:        "Update network failed: %v",
188
-		Description:    "There was an error trying to update the configuration information of the specified network sandbox",
189
-		HTTPStatusCode: http.StatusInternalServerError,
190
-	})
191
-
192
-	// ErrorCodeNetworkRefresh is generated when there is an error while
193
-	// trying refresh a network/sandbox config.
194
-	ErrorCodeNetworkRefresh = errcode.Register(errGroup, errcode.ErrorDescriptor{
195
-		Value:          "NETWORKREFRESH",
196
-		Message:        "Update network failed: Failure in refresh sandbox %s: %v",
197
-		Description:    "There was an error trying to refresh the configuration information of the specified network sandbox",
198
-		HTTPStatusCode: http.StatusInternalServerError,
199
-	})
200
-
201
-	// ErrorCodeHostPort is generated when there was an error while trying
202
-	// to parse a "host/port" string.
203
-	ErrorCodeHostPort = errcode.Register(errGroup, errcode.ErrorDescriptor{
204
-		Value:          "HOSTPORT",
205
-		Message:        "Error parsing HostPort value(%s):%v",
206
-		Description:    "There was an error trying to parse the specified 'HostPort' value",
207
-		HTTPStatusCode: http.StatusInternalServerError,
208
-	})
209
-
210
-	// ErrorCodeNetworkConflict is generated when we try to publish a service
211
-	// in network mode.
212
-	ErrorCodeNetworkConflict = errcode.Register(errGroup, errcode.ErrorDescriptor{
213
-		Value:          "NETWORKCONFLICT",
214
-		Message:        "conflicting options: publishing a service and network mode",
215
-		Description:    "It is not possible to publish a service when it is in network mode",
216
-		HTTPStatusCode: http.StatusConflict,
217
-	})
218
-
219
-	// ErrorCodeJoinInfo is generated when we failed to update a container's
220
-	// join info.
221
-	ErrorCodeJoinInfo = errcode.Register(errGroup, errcode.ErrorDescriptor{
222
-		Value:          "JOININFO",
223
-		Message:        "Updating join info failed: %v",
224
-		Description:    "There was an error during an attempt update a container's join information",
225
-		HTTPStatusCode: http.StatusInternalServerError,
226
-	})
227
-
228
-	// ErrorCodeIPCRunning is generated when we try to join a container's
229
-	// IPC but it's not running.
230
-	ErrorCodeIPCRunning = errcode.Register(errGroup, errcode.ErrorDescriptor{
231
-		Value:          "IPCRUNNING",
232
-		Message:        "cannot join IPC of a non running container: %s",
233
-		Description:    "An attempt was made to join the IPC of a container, but the container is not running",
234
-		HTTPStatusCode: http.StatusConflict,
235
-	})
236
-
237
-	// ErrorCodeNotADir is generated when we try to create a directory
238
-	// but the path isn't a dir.
239
-	ErrorCodeNotADir = errcode.Register(errGroup, errcode.ErrorDescriptor{
240
-		Value:          "NOTADIR",
241
-		Message:        "Cannot mkdir: %s is not a directory",
242
-		Description:    "An attempt was made create a directory, but the location in which it is being created is not a directory",
243
-		HTTPStatusCode: http.StatusInternalServerError,
244
-	})
245
-
246
-	// ErrorCodeParseContainer is generated when the reference to a
247
-	// container doesn't include a ":" (another container).
248
-	ErrorCodeParseContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
249
-		Value:          "PARSECONTAINER",
250
-		Message:        "no container specified to join network",
251
-		Description:    "The specified reference to a container is missing a ':' as a separator between 'container' and 'name'/'id'",
252
-		HTTPStatusCode: http.StatusInternalServerError,
253
-	})
254
-
255
-	// ErrorCodeJoinSelf is generated when we try to network to ourselves.
256
-	ErrorCodeJoinSelf = errcode.Register(errGroup, errcode.ErrorDescriptor{
257
-		Value:          "JOINSELF",
258
-		Message:        "cannot join own network",
259
-		Description:    "An attempt was made to have a container join its own network",
260
-		HTTPStatusCode: http.StatusInternalServerError,
261
-	})
262
-
263
-	// ErrorCodeJoinRunning is generated when we try to network to ourselves.
264
-	ErrorCodeJoinRunning = errcode.Register(errGroup, errcode.ErrorDescriptor{
265
-		Value:          "JOINRUNNING",
266
-		Message:        "cannot join network of a non running container: %s",
267
-		Description:    "An attempt to join the network of a container, but that container isn't running",
268
-		HTTPStatusCode: http.StatusConflict,
269
-	})
270
-
271
-	// ErrorCodeModeNotContainer is generated when we try to network to
272
-	// another container but the mode isn't 'container'.
273
-	ErrorCodeModeNotContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
274
-		Value:          "MODENOTCONTAINER",
275
-		Message:        "network mode not set to container",
276
-		Description:    "An attempt was made to connect to a container's network but the mode wasn't set to 'container'",
277
-		HTTPStatusCode: http.StatusInternalServerError,
278
-	})
279
-
280
-	// ErrorCodeRemovingVolume is generated when we try remove a mount
281
-	// point (volume) but fail.
282
-	ErrorCodeRemovingVolume = errcode.Register(errGroup, errcode.ErrorDescriptor{
283
-		Value:          "REMOVINGVOLUME",
284
-		Message:        "Error removing volumes:\n%v",
285
-		Description:    "There was an error while trying to remove the mount point (volume) of a container",
286
-		HTTPStatusCode: http.StatusInternalServerError,
287
-	})
288
-
289
-	// ErrorCodeInvalidNetworkMode is generated when an invalid network
290
-	// mode value is specified.
291
-	ErrorCodeInvalidNetworkMode = errcode.Register(errGroup, errcode.ErrorDescriptor{
292
-		Value:          "INVALIDNETWORKMODE",
293
-		Message:        "invalid network mode: %s",
294
-		Description:    "The specified networking mode is not valid",
295
-		HTTPStatusCode: http.StatusInternalServerError,
296
-	})
297
-
298
-	// ErrorCodeGetGraph is generated when there was an error while
299
-	// trying to find a graph/image.
300
-	ErrorCodeGetGraph = errcode.Register(errGroup, errcode.ErrorDescriptor{
301
-		Value:          "GETGRAPH",
302
-		Message:        "Failed to graph.Get on ImageID %s - %s",
303
-		Description:    "There was an error trying to retrieve the image for the specified image ID",
304
-		HTTPStatusCode: http.StatusInternalServerError,
305
-	})
306
-
307
-	// ErrorCodeGetLayer is generated when there was an error while
308
-	// trying to retrieve a particular layer of an image.
309
-	ErrorCodeGetLayer = errcode.Register(errGroup, errcode.ErrorDescriptor{
310
-		Value:          "GETLAYER",
311
-		Message:        "Failed to get layer path from graphdriver %s for ImageID %s - %s",
312
-		Description:    "There was an error trying to retrieve the layer of the specified image",
313
-		HTTPStatusCode: http.StatusInternalServerError,
314
-	})
315
-
316
-	// ErrorCodePutLayer is generated when there was an error while
317
-	// trying to 'put' a particular layer of an image.
318
-	ErrorCodePutLayer = errcode.Register(errGroup, errcode.ErrorDescriptor{
319
-		Value:          "PUTLAYER",
320
-		Message:        "Failed to put layer path from graphdriver %s for ImageID %s - %s",
321
-		Description:    "There was an error trying to store a layer for the specified image",
322
-		HTTPStatusCode: http.StatusInternalServerError,
323
-	})
324
-
325
-	// ErrorCodeGetLayerMetadata is generated when there was an error while
326
-	// trying to retrieve the metadata of a layer of an image.
327
-	ErrorCodeGetLayerMetadata = errcode.Register(errGroup, errcode.ErrorDescriptor{
328
-		Value:          "GETLAYERMETADATA",
329
-		Message:        "Failed to get layer metadata - %s",
330
-		Description:    "There was an error trying to retrieve the metadata of a layer for the specified image",
331
-		HTTPStatusCode: http.StatusInternalServerError,
332
-	})
333
-
334
-	// ErrorCodeEmptyConfig is generated when the input config data
335
-	// is empty.
336
-	ErrorCodeEmptyConfig = errcode.Register(errGroup, errcode.ErrorDescriptor{
337
-		Value:          "EMPTYCONFIG",
338
-		Message:        "Config cannot be empty in order to create a container",
339
-		Description:    "While trying to create a container, the specified configuration information was empty",
340
-		HTTPStatusCode: http.StatusInternalServerError,
341
-	})
342
-
343
-	// ErrorCodeNoSuchImageHash is generated when we can't find the
344
-	// specified image by its hash
345
-	ErrorCodeNoSuchImageHash = errcode.Register(errGroup, errcode.ErrorDescriptor{
346
-		Value:          "NOSUCHIMAGEHASH",
347
-		Message:        "No such image: %s",
348
-		Description:    "An attempt was made to find an image by its hash, but the lookup failed",
349
-		HTTPStatusCode: http.StatusNotFound,
350
-	})
351
-
352
-	// ErrorCodeNoSuchImageTag is generated when we can't find the
353
-	// specified image byt its name/tag.
354
-	ErrorCodeNoSuchImageTag = errcode.Register(errGroup, errcode.ErrorDescriptor{
355
-		Value:          "NOSUCHIMAGETAG",
356
-		Message:        "No such image: %s:%s",
357
-		Description:    "An attempt was made to find an image by its name/tag, but the lookup failed",
358
-		HTTPStatusCode: http.StatusNotFound,
359
-	})
360
-
361
-	// ErrorCodeMountOverFile is generated when we try to mount a volume
362
-	// over an existing file (but not a dir).
363
-	ErrorCodeMountOverFile = errcode.Register(errGroup, errcode.ErrorDescriptor{
364
-		Value:          "MOUNTOVERFILE",
365
-		Message:        "cannot mount volume over existing file, file exists %s",
366
-		Description:    "An attempt was made to mount a volume at the same location as a pre-existing file",
367
-		HTTPStatusCode: http.StatusInternalServerError,
368
-	})
369
-
370
-	// ErrorCodeMountSetup is generated when we can't define a mount point
371
-	// due to the source and destination being undefined.
372
-	ErrorCodeMountSetup = errcode.Register(errGroup, errcode.ErrorDescriptor{
373
-		Value:          "MOUNTSETUP",
374
-		Message:        "Unable to setup mount point, neither source nor volume defined",
375
-		Description:    "An attempt was made to setup a mount point, but the source and destination are undefined",
376
-		HTTPStatusCode: http.StatusInternalServerError,
377
-	})
378
-
379
-	// ErrorCodeVolumeInvalidMode is generated when the mode of a volume/bind
380
-	// mount is invalid.
381
-	ErrorCodeVolumeInvalidMode = errcode.Register(errGroup, errcode.ErrorDescriptor{
382
-		Value:          "VOLUMEINVALIDMODE",
383
-		Message:        "invalid mode: %q",
384
-		Description:    "An invalid 'mode' was specified",
385
-		HTTPStatusCode: http.StatusInternalServerError,
386
-	})
387
-
388
-	// ErrorCodeVolumeInvalid is generated when the format fo the
389
-	// volume specification isn't valid.
390
-	ErrorCodeVolumeInvalid = errcode.Register(errGroup, errcode.ErrorDescriptor{
391
-		Value:          "VOLUMEINVALID",
392
-		Message:        "Invalid volume specification: '%s'",
393
-		Description:    "An invalid 'volume' was specified in the mount request",
394
-		HTTPStatusCode: http.StatusInternalServerError,
395
-	})
396
-
397
-	// ErrorCodeVolumeAbs is generated when path to a volume isn't absolute.
398
-	ErrorCodeVolumeAbs = errcode.Register(errGroup, errcode.ErrorDescriptor{
399
-		Value:          "VOLUMEABS",
400
-		Message:        "Invalid volume destination path: '%s' mount path must be absolute.",
401
-		Description:    "An invalid 'destination' path was specified in the mount request, it must be an absolute path",
402
-		HTTPStatusCode: http.StatusInternalServerError,
403
-	})
404
-
405
-	// ErrorCodeVolumeName is generated when the name of named volume isn't valid.
406
-	ErrorCodeVolumeName = errcode.Register(errGroup, errcode.ErrorDescriptor{
407
-		Value:          "VOLUME_NAME_INVALID",
408
-		Message:        "%q includes invalid characters for a local volume name, only %q are allowed",
409
-		Description:    "The name of volume is invalid",
410
-		HTTPStatusCode: http.StatusBadRequest,
411
-	})
412
-
413
-	// ErrorCodeVolumeSlash is generated when destination path to a volume is /
414
-	ErrorCodeVolumeSlash = errcode.Register(errGroup, errcode.ErrorDescriptor{
415
-		Value:          "VOLUMESLASH",
416
-		Message:        "Invalid specification: destination can't be '/' in '%s'",
417
-		HTTPStatusCode: http.StatusInternalServerError,
418
-	})
419
-
420
-	// ErrorCodeVolumeDestIsC is generated the destination is c: (Windows specific)
421
-	ErrorCodeVolumeDestIsC = errcode.Register(errGroup, errcode.ErrorDescriptor{
422
-		Value:          "VOLUMEDESTISC",
423
-		Message:        "Destination drive letter in '%s' cannot be c:",
424
-		HTTPStatusCode: http.StatusInternalServerError,
425
-	})
426
-
427
-	// ErrorCodeVolumeDestIsCRoot is generated the destination path is c:\ (Windows specific)
428
-	ErrorCodeVolumeDestIsCRoot = errcode.Register(errGroup, errcode.ErrorDescriptor{
429
-		Value:          "VOLUMEDESTISCROOT",
430
-		Message:        `Destination path in '%s' cannot be c:\`,
431
-		HTTPStatusCode: http.StatusInternalServerError,
432
-	})
433
-
434
-	// ErrorCodeVolumeSourceNotFound is generated the source directory could not be found (Windows specific)
435
-	ErrorCodeVolumeSourceNotFound = errcode.Register(errGroup, errcode.ErrorDescriptor{
436
-		Value:          "VOLUMESOURCENOTFOUND",
437
-		Message:        "Source directory '%s' could not be found: %s",
438
-		HTTPStatusCode: http.StatusInternalServerError,
439
-	})
440
-
441
-	// ErrorCodeVolumeSourceNotDirectory is generated the source is not a directory (Windows specific)
442
-	ErrorCodeVolumeSourceNotDirectory = errcode.Register(errGroup, errcode.ErrorDescriptor{
443
-		Value:          "VOLUMESOURCENOTDIRECTORY",
444
-		Message:        "Source '%s' is not a directory",
445
-		HTTPStatusCode: http.StatusInternalServerError,
446
-	})
447
-
448
-	// ErrorCodeVolumeFromBlank is generated when path to a volume is blank.
449
-	ErrorCodeVolumeFromBlank = errcode.Register(errGroup, errcode.ErrorDescriptor{
450
-		Value:          "VOLUMEFROMBLANK",
451
-		Message:        "malformed volumes-from specification: %q",
452
-		Description:    "An invalid 'destination' path was specified in the mount request, it must not be blank",
453
-		HTTPStatusCode: http.StatusInternalServerError,
454
-	})
455
-
456
-	// ErrorCodeMountDup is generated when we try to mount two mounts points
457
-	// to the same path.
458
-	ErrorCodeMountDup = errcode.Register(errGroup, errcode.ErrorDescriptor{
459
-		Value:          "MOUNTDUP",
460
-		Message:        "Duplicate mount point '%s'",
461
-		Description:    "An attempt was made to mount a content but the specified destination location is already used in a previous mount",
462
-		HTTPStatusCode: http.StatusInternalServerError,
463
-	})
464
-
465
-	// ErrorCodeVolumeNoSourceForMount is generated when no source directory
466
-	// for a volume mount was found. (Windows specific)
467
-	ErrorCodeVolumeNoSourceForMount = errcode.Register(errGroup, errcode.ErrorDescriptor{
468
-		Value:          "VOLUMENOSOURCEFORMOUNT",
469
-		Message:        "No source for mount name '%s' driver %q destination '%s'",
470
-		HTTPStatusCode: http.StatusInternalServerError,
471
-	})
472
-
473
-	// ErrorCodeVolumeNameReservedWord is generated when the name in a volume
474
-	// uses a reserved word for filenames. (Windows specific)
475
-	ErrorCodeVolumeNameReservedWord = errcode.Register(errGroup, errcode.ErrorDescriptor{
476
-		Value:          "VOLUMENAMERESERVEDWORD",
477
-		Message:        "Volume name %q cannot be a reserved word for Windows filenames",
478
-		HTTPStatusCode: http.StatusInternalServerError,
479
-	})
480
-
481
-	// ErrorCodeCantPause is generated when there's an error while trying
482
-	// to pause a container.
483
-	ErrorCodeCantPause = errcode.Register(errGroup, errcode.ErrorDescriptor{
484
-		Value:          "CANTPAUSE",
485
-		Message:        "Cannot pause container %s: %s",
486
-		Description:    "An error occurred while trying to pause the specified container",
487
-		HTTPStatusCode: http.StatusInternalServerError,
488
-	})
489
-
490
-	// ErrorCodeCantUnpause is generated when there's an error while trying
491
-	// to unpause a container.
492
-	ErrorCodeCantUnpause = errcode.Register(errGroup, errcode.ErrorDescriptor{
493
-		Value:          "CANTUNPAUSE",
494
-		Message:        "Cannot unpause container %s: %s",
495
-		Description:    "An error occurred while trying to unpause the specified container",
496
-		HTTPStatusCode: http.StatusInternalServerError,
497
-	})
498
-
499
-	// ErrorCodeCantKill is generated when there's an error while trying
500
-	// to kill a container.
501
-	ErrorCodeCantKill = errcode.Register(errGroup, errcode.ErrorDescriptor{
502
-		Value:          "CANTKILL",
503
-		Message:        "Cannot kill container %s: %s",
504
-		Description:    "An error occurred while trying to kill the specified container",
505
-		HTTPStatusCode: http.StatusInternalServerError,
506
-	})
507
-
508
-	// ErrorCodeCantUpdate is generated when there's an error while trying
509
-	// to update a container.
510
-	ErrorCodeCantUpdate = errcode.Register(errGroup, errcode.ErrorDescriptor{
511
-		Value:          "CANTUPDATE",
512
-		Message:        "Cannot update container %s: %s",
513
-		Description:    "An error occurred while trying to update the specified container",
514
-		HTTPStatusCode: http.StatusInternalServerError,
515
-	})
516
-	// ErrorCodePSError is generated when trying to run 'ps'.
517
-	ErrorCodePSError = errcode.Register(errGroup, errcode.ErrorDescriptor{
518
-		Value:          "PSError",
519
-		Message:        "Error running ps: %s",
520
-		Description:    "There was an error trying to run the 'ps' command in the specified container",
521
-		HTTPStatusCode: http.StatusInternalServerError,
522
-	})
523
-
524
-	// ErrorCodeNoPID is generated when looking for the PID field in the
525
-	// ps output.
526
-	ErrorCodeNoPID = errcode.Register(errGroup, errcode.ErrorDescriptor{
527
-		Value:          "NOPID",
528
-		Message:        "Couldn't find PID field in ps output",
529
-		Description:    "There was no 'PID' field in the output of the 'ps' command that was executed",
530
-		HTTPStatusCode: http.StatusInternalServerError,
531
-	})
532
-
533
-	// ErrorCodeBadPID is generated when we can't convert a PID to an int.
534
-	ErrorCodeBadPID = errcode.Register(errGroup, errcode.ErrorDescriptor{
535
-		Value:          "BADPID",
536
-		Message:        "Unexpected pid '%s': %s",
537
-		Description:    "While trying to parse the output of the 'ps' command, the 'PID' field was not an integer",
538
-		HTTPStatusCode: http.StatusInternalServerError,
539
-	})
540
-
541
-	// ErrorCodeNoTop is generated when we try to run 'top' but can't
542
-	// because we're on windows.
543
-	ErrorCodeNoTop = errcode.Register(errGroup, errcode.ErrorDescriptor{
544
-		Value:          "NOTOP",
545
-		Message:        "Top is not supported on Windows",
546
-		Description:    "The 'top' command is not supported on Windows",
547
-		HTTPStatusCode: http.StatusInternalServerError,
548
-	})
549
-
550
-	// ErrorCodeStopped is generated when we try to stop a container
551
-	// that is already stopped.
552
-	ErrorCodeStopped = errcode.Register(errGroup, errcode.ErrorDescriptor{
553
-		Value:          "STOPPED",
554
-		Message:        "Container %s is already stopped",
555
-		Description:    "An attempt was made to stop a container, but the container is already stopped",
556
-		HTTPStatusCode: http.StatusNotModified,
557
-	})
558
-
559
-	// ErrorCodeCantStop is generated when we try to stop a container
560
-	// but failed for some reason.
561
-	ErrorCodeCantStop = errcode.Register(errGroup, errcode.ErrorDescriptor{
562
-		Value:          "CANTSTOP",
563
-		Message:        "Cannot stop container %s: %s\n",
564
-		Description:    "An error occurred while tring to stop the specified container",
565
-		HTTPStatusCode: http.StatusInternalServerError,
566
-	})
567
-
568
-	// ErrorCodeBadCPUFields is generated when the number of CPU fields is
569
-	// less than 8.
570
-	ErrorCodeBadCPUFields = errcode.Register(errGroup, errcode.ErrorDescriptor{
571
-		Value:          "BADCPUFIELDS",
572
-		Message:        "invalid number of cpu fields",
573
-		Description:    "While reading the '/proc/stat' file, the number of 'cpu' fields is less than 8",
574
-		HTTPStatusCode: http.StatusInternalServerError,
575
-	})
576
-
577
-	// ErrorCodeBadCPUInt is generated the CPU field can't be parsed as an int.
578
-	ErrorCodeBadCPUInt = errcode.Register(errGroup, errcode.ErrorDescriptor{
579
-		Value:          "BADCPUINT",
580
-		Message:        "Unable to convert value %s to int: %s",
581
-		Description:    "While reading the '/proc/stat' file, the 'CPU' field could not be parsed as an integer",
582
-		HTTPStatusCode: http.StatusInternalServerError,
583
-	})
584
-
585
-	// ErrorCodeBadStatFormat is generated the output of the stat info
586
-	// isn't parseable.
587
-	ErrorCodeBadStatFormat = errcode.Register(errGroup, errcode.ErrorDescriptor{
588
-		Value:          "BADSTATFORMAT",
589
-		Message:        "invalid stat format",
590
-		Description:    "There was an error trying to parse the '/proc/stat' file",
591
-		HTTPStatusCode: http.StatusInternalServerError,
592
-	})
593
-
594
-	// ErrorCodeTimedOut is generated when a timer expires.
595
-	ErrorCodeTimedOut = errcode.Register(errGroup, errcode.ErrorDescriptor{
596
-		Value:          "TIMEDOUT",
597
-		Message:        "Timed out: %v",
598
-		Description:    "A timer expired",
599
-		HTTPStatusCode: http.StatusInternalServerError,
600
-	})
601
-
602
-	// ErrorCodeAlreadyRemoving is generated when we try to remove a
603
-	// container that is already being removed.
604
-	ErrorCodeAlreadyRemoving = errcode.Register(errGroup, errcode.ErrorDescriptor{
605
-		Value:          "ALREADYREMOVING",
606
-		Message:        "Status is already RemovalInProgress",
607
-		Description:    "An attempt to remove a container was made, but the container is already in the process of being removed",
608
-		HTTPStatusCode: http.StatusInternalServerError,
609
-	})
610
-
611
-	// ErrorCodeStartPaused is generated when we start a paused container.
612
-	ErrorCodeStartPaused = errcode.Register(errGroup, errcode.ErrorDescriptor{
613
-		Value:          "STARTPAUSED",
614
-		Message:        "Cannot start a paused container, try unpause instead.",
615
-		Description:    "An attempt to start a container was made, but the container is paused. Unpause it first",
616
-		HTTPStatusCode: http.StatusInternalServerError,
617
-	})
618
-
619
-	// ErrorCodeAlreadyStarted is generated when we try to start a container
620
-	// that is already running.
621
-	ErrorCodeAlreadyStarted = errcode.Register(errGroup, errcode.ErrorDescriptor{
622
-		Value:          "ALREADYSTARTED",
623
-		Message:        "Container already started",
624
-		Description:    "An attempt to start a container was made, but the container is already started",
625
-		HTTPStatusCode: http.StatusNotModified,
626
-	})
627
-
628
-	// ErrorCodeHostConfigStart is generated when a HostConfig is passed
629
-	// into the start command.
630
-	ErrorCodeHostConfigStart = errcode.Register(errGroup, errcode.ErrorDescriptor{
631
-		Value:          "HOSTCONFIGSTART",
632
-		Message:        "Supplying a hostconfig on start is not supported. It should be supplied on create",
633
-		Description:    "The 'start' command does not accept 'HostConfig' data, try using the 'create' command instead",
634
-		HTTPStatusCode: http.StatusInternalServerError,
635
-	})
636
-
637
-	// ErrorCodeCantRestart is generated when an error occurred while
638
-	// trying to restart a container.
639
-	ErrorCodeCantRestart = errcode.Register(errGroup, errcode.ErrorDescriptor{
640
-		Value:          "CANTRESTART",
641
-		Message:        "Cannot restart container %s: %s",
642
-		Description:    "There was an error while trying to restart a container",
643
-		HTTPStatusCode: http.StatusInternalServerError,
644
-	})
645
-
646
-	// ErrorCodeEmptyRename is generated when one of the names on a
647
-	// rename is empty.
648
-	ErrorCodeEmptyRename = errcode.Register(errGroup, errcode.ErrorDescriptor{
649
-		Value:          "EMPTYRENAME",
650
-		Message:        "Neither old nor new names may be empty",
651
-		Description:    "An attempt was made to rename a container but either the old or new names were blank",
652
-		HTTPStatusCode: http.StatusInternalServerError,
653
-	})
654
-
655
-	// ErrorCodeRenameTaken is generated when we try to rename but the
656
-	// new name isn't available.
657
-	ErrorCodeRenameTaken = errcode.Register(errGroup, errcode.ErrorDescriptor{
658
-		Value:          "RENAMETAKEN",
659
-		Message:        "Error when allocating new name: %s",
660
-		Description:    "The new name specified on the 'rename' command is already being used",
661
-		HTTPStatusCode: http.StatusInternalServerError,
662
-	})
663
-
664
-	// ErrorCodeRenameDelete is generated when we try to rename but
665
-	// failed trying to delete the old container.
666
-	ErrorCodeRenameDelete = errcode.Register(errGroup, errcode.ErrorDescriptor{
667
-		Value:          "RENAMEDELETE",
668
-		Message:        "Failed to delete container %q: %v",
669
-		Description:    "There was an error trying to delete the specified container",
670
-		HTTPStatusCode: http.StatusInternalServerError,
671
-	})
672
-
673
-	// ErrorCodePauseError is generated when we try to pause a container
674
-	// but failed.
675
-	ErrorCodePauseError = errcode.Register(errGroup, errcode.ErrorDescriptor{
676
-		Value:          "PAUSEERROR",
677
-		Message:        "Cannot pause container %s: %s",
678
-		Description:    "There was an error trying to pause the specified container",
679
-		HTTPStatusCode: http.StatusInternalServerError,
680
-	})
681
-
682
-	// ErrorCodeNeedStream is generated when we try to stream a container's
683
-	// logs but no output stream was specified.
684
-	ErrorCodeNeedStream = errcode.Register(errGroup, errcode.ErrorDescriptor{
685
-		Value:          "NEEDSTREAM",
686
-		Message:        "You must choose at least one stream",
687
-		Description:    "While trying to stream a container's logs, no output stream was specified",
688
-		HTTPStatusCode: http.StatusInternalServerError,
689
-	})
690
-
691
-	// ErrorCodeDanglingOne is generated when we try to specify more than one
692
-	// 'dangling' specifier.
693
-	ErrorCodeDanglingOne = errcode.Register(errGroup, errcode.ErrorDescriptor{
694
-		Value:          "DANLGINGONE",
695
-		Message:        "Conflict: cannot use more than 1 value for `dangling` filter",
696
-		Description:    "The specified 'dangling' filter may not have more than one value",
697
-		HTTPStatusCode: http.StatusConflict,
698
-	})
699
-
700
-	// ErrorCodeImgDelUsed is generated when we try to delete an image
701
-	// but it is being used.
702
-	ErrorCodeImgDelUsed = errcode.Register(errGroup, errcode.ErrorDescriptor{
703
-		Value:          "IMGDELUSED",
704
-		Message:        "conflict: unable to remove repository reference %q (must force) - container %s is using its referenced image %s",
705
-		Description:    "An attempt was made to delete an image but it is currently being used",
706
-		HTTPStatusCode: http.StatusConflict,
707
-	})
708
-
709
-	// ErrorCodeImgNoParent is generated when we try to find an image's
710
-	// parent but its not in the graph.
711
-	ErrorCodeImgNoParent = errcode.Register(errGroup, errcode.ErrorDescriptor{
712
-		Value:          "IMGNOPARENT",
713
-		Message:        "unable to get parent image: %v",
714
-		Description:    "There was an error trying to find an image's parent, it was not in the graph",
715
-		HTTPStatusCode: http.StatusInternalServerError,
716
-	})
717
-
718
-	// ErrorCodeExportFailed is generated when an export fails.
719
-	ErrorCodeExportFailed = errcode.Register(errGroup, errcode.ErrorDescriptor{
720
-		Value:          "EXPORTFAILED",
721
-		Message:        "%s: %s",
722
-		Description:    "There was an error during an export operation",
723
-		HTTPStatusCode: http.StatusInternalServerError,
724
-	})
725
-
726
-	// ErrorCodeExecResize is generated when we try to resize an exec
727
-	// but its not running.
728
-	ErrorCodeExecResize = errcode.Register(errGroup, errcode.ErrorDescriptor{
729
-		Value:          "EXECRESIZE",
730
-		Message:        "Exec %s is not running, so it can not be resized.",
731
-		Description:    "An attempt was made to resize an 'exec', but the 'exec' is not running",
732
-		HTTPStatusCode: http.StatusInternalServerError,
733
-	})
734
-
735
-	// ErrorCodeContainerNotRunning is generated when we try to get the info
736
-	// on an exec but the container is not running.
737
-	ErrorCodeContainerNotRunning = errcode.Register(errGroup, errcode.ErrorDescriptor{
738
-		Value:          "CONTAINERNOTRUNNING",
739
-		Message:        "Container %s is not running: %s",
740
-		Description:    "An attempt was made to retrieve the information about an 'exec' but the container is not running",
741
-		HTTPStatusCode: http.StatusConflict,
742
-	})
743
-
744
-	// ErrorCodeContainerRestarting is generated when an operation was made
745
-	// on a restarting container.
746
-	ErrorCodeContainerRestarting = errcode.Register(errGroup, errcode.ErrorDescriptor{
747
-		Value:          "CONTAINERRESTARTING",
748
-		Message:        "Container %s is restarting, wait until the container is running",
749
-		Description:    "An operation was made on a restarting container",
750
-		HTTPStatusCode: http.StatusConflict,
751
-	})
752
-
753
-	// ErrorCodeNoExecID is generated when we try to get the info
754
-	// on an exec but it can't be found.
755
-	ErrorCodeNoExecID = errcode.Register(errGroup, errcode.ErrorDescriptor{
756
-		Value:          "NOEXECID",
757
-		Message:        "No such exec instance '%s' found in daemon",
758
-		Description:    "The specified 'exec' instance could not be found",
759
-		HTTPStatusCode: http.StatusNotFound,
760
-	})
761
-
762
-	// ErrorCodeExecPaused is generated when we try to start an exec
763
-	// but the container is paused.
764
-	ErrorCodeExecPaused = errcode.Register(errGroup, errcode.ErrorDescriptor{
765
-		Value:          "EXECPAUSED",
766
-		Message:        "Container %s is paused, unpause the container before exec",
767
-		Description:    "An attempt to start an 'exec' was made, but the owning container is paused",
768
-		HTTPStatusCode: http.StatusConflict,
769
-	})
770
-
771
-	// ErrorCodeExecRunning is generated when we try to start an exec
772
-	// but its already running.
773
-	ErrorCodeExecRunning = errcode.Register(errGroup, errcode.ErrorDescriptor{
774
-		Value:          "EXECRUNNING",
775
-		Message:        "Error: Exec command %s is already running",
776
-		Description:    "An attempt to start an 'exec' was made, but 'exec' is already running",
777
-		HTTPStatusCode: http.StatusInternalServerError,
778
-	})
779
-
780
-	// ErrorCodeExecExited is generated when we try to start an exec
781
-	// but its already running.
782
-	ErrorCodeExecExited = errcode.Register(errGroup, errcode.ErrorDescriptor{
783
-		Value:          "EXECEXITED",
784
-		Message:        "Error: Exec command %s has already run",
785
-		Description:    "An attempt to start an 'exec' was made, but 'exec' was already run",
786
-		HTTPStatusCode: http.StatusConflict,
787
-	})
788
-
789
-	// ErrorCodeExecCantRun is generated when we try to start an exec
790
-	// but it failed for some reason.
791
-	ErrorCodeExecCantRun = errcode.Register(errGroup, errcode.ErrorDescriptor{
792
-		Value:          "EXECCANTRUN",
793
-		Message:        "Cannot run exec command %s in container %s: %s",
794
-		Description:    "An attempt to start an 'exec' was made, but an error occurred",
795
-		HTTPStatusCode: http.StatusInternalServerError,
796
-	})
797
-
798
-	// ErrorCodeExecAttach is generated when we try to attach to an exec
799
-	// but failed.
800
-	ErrorCodeExecAttach = errcode.Register(errGroup, errcode.ErrorDescriptor{
801
-		Value:          "EXECATTACH",
802
-		Message:        "attach failed with error: %s",
803
-		Description:    "There was an error while trying to attach to an 'exec'",
804
-		HTTPStatusCode: http.StatusInternalServerError,
805
-	})
806
-
807
-	// ErrorCodeExecContainerStopped is generated when we try to start
808
-	// an exec but then the container stopped.
809
-	ErrorCodeExecContainerStopped = errcode.Register(errGroup, errcode.ErrorDescriptor{
810
-		Value:          "EXECCONTAINERSTOPPED",
811
-		Message:        "container stopped while running exec",
812
-		Description:    "An attempt was made to start an 'exec' but the owning container is in the 'stopped' state",
813
-		HTTPStatusCode: http.StatusInternalServerError,
814
-	})
815
-
816
-	// ErrorCodeDefaultName is generated when we try to delete the
817
-	// default name of a container.
818
-	ErrorCodeDefaultName = errcode.Register(errGroup, errcode.ErrorDescriptor{
819
-		Value:          "DEFAULTNAME",
820
-		Message:        "Conflict, cannot remove the default name of the container",
821
-		Description:    "An attempt to delete the default name of a container was made, but that is not allowed",
822
-		HTTPStatusCode: http.StatusConflict,
823
-	})
824
-
825
-	// ErrorCodeNoParent is generated when we try to delete a container
826
-	// but we can't find its parent image.
827
-	ErrorCodeNoParent = errcode.Register(errGroup, errcode.ErrorDescriptor{
828
-		Value:          "NOPARENT",
829
-		Message:        "Cannot get parent %s for name %s",
830
-		Description:    "An attempt was made to delete a container but its parent image could not be found",
831
-		HTTPStatusCode: http.StatusInternalServerError,
832
-	})
833
-
834
-	// ErrorCodeCantDestroy is generated when we try to delete a container
835
-	// but failed for some reason.
836
-	ErrorCodeCantDestroy = errcode.Register(errGroup, errcode.ErrorDescriptor{
837
-		Value:          "CANTDESTROY",
838
-		Message:        "Cannot destroy container %s: %v",
839
-		Description:    "An attempt was made to delete a container but it failed",
840
-		HTTPStatusCode: http.StatusInternalServerError,
841
-	})
842
-
843
-	// ErrorCodeRmRunning is generated when we try to delete a container
844
-	// but its still running.
845
-	ErrorCodeRmRunning = errcode.Register(errGroup, errcode.ErrorDescriptor{
846
-		Value:          "RMRUNNING",
847
-		Message:        "You cannot remove a running container %s. Stop the container before attempting removal or use -f",
848
-		Description:    "An attempt was made to delete a container but the container is still running, try to either stop it first or use '-f'",
849
-		HTTPStatusCode: http.StatusConflict,
850
-	})
851
-
852
-	// ErrorCodeRmFailed is generated when we try to delete a container
853
-	// but it failed for some reason.
854
-	ErrorCodeRmFailed = errcode.Register(errGroup, errcode.ErrorDescriptor{
855
-		Value:          "RMFAILED",
856
-		Message:        "Could not kill running container %s, cannot remove - %v",
857
-		Description:    "An error occurred while trying to delete a running container",
858
-		HTTPStatusCode: http.StatusInternalServerError,
859
-	})
860
-
861
-	// ErrorCodeRmNotFound is generated when we try to delete a container
862
-	// but couldn't find it.
863
-	ErrorCodeRmNotFound = errcode.Register(errGroup, errcode.ErrorDescriptor{
864
-		Value:          "RMNOTFOUND",
865
-		Message:        "Could not kill running container, cannot remove - %v",
866
-		Description:    "An attempt to delete a container was made but the container could not be found",
867
-		HTTPStatusCode: http.StatusInternalServerError,
868
-	})
869
-
870
-	// ErrorCodeRmState is generated when we try to delete a container
871
-	// but couldn't set its state to RemovalInProgress.
872
-	ErrorCodeRmState = errcode.Register(errGroup, errcode.ErrorDescriptor{
873
-		Value:          "RMSTATE",
874
-		Message:        "Failed to set container %s state to RemovalInProgress: %s",
875
-		Description:    "An attempt to delete a container was made, but there as an error trying to set its state to 'RemovalInProgress'",
876
-		HTTPStatusCode: http.StatusInternalServerError,
877
-	})
878
-
879
-	// ErrorCodeRmDriverFS is generated when we try to delete a container
880
-	// but the driver failed to delete its filesystem.
881
-	ErrorCodeRmDriverFS = errcode.Register(errGroup, errcode.ErrorDescriptor{
882
-		Value:          "RMDRIVERFS",
883
-		Message:        "Driver %s failed to remove root filesystem %s: %s",
884
-		Description:    "While trying to delete a container, the driver failed to remove the root filesystem",
885
-		HTTPStatusCode: http.StatusInternalServerError,
886
-	})
887
-
888
-	// ErrorCodeRmFS is generated when we try to delete a container
889
-	// but failed deleting its filesystem.
890
-	ErrorCodeRmFS = errcode.Register(errGroup, errcode.ErrorDescriptor{
891
-		Value:          "RMFS",
892
-		Message:        "Unable to remove filesystem for %v: %v",
893
-		Description:    "While trying to delete a container, the driver failed to remove the filesystem",
894
-		HTTPStatusCode: http.StatusInternalServerError,
895
-	})
896
-
897
-	// ErrorCodeRmExecDriver is generated when we try to delete a container
898
-	// but failed deleting its exec driver data.
899
-	ErrorCodeRmExecDriver = errcode.Register(errGroup, errcode.ErrorDescriptor{
900
-		Value:          "RMEXECDRIVER",
901
-		Message:        "Unable to remove execdriver data for %s: %s",
902
-		Description:    "While trying to delete a container, there was an error trying to remove th exec driver data",
903
-		HTTPStatusCode: http.StatusInternalServerError,
904
-	})
905
-
906
-	// ErrorCodeRmVolumeInUse is generated when we try to delete a container
907
-	// but failed deleting a volume because its being used.
908
-	ErrorCodeRmVolumeInUse = errcode.Register(errGroup, errcode.ErrorDescriptor{
909
-		Value:          "RMVOLUMEINUSE",
910
-		Message:        "Conflict: %v",
911
-		Description:    "While trying to delete a container, one of its volumes is still being used",
912
-		HTTPStatusCode: http.StatusConflict,
913
-	})
914
-
915
-	// ErrorCodeRmVolume is generated when we try to delete a container
916
-	// but failed deleting a volume.
917
-	ErrorCodeRmVolume = errcode.Register(errGroup, errcode.ErrorDescriptor{
918
-		Value:          "RMVOLUME",
919
-		Message:        "Error while removing volume %s: %v",
920
-		Description:    "While trying to delete a container, there was an error trying to delete one of its volumes",
921
-		HTTPStatusCode: http.StatusInternalServerError,
922
-	})
923
-
924
-	// ErrorCodeInvalidCpusetCpus is generated when user provided cpuset CPUs
925
-	// are invalid.
926
-	ErrorCodeInvalidCpusetCpus = errcode.Register(errGroup, errcode.ErrorDescriptor{
927
-		Value:          "INVALIDCPUSETCPUS",
928
-		Message:        "Invalid value %s for cpuset cpus.",
929
-		Description:    "While verifying the container's 'HostConfig', CpusetCpus value was in an incorrect format",
930
-		HTTPStatusCode: http.StatusInternalServerError,
931
-	})
932
-
933
-	// ErrorCodeInvalidCpusetMems is generated when user provided cpuset mems
934
-	// are invalid.
935
-	ErrorCodeInvalidCpusetMems = errcode.Register(errGroup, errcode.ErrorDescriptor{
936
-		Value:          "INVALIDCPUSETMEMS",
937
-		Message:        "Invalid value %s for cpuset mems.",
938
-		Description:    "While verifying the container's 'HostConfig', CpusetMems value was in an incorrect format",
939
-		HTTPStatusCode: http.StatusInternalServerError,
940
-	})
941
-
942
-	// ErrorCodeNotAvailableCpusetCpus is generated when user provided cpuset
943
-	// CPUs aren't available in the container's cgroup.
944
-	ErrorCodeNotAvailableCpusetCpus = errcode.Register(errGroup, errcode.ErrorDescriptor{
945
-		Value:          "NOTAVAILABLECPUSETCPUS",
946
-		Message:        "Requested CPUs are not available - requested %s, available: %s.",
947
-		Description:    "While verifying the container's 'HostConfig', cpuset CPUs provided aren't available in the container's cgroup available set",
948
-		HTTPStatusCode: http.StatusInternalServerError,
949
-	})
950
-
951
-	// ErrorCodeNotAvailableCpusetMems is generated when user provided cpuset
952
-	// memory nodes aren't available in the container's cgroup.
953
-	ErrorCodeNotAvailableCpusetMems = errcode.Register(errGroup, errcode.ErrorDescriptor{
954
-		Value:          "NOTAVAILABLECPUSETMEMS",
955
-		Message:        "Requested memory nodes are not available - requested %s, available: %s.",
956
-		Description:    "While verifying the container's 'HostConfig', cpuset memory nodes provided aren't available in the container's cgroup available set",
957
-		HTTPStatusCode: http.StatusInternalServerError,
958
-	})
959
-
960
-	// ErrorVolumeNameTaken is generated when an error occurred while
961
-	// trying to create a volume that has existed using different driver.
962
-	ErrorVolumeNameTaken = errcode.Register(errGroup, errcode.ErrorDescriptor{
963
-		Value:          "VOLUME_NAME_TAKEN",
964
-		Message:        "A volume named %s already exists. Choose a different volume name.",
965
-		Description:    "An attempt to create a volume using a driver but the volume already exists with a different driver",
966
-		HTTPStatusCode: http.StatusInternalServerError,
967
-	})
968
-
969
-	// ErrorCodeCmdNotFound is generated when container cmd can't start,
970
-	// container command not found error, exit code 127
971
-	ErrorCodeCmdNotFound = errcode.Register(errGroup, errcode.ErrorDescriptor{
972
-		Value:          "CMDNOTFOUND",
973
-		Message:        "Container command not found or does not exist.",
974
-		Description:    "Command could not be found, command does not exist",
975
-		HTTPStatusCode: http.StatusInternalServerError,
976
-	})
977
-
978
-	// ErrorCodeCmdCouldNotBeInvoked is generated when container cmd can't start,
979
-	// container command permission denied error, exit code 126
980
-	ErrorCodeCmdCouldNotBeInvoked = errcode.Register(errGroup, errcode.ErrorDescriptor{
981
-		Value:          "CMDCOULDNOTBEINVOKED",
982
-		Message:        "Container command could not be invoked.",
983
-		Description:    "Permission denied, cannot invoke command",
984
-		HTTPStatusCode: http.StatusInternalServerError,
985
-	})
986
-
987
-	// ErrorCodeCantStart is generated when container cmd can't start,
988
-	// for any reason other than above 2 errors
989
-	ErrorCodeCantStart = errcode.Register(errGroup, errcode.ErrorDescriptor{
990
-		Value:          "CANTSTART",
991
-		Message:        "Cannot start container %s: %s",
992
-		Description:    "There was an error while trying to start a container",
993
-		HTTPStatusCode: http.StatusInternalServerError,
994
-	})
995
-
996
-	// ErrorCodeCantDeletePredefinedNetwork is generated when one of the predefined networks
997
-	// is attempted to be deleted.
998
-	ErrorCodeCantDeletePredefinedNetwork = errcode.Register(errGroup, errcode.ErrorDescriptor{
999
-		Value:          "CANT_DELETE_PREDEFINED_NETWORK",
1000
-		Message:        "%s is a pre-defined network and cannot be removed",
1001
-		Description:    "Engine's predefined networks cannot be deleted",
1002
-		HTTPStatusCode: http.StatusForbidden,
1003
-	})
1004
-
1005
-	// ErrorCodeMultipleNetworkConnect is generated when more than one network is passed
1006
-	// when creating a container
1007
-	ErrorCodeMultipleNetworkConnect = errcode.Register(errGroup, errcode.ErrorDescriptor{
1008
-		Value:          "CANNOT_CONNECT_TO_MULTIPLE_NETWORKS",
1009
-		Message:        "Container cannot be connected to %s",
1010
-		Description:    "A container can only be connected to one network at the time",
1011
-		HTTPStatusCode: http.StatusBadRequest,
1012
-	})
1013
-)
1014 1
deleted file mode 100644
... ...
@@ -1,6 +0,0 @@
1
-package errors
2
-
3
-// This file contains all of the errors that can be generated from the
4
-// docker engine but are not tied to any specific top-level component.
5
-
6
-const errGroup = "engine"
7 1
new file mode 100644
... ...
@@ -0,0 +1,41 @@
0
+package errors
1
+
2
+import "net/http"
3
+
4
+// apiError is an error wrapper that also
5
+// holds information about response status codes.
6
+type apiError struct {
7
+	error
8
+	statusCode int
9
+}
10
+
11
+// HTTPErrorStatusCode returns a status code.
12
+func (e apiError) HTTPErrorStatusCode() int {
13
+	return e.statusCode
14
+}
15
+
16
+// NewErrorWithStatusCode allows you to associate
17
+// a specific HTTP Status Code to an error.
18
+// The Server will take that code and set
19
+// it as the response status.
20
+func NewErrorWithStatusCode(err error, code int) error {
21
+	return apiError{err, code}
22
+}
23
+
24
+// NewBadRequestError creates a new API error
25
+// that has the 400 HTTP status code associated to it.
26
+func NewBadRequestError(err error) error {
27
+	return NewErrorWithStatusCode(err, http.StatusBadRequest)
28
+}
29
+
30
+// NewRequestNotFoundError creates a new API error
31
+// that has the 404 HTTP status code associated to it.
32
+func NewRequestNotFoundError(err error) error {
33
+	return NewErrorWithStatusCode(err, http.StatusNotFound)
34
+}
35
+
36
+// NewRequestConflictError creates a new API error
37
+// that has the 409 HTTP status code associated to it.
38
+func NewRequestConflictError(err error) error {
39
+	return NewErrorWithStatusCode(err, http.StatusConflict)
40
+}
0 41
deleted file mode 100644
... ...
@@ -1,20 +0,0 @@
1
-package errors
2
-
3
-// This file contains all of the errors that can be generated from the
4
-// docker/image component.
5
-
6
-import (
7
-	"net/http"
8
-
9
-	"github.com/docker/distribution/registry/api/errcode"
10
-)
11
-
12
-var (
13
-	// ErrorCodeInvalidImageID is generated when image id specified is incorrectly formatted.
14
-	ErrorCodeInvalidImageID = errcode.Register(errGroup, errcode.ErrorDescriptor{
15
-		Value:          "INVALIDIMAGEID",
16
-		Message:        "image ID '%s' is invalid ",
17
-		Description:    "The specified image id is incorrectly formatted",
18
-		HTTPStatusCode: http.StatusInternalServerError,
19
-	})
20
-)
21 1
deleted file mode 100644
... ...
@@ -1,45 +0,0 @@
1
-package errors
2
-
3
-import (
4
-	"net/http"
5
-
6
-	"github.com/docker/distribution/registry/api/errcode"
7
-)
8
-
9
-var (
10
-	// ErrorCodeNewerClientVersion is generated when a request from a client
11
-	// specifies a higher version than the server supports.
12
-	ErrorCodeNewerClientVersion = errcode.Register(errGroup, errcode.ErrorDescriptor{
13
-		Value:          "NEWERCLIENTVERSION",
14
-		Message:        "client is newer than server (client API version: %s, server API version: %s)",
15
-		Description:    "The client version is higher than the server version",
16
-		HTTPStatusCode: http.StatusBadRequest,
17
-	})
18
-
19
-	// ErrorCodeOldClientVersion is generated when a request from a client
20
-	// specifies a version lower than the minimum version supported by the server.
21
-	ErrorCodeOldClientVersion = errcode.Register(errGroup, errcode.ErrorDescriptor{
22
-		Value:          "OLDCLIENTVERSION",
23
-		Message:        "client version %s is too old. Minimum supported API version is %s, please upgrade your client to a newer version",
24
-		Description:    "The client version is too old for the server",
25
-		HTTPStatusCode: http.StatusBadRequest,
26
-	})
27
-
28
-	// ErrorNetworkControllerNotEnabled is generated when the networking stack in not enabled
29
-	// for certain platforms, like windows.
30
-	ErrorNetworkControllerNotEnabled = errcode.Register(errGroup, errcode.ErrorDescriptor{
31
-		Value:          "NETWORK_CONTROLLER_NOT_ENABLED",
32
-		Message:        "the network controller is not enabled for this platform",
33
-		Description:    "Docker's networking stack is disabled for this platform",
34
-		HTTPStatusCode: http.StatusNotFound,
35
-	})
36
-
37
-	// ErrorCodeNoHijackConnection is generated when a request tries to attach to a container
38
-	// but the connection to hijack is not provided.
39
-	ErrorCodeNoHijackConnection = errcode.Register(errGroup, errcode.ErrorDescriptor{
40
-		Value:          "HIJACK_CONNECTION_MISSING",
41
-		Message:        "error attaching to container %s, hijack connection missing",
42
-		Description:    "The caller didn't provide a connection to hijack",
43
-		HTTPStatusCode: http.StatusBadRequest,
44
-	})
45
-)
... ...
@@ -643,7 +643,7 @@ func (s *DockerSuite) TestContainerApiCreateMultipleNetworksConfig(c *check.C) {
643 643
 	c.Assert(err, checker.IsNil)
644 644
 	c.Assert(status, checker.Equals, http.StatusBadRequest)
645 645
 	// network name order in error message is not deterministic
646
-	c.Assert(string(b), checker.Contains, "Container cannot be connected to [")
646
+	c.Assert(string(b), checker.Contains, "Container cannot be connected to network endpoints")
647 647
 	c.Assert(string(b), checker.Contains, "net1")
648 648
 	c.Assert(string(b), checker.Contains, "net2")
649 649
 	c.Assert(string(b), checker.Contains, "net3")
... ...
@@ -463,7 +463,7 @@ func (s *DockerSuite) TestRunVolumesFromInReadWriteMode(c *check.C) {
463 463
 	dockerCmd(c, "run", "--name", "parent", "-v", volumeDir, "busybox", "true")
464 464
 	dockerCmd(c, "run", "--volumes-from", "parent:rw", "busybox", "touch", fileInVol)
465 465
 
466
-	if out, _, err := dockerCmdWithError("run", "--volumes-from", "parent:bar", "busybox", "touch", fileInVol); err == nil || !strings.Contains(out, `invalid mode: "bar"`) {
466
+	if out, _, err := dockerCmdWithError("run", "--volumes-from", "parent:bar", "busybox", "touch", fileInVol); err == nil || !strings.Contains(out, `invalid mode: bar`) {
467 467
 		c.Fatalf("running --volumes-from parent:bar should have failed with invalid mode: %q", out)
468 468
 	}
469 469
 
... ...
@@ -7,7 +7,6 @@ import (
7 7
 	"runtime"
8 8
 	"strings"
9 9
 
10
-	"github.com/docker/distribution/registry/api/errcode"
11 10
 	"github.com/docker/docker/pkg/archive"
12 11
 	"github.com/docker/docker/pkg/stringid"
13 12
 )
... ...
@@ -86,22 +85,3 @@ func ReplaceOrAppendEnvValues(defaults, overrides []string) []string {
86 86
 
87 87
 	return defaults
88 88
 }
89
-
90
-// GetErrorMessage returns the human readable message associated with
91
-// the passed-in error. In some cases the default Error() func returns
92
-// something that is less than useful so based on its types this func
93
-// will go and get a better piece of text.
94
-func GetErrorMessage(err error) string {
95
-	switch err.(type) {
96
-	case errcode.Error:
97
-		e, _ := err.(errcode.Error)
98
-		return e.Message
99
-
100
-	case errcode.ErrorCode:
101
-		ec, _ := err.(errcode.ErrorCode)
102
-		return ec.Message()
103
-
104
-	default:
105
-		return err.Error()
106
-	}
107
-}
... ...
@@ -4,14 +4,12 @@
4 4
 package local
5 5
 
6 6
 import (
7
-	"errors"
8 7
 	"fmt"
9 8
 	"io/ioutil"
10 9
 	"os"
11 10
 	"path/filepath"
12 11
 	"sync"
13 12
 
14
-	derr "github.com/docker/docker/errors"
15 13
 	"github.com/docker/docker/pkg/idtools"
16 14
 	"github.com/docker/docker/utils"
17 15
 	"github.com/docker/docker/volume"
... ...
@@ -27,13 +25,21 @@ const (
27 27
 
28 28
 var (
29 29
 	// ErrNotFound is the typed error returned when the requested volume name can't be found
30
-	ErrNotFound = errors.New("volume not found")
30
+	ErrNotFound = fmt.Errorf("volume not found")
31 31
 	// volumeNameRegex ensures the name assigned for the volume is valid.
32 32
 	// This name is used to create the bind directory, so we need to avoid characters that
33 33
 	// would make the path to escape the root directory.
34 34
 	volumeNameRegex = utils.RestrictedVolumeNamePattern
35 35
 )
36 36
 
37
+type validationError struct {
38
+	error
39
+}
40
+
41
+func (validationError) IsValidationError() bool {
42
+	return true
43
+}
44
+
37 45
 // New instantiates a new Root instance with the provided scope. Scope
38 46
 // is the base path that the Root instance uses to store its
39 47
 // volumes. The base path is created here if it does not exist.
... ...
@@ -142,7 +148,7 @@ func (r *Root) Remove(v volume.Volume) error {
142 142
 
143 143
 	lv, ok := v.(*localVolume)
144 144
 	if !ok {
145
-		return errors.New("unknown volume type")
145
+		return fmt.Errorf("unknown volume type")
146 146
 	}
147 147
 
148 148
 	realPath, err := filepath.EvalSymlinks(lv.path)
... ...
@@ -188,7 +194,7 @@ func (r *Root) Get(name string) (volume.Volume, error) {
188 188
 
189 189
 func (r *Root) validateName(name string) error {
190 190
 	if !volumeNameRegex.MatchString(name) {
191
-		return derr.ErrorCodeVolumeName.WithArgs(name, utils.RestrictedNameChars)
191
+		return validationError{fmt.Errorf("%q includes invalid characters for a local volume name, only %q are allowed", name, utils.RestrictedNameChars)}
192 192
 	}
193 193
 	return nil
194 194
 }
... ...
@@ -1,12 +1,12 @@
1 1
 package volume
2 2
 
3 3
 import (
4
+	"fmt"
4 5
 	"os"
5 6
 	"runtime"
6 7
 	"strings"
7 8
 
8 9
 	"github.com/Sirupsen/logrus"
9
-	derr "github.com/docker/docker/errors"
10 10
 	"github.com/docker/docker/pkg/system"
11 11
 )
12 12
 
... ...
@@ -82,7 +82,7 @@ func (m *MountPoint) Setup() (string, error) {
82 82
 		}
83 83
 		return m.Source, nil
84 84
 	}
85
-	return "", derr.ErrorCodeMountSetup
85
+	return "", fmt.Errorf("Unable to setup mount point, neither source nor volume defined")
86 86
 }
87 87
 
88 88
 // Path returns the path of a volume in a mount point.
... ...
@@ -96,7 +96,7 @@ func (m *MountPoint) Path() string {
96 96
 // ParseVolumesFrom ensure that the supplied volumes-from is valid.
97 97
 func ParseVolumesFrom(spec string) (string, string, error) {
98 98
 	if len(spec) == 0 {
99
-		return "", "", derr.ErrorCodeVolumeFromBlank.WithArgs(spec)
99
+		return "", "", fmt.Errorf("malformed volumes-from specification: %s", spec)
100 100
 	}
101 101
 
102 102
 	specParts := strings.SplitN(spec, ":", 2)
... ...
@@ -106,15 +106,23 @@ func ParseVolumesFrom(spec string) (string, string, error) {
106 106
 	if len(specParts) == 2 {
107 107
 		mode = specParts[1]
108 108
 		if !ValidMountMode(mode) {
109
-			return "", "", derr.ErrorCodeVolumeInvalidMode.WithArgs(mode)
109
+			return "", "", errInvalidMode(mode)
110 110
 		}
111 111
 		// For now don't allow propagation properties while importing
112 112
 		// volumes from data container. These volumes will inherit
113 113
 		// the same propagation property as of the original volume
114 114
 		// in data container. This probably can be relaxed in future.
115 115
 		if HasPropagation(mode) {
116
-			return "", "", derr.ErrorCodeVolumeInvalidMode.WithArgs(mode)
116
+			return "", "", errInvalidMode(mode)
117 117
 		}
118 118
 	}
119 119
 	return id, mode, nil
120 120
 }
121
+
122
+func errInvalidMode(mode string) error {
123
+	return fmt.Errorf("invalid mode: %v", mode)
124
+}
125
+
126
+func errInvalidSpec(spec string) error {
127
+	return fmt.Errorf("Invalid volume specification: '%s'", spec)
128
+}
... ...
@@ -34,8 +34,8 @@ func TestParseMountSpecPropagation(t *testing.T) {
34 34
 		"/hostPath:/containerPath:ro,Z,rprivate",
35 35
 	}
36 36
 	invalid = map[string]string{
37
-		"/path:/path:ro,rshared,rslave":   `invalid mode: "ro,rshared,rslave"`,
38
-		"/path:/path:ro,z,rshared,rslave": `invalid mode: "ro,z,rshared,rslave"`,
37
+		"/path:/path:ro,rshared,rslave":   `invalid mode: ro,rshared,rslave`,
38
+		"/path:/path:ro,z,rshared,rslave": `invalid mode: ro,z,rshared,rslave`,
39 39
 		"/path:shared":                    "Invalid volume specification",
40 40
 		"/path:slave":                     "Invalid volume specification",
41 41
 		"/path:private":                   "Invalid volume specification",
... ...
@@ -111,8 +111,8 @@ func TestParseMountSpec(t *testing.T) {
111 111
 			"/path:ro":        "Invalid volume specification",
112 112
 			"/rw:rw":          "Invalid volume specification",
113 113
 			"path:ro":         "Invalid volume specification",
114
-			"/path:/path:sw":  `invalid mode: "sw"`,
115
-			"/path:/path:rwz": `invalid mode: "rwz"`,
114
+			"/path:/path:sw":  `invalid mode: sw`,
115
+			"/path:/path:rwz": `invalid mode: rwz`,
116 116
 		}
117 117
 	}
118 118
 
... ...
@@ -6,8 +6,6 @@ import (
6 6
 	"fmt"
7 7
 	"path/filepath"
8 8
 	"strings"
9
-
10
-	derr "github.com/docker/docker/errors"
11 9
 )
12 10
 
13 11
 // read-write modes
... ...
@@ -47,12 +45,12 @@ func ParseMountSpec(spec, volumeDriver string) (*MountPoint, error) {
47 47
 		Propagation: DefaultPropagationMode,
48 48
 	}
49 49
 	if strings.Count(spec, ":") > 2 {
50
-		return nil, derr.ErrorCodeVolumeInvalid.WithArgs(spec)
50
+		return nil, errInvalidSpec(spec)
51 51
 	}
52 52
 
53 53
 	arr := strings.SplitN(spec, ":", 3)
54 54
 	if arr[0] == "" {
55
-		return nil, derr.ErrorCodeVolumeInvalid.WithArgs(spec)
55
+		return nil, errInvalidSpec(spec)
56 56
 	}
57 57
 
58 58
 	switch len(arr) {
... ...
@@ -63,7 +61,7 @@ func ParseMountSpec(spec, volumeDriver string) (*MountPoint, error) {
63 63
 		if isValid := ValidMountMode(arr[1]); isValid {
64 64
 			// Destination + Mode is not a valid volume - volumes
65 65
 			// cannot include a mode. eg /foo:rw
66
-			return nil, derr.ErrorCodeVolumeInvalid.WithArgs(spec)
66
+			return nil, errInvalidSpec(spec)
67 67
 		}
68 68
 		// Host Source Path or Name + Destination
69 69
 		mp.Source = arr[0]
... ...
@@ -74,23 +72,23 @@ func ParseMountSpec(spec, volumeDriver string) (*MountPoint, error) {
74 74
 		mp.Destination = arr[1]
75 75
 		mp.Mode = arr[2] // Mode field is used by SELinux to decide whether to apply label
76 76
 		if !ValidMountMode(mp.Mode) {
77
-			return nil, derr.ErrorCodeVolumeInvalidMode.WithArgs(mp.Mode)
77
+			return nil, errInvalidMode(mp.Mode)
78 78
 		}
79 79
 		mp.RW = ReadWrite(mp.Mode)
80 80
 		mp.Propagation = GetPropagation(mp.Mode)
81 81
 	default:
82
-		return nil, derr.ErrorCodeVolumeInvalid.WithArgs(spec)
82
+		return nil, errInvalidSpec(spec)
83 83
 	}
84 84
 
85 85
 	//validate the volumes destination path
86 86
 	mp.Destination = filepath.Clean(mp.Destination)
87 87
 	if !filepath.IsAbs(mp.Destination) {
88
-		return nil, derr.ErrorCodeVolumeAbs.WithArgs(mp.Destination)
88
+		return nil, fmt.Errorf("Invalid volume destination path: '%s' mount path must be absolute.", mp.Destination)
89 89
 	}
90 90
 
91 91
 	// Destination cannot be "/"
92 92
 	if mp.Destination == "/" {
93
-		return nil, derr.ErrorCodeVolumeSlash.WithArgs(spec)
93
+		return nil, fmt.Errorf("Invalid specification: destination can't be '/' in '%s'", spec)
94 94
 	}
95 95
 
96 96
 	name, source := ParseVolumeSource(mp.Source)
... ...
@@ -106,7 +104,7 @@ func ParseMountSpec(spec, volumeDriver string) (*MountPoint, error) {
106 106
 		// cleanup becomes an issue if container does not unmount
107 107
 		// submounts explicitly.
108 108
 		if HasPropagation(mp.Mode) {
109
-			return nil, derr.ErrorCodeVolumeInvalid.WithArgs(spec)
109
+			return nil, errInvalidSpec(spec)
110 110
 		}
111 111
 	} else {
112 112
 		mp.Source = filepath.Clean(source)
... ...
@@ -1,13 +1,13 @@
1 1
 package volume
2 2
 
3 3
 import (
4
+	"fmt"
4 5
 	"os"
5 6
 	"path/filepath"
6 7
 	"regexp"
7 8
 	"strings"
8 9
 
9 10
 	"github.com/Sirupsen/logrus"
10
-	derr "github.com/docker/docker/errors"
11 11
 )
12 12
 
13 13
 // read-write modes
... ...
@@ -96,7 +96,7 @@ func ParseMountSpec(spec string, volumeDriver string) (*MountPoint, error) {
96 96
 
97 97
 	// Must have something back
98 98
 	if len(match) == 0 {
99
-		return nil, derr.ErrorCodeVolumeInvalid.WithArgs(spec)
99
+		return nil, errInvalidSpec(spec)
100 100
 	}
101 101
 
102 102
 	// Pull out the sub expressions from the named capture groups
... ...
@@ -116,7 +116,7 @@ func ParseMountSpec(spec string, volumeDriver string) (*MountPoint, error) {
116 116
 
117 117
 	// Volumes cannot include an explicitly supplied mode eg c:\path:rw
118 118
 	if mp.Source == "" && mp.Destination != "" && matchgroups["mode"] != "" {
119
-		return nil, derr.ErrorCodeVolumeInvalid.WithArgs(spec)
119
+		return nil, errInvalidSpec(spec)
120 120
 	}
121 121
 
122 122
 	// 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) {
125 125
 	if filepath.VolumeName(mp.Destination) == mp.Destination {
126 126
 		// Ensure the destination path, if a drive letter, is not the c drive
127 127
 		if strings.ToLower(mp.Destination) == "c:" {
128
-			return nil, derr.ErrorCodeVolumeDestIsC.WithArgs(spec)
128
+			return nil, fmt.Errorf("Destination drive letter in '%s' cannot be c:", spec)
129 129
 		}
130 130
 	} else {
131 131
 		// So we know the destination is a path, not drive letter. Clean it up.
132 132
 		mp.Destination = filepath.Clean(mp.Destination)
133 133
 		// Ensure the destination path, if a path, is not the c root directory
134 134
 		if strings.ToLower(mp.Destination) == `c:\` {
135
-			return nil, derr.ErrorCodeVolumeDestIsCRoot.WithArgs(spec)
135
+			return nil, fmt.Errorf(`Destination path in '%s' cannot be c:\`, spec)
136 136
 		}
137 137
 	}
138 138
 
... ...
@@ -163,10 +163,10 @@ func ParseMountSpec(spec string, volumeDriver string) (*MountPoint, error) {
163 163
 		var fi os.FileInfo
164 164
 		var err error
165 165
 		if fi, err = os.Stat(mp.Source); err != nil {
166
-			return nil, derr.ErrorCodeVolumeSourceNotFound.WithArgs(mp.Source, err)
166
+			return nil, fmt.Errorf("Source directory '%s' could not be found: %s", mp.Source, err)
167 167
 		}
168 168
 		if !fi.IsDir() {
169
-			return nil, derr.ErrorCodeVolumeSourceNotDirectory.WithArgs(mp.Source)
169
+			return nil, fmt.Errorf("Source '%s' is not a directory", mp.Source)
170 170
 		}
171 171
 	}
172 172
 
... ...
@@ -182,7 +182,7 @@ func IsVolumeNameValid(name string) (bool, error) {
182 182
 	}
183 183
 	nameExp = regexp.MustCompile(`^` + RXReservedNames + `$`)
184 184
 	if nameExp.MatchString(name) {
185
-		return false, derr.ErrorCodeVolumeNameReservedWord.WithArgs(name)
185
+		return false, fmt.Errorf("Volume name %q cannot be a reserved word for Windows filenames", name)
186 186
 	}
187 187
 	return true, nil
188 188
 }