diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index 1b6bbaecdd..ab9a9cf92b 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -546,6 +546,13 @@ func (ic *ContainerEngine) ContainerAttach(ctx context.Context, nameOrID string, return fmt.Errorf("you can only attach to running containers") } options := new(containers.AttachOptions).WithStream(true).WithDetachKeys(opts.DetachKeys) + if opts.SigProxy { + remoteProxySignals(ctr.ID, func(signal string) error { + killOpts := entities.KillOptions{All: false, Latest: false, Signal: signal} + _, err := ic.ContainerKill(ctx, []string{ctr.ID}, killOpts) + return err + }) + } return containers.Attach(ic.ClientCtx, nameOrID, opts.Stdin, opts.Stdout, opts.Stderr, nil, options) } @@ -611,7 +618,7 @@ func (ic *ContainerEngine) ContainerExecDetached(ctx context.Context, nameOrID s return sessionID, nil } -func startAndAttach(ic *ContainerEngine, name string, detachKeys *string, input, output, errput *os.File) error { +func startAndAttach(ic *ContainerEngine, name string, detachKeys *string, sigProxy bool, input, output, errput *os.File) error { if output == nil && errput == nil { fmt.Printf("%s\n", name) } @@ -621,6 +628,14 @@ func startAndAttach(ic *ContainerEngine, name string, detachKeys *string, input, if dk := detachKeys; dk != nil { options.WithDetachKeys(*dk) } + if sigProxy { + remoteProxySignals(name, func(signal string) error { + killOpts := entities.KillOptions{All: false, Latest: false, Signal: signal} + _, err := ic.ContainerKill(ic.ClientCtx, []string{name}, killOpts) + return err + }) + } + go func() { err := containers.Attach(ic.ClientCtx, name, input, output, errput, attachReady, options) attachErr <- err @@ -693,7 +708,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri } ctrRunning := ctr.State == define.ContainerStateRunning.String() if options.Attach { - err = startAndAttach(ic, name, &options.DetachKeys, options.Stdin, options.Stdout, options.Stderr) + err = startAndAttach(ic, name, &options.DetachKeys, options.SigProxy, options.Stdin, options.Stdout, options.Stderr) if err == define.ErrDetach { // User manually detached // Exit cleanly immediately @@ -851,7 +866,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta return err }) } - if err := startAndAttach(ic, con.ID, &opts.DetachKeys, opts.InputStream, opts.OutputStream, opts.ErrorStream); err != nil { + if err := startAndAttach(ic, con.ID, &opts.DetachKeys, opts.SigProxy, opts.InputStream, opts.OutputStream, opts.ErrorStream); err != nil { if err == define.ErrDetach { return &report, nil } diff --git a/test/system/032-sig-proxy.bats b/test/system/032-sig-proxy.bats index 808bfe3114..2fddfdd0dc 100644 --- a/test/system/032-sig-proxy.bats +++ b/test/system/032-sig-proxy.bats @@ -2,32 +2,38 @@ load helpers -@test "podman sigkill" { - $PODMAN run -i --name foo $IMAGE sh -c 'trap "echo BYE;exit 0" INT;echo READY;while :;do sleep 0.1;done' & - local kidpid=$! +# Command to run in each of the tests. +SLEEPLOOP='trap "echo BYE;exit 0" INT;echo READY;while :;do sleep 0.1;done' + +# Main test code: wait for container to exist and be ready, send it a +# signal, wait for container to acknowledge and exit. +function _test_sigproxy() { + local cname=$1 + local kidpid=$2 # Wait for container to appear local timeout=5 while :;do sleep 0.5 - run_podman '?' container exists foo + run_podman '?' container exists $cname if [[ $status -eq 0 ]]; then break fi timeout=$((timeout - 1)) if [[ $timeout -eq 0 ]]; then - die "Timed out waiting for container to start" + die "Timed out waiting for container $cname to start" fi done - wait_for_ready foo + # Now that container exists, wait for it to declare itself READY + wait_for_ready $cname # Signal, and wait for container to exit kill -INT $kidpid local timeout=10 while :;do sleep 0.5 - run_podman logs foo + run_podman logs $cname if [[ "$output" =~ BYE ]]; then break fi @@ -37,7 +43,37 @@ load helpers fi done - run_podman rm -f -t0 foo + run_podman rm -f -t0 $cname +} + +# Each of the tests below does some setup, then invokes the above helper. + +@test "podman sigproxy test: run" { + # We're forced to use $PODMAN because run_podman cannot be backgrounded + $PODMAN run -i --name c_run $IMAGE sh -c "$SLEEPLOOP" & + local kidpid=$! + + _test_sigproxy c_run $kidpid +} + +@test "podman sigproxy test: start" { + run_podman create --name c_start $IMAGE sh -c "$SLEEPLOOP" + + # See above comments regarding $PODMAN and backgrounding + $PODMAN start --attach c_start & + local kidpid=$! + + _test_sigproxy c_start $kidpid +} + +@test "podman sigproxy test: attach" { + run_podman run -d --name c_attach $IMAGE sh -c "$SLEEPLOOP" + + # See above comments regarding $PODMAN and backgrounding + $PODMAN attach c_attach & + local kidpid=$! + + _test_sigproxy c_attach $kidpid } # vim: filetype=sh