diff --git a/test/e2e/framework/pod/exec_util.go b/test/e2e/framework/pod/exec_util.go index 7f6e6064e02..95a4d70b23c 100644 --- a/test/e2e/framework/pod/exec_util.go +++ b/test/e2e/framework/pod/exec_util.go @@ -19,6 +19,7 @@ package pod import ( "bytes" "context" + "errors" "io" "net/url" "strings" @@ -28,6 +29,7 @@ import ( "k8s.io/client-go/kubernetes/scheme" restclient "k8s.io/client-go/rest" "k8s.io/client-go/tools/remotecommand" + clientexec "k8s.io/client-go/util/exec" "k8s.io/kubernetes/test/e2e/framework" "github.com/onsi/gomega" @@ -141,6 +143,43 @@ func ExecShellInPodWithFullOutput(ctx context.Context, f *framework.Framework, p return execCommandInPodWithFullOutput(ctx, f, podName, "/bin/sh", "-c", cmd) } +// VerifyExecInPodSucceed verifies shell cmd in target pod succeed +func VerifyExecInPodSucceed(ctx context.Context, f *framework.Framework, pod *v1.Pod, shExec string) { + stdout, stderr, err := ExecShellInPodWithFullOutput(ctx, f, pod.Name, shExec) + if err != nil { + var exitError clientexec.CodeExitError + if errors.As(err, &exitError) { + exitCode := exitError.ExitStatus() + framework.ExpectNoError(err, + "%q should succeed, but failed with exit code %d and error message %q\nstdout: %s\nstderr: %s", + shExec, exitCode, exitError, stdout, stderr) + } else { + framework.ExpectNoError(err, + "%q should succeed, but failed with error message %q\nstdout: %s\nstderr: %s", + shExec, err, stdout, stderr) + } + } +} + +// VerifyExecInPodFail verifies shell cmd in target pod fail with certain exit code +func VerifyExecInPodFail(ctx context.Context, f *framework.Framework, pod *v1.Pod, shExec string, exitCode int) { + stdout, stderr, err := ExecShellInPodWithFullOutput(ctx, f, pod.Name, shExec) + if err != nil { + var exitError clientexec.CodeExitError + if errors.As(err, &exitError) { + actualExitCode := exitError.ExitStatus() + gomega.Expect(actualExitCode).To(gomega.Equal(exitCode), + "%q should fail with exit code %d, but failed with exit code %d and error message %q\nstdout: %s\nstderr: %s", + shExec, exitCode, actualExitCode, exitError, stdout, stderr) + } else { + framework.ExpectNoError(err, + "%q should fail with exit code %d, but failed with error message %q\nstdout: %s\nstderr: %s", + shExec, exitCode, err, stdout, stderr) + } + } + gomega.Expect(err).To(gomega.HaveOccurred(), "%q should fail with exit code %d, but exit without error", shExec, exitCode) +} + func execute(ctx context.Context, method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool) error { exec, err := remotecommand.NewSPDYExecutor(config, method, url) if err != nil { diff --git a/test/e2e/framework/volume/fixtures.go b/test/e2e/framework/volume/fixtures.go index 9f0425ed55a..01f0f17acc6 100644 --- a/test/e2e/framework/volume/fixtures.go +++ b/test/e2e/framework/volume/fixtures.go @@ -53,14 +53,12 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" clientset "k8s.io/client-go/kubernetes" - clientexec "k8s.io/client-go/util/exec" "k8s.io/kubernetes/test/e2e/framework" e2ekubectl "k8s.io/kubernetes/test/e2e/framework/kubectl" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" e2epodoutput "k8s.io/kubernetes/test/e2e/framework/pod/output" imageutils "k8s.io/kubernetes/test/utils/image" admissionapi "k8s.io/pod-security-admission/api" - uexec "k8s.io/utils/exec" "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" @@ -179,18 +177,18 @@ func NewNFSServerWithNodeName(ctx context.Context, cs clientset.Interface, names // Restart the passed-in nfs-server by issuing a `rpc.nfsd 1` command in the // pod's (only) container. This command changes the number of nfs server threads from // (presumably) zero back to 1, and therefore allows nfs to open connections again. -func RestartNFSServer(f *framework.Framework, serverPod *v1.Pod) { +func RestartNFSServer(ctx context.Context, f *framework.Framework, serverPod *v1.Pod) { const startcmd = "rpc.nfsd 1" - _, _, err := PodExec(f, serverPod, startcmd) + _, _, err := e2epod.ExecShellInPodWithFullOutput(ctx, f, serverPod.Name, startcmd) framework.ExpectNoError(err) } // Stop the passed-in nfs-server by issuing a `rpc.nfsd 0` command in the // pod's (only) container. This command changes the number of nfs server threads to 0, // thus closing all open nfs connections. -func StopNFSServer(f *framework.Framework, serverPod *v1.Pod) { +func StopNFSServer(ctx context.Context, f *framework.Framework, serverPod *v1.Pod) { const stopcmd = "rpc.nfsd 0 && for i in $(seq 200); do rpcinfo -p | grep -q nfs || break; sleep 1; done" - _, _, err := PodExec(f, serverPod, stopcmd) + _, _, err := e2epod.ExecShellInPodWithFullOutput(ctx, f, serverPod.Name, stopcmd) framework.ExpectNoError(err) } @@ -501,7 +499,7 @@ func runVolumeTesterPod(ctx context.Context, client clientset.Interface, timeout return clientPod, nil } -func testVolumeContent(f *framework.Framework, pod *v1.Pod, containerName string, fsGroup *int64, fsType string, tests []Test) { +func testVolumeContent(ctx context.Context, f *framework.Framework, pod *v1.Pod, containerName string, fsGroup *int64, fsType string, tests []Test) { ginkgo.By("Checking that text file contents are perfect.") for i, test := range tests { if test.Mode == v1.PersistentVolumeBlock { @@ -512,7 +510,7 @@ func testVolumeContent(f *framework.Framework, pod *v1.Pod, containerName string framework.ExpectNoError(err, "failed: finding the contents of the block device %s.", deviceName) // Check that it's a real block device - CheckVolumeModeOfPath(f, pod, test.Mode, deviceName) + CheckVolumeModeOfPath(ctx, f, pod, test.Mode, deviceName) } else { // Filesystem: check content fileName := fmt.Sprintf("/opt/%d/%s", i, test.File) @@ -522,7 +520,7 @@ func testVolumeContent(f *framework.Framework, pod *v1.Pod, containerName string // Check that a directory has been mounted dirName := filepath.Dir(fileName) - CheckVolumeModeOfPath(f, pod, test.Mode, dirName) + CheckVolumeModeOfPath(ctx, f, pod, test.Mode, dirName) if !framework.NodeOSDistroIs("windows") { // Filesystem: check fsgroup @@ -576,7 +574,7 @@ func testVolumeClient(ctx context.Context, f *framework.Framework, config TestCo framework.ExpectNoError(e2epod.WaitForPodNotFoundInNamespace(ctx, f.ClientSet, clientPod.Name, clientPod.Namespace, timeouts.PodDelete)) }() - testVolumeContent(f, clientPod, "", fsGroup, fsType, tests) + testVolumeContent(ctx, f, clientPod, "", fsGroup, fsType, tests) ginkgo.By("Repeating the test on an ephemeral container (if enabled)") ec := &v1.EphemeralContainer{ @@ -587,7 +585,7 @@ func testVolumeClient(ctx context.Context, f *framework.Framework, config TestCo err = e2epod.NewPodClient(f).AddEphemeralContainerSync(ctx, clientPod, ec, timeouts.PodStart) // The API server will return NotFound for the subresource when the feature is disabled framework.ExpectNoError(err, "failed to add ephemeral container for re-test") - testVolumeContent(f, clientPod, ec.Name, fsGroup, fsType, tests) + testVolumeContent(ctx, f, clientPod, ec.Name, fsGroup, fsType, tests) } // InjectContent inserts index.html with given content into given volume. It does so by @@ -630,7 +628,7 @@ func InjectContent(ctx context.Context, f *framework.Framework, config TestConfi // Check that the data have been really written in this pod. // This tests non-persistent volume types - testVolumeContent(f, injectorPod, "", fsGroup, fsType, tests) + testVolumeContent(ctx, f, injectorPod, "", fsGroup, fsType, tests) } // generateWriteCmd is used by generateWriteBlockCmd and generateWriteFileCmd @@ -665,64 +663,18 @@ func generateWriteFileCmd(content, fullPath string) []string { } // CheckVolumeModeOfPath check mode of volume -func CheckVolumeModeOfPath(f *framework.Framework, pod *v1.Pod, volMode v1.PersistentVolumeMode, path string) { +func CheckVolumeModeOfPath(ctx context.Context, f *framework.Framework, pod *v1.Pod, volMode v1.PersistentVolumeMode, path string) { if volMode == v1.PersistentVolumeBlock { // Check if block exists - VerifyExecInPodSucceed(f, pod, fmt.Sprintf("test -b %s", path)) + e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("test -b %s", path)) // Double check that it's not directory - VerifyExecInPodFail(f, pod, fmt.Sprintf("test -d %s", path), 1) + e2epod.VerifyExecInPodFail(ctx, f, pod, fmt.Sprintf("test -d %s", path), 1) } else { // Check if directory exists - VerifyExecInPodSucceed(f, pod, fmt.Sprintf("test -d %s", path)) + e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("test -d %s", path)) // Double check that it's not block - VerifyExecInPodFail(f, pod, fmt.Sprintf("test -b %s", path), 1) + e2epod.VerifyExecInPodFail(ctx, f, pod, fmt.Sprintf("test -b %s", path), 1) } } - -// PodExec runs f.ExecCommandInContainerWithFullOutput to execute a shell cmd in target pod -// TODO: put this under e2epod once https://github.com/kubernetes/kubernetes/issues/81245 -// is resolved. Otherwise there will be dependency issue. -func PodExec(f *framework.Framework, pod *v1.Pod, shExec string) (string, string, error) { - return e2epod.ExecCommandInContainerWithFullOutput(f, pod.Name, pod.Spec.Containers[0].Name, "/bin/sh", "-c", shExec) -} - -// VerifyExecInPodSucceed verifies shell cmd in target pod succeed -// TODO: put this under e2epod once https://github.com/kubernetes/kubernetes/issues/81245 -// is resolved. Otherwise there will be dependency issue. -func VerifyExecInPodSucceed(f *framework.Framework, pod *v1.Pod, shExec string) { - stdout, stderr, err := PodExec(f, pod, shExec) - if err != nil { - if exiterr, ok := err.(uexec.CodeExitError); ok { - exitCode := exiterr.ExitStatus() - framework.ExpectNoError(err, - "%q should succeed, but failed with exit code %d and error message %q\nstdout: %s\nstderr: %s", - shExec, exitCode, exiterr, stdout, stderr) - } else { - framework.ExpectNoError(err, - "%q should succeed, but failed with error message %q\nstdout: %s\nstderr: %s", - shExec, err, stdout, stderr) - } - } -} - -// VerifyExecInPodFail verifies shell cmd in target pod fail with certain exit code -// TODO: put this under e2epod once https://github.com/kubernetes/kubernetes/issues/81245 -// is resolved. Otherwise there will be dependency issue. -func VerifyExecInPodFail(f *framework.Framework, pod *v1.Pod, shExec string, exitCode int) { - stdout, stderr, err := PodExec(f, pod, shExec) - if err != nil { - if exiterr, ok := err.(clientexec.ExitError); ok { - actualExitCode := exiterr.ExitStatus() - gomega.Expect(actualExitCode).To(gomega.Equal(exitCode), - "%q should fail with exit code %d, but failed with exit code %d and error message %q\nstdout: %s\nstderr: %s", - shExec, exitCode, actualExitCode, exiterr, stdout, stderr) - } else { - framework.ExpectNoError(err, - "%q should fail with exit code %d, but failed with error message %q\nstdout: %s\nstderr: %s", - shExec, exitCode, err, stdout, stderr) - } - } - gomega.Expect(err).To(gomega.HaveOccurred(), "%q should fail with exit code %d, but exit without error", shExec, exitCode) -} diff --git a/test/e2e/node/kubelet.go b/test/e2e/node/kubelet.go index 22cc5fd28ea..7744de2593e 100644 --- a/test/e2e/node/kubelet.go +++ b/test/e2e/node/kubelet.go @@ -421,7 +421,7 @@ var _ = SIGDescribe("kubelet", func() { pod = createPodUsingNfs(ctx, f, c, ns, nfsIP, t.podCmd) ginkgo.By("Stop the NFS server") - e2evolume.StopNFSServer(f, nfsServerPod) + e2evolume.StopNFSServer(ctx, f, nfsServerPod) ginkgo.By("Delete the pod mounted to the NFS volume -- expect failure") err := e2epod.DeletePodWithWait(ctx, c, pod) @@ -432,7 +432,7 @@ var _ = SIGDescribe("kubelet", func() { checkPodCleanup(ctx, c, pod, false) ginkgo.By("Restart the nfs server") - e2evolume.RestartNFSServer(f, nfsServerPod) + e2evolume.RestartNFSServer(ctx, f, nfsServerPod) ginkgo.By("Verify that the deleted client pod is now cleaned up") checkPodCleanup(ctx, c, pod, true) diff --git a/test/e2e/storage/csimock/csi_fsgroup_policy.go b/test/e2e/storage/csimock/csi_fsgroup_policy.go index 14dab2c21f0..2bc4a9a9c33 100644 --- a/test/e2e/storage/csimock/csi_fsgroup_policy.go +++ b/test/e2e/storage/csimock/csi_fsgroup_policy.go @@ -28,7 +28,6 @@ import ( "k8s.io/kubernetes/test/e2e/framework" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper" - e2evolume "k8s.io/kubernetes/test/e2e/framework/volume" "k8s.io/kubernetes/test/e2e/storage/utils" admissionapi "k8s.io/pod-security-admission/api" ) @@ -166,27 +165,27 @@ func waitUtilFSGroupInPod(ctx context.Context, m *mockDriverSetup, modified bool // Create the subdirectory to ensure that fsGroup propagates createDirectory := fmt.Sprintf("mkdir %s", dirName) - _, _, err = e2evolume.PodExec(m.f, pod, createDirectory) + _, _, err = e2epod.ExecShellInPodWithFullOutput(ctx, m.f, pod.Name, createDirectory) framework.ExpectNoError(err, "failed: creating the directory: %s", err) // Inject the contents onto the mount createFile := fmt.Sprintf("echo '%s' > '%s'; sync", "filecontents", fileName) - _, _, err = e2evolume.PodExec(m.f, pod, createFile) + _, _, err = e2epod.ExecShellInPodWithFullOutput(ctx, m.f, pod.Name, createFile) framework.ExpectNoError(err, "failed: writing the contents: %s", err) // Delete the created file. This step is mandatory, as the mock driver // won't clean up the contents automatically. defer func() { deleteDir := fmt.Sprintf("rm -fr %s", dirName) - _, _, err = e2evolume.PodExec(m.f, pod, deleteDir) + _, _, err = e2epod.ExecShellInPodWithFullOutput(ctx, m.f, pod.Name, deleteDir) framework.ExpectNoError(err, "failed: deleting the directory: %s", err) }() // Ensure that the fsGroup matches what we expect if modified { - utils.VerifyFSGroupInPod(m.f, fileName, strconv.FormatInt(*fsGroup, 10), pod) + utils.VerifyFSGroupInPod(ctx, m.f, fileName, strconv.FormatInt(*fsGroup, 10), pod) } else { - utils.VerifyFSGroupInPod(m.f, fileName, "root", pod) + utils.VerifyFSGroupInPod(ctx, m.f, fileName, "root", pod) } }) diff --git a/test/e2e/storage/host_path_type.go b/test/e2e/storage/host_path_type.go index 5b1a8154995..f177eca24a0 100644 --- a/test/e2e/storage/host_path_type.go +++ b/test/e2e/storage/host_path_type.go @@ -28,7 +28,6 @@ import ( "k8s.io/kubernetes/test/e2e/framework" e2eevents "k8s.io/kubernetes/test/e2e/framework/events" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" - e2evolume "k8s.io/kubernetes/test/e2e/framework/volume" "k8s.io/kubernetes/test/e2e/storage/utils" imageutils "k8s.io/kubernetes/test/utils/image" admissionapi "k8s.io/pod-security-admission/api" @@ -270,7 +269,7 @@ var _ = utils.SIGDescribe("HostPathType Character Device", framework.WithSlow(), targetCharDev = path.Join(hostBaseDir, "achardev") ginkgo.By("Create a character device for further testing") cmd := fmt.Sprintf("mknod %s c 89 1", path.Join(mountBaseDir, "achardev")) - stdout, stderr, err := e2evolume.PodExec(f, basePod, cmd) + stdout, stderr, err := e2epod.ExecShellInPodWithFullOutput(ctx, f, basePod.Name, cmd) framework.ExpectNoError(err, "command: %q, stdout: %s\nstderr: %s", cmd, stdout, stderr) }) @@ -340,7 +339,7 @@ var _ = utils.SIGDescribe("HostPathType Block Device", framework.WithSlow(), fun targetBlockDev = path.Join(hostBaseDir, "ablkdev") ginkgo.By("Create a block device for further testing") cmd := fmt.Sprintf("mknod %s b 89 1", path.Join(mountBaseDir, "ablkdev")) - stdout, stderr, err := e2evolume.PodExec(f, basePod, cmd) + stdout, stderr, err := e2epod.ExecShellInPodWithFullOutput(ctx, f, basePod.Name, cmd) framework.ExpectNoError(err, "command %q: stdout: %s\nstderr: %s", cmd, stdout, stderr) }) diff --git a/test/e2e/storage/persistent_volumes-local.go b/test/e2e/storage/persistent_volumes-local.go index 9a5bc5711d3..69cd4799cd8 100644 --- a/test/e2e/storage/persistent_volumes-local.go +++ b/test/e2e/storage/persistent_volumes-local.go @@ -48,7 +48,6 @@ import ( e2epv "k8s.io/kubernetes/test/e2e/framework/pv" e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper" e2estatefulset "k8s.io/kubernetes/test/e2e/framework/statefulset" - e2evolume "k8s.io/kubernetes/test/e2e/framework/volume" "k8s.io/kubernetes/test/e2e/storage/utils" imageutils "k8s.io/kubernetes/test/utils/image" admissionapi "k8s.io/pod-security-admission/api" @@ -232,7 +231,7 @@ var _ = utils.SIGDescribe("PersistentVolumes-local", func() { writeCmd := createWriteCmd(volumeDir, testFile, testFileContent, testVol.localVolumeType) ginkgo.By("Writing in pod1") - podRWCmdExec(f, pod1, writeCmd) + podRWCmdExec(ctx, f, pod1, writeCmd) }) ginkgo.AfterEach(func(ctx context.Context) { @@ -243,16 +242,16 @@ var _ = utils.SIGDescribe("PersistentVolumes-local", func() { ginkgo.It("should be able to mount volume and read from pod1", func(ctx context.Context) { ginkgo.By("Reading in pod1") // testFileContent was written in BeforeEach - testReadFileContent(f, volumeDir, testFile, testFileContent, pod1, testVolType) + testReadFileContent(ctx, f, volumeDir, testFile, testFileContent, pod1, testVolType) }) ginkgo.It("should be able to mount volume and write from pod1", func(ctx context.Context) { // testFileContent was written in BeforeEach - testReadFileContent(f, volumeDir, testFile, testFileContent, pod1, testVolType) + testReadFileContent(ctx, f, volumeDir, testFile, testFileContent, pod1, testVolType) ginkgo.By("Writing in pod1") writeCmd := createWriteCmd(volumeDir, testFile, testVol.ltr.Path /*writeTestFileContent*/, testVolType) - podRWCmdExec(f, pod1, writeCmd) + podRWCmdExec(ctx, f, pod1, writeCmd) }) }) @@ -685,10 +684,10 @@ func twoPodsReadWriteTest(ctx context.Context, f *framework.Framework, config *l writeCmd := createWriteCmd(volumeDir, testFile, testFileContent, testVol.localVolumeType) ginkgo.By("Writing in pod1") - podRWCmdExec(f, pod1, writeCmd) + podRWCmdExec(ctx, f, pod1, writeCmd) // testFileContent was written after creating pod1 - testReadFileContent(f, volumeDir, testFile, testFileContent, pod1, testVol.localVolumeType) + testReadFileContent(ctx, f, volumeDir, testFile, testFileContent, pod1, testVol.localVolumeType) ginkgo.By("Creating pod2 to read from the PV") pod2, pod2Err := createLocalPod(ctx, config, testVol, nil) @@ -696,15 +695,15 @@ func twoPodsReadWriteTest(ctx context.Context, f *framework.Framework, config *l verifyLocalPod(ctx, config, testVol, pod2, config.randomNode.Name) // testFileContent was written after creating pod1 - testReadFileContent(f, volumeDir, testFile, testFileContent, pod2, testVol.localVolumeType) + testReadFileContent(ctx, f, volumeDir, testFile, testFileContent, pod2, testVol.localVolumeType) writeCmd = createWriteCmd(volumeDir, testFile, testVol.ltr.Path /*writeTestFileContent*/, testVol.localVolumeType) ginkgo.By("Writing in pod2") - podRWCmdExec(f, pod2, writeCmd) + podRWCmdExec(ctx, f, pod2, writeCmd) ginkgo.By("Reading in pod1") - testReadFileContent(f, volumeDir, testFile, testVol.ltr.Path, pod1, testVol.localVolumeType) + testReadFileContent(ctx, f, volumeDir, testFile, testVol.ltr.Path, pod1, testVol.localVolumeType) ginkgo.By("Deleting pod1") e2epod.DeletePodOrFail(ctx, config.client, config.ns, pod1.Name) @@ -722,10 +721,10 @@ func twoPodsReadWriteSerialTest(ctx context.Context, f *framework.Framework, con writeCmd := createWriteCmd(volumeDir, testFile, testFileContent, testVol.localVolumeType) ginkgo.By("Writing in pod1") - podRWCmdExec(f, pod1, writeCmd) + podRWCmdExec(ctx, f, pod1, writeCmd) // testFileContent was written after creating pod1 - testReadFileContent(f, volumeDir, testFile, testFileContent, pod1, testVol.localVolumeType) + testReadFileContent(ctx, f, volumeDir, testFile, testFileContent, pod1, testVol.localVolumeType) ginkgo.By("Deleting pod1") e2epod.DeletePodOrFail(ctx, config.client, config.ns, pod1.Name) @@ -736,7 +735,7 @@ func twoPodsReadWriteSerialTest(ctx context.Context, f *framework.Framework, con verifyLocalPod(ctx, config, testVol, pod2, config.randomNode.Name) ginkgo.By("Reading in pod2") - testReadFileContent(f, volumeDir, testFile, testFileContent, pod2, testVol.localVolumeType) + testReadFileContent(ctx, f, volumeDir, testFile, testFileContent, pod2, testVol.localVolumeType) ginkgo.By("Deleting pod2") e2epod.DeletePodOrFail(ctx, config.client, config.ns, pod2.Name) @@ -1022,16 +1021,16 @@ func createReadCmd(testFileDir string, testFile string, volumeType localVolumeTy } // Read testFile and evaluate whether it contains the testFileContent -func testReadFileContent(f *framework.Framework, testFileDir string, testFile string, testFileContent string, pod *v1.Pod, volumeType localVolumeType) { +func testReadFileContent(ctx context.Context, f *framework.Framework, testFileDir string, testFile string, testFileContent string, pod *v1.Pod, volumeType localVolumeType) { readCmd := createReadCmd(testFileDir, testFile, volumeType) - readOut := podRWCmdExec(f, pod, readCmd) + readOut := podRWCmdExec(ctx, f, pod, readCmd) gomega.Expect(readOut).To(gomega.ContainSubstring(testFileContent)) } // Execute a read or write command in a pod. // Fail on error -func podRWCmdExec(f *framework.Framework, pod *v1.Pod, cmd string) string { - stdout, stderr, err := e2evolume.PodExec(f, pod, cmd) +func podRWCmdExec(ctx context.Context, f *framework.Framework, pod *v1.Pod, cmd string) string { + stdout, stderr, err := e2epod.ExecShellInPodWithFullOutput(ctx, f, pod.Name, cmd) framework.Logf("podRWCmdExec cmd: %q, out: %q, stderr: %q, err: %v", cmd, stdout, stderr, err) framework.ExpectNoError(err) return stdout diff --git a/test/e2e/storage/testsuites/ephemeral.go b/test/e2e/storage/testsuites/ephemeral.go index 17b281ba03a..d851329805a 100644 --- a/test/e2e/storage/testsuites/ephemeral.go +++ b/test/e2e/storage/testsuites/ephemeral.go @@ -194,7 +194,7 @@ func (p *ephemeralTestSuite) DefineTests(driver storageframework.TestDriver, pat // attempt to create a dummy file and expect for it not to be created command = "ls /mnt/test* && (touch /mnt/test-0/hello-world || true) && [ ! -f /mnt/test-0/hello-world ]" } - e2evolume.VerifyExecInPodSucceed(f, pod, command) + e2epod.VerifyExecInPodSucceed(ctx, f, pod, command) return nil } l.testCase.TestEphemeral(ctx) @@ -214,7 +214,7 @@ func (p *ephemeralTestSuite) DefineTests(driver storageframework.TestDriver, pat if pattern.VolMode == v1.PersistentVolumeBlock { command = "if ! [ -b /mnt/test-0 ]; then echo /mnt/test-0 is not a block device; exit 1; fi" } - e2evolume.VerifyExecInPodSucceed(f, pod, command) + e2epod.VerifyExecInPodSucceed(ctx, f, pod, command) return nil } l.testCase.TestEphemeral(ctx) @@ -308,8 +308,8 @@ func (p *ephemeralTestSuite) DefineTests(driver storageframework.TestDriver, pat // visible in the other. if pattern.VolMode != v1.PersistentVolumeBlock && !readOnly && !shared { ginkgo.By("writing data in one pod and checking the second does not see it (it should get its own volume)") - e2evolume.VerifyExecInPodSucceed(f, pod, "touch /mnt/test-0/hello-world") - e2evolume.VerifyExecInPodSucceed(f, pod2, "[ ! -f /mnt/test-0/hello-world ]") + e2epod.VerifyExecInPodSucceed(ctx, f, pod, "touch /mnt/test-0/hello-world") + e2epod.VerifyExecInPodSucceed(ctx, f, pod2, "[ ! -f /mnt/test-0/hello-world ]") } // TestEphemeral expects the pod to be fully deleted diff --git a/test/e2e/storage/testsuites/fsgroupchangepolicy.go b/test/e2e/storage/testsuites/fsgroupchangepolicy.go index 6aa8512e03e..0669f8b48d1 100644 --- a/test/e2e/storage/testsuites/fsgroupchangepolicy.go +++ b/test/e2e/storage/testsuites/fsgroupchangepolicy.go @@ -250,12 +250,12 @@ func (s *fsGroupChangePolicyTestSuite) DefineTests(driver storageframework.TestD // Change the ownership of files in the initial pod. if test.changedRootDirFileOwnership != 0 { ginkgo.By(fmt.Sprintf("Changing the root directory file ownership to %s", strconv.Itoa(test.changedRootDirFileOwnership))) - storageutils.ChangeFilePathGidInPod(f, rootDirFilePath, strconv.Itoa(test.changedRootDirFileOwnership), pod) + storageutils.ChangeFilePathGidInPod(ctx, f, rootDirFilePath, strconv.Itoa(test.changedRootDirFileOwnership), pod) } if test.changedSubDirFileOwnership != 0 { ginkgo.By(fmt.Sprintf("Changing the sub-directory file ownership to %s", strconv.Itoa(test.changedSubDirFileOwnership))) - storageutils.ChangeFilePathGidInPod(f, subDirFilePath, strconv.Itoa(test.changedSubDirFileOwnership), pod) + storageutils.ChangeFilePathGidInPod(ctx, f, subDirFilePath, strconv.Itoa(test.changedSubDirFileOwnership), pod) } ginkgo.By(fmt.Sprintf("Deleting Pod %s/%s", pod.Namespace, pod.Name)) @@ -281,24 +281,24 @@ func createPodAndVerifyContentGid(ctx context.Context, f *framework.Framework, p ginkgo.By(fmt.Sprintf("Creating a sub-directory and file, and verifying their ownership is %s", podFsGroup)) cmd := fmt.Sprintf("touch %s", rootDirFilePath) var err error - _, _, err = e2evolume.PodExec(f, pod, cmd) + _, _, err = e2epod.ExecShellInPodWithFullOutput(ctx, f, pod.Name, cmd) framework.ExpectNoError(err) - storageutils.VerifyFilePathGidInPod(f, rootDirFilePath, podFsGroup, pod) + storageutils.VerifyFilePathGidInPod(ctx, f, rootDirFilePath, podFsGroup, pod) cmd = fmt.Sprintf("mkdir %s", subdir) - _, _, err = e2evolume.PodExec(f, pod, cmd) + _, _, err = e2epod.ExecShellInPodWithFullOutput(ctx, f, pod.Name, cmd) framework.ExpectNoError(err) cmd = fmt.Sprintf("touch %s", subDirFilePath) - _, _, err = e2evolume.PodExec(f, pod, cmd) + _, _, err = e2epod.ExecShellInPodWithFullOutput(ctx, f, pod.Name, cmd) framework.ExpectNoError(err) - storageutils.VerifyFilePathGidInPod(f, subDirFilePath, podFsGroup, pod) + storageutils.VerifyFilePathGidInPod(ctx, f, subDirFilePath, podFsGroup, pod) return pod } // Verify existing contents of the volume ginkgo.By(fmt.Sprintf("Verifying the ownership of root directory file is %s", expectedRootDirFileOwnership)) - storageutils.VerifyFilePathGidInPod(f, rootDirFilePath, expectedRootDirFileOwnership, pod) + storageutils.VerifyFilePathGidInPod(ctx, f, rootDirFilePath, expectedRootDirFileOwnership, pod) ginkgo.By(fmt.Sprintf("Verifying the ownership of sub directory file is %s", expectedSubDirFileOwnership)) - storageutils.VerifyFilePathGidInPod(f, subDirFilePath, expectedSubDirFileOwnership, pod) + storageutils.VerifyFilePathGidInPod(ctx, f, subDirFilePath, expectedSubDirFileOwnership, pod) return pod } diff --git a/test/e2e/storage/testsuites/multivolume.go b/test/e2e/storage/testsuites/multivolume.go index 792c29e69ac..d54cb454e8c 100644 --- a/test/e2e/storage/testsuites/multivolume.go +++ b/test/e2e/storage/testsuites/multivolume.go @@ -499,18 +499,18 @@ func testAccessMultipleVolumes(ctx context.Context, f *framework.Framework, cs c index := i + 1 path := fmt.Sprintf("/mnt/volume%d", index) ginkgo.By(fmt.Sprintf("Checking if the volume%d exists as expected volume mode (%s)", index, *pvc.Spec.VolumeMode)) - e2evolume.CheckVolumeModeOfPath(f, pod, *pvc.Spec.VolumeMode, path) + e2evolume.CheckVolumeModeOfPath(ctx, f, pod, *pvc.Spec.VolumeMode, path) if readSeedBase > 0 { ginkgo.By(fmt.Sprintf("Checking if read from the volume%d works properly", index)) - storageutils.CheckReadFromPath(f, pod, *pvc.Spec.VolumeMode, false, path, byteLen, readSeedBase+int64(i)) + storageutils.CheckReadFromPath(ctx, f, pod, *pvc.Spec.VolumeMode, false, path, byteLen, readSeedBase+int64(i)) } ginkgo.By(fmt.Sprintf("Checking if write to the volume%d works properly", index)) - storageutils.CheckWriteToPath(f, pod, *pvc.Spec.VolumeMode, false, path, byteLen, writeSeedBase+int64(i)) + storageutils.CheckWriteToPath(ctx, f, pod, *pvc.Spec.VolumeMode, false, path, byteLen, writeSeedBase+int64(i)) ginkgo.By(fmt.Sprintf("Checking if read from the volume%d works properly", index)) - storageutils.CheckReadFromPath(f, pod, *pvc.Spec.VolumeMode, false, path, byteLen, writeSeedBase+int64(i)) + storageutils.CheckReadFromPath(ctx, f, pod, *pvc.Spec.VolumeMode, false, path, byteLen, writeSeedBase+int64(i)) } pod, err = cs.CoreV1().Pods(pod.Namespace).Get(ctx, pod.Name, metav1.GetOptions{}) @@ -599,7 +599,7 @@ func TestConcurrentAccessToSingleVolume(ctx context.Context, f *framework.Framew framework.Failf("Number of pods shouldn't be less than 1, but got %d", len(pods)) } // byteLen should be the size of a sector to enable direct I/O - byteLen = storageutils.GetSectorSize(f, pods[0], path) + byteLen = storageutils.GetSectorSize(ctx, f, pods[0], path) directIO = true } @@ -607,7 +607,7 @@ func TestConcurrentAccessToSingleVolume(ctx context.Context, f *framework.Framew for i, pod := range pods { index := i + 1 ginkgo.By(fmt.Sprintf("Checking if the volume in pod%d exists as expected volume mode (%s)", index, *pvc.Spec.VolumeMode)) - e2evolume.CheckVolumeModeOfPath(f, pod, *pvc.Spec.VolumeMode, path) + e2evolume.CheckVolumeModeOfPath(ctx, f, pod, *pvc.Spec.VolumeMode, path) if readOnly { ginkgo.By("Skipping volume content checks, volume is read-only") @@ -617,17 +617,17 @@ func TestConcurrentAccessToSingleVolume(ctx context.Context, f *framework.Framew if i != 0 { ginkgo.By(fmt.Sprintf("From pod%d, checking if reading the data that pod%d write works properly", index, index-1)) // For 1st pod, no one has written data yet, so pass the read check - storageutils.CheckReadFromPath(f, pod, *pvc.Spec.VolumeMode, directIO, path, byteLen, seed) + storageutils.CheckReadFromPath(ctx, f, pod, *pvc.Spec.VolumeMode, directIO, path, byteLen, seed) } // Update the seed and check if write/read works properly seed = time.Now().UTC().UnixNano() ginkgo.By(fmt.Sprintf("Checking if write to the volume in pod%d works properly", index)) - storageutils.CheckWriteToPath(f, pod, *pvc.Spec.VolumeMode, directIO, path, byteLen, seed) + storageutils.CheckWriteToPath(ctx, f, pod, *pvc.Spec.VolumeMode, directIO, path, byteLen, seed) ginkgo.By(fmt.Sprintf("Checking if read from the volume in pod%d works properly", index)) - storageutils.CheckReadFromPath(f, pod, *pvc.Spec.VolumeMode, directIO, path, byteLen, seed) + storageutils.CheckReadFromPath(ctx, f, pod, *pvc.Spec.VolumeMode, directIO, path, byteLen, seed) } if len(pods) < 2 { @@ -643,7 +643,7 @@ func TestConcurrentAccessToSingleVolume(ctx context.Context, f *framework.Framew index := i + 1 // index of pod and index of pvc match, because pods are created above way ginkgo.By(fmt.Sprintf("Rechecking if the volume in pod%d exists as expected volume mode (%s)", index, *pvc.Spec.VolumeMode)) - e2evolume.CheckVolumeModeOfPath(f, pod, *pvc.Spec.VolumeMode, "/mnt/volume1") + e2evolume.CheckVolumeModeOfPath(ctx, f, pod, *pvc.Spec.VolumeMode, "/mnt/volume1") if readOnly { ginkgo.By("Skipping volume content checks, volume is read-only") @@ -656,16 +656,16 @@ func TestConcurrentAccessToSingleVolume(ctx context.Context, f *framework.Framew } else { ginkgo.By(fmt.Sprintf("From pod%d, rechecking if reading the data that pod%d write works properly", index, index-1)) } - storageutils.CheckReadFromPath(f, pod, *pvc.Spec.VolumeMode, directIO, path, byteLen, seed) + storageutils.CheckReadFromPath(ctx, f, pod, *pvc.Spec.VolumeMode, directIO, path, byteLen, seed) // Update the seed and check if write/read works properly seed = time.Now().UTC().UnixNano() ginkgo.By(fmt.Sprintf("Rechecking if write to the volume in pod%d works properly", index)) - storageutils.CheckWriteToPath(f, pod, *pvc.Spec.VolumeMode, directIO, path, byteLen, seed) + storageutils.CheckWriteToPath(ctx, f, pod, *pvc.Spec.VolumeMode, directIO, path, byteLen, seed) ginkgo.By(fmt.Sprintf("Rechecking if read from the volume in pod%d works properly", index)) - storageutils.CheckReadFromPath(f, pod, *pvc.Spec.VolumeMode, directIO, path, byteLen, seed) + storageutils.CheckReadFromPath(ctx, f, pod, *pvc.Spec.VolumeMode, directIO, path, byteLen, seed) } } diff --git a/test/e2e/storage/testsuites/volume_io.go b/test/e2e/storage/testsuites/volume_io.go index dce9baf767c..6c01dbf1624 100644 --- a/test/e2e/storage/testsuites/volume_io.go +++ b/test/e2e/storage/testsuites/volume_io.go @@ -243,11 +243,11 @@ func makePodSpec(config e2evolume.TestConfig, initCmd string, volsrc v1.VolumeSo } // Write `fsize` bytes to `fpath` in the pod, using dd and the `ddInput` file. -func writeToFile(f *framework.Framework, pod *v1.Pod, fpath, ddInput string, fsize int64) error { +func writeToFile(ctx context.Context, f *framework.Framework, pod *v1.Pod, fpath, ddInput string, fsize int64) error { ginkgo.By(fmt.Sprintf("writing %d bytes to test file %s", fsize, fpath)) loopCnt := fsize / storageframework.MinFileSize writeCmd := fmt.Sprintf("i=0; while [ $i -lt %d ]; do dd if=%s bs=%d >>%s 2>/dev/null; let i+=1; done", loopCnt, ddInput, storageframework.MinFileSize, fpath) - stdout, stderr, err := e2evolume.PodExec(f, pod, writeCmd) + stdout, stderr, err := e2epod.ExecShellInPodWithFullOutput(ctx, f, pod.Name, writeCmd) if err != nil { return fmt.Errorf("error writing to volume using %q: %s\nstdout: %s\nstderr: %s", writeCmd, err, stdout, stderr) } @@ -255,9 +255,9 @@ func writeToFile(f *framework.Framework, pod *v1.Pod, fpath, ddInput string, fsi } // Verify that the test file is the expected size and contains the expected content. -func verifyFile(f *framework.Framework, pod *v1.Pod, fpath string, expectSize int64, ddInput string) error { +func verifyFile(ctx context.Context, f *framework.Framework, pod *v1.Pod, fpath string, expectSize int64, ddInput string) error { ginkgo.By("verifying file size") - rtnstr, stderr, err := e2evolume.PodExec(f, pod, fmt.Sprintf("stat -c %%s %s", fpath)) + rtnstr, stderr, err := e2epod.ExecShellInPodWithFullOutput(ctx, f, pod.Name, fmt.Sprintf("stat -c %%s %s", fpath)) if err != nil || rtnstr == "" { return fmt.Errorf("unable to get file size via `stat %s`: %v\nstdout: %s\nstderr: %s", fpath, err, rtnstr, stderr) } @@ -270,14 +270,14 @@ func verifyFile(f *framework.Framework, pod *v1.Pod, fpath string, expectSize in } ginkgo.By("verifying file hash") - rtnstr, stderr, err = e2evolume.PodExec(f, pod, fmt.Sprintf("md5sum %s | cut -d' ' -f1", fpath)) + rtnstr, stderr, err = e2epod.ExecShellInPodWithFullOutput(ctx, f, pod.Name, fmt.Sprintf("md5sum %s | cut -d' ' -f1", fpath)) if err != nil { return fmt.Errorf("unable to test file hash via `md5sum %s`: %v\nstdout: %s\nstderr: %s", fpath, err, rtnstr, stderr) } actualHash := strings.TrimSuffix(rtnstr, "\n") expectedHash, ok := md5hashes[expectSize] if !ok { - return fmt.Errorf("File hash is unknown for file size %d. Was a new file size added to the test suite?", + return fmt.Errorf("file hash is unknown for file size %d. Was a new file size added to the test suite?", expectSize) } if actualHash != expectedHash { @@ -289,9 +289,9 @@ func verifyFile(f *framework.Framework, pod *v1.Pod, fpath string, expectSize in } // Delete `fpath` to save some disk space on host. Delete errors are logged but ignored. -func deleteFile(f *framework.Framework, pod *v1.Pod, fpath string) { +func deleteFile(ctx context.Context, f *framework.Framework, pod *v1.Pod, fpath string) { ginkgo.By(fmt.Sprintf("deleting test file %s...", fpath)) - stdout, stderr, err := e2evolume.PodExec(f, pod, fmt.Sprintf("rm -f %s", fpath)) + stdout, stderr, err := e2epod.ExecShellInPodWithFullOutput(ctx, f, pod.Name, fmt.Sprintf("rm -f %s", fpath)) if err != nil { // keep going, the test dir will be deleted when the volume is unmounted framework.Logf("unable to delete test file %s: %v\nerror ignored, continuing test\nstdout: %s\nstderr: %s", fpath, err, stdout, stderr) @@ -323,7 +323,7 @@ func testVolumeIO(ctx context.Context, f *framework.Framework, cs clientset.Inte return fmt.Errorf("failed to create client pod %q: %w", clientPod.Name, err) } ginkgo.DeferCleanup(func(ctx context.Context) { - deleteFile(f, clientPod, ddInput) + deleteFile(ctx, f, clientPod, ddInput) ginkgo.By(fmt.Sprintf("deleting client pod %q...", clientPod.Name)) e := e2epod.DeletePodWithWait(ctx, cs, clientPod) if e != nil { @@ -350,12 +350,12 @@ func testVolumeIO(ctx context.Context, f *framework.Framework, cs clientset.Inte } fpath := filepath.Join(mountPath, fmt.Sprintf("%s-%d", file, fsize)) defer func() { - deleteFile(f, clientPod, fpath) + deleteFile(ctx, f, clientPod, fpath) }() - if err = writeToFile(f, clientPod, fpath, ddInput, fsize); err != nil { + if err = writeToFile(ctx, f, clientPod, fpath, ddInput, fsize); err != nil { return err } - if err = verifyFile(f, clientPod, fpath, fsize, ddInput); err != nil { + if err = verifyFile(ctx, f, clientPod, fpath, fsize, ddInput); err != nil { return err } } diff --git a/test/e2e/storage/utils/utils.go b/test/e2e/storage/utils/utils.go index e902d5224d2..d6d9c995923 100644 --- a/test/e2e/storage/utils/utils.go +++ b/test/e2e/storage/utils/utils.go @@ -64,9 +64,9 @@ const ( ) // VerifyFSGroupInPod verifies that the passed in filePath contains the expectedFSGroup -func VerifyFSGroupInPod(f *framework.Framework, filePath, expectedFSGroup string, pod *v1.Pod) { +func VerifyFSGroupInPod(ctx context.Context, f *framework.Framework, filePath, expectedFSGroup string, pod *v1.Pod) { cmd := fmt.Sprintf("ls -l %s", filePath) - stdout, stderr, err := e2evolume.PodExec(f, pod, cmd) + stdout, stderr, err := e2epod.ExecShellInPodWithFullOutput(ctx, f, pod.Name, cmd) framework.ExpectNoError(err) framework.Logf("pod %s/%s exec for cmd %s, stdout: %s, stderr: %s", pod.Namespace, pod.Name, cmd, stdout, stderr) fsGroupResult := strings.Fields(stdout)[3] @@ -91,7 +91,7 @@ func TestKubeletRestartsAndRestoresMount(ctx context.Context, c clientset.Interf seed := time.Now().UTC().UnixNano() ginkgo.By("Writing to the volume.") - CheckWriteToPath(f, clientPod, v1.PersistentVolumeFilesystem, false, volumePath, byteLen, seed) + CheckWriteToPath(ctx, f, clientPod, v1.PersistentVolumeFilesystem, false, volumePath, byteLen, seed) ginkgo.By("Restarting kubelet") KubeletCommand(ctx, KRestart, c, clientPod) @@ -100,7 +100,7 @@ func TestKubeletRestartsAndRestoresMount(ctx context.Context, c clientset.Interf time.Sleep(20 * time.Second) ginkgo.By("Testing that written file is accessible.") - CheckReadFromPath(f, clientPod, v1.PersistentVolumeFilesystem, false, volumePath, byteLen, seed) + CheckReadFromPath(ctx, f, clientPod, v1.PersistentVolumeFilesystem, false, volumePath, byteLen, seed) framework.Logf("Volume mount detected on pod %s and written file %s is readable post-restart.", clientPod.Name, volumePath) } @@ -111,7 +111,7 @@ func TestKubeletRestartsAndRestoresMap(ctx context.Context, c clientset.Interfac seed := time.Now().UTC().UnixNano() ginkgo.By("Writing to the volume.") - CheckWriteToPath(f, clientPod, v1.PersistentVolumeBlock, false, volumePath, byteLen, seed) + CheckWriteToPath(ctx, f, clientPod, v1.PersistentVolumeBlock, false, volumePath, byteLen, seed) ginkgo.By("Restarting kubelet") KubeletCommand(ctx, KRestart, c, clientPod) @@ -120,7 +120,7 @@ func TestKubeletRestartsAndRestoresMap(ctx context.Context, c clientset.Interfac time.Sleep(20 * time.Second) ginkgo.By("Testing that written pv is accessible.") - CheckReadFromPath(f, clientPod, v1.PersistentVolumeBlock, false, volumePath, byteLen, seed) + CheckReadFromPath(ctx, f, clientPod, v1.PersistentVolumeBlock, false, volumePath, byteLen, seed) framework.Logf("Volume map detected on pod %s and written data %s is readable post-restart.", clientPod.Name, volumePath) } @@ -151,7 +151,7 @@ func TestVolumeUnmountsFromDeletedPodWithForceOption(ctx context.Context, c clie ginkgo.By("Writing to the volume.") byteLen := 64 seed := time.Now().UTC().UnixNano() - CheckWriteToPath(f, clientPod, v1.PersistentVolumeFilesystem, false, volumePath, byteLen, seed) + CheckWriteToPath(ctx, f, clientPod, v1.PersistentVolumeFilesystem, false, volumePath, byteLen, seed) // This command is to make sure kubelet is started after test finishes no matter it fails or not. ginkgo.DeferCleanup(KubeletCommand, KStart, c, clientPod) @@ -201,7 +201,7 @@ func TestVolumeUnmountsFromDeletedPodWithForceOption(ctx context.Context, c clie gomega.Expect(result.Code).To(gomega.Equal(0), fmt.Sprintf("Expected grep exit code of 0, got %d", result.Code)) ginkgo.By("Testing that written file is accessible in the second pod.") - CheckReadFromPath(f, secondPod, v1.PersistentVolumeFilesystem, false, volumePath, byteLen, seed) + CheckReadFromPath(ctx, f, secondPod, v1.PersistentVolumeFilesystem, false, volumePath, byteLen, seed) err = c.CoreV1().Pods(secondPod.Namespace).Delete(context.TODO(), secondPod.Name, metav1.DeleteOptions{}) framework.ExpectNoError(err, "when deleting the second pod") err = e2epod.WaitForPodNotFoundInNamespace(ctx, f.ClientSet, secondPod.Name, f.Namespace.Name, f.Timeouts.PodDelete) @@ -446,28 +446,28 @@ func isSudoPresent(ctx context.Context, nodeIP string, provider string) bool { } // CheckReadWriteToPath check that path can b e read and written -func CheckReadWriteToPath(f *framework.Framework, pod *v1.Pod, volMode v1.PersistentVolumeMode, path string) { +func CheckReadWriteToPath(ctx context.Context, f *framework.Framework, pod *v1.Pod, volMode v1.PersistentVolumeMode, path string) { if volMode == v1.PersistentVolumeBlock { // random -> file1 - e2evolume.VerifyExecInPodSucceed(f, pod, "dd if=/dev/urandom of=/tmp/file1 bs=64 count=1") + e2epod.VerifyExecInPodSucceed(ctx, f, pod, "dd if=/dev/urandom of=/tmp/file1 bs=64 count=1") // file1 -> dev (write to dev) - e2evolume.VerifyExecInPodSucceed(f, pod, fmt.Sprintf("dd if=/tmp/file1 of=%s bs=64 count=1", path)) + e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("dd if=/tmp/file1 of=%s bs=64 count=1", path)) // dev -> file2 (read from dev) - e2evolume.VerifyExecInPodSucceed(f, pod, fmt.Sprintf("dd if=%s of=/tmp/file2 bs=64 count=1", path)) + e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("dd if=%s of=/tmp/file2 bs=64 count=1", path)) // file1 == file2 (check contents) - e2evolume.VerifyExecInPodSucceed(f, pod, "diff /tmp/file1 /tmp/file2") + e2epod.VerifyExecInPodSucceed(ctx, f, pod, "diff /tmp/file1 /tmp/file2") // Clean up temp files - e2evolume.VerifyExecInPodSucceed(f, pod, "rm -f /tmp/file1 /tmp/file2") + e2epod.VerifyExecInPodSucceed(ctx, f, pod, "rm -f /tmp/file1 /tmp/file2") // Check that writing file to block volume fails - e2evolume.VerifyExecInPodFail(f, pod, fmt.Sprintf("echo 'Hello world.' > %s/file1.txt", path), 1) + e2epod.VerifyExecInPodFail(ctx, f, pod, fmt.Sprintf("echo 'Hello world.' > %s/file1.txt", path), 1) } else { // text -> file1 (write to file) - e2evolume.VerifyExecInPodSucceed(f, pod, fmt.Sprintf("echo 'Hello world.' > %s/file1.txt", path)) + e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("echo 'Hello world.' > %s/file1.txt", path)) // grep file1 (read from file and check contents) - e2evolume.VerifyExecInPodSucceed(f, pod, readFile("Hello word.", path)) + e2epod.VerifyExecInPodSucceed(ctx, f, pod, readFile("Hello word.", path)) // Check that writing to directory as block volume fails - e2evolume.VerifyExecInPodFail(f, pod, fmt.Sprintf("dd if=/dev/urandom of=%s bs=64 count=1", path), 1) + e2epod.VerifyExecInPodFail(ctx, f, pod, fmt.Sprintf("dd if=/dev/urandom of=%s bs=64 count=1", path), 1) } } @@ -497,7 +497,7 @@ func genBinDataFromSeed(len int, seed int64) []byte { // directIO to function correctly, is to read whole sector(s) for Block-mode // PVCs (normally a sector is 512 bytes), or memory pages for files (commonly // 4096 bytes). -func CheckReadFromPath(f *framework.Framework, pod *v1.Pod, volMode v1.PersistentVolumeMode, directIO bool, path string, len int, seed int64) { +func CheckReadFromPath(ctx context.Context, f *framework.Framework, pod *v1.Pod, volMode v1.PersistentVolumeMode, directIO bool, path string, len int, seed int64) { var pathForVolMode string var iflag string @@ -513,8 +513,8 @@ func CheckReadFromPath(f *framework.Framework, pod *v1.Pod, volMode v1.Persisten sum := sha256.Sum256(genBinDataFromSeed(len, seed)) - e2evolume.VerifyExecInPodSucceed(f, pod, fmt.Sprintf("dd if=%s %s bs=%d count=1 | sha256sum", pathForVolMode, iflag, len)) - e2evolume.VerifyExecInPodSucceed(f, pod, fmt.Sprintf("dd if=%s %s bs=%d count=1 | sha256sum | grep -Fq %x", pathForVolMode, iflag, len, sum)) + e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("dd if=%s %s bs=%d count=1 | sha256sum", pathForVolMode, iflag, len)) + e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("dd if=%s %s bs=%d count=1 | sha256sum | grep -Fq %x", pathForVolMode, iflag, len, sum)) } // CheckWriteToPath that file can be properly written. @@ -522,7 +522,7 @@ func CheckReadFromPath(f *framework.Framework, pod *v1.Pod, volMode v1.Persisten // Note: nocache does not work with (default) BusyBox Pods. To read without // caching, enable directIO with CheckReadFromPath and check the hints about // the len requirements. -func CheckWriteToPath(f *framework.Framework, pod *v1.Pod, volMode v1.PersistentVolumeMode, nocache bool, path string, len int, seed int64) { +func CheckWriteToPath(ctx context.Context, f *framework.Framework, pod *v1.Pod, volMode v1.PersistentVolumeMode, nocache bool, path string, len int, seed int64) { var pathForVolMode string var oflag string @@ -538,13 +538,13 @@ func CheckWriteToPath(f *framework.Framework, pod *v1.Pod, volMode v1.Persistent encoded := base64.StdEncoding.EncodeToString(genBinDataFromSeed(len, seed)) - e2evolume.VerifyExecInPodSucceed(f, pod, fmt.Sprintf("echo %s | base64 -d | sha256sum", encoded)) - e2evolume.VerifyExecInPodSucceed(f, pod, fmt.Sprintf("echo %s | base64 -d | dd of=%s %s bs=%d count=1", encoded, pathForVolMode, oflag, len)) + e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("echo %s | base64 -d | sha256sum", encoded)) + e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("echo %s | base64 -d | dd of=%s %s bs=%d count=1", encoded, pathForVolMode, oflag, len)) } // GetSectorSize returns the sector size of the device. -func GetSectorSize(f *framework.Framework, pod *v1.Pod, device string) int { - stdout, _, err := e2evolume.PodExec(f, pod, fmt.Sprintf("blockdev --getss %s", device)) +func GetSectorSize(ctx context.Context, f *framework.Framework, pod *v1.Pod, device string) int { + stdout, _, err := e2epod.ExecShellInPodWithFullOutput(ctx, f, pod.Name, fmt.Sprintf("blockdev --getss %s", device)) framework.ExpectNoError(err, "Failed to get sector size of %s", device) ss, err := strconv.Atoi(stdout) framework.ExpectNoError(err, "Sector size returned by blockdev command isn't integer value.") @@ -723,9 +723,9 @@ func WaitForGVRFinalizer(ctx context.Context, c dynamic.Interface, gvr schema.Gr } // VerifyFilePathGidInPod verfies expected GID of the target filepath -func VerifyFilePathGidInPod(f *framework.Framework, filePath, expectedGid string, pod *v1.Pod) { +func VerifyFilePathGidInPod(ctx context.Context, f *framework.Framework, filePath, expectedGid string, pod *v1.Pod) { cmd := fmt.Sprintf("ls -l %s", filePath) - stdout, stderr, err := e2evolume.PodExec(f, pod, cmd) + stdout, stderr, err := e2epod.ExecShellInPodWithFullOutput(ctx, f, pod.Name, cmd) framework.ExpectNoError(err) framework.Logf("pod %s/%s exec for cmd %s, stdout: %s, stderr: %s", pod.Namespace, pod.Name, cmd, stdout, stderr) ll := strings.Fields(stdout) @@ -734,11 +734,11 @@ func VerifyFilePathGidInPod(f *framework.Framework, filePath, expectedGid string } // ChangeFilePathGidInPod changes the GID of the target filepath. -func ChangeFilePathGidInPod(f *framework.Framework, filePath, targetGid string, pod *v1.Pod) { +func ChangeFilePathGidInPod(ctx context.Context, f *framework.Framework, filePath, targetGid string, pod *v1.Pod) { cmd := fmt.Sprintf("chgrp %s %s", targetGid, filePath) - _, _, err := e2evolume.PodExec(f, pod, cmd) + _, _, err := e2epod.ExecShellInPodWithFullOutput(ctx, f, pod.Name, cmd) framework.ExpectNoError(err) - VerifyFilePathGidInPod(f, filePath, targetGid, pod) + VerifyFilePathGidInPod(ctx, f, filePath, targetGid, pod) } // DeleteStorageClass deletes the passed in StorageClass and catches errors other than "Not Found" diff --git a/test/e2e/upgrades/storage/volume_mode.go b/test/e2e/upgrades/storage/volume_mode.go index 8fe978740e4..6bea0776c80 100644 --- a/test/e2e/upgrades/storage/volume_mode.go +++ b/test/e2e/upgrades/storage/volume_mode.go @@ -105,10 +105,10 @@ func (t *VolumeModeDowngradeTest) Setup(ctx context.Context, f *framework.Framew framework.ExpectNoError(err) ginkgo.By("Checking if PV exists as expected volume mode") - e2evolume.CheckVolumeModeOfPath(f, t.pod, block, devicePath) + e2evolume.CheckVolumeModeOfPath(ctx, f, t.pod, block, devicePath) ginkgo.By("Checking if read/write to PV works properly") - storageutils.CheckReadWriteToPath(f, t.pod, block, devicePath) + storageutils.CheckReadWriteToPath(ctx, f, t.pod, block, devicePath) } // Test waits for the downgrade to complete, and then verifies that a pod can no @@ -118,7 +118,7 @@ func (t *VolumeModeDowngradeTest) Test(ctx context.Context, f *framework.Framewo <-done ginkgo.By("Verifying that nothing exists at the device path in the pod") - e2evolume.VerifyExecInPodFail(f, t.pod, fmt.Sprintf("test -e %s", devicePath), 1) + e2epod.VerifyExecInPodFail(ctx, f, t.pod, fmt.Sprintf("test -e %s", devicePath), 1) } // Teardown cleans up any remaining resources. diff --git a/test/e2e_node/mirror_pod_test.go b/test/e2e_node/mirror_pod_test.go index 7549640d5ad..78dfa0c2b5e 100644 --- a/test/e2e_node/mirror_pod_test.go +++ b/test/e2e_node/mirror_pod_test.go @@ -231,7 +231,7 @@ var _ = SIGDescribe("MirrorPod", func() { } ginkgo.By("Stopping the NFS server") - e2evolume.StopNFSServer(f, nfsServerPod) + e2evolume.StopNFSServer(ctx, f, nfsServerPod) ginkgo.By(fmt.Sprintf("Deleting the static nfs test pod: %s", staticPodName)) err = deleteStaticPod(podPath, staticPodName, ns) @@ -243,7 +243,7 @@ var _ = SIGDescribe("MirrorPod", func() { }, 5*time.Minute, 10*time.Second).Should(gomega.BeTrueBecause("pod volume should exist while nfs server is stopped")) ginkgo.By("Start the NFS server") - e2evolume.RestartNFSServer(f, nfsServerPod) + e2evolume.RestartNFSServer(ctx, f, nfsServerPod) ginkgo.By("Waiting for the pod volume to deleted after the NFS server is started") gomega.Eventually(func() bool {