From c581e0b392219919c2a2a4ac5e0626d722a95f9a Mon Sep 17 00:00:00 2001 From: Byounguk Lee Date: Tue, 4 Nov 2025 12:56:21 +0000 Subject: [PATCH] Fixes #27421 aritfact push and pull with authfile Signed-off-by: Byounguk Lee --- pkg/api/handlers/libpod/artifacts.go | 1 + pkg/domain/infra/tunnel/artifact.go | 2 ++ test/e2e/artifact_test.go | 50 ++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/pkg/api/handlers/libpod/artifacts.go b/pkg/api/handlers/libpod/artifacts.go index ab7272b416..cb712fcf52 100644 --- a/pkg/api/handlers/libpod/artifacts.go +++ b/pkg/api/handlers/libpod/artifacts.go @@ -320,6 +320,7 @@ func PushArtifact(w http.ResponseWriter, r *http.Request) { } defer auth.RemoveAuthfile(authfile) + artifactsPushOptions.Authfile = authfile if authConf != nil { artifactsPushOptions.Username = authConf.Username artifactsPushOptions.Password = authConf.Password diff --git a/pkg/domain/infra/tunnel/artifact.go b/pkg/domain/infra/tunnel/artifact.go index 59c49fff79..177c30b33e 100644 --- a/pkg/domain/infra/tunnel/artifact.go +++ b/pkg/domain/infra/tunnel/artifact.go @@ -38,6 +38,7 @@ func (ir *ImageEngine) ArtifactPull(_ context.Context, name string, opts entitie options := artifacts.PullOptions{ Username: &opts.Username, Password: &opts.Password, + Authfile: &opts.AuthFilePath, Quiet: &opts.Quiet, RetryDelay: &opts.RetryDelay, Retry: opts.MaxRetries, @@ -67,6 +68,7 @@ func (ir *ImageEngine) ArtifactPush(_ context.Context, name string, opts entitie options := artifacts.PushOptions{ Username: &opts.Username, Password: &opts.Password, + Authfile: &opts.Authfile, Quiet: &opts.Quiet, RetryDelay: &opts.RetryDelay, Retry: opts.Retry, diff --git a/test/e2e/artifact_test.go b/test/e2e/artifact_test.go index daed989753..71fc6c1641 100644 --- a/test/e2e/artifact_test.go +++ b/test/e2e/artifact_test.go @@ -254,6 +254,56 @@ var _ = Describe("Podman artifact", func() { podmanTest.PodmanExitCleanly("artifact", "push", "-q", "--tls-verify=false", "--creds=podmantest:test", artifact1Name) }) + It("podman artifact push and pull with authfile", func() { + portNo, err := utils.GetRandomPort() + Expect(err).ToNot(HaveOccurred()) + port := strconv.Itoa(portNo) + + lock := GetPortLock(port) + defer lock.Unlock() + + artifact1File, err := createArtifactFile(1024) + Expect(err).ToNot(HaveOccurred()) + artifact1Name := fmt.Sprintf("localhost:%s/test/artifact1", port) + podmanTest.PodmanExitCleanly("artifact", "add", artifact1Name, artifact1File) + + authPath := filepath.Join(podmanTest.TempDir, "auth") + err = os.Mkdir(authPath, os.ModePerm) + Expect(err).ToNot(HaveOccurred()) + htpasswd := SystemExec("htpasswd", []string{"-Bbn", "podmantest", "test"}) + htpasswd.WaitWithDefaultTimeout() + Expect(htpasswd).Should(ExitCleanly()) + + f, err := os.Create(filepath.Join(authPath, "htpasswd")) + Expect(err).ToNot(HaveOccurred()) + defer f.Close() + _, err = f.WriteString(htpasswd.OutputToString()) + Expect(err).ToNot(HaveOccurred()) + err = f.Sync() + Expect(err).ToNot(HaveOccurred()) + + podmanTest.PodmanExitCleanly("run", "-d", "-p", port+":5000", "--name", "artifact-authfile-registry", "-v", + strings.Join([]string{authPath, "/auth", "z"}, ":"), "-e", "REGISTRY_AUTH=htpasswd", "-e", + "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm", "-e", "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd", + REGISTRY_IMAGE) + Expect(WaitContainerReady(podmanTest, "artifact-authfile-registry", "listening on", 20, 1)).To(BeTrue(), "registry container ready") + + authFile := filepath.Join(podmanTest.TempDir, "auth.json") + server := fmt.Sprintf("localhost:%s", port) + podmanTest.PodmanExitCleanly("login", "--username", "podmantest", "--password", "test", "--authfile", authFile, "--tls-verify=false", server) + + pushFail := podmanTest.Podman([]string{"artifact", "push", "-q", "--authfile", "/tmp/nonexistent", "--tls-verify=false", artifact1Name}) + pushFail.WaitWithDefaultTimeout() + Expect(pushFail).To(ExitWithError(125, "credential file is not accessible")) + + podmanTest.PodmanExitCleanly("artifact", "push", "-q", "--authfile", authFile, "--tls-verify=false", artifact1Name) + + podmanTest.PodmanExitCleanly("artifact", "rm", artifact1Name) + podmanTest.PodmanExitCleanly("artifact", "pull", "--authfile", authFile, "--tls-verify=false", artifact1Name) + inspectedArtifact := podmanTest.InspectArtifact(artifact1Name) + Expect(inspectedArtifact.Name).To(Equal(artifact1Name)) + }) + It("podman artifact remove", func() { // Trying to remove an image that does not exist should fail rmFail := podmanTest.Podman([]string{"artifact", "rm", "foobar"})