1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #16355 from duglin/DaemonErrors

Convert some "daemon" static error strings to the new errocode package format
This commit is contained in:
Jess Frazelle 2015-09-17 11:48:37 -07:00
commit 828e4ac45a
17 changed files with 565 additions and 98 deletions

View file

@ -18,4 +18,475 @@ var (
Description: "The specified container can not be found",
HTTPStatusCode: http.StatusNotFound,
})
// ErrorCodeUnregisteredContainer is generated when we try to load
// a storage driver for an unregistered container
ErrorCodeUnregisteredContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "UNREGISTEREDCONTAINER",
Message: "Can't load storage driver for unregistered container %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeContainerBeingRemoved is generated when an attempt to start
// a container is made but its in the process of being removed, or is dead.
ErrorCodeContainerBeingRemoved = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "CONTAINERBEINGREMOVED",
Message: "Container is marked for removal and cannot be started.",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeUnpauseContainer is generated when we attempt to stop a
// container but its paused.
ErrorCodeUnpauseContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "UNPAUSECONTAINER",
Message: "Container %s is paused. Unpause the container before stopping",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeAlreadyPaused is generated when we attempt to pause a
// container when its already paused.
ErrorCodeAlreadyPaused = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "ALREADYPAUSED",
Message: "Container %s is already paused",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeNotPaused is generated when we attempt to unpause a
// container when its not paused.
ErrorCodeNotPaused = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "NOTPAUSED",
Message: "Container %s is not paused",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeImageUnregContainer is generated when we attempt to get the
// image of an unknown/unregistered container.
ErrorCodeImageUnregContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "IMAGEUNREGCONTAINER",
Message: "Can't get image of unregistered container",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeEmptyID is generated when an ID is the emptry string.
ErrorCodeEmptyID = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "EMPTYID",
Message: "Invalid empty id",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeLoggingFactory is generated when we could not load the
// log driver.
ErrorCodeLoggingFactory = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "LOGGINGFACTORY",
Message: "Failed to get logging factory: %v",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeInitLogger is generated when we could not initialize
// the logging driver.
ErrorCodeInitLogger = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "INITLOGGER",
Message: "Failed to initialize logging driver: %v",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeNotRunning is generated when we need to verify that
// a container is running, but its not.
ErrorCodeNotRunning = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "NOTRUNNING",
Message: "Container %s is not running",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeLinkNotRunning is generated when we try to link to a
// container that is not running.
ErrorCodeLinkNotRunning = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "LINKNOTRUNNING",
Message: "Cannot link to a non running container: %s AS %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeDeviceInfo is generated when there is an error while trying
// to get info about a custom device.
// container that is not running.
ErrorCodeDeviceInfo = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "DEVICEINFO",
Message: "error gathering device information while adding custom device %q: %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeEmptyEndpoint is generated when the endpoint for a port
// map is nil.
ErrorCodeEmptyEndpoint = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "EMPTYENDPOINT",
Message: "invalid endpoint while building port map info",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeEmptyNetwork is generated when the networkSettings for a port
// map is nil.
ErrorCodeEmptyNetwork = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "EMPTYNETWORK",
Message: "invalid networksettings while building port map info",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeParsingPort is generated when there is an error parsing
// a "port" string.
ErrorCodeParsingPort = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "PARSINGPORT",
Message: "Error parsing Port value(%v):%v",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeNoSandbox is generated when we can't find the specified
// sandbox(network) by ID.
ErrorCodeNoSandbox = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "NOSANDBOX",
Message: "error locating sandbox id %s: %v",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeNetworkUpdate is generated when there is an error while
// trying update a network/sandbox config.
ErrorCodeNetworkUpdate = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "NETWORKUPDATE",
Message: "Update network failed: %v",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeNetworkRefresh is generated when there is an error while
// trying refresh a network/sandbox config.
ErrorCodeNetworkRefresh = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "NETWORKREFRESH",
Message: "Update network failed: Failure in refresh sandbox %s: %v",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeHostPort is generated when there was an error while trying
// to parse a "host/por" string.
ErrorCodeHostPort = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "HOSTPORT",
Message: "Error parsing HostPort value(%s):%v",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeNetworkConflict is generated when we try to public a service
// in network mode.
ErrorCodeNetworkConflict = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "NETWORKCONFLICT",
Message: "conflicting options: publishing a service and network mode",
HTTPStatusCode: http.StatusConflict,
})
// ErrorCodeJoinInfo is generated when we failed to update a container's
// join info.
ErrorCodeJoinInfo = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "JOININFO",
Message: "Updating join info failed: %v",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeIPCRunning is generated when we try to join a container's
// IPC but its running.
ErrorCodeIPCRunning = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "IPCRUNNING",
Message: "cannot join IPC of a non running container: %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeNotADir is generated when we try to create a directory
// but the path isn't a dir.
ErrorCodeNotADir = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "NOTADIR",
Message: "Cannot mkdir: %s is not a directory",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeParseContainer is generated when the reference to a
// container doesn't include a ":" (another container).
ErrorCodeParseContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "PARSECONTAINER",
Message: "no container specified to join network",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeJoinSelf is generated when we try to network to ourselves.
ErrorCodeJoinSelf = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "JOINSELF",
Message: "cannot join own network",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeJoinRunning is generated when we try to network to ourselves.
ErrorCodeJoinRunning = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "JOINRUNNING",
Message: "cannot join network of a non running container: %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeModeNotContainer is generated when we try to network to
// another container but the mode isn't 'container'.
ErrorCodeModeNotContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "MODENOTCONTAINER",
Message: "network mode not set to container",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeRemovingVolume is generated when we try remove a mount
// point (volume) but fail.
ErrorCodeRemovingVolume = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "REMOVINGVOLUME",
Message: "Error removing volumes:\n%v",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeInvalidNetworkMode is generated when an invalid network
// mode value is specified.
ErrorCodeInvalidNetworkMode = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "INVALIDNETWORKMODE",
Message: "invalid network mode: %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeGetGraph is generated when there was an error while
// trying to find a graph/image.
ErrorCodeGetGraph = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "GETGRAPH",
Message: "Failed to graph.Get on ImageID %s - %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeGetLayer is generated when there was an error while
// trying to retrieve a particular layer of an image.
ErrorCodeGetLayer = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "GETLAYER",
Message: "Failed to get layer path from graphdriver %s for ImageID %s - %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodePutLayer is generated when there was an error while
// trying to 'put' a particular layer of an image.
ErrorCodePutLayer = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "PUTLAYER",
Message: "Failed to put layer path from graphdriver %s for ImageID %s - %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeGetLayerMetadata is generated when there was an error while
// trying to retrieve the metadata of a layer of an image.
ErrorCodeGetLayerMetadata = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "GETLAYERMETADATA",
Message: "Failed to get layer metadata - %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeEmptyConfig is generated when the input config data
// is empty.
ErrorCodeEmptyConfig = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "EMPTYCONFIG",
Message: "Config cannot be empty in order to create a container",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeNoSuchImageHash is generated when we can't find the
// specified image by its hash
ErrorCodeNoSuchImageHash = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "NOSUCHIMAGEHASH",
Message: "No such image: %s",
HTTPStatusCode: http.StatusNotFound,
})
// ErrorCodeNoSuchImageTag is generated when we can't find the
// specified image byt its name/tag.
ErrorCodeNoSuchImageTag = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "NOSUCHIMAGETAG",
Message: "No such image: %s:%s",
HTTPStatusCode: http.StatusNotFound,
})
// ErrorCodeMountOverFile is generated when we try to mount a volume
// over an existing file (but not a dir).
ErrorCodeMountOverFile = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "MOUNTOVERFILE",
Message: "cannot mount volume over existing file, file exists %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeMountSetup is generated when we can't define a mount point
// due to the source and destination are defined.
ErrorCodeMountSetup = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "MOUNTSETUP",
Message: "Unable to setup mount point, neither source nor volume defined",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeVolumeInvalidMode is generated when we the mode of a volume
// mount is invalid.
ErrorCodeVolumeInvalidMode = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "VOLUMEINVALIDMODE",
Message: "invalid mode for volumes-from: %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeVolumeInvalid is generated when the format fo the
// volume specification isn't valid.
ErrorCodeVolumeInvalid = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "VOLUMEINVALID",
Message: "Invalid volume specification: %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeVolumeAbs is generated when path to a volume isn't absolute.
ErrorCodeVolumeAbs = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "VOLUMEABS",
Message: "Invalid volume destination path: %s mount path must be absolute.",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeVolumeFromBlank is generated when path to a volume is blank.
ErrorCodeVolumeFromBlank = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "VOLUMEFROMBLANK",
Message: "malformed volumes-from specification: %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeVolumeMode is generated when 'mode' for a volume
// isn't a valid.
ErrorCodeVolumeMode = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "VOLUMEMODE",
Message: "invalid mode for volumes-from: %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeVolumeDup is generated when we try to mount two volumes
// to the same path.
ErrorCodeVolumeDup = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "VOLUMEDUP",
Message: "Duplicate bind mount %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeCantUnpause is generated when there's an error while trying
// to unpause a container.
ErrorCodeCantUnpause = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "CANTUNPAUSE",
Message: "Cannot unpause container %s: %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodePSError is generated when trying to run 'ps'.
ErrorCodePSError = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "PSError",
Message: "Error running ps: %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeNoPID is generated when looking for the PID field in the
// ps output.
ErrorCodeNoPID = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "NOPID",
Message: "Couldn't find PID field in ps output",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeBadPID is generated when we can't convert a PID to an int.
ErrorCodeBadPID = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "BADPID",
Message: "Unexpected pid '%s': %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeNoTop is generated when we try to run 'top' but can't
// because we're on windows.
ErrorCodeNoTop = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "NOTOP",
Message: "Top is not supported on Windows",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeStopped is generated when we try to stop a container
// that is already stopped.
ErrorCodeStopped = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "STOPPED",
Message: "Container already stopped",
HTTPStatusCode: http.StatusNotModified,
})
// ErrorCodeCantStop is generated when we try to stop a container
// but failed for some reason.
ErrorCodeCantStop = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "CANTSTOP",
Message: "Cannot stop container %s: %s\n",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeBadCPUFields is generated the number of CPU fields is
// less than 8.
ErrorCodeBadCPUFields = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "BADCPUFIELDS",
Message: "invalid number of cpu fields",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeBadCPUInt is generated the CPU field can't be parsed as an int.
ErrorCodeBadCPUInt = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "BADCPUINT",
Message: "Unable to convert value %s to int: %s",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeBadStatFormat is generated the output of the stat info
// isn't parseable.
ErrorCodeBadStatFormat = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "BADSTATFORMAT",
Message: "invalid stat format",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeTimedOut is generated when a timer expires.
ErrorCodeTimedOut = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "TIMEDOUT",
Message: "Timed out: %v",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeAlreadyRemoving is generated when we try to remove a
// container that is already being removed.
ErrorCodeAlreadyRemoving = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "ALREADYREMOVING",
Message: "Status is already RemovalInProgress",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeStartPaused is generated when we start a paused container.
ErrorCodeStartPaused = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "STARTPAUSED",
Message: "Cannot start a paused container, try unpause instead.",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeAlreadyStarted is generated when we try to start a container
// that is already running.
ErrorCodeAlreadyStarted = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "ALREADYSTARTED",
Message: "Container already started",
HTTPStatusCode: http.StatusNotModified,
})
// ErrorCodeHostConfigStart is generated when a HostConfig is passed
// into the start command.
ErrorCodeHostConfigStart = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "HOSTCONFIGSTART",
Message: "Supplying a hostconfig on start is not supported. It should be supplied on create",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorCodeCantStart is generated when an error occurred while
// trying to start a container.
ErrorCodeCantStart = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "CANTSTART",
Message: "Cannot start container %s: %s",
HTTPStatusCode: http.StatusInternalServerError,
})
)

