mirror of https://github.com/containers/podman.git
Set correct exitcode in remove events and change ContainerExitCode from int to int ptr
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 #19124 Signed-off-by: Chetan Giradkar <cgiradka@redhat.com>
This commit is contained in:
parent
720a0ead3a
commit
572f38c0db
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -934,8 +934,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