import bitmath class V2RegistryException(Exception): def __init__( self, error_code_str, message, detail, http_status_code=400, repository=None, scopes=None, is_read_only=False, ): super(V2RegistryException, self).__init__(message) self.http_status_code = http_status_code self.repository = repository self.scopes = scopes self.is_read_only = is_read_only self._error_code_str = error_code_str self._detail = detail def as_dict(self): error_dict = { "code": self._error_code_str, "message": str(self), "detail": self._detail if self._detail is not None else {}, } if self.is_read_only: error_dict["is_readonly"] = True return error_dict class BlobUnknown(V2RegistryException): def __init__(self, detail=None): super(BlobUnknown, self).__init__("BLOB_UNKNOWN", "blob unknown to registry", detail, 404) class BlobUploadInvalid(V2RegistryException): def __init__(self, detail=None): super(BlobUploadInvalid, self).__init__( "BLOB_UPLOAD_INVALID", "blob upload invalid", detail ) class BlobUploadUnknown(V2RegistryException): def __init__(self, detail=None): super(BlobUploadUnknown, self).__init__( "BLOB_UPLOAD_UNKNOWN", "blob upload unknown to registry", detail, 404 ) class DigestInvalid(V2RegistryException): def __init__(self, detail=None): super(DigestInvalid, self).__init__( "DIGEST_INVALID", "provided digest did not match uploaded content", detail ) class ManifestBlobUnknown(V2RegistryException): def __init__(self, detail=None): super(ManifestBlobUnknown, self).__init__( "MANIFEST_BLOB_UNKNOWN", "manifest blob unknown to registry", detail ) class ManifestInvalid(V2RegistryException): def __init__(self, detail=None, http_status_code=400): super(ManifestInvalid, self).__init__( "MANIFEST_INVALID", "manifest invalid", detail, http_status_code ) class ManifestUnknown(V2RegistryException): def __init__(self, message=None, detail=None): super(ManifestUnknown, self).__init__( "MANIFEST_UNKNOWN", message or "manifest unknown", detail, 404 ) class TagExpired(V2RegistryException): def __init__(self, message=None, detail=None): super(TagExpired, self).__init__("TAG_EXPIRED", message or "Tag has expired", detail, 404) class ManifestUnverified(V2RegistryException): def __init__(self, detail=None): super(ManifestUnverified, self).__init__( "MANIFEST_UNVERIFIED", "manifest failed signature verification", detail ) class NameInvalid(V2RegistryException): def __init__(self, detail=None, message=None): super(NameInvalid, self).__init__( "NAME_INVALID", message or "invalid repository name", detail ) class NameUnknown(V2RegistryException): def __init__(self, message, detail=None): super(NameUnknown, self).__init__( "NAME_UNKNOWN", message or "repository name not known to registry", detail, 404 ) class SizeInvalid(V2RegistryException): def __init__(self, detail=None): super(SizeInvalid, self).__init__( "SIZE_INVALID", "provided length did not match content length", detail ) class TagAlreadyExists(V2RegistryException): def __init__(self, detail=None): super(TagAlreadyExists, self).__init__( "TAG_ALREADY_EXISTS", "tag was already pushed", detail, 409 ) class TagInvalid(V2RegistryException): def __init__(self, detail=None): super(TagInvalid, self).__init__("TAG_INVALID", "manifest tag did not match URI", detail) class LayerTooLarge(V2RegistryException): def __init__(self, uploaded=None, max_allowed=None): detail = {} message = "Uploaded blob is larger than allowed by this registry" if uploaded is not None and max_allowed is not None: detail = { "reason": "%s is greater than maximum allowed size %s" % (uploaded, max_allowed), "max_allowed": max_allowed, "uploaded": uploaded, } up_str = bitmath.Byte(uploaded).best_prefix().format("{value:.2f} {unit}") max_str = bitmath.Byte(max_allowed).best_prefix().format("{value:.2f} {unit}") message = "Uploaded blob of %s is larger than %s allowed by this registry" % ( up_str, max_str, ) class QuotaExceeded(V2RegistryException): def __init__(self): super(QuotaExceeded, self).__init__( "DENIED", "Quota has been exceeded on namespace", {}, 403 ) class Unauthorized(V2RegistryException): def __init__(self, detail=None, repository=None, scopes=None): super(Unauthorized, self).__init__( "UNAUTHORIZED", "access to the requested resource is not authorized", detail, 401, repository=repository, scopes=scopes, ) class Unsupported(V2RegistryException): def __init__(self, detail=None, message=None): super(Unsupported, self).__init__( "UNSUPPORTED", message or "The operation is unsupported.", detail, 405 ) class InvalidLogin(V2RegistryException): def __init__(self, message=None): super(InvalidLogin, self).__init__( "UNAUTHORIZED", message or "Specified credentials are invalid", {}, 401 ) class InvalidRequest(V2RegistryException): def __init__(self, message=None): super(InvalidRequest, self).__init__( "INVALID_REQUEST", message or "Invalid request", {}, 400 ) class NamespaceDisabled(V2RegistryException): def __init__(self, message=None): message = message or "This namespace is disabled. Please contact your system administrator." super(NamespaceDisabled, self).__init__("DENIED", message, {}, 405) class BlobDownloadGeoBlocked(V2RegistryException): def __init__(self, detail=None): message = ( "The region from which you are pulling has been geo-ip blocked. " + "Please contact the namespace owner." ) super(BlobDownloadGeoBlocked, self).__init__("DENIED", message, detail, 403) class ReadOnlyMode(V2RegistryException): def __init__(self, detail=None): message = ( "System is currently read-only. Pulls will succeed but all write operations " + "are currently suspended." ) super(ReadOnlyMode, self).__init__("DENIED", message, detail, 405, is_read_only=True)