View file

@ -12,6 +12,8 @@ import (
"golang.org/x/net/websocket"
"github.com/Sirupsen/logrus"
"github.com/docker/distribution/registry/api/errcode"
derr "github.com/docker/docker/api/errors"
"github.com/docker/docker/api/types"
"github.com/docker/docker/context"
"github.com/docker/docker/daemon"
@ -19,6 +21,7 @@ import (
"github.com/docker/docker/pkg/signal"
"github.com/docker/docker/pkg/version"
"github.com/docker/docker/runconfig"
"github.com/docker/docker/utils"
)
func (s *Server) getContainersJSON(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
@ -137,7 +140,7 @@ func (s *Server) getContainersLogs(ctx context.Context, w http.ResponseWriter, r
// The client may be expecting all of the data we're sending to
// be multiplexed, so send it through OutStream, which will
// have been set up to handle that if needed.
fmt.Fprintf(logsConfig.OutStream, "Error running logs job: %s\n", err)
fmt.Fprintf(logsConfig.OutStream, "Error running logs job: %s\n", utils.GetErrorMessage(err))
}
return nil
@ -177,10 +180,6 @@ func (s *Server) postContainersStart(ctx context.Context, w http.ResponseWriter,
}
if err := s.daemon.ContainerStart(vars["name"], hostConfig); err != nil {
if err.Error() == "Container already started" {
w.WriteHeader(http.StatusNotModified)
return nil
}
return err
}
w.WriteHeader(http.StatusNoContent)
@ -198,10 +197,6 @@ func (s *Server) postContainersStop(ctx context.Context, w http.ResponseWriter,
seconds, _ := strconv.Atoi(r.Form.Get("t"))
if err := s.daemon.ContainerStop(vars["name"], seconds); err != nil {
if err.Error() == "Container already stopped" {
w.WriteHeader(http.StatusNotModified)
return nil
}
return err
}
w.WriteHeader(http.StatusNoContent)
@ -229,7 +224,9 @@ func (s *Server) postContainersKill(ctx context.Context, w http.ResponseWriter,
}
if err := s.daemon.ContainerKill(name, uint64(sig)); err != nil {
_, isStopped := err.(daemon.ErrContainerNotRunning)
theErr, isDerr := err.(errcode.ErrorCoder)
isStopped := isDerr && theErr.ErrorCode() == derr.ErrorCodeNotRunning
// Return error that's not caused because the container is stopped.
// Return error if the container is not running and the api is >= 1.20
// to keep backwards compatibility.

View file

@ -15,6 +15,7 @@ import (
"github.com/opencontainers/runc/libcontainer/label"
"github.com/Sirupsen/logrus"
derr "github.com/docker/docker/api/errors"
"github.com/docker/docker/daemon/execdriver"
"github.com/docker/docker/daemon/logger"
"github.com/docker/docker/daemon/logger/jsonfilelog"
@ -39,15 +40,6 @@ var (
ErrRootFSReadOnly = errors.New("container rootfs is marked read-only")
)
// ErrContainerNotRunning holds the id of the container that is not running.
type ErrContainerNotRunning struct {
id string
}
func (e ErrContainerNotRunning) Error() string {
return fmt.Sprintf("Container %s is not running", e.id)
}
type streamConfig struct {
stdout *broadcastwriter.BroadcastWriter
stderr *broadcastwriter.BroadcastWriter
@ -229,7 +221,7 @@ func (container *Container) getRootResourcePath(path string) (string, error) {
func (container *Container) exportContainerRw() (archive.Archive, error) {
if container.daemon == nil {
return nil, fmt.Errorf("Can't load storage driver for unregistered container %s", container.ID)
return nil, derr.ErrorCodeUnregisteredContainer.WithArgs(container.ID)
}
archive, err := container.daemon.diff(container)
if err != nil {
@ -255,7 +247,7 @@ func (container *Container) Start() (err error) {
}
if container.removalInProgress || container.Dead {
return fmt.Errorf("Container is marked for removal and cannot be started.")
return derr.ErrorCodeContainerBeingRemoved
}
// if we encounter an error during start we need to ensure that any other
@ -361,11 +353,11 @@ func (container *Container) killSig(sig int) error {
// We could unpause the container for them rather than returning this error
if container.Paused {
return fmt.Errorf("Container %s is paused. Unpause the container before stopping", container.ID)
return derr.ErrorCodeUnpauseContainer.WithArgs(container.ID)
}
if !container.Running {
return ErrContainerNotRunning{container.ID}
return derr.ErrorCodeNotRunning.WithArgs(container.ID)
}
// signal to the monitor that it should not restart the container
@ -402,12 +394,12 @@ func (container *Container) pause() error {
// We cannot Pause the container which is not running
if !container.Running {
return ErrContainerNotRunning{container.ID}
return derr.ErrorCodeNotRunning.WithArgs(container.ID)
}
// We cannot Pause the container which is already paused
if container.Paused {
return fmt.Errorf("Container %s is already paused", container.ID)
return derr.ErrorCodeAlreadyPaused.WithArgs(container.ID)
}
if err := container.daemon.execDriver.Pause(container.command); err != nil {
@ -424,12 +416,12 @@ func (container *Container) unpause() error {
// We cannot unpause the container which is not running
if !container.Running {
return ErrContainerNotRunning{container.ID}
return derr.ErrorCodeNotRunning.WithArgs(container.ID)
}
// We cannot unpause the container which is not paused
if !container.Paused {
return fmt.Errorf("Container %s is not paused", container.ID)
return derr.ErrorCodeNotPaused.WithArgs(container.ID)
}
if err := container.daemon.execDriver.Unpause(container.command); err != nil {
@ -443,7 +435,7 @@ func (container *Container) unpause() error {
// Kill forcefully terminates a container.
func (container *Container) Kill() error {
if !container.IsRunning() {
return ErrContainerNotRunning{container.ID}
return derr.ErrorCodeNotRunning.WithArgs(container.ID)
}
// 1. Send SIGKILL
@ -536,7 +528,7 @@ func (container *Container) Restart(seconds int) error {
// to the given height and width. The container must be running.
func (container *Container) Resize(h, w int) error {
if !container.IsRunning() {
return ErrContainerNotRunning{container.ID}
return derr.ErrorCodeNotRunning.WithArgs(container.ID)
}
if err := container.command.ProcessConfig.Terminal.Resize(h, w); err != nil {
return err
@ -577,7 +569,7 @@ func (container *Container) changes() ([]archive.Change, error) {
func (container *Container) getImage() (*image.Image, error) {
if container.daemon == nil {
return nil, fmt.Errorf("Can't get image of unregistered container")
return nil, derr.ErrorCodeImageUnregContainer
}
return container.daemon.graph.Get(container.ImageID)
}
@ -604,7 +596,7 @@ func (container *Container) rootfsPath() string {
func validateID(id string) error {
if id == "" {
return fmt.Errorf("Invalid empty id")
return derr.ErrorCodeEmptyID
}
return nil
}
@ -702,7 +694,7 @@ func (container *Container) getLogger() (logger.Logger, error) {
}
c, err := logger.GetLogDriver(cfg.Type)
if err != nil {
return nil, fmt.Errorf("Failed to get logging factory: %v", err)
return nil, derr.ErrorCodeLoggingFactory.WithArgs(err)
}
ctx := logger.Context{
Config: cfg.Config,
@ -733,7 +725,7 @@ func (container *Container) startLogging() error {
l, err := container.getLogger()
if err != nil {
return fmt.Errorf("Failed to initialize logging driver: %v", err)
return derr.ErrorCodeInitLogger.WithArgs(err)
}
copier := logger.NewCopier(container.ID, map[string]io.Reader{"stdout": container.StdoutPipe(), "stderr": container.StderrPipe()}, l)

View file

@ -15,6 +15,7 @@ import (
"time"
"github.com/Sirupsen/logrus"
derr "github.com/docker/docker/api/errors"
"github.com/docker/docker/daemon/execdriver"
"github.com/docker/docker/daemon/links"
"github.com/docker/docker/daemon/network"
@ -86,7 +87,7 @@ func (container *Container) setupLinkedContainers() ([]string, error) {
if len(children) > 0 {
for linkAlias, child := range children {
if !child.IsRunning() {
return nil, fmt.Errorf("Cannot link to a non running container: %s AS %s", child.Name, linkAlias)
return nil, derr.ErrorCodeLinkNotRunning.WithArgs(child.Name, linkAlias)
}
link := links.NewLink(
@ -168,7 +169,7 @@ func getDevicesFromPath(deviceMapping runconfig.DeviceMapping) (devs []*configs.
return devs, nil
}
return devs, fmt.Errorf("error gathering device information while adding custom device %q: %s", deviceMapping.PathOnHost, err)
return devs, derr.ErrorCodeDeviceInfo.WithArgs(deviceMapping.PathOnHost, err)
}
func populateCommand(c *Container, env []string) error {
@ -527,11 +528,11 @@ func (container *Container) buildSandboxOptions() ([]libnetwork.SandboxOption, e
func (container *Container) buildPortMapInfo(ep libnetwork.Endpoint, networkSettings *network.Settings) (*network.Settings, error) {
if ep == nil {
return nil, fmt.Errorf("invalid endpoint while building port map info")
return nil, derr.ErrorCodeEmptyEndpoint
}
if networkSettings == nil {
return nil, fmt.Errorf("invalid networksettings while building port map info")
return nil, derr.ErrorCodeEmptyNetwork
}
driverInfo, err := ep.DriverInfo()
@ -555,7 +556,7 @@ func (container *Container) buildPortMapInfo(ep libnetwork.Endpoint, networkSett
for _, tp := range exposedPorts {
natPort, err := nat.NewPort(tp.Proto.String(), strconv.Itoa(int(tp.Port)))
if err != nil {
return nil, fmt.Errorf("Error parsing Port value(%v):%v", tp.Port, err)
return nil, derr.ErrorCodeParsingPort.WithArgs(tp.Port, err)
}
networkSettings.Ports[natPort] = nil
}
@ -583,11 +584,11 @@ func (container *Container) buildPortMapInfo(ep libnetwork.Endpoint, networkSett
func (container *Container) buildEndpointInfo(ep libnetwork.Endpoint, networkSettings *network.Settings) (*network.Settings, error) {
if ep == nil {
return nil, fmt.Errorf("invalid endpoint while building port map info")
return nil, derr.ErrorCodeEmptyEndpoint
}
if networkSettings == nil {
return nil, fmt.Errorf("invalid networksettings while building port map info")
return nil, derr.ErrorCodeEmptyNetwork
}
epInfo := ep.Info()
@ -664,16 +665,16 @@ func (container *Container) updateNetwork() error {
sb, err := ctrl.SandboxByID(sid)
if err != nil {
return fmt.Errorf("error locating sandbox id %s: %v", sid, err)
return derr.ErrorCodeNoSandbox.WithArgs(sid, err)
}
options, err := container.buildSandboxOptions()
if err != nil {
return fmt.Errorf("Update network failed: %v", err)
return derr.ErrorCodeNetworkUpdate.WithArgs(err)
}
if err := sb.Refresh(options...); err != nil {
return fmt.Errorf("Update network failed: Failure in refresh sandbox %s: %v", sid, err)
return derr.ErrorCodeNetworkRefresh.WithArgs(sid, err)
}
return nil
@ -727,7 +728,7 @@ func (container *Container) buildCreateEndpointOptions() ([]libnetwork.EndpointO
portStart, portEnd, err = newP.Range()
}
if err != nil {
return nil, fmt.Errorf("Error parsing HostPort value(%s):%v", binding[i].HostPort, err)
return nil, derr.ErrorCodeHostPort.WithArgs(binding[i].HostPort, err)
}
pbCopy.HostPort = uint16(portStart)
pbCopy.HostPortEnd = uint16(portEnd)
@ -828,7 +829,7 @@ func (container *Container) allocateNetwork() error {
networkDriver = controller.Config().Daemon.DefaultDriver
}
} else if service != "" {
return fmt.Errorf("conflicting options: publishing a service and network mode")
return derr.ErrorCodeNetworkConflict
}
if runconfig.NetworkMode(networkDriver).IsBridge() && container.daemon.configStore.DisableBridge {
@ -919,7 +920,7 @@ func (container *Container) configureNetwork(networkName, service, networkDriver
}
if err := container.updateJoinInfo(ep); err != nil {
return fmt.Errorf("Updating join info failed: %v", err)
return derr.ErrorCodeJoinInfo.WithArgs(err)
}
return nil
@ -984,7 +985,7 @@ func (container *Container) getIpcContainer() (*Container, error) {
return nil, err
}
if !c.IsRunning() {
return nil, fmt.Errorf("cannot join IPC of a non running container: %s", containerID)
return nil, derr.ErrorCodeIPCRunning
}
return c, nil
}
@ -1009,7 +1010,7 @@ func (container *Container) setupWorkingDirectory() error {
}
}
if pthInfo != nil && !pthInfo.IsDir() {
return fmt.Errorf("Cannot mkdir: %s is not a directory", container.Config.WorkingDir)
return derr.ErrorCodeNotADir.WithArgs(container.Config.WorkingDir)
}
}
return nil
@ -1020,21 +1021,21 @@ func (container *Container) getNetworkedContainer() (*Container, error) {
switch parts[0] {
case "container":
if len(parts) != 2 {
return nil, fmt.Errorf("no container specified to join network")
return nil, derr.ErrorCodeParseContainer
}
nc, err := container.daemon.Get(parts[1])
if err != nil {
return nil, err
}
if container == nc {
return nil, fmt.Errorf("cannot join own network")
return nil, derr.ErrorCodeJoinSelf
}
if !nc.IsRunning() {
return nil, fmt.Errorf("cannot join network of a non running container: %s", parts[1])
return nil, derr.ErrorCodeJoinRunning.WithArgs(parts[1])
}
return nc, nil
default:
return nil, fmt.Errorf("network mode not set to container")
return nil, derr.ErrorCodeModeNotContainer
}
}
@ -1230,7 +1231,7 @@ func (container *Container) removeMountPoints(rm bool) error {
}
}
if len(rmErrors) > 0 {
return fmt.Errorf("Error removing volumes:\n%v", strings.Join(rmErrors, "\n"))
return derr.ErrorCodeRemovingVolume.WithArgs(strings.Join(rmErrors, "\n"))
}
return nil
}

View file

@ -3,9 +3,9 @@
package daemon
import (
"fmt"
"strings"
derr "github.com/docker/docker/api/errors"
"github.com/docker/docker/daemon/execdriver"
)
@ -64,7 +64,7 @@ func populateCommand(c *Container, env []string) error {
}
}
default:
return fmt.Errorf("invalid network mode: %s", c.hostConfig.NetworkMode)
return derr.ErrorCodeInvalidNetworkMode.WithArgs(c.hostConfig.NetworkMode)
}
pid := &execdriver.Pid{}
@ -90,22 +90,22 @@ func populateCommand(c *Container, env []string) error {
var layerPaths []string
img, err := c.daemon.graph.Get(c.ImageID)
if err != nil {
return fmt.Errorf("Failed to graph.Get on ImageID %s - %s", c.ImageID, err)
return derr.ErrorCodeGetGraph.WithArgs(c.ImageID, err)
}
for i := img; i != nil && err == nil; i, err = c.daemon.graph.GetParent(i) {
lp, err := c.daemon.driver.Get(i.ID, "")
if err != nil {
return fmt.Errorf("Failed to get layer path from graphdriver %s for ImageID %s - %s", c.daemon.driver.String(), i.ID, err)
return derr.ErrorCodeGetLayer.WithArgs(c.daemon.driver.String(), i.ID, err)
}
layerPaths = append(layerPaths, lp)
err = c.daemon.driver.Put(i.ID)
if err != nil {
return fmt.Errorf("Failed to put layer path from graphdriver %s for ImageID %s - %s", c.daemon.driver.String(), i.ID, err)
return derr.ErrorCodePutLayer.WithArgs(c.daemon.driver.String(), i.ID, err)
}
}
m, err := c.daemon.driver.GetMetadata(c.ID)
if err != nil {
return fmt.Errorf("Failed to get layer metadata - %s", err)
return derr.ErrorCodeGetLayerMetadata.WithArgs(err)
}
layerFolder := m["dir"]

View file

@ -1,10 +1,10 @@
package daemon
import (
"fmt"
"strings"
"github.com/Sirupsen/logrus"
derr "github.com/docker/docker/api/errors"
"github.com/docker/docker/api/types"
"github.com/docker/docker/graph/tags"
"github.com/docker/docker/image"
@ -17,7 +17,7 @@ import (
// ContainerCreate takes configs and creates a container.
func (daemon *Daemon) ContainerCreate(name string, config *runconfig.Config, hostConfig *runconfig.HostConfig, adjustCPUShares bool) (*Container, []string, error) {
if config == nil {
return nil, nil, fmt.Errorf("Config cannot be empty in order to create a container")
return nil, nil, derr.ErrorCodeEmptyConfig
}
warnings, err := daemon.verifyContainerSettings(hostConfig, config)
@ -31,13 +31,13 @@ func (daemon *Daemon) ContainerCreate(name string, config *runconfig.Config, hos
if err != nil {
if daemon.Graph().IsNotExist(err, config.Image) {
if strings.Contains(config.Image, "@") {
return nil, warnings, fmt.Errorf("No such image: %s", config.Image)
return nil, warnings, derr.ErrorCodeNoSuchImageHash.WithArgs(config.Image)
}
img, tag := parsers.ParseRepositoryTag(config.Image)
if tag == "" {
tag = tags.DefaultTag
}
return nil, warnings, fmt.Errorf("No such image: %s:%s", img, tag)
return nil, warnings, derr.ErrorCodeNoSuchImageTag.WithArgs(img, tag)
}
return nil, warnings, err
}

View file

@ -3,11 +3,11 @@
package daemon
import (
"fmt"
"os"
"path/filepath"
"strings"
derr "github.com/docker/docker/api/errors"
"github.com/docker/docker/image"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/runconfig"
@ -41,7 +41,7 @@ func createContainerPlatformSpecificSettings(container *Container, config *runco
stat, err := os.Stat(path)
if err == nil && !stat.IsDir() {
return fmt.Errorf("cannot mount volume over existing file, file exists %s", path)
return derr.ErrorCodeMountOverFile.WithArgs(path)
}
volumeDriver := hostConfig.VolumeDriver

View file

@ -1,10 +1,11 @@
package daemon
import (
"fmt"
"runtime"
derr "github.com/docker/docker/api/errors"
"github.com/docker/docker/runconfig"
"github.com/docker/docker/utils"
)
// ContainerStart starts a container.
@ -15,11 +16,11 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *runconfig.HostConf
}
if container.isPaused() {
return fmt.Errorf("Cannot start a paused container, try unpause instead.")
return derr.ErrorCodeStartPaused
}
if container.IsRunning() {
return fmt.Errorf("Container already started")
return derr.ErrorCodeAlreadyStarted
}
// Windows does not have the backwards compatibility issue here.
@ -33,7 +34,7 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *runconfig.HostConf
}
} else {
if hostConfig != nil {
return fmt.Errorf("Supplying a hostconfig on start is not supported. It should be supplied on create")
return derr.ErrorCodeHostConfigStart
}
}
@ -44,7 +45,7 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *runconfig.HostConf
}
if err := container.Start(); err != nil {
return fmt.Errorf("Cannot start container %s: %s", name, err)
return derr.ErrorCodeCantStart.WithArgs(name, utils.GetErrorMessage(err))
}
return nil

View file

@ -5,6 +5,7 @@ import (
"sync"
"time"
derr "github.com/docker/docker/api/errors"
"github.com/docker/docker/daemon/execdriver"
"github.com/docker/docker/pkg/units"
)
@ -111,7 +112,7 @@ func wait(waitChan <-chan struct{}, timeout time.Duration) error {
}
select {
case <-time.After(timeout):
return fmt.Errorf("Timed out: %v", timeout)
return derr.ErrorCodeTimedOut.WithArgs(timeout)
case <-waitChan:
return nil
}
@ -251,7 +252,7 @@ func (s *State) setRemovalInProgress() error {
s.Lock()
defer s.Unlock()
if s.removalInProgress {
return fmt.Errorf("Status is already RemovalInProgress")
return derr.ErrorCodeAlreadyRemoving
}
s.removalInProgress = true
return nil

View file

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

View file

@ -1,6 +1,8 @@
package daemon
import "fmt"
import (
derr "github.com/docker/docker/api/errors"
)
// ContainerStop looks for the given container and terminates it,
// waiting the given number of seconds before forcefully killing the
@ -14,10 +16,10 @@ func (daemon *Daemon) ContainerStop(name string, seconds int) error {
return err
}
if !container.IsRunning() {
return fmt.Errorf("Container already stopped")
return derr.ErrorCodeStopped
}
if err := container.Stop(seconds); err != nil {
return fmt.Errorf("Cannot stop container %s: %s\n", name, err)
return derr.ErrorCodeCantStop.WithArgs(name, err)
}
return nil
}

View file

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

View file

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

View file

@ -1,6 +1,8 @@
package daemon
import "fmt"
import (
derr "github.com/docker/docker/api/errors"
)
// ContainerUnpause unpauses a container
func (daemon *Daemon) ContainerUnpause(name string) error {
@ -10,7 +12,7 @@ func (daemon *Daemon) ContainerUnpause(name string) error {
}
if err := container.unpause(); err != nil {
return fmt.Errorf("Cannot unpause container %s: %s", name, err)
return derr.ErrorCodeCantUnpause.WithArgs(name, err)
}
return nil

View file

@ -10,6 +10,7 @@ import (
"sync"
"github.com/Sirupsen/logrus"
derr "github.com/docker/docker/api/errors"
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/chrootarchive"
"github.com/docker/docker/pkg/system"
@ -59,7 +60,7 @@ func (m *mountPoint) Setup() (string, error) {
return m.Source, nil
}
return "", fmt.Errorf("Unable to setup mount point, neither source nor volume defined")
return "", derr.ErrorCodeMountSetup
}
// hasResource checks whether the given absolute path for a container is in

View file

@ -3,7 +3,6 @@
package daemon
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
@ -11,6 +10,7 @@ import (
"strings"
"github.com/Sirupsen/logrus"
derr "github.com/docker/docker/api/errors"
"github.com/docker/docker/daemon/execdriver"
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/runconfig"
@ -72,18 +72,18 @@ func parseBindMount(spec, volumeDriver string) (*mountPoint, error) {
bind.Destination = arr[1]
mode := arr[2]
if !volume.ValidMountMode(mode) {
return nil, fmt.Errorf("invalid mode for volumes-from: %s", mode)
return nil, derr.ErrorCodeVolumeInvalidMode.WithArgs(mode)
}
bind.RW = volume.ReadWrite(mode)
// Mode field is used by SELinux to decide whether to apply label
bind.Mode = mode
default:
return nil, fmt.Errorf("Invalid volume specification: %s", spec)
return nil, derr.ErrorCodeVolumeInvalid.WithArgs(spec)
}
//validate the volumes destination path
if !filepath.IsAbs(bind.Destination) {
return nil, fmt.Errorf("Invalid volume destination path: %s mount path must be absolute.", bind.Destination)
return nil, derr.ErrorCodeVolumeAbs.WithArgs(bind.Destination)
}
name, source, err := parseVolumeSource(arr[0])
@ -263,7 +263,7 @@ func (daemon *Daemon) verifyVolumesInfo(container *Container) error {
// parseVolumesFrom ensure that the supplied volumes-from is valid.
func parseVolumesFrom(spec string) (string, string, error) {
if len(spec) == 0 {
return "", "", fmt.Errorf("malformed volumes-from specification: %s", spec)
return "", "", derr.ErrorCodeVolumeFromBlank.WithArgs(spec)
}
specParts := strings.SplitN(spec, ":", 2)
@ -273,7 +273,7 @@ func parseVolumesFrom(spec string) (string, string, error) {
if len(specParts) == 2 {
mode = specParts[1]
if !volume.ValidMountMode(mode) {
return "", "", fmt.Errorf("invalid mode for volumes-from: %s", mode)
return "", "", derr.ErrorCodeVolumeMode.WithArgs(mode)
}
}
return id, mode, nil
@ -336,7 +336,7 @@ func (daemon *Daemon) registerMountPoints(container *Container, hostConfig *runc
}
if binds[bind.Destination] {
return fmt.Errorf("Duplicate bind mount %s", bind.Destination)
return derr.ErrorCodeVolumeDup.WithArgs(bind.Destination)
}
if len(bind.Name) > 0 && len(bind.Driver) > 0 {

View file

@ -3010,7 +3010,7 @@ func (s *DockerSuite) TestRunContainerNetworkModeToSelf(c *check.C) {
testRequires(c, DaemonIsLinux)
out, _, err := dockerCmdWithError("run", "--name=me", "--net=container:me", "busybox", "true")
if err == nil || !strings.Contains(out, "cannot join own network") {
c.Fatalf("using container net mode to self should result in an error")
c.Fatalf("using container net mode to self should result in an error\nerr: %q\nout: %s", err, out)
}
}