Skip to content

Commit

Permalink
Merge pull request #1696 from mtrmac/5.23-backports
Browse files Browse the repository at this point in the history
[release-5.23] 5.23 backports
  • Loading branch information
rhatdan committed Oct 19, 2022
2 parents f649a19 + 52a50cf commit d92bac8
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 10 deletions.
4 changes: 2 additions & 2 deletions .cirrus.yml
Expand Up @@ -6,9 +6,9 @@ env:
#### Global variables used for all tasks
####
# Name of the ultimate destination branch for this CI run
DEST_BRANCH: "main"
DEST_BRANCH: "release-5.22"
# CI container image tag (c/skopeo branch name)
SKOPEO_CI_TAG: "main"
SKOPEO_CI_TAG: "release-1.10"
# Use GO module mirror (reason unknown, travis did it this way)
GOPROXY: https://proxy.golang.org
# Overrides default location (/tmp/cirrus) for repo clone
Expand Down
25 changes: 18 additions & 7 deletions docker/docker_client.go
@@ -1,6 +1,7 @@
package docker

import (
"bytes"
"context"
"crypto/tls"
"encoding/json"
Expand Down Expand Up @@ -983,15 +984,25 @@ func (c *dockerClient) getOCIDescriptorContents(ctx context.Context, ref dockerR
// isManifestUnknownError returns true iff err from fetchManifest is a “manifest unknown” error.
func isManifestUnknownError(err error) bool {
var errs errcode.Errors
if !errors.As(err, &errs) || len(errs) == 0 {
return false
if errors.As(err, &errs) && len(errs) != 0 {
firstErr := errs[0]
// docker/distribution, and as defined in the spec
var ec errcode.ErrorCoder
if errors.As(firstErr, &ec) && ec.ErrorCode() == v2.ErrorCodeManifestUnknown {
return true
}
// registry.redhat.io as of October 2022
var e errcode.Error
if errors.As(firstErr, &e) && e.ErrorCode() == errcode.ErrorCodeUnknown && e.Message == "Not Found" {
return true
}
}
err = errs[0]
ec, ok := err.(errcode.ErrorCoder)
if !ok {
return false
// ALSO registry.redhat.io as of October 2022
var unexpected *unexpectedHTTPResponseError
if errors.As(err, &unexpected) && unexpected.StatusCode == http.StatusNotFound && bytes.Contains(unexpected.Response, []byte("Not found")) {
return true
}
return ec.ErrorCode() == v2.ErrorCodeManifestUnknown
return false
}

// getSigstoreAttachmentManifest loads and parses the manifest for sigstore attachments for
Expand Down
58 changes: 58 additions & 0 deletions docker/docker_client_test.go
@@ -1,6 +1,8 @@
package docker

import (
"bufio"
"bytes"
"context"
"errors"
"fmt"
Expand Down Expand Up @@ -328,3 +330,59 @@ func TestNeedsNoRetry(t *testing.T) {
t.Fatal("Got the need to retry, but none should be required")
}
}

func TestIsManifestUnknownError(t *testing.T) {
// Mostly a smoke test; we can add more registries here if they need special handling.

for _, c := range []struct{ name, response string }{
{
name: "docker.io when a tag in an _existing repo_ is not found",
response: "HTTP/1.1 404 Not Found\r\n" +
"Connection: close\r\n" +
"Content-Length: 109\r\n" +
"Content-Type: application/json\r\n" +
"Date: Thu, 12 Aug 2021 20:51:32 GMT\r\n" +
"Docker-Distribution-Api-Version: registry/2.0\r\n" +
"Ratelimit-Limit: 100;w=21600\r\n" +
"Ratelimit-Remaining: 100;w=21600\r\n" +
"Strict-Transport-Security: max-age=31536000\r\n" +
"\r\n" +
"{\"errors\":[{\"code\":\"MANIFEST_UNKNOWN\",\"message\":\"manifest unknown\",\"detail\":{\"Tag\":\"this-does-not-exist\"}}]}\n",
},
{
name: "registry.redhat.io/v2/this-does-not-exist/manifests/latest",
response: "HTTP/1.1 404 Not Found\r\n" +
"Connection: close\r\n" +
"Content-Length: 53\r\n" +
"Cache-Control: max-age=0, no-cache, no-store\r\n" +
"Content-Type: application/json\r\n" +
"Date: Thu, 13 Oct 2022 18:15:15 GMT\r\n" +
"Expires: Thu, 13 Oct 2022 18:15:15 GMT\r\n" +
"Pragma: no-cache\r\n" +
"Server: Apache\r\n" +
"Strict-Transport-Security: max-age=63072000; includeSubdomains; preload\r\n" +
"X-Hostname: crane-tbr06.cran-001.prod.iad2.dc.redhat.com\r\n" +
"\r\n" +
"{\"errors\": [{\"code\": \"404\", \"message\": \"Not Found\"}]}\r\n",
},
{
name: "registry.redhat.io/v2/rhosp15-rhel8/openstack-cron/manifests/sha256-8df5e60c42668706ac108b59c559b9187fa2de7e4e262e2967e3e9da35d5a8d7.sig",
response: "HTTP/1.1 404 Not Found\r\n" +
"Connection: close\r\n" +
"Content-Length: 10\r\n" +
"Accept-Ranges: bytes\r\n" +
"Date: Thu, 13 Oct 2022 18:13:53 GMT\r\n" +
"Server: AkamaiNetStorage\r\n" +
"X-Docker-Size: -1\r\n" +
"\r\n" +
"Not found\r\n",
},
} {
resp, err := http.ReadResponse(bufio.NewReader(bytes.NewReader([]byte(c.response))), nil)
require.NoError(t, err, c.name)
err = fmt.Errorf("wrapped: %w", registryHTTPResponseToError(resp))

res := isManifestUnknownError(err)
assert.True(t, res, "%#v", err, c.name)
}
}
1 change: 1 addition & 0 deletions docker/docker_image_dest.go
Expand Up @@ -653,6 +653,7 @@ func (d *dockerImageDestination) putSignaturesToSigstoreAttachments(ctx context.
Digest: "", // We will fill this in later.
Size: 0,
}, nil)
ociConfig.RootFS.Type = "layers"
} else {
logrus.Debugf("Fetching sigstore attachment config %s", ociManifest.Config.Digest.String())
// We don’t benefit from a real BlobInfoCache here because we never try to reuse/mount configs.
Expand Down
3 changes: 2 additions & 1 deletion docker/errors.go
Expand Up @@ -52,7 +52,8 @@ func registryHTTPResponseToError(res *http.Response) error {
if len(response) > 50 {
response = response[:50] + "..."
}
err = fmt.Errorf("StatusCode: %d, %s", e.StatusCode, response)
// %.0w makes e visible to error.Unwrap() without including any text
err = fmt.Errorf("StatusCode: %d, %s%.0w", e.StatusCode, response, e)
}
return err
}

0 comments on commit d92bac8

Please sign in to comment.