diff --git a/pkg/handlers/generic/mutation/mirrors/mirror.go b/pkg/handlers/generic/mutation/mirrors/mirror.go index 17a62b5ea..27e5e46da 100644 --- a/pkg/handlers/generic/mutation/mirrors/mirror.go +++ b/pkg/handlers/generic/mutation/mirrors/mirror.go @@ -8,6 +8,8 @@ import ( "context" _ "embed" "fmt" + "net/url" + "path" "text/template" corev1 "k8s.io/api/core/v1" @@ -97,11 +99,15 @@ func generateGlobalRegistryMirrorFile(mirror *mirrorConfig) ([]cabpkv1.File, err if mirror == nil { return nil, nil } + formattedURL, err := formatURLForContainerd(mirror.URL) + if err != nil { + return nil, fmt.Errorf("failed formatting registry mirror URL for Containerd: %w", err) + } templateInput := struct { URL string CACertPath string }{ - URL: mirror.URL, + URL: formattedURL, } // CA cert is optional for mirror registry. // i.e. registry is using signed certificates. Insecure registry will not be allowed. @@ -110,7 +116,7 @@ func generateGlobalRegistryMirrorFile(mirror *mirrorConfig) ([]cabpkv1.File, err } var b bytes.Buffer - err := defaultRegistryMirrorPatchTemplate.Execute(&b, templateInput) + err = defaultRegistryMirrorPatchTemplate.Execute(&b, templateInput) if err != nil { return nil, fmt.Errorf("failed executing template for registry mirror: %w", err) } @@ -143,3 +149,20 @@ func generateMirrorCACertFile( }, } } + +func formatURLForContainerd(uri string) (string, error) { + mirrorURL, err := url.ParseRequestURI(uri) + if err != nil { + return "", fmt.Errorf("failed parsing mirror: %w", err) + } + + mirror := fmt.Sprintf("%s://%s", mirrorURL.Scheme, mirrorURL.Host) + // assume Containerd expects the following pattern: + // scheme://host/v2/path + mirrorPath := "v2" + if mirrorURL.Path != "" { + mirrorPath = path.Join(mirrorPath, mirrorURL.Path) + } + // using path.Join on all elements incorrectly drops a "/" from "https://" + return fmt.Sprintf("%s/%s", mirror, mirrorPath), nil +} diff --git a/pkg/handlers/generic/mutation/mirrors/mirror_test.go b/pkg/handlers/generic/mutation/mirrors/mirror_test.go index 8a16bea61..cdc7fdeec 100644 --- a/pkg/handlers/generic/mutation/mirrors/mirror_test.go +++ b/pkg/handlers/generic/mutation/mirrors/mirror_test.go @@ -31,8 +31,31 @@ func Test_generateDefaultRegistryMirrorFile(t *testing.T) { Permissions: "0600", Encoding: "", Append: false, - Content: `[host."https://123456789.dkr.ecr.us-east-1.amazonaws.com"] + Content: `[host."https://123456789.dkr.ecr.us-east-1.amazonaws.com/v2"] capabilities = ["pull", "resolve"] + # don't rely on Containerd to add the v2/ suffix + # there is a bug where it is added incorrectly for mirrors with a path + override_path = true +`, + }, + }, + wantErr: nil, + }, + { + name: "ECR image registry with a path and no CA certificate", + config: &mirrorConfig{URL: "https://123456789.dkr.ecr.us-east-1.amazonaws.com/myproject"}, + want: []cabpkv1.File{ + { + Path: "/etc/containerd/certs.d/_default/hosts.toml", + Owner: "", + Permissions: "0600", + Encoding: "", + Append: false, + Content: `[host."https://123456789.dkr.ecr.us-east-1.amazonaws.com/v2/myproject"] + capabilities = ["pull", "resolve"] + # don't rely on Containerd to add the v2/ suffix + # there is a bug where it is added incorrectly for mirrors with a path + override_path = true `, }, }, @@ -51,9 +74,12 @@ func Test_generateDefaultRegistryMirrorFile(t *testing.T) { Permissions: "0600", Encoding: "", Append: false, - Content: `[host."https://myregistry.com"] + Content: `[host."https://myregistry.com/v2"] capabilities = ["pull", "resolve"] ca = "/etc/certs/mirror.pem" + # don't rely on Containerd to add the v2/ suffix + # there is a bug where it is added incorrectly for mirrors with a path + override_path = true `, }, }, diff --git a/pkg/handlers/generic/mutation/mirrors/templates/hosts.toml.gotmpl b/pkg/handlers/generic/mutation/mirrors/templates/hosts.toml.gotmpl index 46237f6e3..41335b8dd 100644 --- a/pkg/handlers/generic/mutation/mirrors/templates/hosts.toml.gotmpl +++ b/pkg/handlers/generic/mutation/mirrors/templates/hosts.toml.gotmpl @@ -3,3 +3,6 @@ {{- if .CACertPath }} ca = "{{ .CACertPath }}" {{- end }} + # don't rely on Containerd to add the v2/ suffix + # there is a bug where it is added incorrectly for mirrors with a path + override_path = true