mirror of
https://github.com/containers/podman.git
synced 2026-03-13 08:01:19 +08:00
Merge pull request #27766 from Banana-Cultist/podman-events-oom
Improve OOMKilled Visibility
This commit is contained in:
@@ -54,6 +54,8 @@ 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"`
|
||||||
|
// OOMKilled indicates whether the container was killed by an OOM condition
|
||||||
|
OOMKilled *bool `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
|
||||||
@@ -81,6 +83,7 @@ type Event struct {
|
|||||||
func newEventFromLibpodEvent(e *events.Event) Event {
|
func newEventFromLibpodEvent(e *events.Event) Event {
|
||||||
return Event{
|
return Event{
|
||||||
ContainerExitCode: e.ContainerExitCode,
|
ContainerExitCode: e.ContainerExitCode,
|
||||||
|
OOMKilled: e.OOMKilled,
|
||||||
ID: e.ID,
|
ID: e.ID,
|
||||||
Image: e.Image,
|
Image: e.Image,
|
||||||
Name: e.Name,
|
Name: e.Name,
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ Format the output to JSON Lines or using the given Go template.
|
|||||||
| .Image | Name of image being run (string) |
|
| .Image | Name of image being run (string) |
|
||||||
| .Name | Container name (string) |
|
| .Name | Container name (string) |
|
||||||
| .Network | Name of network being used (string) |
|
| .Network | Name of network being used (string) |
|
||||||
|
| .OOMKilled | Whether container was killed due to OOM (bool) |
|
||||||
| .PodID | ID of pod associated with container, if any |
|
| .PodID | ID of pod associated with container, if any |
|
||||||
| .Status | Event status (e.g., create, start, died, ...) |
|
| .Status | Event status (e.g., create, start, died, ...) |
|
||||||
| .Time | Event timestamp (string) |
|
| .Time | Event timestamp (string) |
|
||||||
|
|||||||
@@ -147,6 +147,12 @@ podman container inspect --latest --format {{.EffectiveCaps}}
|
|||||||
[CAP_CHOWN CAP_DAC_OVERRIDE CAP_FSETID CAP_FOWNER CAP_SETGID CAP_SETUID CAP_SETFCAP CAP_SETPCAP CAP_NET_BIND_SERVICE CAP_KILL]
|
[CAP_CHOWN CAP_DAC_OVERRIDE CAP_FSETID CAP_FOWNER CAP_SETGID CAP_SETUID CAP_SETFCAP CAP_SETPCAP CAP_NET_BIND_SERVICE CAP_KILL]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Inspect the specified container for the `OOMKilled` format specifier
|
||||||
|
```
|
||||||
|
podman container inspect myContainer --format {{.State.OOMKilled}}
|
||||||
|
false
|
||||||
|
```
|
||||||
|
|
||||||
Inspect the specified pod for the `Name` format specifier:
|
Inspect the specified pod for the `Name` format specifier:
|
||||||
```
|
```
|
||||||
# podman inspect myPod --type pod --format "{{.Name}}"
|
# podman inspect myPod --type pod --format "{{.Name}}"
|
||||||
|
|||||||
@@ -105,9 +105,11 @@ func (c *Container) newContainerExitedEvent(exitCode int32) {
|
|||||||
intExitCode := int(exitCode)
|
intExitCode := int(exitCode)
|
||||||
e.ContainerExitCode = &intExitCode
|
e.ContainerExitCode = &intExitCode
|
||||||
|
|
||||||
e.Details = events.Details{
|
attrs := c.Labels()
|
||||||
Attributes: c.Labels(),
|
if c.state.OOMKilled {
|
||||||
|
e.OOMKilled = &c.state.OOMKilled
|
||||||
}
|
}
|
||||||
|
e.Details = events.Details{Attributes: attrs}
|
||||||
|
|
||||||
if err := c.runtime.eventer.Write(e); err != nil {
|
if err := c.runtime.eventer.Write(e); err != nil {
|
||||||
logrus.Errorf("Unable to write container exited event: %q", err)
|
logrus.Errorf("Unable to write container exited event: %q", err)
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ 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"`
|
||||||
|
// OOMKilled indicates whether the container was killed by an OOM condition
|
||||||
|
OOMKilled *bool `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
|
||||||
|
|||||||
@@ -50,6 +50,9 @@ func (e EventJournalD) Write(ee Event) error {
|
|||||||
if ee.ContainerExitCode != nil {
|
if ee.ContainerExitCode != nil {
|
||||||
m["PODMAN_EXIT_CODE"] = strconv.Itoa(*ee.ContainerExitCode)
|
m["PODMAN_EXIT_CODE"] = strconv.Itoa(*ee.ContainerExitCode)
|
||||||
}
|
}
|
||||||
|
if ee.OOMKilled != nil {
|
||||||
|
m["PODMAN_OOM_KILLED"] = strconv.FormatBool(*ee.OOMKilled)
|
||||||
|
}
|
||||||
if ee.PodID != "" {
|
if ee.PodID != "" {
|
||||||
m["PODMAN_POD_ID"] = ee.PodID
|
m["PODMAN_POD_ID"] = ee.PodID
|
||||||
}
|
}
|
||||||
@@ -250,6 +253,14 @@ func newEventFromJournalEntry(entry *sdjournal.JournalEntry) (*Event, error) {
|
|||||||
newEvent.ContainerExitCode = &intCode
|
newEvent.ContainerExitCode = &intCode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if val, ok := entry.Fields["PODMAN_OOM_KILLED"]; ok {
|
||||||
|
oomKilled, err := strconv.ParseBool(val)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("Parsing event oom killed value %s", val)
|
||||||
|
} else {
|
||||||
|
newEvent.OOMKilled = &oomKilled
|
||||||
|
}
|
||||||
|
}
|
||||||
if err := getLabelsFromJournal(entry, &newEvent); err != nil {
|
if err := getLabelsFromJournal(entry, &newEvent); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,16 @@ func ConvertToLibpodEvent(e Event) *libpodEvents.Event {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
var (
|
||||||
|
oomKilled bool
|
||||||
|
hasOOM bool
|
||||||
|
)
|
||||||
|
if raw, ok := e.Actor.Attributes["oomKilled"]; ok {
|
||||||
|
if parsed, err := strconv.ParseBool(raw); err == nil {
|
||||||
|
oomKilled = parsed
|
||||||
|
hasOOM = true
|
||||||
|
}
|
||||||
|
}
|
||||||
image := e.Actor.Attributes["image"]
|
image := e.Actor.Attributes["image"]
|
||||||
name := e.Actor.Attributes["name"]
|
name := e.Actor.Attributes["name"]
|
||||||
network := e.Actor.Attributes["network"]
|
network := e.Actor.Attributes["network"]
|
||||||
@@ -41,7 +51,8 @@ func ConvertToLibpodEvent(e Event) *libpodEvents.Event {
|
|||||||
delete(details, "podId")
|
delete(details, "podId")
|
||||||
delete(details, "error")
|
delete(details, "error")
|
||||||
delete(details, "containerExitCode")
|
delete(details, "containerExitCode")
|
||||||
return &libpodEvents.Event{
|
delete(details, "oomKilled")
|
||||||
|
newEvent := &libpodEvents.Event{
|
||||||
ContainerExitCode: &exitCode,
|
ContainerExitCode: &exitCode,
|
||||||
ID: e.Actor.ID,
|
ID: e.Actor.ID,
|
||||||
Image: image,
|
Image: image,
|
||||||
@@ -57,6 +68,10 @@ func ConvertToLibpodEvent(e Event) *libpodEvents.Event {
|
|||||||
Attributes: details,
|
Attributes: details,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
if hasOOM {
|
||||||
|
newEvent.OOMKilled = &oomKilled
|
||||||
|
}
|
||||||
|
return newEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConvertToEntitiesEvent converts a libpod event to an entities one.
|
// ConvertToEntitiesEvent converts a libpod event to an entities one.
|
||||||
@@ -70,6 +85,9 @@ func ConvertToEntitiesEvent(e libpodEvents.Event) *types.Event {
|
|||||||
if e.ContainerExitCode != nil {
|
if e.ContainerExitCode != nil {
|
||||||
attributes["containerExitCode"] = strconv.Itoa(*e.ContainerExitCode)
|
attributes["containerExitCode"] = strconv.Itoa(*e.ContainerExitCode)
|
||||||
}
|
}
|
||||||
|
if e.OOMKilled != nil {
|
||||||
|
attributes["oomKilled"] = strconv.FormatBool(*e.OOMKilled)
|
||||||
|
}
|
||||||
attributes["podId"] = e.PodID
|
attributes["podId"] = e.PodID
|
||||||
if e.Network != "" {
|
if e.Network != "" {
|
||||||
attributes["network"] = e.Network
|
attributes["network"] = e.Network
|
||||||
|
|||||||
@@ -338,6 +338,24 @@ EOF
|
|||||||
assert "$output" = "$lvalue" "podman-events output includes container label"
|
assert "$output" = "$lvalue" "podman-events output includes container label"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "events - died event contains OOMKilled attribute" {
|
||||||
|
local cname=c-$(safename)
|
||||||
|
|
||||||
|
run_podman run -d --rm \
|
||||||
|
--name $cname \
|
||||||
|
--memory 20m \
|
||||||
|
--cgroup-conf=memory.oom.group=1 \
|
||||||
|
$IMAGE sh -c "x=a; while :; do x=\$x\$x\$x\$x; done"
|
||||||
|
run_podman wait $cname
|
||||||
|
run_podman events \
|
||||||
|
--filter container=$cname \
|
||||||
|
--filter event=died \
|
||||||
|
--stream=false \
|
||||||
|
--format "{{.OOMKilled}}"
|
||||||
|
|
||||||
|
assert "$output" = "true" "OOMKilled attribute should be present and set to true"
|
||||||
|
}
|
||||||
|
|
||||||
# bats test_tags=ci:parallel
|
# bats test_tags=ci:parallel
|
||||||
@test "events - backend none should error" {
|
@test "events - backend none should error" {
|
||||||
skip_if_remote "remote does not support --events-backend"
|
skip_if_remote "remote does not support --events-backend"
|
||||||
|
|||||||
Reference in New Issue
Block a user