mirror of
https://github.com/containers/podman.git
synced 2026-03-13 08:01:19 +08:00
Improve OOMKilled visibility in podman events and in podman inspect docs
Signed-off-by: Bruce Fan <brucexfan@gmail.com>
This commit is contained in:
@@ -54,6 +54,8 @@ 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"`
|
||||
// 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 string `json:",omitempty"`
|
||||
// Image used where applicable
|
||||
@@ -81,6 +83,7 @@ type Event struct {
|
||||
func newEventFromLibpodEvent(e *events.Event) Event {
|
||||
return Event{
|
||||
ContainerExitCode: e.ContainerExitCode,
|
||||
OOMKilled: e.OOMKilled,
|
||||
ID: e.ID,
|
||||
Image: e.Image,
|
||||
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) |
|
||||
| .Name | Container name (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 |
|
||||
| .Status | Event status (e.g., create, start, died, ...) |
|
||||
| .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]
|
||||
```
|
||||
|
||||
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:
|
||||
```
|
||||
# podman inspect myPod --type pod --format "{{.Name}}"
|
||||
|
||||
@@ -105,9 +105,11 @@ func (c *Container) newContainerExitedEvent(exitCode int32) {
|
||||
intExitCode := int(exitCode)
|
||||
e.ContainerExitCode = &intExitCode
|
||||
|
||||
e.Details = events.Details{
|
||||
Attributes: c.Labels(),
|
||||
attrs := 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 {
|
||||
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
|
||||
// be used for "internal" event notification
|
||||
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 string `json:",omitempty"`
|
||||
// Image used where applicable
|
||||
|
||||
@@ -50,6 +50,9 @@ func (e EventJournalD) Write(ee Event) error {
|
||||
if ee.ContainerExitCode != nil {
|
||||
m["PODMAN_EXIT_CODE"] = strconv.Itoa(*ee.ContainerExitCode)
|
||||
}
|
||||
if ee.OOMKilled != nil {
|
||||
m["PODMAN_OOM_KILLED"] = strconv.FormatBool(*ee.OOMKilled)
|
||||
}
|
||||
if ee.PodID != "" {
|
||||
m["PODMAN_POD_ID"] = ee.PodID
|
||||
}
|
||||
@@ -250,6 +253,14 @@ func newEventFromJournalEntry(entry *sdjournal.JournalEntry) (*Event, error) {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -29,6 +29,16 @@ func ConvertToLibpodEvent(e Event) *libpodEvents.Event {
|
||||
if err != 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"]
|
||||
name := e.Actor.Attributes["name"]
|
||||
network := e.Actor.Attributes["network"]
|
||||
@@ -41,7 +51,8 @@ func ConvertToLibpodEvent(e Event) *libpodEvents.Event {
|
||||
delete(details, "podId")
|
||||
delete(details, "error")
|
||||
delete(details, "containerExitCode")
|
||||
return &libpodEvents.Event{
|
||||
delete(details, "oomKilled")
|
||||
newEvent := &libpodEvents.Event{
|
||||
ContainerExitCode: &exitCode,
|
||||
ID: e.Actor.ID,
|
||||
Image: image,
|
||||
@@ -57,6 +68,10 @@ func ConvertToLibpodEvent(e Event) *libpodEvents.Event {
|
||||
Attributes: details,
|
||||
},
|
||||
}
|
||||
if hasOOM {
|
||||
newEvent.OOMKilled = &oomKilled
|
||||
}
|
||||
return newEvent
|
||||
}
|
||||
|
||||
// ConvertToEntitiesEvent converts a libpod event to an entities one.
|
||||
@@ -70,6 +85,9 @@ func ConvertToEntitiesEvent(e libpodEvents.Event) *types.Event {
|
||||
if e.ContainerExitCode != nil {
|
||||
attributes["containerExitCode"] = strconv.Itoa(*e.ContainerExitCode)
|
||||
}
|
||||
if e.OOMKilled != nil {
|
||||
attributes["oomKilled"] = strconv.FormatBool(*e.OOMKilled)
|
||||
}
|
||||
attributes["podId"] = e.PodID
|
||||
if e.Network != "" {
|
||||
attributes["network"] = e.Network
|
||||
|
||||
@@ -338,6 +338,24 @@ EOF
|
||||
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
|
||||
@test "events - backend none should error" {
|
||||
skip_if_remote "remote does not support --events-backend"
|
||||
|
||||
Reference in New Issue
Block a user