Skip to content

Commit

Permalink
Set correct exitcode in remove events and change ContainerExitCode fr…
Browse files Browse the repository at this point in the history
…om int to int pointer

Added additional check for event type to be remove and set the correct exitcode.
While it was getting difficult to maintain the omitempty notation for Event->ContainerExitCode, changing the type from int to int ptr gives us the ability to check for ContainerExitCode to be not nil and continue operations from there.

closes containers#19124

Signed-off-by: Chetan Giradkar <cgiradka@redhat.com>
  • Loading branch information
cgiradkar committed Nov 28, 2023
1 parent 7d27462 commit 32801a9
Show file tree
Hide file tree
Showing 11 changed files with 45 additions and 19 deletions.
2 changes: 1 addition & 1 deletion libpod/container_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,7 @@ func (c *Container) exec(config *ExecConfig, streams *define.AttachStreams, resi
if err != nil {
return -1, fmt.Errorf("retrieving exec session %s exit code: %w", sessionID, err)
}
return diedEvent.ContainerExitCode, nil
return *diedEvent.ContainerExitCode, nil
}
return -1, err
}
Expand Down
14 changes: 12 additions & 2 deletions libpod/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ func (c *Container) newContainerEventWithInspectData(status events.Status, inspe
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)
}

Expand All @@ -88,7 +96,8 @@ func (c *Container) newContainerExitedEvent(exitCode int32) {
e.Image = c.config.RootfsImageName
e.Type = events.Container
e.PodID = c.PodID()
e.ContainerExitCode = int(exitCode)
intExitCode := int(exitCode)
e.ContainerExitCode = &intExitCode

e.Details = events.Details{
ID: e.ID,
Expand All @@ -107,7 +116,8 @@ func (c *Container) newExecDiedEvent(sessionID string, exitCode int) {
e.Name = c.Name()
e.Image = c.config.RootfsImageName
e.Type = events.Container
e.ContainerExitCode = exitCode
intExitCode := exitCode
e.ContainerExitCode = &intExitCode
e.Attributes = make(map[string]string)
e.Attributes["execID"] = sessionID

Expand Down
2 changes: 1 addition & 1 deletion libpod/events/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const (
type Event struct {
// ContainerExitCode is for storing the exit code of a container which can
// be used for "internal" event notification
ContainerExitCode int `json:",omitempty"`
ContainerExitCode *int `json:",omitempty"`
// ID can be for the container, image, volume, etc
ID string `json:",omitempty"`
// Image used where applicable
Expand Down
3 changes: 3 additions & 0 deletions libpod/events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ func (e *Event) ToJSONString() (string, error) {

// ToHumanReadable returns human-readable event as a formatted string
func (e *Event) ToHumanReadable(truncate bool) string {
if e == nil {
return ""
}
var humanFormat string
id := e.ID
if truncate {
Expand Down
6 changes: 3 additions & 3 deletions libpod/events/journal_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ func (e EventJournalD) Write(ee Event) error {
m["PODMAN_IMAGE"] = ee.Image
m["PODMAN_NAME"] = ee.Name
m["PODMAN_ID"] = ee.ID
if ee.ContainerExitCode != 0 {
m["PODMAN_EXIT_CODE"] = strconv.Itoa(ee.ContainerExitCode)
if ee.ContainerExitCode != nil {
m["PODMAN_EXIT_CODE"] = strconv.Itoa(*ee.ContainerExitCode)
}
if ee.PodID != "" {
m["PODMAN_POD_ID"] = ee.PodID
Expand Down Expand Up @@ -206,7 +206,7 @@ func newEventFromJournalEntry(entry *sdjournal.JournalEntry) (*Event, error) {
if err != nil {
logrus.Errorf("Parsing event exit code %s", code)
} else {
newEvent.ContainerExitCode = intCode
newEvent.ContainerExitCode = &intCode
}
}

Expand Down
3 changes: 1 addition & 2 deletions libpod/sqlite_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -934,8 +934,7 @@ func (s *SQLiteState) GetContainerExitCode(id string) (int32, error) {
}

row := s.conn.QueryRow("SELECT ExitCode FROM ContainerExitCode WHERE ID=?;", id)

var exitCode int32
var exitCode int32 = -1
if err := row.Scan(&exitCode); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return -1, fmt.Errorf("getting exit code of container %s from DB: %w", id, define.ErrNoSuchExitCode)
Expand Down
5 changes: 4 additions & 1 deletion pkg/api/handlers/utils/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,10 @@ func waitNextExit(ctx context.Context, containerName string) (int32, error) {

evt, ok := <-eventChannel
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
// it may happen if request was canceled (e.g. client closed connection prematurely) or
Expand Down
16 changes: 11 additions & 5 deletions pkg/domain/entities/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@ type Event struct {

// ConvertToLibpodEvent converts an entities event to a libpod one.
func ConvertToLibpodEvent(e Event) *libpodEvents.Event {
exitCode, err := strconv.Atoi(e.Actor.Attributes["containerExitCode"])
if err != nil {
return nil
var exitCode int
if ec, ok := e.Actor.Attributes["containerExitCode"]; ok {
var err error
exitCode, err = strconv.Atoi(ec)
if err != nil {
return nil
}
}
status, err := libpodEvents.StringToStatus(e.Action)
if err != nil {
Expand All @@ -39,7 +43,7 @@ func ConvertToLibpodEvent(e Event) *libpodEvents.Event {
delete(details, "name")
delete(details, "containerExitCode")
return &libpodEvents.Event{
ContainerExitCode: exitCode,
ContainerExitCode: &exitCode,
ID: e.Actor.ID,
Image: image,
Name: name,
Expand All @@ -62,7 +66,9 @@ func ConvertToEntitiesEvent(e libpodEvents.Event) *Event {
}
attributes["image"] = e.Image
attributes["name"] = e.Name
attributes["containerExitCode"] = strconv.Itoa(e.ContainerExitCode)
if e.ContainerExitCode != nil {
attributes["containerExitCode"] = strconv.Itoa(*e.ContainerExitCode)
}
attributes["podId"] = e.PodID
message := dockerEvents.Message{
// Compatibility with clients that still look for deprecated API elements
Expand Down
3 changes: 2 additions & 1 deletion pkg/domain/infra/abi/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,8 @@ func (ic *ContainerEngine) GetContainerExitCode(ctx context.Context, ctr *libpod
exitCode, err := ctr.Wait(ctx)
if err != nil {
logrus.Errorf("Waiting for container %s: %v", ctr.ID(), err)
return define.ExecErrorCodeNotFound
intExitCode := int(define.ExecErrorCodeNotFound)
return intExitCode
}
return int(exitCode)
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/domain/infra/tunnel/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
logrus.Errorf("Cannot get exit code: %v", err)
report.ExitCode = define.ExecErrorCodeNotFound
} else {
report.ExitCode = event.ContainerExitCode
report.ExitCode = *event.ContainerExitCode
}
} else {
report.ExitCode = int(exitCode)
Expand Down Expand Up @@ -962,7 +962,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
return &report, nil //nolint: nilerr
}

report.ExitCode = lastEvent.ContainerExitCode
report.ExitCode = *lastEvent.ContainerExitCode
return &report, err
}

Expand Down
6 changes: 5 additions & 1 deletion test/apiv2/27-containersEvents.at
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ podman rm -a -f &>/dev/null

START=$(date +%s)

podman run $IMAGE false || true
podman run --rm $IMAGE false || true

# libpod api
t GET "libpod/events?stream=false&since=$START" 200 \
Expand All @@ -28,4 +28,8 @@ t GET "events?stream=false&since=$START" 200 \
'select(.status | contains("die")).Action=die' \
'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

0 comments on commit 32801a9

Please sign in to comment.