diff --git a/pkg/bindings/manifests/manifests.go b/pkg/bindings/manifests/manifests.go index 458cb913a102..4237f9fc78de 100644 --- a/pkg/bindings/manifests/manifests.go +++ b/pkg/bindings/manifests/manifests.go @@ -11,7 +11,9 @@ import ( "github.com/blang/semver" "github.com/containers/image/v5/manifest" + imageTypes "github.com/containers/image/v5/types" "github.com/containers/podman/v4/pkg/api/handlers" + "github.com/containers/podman/v4/pkg/auth" "github.com/containers/podman/v4/pkg/bindings" "github.com/containers/podman/v4/pkg/bindings/images" "github.com/containers/podman/v4/version" @@ -179,6 +181,11 @@ func Push(ctx context.Context, name, destination string, options *images.PushOpt return "", err } + header, err := auth.MakeXRegistryAuthHeader(&imageTypes.SystemContext{AuthFilePath: options.GetAuthfile()}, options.GetUsername(), options.GetPassword()) + if err != nil { + return "", err + } + params, err := options.ToParams() if err != nil { return "", err @@ -192,11 +199,11 @@ func Push(ctx context.Context, name, destination string, options *images.PushOpt var response *bindings.APIResponse if bindings.ServiceVersion(ctx).GTE(semver.MustParse("4.0.0")) { - response, err = conn.DoRequest(ctx, nil, http.MethodPost, "/manifests/%s/registry/%s", params, nil, name, destination) + response, err = conn.DoRequest(ctx, nil, http.MethodPost, "/manifests/%s/registry/%s", params, header, name, destination) } else { params.Set("image", name) params.Set("destination", destination) - response, err = conn.DoRequest(ctx, nil, http.MethodPost, "/manifests/%s/push", params, nil, name) + response, err = conn.DoRequest(ctx, nil, http.MethodPost, "/manifests/%s/push", params, header, name) } if err != nil { return "", err diff --git a/test/e2e/manifest_test.go b/test/e2e/manifest_test.go index eaa9cdae6663..369b26d36d71 100644 --- a/test/e2e/manifest_test.go +++ b/test/e2e/manifest_test.go @@ -272,6 +272,55 @@ var _ = Describe("Podman manifest", func() { )) }) + It("authenticated push", func() { + if podmanTest.Host.Arch == "ppc64le" { + Skip("No registry image for ppc64le") + } + session := podmanTest.Podman([]string{"manifest", "create", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + session = podmanTest.Podman([]string{"pull", ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + lock := GetPortLock("5000") + defer lock.Unlock() + + session = podmanTest.Podman([]string{"run", "-d", "-p", "5000:5000", "--name", "registry", "-e", "REGISTRY_AUTH=htpasswd", "-e", + "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm", "-e", "REGISTRY_AUTH_HTPASSWD_PATH=/htpasswd", + "--entrypoint", "/bin/sh", registry, "-c", + "htpasswd -Bbc /htpasswd podmantest test && /entrypoint.sh /etc/docker/registry/config.yml"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + if !WaitContainerReady(podmanTest, "registry", "listening on", 20, 1) { + Skip("Cannot start docker registry.") + } + + session = podmanTest.Podman([]string{"logs", "registry"}) + session.WaitWithDefaultTimeout() + + session = podmanTest.Podman([]string{"tag", ALPINE, "localhost:5000/alpine:latest"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + push := podmanTest.Podman([]string{"push", "--creds=podmantest:test", "--format=v2s2", "localhost:5000/alpine:latest"}) + push.WaitWithDefaultTimeout() + Expect(push).Should(Exit(0)) + + session = podmanTest.Podman([]string{"manifest", "add", "--creds=podmantest:test", "foo", "localhost:5000/alpine:latest"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + push = podmanTest.Podman([]string{"manifest", "push", "--creds=podmantest:test", "foo", "localhost:5000/credstest"}) + push.WaitWithDefaultTimeout() + Expect(push).Should(Exit(0)) + + push = podmanTest.Podman([]string{"manifest", "push", "--creds=podmantest:wrongpasswd", "foo", "localhost:5000/credstest"}) + push.WaitWithDefaultTimeout() + Expect(push).To(ExitWithError()) + }) + It("push --rm", func() { SkipIfRemote("remote does not support --rm") session := podmanTest.Podman([]string{"manifest", "create", "foo"})