Merge pull request #4040 from thaJeztah/move_api_errors

This commit is contained in:
Milos Gajdos 2023-09-15 09:36:36 +01:00 committed by GitHub
commit 612ad42609
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 367 additions and 289 deletions

View file

@ -10,21 +10,21 @@ import (
// TestErrorsManagement does a quick check of the Errors type to ensure that
// members are properly pushed and marshaled.
var ErrorCodeTest1 = Register("test.errors", ErrorDescriptor{
var ErrorCodeTest1 = register("test.errors", ErrorDescriptor{
Value: "TEST1",
Message: "test error 1",
Description: `Just a test message #1.`,
HTTPStatusCode: http.StatusInternalServerError,
})
var ErrorCodeTest2 = Register("test.errors", ErrorDescriptor{
var ErrorCodeTest2 = register("test.errors", ErrorDescriptor{
Value: "TEST2",
Message: "test error 2",
Description: `Just a test message #2.`,
HTTPStatusCode: http.StatusNotFound,
})
var ErrorCodeTest3 = Register("test.errors", ErrorDescriptor{
var ErrorCodeTest3 = register("test.errors", ErrorDescriptor{
Value: "TEST3",
Message: "Sorry %q isn't valid",
Description: `Just a test message #3.`,

View file

@ -16,7 +16,7 @@ var (
var (
// ErrorCodeUnknown is a generic error that can be used as a last
// resort if there is no situation-specific error message that can be used
ErrorCodeUnknown = Register("errcode", ErrorDescriptor{
ErrorCodeUnknown = register("errcode", ErrorDescriptor{
Value: "UNKNOWN",
Message: "unknown error",
Description: `Generic error returned when the error does not have an
@ -25,7 +25,7 @@ var (
})
// ErrorCodeUnsupported is returned when an operation is not supported.
ErrorCodeUnsupported = Register("errcode", ErrorDescriptor{
ErrorCodeUnsupported = register("errcode", ErrorDescriptor{
Value: "UNSUPPORTED",
Message: "The operation is unsupported.",
Description: `The operation was unsupported due to a missing
@ -35,7 +35,7 @@ var (
// ErrorCodeUnauthorized is returned if a request requires
// authentication.
ErrorCodeUnauthorized = Register("errcode", ErrorDescriptor{
ErrorCodeUnauthorized = register("errcode", ErrorDescriptor{
Value: "UNAUTHORIZED",
Message: "authentication required",
Description: `The access controller was unable to authenticate
@ -47,7 +47,7 @@ var (
// ErrorCodeDenied is returned if a client does not have sufficient
// permission to perform an action.
ErrorCodeDenied = Register("errcode", ErrorDescriptor{
ErrorCodeDenied = register("errcode", ErrorDescriptor{
Value: "DENIED",
Message: "requested access to the resource is denied",
Description: `The access controller denied access for the
@ -57,7 +57,7 @@ var (
// ErrorCodeUnavailable provides a common error to report unavailability
// of a service or endpoint.
ErrorCodeUnavailable = Register("errcode", ErrorDescriptor{
ErrorCodeUnavailable = register("errcode", ErrorDescriptor{
Value: "UNAVAILABLE",
Message: "service unavailable",
Description: "Returned when a service is not available",
@ -66,7 +66,7 @@ var (
// ErrorCodeTooManyRequests is returned if a client attempts too many
// times to contact a service endpoint.
ErrorCodeTooManyRequests = Register("errcode", ErrorDescriptor{
ErrorCodeTooManyRequests = register("errcode", ErrorDescriptor{
Value: "TOOMANYREQUESTS",
Message: "too many requests",
Description: `Returned when a client attempts to contact a
@ -75,6 +75,157 @@ var (
})
)
const errGroup = "registry.api.v2"
var (
// ErrorCodeDigestInvalid is returned when uploading a blob if the
// provided digest does not match the blob contents.
ErrorCodeDigestInvalid = register(errGroup, ErrorDescriptor{
Value: "DIGEST_INVALID",
Message: "provided digest did not match uploaded content",
Description: `When a blob is uploaded, the registry will check that
the content matches the digest provided by the client. The error may
include a detail structure with the key "digest", including the
invalid digest string. This error may also be returned when a manifest
includes an invalid layer digest.`,
HTTPStatusCode: http.StatusBadRequest,
})
// ErrorCodeSizeInvalid is returned when uploading a blob if the provided
ErrorCodeSizeInvalid = register(errGroup, ErrorDescriptor{
Value: "SIZE_INVALID",
Message: "provided length did not match content length",
Description: `When a layer is uploaded, the provided size will be
checked against the uploaded content. If they do not match, this error
will be returned.`,
HTTPStatusCode: http.StatusBadRequest,
})
// ErrorCodeRangeInvalid is returned when uploading a blob if the provided
// content range is invalid.
ErrorCodeRangeInvalid = register(errGroup, ErrorDescriptor{
Value: "RANGE_INVALID",
Message: "invalid content range",
Description: `When a layer is uploaded, the provided range is checked
against the uploaded chunk. This error is returned if the range is
out of order.`,
HTTPStatusCode: http.StatusRequestedRangeNotSatisfiable,
})
// ErrorCodeNameInvalid is returned when the name in the manifest does not
// match the provided name.
ErrorCodeNameInvalid = register(errGroup, ErrorDescriptor{
Value: "NAME_INVALID",
Message: "invalid repository name",
Description: `Invalid repository name encountered either during
manifest validation or any API operation.`,
HTTPStatusCode: http.StatusBadRequest,
})
// ErrorCodeTagInvalid is returned when the tag in the manifest does not
// match the provided tag.
ErrorCodeTagInvalid = register(errGroup, ErrorDescriptor{
Value: "TAG_INVALID",
Message: "manifest tag did not match URI",
Description: `During a manifest upload, if the tag in the manifest
does not match the uri tag, this error will be returned.`,
HTTPStatusCode: http.StatusBadRequest,
})
// ErrorCodeNameUnknown when the repository name is not known.
ErrorCodeNameUnknown = register(errGroup, ErrorDescriptor{
Value: "NAME_UNKNOWN",
Message: "repository name not known to registry",
Description: `This is returned if the name used during an operation is
unknown to the registry.`,
HTTPStatusCode: http.StatusNotFound,
})
// ErrorCodeManifestUnknown returned when image manifest is unknown.
ErrorCodeManifestUnknown = register(errGroup, ErrorDescriptor{
Value: "MANIFEST_UNKNOWN",
Message: "manifest unknown",
Description: `This error is returned when the manifest, identified by
name and tag is unknown to the repository.`,
HTTPStatusCode: http.StatusNotFound,
})
// ErrorCodeManifestInvalid returned when an image manifest is invalid,
// typically during a PUT operation. This error encompasses all errors
// encountered during manifest validation that aren't signature errors.
ErrorCodeManifestInvalid = register(errGroup, ErrorDescriptor{
Value: "MANIFEST_INVALID",
Message: "manifest invalid",
Description: `During upload, manifests undergo several checks ensuring
validity. If those checks fail, this error may be returned, unless a
more specific error is included. The detail will contain information
the failed validation.`,
HTTPStatusCode: http.StatusBadRequest,
})
// ErrorCodeManifestUnverified is returned when the manifest fails
// signature verification.
ErrorCodeManifestUnverified = register(errGroup, ErrorDescriptor{
Value: "MANIFEST_UNVERIFIED",
Message: "manifest failed signature verification",
Description: `During manifest upload, if the manifest fails signature
verification, this error will be returned.`,
HTTPStatusCode: http.StatusBadRequest,
})
// ErrorCodeManifestBlobUnknown is returned when a manifest blob is
// unknown to the registry.
ErrorCodeManifestBlobUnknown = register(errGroup, ErrorDescriptor{
Value: "MANIFEST_BLOB_UNKNOWN",
Message: "blob unknown to registry",
Description: `This error may be returned when a manifest blob is
unknown to the registry.`,
HTTPStatusCode: http.StatusBadRequest,
})
// ErrorCodeBlobUnknown is returned when a blob is unknown to the
// registry. This can happen when the manifest references a nonexistent
// layer or the result is not found by a blob fetch.
ErrorCodeBlobUnknown = register(errGroup, ErrorDescriptor{
Value: "BLOB_UNKNOWN",
Message: "blob unknown to registry",
Description: `This error may be returned when a blob is unknown to the
registry in a specified repository. This can be returned with a
standard get or if a manifest references an unknown layer during
upload.`,
HTTPStatusCode: http.StatusNotFound,
})
// ErrorCodeBlobUploadUnknown is returned when an upload is unknown.
ErrorCodeBlobUploadUnknown = register(errGroup, ErrorDescriptor{
Value: "BLOB_UPLOAD_UNKNOWN",
Message: "blob upload unknown to registry",
Description: `If a blob upload has been cancelled or was never
started, this error code may be returned.`,
HTTPStatusCode: http.StatusNotFound,
})
// ErrorCodeBlobUploadInvalid is returned when an upload is invalid.
ErrorCodeBlobUploadInvalid = register(errGroup, ErrorDescriptor{
Value: "BLOB_UPLOAD_INVALID",
Message: "blob upload invalid",
Description: `The blob upload encountered an error and can no
longer proceed.`,
HTTPStatusCode: http.StatusNotFound,
})
// ErrorCodePaginationNumberInvalid is returned when the `n` parameter is
// not an integer, or `n` is negative.
ErrorCodePaginationNumberInvalid = register(errGroup, ErrorDescriptor{
Value: "PAGINATION_NUMBER_INVALID",
Message: "invalid number of results requested",
Description: `Returned when the "n" parameter (number of results
to return) is not an integer, "n" is negative or "n" is bigger than
the maximum allowed.`,
HTTPStatusCode: http.StatusBadRequest,
})
)
var (
nextCode = 1000
registerLock sync.Mutex
@ -83,6 +234,12 @@ var (
// Register will make the passed-in error known to the environment and
// return a new ErrorCode
func Register(group string, descriptor ErrorDescriptor) ErrorCode {
return register(group, descriptor)
}
// register will make the passed-in error known to the environment and
// return a new ErrorCode
func register(group string, descriptor ErrorDescriptor) ErrorCode {
registerLock.Lock()
defer registerLock.Unlock()

View file

@ -143,7 +143,7 @@ var (
Format: errorsBody,
},
ErrorCodes: []errcode.ErrorCode{
ErrorCodePaginationNumberInvalid,
errcode.ErrorCodePaginationNumberInvalid,
},
}
@ -164,7 +164,7 @@ var (
Format: errorsBody,
},
ErrorCodes: []errcode.ErrorCode{
ErrorCodeNameUnknown,
errcode.ErrorCodeNameUnknown,
},
}
@ -550,8 +550,8 @@ var routeDescriptors = []RouteDescriptor{
Description: "The name or reference was invalid.",
StatusCode: http.StatusBadRequest,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeNameInvalid,
ErrorCodeTagInvalid,
errcode.ErrorCodeNameInvalid,
errcode.ErrorCodeTagInvalid,
},
Body: BodyDescriptor{
ContentType: "application/json",
@ -609,11 +609,11 @@ var routeDescriptors = []RouteDescriptor{
Format: errorsBody,
},
ErrorCodes: []errcode.ErrorCode{
ErrorCodeNameInvalid,
ErrorCodeTagInvalid,
ErrorCodeManifestInvalid,
ErrorCodeManifestUnverified,
ErrorCodeBlobUnknown,
errcode.ErrorCodeNameInvalid,
errcode.ErrorCodeTagInvalid,
errcode.ErrorCodeManifestInvalid,
errcode.ErrorCodeManifestUnverified,
errcode.ErrorCodeBlobUnknown,
},
},
unauthorizedResponseDescriptor,
@ -625,7 +625,7 @@ var routeDescriptors = []RouteDescriptor{
Description: "One or more layers may be missing during a manifest upload. If so, the missing layers will be enumerated in the error response.",
StatusCode: http.StatusBadRequest,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeBlobUnknown,
errcode.ErrorCodeBlobUnknown,
},
Body: BodyDescriptor{
ContentType: "application/json",
@ -678,8 +678,8 @@ var routeDescriptors = []RouteDescriptor{
Description: "The specified `name` or `reference` were invalid and the delete was unable to proceed.",
StatusCode: http.StatusBadRequest,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeNameInvalid,
ErrorCodeTagInvalid,
errcode.ErrorCodeNameInvalid,
errcode.ErrorCodeTagInvalid,
},
Body: BodyDescriptor{
ContentType: "application/json",
@ -695,8 +695,8 @@ var routeDescriptors = []RouteDescriptor{
Description: "The specified `name` or `reference` are unknown to the registry and the delete was unable to proceed. Clients can assume the manifest or tag was already deleted if this response is returned.",
StatusCode: http.StatusNotFound,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeNameUnknown,
ErrorCodeManifestUnknown,
errcode.ErrorCodeNameUnknown,
errcode.ErrorCodeManifestUnknown,
},
Body: BodyDescriptor{
ContentType: "application/json",
@ -775,8 +775,8 @@ var routeDescriptors = []RouteDescriptor{
Description: "There was a problem with the request that needs to be addressed by the client, such as an invalid `name` or `tag`.",
StatusCode: http.StatusBadRequest,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeNameInvalid,
ErrorCodeDigestInvalid,
errcode.ErrorCodeNameInvalid,
errcode.ErrorCodeDigestInvalid,
},
Body: BodyDescriptor{
ContentType: "application/json",
@ -791,8 +791,8 @@ var routeDescriptors = []RouteDescriptor{
Format: errorsBody,
},
ErrorCodes: []errcode.ErrorCode{
ErrorCodeNameUnknown,
ErrorCodeBlobUnknown,
errcode.ErrorCodeNameUnknown,
errcode.ErrorCodeBlobUnknown,
},
},
unauthorizedResponseDescriptor,
@ -847,8 +847,8 @@ var routeDescriptors = []RouteDescriptor{
Description: "There was a problem with the request that needs to be addressed by the client, such as an invalid `name` or `tag`.",
StatusCode: http.StatusBadRequest,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeNameInvalid,
ErrorCodeDigestInvalid,
errcode.ErrorCodeNameInvalid,
errcode.ErrorCodeDigestInvalid,
},
Body: BodyDescriptor{
ContentType: "application/json",
@ -858,8 +858,8 @@ var routeDescriptors = []RouteDescriptor{
{
StatusCode: http.StatusNotFound,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeNameUnknown,
ErrorCodeBlobUnknown,
errcode.ErrorCodeNameUnknown,
errcode.ErrorCodeBlobUnknown,
},
Body: BodyDescriptor{
ContentType: "application/json",
@ -910,8 +910,8 @@ var routeDescriptors = []RouteDescriptor{
Name: "Invalid Name or Digest",
StatusCode: http.StatusBadRequest,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeDigestInvalid,
ErrorCodeNameInvalid,
errcode.ErrorCodeDigestInvalid,
errcode.ErrorCodeNameInvalid,
},
},
{
@ -922,8 +922,8 @@ var routeDescriptors = []RouteDescriptor{
Format: errorsBody,
},
ErrorCodes: []errcode.ErrorCode{
ErrorCodeNameUnknown,
ErrorCodeBlobUnknown,
errcode.ErrorCodeNameUnknown,
errcode.ErrorCodeBlobUnknown,
},
},
{
@ -1010,8 +1010,8 @@ var routeDescriptors = []RouteDescriptor{
Name: "Invalid Name or Digest",
StatusCode: http.StatusBadRequest,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeDigestInvalid,
ErrorCodeNameInvalid,
errcode.ErrorCodeDigestInvalid,
errcode.ErrorCodeNameInvalid,
},
},
{
@ -1065,8 +1065,8 @@ var routeDescriptors = []RouteDescriptor{
Name: "Invalid Name or Digest",
StatusCode: http.StatusBadRequest,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeDigestInvalid,
ErrorCodeNameInvalid,
errcode.ErrorCodeDigestInvalid,
errcode.ErrorCodeNameInvalid,
},
},
unauthorizedResponseDescriptor,
@ -1122,8 +1122,8 @@ var routeDescriptors = []RouteDescriptor{
Name: "Invalid Name or Digest",
StatusCode: http.StatusBadRequest,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeDigestInvalid,
ErrorCodeNameInvalid,
errcode.ErrorCodeDigestInvalid,
errcode.ErrorCodeNameInvalid,
},
},
{
@ -1187,9 +1187,9 @@ var routeDescriptors = []RouteDescriptor{
Description: "There was an error processing the upload and it must be restarted.",
StatusCode: http.StatusBadRequest,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeDigestInvalid,
ErrorCodeNameInvalid,
ErrorCodeBlobUploadInvalid,
errcode.ErrorCodeDigestInvalid,
errcode.ErrorCodeNameInvalid,
errcode.ErrorCodeBlobUploadInvalid,
},
Body: BodyDescriptor{
ContentType: "application/json",
@ -1200,7 +1200,7 @@ var routeDescriptors = []RouteDescriptor{
Description: "The upload is unknown to the registry. The upload must be restarted.",
StatusCode: http.StatusNotFound,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeBlobUploadUnknown,
errcode.ErrorCodeBlobUploadUnknown,
},
Body: BodyDescriptor{
ContentType: "application/json",
@ -1262,9 +1262,9 @@ var routeDescriptors = []RouteDescriptor{
Description: "There was an error processing the upload and it must be restarted.",
StatusCode: http.StatusBadRequest,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeDigestInvalid,
ErrorCodeNameInvalid,
ErrorCodeBlobUploadInvalid,
errcode.ErrorCodeDigestInvalid,
errcode.ErrorCodeNameInvalid,
errcode.ErrorCodeBlobUploadInvalid,
},
Body: BodyDescriptor{
ContentType: "application/json",
@ -1275,7 +1275,7 @@ var routeDescriptors = []RouteDescriptor{
Description: "The upload is unknown to the registry. The upload must be restarted.",
StatusCode: http.StatusNotFound,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeBlobUploadUnknown,
errcode.ErrorCodeBlobUploadUnknown,
},
Body: BodyDescriptor{
ContentType: "application/json",
@ -1344,9 +1344,9 @@ var routeDescriptors = []RouteDescriptor{
Description: "There was an error processing the upload and it must be restarted.",
StatusCode: http.StatusBadRequest,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeDigestInvalid,
ErrorCodeNameInvalid,
ErrorCodeBlobUploadInvalid,
errcode.ErrorCodeDigestInvalid,
errcode.ErrorCodeNameInvalid,
errcode.ErrorCodeBlobUploadInvalid,
},
Body: BodyDescriptor{
ContentType: "application/json",
@ -1357,7 +1357,7 @@ var routeDescriptors = []RouteDescriptor{
Description: "The upload is unknown to the registry. The upload must be restarted.",
StatusCode: http.StatusNotFound,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeBlobUploadUnknown,
errcode.ErrorCodeBlobUploadUnknown,
},
Body: BodyDescriptor{
ContentType: "application/json",
@ -1438,9 +1438,9 @@ var routeDescriptors = []RouteDescriptor{
Description: "There was an error processing the upload and it must be restarted.",
StatusCode: http.StatusBadRequest,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeDigestInvalid,
ErrorCodeNameInvalid,
ErrorCodeBlobUploadInvalid,
errcode.ErrorCodeDigestInvalid,
errcode.ErrorCodeNameInvalid,
errcode.ErrorCodeBlobUploadInvalid,
errcode.ErrorCodeUnsupported,
},
Body: BodyDescriptor{
@ -1452,7 +1452,7 @@ var routeDescriptors = []RouteDescriptor{
Description: "The upload is unknown to the registry. The upload must be restarted.",
StatusCode: http.StatusNotFound,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeBlobUploadUnknown,
errcode.ErrorCodeBlobUploadUnknown,
},
Body: BodyDescriptor{
ContentType: "application/json",
@ -1497,8 +1497,8 @@ var routeDescriptors = []RouteDescriptor{
Description: "An error was encountered processing the delete. The client may ignore this error.",
StatusCode: http.StatusBadRequest,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeNameInvalid,
ErrorCodeBlobUploadInvalid,
errcode.ErrorCodeNameInvalid,
errcode.ErrorCodeBlobUploadInvalid,
},
Body: BodyDescriptor{
ContentType: "application/json",
@ -1509,7 +1509,7 @@ var routeDescriptors = []RouteDescriptor{
Description: "The upload is unknown to the registry. The client may ignore this error and assume the upload has been deleted.",
StatusCode: http.StatusNotFound,
ErrorCodes: []errcode.ErrorCode{
ErrorCodeBlobUploadUnknown,
errcode.ErrorCodeBlobUploadUnknown,
},
Body: BodyDescriptor{
ContentType: "application/json",

View file

@ -1,158 +0,0 @@
package v2
import (
"net/http"
"github.com/distribution/distribution/v3/registry/api/errcode"
)
const errGroup = "registry.api.v2"
var (
// ErrorCodeDigestInvalid is returned when uploading a blob if the
// provided digest does not match the blob contents.
ErrorCodeDigestInvalid = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "DIGEST_INVALID",
Message: "provided digest did not match uploaded content",
Description: `When a blob is uploaded, the registry will check that
the content matches the digest provided by the client. The error may
include a detail structure with the key "digest", including the
invalid digest string. This error may also be returned when a manifest
includes an invalid layer digest.`,
HTTPStatusCode: http.StatusBadRequest,
})
// ErrorCodeSizeInvalid is returned when uploading a blob if the provided
ErrorCodeSizeInvalid = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "SIZE_INVALID",
Message: "provided length did not match content length",
Description: `When a layer is uploaded, the provided size will be
checked against the uploaded content. If they do not match, this error
will be returned.`,
HTTPStatusCode: http.StatusBadRequest,
})
// ErrorCodeRangeInvalid is returned when uploading a blob if the provided
// content range is invalid.
ErrorCodeRangeInvalid = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "RANGE_INVALID",
Message: "invalid content range",
Description: `When a layer is uploaded, the provided range is checked
against the uploaded chunk. This error is returned if the range is
out of order.`,
HTTPStatusCode: http.StatusRequestedRangeNotSatisfiable,
})
// ErrorCodeNameInvalid is returned when the name in the manifest does not
// match the provided name.
ErrorCodeNameInvalid = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "NAME_INVALID",
Message: "invalid repository name",
Description: `Invalid repository name encountered either during
manifest validation or any API operation.`,
HTTPStatusCode: http.StatusBadRequest,
})
// ErrorCodeTagInvalid is returned when the tag in the manifest does not
// match the provided tag.
ErrorCodeTagInvalid = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "TAG_INVALID",
Message: "manifest tag did not match URI",
Description: `During a manifest upload, if the tag in the manifest
does not match the uri tag, this error will be returned.`,
HTTPStatusCode: http.StatusBadRequest,
})
// ErrorCodeNameUnknown when the repository name is not known.
ErrorCodeNameUnknown = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "NAME_UNKNOWN",
Message: "repository name not known to registry",
Description: `This is returned if the name used during an operation is
unknown to the registry.`,
HTTPStatusCode: http.StatusNotFound,
})
// ErrorCodeManifestUnknown returned when image manifest is unknown.
ErrorCodeManifestUnknown = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "MANIFEST_UNKNOWN",
Message: "manifest unknown",
Description: `This error is returned when the manifest, identified by
name and tag is unknown to the repository.`,
HTTPStatusCode: http.StatusNotFound,
})
// ErrorCodeManifestInvalid returned when an image manifest is invalid,
// typically during a PUT operation. This error encompasses all errors
// encountered during manifest validation that aren't signature errors.
ErrorCodeManifestInvalid = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "MANIFEST_INVALID",
Message: "manifest invalid",
Description: `During upload, manifests undergo several checks ensuring
validity. If those checks fail, this error may be returned, unless a
more specific error is included. The detail will contain information
the failed validation.`,
HTTPStatusCode: http.StatusBadRequest,
})
// ErrorCodeManifestUnverified is returned when the manifest fails
// signature verification.
ErrorCodeManifestUnverified = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "MANIFEST_UNVERIFIED",
Message: "manifest failed signature verification",
Description: `During manifest upload, if the manifest fails signature
verification, this error will be returned.`,
HTTPStatusCode: http.StatusBadRequest,
})
// ErrorCodeManifestBlobUnknown is returned when a manifest blob is
// unknown to the registry.
ErrorCodeManifestBlobUnknown = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "MANIFEST_BLOB_UNKNOWN",
Message: "blob unknown to registry",
Description: `This error may be returned when a manifest blob is
unknown to the registry.`,
HTTPStatusCode: http.StatusBadRequest,
})
// ErrorCodeBlobUnknown is returned when a blob is unknown to the
// registry. This can happen when the manifest references a nonexistent
// layer or the result is not found by a blob fetch.
ErrorCodeBlobUnknown = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "BLOB_UNKNOWN",
Message: "blob unknown to registry",
Description: `This error may be returned when a blob is unknown to the
registry in a specified repository. This can be returned with a
standard get or if a manifest references an unknown layer during
upload.`,
HTTPStatusCode: http.StatusNotFound,
})
// ErrorCodeBlobUploadUnknown is returned when an upload is unknown.
ErrorCodeBlobUploadUnknown = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "BLOB_UPLOAD_UNKNOWN",
Message: "blob upload unknown to registry",
Description: `If a blob upload has been cancelled or was never
started, this error code may be returned.`,
HTTPStatusCode: http.StatusNotFound,
})
// ErrorCodeBlobUploadInvalid is returned when an upload is invalid.
ErrorCodeBlobUploadInvalid = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "BLOB_UPLOAD_INVALID",
Message: "blob upload invalid",
Description: `The blob upload encountered an error and can no
longer proceed.`,
HTTPStatusCode: http.StatusNotFound,
})
// ErrorCodePaginationNumberInvalid is returned when the `n` parameter is
// not an integer, or `n` is negative.
ErrorCodePaginationNumberInvalid = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "PAGINATION_NUMBER_INVALID",
Message: "invalid number of results requested",
Description: `Returned when the "n" parameter (number of results
to return) is not an integer, "n" is negative or "n" is bigger than
the maximum allowed.`,
HTTPStatusCode: http.StatusBadRequest,
})
)

View file

@ -0,0 +1,86 @@
package v2
import "github.com/distribution/distribution/v3/registry/api/errcode"
var (
// ErrorCodeDigestInvalid is returned when uploading a blob if the
// provided digest does not match the blob contents.
//
// Deprecated: use [errcode.ErrorCodeDigestInvalid].
ErrorCodeDigestInvalid = errcode.ErrorCodeDigestInvalid
// ErrorCodeSizeInvalid is returned when uploading a blob if the provided
//
// Deprecated: use [errcode.ErrorCodeSizeInvalid].
ErrorCodeSizeInvalid = errcode.ErrorCodeSizeInvalid
// ErrorCodeRangeInvalid is returned when uploading a blob if the provided
// content range is invalid.
//
// Deprecated: use [errcode.ErrorCodeRangeInvalid].
ErrorCodeRangeInvalid = errcode.ErrorCodeRangeInvalid
// ErrorCodeNameInvalid is returned when the name in the manifest does not
// match the provided name.
//
// Deprecated: use [errcode.ErrorCodeNameInvalid].
ErrorCodeNameInvalid = errcode.ErrorCodeNameInvalid
// ErrorCodeTagInvalid is returned when the tag in the manifest does not
// match the provided tag.
//
// Deprecated: use [errcode.ErrorCodeTagInvalid].
ErrorCodeTagInvalid = errcode.ErrorCodeTagInvalid
// ErrorCodeNameUnknown when the repository name is not known.
//
// Deprecated: use [errcode.ErrorCodeNameUnknown].
ErrorCodeNameUnknown = errcode.ErrorCodeNameUnknown
// ErrorCodeManifestUnknown returned when image manifest is unknown.
//
// Deprecated: use [errcode.ErrorCodeManifestUnknown].
ErrorCodeManifestUnknown = errcode.ErrorCodeManifestUnknown
// ErrorCodeManifestInvalid returned when an image manifest is invalid,
// typically during a PUT operation. This error encompasses all errors
// encountered during manifest validation that aren't signature errors.
//
// Deprecated: use [errcode.ErrorCodeManifestInvalid].
ErrorCodeManifestInvalid = errcode.ErrorCodeManifestInvalid
// ErrorCodeManifestUnverified is returned when the manifest fails
// signature verification.
//
// Deprecated: use [errcode.ErrorCodeManifestUnverified].
ErrorCodeManifestUnverified = errcode.ErrorCodeManifestUnverified
// ErrorCodeManifestBlobUnknown is returned when a manifest blob is
// unknown to the registry.
//
// Deprecated: use [errcode.ErrorCodeManifestBlobUnknown].
ErrorCodeManifestBlobUnknown = errcode.ErrorCodeManifestBlobUnknown
// ErrorCodeBlobUnknown is returned when a blob is unknown to the
// registry. This can happen when the manifest references a nonexistent
// layer or the result is not found by a blob fetch.
//
// Deprecated: use [errcode.ErrorCodeBlobUnknown].
ErrorCodeBlobUnknown = errcode.ErrorCodeBlobUnknown
// ErrorCodeBlobUploadUnknown is returned when an upload is unknown.
//
// Deprecated: use [errcode.ErrorCodeBlobUploadUnknown].
ErrorCodeBlobUploadUnknown = errcode.ErrorCodeBlobUploadUnknown
// ErrorCodeBlobUploadInvalid is returned when an upload is invalid.
//
// Deprecated: use [errcode.ErrorCodeBlobUploadInvalid].
ErrorCodeBlobUploadInvalid = errcode.ErrorCodeBlobUploadInvalid
// ErrorCodePaginationNumberInvalid is returned when the `n` parameter is
// not an integer, or `n` is negative.
//
// Deprecated: use [errcode.ErrorCodePaginationNumberInvalid].
ErrorCodePaginationNumberInvalid = errcode.ErrorCodePaginationNumberInvalid
)

View file

@ -9,7 +9,6 @@ import (
"github.com/distribution/distribution/v3"
"github.com/distribution/distribution/v3/registry/api/errcode"
v2 "github.com/distribution/distribution/v3/registry/api/v2"
"github.com/distribution/distribution/v3/testutil"
)
@ -175,8 +174,8 @@ func TestUploadReadFrom(t *testing.T) {
if !ok {
t.Fatalf("Not an 'Error' type: %#v", uploadErr[0])
}
if v2Err.Code != v2.ErrorCodeBlobUploadInvalid {
t.Fatalf("Unexpected error code: %s, expected %d", v2Err.Code.String(), v2.ErrorCodeBlobUploadInvalid)
if v2Err.Code != errcode.ErrorCodeBlobUploadInvalid {
t.Fatalf("Unexpected error code: %s, expected %d", v2Err.Code.String(), errcode.ErrorCodeBlobUploadInvalid)
}
if expected := "blob upload invalid"; v2Err.Message != expected {
t.Fatalf("Unexpected error message: %q, expected %q", v2Err.Message, expected)
@ -463,8 +462,8 @@ func TestUploadWrite(t *testing.T) {
if !ok {
t.Fatalf("Not an 'Error' type: %#v", uploadErr[0])
}
if v2Err.Code != v2.ErrorCodeBlobUploadInvalid {
t.Fatalf("Unexpected error code: %s, expected %d", v2Err.Code.String(), v2.ErrorCodeBlobUploadInvalid)
if v2Err.Code != errcode.ErrorCodeBlobUploadInvalid {
t.Fatalf("Unexpected error code: %s, expected %d", v2Err.Code.String(), errcode.ErrorCodeBlobUploadInvalid)
}
if expected := "blob upload invalid"; v2Err.Message != expected {
t.Fatalf("Unexpected error message: %q, expected %q", v2Err.Message, expected)

View file

@ -21,7 +21,6 @@ import (
"github.com/distribution/distribution/v3/manifest"
"github.com/distribution/distribution/v3/manifest/ocischema"
"github.com/distribution/distribution/v3/registry/api/errcode"
v2 "github.com/distribution/distribution/v3/registry/api/v2"
"github.com/distribution/distribution/v3/testutil"
"github.com/distribution/distribution/v3/uuid"
"github.com/distribution/reference"
@ -1440,7 +1439,7 @@ func TestObtainsErrorForMissingTag(t *testing.T) {
var m testutil.RequestResponseMap
var errors errcode.Errors
errors = append(errors, v2.ErrorCodeManifestUnknown.WithDetail("unknown manifest"))
errors = append(errors, errcode.ErrorCodeManifestUnknown.WithDetail("unknown manifest"))
errBytes, err := json.Marshal(errors)
if err != nil {
t.Fatal(err)

View file

@ -339,7 +339,7 @@ func TestCatalogAPI(t *testing.T) {
defer resp.Body.Close()
checkResponse(t, "issuing catalog api check", resp, http.StatusBadRequest)
checkBodyHasErrorCodes(t, "invalid number of results requested", resp, v2.ErrorCodePaginationNumberInvalid)
checkBodyHasErrorCodes(t, "invalid number of results requested", resp, errcode.ErrorCodePaginationNumberInvalid)
// -----------------------------------
// Case No. 6: request n > maxentries but <= total catalog
@ -360,7 +360,7 @@ func TestCatalogAPI(t *testing.T) {
defer resp.Body.Close()
checkResponse(t, "issuing catalog api check", resp, http.StatusBadRequest)
checkBodyHasErrorCodes(t, "invalid number of results requested", resp, v2.ErrorCodePaginationNumberInvalid)
checkBodyHasErrorCodes(t, "invalid number of results requested", resp, errcode.ErrorCodePaginationNumberInvalid)
// -----------------------------------
// Case No. 7: n = 0
@ -409,7 +409,7 @@ func TestCatalogAPI(t *testing.T) {
defer resp.Body.Close()
checkResponse(t, "issuing catalog api check", resp, http.StatusBadRequest)
checkBodyHasErrorCodes(t, "invalid number of results requested", resp, v2.ErrorCodePaginationNumberInvalid)
checkBodyHasErrorCodes(t, "invalid number of results requested", resp, errcode.ErrorCodePaginationNumberInvalid)
// -----------------------------------
// Case No. 9: n = 5, max = 5, total catalog = 4
@ -504,13 +504,13 @@ func TestTagsAPI(t *testing.T) {
name: "negative n query parameter",
queryParams: url.Values{"n": []string{"-1"}},
expectedStatusCode: http.StatusBadRequest,
expectedBodyErr: &v2.ErrorCodePaginationNumberInvalid,
expectedBodyErr: &errcode.ErrorCodePaginationNumberInvalid,
},
{
name: "non integer n query parameter",
queryParams: url.Values{"n": []string{"foo"}},
expectedStatusCode: http.StatusBadRequest,
expectedBodyErr: &v2.ErrorCodePaginationNumberInvalid,
expectedBodyErr: &errcode.ErrorCodePaginationNumberInvalid,
},
{
name: "1st page",
@ -900,7 +900,7 @@ func testBlobAPI(t *testing.T, env *testEnv, args blobArgs) *testEnv {
defer resp.Body.Close()
checkResponse(t, "bad layer push", resp, http.StatusBadRequest)
checkBodyHasErrorCodes(t, "bad layer push", resp, v2.ErrorCodeDigestInvalid)
checkBodyHasErrorCodes(t, "bad layer push", resp, errcode.ErrorCodeDigestInvalid)
// -----------------------------------------
// Do layer push with an empty body and correct digest
@ -1342,7 +1342,7 @@ func TestManifestAPI_DeleteTag_Unknown(t *testing.T) {
defer resp.Body.Close()
checkResponse(t, msg, resp, http.StatusNotFound)
checkBodyHasErrorCodes(t, msg, resp, v2.ErrorCodeManifestUnknown)
checkBodyHasErrorCodes(t, msg, resp, errcode.ErrorCodeManifestUnknown)
}
func TestManifestAPI_DeleteTag_ReadOnly(t *testing.T) {
@ -1442,7 +1442,7 @@ func TestGetManifestWithStorageError(t *testing.T) {
defer env1.Shutdown()
repo, _ := reference.WithName(repositoryWithManifestNotFound)
testManifestWithStorageError(t, env1, repo, http.StatusNotFound, v2.ErrorCodeManifestUnknown)
testManifestWithStorageError(t, env1, repo, http.StatusNotFound, errcode.ErrorCodeManifestUnknown)
repo, _ = reference.WithName(repositoryWithGenericStorageError)
testManifestWithStorageError(t, env1, repo, http.StatusInternalServerError, errcode.ErrorCodeUnknown)
@ -1528,7 +1528,7 @@ func testManifestAPISchema2(t *testing.T, env *testEnv, imageName reference.Name
defer resp.Body.Close()
checkResponse(t, "getting non-existent manifest", resp, http.StatusNotFound)
checkBodyHasErrorCodes(t, "getting non-existent manifest", resp, v2.ErrorCodeManifestUnknown)
checkBodyHasErrorCodes(t, "getting non-existent manifest", resp, errcode.ErrorCodeManifestUnknown)
tagsURL, err := env.builder.BuildTagsURL(imageName)
if err != nil {
@ -1543,7 +1543,7 @@ func testManifestAPISchema2(t *testing.T, env *testEnv, imageName reference.Name
// Check that we get an unknown repository error when asking for tags
checkResponse(t, "getting unknown manifest tags", resp, http.StatusNotFound)
checkBodyHasErrorCodes(t, "getting unknown manifest tags", resp, v2.ErrorCodeNameUnknown)
checkBodyHasErrorCodes(t, "getting unknown manifest tags", resp, errcode.ErrorCodeNameUnknown)
// --------------------------------
// Attempt to push manifest with missing config and missing layers
@ -1574,10 +1574,10 @@ func testManifestAPISchema2(t *testing.T, env *testEnv, imageName reference.Name
resp = putManifest(t, "putting missing config manifest", manifestURL, schema2.MediaTypeManifest, manifest)
defer resp.Body.Close()
checkResponse(t, "putting missing config manifest", resp, http.StatusBadRequest)
_, p, counts := checkBodyHasErrorCodes(t, "putting missing config manifest", resp, v2.ErrorCodeManifestBlobUnknown)
_, p, counts := checkBodyHasErrorCodes(t, "putting missing config manifest", resp, errcode.ErrorCodeManifestBlobUnknown)
expectedCounts := map[errcode.ErrorCode]int{
v2.ErrorCodeManifestBlobUnknown: 3,
errcode.ErrorCodeManifestBlobUnknown: 3,
}
if !reflect.DeepEqual(counts, expectedCounts) {
@ -1616,10 +1616,10 @@ func testManifestAPISchema2(t *testing.T, env *testEnv, imageName reference.Name
resp = putManifest(t, "putting missing layer manifest", manifestURL, schema2.MediaTypeManifest, manifest)
defer resp.Body.Close()
checkResponse(t, "putting missing layer manifest", resp, http.StatusBadRequest)
_, p, counts = checkBodyHasErrorCodes(t, "getting unknown manifest tags", resp, v2.ErrorCodeManifestBlobUnknown)
_, p, counts = checkBodyHasErrorCodes(t, "getting unknown manifest tags", resp, errcode.ErrorCodeManifestBlobUnknown)
expectedCounts = map[errcode.ErrorCode]int{
v2.ErrorCodeManifestBlobUnknown: 2,
errcode.ErrorCodeManifestBlobUnknown: 2,
}
if !reflect.DeepEqual(counts, expectedCounts) {
@ -1840,10 +1840,10 @@ func testManifestAPIManifestList(t *testing.T, env *testEnv, args manifestArgs)
resp := putManifest(t, "putting missing manifest manifestlist", manifestURL, manifestlist.MediaTypeManifestList, manifestList)
defer resp.Body.Close()
checkResponse(t, "putting missing manifest manifestlist", resp, http.StatusBadRequest)
_, p, counts := checkBodyHasErrorCodes(t, "putting missing manifest manifestlist", resp, v2.ErrorCodeManifestBlobUnknown)
_, p, counts := checkBodyHasErrorCodes(t, "putting missing manifest manifestlist", resp, errcode.ErrorCodeManifestBlobUnknown)
expectedCounts := map[errcode.ErrorCode]int{
v2.ErrorCodeManifestBlobUnknown: 1,
errcode.ErrorCodeManifestBlobUnknown: 1,
}
if !reflect.DeepEqual(counts, expectedCounts) {

View file

@ -661,9 +661,9 @@ func (app *App) dispatcher(dispatch dispatchFunc) http.Handler {
switch err := err.(type) {
case distribution.ErrRepositoryUnknown:
context.Errors = append(context.Errors, v2.ErrorCodeNameUnknown.WithDetail(err))
context.Errors = append(context.Errors, errcode.ErrorCodeNameUnknown.WithDetail(err))
case distribution.ErrRepositoryNameInvalid:
context.Errors = append(context.Errors, v2.ErrorCodeNameInvalid.WithDetail(err))
context.Errors = append(context.Errors, errcode.ErrorCodeNameInvalid.WithDetail(err))
case errcode.Error:
context.Errors = append(context.Errors, err)
}

View file

@ -6,7 +6,6 @@ import (
"github.com/distribution/distribution/v3"
"github.com/distribution/distribution/v3/context"
"github.com/distribution/distribution/v3/registry/api/errcode"
v2 "github.com/distribution/distribution/v3/registry/api/v2"
"github.com/gorilla/handlers"
"github.com/opencontainers/go-digest"
)
@ -18,12 +17,12 @@ func blobDispatcher(ctx *Context, r *http.Request) http.Handler {
if err == errDigestNotAvailable {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx.Errors = append(ctx.Errors, v2.ErrorCodeDigestInvalid.WithDetail(err))
ctx.Errors = append(ctx.Errors, errcode.ErrorCodeDigestInvalid.WithDetail(err))
})
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx.Errors = append(ctx.Errors, v2.ErrorCodeDigestInvalid.WithDetail(err))
ctx.Errors = append(ctx.Errors, errcode.ErrorCodeDigestInvalid.WithDetail(err))
})
}
@ -59,7 +58,7 @@ func (bh *blobHandler) GetBlob(w http.ResponseWriter, r *http.Request) {
desc, err := blobs.Stat(bh, bh.Digest)
if err != nil {
if err == distribution.ErrBlobUnknown {
bh.Errors = append(bh.Errors, v2.ErrorCodeBlobUnknown.WithDetail(bh.Digest))
bh.Errors = append(bh.Errors, errcode.ErrorCodeBlobUnknown.WithDetail(bh.Digest))
} else {
bh.Errors = append(bh.Errors, errcode.ErrorCodeUnknown.WithDetail(err))
}
@ -85,7 +84,7 @@ func (bh *blobHandler) DeleteBlob(w http.ResponseWriter, r *http.Request) {
bh.Errors = append(bh.Errors, errcode.ErrorCodeUnsupported)
return
case distribution.ErrBlobUnknown:
bh.Errors = append(bh.Errors, v2.ErrorCodeBlobUnknown)
bh.Errors = append(bh.Errors, errcode.ErrorCodeBlobUnknown)
return
default:
bh.Errors = append(bh.Errors, err)

View file

@ -9,7 +9,6 @@ import (
"github.com/distribution/distribution/v3"
dcontext "github.com/distribution/distribution/v3/context"
"github.com/distribution/distribution/v3/registry/api/errcode"
v2 "github.com/distribution/distribution/v3/registry/api/v2"
"github.com/distribution/distribution/v3/registry/storage"
"github.com/distribution/reference"
"github.com/gorilla/handlers"
@ -110,7 +109,7 @@ func (buh *blobUploadHandler) GetUploadStatus(w http.ResponseWriter, r *http.Req
upload, err := blobs.Resume(buh, buh.UUID)
if err != nil {
if err == distribution.ErrBlobUploadUnknown {
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadUnknown.WithDetail(err))
buh.Errors = append(buh.Errors, errcode.ErrorCodeBlobUploadUnknown.WithDetail(err))
} else {
buh.Errors = append(buh.Errors, errcode.ErrorCodeUnknown.WithDetail(err))
}
@ -131,7 +130,7 @@ func (buh *blobUploadHandler) GetUploadStatus(w http.ResponseWriter, r *http.Req
// PatchBlobData writes data to an upload.
func (buh *blobUploadHandler) PatchBlobData(w http.ResponseWriter, r *http.Request) {
if buh.Upload == nil {
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadUnknown)
buh.Errors = append(buh.Errors, errcode.ErrorCodeBlobUploadUnknown)
return
}
@ -151,7 +150,7 @@ func (buh *blobUploadHandler) PatchBlobData(w http.ResponseWriter, r *http.Reque
return
}
if start > end || start != buh.Upload.Size() {
buh.Errors = append(buh.Errors, v2.ErrorCodeRangeInvalid)
buh.Errors = append(buh.Errors, errcode.ErrorCodeRangeInvalid)
return
}
@ -161,7 +160,7 @@ func (buh *blobUploadHandler) PatchBlobData(w http.ResponseWriter, r *http.Reque
return
}
if clInt != (end-start)+1 {
buh.Errors = append(buh.Errors, v2.ErrorCodeSizeInvalid)
buh.Errors = append(buh.Errors, errcode.ErrorCodeSizeInvalid)
return
}
}
@ -186,7 +185,7 @@ func (buh *blobUploadHandler) PatchBlobData(w http.ResponseWriter, r *http.Reque
// url of the blob.
func (buh *blobUploadHandler) PutBlobUploadComplete(w http.ResponseWriter, r *http.Request) {
if buh.Upload == nil {
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadUnknown)
buh.Errors = append(buh.Errors, errcode.ErrorCodeBlobUploadUnknown)
return
}
defer buh.Upload.Close()
@ -195,14 +194,14 @@ func (buh *blobUploadHandler) PutBlobUploadComplete(w http.ResponseWriter, r *ht
if dgstStr == "" {
// no digest? return error, but allow retry.
buh.Errors = append(buh.Errors, v2.ErrorCodeDigestInvalid.WithDetail("digest missing"))
buh.Errors = append(buh.Errors, errcode.ErrorCodeDigestInvalid.WithDetail("digest missing"))
return
}
dgst, err := digest.Parse(dgstStr)
if err != nil {
// no digest? return error, but allow retry.
buh.Errors = append(buh.Errors, v2.ErrorCodeDigestInvalid.WithDetail("digest parsing failed"))
buh.Errors = append(buh.Errors, errcode.ErrorCodeDigestInvalid.WithDetail("digest parsing failed"))
return
}
@ -221,7 +220,7 @@ func (buh *blobUploadHandler) PutBlobUploadComplete(w http.ResponseWriter, r *ht
if err != nil {
switch err := err.(type) {
case distribution.ErrBlobInvalidDigest:
buh.Errors = append(buh.Errors, v2.ErrorCodeDigestInvalid.WithDetail(err))
buh.Errors = append(buh.Errors, errcode.ErrorCodeDigestInvalid.WithDetail(err))
case errcode.Error:
buh.Errors = append(buh.Errors, err)
default:
@ -231,7 +230,7 @@ func (buh *blobUploadHandler) PutBlobUploadComplete(w http.ResponseWriter, r *ht
case distribution.ErrUnsupported:
buh.Errors = append(buh.Errors, errcode.ErrorCodeUnsupported)
case distribution.ErrBlobInvalidLength, distribution.ErrBlobDigestUnsupported:
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadInvalid.WithDetail(err))
buh.Errors = append(buh.Errors, errcode.ErrorCodeBlobUploadInvalid.WithDetail(err))
default:
dcontext.GetLogger(buh).Errorf("unknown error completing upload: %v", err)
buh.Errors = append(buh.Errors, errcode.ErrorCodeUnknown.WithDetail(err))
@ -256,7 +255,7 @@ func (buh *blobUploadHandler) PutBlobUploadComplete(w http.ResponseWriter, r *ht
// CancelBlobUpload cancels an in-progress upload of a blob.
func (buh *blobUploadHandler) CancelBlobUpload(w http.ResponseWriter, r *http.Request) {
if buh.Upload == nil {
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadUnknown)
buh.Errors = append(buh.Errors, errcode.ErrorCodeBlobUploadUnknown)
return
}
defer buh.Upload.Close()
@ -275,7 +274,7 @@ func (buh *blobUploadHandler) ResumeBlobUpload(ctx *Context, r *http.Request) ht
if err != nil {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
dcontext.GetLogger(ctx).Infof("error resolving upload: %v", err)
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadInvalid.WithDetail(err))
buh.Errors = append(buh.Errors, errcode.ErrorCodeBlobUploadInvalid.WithDetail(err))
})
}
buh.State = state
@ -283,14 +282,14 @@ func (buh *blobUploadHandler) ResumeBlobUpload(ctx *Context, r *http.Request) ht
if state.Name != ctx.Repository.Named().Name() {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
dcontext.GetLogger(ctx).Infof("mismatched repository name in upload state: %q != %q", state.Name, buh.Repository.Named().Name())
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadInvalid.WithDetail(err))
buh.Errors = append(buh.Errors, errcode.ErrorCodeBlobUploadInvalid.WithDetail(err))
})
}
if state.UUID != buh.UUID {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
dcontext.GetLogger(ctx).Infof("mismatched uuid in upload state: %q != %q", state.UUID, buh.UUID)
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadInvalid.WithDetail(err))
buh.Errors = append(buh.Errors, errcode.ErrorCodeBlobUploadInvalid.WithDetail(err))
})
}
@ -300,7 +299,7 @@ func (buh *blobUploadHandler) ResumeBlobUpload(ctx *Context, r *http.Request) ht
dcontext.GetLogger(ctx).Errorf("error resolving upload: %v", err)
if err == distribution.ErrBlobUploadUnknown {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadUnknown.WithDetail(err))
buh.Errors = append(buh.Errors, errcode.ErrorCodeBlobUploadUnknown.WithDetail(err))
})
}
@ -313,7 +312,7 @@ func (buh *blobUploadHandler) ResumeBlobUpload(ctx *Context, r *http.Request) ht
if size := upload.Size(); size != buh.State.Offset {
dcontext.GetLogger(ctx).Errorf("upload resumed at wrong offset: %d != %d", size, buh.State.Offset)
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
buh.Errors = append(buh.Errors, v2.ErrorCodeRangeInvalid.WithDetail(err))
buh.Errors = append(buh.Errors, errcode.ErrorCodeRangeInvalid.WithDetail(err))
})
}
return nil

View file

@ -9,7 +9,6 @@ import (
"strconv"
"github.com/distribution/distribution/v3/registry/api/errcode"
v2 "github.com/distribution/distribution/v3/registry/api/v2"
"github.com/distribution/distribution/v3/registry/storage/driver"
"github.com/gorilla/handlers"
)
@ -47,13 +46,13 @@ func (ch *catalogHandler) GetCatalog(w http.ResponseWriter, r *http.Request) {
if n := q.Get("n"); n != "" {
parsedMax, err := strconv.Atoi(n)
if err != nil || parsedMax < 0 {
ch.Errors = append(ch.Errors, v2.ErrorCodePaginationNumberInvalid.WithDetail(map[string]string{"n": n}))
ch.Errors = append(ch.Errors, errcode.ErrorCodePaginationNumberInvalid.WithDetail(map[string]string{"n": n}))
return
}
// if a client requests more than it's allowed to receive
if parsedMax > maximumConfiguredEntries {
ch.Errors = append(ch.Errors, v2.ErrorCodePaginationNumberInvalid.WithDetail(map[string]int{"n": parsedMax}))
ch.Errors = append(ch.Errors, errcode.ErrorCodePaginationNumberInvalid.WithDetail(map[string]int{"n": parsedMax}))
return
}
entries = parsedMax

View file

@ -13,7 +13,6 @@ import (
"github.com/distribution/distribution/v3/manifest/ocischema"
"github.com/distribution/distribution/v3/manifest/schema2"
"github.com/distribution/distribution/v3/registry/api/errcode"
v2 "github.com/distribution/distribution/v3/registry/api/v2"
"github.com/distribution/distribution/v3/registry/auth"
"github.com/distribution/distribution/v3/registry/storage/driver"
"github.com/distribution/reference"
@ -119,7 +118,7 @@ func (imh *manifestHandler) GetManifest(w http.ResponseWriter, r *http.Request)
desc, err := tags.Get(imh, imh.Tag)
if err != nil {
if _, ok := err.(distribution.ErrTagUnknown); ok {
imh.Errors = append(imh.Errors, v2.ErrorCodeManifestUnknown.WithDetail(err))
imh.Errors = append(imh.Errors, errcode.ErrorCodeManifestUnknown.WithDetail(err))
} else {
imh.Errors = append(imh.Errors, errcode.ErrorCodeUnknown.WithDetail(err))
}
@ -140,7 +139,7 @@ func (imh *manifestHandler) GetManifest(w http.ResponseWriter, r *http.Request)
manifest, err := manifests.Get(imh, imh.Digest, options...)
if err != nil {
if _, ok := err.(distribution.ErrManifestUnknownRevision); ok {
imh.Errors = append(imh.Errors, v2.ErrorCodeManifestUnknown.WithDetail(err))
imh.Errors = append(imh.Errors, errcode.ErrorCodeManifestUnknown.WithDetail(err))
} else {
imh.Errors = append(imh.Errors, errcode.ErrorCodeUnknown.WithDetail(err))
}
@ -160,11 +159,11 @@ func (imh *manifestHandler) GetManifest(w http.ResponseWriter, r *http.Request)
}
if manifestType == ociSchema && !supports[ociSchema] {
imh.Errors = append(imh.Errors, v2.ErrorCodeManifestUnknown.WithMessage("OCI manifest found, but accept header does not support OCI manifests"))
imh.Errors = append(imh.Errors, errcode.ErrorCodeManifestUnknown.WithMessage("OCI manifest found, but accept header does not support OCI manifests"))
return
}
if manifestType == ociImageIndexSchema && !supports[ociImageIndexSchema] {
imh.Errors = append(imh.Errors, v2.ErrorCodeManifestUnknown.WithMessage("OCI index found, but accept header does not support OCI indexes"))
imh.Errors = append(imh.Errors, errcode.ErrorCodeManifestUnknown.WithMessage("OCI index found, but accept header does not support OCI indexes"))
return
}
@ -183,14 +182,14 @@ func (imh *manifestHandler) GetManifest(w http.ResponseWriter, r *http.Request)
}
if manifestDigest == "" {
imh.Errors = append(imh.Errors, v2.ErrorCodeManifestUnknown)
imh.Errors = append(imh.Errors, errcode.ErrorCodeManifestUnknown)
return
}
manifest, err = manifests.Get(imh, manifestDigest)
if err != nil {
if _, ok := err.(distribution.ErrManifestUnknownRevision); ok {
imh.Errors = append(imh.Errors, v2.ErrorCodeManifestUnknown.WithDetail(err))
imh.Errors = append(imh.Errors, errcode.ErrorCodeManifestUnknown.WithDetail(err))
} else {
imh.Errors = append(imh.Errors, errcode.ErrorCodeUnknown.WithDetail(err))
}
@ -198,7 +197,7 @@ func (imh *manifestHandler) GetManifest(w http.ResponseWriter, r *http.Request)
}
if _, isSchema2 := manifest.(*schema2.DeserializedManifest); isSchema2 && !supports[manifestSchema2] {
imh.Errors = append(imh.Errors, v2.ErrorCodeManifestInvalid.WithMessage("Schema 2 manifest not supported by client"))
imh.Errors = append(imh.Errors, errcode.ErrorCodeManifestInvalid.WithMessage("Schema 2 manifest not supported by client"))
return
} else {
imh.Digest = manifestDigest
@ -238,27 +237,27 @@ func (imh *manifestHandler) PutManifest(w http.ResponseWriter, r *http.Request)
var jsonBuf bytes.Buffer
if err := copyFullPayload(imh, w, r, &jsonBuf, maxManifestBodySize, "image manifest PUT"); err != nil {
// copyFullPayload reports the error if necessary
imh.Errors = append(imh.Errors, v2.ErrorCodeManifestInvalid.WithDetail(err.Error()))
imh.Errors = append(imh.Errors, errcode.ErrorCodeManifestInvalid.WithDetail(err.Error()))
return
}
mediaType := r.Header.Get("Content-Type")
manifest, desc, err := distribution.UnmarshalManifest(mediaType, jsonBuf.Bytes())
if err != nil {
imh.Errors = append(imh.Errors, v2.ErrorCodeManifestInvalid.WithDetail(err))
imh.Errors = append(imh.Errors, errcode.ErrorCodeManifestInvalid.WithDetail(err))
return
}
if imh.Digest != "" {
if desc.Digest != imh.Digest {
dcontext.GetLogger(imh).Errorf("payload digest does not match: %q != %q", desc.Digest, imh.Digest)
imh.Errors = append(imh.Errors, v2.ErrorCodeDigestInvalid)
imh.Errors = append(imh.Errors, errcode.ErrorCodeDigestInvalid)
return
}
} else if imh.Tag != "" {
imh.Digest = desc.Digest
} else {
imh.Errors = append(imh.Errors, v2.ErrorCodeTagInvalid.WithDetail("no tag or digest specified"))
imh.Errors = append(imh.Errors, errcode.ErrorCodeTagInvalid.WithDetail("no tag or digest specified"))
return
}
@ -297,14 +296,14 @@ func (imh *manifestHandler) PutManifest(w http.ResponseWriter, r *http.Request)
for _, verificationError := range err {
switch verificationError := verificationError.(type) {
case distribution.ErrManifestBlobUnknown:
imh.Errors = append(imh.Errors, v2.ErrorCodeManifestBlobUnknown.WithDetail(verificationError.Digest))
imh.Errors = append(imh.Errors, errcode.ErrorCodeManifestBlobUnknown.WithDetail(verificationError.Digest))
case distribution.ErrManifestNameInvalid:
imh.Errors = append(imh.Errors, v2.ErrorCodeNameInvalid.WithDetail(err))
imh.Errors = append(imh.Errors, errcode.ErrorCodeNameInvalid.WithDetail(err))
case distribution.ErrManifestUnverified:
imh.Errors = append(imh.Errors, v2.ErrorCodeManifestUnverified)
imh.Errors = append(imh.Errors, errcode.ErrorCodeManifestUnverified)
default:
if verificationError == digest.ErrDigestInvalidFormat {
imh.Errors = append(imh.Errors, v2.ErrorCodeDigestInvalid)
imh.Errors = append(imh.Errors, errcode.ErrorCodeDigestInvalid)
} else {
imh.Errors = append(imh.Errors, errcode.ErrorCodeUnknown, verificationError)
}
@ -434,7 +433,7 @@ func (imh *manifestHandler) DeleteManifest(w http.ResponseWriter, r *http.Reques
if err := tagService.Untag(imh.Context, imh.Tag); err != nil {
switch err.(type) {
case distribution.ErrTagUnknown, driver.PathNotFoundError:
imh.Errors = append(imh.Errors, v2.ErrorCodeManifestUnknown.WithDetail(err))
imh.Errors = append(imh.Errors, errcode.ErrorCodeManifestUnknown.WithDetail(err))
default:
imh.Errors = append(imh.Errors, errcode.ErrorCodeUnknown.WithDetail(err))
}
@ -455,10 +454,10 @@ func (imh *manifestHandler) DeleteManifest(w http.ResponseWriter, r *http.Reques
switch err {
case digest.ErrDigestUnsupported:
case digest.ErrDigestInvalidFormat:
imh.Errors = append(imh.Errors, v2.ErrorCodeDigestInvalid)
imh.Errors = append(imh.Errors, errcode.ErrorCodeDigestInvalid)
return
case distribution.ErrBlobUnknown:
imh.Errors = append(imh.Errors, v2.ErrorCodeManifestUnknown)
imh.Errors = append(imh.Errors, errcode.ErrorCodeManifestUnknown)
return
case distribution.ErrUnsupported:
imh.Errors = append(imh.Errors, errcode.ErrorCodeUnsupported)

View file

@ -8,7 +8,6 @@ import (
"github.com/distribution/distribution/v3"
"github.com/distribution/distribution/v3/registry/api/errcode"
v2 "github.com/distribution/distribution/v3/registry/api/v2"
"github.com/gorilla/handlers"
)
@ -42,7 +41,7 @@ func (th *tagsHandler) GetTags(w http.ResponseWriter, r *http.Request) {
if err != nil {
switch err := err.(type) {
case distribution.ErrRepositoryUnknown:
th.Errors = append(th.Errors, v2.ErrorCodeNameUnknown.WithDetail(map[string]string{"name": th.Repository.Named().Name()}))
th.Errors = append(th.Errors, errcode.ErrorCodeNameUnknown.WithDetail(map[string]string{"name": th.Repository.Named().Name()}))
case errcode.Error:
th.Errors = append(th.Errors, err)
default:
@ -71,7 +70,7 @@ func (th *tagsHandler) GetTags(w http.ResponseWriter, r *http.Request) {
if n := q.Get("n"); n != "" {
maxEntries, err := strconv.Atoi(n)
if err != nil || maxEntries < 0 {
th.Errors = append(th.Errors, v2.ErrorCodePaginationNumberInvalid.WithDetail(map[string]string{"n": n}))
th.Errors = append(th.Errors, errcode.ErrorCodePaginationNumberInvalid.WithDetail(map[string]string{"n": n}))
return
}