From e805eef24dfb1168d566ef81c2fe45b1763ab6cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= Date: Fri, 10 Nov 2023 01:01:22 +0100 Subject: [PATCH] WIP add login/logout tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miloslav Trmač --- test/e2e/login_logout_test.go | 79 +++++++++++++++++++++++++++++++++++ test/system/150-login.bats | 13 +++++- test/utils/utils.go | 13 ++++++ 3 files changed, 103 insertions(+), 2 deletions(-) diff --git a/test/e2e/login_logout_test.go b/test/e2e/login_logout_test.go index a5ebb4a1382a..1c2747a704b1 100644 --- a/test/e2e/login_logout_test.go +++ b/test/e2e/login_logout_test.go @@ -11,6 +11,7 @@ import ( . "github.com/containers/podman/v4/test/utils" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman login and logout", func() { @@ -189,6 +190,84 @@ var _ = Describe("Podman login and logout", func() { Expect(session).Should(ExitCleanly()) }) + 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.WaitWithDefaultTimeout() + Expect(session).Should(ExitCleanly()) + + readAuthInfo(compatAuthFile) + + session = podmanTest.Podman([]string{"logout", "--compat-auth-file", compatAuthFile, server}) + session.WaitWithDefaultTimeout() + Expect(session).Should(ExitCleanly()) + + // logout should fail with nonexistent authfile + session = podmanTest.Podman([]string{"logout", "--compat-auth-file", "/tmp/nonexistent", server}) + session.WaitWithDefaultTimeout() + Expect(session).To(ExitWithError()) + Expect(session.ErrorToString()).To(Equal("Error: credential file is not accessible: stat /tmp/nonexistent: no such file or directory")) + + // inconsistent command line flags are rejected + // Pre-create the files to make sure we are not hitting the “file not found” path + authFile := filepath.Join(podmanTest.TempDir, "auth.json") + err := os.WriteFile(authFile, []byte("{}"), 0o700) + Expect(err).ToNot(HaveOccurred()) + err = os.WriteFile(compatAuthFile, []byte("{}"), 0o700) + Expect(err).ToNot(HaveOccurred()) + + session = podmanTest.Podman([]string{"login", "--username", "podmantest", "--password", "test", + "--authfile", authFile, "--compat-auth-file", compatAuthFile, server}) + session.WaitWithDefaultTimeout() + Expect(session).To(ExitWithError()) + Expect(session.ErrorToString()).To(Equal("Error: --authfile and --compat-auth-file can not be set simultaneously")) + + session = podmanTest.Podman([]string{"logout", "--authfile", authFile, "--compat-auth-file", compatAuthFile, server}) + session.WaitWithDefaultTimeout() + Expect(session).To(ExitWithError()) + Expect(session.ErrorToString()).To(Equal("Error: --authfile and --compat-auth-file can not be set simultaneously")) + }) + + It("podman login and logout --compat-auth-file work with Docker", func() { + SkipIfRootless("rootless user has no permission to use default docker.sock") + setup := SystemExec("bash", []string{"-c", "systemctl status docker 2>&1"}) + + if setup.LineInOutputContains("Active: inactive") { + setup = SystemExec("systemctl", []string{"start", "docker"}) + Expect(setup).Should(ExitCleanly()) + defer func() { + stop := SystemExec("systemctl", []string{"stop", "docker"}) + Expect(stop).Should(Exit(0)) + }() + } else if setup.ExitCode() != 0 { + Skip("Docker is not available") + } + + dockerConfigDir := filepath.Join(podmanTest.TempDir, "docker-config") + dockerConfigPath := filepath.Join(dockerConfigDir, "config.json") + + // Access with no credentials fails + access := SystemExecWithEnv([]string{"DOCKER_CONFIG=" + dockerConfigDir}, "docker", []string{"search", server + "/search-term"}) + GinkgoWriter.Printf("docker search: ===%d== \n%s\n", access.ExitCode(), access.OutputToString()) // FIXME: DEBUGGING + Expect(access).To(Not(Exit(0))) + + // Login works, and access works afterwards + session := podmanTest.Podman([]string{"login", "--compat-auth-file", dockerConfigPath, "--username", "podmantest", "--password", "test", server}) + session.WaitWithDefaultTimeout() + Expect(session).To(ExitCleanly()) + access = SystemExecWithEnv([]string{"DOCKER_CONFIG=" + dockerConfigDir}, "docker", []string{"search", server + "/search-term"}) + GinkgoWriter.Printf("docker search: ===%d== \n%s\n", access.ExitCode(), access.OutputToString()) // FIXME: DEBUGGING + Expect(access).To(Exit(0)) + + session = podmanTest.Podman([]string{"logout", "--compat-auth-file", dockerConfigPath, server}) + session.WaitWithDefaultTimeout() + Expect(session).To(ExitCleanly()) + access = SystemExecWithEnv([]string{"DOCKER_CONFIG=" + dockerConfigDir}, "docker", []string{"search", server + "/search-term"}) + GinkgoWriter.Printf("docker search: ===%d== \n%s\n", access.ExitCode(), access.OutputToString()) // FIXME: DEBUGGING + Expect(access).To(Not(Exit(0))) + }) + It("podman manifest with --authfile", func() { os.Unsetenv("REGISTRY_AUTH_FILE") diff --git a/test/system/150-login.bats b/test/system/150-login.bats index c0d63e8b5af9..0aa5f7f9304c 100644 --- a/test/system/150-login.bats +++ b/test/system/150-login.bats @@ -80,6 +80,17 @@ function setup() { is "$output" "{}" "credentials removed from $authfile" } +@test "podman login inconsistent authfiles" { + ambiguous_file=${PODMAN_LOGIN_WORKDIR}/ambiguous-auth.json + echo '{}' > $ambiguous_file # To make sure we are not hitting the “file not found” path + + run_podman 125 login --authfile "$ambiguous_file" --compat-auth-file "$ambiguous_file" localhost:5000 + expect_output "Error: --authfile and --compat-auth-file can not be set simultaneously" + + run_podman 125 logout --authfile "$ambiguous_file" --compat-auth-file "$ambiguous_file" localhost:5000 + expect_output "Error: --authfile and --compat-auth-file can not be set simultaneously" +} + # Some push tests @test "podman push fail" { @@ -284,8 +295,6 @@ function _test_skopeo_credential_sharing() { } -# FIXME: Test login/logout with --compat-auth-file - # END cooperation with skopeo # END actual tests ############################################################################### diff --git a/test/utils/utils.go b/test/utils/utils.go index 205c4edd89cd..fb9d810f2e97 100644 --- a/test/utils/utils.go +++ b/test/utils/utils.go @@ -393,6 +393,19 @@ func SystemExec(command string, args []string) *PodmanSession { return &PodmanSession{session} } +// SystemExecWithEnv is used to exec a system command to check its exit code or output +func SystemExecWithEnv(env []string, command string, args []string) *PodmanSession { + c := exec.Command(command, args...) + c.Env = append(c.Env, env...) + GinkgoWriter.Println("Execing " + c.String() + "\n") + session, err := Start(c, GinkgoWriter, GinkgoWriter) + if err != nil { + Fail(fmt.Sprintf("unable to run command: %s %s", command, strings.Join(args, " "))) + } + session.Wait(DefaultWaitTimeout) + return &PodmanSession{session} +} + // StartSystemExec is used to start exec a system command func StartSystemExec(command string, args []string) *PodmanSession { c := exec.Command(command, args...)