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  })