errors.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. package daemon
  2. import (
  3. "fmt"
  4. "strings"
  5. "syscall"
  6. "github.com/docker/docker/errdefs"
  7. "github.com/pkg/errors"
  8. "google.golang.org/grpc"
  9. )
  10. func errNotRunning(id string) error {
  11. return errdefs.Conflict(errors.Errorf("Container %s is not running", id))
  12. }
  13. func containerNotFound(id string) error {
  14. return objNotFoundError{"container", id}
  15. }
  16. func volumeNotFound(id string) error {
  17. return objNotFoundError{"volume", id}
  18. }
  19. type objNotFoundError struct {
  20. object string
  21. id string
  22. }
  23. func (e objNotFoundError) Error() string {
  24. return "No such " + e.object + ": " + e.id
  25. }
  26. func (e objNotFoundError) NotFound() {}
  27. func errContainerIsRestarting(containerID string) error {
  28. cause := errors.Errorf("Container %s is restarting, wait until the container is running", containerID)
  29. return errdefs.Conflict(cause)
  30. }
  31. func errExecNotFound(id string) error {
  32. return objNotFoundError{"exec instance", id}
  33. }
  34. func errExecPaused(id string) error {
  35. cause := errors.Errorf("Container %s is paused, unpause the container before exec", id)
  36. return errdefs.Conflict(cause)
  37. }
  38. func errNotPaused(id string) error {
  39. cause := errors.Errorf("Container %s is already paused", id)
  40. return errdefs.Conflict(cause)
  41. }
  42. type nameConflictError struct {
  43. id string
  44. name string
  45. }
  46. func (e nameConflictError) Error() string {
  47. 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)
  48. }
  49. func (nameConflictError) Conflict() {}
  50. type containerNotModifiedError struct {
  51. running bool
  52. }
  53. func (e containerNotModifiedError) Error() string {
  54. if e.running {
  55. return "Container is already started"
  56. }
  57. return "Container is already stopped"
  58. }
  59. func (e containerNotModifiedError) NotModified() {}
  60. type invalidIdentifier string
  61. func (e invalidIdentifier) Error() string {
  62. return fmt.Sprintf("invalid name or ID supplied: %q", string(e))
  63. }
  64. func (invalidIdentifier) InvalidParameter() {}
  65. type duplicateMountPointError string
  66. func (e duplicateMountPointError) Error() string {
  67. return "Duplicate mount point: " + string(e)
  68. }
  69. func (duplicateMountPointError) InvalidParameter() {}
  70. type containerFileNotFound struct {
  71. file string
  72. container string
  73. }
  74. func (e containerFileNotFound) Error() string {
  75. return "Could not find the file " + e.file + " in container " + e.container
  76. }
  77. func (containerFileNotFound) NotFound() {}
  78. type invalidFilter struct {
  79. filter string
  80. value interface{}
  81. }
  82. func (e invalidFilter) Error() string {
  83. msg := "Invalid filter '" + e.filter
  84. if e.value != nil {
  85. msg += fmt.Sprintf("=%s", e.value)
  86. }
  87. return msg + "'"
  88. }
  89. func (e invalidFilter) InvalidParameter() {}
  90. type startInvalidConfigError string
  91. func (e startInvalidConfigError) Error() string {
  92. return string(e)
  93. }
  94. func (e startInvalidConfigError) InvalidParameter() {} // Is this right???
  95. func translateContainerdStartErr(cmd string, setExitCode func(int), err error) error {
  96. errDesc := grpc.ErrorDesc(err)
  97. contains := func(s1, s2 string) bool {
  98. return strings.Contains(strings.ToLower(s1), s2)
  99. }
  100. var retErr = errdefs.Unknown(errors.New(errDesc))
  101. // if we receive an internal error from the initial start of a container then lets
  102. // return it instead of entering the restart loop
  103. // set to 127 for container cmd not found/does not exist)
  104. if contains(errDesc, cmd) &&
  105. (contains(errDesc, "executable file not found") ||
  106. contains(errDesc, "no such file or directory") ||
  107. contains(errDesc, "system cannot find the file specified")) {
  108. setExitCode(127)
  109. retErr = startInvalidConfigError(errDesc)
  110. }
  111. // set to 126 for container cmd can't be invoked errors
  112. if contains(errDesc, syscall.EACCES.Error()) {
  113. setExitCode(126)
  114. retErr = startInvalidConfigError(errDesc)
  115. }
  116. // attempted to mount a file onto a directory, or a directory onto a file, maybe from user specified bind mounts
  117. if contains(errDesc, syscall.ENOTDIR.Error()) {
  118. 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"
  119. setExitCode(127)
  120. retErr = startInvalidConfigError(errDesc)
  121. }
  122. // TODO: it would be nice to get some better errors from containerd so we can return better errors here
  123. return retErr
  124. }