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