mirror of
https://github.com/containers/podman.git
synced 2025-06-23 02:18:13 +08:00
Merge pull request #7574 from vrothberg/fix-7117
remote run: consult events for exit code
This commit is contained in:
@ -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,23 +509,33 @@ 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 {
|
|
||||||
report.ExitCode = int(exitCode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = containers.Start(ic.ClientCxt, con.ID, nil)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
report.ExitCode = define.ExitCode(err)
|
report.ExitCode = define.ExitCode(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 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 err := containers.Remove(ic.ClientCxt, con.ID, bindings.PFalse, bindings.PTrue); err != nil {
|
||||||
if errors.Cause(err) == define.ErrNoSuchCtr ||
|
if errors.Cause(err) == define.ErrNoSuchCtr ||
|
||||||
errors.Cause(err) == define.ErrCtrRemoved {
|
errors.Cause(err) == define.ErrCtrRemoved {
|
||||||
@ -532,8 +544,55 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
|
|||||||
logrus.Errorf("Error removing container %s: %v", con.ID, err)
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user