Recognize "manifest unknown" errors reported by Harbor

... per data in https://github.com/containers/image/issues/2203 .

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
Miloslav Trmač 2024-05-13 20:20:23 +02:00
parent f26a2b2d57
commit 5e98ea38e7
3 changed files with 47 additions and 1 deletions

View File

@ -1097,6 +1097,11 @@ func isManifestUnknownError(err error) bool {
if errors.As(err, &e) && e.ErrorCode() == errcode.ErrorCodeUnknown && e.Message == "Not Found" {
return true
}
// Harbor v2.10.2
if errors.As(err, &e) && e.ErrorCode() == errcode.ErrorCodeUnknown && strings.Contains(strings.ToLower(e.Message), "not found") {
return true
}
// opencontainers/distribution-spec does not require the errcode.Error payloads to be used,
// but specifies that the HTTP status must be 404.
var unexpected *unexpectedHTTPResponseError

View File

@ -392,6 +392,19 @@ func TestIsManifestUnknownError(t *testing.T) {
"\r\n" +
"Not found\r\n",
},
{
name: "Harbor v2.10.2",
response: "HTTP/1.1 404 Not Found\r\n" +
"Content-Length: 153\r\n" +
"Connection: keep-alive\r\n" +
"Content-Type: application/json; charset=utf-8\r\n" +
"Date: Wed, 08 May 2024 08:14:59 GMT\r\n" +
"Server: nginx\r\n" +
"Set-Cookie: sid=f617c257877837614ada2561513d6827; Path=/; HttpOnly\r\n" +
"X-Request-Id: 1b151fb1-c943-4190-a9ce-5156ed5e3200\r\n" +
"\r\n" +
"{\"errors\":[{\"code\":\"NOT_FOUND\",\"message\":\"artifact test/alpine:sha256-443205b0cfcc78444321d56a2fe273f06e27b2c72b5058f8d7e975997d45b015.sig not found\"}]}\n",
},
} {
resp, err := http.ReadResponse(bufio.NewReader(bytes.NewReader([]byte(c.response))), nil)
require.NoError(t, err, c.name)
@ -399,6 +412,6 @@ func TestIsManifestUnknownError(t *testing.T) {
err = fmt.Errorf("wrapped: %w", registryHTTPResponseToError(resp))
res := isManifestUnknownError(err)
assert.True(t, res, "%#v", err, c.name)
assert.True(t, res, "%s: %#v", c.name, err)
}
}

View File

@ -173,6 +173,34 @@ func TestRegistryHTTPResponseToError(t *testing.T) {
assert.Equal(t, []byte("Not found\r"), e.Response)
},
},
{ // Harbor v2.10.2 uses an unspecified NOT_FOUND error code
name: "Harbor v2.10.2 manifest not found",
response: "HTTP/1.1 404 Not Found\r\n" +
"Content-Length: 153\r\n" +
"Connection: keep-alive\r\n" +
"Content-Type: application/json; charset=utf-8\r\n" +
"Date: Wed, 08 May 2024 08:14:59 GMT\r\n" +
"Server: nginx\r\n" +
"Set-Cookie: sid=f617c257877837614ada2561513d6827; Path=/; HttpOnly\r\n" +
"X-Request-Id: 1b151fb1-c943-4190-a9ce-5156ed5e3200\r\n" +
"\r\n" +
"{\"errors\":[{\"code\":\"NOT_FOUND\",\"message\":\"artifact test/alpine:sha256-443205b0cfcc78444321d56a2fe273f06e27b2c72b5058f8d7e975997d45b015.sig not found\"}]}\n",
errorString: "unknown: artifact test/alpine:sha256-443205b0cfcc78444321d56a2fe273f06e27b2c72b5058f8d7e975997d45b015.sig not found",
errorType: errcode.Error{},
unwrappedErrorPtr: &unwrappedErrcodeError,
errorCode: &errcode.ErrorCodeUnknown,
fn: func(t *testing.T, err error) {
var e errcode.Error
ok := errors.As(err, &e)
require.True(t, ok)
// isManifestUnknownError is checking for this
assert.Equal(t, errcode.Error{
Code: errcode.ErrorCodeUnknown, // The NOT_FOUND value is not defined, and turns into Unknown
Message: "artifact test/alpine:sha256-443205b0cfcc78444321d56a2fe273f06e27b2c72b5058f8d7e975997d45b015.sig not found",
Detail: nil,
}, e)
},
},
} {
res, err := http.ReadResponse(bufio.NewReader(bytes.NewReader([]byte(c.response))), nil)
require.NoError(t, err, c.name)