2018-03-06 10:41:43 -05:00
package daemon // import "github.com/docker/docker/daemon"
2018-03-06 10:32:47 -05:00
import (
"fmt"
"strings"
"syscall"
2018-03-06 10:41:43 -05:00
"github.com/docker/docker/errdefs"
2018-03-06 10:32:47 -05:00
"github.com/pkg/errors"
"google.golang.org/grpc"
)
func errNotRunning ( id string ) error {
2018-03-06 10:41:43 -05:00
return errdefs . Conflict ( errors . Errorf ( "Container %s is not running" , id ) )
2018-03-06 10:32:47 -05:00
}
func containerNotFound ( id string ) error {
return objNotFoundError { "container" , id }
}
func volumeNotFound ( id string ) error {
return objNotFoundError { "volume" , id }
}
type objNotFoundError struct {
object string
id string
}
func ( e objNotFoundError ) Error ( ) string {
return "No such " + e . object + ": " + e . id
}
func ( e objNotFoundError ) NotFound ( ) { }
func errContainerIsRestarting ( containerID string ) error {
cause := errors . Errorf ( "Container %s is restarting, wait until the container is running" , containerID )
2018-03-06 10:41:43 -05:00
return errdefs . Conflict ( cause )
2018-03-06 10:32:47 -05:00
}
func errExecNotFound ( id string ) error {
return objNotFoundError { "exec instance" , id }
}
func errExecPaused ( id string ) error {
cause := errors . Errorf ( "Container %s is paused, unpause the container before exec" , id )
2018-03-06 10:41:43 -05:00
return errdefs . Conflict ( cause )
2018-03-06 10:32:47 -05:00
}
func errNotPaused ( id string ) error {
cause := errors . Errorf ( "Container %s is already paused" , id )
2018-03-06 10:41:43 -05:00
return errdefs . Conflict ( cause )
2018-03-06 10:32:47 -05:00
}
type nameConflictError struct {
id string
name string
}
func ( e nameConflictError ) Error ( ) string {
return fmt . Sprintf ( "Conflict. The container name %q is already in use by container %q. You have to remove (or rename) that container to be able to reuse that name." , e . name , e . id )
}
func ( nameConflictError ) Conflict ( ) { }
type containerNotModifiedError struct {
running bool
}
func ( e containerNotModifiedError ) Error ( ) string {
if e . running {
return "Container is already started"
}
return "Container is already stopped"
}
func ( e containerNotModifiedError ) NotModified ( ) { }
type invalidIdentifier string
func ( e invalidIdentifier ) Error ( ) string {
return fmt . Sprintf ( "invalid name or ID supplied: %q" , string ( e ) )
}
func ( invalidIdentifier ) InvalidParameter ( ) { }
type duplicateMountPointError string
func ( e duplicateMountPointError ) Error ( ) string {
return "Duplicate mount point: " + string ( e )
}
func ( duplicateMountPointError ) InvalidParameter ( ) { }
type containerFileNotFound struct {
file string
container string
}
func ( e containerFileNotFound ) Error ( ) string {
return "Could not find the file " + e . file + " in container " + e . container
}
func ( containerFileNotFound ) NotFound ( ) { }
type invalidFilter struct {
filter string
value interface { }
}
func ( e invalidFilter ) Error ( ) string {
msg := "Invalid filter '" + e . filter
if e . value != nil {
msg += fmt . Sprintf ( "=%s" , e . value )
}
return msg + "'"
}
func ( e invalidFilter ) InvalidParameter ( ) { }
type startInvalidConfigError string
func ( e startInvalidConfigError ) Error ( ) string {
return string ( e )
}
func ( e startInvalidConfigError ) InvalidParameter ( ) { } // Is this right???
func translateContainerdStartErr ( cmd string , setExitCode func ( int ) , err error ) error {
errDesc := grpc . ErrorDesc ( err )
contains := func ( s1 , s2 string ) bool {
return strings . Contains ( strings . ToLower ( s1 ) , s2 )
}
2018-03-06 10:41:43 -05:00
var retErr = errdefs . Unknown ( errors . New ( errDesc ) )
2018-03-06 10:32:47 -05:00
// if we receive an internal error from the initial start of a container then lets
// return it instead of entering the restart loop
// set to 127 for container cmd not found/does not exist)
if contains ( errDesc , cmd ) &&
( contains ( errDesc , "executable file not found" ) ||
contains ( errDesc , "no such file or directory" ) ||
contains ( errDesc , "system cannot find the file specified" ) ) {
setExitCode ( 127 )
retErr = startInvalidConfigError ( errDesc )
}
// set to 126 for container cmd can't be invoked errors
if contains ( errDesc , syscall . EACCES . Error ( ) ) {
setExitCode ( 126 )
retErr = startInvalidConfigError ( errDesc )
}
// attempted to mount a file onto a directory, or a directory onto a file, maybe from user specified bind mounts
if contains ( errDesc , syscall . ENOTDIR . Error ( ) ) {
errDesc += ": Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type"
setExitCode ( 127 )
retErr = startInvalidConfigError ( errDesc )
}
// TODO: it would be nice to get some better errors from containerd so we can return better errors here
return retErr
}