From 88a32272b730a964728ea1f9ae96db7fab235949 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Fri, 5 Jun 2026 12:42:05 +0200 Subject: [PATCH 1/2] test/e2e: do not call out to htpasswd/cp in registry tests Because we use hard coded names anyway we might as well skip the extra command execution here that happened for each test. Just inline a valid htpasswd line. Also remove the extra sync call, there is no reason whatsoever for this file to be synced. For cp there is also no reason at all to call an external command. Worse the command also was never checked for errors. Signed-off-by: Paul Holzinger --- test/e2e/login_logout_test.go | 72 +++++++++++++++++------------------ test/e2e/push_test.go | 22 +++++------ 2 files changed, 44 insertions(+), 50 deletions(-) diff --git a/test/e2e/login_logout_test.go b/test/e2e/login_logout_test.go index 3b0eeaeb41..f32d287dea 100644 --- a/test/e2e/login_logout_test.go +++ b/test/e2e/login_logout_test.go @@ -13,6 +13,13 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" . "go.podman.io/podman/v6/test/utils" + "go.podman.io/storage/pkg/fileutils" +) + +const ( + registryUser = "podmantest" + registryPassword = "test" + htpasswdLine = "podmantest:$2y$05$OIqogLGEkRXVUYqeRemzk.ZAeX4QmchNPQQRZY35AGyAt/dkaSM3W\n" ) var _ = Describe("Podman login and logout", func() { @@ -31,17 +38,11 @@ var _ = Describe("Podman login and logout", func() { 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() + _, err = f.WriteString(htpasswdLine) Expect(err).ToNot(HaveOccurred()) port := GetPort() server = strings.Join([]string{"localhost", strconv.Itoa(port)}, ":") @@ -56,8 +57,8 @@ var _ = Describe("Podman login and logout", func() { cwd, _ := os.Getwd() certPath = filepath.Join(cwd, "../", "certs") - setup := SystemExec("cp", []string{filepath.Join(certPath, "domain.crt"), filepath.Join(certDirPath, "ca.crt")}) - setup.WaitWithDefaultTimeout() + _, err = fileutils.CopyFile(filepath.Join(certPath, "domain.crt"), filepath.Join(certDirPath, "ca.crt")) + Expect(err).ToNot(HaveOccurred()) session := podmanTest.Podman([]string{ "run", "-d", "-p", strings.Join([]string{strconv.Itoa(port), strconv.Itoa(port)}, ":"), @@ -106,7 +107,7 @@ var _ = Describe("Podman login and logout", func() { authFile := os.Getenv("REGISTRY_AUTH_FILE") Expect(authFile).NotTo(BeEmpty(), "$REGISTRY_AUTH_FILE") - session := podmanTest.Podman([]string{"login", "-u", "podmantest", "-p", "test", server}) + session := podmanTest.Podman([]string{"login", "-u", registryUser, "-p", registryPassword, server}) session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) @@ -150,7 +151,7 @@ var _ = Describe("Podman login and logout", func() { }() os.Setenv("CONTAINERS_REGISTRIES_CONF", registriesConf.Name()) - session := podmanTest.Podman([]string{"login", "-u", "podmantest", "-p", "test"}) + session := podmanTest.Podman([]string{"login", "-u", registryUser, "-p", registryPassword}) session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) @@ -161,7 +162,7 @@ var _ = Describe("Podman login and logout", func() { It("podman login and logout with flag --authfile", func() { authFile := filepath.Join(podmanTest.TempDir, "auth.json") - session := podmanTest.Podman([]string{"login", "--username", "podmantest", "--password", "test", "--authfile", authFile, server}) + session := podmanTest.Podman([]string{"login", "--username", registryUser, "--password", registryPassword, "--authfile", authFile, server}) session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) @@ -193,7 +194,7 @@ var _ = Describe("Podman login and logout", func() { It("podman login and logout --compat-auth-file flag handling", func() { // A minimal smoke test compatAuthFile := filepath.Join(podmanTest.TempDir, "config.json") - session := podmanTest.Podman([]string{"login", "--username", "podmantest", "--password", "test", "--compat-auth-file", compatAuthFile, server}) + session := podmanTest.Podman([]string{"login", "--username", registryUser, "--password", registryPassword, "--compat-auth-file", compatAuthFile, server}) session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) @@ -217,7 +218,7 @@ var _ = Describe("Podman login and logout", func() { Expect(err).ToNot(HaveOccurred()) session = podmanTest.Podman([]string{ - "login", "--username", "podmantest", "--password", "test", + "login", "--username", registryUser, "--password", registryPassword, "--authfile", authFile, "--compat-auth-file", compatAuthFile, server, }) session.WaitWithDefaultTimeout() @@ -232,7 +233,7 @@ var _ = Describe("Podman login and logout", func() { os.Unsetenv("REGISTRY_AUTH_FILE") authFile := filepath.Join(podmanTest.TempDir, "auth.json") - session := podmanTest.Podman([]string{"login", "--username", "podmantest", "--password", "test", "--authfile", authFile, server}) + session := podmanTest.Podman([]string{"login", "--username", registryUser, "--password", registryPassword, "--authfile", authFile, server}) session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) @@ -265,7 +266,7 @@ var _ = Describe("Podman login and logout", func() { }) It("podman login and logout with --tls-verify", func() { - session := podmanTest.Podman([]string{"login", "--username", "podmantest", "--password", "test", "--tls-verify=false", server}) + session := podmanTest.Podman([]string{"login", "--username", registryUser, "--password", registryPassword, "--tls-verify=false", server}) session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) @@ -282,10 +283,10 @@ var _ = Describe("Podman login and logout", func() { err := os.MkdirAll(certDir, os.ModePerm) Expect(err).ToNot(HaveOccurred()) - setup := SystemExec("cp", []string{filepath.Join(certPath, "domain.crt"), filepath.Join(certDir, "ca.crt")}) - setup.WaitWithDefaultTimeout() + _, err = fileutils.CopyFile(filepath.Join(certPath, "domain.crt"), filepath.Join(certDir, "ca.crt")) + Expect(err).ToNot(HaveOccurred()) - session := podmanTest.Podman([]string{"login", "--username", "podmantest", "--password", "test", "--cert-dir", certDir, server}) + session := podmanTest.Podman([]string{"login", "--username", registryUser, "--password", registryPassword, "--cert-dir", certDir, server}) session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) @@ -302,11 +303,8 @@ var _ = Describe("Podman login and logout", func() { err = os.MkdirAll(certDir, os.ModePerm) Expect(err).ToNot(HaveOccurred()) - cwd, _ := os.Getwd() - certPath = filepath.Join(cwd, "../", "certs") - - setup := SystemExec("cp", []string{filepath.Join(certPath, "domain.crt"), filepath.Join(certDir, "ca.crt")}) - setup.WaitWithDefaultTimeout() + _, err = fileutils.CopyFile(filepath.Join(certPath, "domain.crt"), filepath.Join(certDir, "ca.crt")) + Expect(err).ToNot(HaveOccurred()) defer os.RemoveAll(certDir) // N/B: This second registry container shares the same auth and cert dirs @@ -326,7 +324,7 @@ var _ = Describe("Podman login and logout", func() { Skip("Cannot start docker registry.") } - session = podmanTest.Podman([]string{"login", "--username", "podmantest", "--password", "test", server}) + session = podmanTest.Podman([]string{"login", "--username", registryUser, "--password", registryPassword, server}) session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) @@ -338,7 +336,7 @@ var _ = Describe("Podman login and logout", func() { session.WaitWithDefaultTimeout() Expect(session).To(ExitWithError(125, "/test-alpine: authentication required")) - session = podmanTest.Podman([]string{"login", "--username", "podmantest", "--password", "test", "localhost:9001"}) + session = podmanTest.Podman([]string{"login", "--username", registryUser, "--password", registryPassword, "localhost:9001"}) session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) @@ -362,7 +360,7 @@ var _ = Describe("Podman login and logout", func() { session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) - session = podmanTest.Podman([]string{"login", "--username", "podmantest", "--password", "test", "localhost:9001"}) + session = podmanTest.Podman([]string{"login", "--username", registryUser, "--password", registryPassword, "localhost:9001"}) session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) @@ -385,8 +383,8 @@ var _ = Describe("Podman login and logout", func() { testRepository := server + "/podmantest" session := podmanTest.Podman([]string{ "login", - "-u", "podmantest", - "-p", "test", + "-u", registryUser, + "-p", registryPassword, "--authfile", authFile, testRepository, }) @@ -414,8 +412,8 @@ var _ = Describe("Podman login and logout", func() { testTarget := server + "/podmantest/test-alpine" session := podmanTest.Podman([]string{ "login", - "-u", "podmantest", - "-p", "test", + "-u", registryUser, + "-p", registryPassword, "--authfile", authFile, testTarget, }) @@ -444,8 +442,8 @@ var _ = Describe("Podman login and logout", func() { for _, testRepo := range testRepos { session := podmanTest.Podman([]string{ "login", - "-u", "podmantest", - "-p", "test", + "-u", registryUser, + "-p", registryPassword, "--authfile", authFile, testRepo, }) @@ -503,8 +501,8 @@ var _ = Describe("Podman login and logout", func() { } { session := podmanTest.Podman([]string{ "login", - "-u", "podmantest", - "-p", "test", + "-u", registryUser, + "-p", registryPassword, "--authfile", authFile, invalidArg, }) @@ -545,8 +543,8 @@ var _ = Describe("Podman login and logout", func() { testTarget := server + "/podmantest/test-alpine" session := podmanTest.Podman([]string{ "login", - "-u", "podmantest", - "-p", "test", + "-u", registryUser, + "-p", registryPassword, "--authfile", authFile, testTarget, }) diff --git a/test/e2e/push_test.go b/test/e2e/push_test.go index bd721b89de..9832efcde1 100644 --- a/test/e2e/push_test.go +++ b/test/e2e/push_test.go @@ -15,6 +15,7 @@ import ( "go.podman.io/image/v5/signature/simplesequoia" . "go.podman.io/podman/v6/test/utils" "go.podman.io/storage/pkg/archive" + "go.podman.io/storage/pkg/fileutils" ) // testSequoiaKeyFingerprint is a fingerprint of a test Sequoia key in testdata. @@ -372,17 +373,12 @@ var _ = Describe("Podman push", func() { lock := GetPortLock("5004") defer lock.Unlock() - 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() + _, err = f.WriteString(htpasswdLine) Expect(err).ToNot(HaveOccurred()) session := podmanTest.Podman([]string{ @@ -397,17 +393,17 @@ var _ = Describe("Podman push", func() { Expect(WaitContainerReady(podmanTest, "registry", "listening on", 20, 1)).To(BeTrue(), "registry container ready") - push := podmanTest.Podman([]string{"push", "--tls-verify=true", "--format=v2s2", "--creds=podmantest:test", ALPINE, "localhost:5004/tlstest"}) + push := podmanTest.Podman([]string{"push", "--tls-verify=true", "--format=v2s2", "--creds=" + registryUser + ":" + registryPassword, ALPINE, "localhost:5004/tlstest"}) push.WaitWithDefaultTimeout() Expect(push).To(ExitWithError(125, "x509: certificate signed by unknown authority")) - push = podmanTest.Podman([]string{"push", "--creds=podmantest:test", "--tls-verify=false", ALPINE, "localhost:5004/tlstest"}) + push = podmanTest.Podman([]string{"push", "--creds=" + registryUser + ":" + registryPassword, "--tls-verify=false", ALPINE, "localhost:5004/tlstest"}) push.WaitWithDefaultTimeout() Expect(push).Should(Exit(0)) Expect(push.ErrorToString()).To(ContainSubstring("Writing manifest to image destination")) - setup := SystemExec("cp", []string{filepath.Join(certPath, "domain.crt"), "/etc/containers/certs.d/localhost:5004/ca.crt"}) - Expect(setup).Should(ExitCleanly()) + _, err = fileutils.CopyFile(filepath.Join(certPath, "domain.crt"), "/etc/containers/certs.d/localhost:5004/ca.crt") + Expect(err).ToNot(HaveOccurred()) push = podmanTest.Podman([]string{"push", "--creds=podmantest:wrongpasswd", ALPINE, "localhost:5004/credstest"}) push.WaitWithDefaultTimeout() @@ -415,12 +411,12 @@ var _ = Describe("Podman push", func() { if !IsRemote() { // remote does not support --cert-dir - push = podmanTest.Podman([]string{"push", "--tls-verify=true", "--creds=podmantest:test", "--cert-dir=fakedir", ALPINE, "localhost:5004/certdirtest"}) + push = podmanTest.Podman([]string{"push", "--tls-verify=true", "--creds=" + registryUser + ":" + registryPassword, "--cert-dir=fakedir", ALPINE, "localhost:5004/certdirtest"}) push.WaitWithDefaultTimeout() Expect(push).To(ExitWithError(125, "x509: certificate signed by unknown authority")) } - push = podmanTest.Podman([]string{"push", "--creds=podmantest:test", ALPINE, "localhost:5004/defaultflags"}) + push = podmanTest.Podman([]string{"push", "--creds=" + registryUser + ":" + registryPassword, ALPINE, "localhost:5004/defaultflags"}) push.WaitWithDefaultTimeout() Expect(push).Should(Exit(0)) Expect(push.ErrorToString()).To(ContainSubstring("Writing manifest to image destination")) @@ -430,7 +426,7 @@ var _ = Describe("Podman push", func() { session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) - session = podmanTest.Podman([]string{"manifest", "push", "--creds=podmantest:test", "--tls-verify=false", "--all", "localhost:5004/manifesttest"}) + session = podmanTest.Podman([]string{"manifest", "push", "--creds=" + registryUser + ":" + registryPassword, "--tls-verify=false", "--all", "localhost:5004/manifesttest"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) Expect(session.ErrorToString()).To(ContainSubstring("Writing manifest list to image destination")) From 1eda0cfbb4159f4b62545b241ba40d68d8cbf07a Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Fri, 5 Jun 2026 13:06:26 +0200 Subject: [PATCH 2/2] test/e2e: fix flake in login tests By default we run tests in parallel so when we mount test/certs with the ":Z" option it means only one container can read it, depending on the startup times this can mean the container fails to start. I observed this error in a CI run: level=fatal msg="open /certs/domain.crt: permission denied" Signed-off-by: Paul Holzinger --- test/e2e/login_logout_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/login_logout_test.go b/test/e2e/login_logout_test.go index f32d287dea..9a02b59e70 100644 --- a/test/e2e/login_logout_test.go +++ b/test/e2e/login_logout_test.go @@ -65,7 +65,7 @@ var _ = Describe("Podman login and logout", func() { "-e", strings.Join([]string{"REGISTRY_HTTP_ADDR=0.0.0.0", strconv.Itoa(port)}, ":"), "--name", "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", - "-v", strings.Join([]string{certPath, "/certs:Z"}, ":"), "-e", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt", + "-v", strings.Join([]string{certPath, "/certs:z"}, ":"), "-e", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt", "-e", "REGISTRY_HTTP_TLS_KEY=/certs/domain.key", REGISTRY_IMAGE, }) session.WaitWithDefaultTimeout()