Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

errors.py 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. import requests
  2. _image_not_found_explanation_fragments = frozenset(
  3. fragment.lower() for fragment in [
  4. 'no such image',
  5. 'not found: does not exist or no pull access',
  6. 'repository does not exist',
  7. 'was found but does not match the specified platform',
  8. ]
  9. )
  10. class DockerException(Exception):
  11. """
  12. A base class from which all other exceptions inherit.
  13. If you want to catch all errors that the Docker SDK might raise,
  14. catch this base exception.
  15. """
  16. def create_api_error_from_http_exception(e):
  17. """
  18. Create a suitable APIError from requests.exceptions.HTTPError.
  19. """
  20. response = e.response
  21. try:
  22. explanation = response.json()['message']
  23. except ValueError:
  24. explanation = (response.content or '').strip()
  25. cls = APIError
  26. if response.status_code == 404:
  27. explanation_msg = (explanation or '').lower()
  28. if any(fragment in explanation_msg
  29. for fragment in _image_not_found_explanation_fragments):
  30. cls = ImageNotFound
  31. else:
  32. cls = NotFound
  33. raise cls(e, response=response, explanation=explanation) from e
  34. class APIError(requests.exceptions.HTTPError, DockerException):
  35. """
  36. An HTTP error from the API.
  37. """
  38. def __init__(self, message, response=None, explanation=None):
  39. # requests 1.2 supports response as a keyword argument, but
  40. # requests 1.1 doesn't
  41. super().__init__(message)
  42. self.response = response
  43. self.explanation = explanation
  44. def __str__(self):
  45. message = super().__str__()
  46. if self.is_client_error():
  47. message = '{} Client Error for {}: {}'.format(
  48. self.response.status_code, self.response.url,
  49. self.response.reason)
  50. elif self.is_server_error():
  51. message = '{} Server Error for {}: {}'.format(
  52. self.response.status_code, self.response.url,
  53. self.response.reason)
  54. if self.explanation:
  55. message = f'{message} ("{self.explanation}")'
  56. return message
  57. @property
  58. def status_code(self):
  59. if self.response is not None:
  60. return self.response.status_code
  61. def is_error(self):
  62. return self.is_client_error() or self.is_server_error()
  63. def is_client_error(self):
  64. if self.status_code is None:
  65. return False
  66. return 400 <= self.status_code < 500
  67. def is_server_error(self):
  68. if self.status_code is None:
  69. return False
  70. return 500 <= self.status_code < 600
  71. class NotFound(APIError):
  72. pass
  73. class ImageNotFound(NotFound):
  74. pass
  75. class InvalidVersion(DockerException):
  76. pass
  77. class InvalidRepository(DockerException):
  78. pass
  79. class InvalidConfigFile(DockerException):
  80. pass
  81. class InvalidArgument(DockerException):
  82. pass
  83. class DeprecatedMethod(DockerException):
  84. pass
  85. class TLSParameterError(DockerException):
  86. def __init__(self, msg):
  87. self.msg = msg
  88. def __str__(self):
  89. return self.msg + (". TLS configurations should map the Docker CLI "
  90. "client configurations. See "
  91. "https://docs.docker.com/engine/articles/https/ "
  92. "for API details.")
  93. class NullResource(DockerException, ValueError):
  94. pass
  95. class ContainerError(DockerException):
  96. """
  97. Represents a container that has exited with a non-zero exit code.
  98. """
  99. def __init__(self, container, exit_status, command, image, stderr):
  100. self.container = container
  101. self.exit_status = exit_status
  102. self.command = command
  103. self.image = image
  104. self.stderr = stderr
  105. err = f": {stderr}" if stderr is not None else ""
  106. msg = ("Command '{}' in image '{}' returned non-zero exit "
  107. "status {}{}").format(command, image, exit_status, err)
  108. super().__init__(msg)
  109. class StreamParseError(RuntimeError):
  110. def __init__(self, reason):
  111. self.msg = reason
  112. class BuildError(DockerException):
  113. def __init__(self, reason, build_log):
  114. super().__init__(reason)
  115. self.msg = reason
  116. self.build_log = build_log
  117. class ImageLoadError(DockerException):
  118. pass
  119. def create_unexpected_kwargs_error(name, kwargs):
  120. quoted_kwargs = [f"'{k}'" for k in sorted(kwargs)]
  121. text = [f"{name}() "]
  122. if len(quoted_kwargs) == 1:
  123. text.append("got an unexpected keyword argument ")
  124. else:
  125. text.append("got unexpected keyword arguments ")
  126. text.append(', '.join(quoted_kwargs))
  127. return TypeError(''.join(text))
  128. class MissingContextParameter(DockerException):
  129. def __init__(self, param):
  130. self.param = param
  131. def __str__(self):
  132. return (f"missing parameter: {self.param}")
  133. class ContextAlreadyExists(DockerException):
  134. def __init__(self, name):
  135. self.name = name
  136. def __str__(self):
  137. return (f"context {self.name} already exists")
  138. class ContextException(DockerException):
  139. def __init__(self, msg):
  140. self.msg = msg
  141. def __str__(self):
  142. return (self.msg)
  143. class ContextNotFound(DockerException):
  144. def __init__(self, name):
  145. self.name = name
  146. def __str__(self):
  147. return (f"context '{self.name}' not found")