From c23d9c6f238357d4b1e03b4f18d5dc15411a653e Mon Sep 17 00:00:00 2001 From: Sainath Sativar Date: Tue, 29 Oct 2024 18:50:51 +0000 Subject: [PATCH] Log network creation and removal events in Podman This commit resolves an issue where network creation and removal events were not being logged in `podman events`. A new function has been introduced in the `events` package to ensure consistent logging of network lifecycle events. This update will allow users to track network operations more effectively through the event log, improving visibility and aiding in debugging network-related issues. Fixes: #24032 Signed-off-by: Sainath Sativar --- libpod/events.go | 13 +++++++++++++ libpod/events/events.go | 8 +++++++- pkg/domain/infra/abi/network.go | 10 +++++++++- test/e2e/events_test.go | 16 ++++++++++++---- 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/libpod/events.go b/libpod/events.go index 6189ee895a..f446ee8cb0 100644 --- a/libpod/events.go +++ b/libpod/events.go @@ -136,6 +136,19 @@ func (c *Container) newExecDiedEvent(sessionID string, exitCode int) { } } +// newNetworkEvent creates a new event based on a network create/remove +func (r *Runtime) NewNetworkEvent(status events.Status, netName, netID, netDriver string) { + e := events.NewEvent(status) + e.Network = netName + e.ID = netID + e.Attributes = make(map[string]string) + e.Attributes["driver"] = netDriver + e.Type = events.Network + if err := r.eventer.Write(e); err != nil { + logrus.Errorf("Unable to write network event: %q", err) + } +} + // newNetworkEvent creates a new event based on a network connect/disconnect func (c *Container) newNetworkEvent(status events.Status, netName string) { e := events.NewEvent(status) diff --git a/libpod/events/events.go b/libpod/events/events.go index 084be84cab..16ebbb51c8 100644 --- a/libpod/events/events.go +++ b/libpod/events/events.go @@ -89,7 +89,13 @@ func (e *Event) ToHumanReadable(truncate bool) string { } humanFormat += ")" case Network: - humanFormat = fmt.Sprintf("%s %s %s %s (container=%s, name=%s)", e.Time, e.Type, e.Status, id, id, e.Network) + if e.Status == Create || e.Status == Remove { + if netdriver, exists := e.Attributes["driver"]; exists { + humanFormat = fmt.Sprintf("%s %s %s %s (name=%s, type=%s)", e.Time, e.Type, e.Status, e.ID, e.Network, netdriver) + } + } else { + humanFormat = fmt.Sprintf("%s %s %s %s (container=%s, name=%s)", e.Time, e.Type, e.Status, id, id, e.Network) + } case Image: humanFormat = fmt.Sprintf("%s %s %s %s %s", e.Time, e.Type, e.Status, id, e.Name) if e.Error != "" { diff --git a/pkg/domain/infra/abi/network.go b/pkg/domain/infra/abi/network.go index 5dc3963ba1..ee99c8127b 100644 --- a/pkg/domain/infra/abi/network.go +++ b/pkg/domain/infra/abi/network.go @@ -14,6 +14,7 @@ import ( "github.com/containers/common/libnetwork/types" netutil "github.com/containers/common/libnetwork/util" "github.com/containers/podman/v5/libpod/define" + "github.com/containers/podman/v5/libpod/events" "github.com/containers/podman/v5/pkg/domain/entities" ) @@ -127,7 +128,6 @@ func (ic *ContainerEngine) NetworkReload(ctx context.Context, names []string, op func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, options entities.NetworkRmOptions) ([]*entities.NetworkRmReport, error) { reports := make([]*entities.NetworkRmReport, 0, len(namesOrIds)) - for _, name := range namesOrIds { report := entities.NetworkRmReport{Name: name} containers, err := ic.Libpod.GetAllContainers() @@ -164,9 +164,16 @@ func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, o } } } + net, err := ic.Libpod.Network().NetworkInspect(name) + if err != nil && !errors.Is(err, define.ErrNoSuchNetwork) { + return reports, err + } if err := ic.Libpod.Network().NetworkRemove(name); err != nil { report.Err = err } + if len(net.Name) != 0 { + ic.Libpod.NewNetworkEvent(events.Remove, net.Name, net.ID, net.Driver) + } reports = append(reports, &report) } return reports, nil @@ -180,6 +187,7 @@ func (ic *ContainerEngine) NetworkCreate(ctx context.Context, network types.Netw if err != nil { return nil, err } + ic.Libpod.NewNetworkEvent(events.Create, network.Name, network.ID, network.Driver) return &network, nil } diff --git a/test/e2e/events_test.go b/test/e2e/events_test.go index d612c1343f..c86ef9e78b 100644 --- a/test/e2e/events_test.go +++ b/test/e2e/events_test.go @@ -242,7 +242,8 @@ var _ = Describe("Podman events", func() { It("podman events network connection", func() { network := stringid.GenerateRandomID() - result := podmanTest.Podman([]string{"create", "--network", "bridge", ALPINE, "top"}) + networkDriver := "bridge" + result := podmanTest.Podman([]string{"create", "--network", networkDriver, ALPINE, "top"}) result.WaitWithDefaultTimeout() Expect(result).Should(ExitCleanly()) ctrID := result.OutputToString() @@ -259,11 +260,16 @@ var _ = Describe("Podman events", func() { result.WaitWithDefaultTimeout() Expect(result).Should(ExitCleanly()) + result = podmanTest.Podman([]string{"network", "rm", network}) + result.WaitWithDefaultTimeout() + Expect(result).Should(ExitCleanly()) + result = podmanTest.Podman([]string{"events", "--stream=false", "--since", "30s"}) result.WaitWithDefaultTimeout() Expect(result).Should(ExitCleanly()) eventDetails := fmt.Sprintf(" %s (container=%s, name=%s)", ctrID, ctrID, network) + networkCreateRemoveDetails := fmt.Sprintf("(name=%s, type=%s)", network, networkDriver) // Workaround for #23634, event order not guaranteed when remote. // Although the issue is closed, the bug is a real one. It seems // unlikely ever to be fixed. @@ -274,9 +280,11 @@ var _ = Describe("Podman events", func() { Expect(lines).To(MatchRegexp(" network connect .* network disconnect ")) } else { lines := result.OutputToStringArray() - Expect(lines).To(HaveLen(5)) - Expect(lines[3]).To(ContainSubstring("network connect" + eventDetails)) - Expect(lines[4]).To(ContainSubstring("network disconnect" + eventDetails)) + Expect(lines).To(HaveLen(7)) + Expect(lines[3]).To(And(ContainSubstring("network create"), ContainSubstring(networkCreateRemoveDetails))) + Expect(lines[4]).To(ContainSubstring("network connect" + eventDetails)) + Expect(lines[5]).To(ContainSubstring("network disconnect" + eventDetails)) + Expect(lines[6]).To(And(ContainSubstring("network remove"), ContainSubstring(networkCreateRemoveDetails))) } })