Browse code

Remove static errors from errors package.

Moving all strings to the errors package wasn't a good idea after all.

Our custom implementation of Go errors predates everything that's nice
and good about working with errors in Go. Take as an example what we
have to do to get an error message:

```go
func GetErrorMessage(err error) string {
switch err.(type) {
case errcode.Error:
e, _ := err.(errcode.Error)
return e.Message

case errcode.ErrorCode:
ec, _ := err.(errcode.ErrorCode)
return ec.Message()

default:
return err.Error()
}
}
```

This goes against every good practice for Go development. The language already provides a simple, intuitive and standard way to get error messages, that is calling the `Error()` method from an error. Reinventing the error interface is a mistake.

Our custom implementation also makes very hard to reason about errors, another nice thing about Go. I found several (>10) error declarations that we don't use anywhere. This is a clear sign about how little we know about the errors we return. I also found several error usages where the number of arguments was different than the parameters declared in the error, another clear example of how difficult is to reason about errors.

Moreover, our custom implementation didn't really make easier for people to return custom HTTP status code depending on the errors. Again, it's hard to reason about when to set custom codes and how. Take an example what we have to do to extract the message and status code from an error before returning a response from the API:

```go
switch err.(type) {
case errcode.ErrorCode:
daError, _ := err.(errcode.ErrorCode)
statusCode = daError.Descriptor().HTTPStatusCode
errMsg = daError.Message()

case errcode.Error:
// For reference, if you're looking for a particular error
// then you can do something like :
// import ( derr "github.com/docker/docker/errors" )
// if daError.ErrorCode() == derr.ErrorCodeNoSuchContainer { ... }

daError, _ := err.(errcode.Error)
statusCode = daError.ErrorCode().Descriptor().HTTPStatusCode
errMsg = daError.Message

default:
// This part of will be removed once we've
// converted everything over to use the errcode package

// FIXME: this is brittle and should not be necessary.
// If we need to differentiate between different possible error types,
// we should create appropriate error types with clearly defined meaning
errStr := strings.ToLower(err.Error())
for keyword, status := range map[string]int{
"not found": http.StatusNotFound,
"no such": http.StatusNotFound,
"bad parameter": http.StatusBadRequest,
"conflict": http.StatusConflict,
"impossible": http.StatusNotAcceptable,
"wrong login/password": http.StatusUnauthorized,
"hasn't been activated": http.StatusForbidden,
} {
if strings.Contains(errStr, keyword) {
statusCode = status
break
}
}
}
```

You can notice two things in that code:

1. We have to explain how errors work, because our implementation goes against how easy to use Go errors are.
2. At no moment we arrived to remove that `switch` statement that was the original reason to use our custom implementation.

This change removes all our status errors from the errors package and puts them back in their specific contexts.
IT puts the messages back with their contexts. That way, we know right away when errors used and how to generate their messages.
It uses custom interfaces to reason about errors. Errors that need to response with a custom status code MUST implementent this simple interface:

```go
type errorWithStatus interface {
HTTPErrorStatusCode() int
}
```

This interface is very straightforward to implement. It also preserves Go errors real behavior, getting the message is as simple as using the `Error()` method.

I included helper functions to generate errors that use custom status code in `errors/errors.go`.

By doing this, we remove the hard dependency we have eeverywhere to our custom errors package. Yes, you can use it as a helper to generate error, but it's still very easy to generate errors without it.

Please, read this fantastic blog post about errors in Go: http://dave.cheney.net/2014/12/24/inspecting-errors

Signed-off-by: David Calavera <david.calavera@gmail.com>

David Calavera authored on 2016/02/26 00:53:35
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
 }