mirror of
https://github.com/containers/podman.git
synced 2025-12-01 18:49:18 +08:00
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 <Sativar.sainath@gmail.com>
313 lines
12 KiB
Go
313 lines
12 KiB
Go
//go:build linux || freebsd
|
|
|
|
package integration
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/containers/podman/v5/cmd/podman/system"
|
|
. "github.com/containers/podman/v5/test/utils"
|
|
"github.com/containers/storage/pkg/stringid"
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
var _ = Describe("Podman events", func() {
|
|
|
|
// For most, all, of these tests we do not "live" test following a log because it may make a fragile test
|
|
// system more complex. Instead we run the "events" and then verify that the events are processed correctly.
|
|
// Perhaps a future version of this test would put events in a go func and send output back over a channel
|
|
// while events occur.
|
|
|
|
It("podman events", func() {
|
|
_, ec, _ := podmanTest.RunLsContainer("")
|
|
Expect(ec).To(Equal(0))
|
|
result := podmanTest.Podman([]string{"events", "--stream=false"})
|
|
result.WaitWithDefaultTimeout()
|
|
Expect(result).Should(ExitCleanly())
|
|
})
|
|
|
|
It("podman events with an event filter", func() {
|
|
_, ec, _ := podmanTest.RunLsContainer("")
|
|
Expect(ec).To(Equal(0))
|
|
result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=start"})
|
|
result.WaitWithDefaultTimeout()
|
|
Expect(result).Should(ExitCleanly())
|
|
Expect(result.OutputToStringArray()).ToNot(BeEmpty(), "Number of events")
|
|
date := time.Now().Format("2006-01-02")
|
|
Expect(result.OutputToStringArray()).To(ContainElement(HavePrefix(date)), "event log has correct timestamp")
|
|
})
|
|
It("podman events with a volume filter", func() {
|
|
_, ec, vname := podmanTest.CreateVolume(nil)
|
|
Expect(ec).To(Equal(0))
|
|
|
|
// Run two event commands - one with the full volume name and the second with the prefix
|
|
result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", fmt.Sprintf("volume=%s", vname)})
|
|
resultPrefix := podmanTest.Podman([]string{"events", "--stream=false", "--filter", fmt.Sprintf("volume=%s", vname[:5])})
|
|
|
|
result.WaitWithDefaultTimeout()
|
|
Expect(result).Should(ExitCleanly())
|
|
events := result.OutputToStringArray()
|
|
Expect(events).To(HaveLen(1), "number of events")
|
|
Expect(events[0]).To(ContainSubstring(vname), "event log includes volume name")
|
|
|
|
resultPrefix.WaitWithDefaultTimeout()
|
|
Expect(resultPrefix).Should(ExitCleanly())
|
|
events = resultPrefix.OutputToStringArray()
|
|
Expect(events).To(HaveLen(1), "number of events")
|
|
Expect(events[0]).To(ContainSubstring(vname), "event log includes volume name")
|
|
})
|
|
|
|
It("podman events with an event filter and container=cid", func() {
|
|
_, ec, cid := podmanTest.RunLsContainer("")
|
|
Expect(ec).To(Equal(0))
|
|
_, ec2, cid2 := podmanTest.RunLsContainer("")
|
|
Expect(ec2).To(Equal(0))
|
|
time.Sleep(5 * time.Second)
|
|
result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=start", "--filter", fmt.Sprintf("container=%s", cid)})
|
|
result.WaitWithDefaultTimeout()
|
|
Expect(result).Should(ExitCleanly())
|
|
events := result.OutputToStringArray()
|
|
Expect(events).To(HaveLen(1), "number of events")
|
|
Expect(events[0]).To(ContainSubstring(cid), "event log includes CID")
|
|
Expect(events[0]).To(Not(ContainSubstring(cid2)), "event log does not include second CID")
|
|
})
|
|
|
|
It("podman events with a type and filter container=id", func() {
|
|
_, ec, cid := podmanTest.RunLsContainer("")
|
|
Expect(ec).To(Equal(0))
|
|
result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "type=pod", "--filter", fmt.Sprintf("container=%s", cid)})
|
|
result.WaitWithDefaultTimeout()
|
|
Expect(result).Should(ExitCleanly())
|
|
Expect(result.OutputToStringArray()).To(BeEmpty())
|
|
})
|
|
|
|
It("podman events with a type", func() {
|
|
setup := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:foobarpod", ALPINE, "top"})
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
podmanTest.StopPod("foobarpod")
|
|
|
|
result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "type=pod", "--filter", "pod=foobarpod"})
|
|
result.WaitWithDefaultTimeout()
|
|
Expect(result).Should(ExitCleanly())
|
|
events := result.OutputToStringArray()
|
|
GinkgoWriter.Println(events)
|
|
Expect(len(events)).To(BeNumerically(">=", 2), "Number of events")
|
|
Expect(events).To(ContainElement(ContainSubstring(" pod create ")))
|
|
Expect(events).To(ContainElement(ContainSubstring(" pod stop ")))
|
|
Expect(events).To(ContainElement(ContainSubstring("name=foobarpod")))
|
|
})
|
|
|
|
It("podman events --since", func() {
|
|
_, ec, _ := podmanTest.RunLsContainer("")
|
|
Expect(ec).To(Equal(0))
|
|
result := podmanTest.Podman([]string{"events", "--stream=false", "--since", "1m"})
|
|
result.WaitWithDefaultTimeout()
|
|
Expect(result).Should(ExitCleanly())
|
|
})
|
|
|
|
It("podman events --until", func() {
|
|
_, ec, _ := podmanTest.RunLsContainer("")
|
|
Expect(ec).To(Equal(0))
|
|
result := podmanTest.Podman([]string{"events", "--stream=false", "--until", "1h"})
|
|
result.WaitWithDefaultTimeout()
|
|
Expect(result).Should(ExitCleanly())
|
|
})
|
|
|
|
It("podman events format", func() {
|
|
start := time.Now()
|
|
ctrName := "testCtr"
|
|
_, ec, _ := podmanTest.RunLsContainer(ctrName)
|
|
end := time.Now()
|
|
Expect(ec).To(Equal(0))
|
|
|
|
test := podmanTest.Podman([]string{"events", "--stream=false", "--format", "json"})
|
|
test.WaitWithDefaultTimeout()
|
|
Expect(test).To(ExitCleanly())
|
|
|
|
jsonArr := test.OutputToStringArray()
|
|
Expect(test.OutputToStringArray()).ShouldNot(BeEmpty())
|
|
|
|
event := system.Event{}
|
|
err := json.Unmarshal([]byte(jsonArr[0]), &event)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
test = podmanTest.Podman([]string{
|
|
"events",
|
|
"--stream=false",
|
|
"--since", strconv.FormatInt(start.Unix(), 10),
|
|
"--filter", fmt.Sprintf("container=%s", ctrName),
|
|
"--format", "{{json .}}",
|
|
})
|
|
|
|
test.WaitWithDefaultTimeout()
|
|
Expect(test).To(ExitCleanly())
|
|
|
|
jsonArr = test.OutputToStringArray()
|
|
Expect(test.OutputToStringArray()).ShouldNot(BeEmpty())
|
|
|
|
event = system.Event{}
|
|
err = json.Unmarshal([]byte(jsonArr[0]), &event)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
Expect(event.Time).To(BeNumerically(">=", start.Unix()))
|
|
Expect(event.Time).To(BeNumerically("<=", end.Unix()))
|
|
Expect(event.TimeNano).To(BeNumerically(">=", start.UnixNano()))
|
|
Expect(event.TimeNano).To(BeNumerically("<=", end.UnixNano()))
|
|
Expect(time.Unix(0, event.TimeNano).Unix()).To(BeEquivalentTo(event.Time))
|
|
|
|
test = podmanTest.Podman([]string{"events", "--stream=false", "--filter=type=container", "--format", "ID: {{.ID}}"})
|
|
test.WaitWithDefaultTimeout()
|
|
Expect(test).To(ExitCleanly())
|
|
arr := test.OutputToStringArray()
|
|
Expect(len(arr)).To(BeNumerically(">", 1))
|
|
Expect(arr[0]).To(MatchRegexp("ID: [a-fA-F0-9]{64}"))
|
|
})
|
|
|
|
It("podman events --until future", func() {
|
|
name1 := stringid.GenerateRandomID()
|
|
name2 := stringid.GenerateRandomID()
|
|
name3 := stringid.GenerateRandomID()
|
|
session := podmanTest.Podman([]string{"create", "--name", name1, ALPINE})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
|
|
var wg sync.WaitGroup
|
|
wg.Add(1)
|
|
go func() {
|
|
defer GinkgoRecover()
|
|
defer wg.Done()
|
|
|
|
// wait 2 seconds to be sure events is running
|
|
time.Sleep(time.Second * 2)
|
|
session = podmanTest.Podman([]string{"create", "--name", name2, ALPINE})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
session = podmanTest.Podman([]string{"create", "--name", name3, ALPINE})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
}()
|
|
|
|
// unix timestamp in 10 seconds
|
|
until := time.Now().Add(time.Second * 10).Unix()
|
|
result := podmanTest.Podman([]string{"events", "--since", "30s", "--until", strconv.FormatInt(until, 10)})
|
|
result.Wait(11)
|
|
Expect(result).Should(ExitCleanly())
|
|
Expect(result.OutputToString()).To(ContainSubstring(name1))
|
|
Expect(result.OutputToString()).To(ContainSubstring(name2))
|
|
Expect(result.OutputToString()).To(ContainSubstring(name3))
|
|
|
|
// string duration in 10 seconds
|
|
untilT := time.Now().Add(time.Second * 9)
|
|
result = podmanTest.Podman([]string{"events", "--since", "30s", "--until", "10s"})
|
|
result.Wait(11)
|
|
Expect(result).Should(ExitCleanly())
|
|
tEnd := time.Now()
|
|
outDur := tEnd.Sub(untilT)
|
|
Expect(outDur.Seconds()).To(BeNumerically(">", 0), "duration")
|
|
Expect(result.OutputToString()).To(ContainSubstring(name1))
|
|
Expect(result.OutputToString()).To(ContainSubstring(name2))
|
|
Expect(result.OutputToString()).To(ContainSubstring(name3))
|
|
|
|
wg.Wait()
|
|
})
|
|
|
|
It("podman events pod creation", func() {
|
|
create := podmanTest.Podman([]string{"pod", "create", "--infra=false", "--name", "foobarpod"})
|
|
create.WaitWithDefaultTimeout()
|
|
Expect(create).Should(ExitCleanly())
|
|
id := create.OutputToString()
|
|
result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "pod=" + id})
|
|
result.WaitWithDefaultTimeout()
|
|
Expect(result).Should(ExitCleanly())
|
|
Expect(result.OutputToStringArray()).To(HaveLen(1))
|
|
Expect(result.OutputToString()).To(ContainSubstring("create"))
|
|
|
|
ctrName := "testCtr"
|
|
run := podmanTest.Podman([]string{"create", "--pod", id, "--name", ctrName, ALPINE, "top"})
|
|
run.WaitWithDefaultTimeout()
|
|
Expect(run).Should(ExitCleanly())
|
|
|
|
result2 := podmanTest.Podman([]string{"events", "--stream=false", "--filter", fmt.Sprintf("container=%s", ctrName), "--since", "30s"})
|
|
result2.WaitWithDefaultTimeout()
|
|
Expect(result2).Should(ExitCleanly())
|
|
Expect(result2.OutputToString()).To(ContainSubstring(fmt.Sprintf("pod_id=%s", id)))
|
|
})
|
|
|
|
It("podman events network connection", func() {
|
|
network := stringid.GenerateRandomID()
|
|
networkDriver := "bridge"
|
|
result := podmanTest.Podman([]string{"create", "--network", networkDriver, ALPINE, "top"})
|
|
result.WaitWithDefaultTimeout()
|
|
Expect(result).Should(ExitCleanly())
|
|
ctrID := result.OutputToString()
|
|
|
|
result = podmanTest.Podman([]string{"network", "create", network})
|
|
result.WaitWithDefaultTimeout()
|
|
Expect(result).Should(ExitCleanly())
|
|
|
|
result = podmanTest.Podman([]string{"network", "connect", network, ctrID})
|
|
result.WaitWithDefaultTimeout()
|
|
Expect(result).Should(ExitCleanly())
|
|
|
|
result = podmanTest.Podman([]string{"network", "disconnect", network, ctrID})
|
|
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.
|
|
if IsRemote() {
|
|
lines := result.OutputToString()
|
|
Expect(lines).To(ContainSubstring("network connect" + eventDetails))
|
|
Expect(lines).To(ContainSubstring("network disconnect" + eventDetails))
|
|
Expect(lines).To(MatchRegexp(" network connect .* network disconnect "))
|
|
} else {
|
|
lines := result.OutputToStringArray()
|
|
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)))
|
|
}
|
|
})
|
|
|
|
It("podman events health_status generated", func() {
|
|
session := podmanTest.Podman([]string{"run", "--name", "test-hc", "-dt", "--health-cmd", "echo working", "busybox"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
|
|
for i := 0; i < 5; i++ {
|
|
hc := podmanTest.Podman([]string{"healthcheck", "run", "test-hc"})
|
|
hc.WaitWithDefaultTimeout()
|
|
exitCode := hc.ExitCode()
|
|
if exitCode == 0 || i == 4 {
|
|
break
|
|
}
|
|
time.Sleep(1 * time.Second)
|
|
}
|
|
|
|
result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=health_status", "--since", "1m"})
|
|
result.WaitWithDefaultTimeout()
|
|
Expect(result).Should(ExitCleanly())
|
|
Expect(result.OutputToStringArray()).ToNot(BeEmpty(), "Number of health_status events")
|
|
})
|
|
|
|
})
|