mirror of https://github.com/containers/podman.git
Merge pull request #20609 from cgiradkar/19124_remove_event_fix
Set correct exitcode in remove events
This commit is contained in:
commit
83c08a2f5c
|
@ -820,7 +820,7 @@ func (c *Container) exec(config *ExecConfig, streams *define.AttachStreams, resi
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, fmt.Errorf("retrieving exec session %s exit code: %w", sessionID, err)
|
return -1, fmt.Errorf("retrieving exec session %s exit code: %w", sessionID, err)
|
||||||
}
|
}
|
||||||
return diedEvent.ContainerExitCode, nil
|
return *diedEvent.ContainerExitCode, nil
|
||||||
}
|
}
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,14 @@ func (c *Container) newContainerEventWithInspectData(status events.Status, inspe
|
||||||
e.HealthStatus = containerHealthStatus
|
e.HealthStatus = containerHealthStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if status == events.Remove {
|
||||||
|
exitCode, err := c.runtime.state.GetContainerExitCode(c.ID())
|
||||||
|
if err == nil {
|
||||||
|
intExitCode := int(exitCode)
|
||||||
|
e.ContainerExitCode = &intExitCode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return c.runtime.eventer.Write(e)
|
return c.runtime.eventer.Write(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +96,8 @@ func (c *Container) newContainerExitedEvent(exitCode int32) {
|
||||||
e.Image = c.config.RootfsImageName
|
e.Image = c.config.RootfsImageName
|
||||||
e.Type = events.Container
|
e.Type = events.Container
|
||||||
e.PodID = c.PodID()
|
e.PodID = c.PodID()
|
||||||
e.ContainerExitCode = int(exitCode)
|
intExitCode := int(exitCode)
|
||||||
|
e.ContainerExitCode = &intExitCode
|
||||||
|
|
||||||
e.Details = events.Details{
|
e.Details = events.Details{
|
||||||
ID: e.ID,
|
ID: e.ID,
|
||||||
|
@ -107,7 +116,8 @@ func (c *Container) newExecDiedEvent(sessionID string, exitCode int) {
|
||||||
e.Name = c.Name()
|
e.Name = c.Name()
|
||||||
e.Image = c.config.RootfsImageName
|
e.Image = c.config.RootfsImageName
|
||||||
e.Type = events.Container
|
e.Type = events.Container
|
||||||
e.ContainerExitCode = exitCode
|
intExitCode := exitCode
|
||||||
|
e.ContainerExitCode = &intExitCode
|
||||||
e.Attributes = make(map[string]string)
|
e.Attributes = make(map[string]string)
|
||||||
e.Attributes["execID"] = sessionID
|
e.Attributes["execID"] = sessionID
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ const (
|
||||||
type Event struct {
|
type Event struct {
|
||||||
// ContainerExitCode is for storing the exit code of a container which can
|
// ContainerExitCode is for storing the exit code of a container which can
|
||||||
// be used for "internal" event notification
|
// be used for "internal" event notification
|
||||||
ContainerExitCode int `json:",omitempty"`
|
ContainerExitCode *int `json:",omitempty"`
|
||||||
// ID can be for the container, image, volume, etc
|
// ID can be for the container, image, volume, etc
|
||||||
ID string `json:",omitempty"`
|
ID string `json:",omitempty"`
|
||||||
// Image used where applicable
|
// Image used where applicable
|
||||||
|
|
|
@ -69,6 +69,9 @@ func (e *Event) ToJSONString() (string, error) {
|
||||||
|
|
||||||
// ToHumanReadable returns human-readable event as a formatted string
|
// ToHumanReadable returns human-readable event as a formatted string
|
||||||
func (e *Event) ToHumanReadable(truncate bool) string {
|
func (e *Event) ToHumanReadable(truncate bool) string {
|
||||||
|
if e == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
var humanFormat string
|
var humanFormat string
|
||||||
id := e.ID
|
id := e.ID
|
||||||
if truncate {
|
if truncate {
|
||||||
|
|
|
@ -48,8 +48,8 @@ func (e EventJournalD) Write(ee Event) error {
|
||||||
m["PODMAN_IMAGE"] = ee.Image
|
m["PODMAN_IMAGE"] = ee.Image
|
||||||
m["PODMAN_NAME"] = ee.Name
|
m["PODMAN_NAME"] = ee.Name
|
||||||
m["PODMAN_ID"] = ee.ID
|
m["PODMAN_ID"] = ee.ID
|
||||||
if ee.ContainerExitCode != 0 {
|
if ee.ContainerExitCode != nil {
|
||||||
m["PODMAN_EXIT_CODE"] = strconv.Itoa(ee.ContainerExitCode)
|
m["PODMAN_EXIT_CODE"] = strconv.Itoa(*ee.ContainerExitCode)
|
||||||
}
|
}
|
||||||
if ee.PodID != "" {
|
if ee.PodID != "" {
|
||||||
m["PODMAN_POD_ID"] = ee.PodID
|
m["PODMAN_POD_ID"] = ee.PodID
|
||||||
|
@ -206,7 +206,7 @@ func newEventFromJournalEntry(entry *sdjournal.JournalEntry) (*Event, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("Parsing event exit code %s", code)
|
logrus.Errorf("Parsing event exit code %s", code)
|
||||||
} else {
|
} else {
|
||||||
newEvent.ContainerExitCode = intCode
|
newEvent.ContainerExitCode = &intCode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -936,8 +936,7 @@ func (s *SQLiteState) GetContainerExitCode(id string) (int32, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
row := s.conn.QueryRow("SELECT ExitCode FROM ContainerExitCode WHERE ID=?;", id)
|
row := s.conn.QueryRow("SELECT ExitCode FROM ContainerExitCode WHERE ID=?;", id)
|
||||||
|
var exitCode int32 = -1
|
||||||
var exitCode int32
|
|
||||||
if err := row.Scan(&exitCode); err != nil {
|
if err := row.Scan(&exitCode); err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) {
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
return -1, fmt.Errorf("getting exit code of container %s from DB: %w", id, define.ErrNoSuchExitCode)
|
return -1, fmt.Errorf("getting exit code of container %s from DB: %w", id, define.ErrNoSuchExitCode)
|
||||||
|
|
|
@ -238,7 +238,10 @@ func waitNextExit(ctx context.Context, containerName string) (int32, error) {
|
||||||
|
|
||||||
evt, ok := <-eventChannel
|
evt, ok := <-eventChannel
|
||||||
if ok {
|
if ok {
|
||||||
return int32(evt.ContainerExitCode), nil
|
if evt.ContainerExitCode != nil {
|
||||||
|
return int32(*evt.ContainerExitCode), nil
|
||||||
|
}
|
||||||
|
return -1, nil
|
||||||
}
|
}
|
||||||
// if ok == false then containerEngine.Events() has exited
|
// if ok == false then containerEngine.Events() has exited
|
||||||
// it may happen if request was canceled (e.g. client closed connection prematurely) or
|
// it may happen if request was canceled (e.g. client closed connection prematurely) or
|
||||||
|
|
|
@ -19,10 +19,14 @@ type Event struct {
|
||||||
|
|
||||||
// ConvertToLibpodEvent converts an entities event to a libpod one.
|
// ConvertToLibpodEvent converts an entities event to a libpod one.
|
||||||
func ConvertToLibpodEvent(e Event) *libpodEvents.Event {
|
func ConvertToLibpodEvent(e Event) *libpodEvents.Event {
|
||||||
exitCode, err := strconv.Atoi(e.Actor.Attributes["containerExitCode"])
|
var exitCode int
|
||||||
|
if ec, ok := e.Actor.Attributes["containerExitCode"]; ok {
|
||||||
|
var err error
|
||||||
|
exitCode, err = strconv.Atoi(ec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
}
|
||||||
status, err := libpodEvents.StringToStatus(e.Action)
|
status, err := libpodEvents.StringToStatus(e.Action)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -39,7 +43,7 @@ func ConvertToLibpodEvent(e Event) *libpodEvents.Event {
|
||||||
delete(details, "name")
|
delete(details, "name")
|
||||||
delete(details, "containerExitCode")
|
delete(details, "containerExitCode")
|
||||||
return &libpodEvents.Event{
|
return &libpodEvents.Event{
|
||||||
ContainerExitCode: exitCode,
|
ContainerExitCode: &exitCode,
|
||||||
ID: e.Actor.ID,
|
ID: e.Actor.ID,
|
||||||
Image: image,
|
Image: image,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -62,7 +66,9 @@ func ConvertToEntitiesEvent(e libpodEvents.Event) *Event {
|
||||||
}
|
}
|
||||||
attributes["image"] = e.Image
|
attributes["image"] = e.Image
|
||||||
attributes["name"] = e.Name
|
attributes["name"] = e.Name
|
||||||
attributes["containerExitCode"] = strconv.Itoa(e.ContainerExitCode)
|
if e.ContainerExitCode != nil {
|
||||||
|
attributes["containerExitCode"] = strconv.Itoa(*e.ContainerExitCode)
|
||||||
|
}
|
||||||
attributes["podId"] = e.PodID
|
attributes["podId"] = e.PodID
|
||||||
message := dockerEvents.Message{
|
message := dockerEvents.Message{
|
||||||
// Compatibility with clients that still look for deprecated API elements
|
// Compatibility with clients that still look for deprecated API elements
|
||||||
|
|
|
@ -1192,7 +1192,8 @@ func (ic *ContainerEngine) GetContainerExitCode(ctx context.Context, ctr *libpod
|
||||||
exitCode, err := ctr.Wait(ctx)
|
exitCode, err := ctr.Wait(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("Waiting for container %s: %v", ctr.ID(), err)
|
logrus.Errorf("Waiting for container %s: %v", ctr.ID(), err)
|
||||||
return define.ExecErrorCodeNotFound
|
intExitCode := int(define.ExecErrorCodeNotFound)
|
||||||
|
return intExitCode
|
||||||
}
|
}
|
||||||
return int(exitCode)
|
return int(exitCode)
|
||||||
}
|
}
|
||||||
|
|
|
@ -773,7 +773,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
|
||||||
logrus.Errorf("Cannot get exit code: %v", err)
|
logrus.Errorf("Cannot get exit code: %v", err)
|
||||||
report.ExitCode = define.ExecErrorCodeNotFound
|
report.ExitCode = define.ExecErrorCodeNotFound
|
||||||
} else {
|
} else {
|
||||||
report.ExitCode = event.ContainerExitCode
|
report.ExitCode = *event.ContainerExitCode
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
report.ExitCode = int(exitCode)
|
report.ExitCode = int(exitCode)
|
||||||
|
@ -962,7 +962,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
|
||||||
return &report, nil //nolint: nilerr
|
return &report, nil //nolint: nilerr
|
||||||
}
|
}
|
||||||
|
|
||||||
report.ExitCode = lastEvent.ContainerExitCode
|
report.ExitCode = *lastEvent.ContainerExitCode
|
||||||
return &report, err
|
return &report, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ podman rm -a -f &>/dev/null
|
||||||
|
|
||||||
START=$(date +%s)
|
START=$(date +%s)
|
||||||
|
|
||||||
podman run $IMAGE false || true
|
podman run --rm $IMAGE false || true
|
||||||
|
|
||||||
# libpod api
|
# libpod api
|
||||||
t GET "libpod/events?stream=false&since=$START" 200 \
|
t GET "libpod/events?stream=false&since=$START" 200 \
|
||||||
|
@ -28,4 +28,8 @@ t GET "events?stream=false&since=$START" 200 \
|
||||||
'select(.status | contains("die")).Action=die' \
|
'select(.status | contains("die")).Action=die' \
|
||||||
'select(.status | contains("die")).Actor.Attributes.exitCode=1'
|
'select(.status | contains("die")).Actor.Attributes.exitCode=1'
|
||||||
|
|
||||||
|
t GET "events?stream=false&since=$START&type=remove" 200 \
|
||||||
|
'select(.status| contains("remove")).Action=remove' \
|
||||||
|
'select(.status | contains("remove")).Actor.Attributes.containerExitCode=1'
|
||||||
|
|
||||||
# vim: filetype=sh
|
# vim: filetype=sh
|
||||||
|
|
Loading…
Reference in New Issue