[v5.6-rhel] podman events: show network create/remove event with journald

In the journald driver there is a bug where the network event
attributes are not preserved. This causes the network driver to be
missing and that in turn causes the ToHumanReadable() function to print
an empty line. Fix it by making sure we preserve the network driver in
the event attributes.

Fixes: https://issues.redhat.com/browse/RHEL-109790

Cherry Pick Fixes: https://issues.redhat.com/browse/RHEL-110317,
https://issues.redhat.com/browse/RHEL-110318

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Signed-off-by: tomsweeneyredhat <tsweeney@redhat.com>
This commit is contained in:
Paul Holzinger 2025-08-19 18:37:37 +02:00 committed by tomsweeneyredhat
parent da671ef6cf
commit 8069823db4
2 changed files with 51 additions and 20 deletions

View file

@ -53,14 +53,8 @@ func (e EventJournalD) Write(ee Event) error {
if ee.PodID != "" {
m["PODMAN_POD_ID"] = ee.PodID
}
// If we have container labels, we need to convert them to a string so they
// can be recorded with the event
if len(ee.Details.Attributes) > 0 {
b, err := json.Marshal(ee.Details.Attributes)
if err != nil {
return err
}
m["PODMAN_LABELS"] = string(b)
if err := addLabelsToJournal(m, ee.Details.Attributes); err != nil {
return err
}
if ee.Status == HealthStatus {
m["PODMAN_HEALTH_STATUS"] = ee.HealthStatus
@ -75,6 +69,9 @@ func (e EventJournalD) Write(ee Event) error {
case Network:
m["PODMAN_ID"] = ee.ID
m["PODMAN_NETWORK_NAME"] = ee.Network
if err := addLabelsToJournal(m, ee.Details.Attributes); err != nil {
return err
}
case Volume:
m["PODMAN_NAME"] = ee.Name
}
@ -93,6 +90,35 @@ func (e EventJournalD) Write(ee Event) error {
return journal.Send(ee.ToHumanReadable(false), prio, m)
}
func addLabelsToJournal(journalEntry, eventAttributes map[string]string) error {
// If we have container labels, we need to convert them to a string so they
// can be recorded with the event
if len(eventAttributes) > 0 {
b, err := json.Marshal(eventAttributes)
if err != nil {
return err
}
journalEntry["PODMAN_LABELS"] = string(b)
}
return nil
}
func getLabelsFromJournal(entry *sdjournal.JournalEntry, event *Event) error {
// we need to check for the presence of labels recorded to a container event
if stringLabels, ok := entry.Fields["PODMAN_LABELS"]; ok && len(stringLabels) > 0 {
labels := make(map[string]string, 0)
if err := json.Unmarshal([]byte(stringLabels), &labels); err != nil {
return err
}
// if we have labels, add them to the event
if len(labels) > 0 {
event.Attributes = labels
}
}
return nil
}
// Read reads events from the journal and sends qualified events to the event channel
func (e EventJournalD) Read(ctx context.Context, options ReadOptions) (retErr error) {
filterMap, err := generateEventFilters(options.Filters, options.Since, options.Until)
@ -224,18 +250,8 @@ func newEventFromJournalEntry(entry *sdjournal.JournalEntry) (*Event, error) {
newEvent.ContainerExitCode = &intCode
}
}
// we need to check for the presence of labels recorded to a container event
if stringLabels, ok := entry.Fields["PODMAN_LABELS"]; ok && len(stringLabels) > 0 {
labels := make(map[string]string, 0)
if err := json.Unmarshal([]byte(stringLabels), &labels); err != nil {
return nil, err
}
// if we have labels, add them to the event
if len(labels) > 0 {
newEvent.Attributes = labels
}
if err := getLabelsFromJournal(entry, &newEvent); err != nil {
return nil, err
}
newEvent.HealthStatus = entry.Fields["PODMAN_HEALTH_STATUS"]
if log, ok := entry.Fields["PODMAN_HEALTH_LOG"]; ok {
@ -251,6 +267,9 @@ func newEventFromJournalEntry(entry *sdjournal.JournalEntry) (*Event, error) {
case Network:
newEvent.ID = entry.Fields["PODMAN_ID"]
newEvent.Network = entry.Fields["PODMAN_NETWORK_NAME"]
if err := getLabelsFromJournal(entry, &newEvent); err != nil {
return nil, err
}
case Image:
newEvent.ID = entry.Fields["PODMAN_ID"]
if val, ok := entry.Fields["ERROR"]; ok {

View file

@ -20,6 +20,8 @@ load helpers.network
run_podman network ls -n
assert "$output" !~ "$heading" "network ls -n shows header anyway"
since=$(date --iso-8601=seconds)
# check deterministic list order
local net1=net-a-$(safename)
local net2=net-b-$(safename)
@ -28,12 +30,22 @@ load helpers.network
run_podman network create $net2
run_podman network create $net3
# Quick check that we generate events
run_podman events --filter type=network --since $since --stream=false
assert "$output" =~ "network create [0-9a-f]{64} \(name=$net1, type=bridge\)" "network1 create event"
assert "$output" =~ "network create [0-9a-f]{64} \(name=$net2, type=bridge\)" "network2 create event"
assert "$output" =~ "network create [0-9a-f]{64} \(name=$net3, type=bridge\)" "network3 create event"
run_podman network ls --quiet
# just check that the order of the created networks is correct
# we cannot do an exact match since developer and CI systems could contain more networks
is "$output" ".*$net1.*$net2.*$net3.*podman.*" "networks sorted alphabetically"
run_podman network rm $net1 $net2 $net3
run_podman events --filter type=network --since $since --stream=false
assert "$output" =~ "network remove [0-9a-f]{64} \(name=$net1, type=bridge\)" "network1 remove event"
assert "$output" =~ "network remove [0-9a-f]{64} \(name=$net2, type=bridge\)" "network2 remove event"
assert "$output" =~ "network remove [0-9a-f]{64} \(name=$net3, type=bridge\)" "network3 remove event"
}
# Copied from tsweeney's https://github.com/containers/podman/issues/4827