github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/test/e2e/run_signal_test.go (about) 1 // +build !remoteclient 2 3 package integration 4 5 import ( 6 "fmt" 7 "io" 8 "os" 9 "path/filepath" 10 "strings" 11 "syscall" 12 "time" 13 14 "github.com/containers/libpod/pkg/rootless" 15 . "github.com/containers/libpod/test/utils" 16 . "github.com/onsi/ginkgo" 17 . "github.com/onsi/gomega" 18 "golang.org/x/sys/unix" 19 ) 20 21 const sigCatch = "trap \"echo FOO >> /h/fifo \" 8; echo READY >> /h/fifo; while :; do sleep 0.25; done" 22 const sigCatch2 = "trap \"echo Received\" SIGFPE; while :; do sleep 0.25; done" 23 24 var _ = Describe("Podman run with --sig-proxy", func() { 25 var ( 26 tmpdir string 27 err error 28 podmanTest *PodmanTestIntegration 29 ) 30 31 BeforeEach(func() { 32 tmpdir, err = CreateTempDirInTempDir() 33 if err != nil { 34 os.Exit(1) 35 } 36 podmanTest = PodmanTestCreate(tmpdir) 37 podmanTest.Setup() 38 podmanTest.SeedImages() 39 }) 40 41 AfterEach(func() { 42 podmanTest.Cleanup() 43 f := CurrentGinkgoTestDescription() 44 processTestResult(f) 45 46 }) 47 48 Specify("signals are forwarded to container using sig-proxy", func() { 49 if podmanTest.Host.Arch == "ppc64le" { 50 Skip("Doesn't work on ppc64le") 51 } 52 signal := syscall.SIGFPE 53 // Set up a socket for communication 54 udsDir := filepath.Join(tmpdir, "socket") 55 os.Mkdir(udsDir, 0700) 56 udsPath := filepath.Join(udsDir, "fifo") 57 syscall.Mkfifo(udsPath, 0600) 58 if rootless.IsRootless() { 59 podmanTest.RestoreArtifact(fedoraMinimal) 60 } 61 _, pid := podmanTest.PodmanPID([]string{"run", "-it", "-v", fmt.Sprintf("%s:/h:Z", udsDir), fedoraMinimal, "bash", "-c", sigCatch}) 62 63 uds, _ := os.OpenFile(udsPath, os.O_RDONLY|syscall.O_NONBLOCK, 0600) 64 defer uds.Close() 65 66 // Wait for the script in the container to alert us that it is READY 67 counter := 0 68 for { 69 buf := make([]byte, 1024) 70 n, err := uds.Read(buf[:]) 71 if err != nil && err != io.EOF { 72 fmt.Println(err) 73 return 74 } 75 data := string(buf[0:n]) 76 if strings.Contains(data, "READY") { 77 break 78 } 79 time.Sleep(1 * time.Second) 80 if counter == 15 { 81 Fail("Timed out waiting for READY from container") 82 } 83 counter++ 84 } 85 // Ok, container is up and running now and so is the script 86 87 if err := unix.Kill(pid, signal); err != nil { 88 Fail(fmt.Sprintf("error killing podman process %d: %v", pid, err)) 89 } 90 91 // The sending of the signal above will send FOO to the socket; here we 92 // listen to the socket for that. 93 counter = 0 94 for { 95 buf := make([]byte, 1024) 96 n, err := uds.Read(buf[:]) 97 if err != nil { 98 fmt.Println(err) 99 return 100 } 101 data := string(buf[0:n]) 102 if strings.Contains(data, "FOO") { 103 break 104 } 105 time.Sleep(1 * time.Second) 106 if counter == 15 { 107 Fail("timed out waiting for FOO from container") 108 } 109 counter++ 110 } 111 }) 112 113 Specify("signals are not forwarded to container with sig-proxy false", func() { 114 signal := syscall.SIGFPE 115 if rootless.IsRootless() { 116 podmanTest.RestoreArtifact(fedoraMinimal) 117 } 118 session, pid := podmanTest.PodmanPID([]string{"run", "--name", "test2", "--sig-proxy=false", fedoraMinimal, "bash", "-c", sigCatch2}) 119 120 ok := WaitForContainer(podmanTest) 121 Expect(ok).To(BeTrue()) 122 123 // Kill with given signal 124 // Should be no output, SIGPOLL is usually ignored 125 if err := unix.Kill(pid, signal); err != nil { 126 Fail(fmt.Sprintf("error killing podman process %d: %v", pid, err)) 127 } 128 129 // Kill with -9 to guarantee the container dies 130 killSession := podmanTest.Podman([]string{"kill", "-s", "9", "test2"}) 131 killSession.WaitWithDefaultTimeout() 132 Expect(killSession.ExitCode()).To(Equal(0)) 133 134 session.WaitWithDefaultTimeout() 135 Expect(session.ExitCode()).ToNot(Equal(0)) 136 ok, _ = session.GrepString("Received") 137 Expect(ok).To(BeFalse()) 138 }) 139 140 })