Merge pull request #7574 from vrothberg/fix-7117

remote run: consult events for exit code
This commit is contained in:
OpenShift Merge Robot
2020-09-10 13:10:48 -04:00
committed by GitHub
2 changed files with 82 additions and 25 deletions

View File

@ -8,11 +8,13 @@ import (
"os" "os"
"strconv" "strconv"
"strings" "strings"
"sync"
"time" "time"
"github.com/containers/common/pkg/config" "github.com/containers/common/pkg/config"
"github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/docker/reference"
"github.com/containers/podman/v2/libpod/define" "github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/libpod/events"
"github.com/containers/podman/v2/pkg/api/handlers" "github.com/containers/podman/v2/pkg/api/handlers"
"github.com/containers/podman/v2/pkg/bindings" "github.com/containers/podman/v2/pkg/bindings"
"github.com/containers/podman/v2/pkg/bindings/containers" "github.com/containers/podman/v2/pkg/bindings/containers"
@ -507,33 +509,90 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
for _, w := range con.Warnings { for _, w := range con.Warnings {
fmt.Fprintf(os.Stderr, "%s\n", w) fmt.Fprintf(os.Stderr, "%s\n", w)
} }
report := entities.ContainerRunReport{Id: con.ID} report := entities.ContainerRunReport{Id: con.ID}
// Attach
if !opts.Detach { if opts.Detach {
err = startAndAttach(ic, con.ID, &opts.DetachKeys, opts.InputStream, opts.OutputStream, opts.ErrorStream) // Detach and return early
if err == nil { err := containers.Start(ic.ClientCxt, con.ID, nil)
exitCode, err := containers.Wait(ic.ClientCxt, con.ID, nil) if err != nil {
if err == nil { report.ExitCode = define.ExitCode(err)
report.ExitCode = int(exitCode)
}
}
} else {
err = containers.Start(ic.ClientCxt, con.ID, nil)
}
if err != nil {
report.ExitCode = define.ExitCode(err)
}
if opts.Rm {
if err := containers.Remove(ic.ClientCxt, con.ID, bindings.PFalse, bindings.PTrue); err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr ||
errors.Cause(err) == define.ErrCtrRemoved {
logrus.Warnf("Container %s does not exist: %v", con.ID, err)
} else {
logrus.Errorf("Error removing container %s: %v", con.ID, err)
}
} }
return &report, err
} }
// Attach
if err := startAndAttach(ic, con.ID, &opts.DetachKeys, opts.InputStream, opts.OutputStream, opts.ErrorStream); err != nil {
report.ExitCode = define.ExitCode(err)
if opts.Rm {
if rmErr := containers.Remove(ic.ClientCxt, con.ID, bindings.PFalse, bindings.PTrue); rmErr != nil {
logrus.Debugf("unable to remove container %s after failing to start and attach to it", con.ID)
}
}
return &report, err
}
if opts.Rm {
// Defer the removal, so we can return early if needed and
// de-spaghetti the code.
defer func() {
if err := containers.Remove(ic.ClientCxt, con.ID, bindings.PFalse, bindings.PTrue); err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr ||
errors.Cause(err) == define.ErrCtrRemoved {
logrus.Warnf("Container %s does not exist: %v", con.ID, err)
} else {
logrus.Errorf("Error removing container %s: %v", con.ID, err)
}
}
}()
}
// Wait
exitCode, waitErr := containers.Wait(ic.ClientCxt, con.ID, nil)
if waitErr == nil {
report.ExitCode = int(exitCode)
return &report, nil
}
// Determine why the wait failed. If the container doesn't exist,
// consult the events.
if !strings.Contains(waitErr.Error(), define.ErrNoSuchCtr.Error()) {
return &report, waitErr
}
// Events
eventsChannel := make(chan *events.Event)
eventOptions := entities.EventsOptions{
EventChan: eventsChannel,
Filter: []string{
"type=container",
fmt.Sprintf("container=%s", con.ID),
fmt.Sprintf("event=%s", events.Exited),
},
}
var lastEvent *events.Event
var mutex sync.Mutex
mutex.Lock()
// Read the events.
go func() {
for e := range eventsChannel {
lastEvent = e
}
mutex.Unlock()
}()
eventsErr := ic.Events(ctx, eventOptions)
// Wait for all events to be read
mutex.Lock()
if eventsErr != nil || lastEvent == nil {
logrus.Errorf("Cannot get exit code: %v", err)
report.ExitCode = define.ExecErrorCodeNotFound
return &report, nil // compat with local client
}
report.ExitCode = lastEvent.ContainerExitCode
return &report, err return &report, err
} }

View File

@ -44,8 +44,6 @@ load helpers
# #
# See https://github.com/containers/podman/issues/3795 # See https://github.com/containers/podman/issues/3795
@test "podman rm -f" { @test "podman rm -f" {
skip_if_remote "FIXME: pending #7117"
rand=$(random_string 30) rand=$(random_string 30)
( sleep 3; run_podman rm -f $rand ) & ( sleep 3; run_podman rm -f $rand ) &
run_podman 137 run --name $rand $IMAGE sleep 30 run_podman 137 run --name $rand $IMAGE sleep 30