diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index b5216db7..dc2f069e 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -19,6 +19,8 @@ jobs: uses: actions/checkout@v2 - name: "Build integration test image" run: DOCKER_BUILDKIT=1 docker build -t rootlesskit:test-integration --target test-integration . + - name: "Integration test: exit-code" + run: docker run --rm --privileged rootlesskit:test-integration ./integration-exit-code.sh - name: "Integration test: propagation" run: docker run --rm --privileged rootlesskit:test-integration ./integration-propagation.sh - name: "Integration test: propagation (with `mount --make-rshared /`)" diff --git a/cmd/rootlesskit/main.go b/cmd/rootlesskit/main.go index 5a740658..572d5706 100644 --- a/cmd/rootlesskit/main.go +++ b/cmd/rootlesskit/main.go @@ -163,6 +163,10 @@ Note: RootlessKit requires /etc/subuid and /etc/subgid to be configured by the r Usage: "mount propagation [rprivate, rslave]", Value: "rprivate", }, + &cli.BoolFlag{ + Name: "reaper", + Usage: "enable process reaper (experimental). Requires --pidns.", + }, } app.Before = func(context *cli.Context) error { if debug { @@ -431,12 +435,18 @@ func (w *logrusDebugWriter) Write(p []byte) (int, error) { } func createChildOpt(clicontext *cli.Context, pipeFDEnvKey string, targetCmd []string) (child.Opt, error) { + pidns := clicontext.Bool("pidns") opt := child.Opt{ PipeFDEnvKey: pipeFDEnvKey, TargetCmd: targetCmd, - MountProcfs: clicontext.Bool("pidns"), + MountProcfs: pidns, Propagation: clicontext.String("propagation"), - Reaper: clicontext.Bool("pidns"), + Reaper: clicontext.Bool("reaper"), + } + if opt.Reaper { + if !pidns { + return opt, errors.New("reaper requires --pidns") + } } switch s := clicontext.String("net"); s { case "host": diff --git a/hack/integration-exit-code.sh b/hack/integration-exit-code.sh new file mode 100755 index 00000000..99cbdf65 --- /dev/null +++ b/hack/integration-exit-code.sh @@ -0,0 +1,22 @@ +#!/bin/bash +source $(realpath $(dirname $0))/common.inc.sh + +function test_exit_code() { + args="$@" + set +e + for f in 0 42; do + $ROOTLESSKIT $args sh -exc "exit $f" >/dev/null 2>&1 + code=$? + if [ $code = $f ]; then + INFO "exit $f works with \"$args\"" + else + ERROR "exit $f does not work with \"$args\", got $code" + exit 1 + fi + done +} + +test_exit_code --pidns=false +test_exit_code --pidns=true + +# FIXME(#129): test_exit_code --pidns=true --reaper=true diff --git a/pkg/child/child.go b/pkg/child/child.go index dcbc41c9..04380e48 100644 --- a/pkg/child/child.go +++ b/pkg/child/child.go @@ -255,6 +255,8 @@ func Child(opt Opt) error { return err } if opt.Reaper { + logrus.Warn("reaper is experimental") + logrus.Warn("reaper is known to have an issue about propagating process exit code (https://github.com/rootless-containers/rootlesskit/issues/129)") if err := runAndReap(cmd); err != nil { return errors.Wrapf(err, "command %v exited", opt.TargetCmd) }