github.com/AbhinandanKurakure/podman/v3@v3.4.10/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/v3/pkg/rootless"
    13  	. "github.com/containers/podman/v3/test/utils"
    14  	. "github.com/onsi/ginkgo"
    15  	. "github.com/onsi/gomega"
    16  	. "github.com/onsi/gomega/gexec"
    17  	"golang.org/x/sys/unix"
    18  )
    19  
    20  const sigCatch = "trap \"echo FOO >> /h/fifo \" 8; echo READY >> /h/fifo; while :; do sleep 0.25; done"
    21  const sigCatch2 = "trap \"echo Received\" SIGFPE; while :; do sleep 0.25; done"
    22  
    23  var _ = Describe("Podman run with --sig-proxy", func() {
    24  	var (
    25  		tmpdir     string
    26  		err        error
    27  		podmanTest *PodmanTestIntegration
    28  	)
    29  
    30  	BeforeEach(func() {
    31  		tmpdir, err = CreateTempDirInTempDir()
    32  		if err != nil {
    33  			os.Exit(1)
    34  		}
    35  		podmanTest = PodmanTestCreate(tmpdir)
    36  		podmanTest.Setup()
    37  		podmanTest.SeedImages()
    38  	})
    39  
    40  	AfterEach(func() {
    41  		podmanTest.Cleanup()
    42  		f := CurrentGinkgoTestDescription()
    43  		processTestResult(f)
    44  
    45  	})
    46  
    47  	Specify("signals are forwarded to container using sig-proxy", func() {
    48  		SkipIfRemote("FIXME: This looks like it is supposed to work in remote")
    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  		SkipIfRemote("FIXME: This looks like it is supposed to work in remote")
   115  		signal := syscall.SIGFPE
   116  		if rootless.IsRootless() {
   117  			podmanTest.RestoreArtifact(fedoraMinimal)
   118  		}
   119  		session, pid := podmanTest.PodmanPID([]string{"run", "--name", "test2", "--sig-proxy=false", fedoraMinimal, "bash", "-c", sigCatch2})
   120  
   121  		ok := WaitForContainer(podmanTest)
   122  		Expect(ok).To(BeTrue())
   123  
   124  		// Kill with given signal
   125  		// Should be no output, SIGPOLL is usually ignored
   126  		if err := unix.Kill(pid, signal); err != nil {
   127  			Fail(fmt.Sprintf("error killing podman process %d: %v", pid, err))
   128  		}
   129  
   130  		// Kill with -9 to guarantee the container dies
   131  		killSession := podmanTest.Podman([]string{"kill", "-s", "9", "test2"})
   132  		killSession.WaitWithDefaultTimeout()
   133  		Expect(killSession).Should(Exit(0))
   134  
   135  		session.WaitWithDefaultTimeout()
   136  		Expect(session).To(ExitWithError())
   137  		ok, _ = session.GrepString("Received")
   138  		Expect(ok).To(BeFalse())
   139  	})
   140  
   141  })