diff --git a/go.mod b/go.mod index e63f14fea976..730e023b9098 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/containernetworking/cni v0.8.1 github.com/containernetworking/plugins v0.9.1 github.com/containers/buildah v1.20.2-0.20210504130217-903dc56408ac - github.com/containers/common v0.37.2-0.20210503193405-42134aa138ce + github.com/containers/common v0.38.1-0.20210510140555-24645399a050 github.com/containers/conmon v2.0.20+incompatible github.com/containers/image/v5 v5.12.0 github.com/containers/ocicrypt v1.1.1 diff --git a/go.sum b/go.sum index 7df32ec57c77..7050cac80e7e 100644 --- a/go.sum +++ b/go.sum @@ -197,8 +197,9 @@ github.com/containernetworking/plugins v0.9.1 h1:FD1tADPls2EEi3flPc2OegIY1M9pUa9 github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= github.com/containers/buildah v1.20.2-0.20210504130217-903dc56408ac h1:rPQTF+1lz+F4uTZgfk2pwqGcEEg9mPSWK58UncsqsrA= github.com/containers/buildah v1.20.2-0.20210504130217-903dc56408ac/go.mod h1:0hqcxPCNk/lit/SwBQoXXymCbp2LUa07U0cwrn/T1c0= -github.com/containers/common v0.37.2-0.20210503193405-42134aa138ce h1:e7VNmGqwfUQkw+D5bms262x1HYqxfN9/+t5SoaFnwTk= github.com/containers/common v0.37.2-0.20210503193405-42134aa138ce/go.mod h1:JjU+yvzIGyx8ZsY8nyf7snzs4VSNh1eIaYsqoSKBoRw= +github.com/containers/common v0.38.1-0.20210510140555-24645399a050 h1:o3UdnXpzCmJwto4y+addBH2NXZObuZ0tXA7COZXNMnQ= +github.com/containers/common v0.38.1-0.20210510140555-24645399a050/go.mod h1:64dWQkAgrd2cxVh9eDOxJ/IgPOulVFg6G7WLRDTrAuA= github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg= github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I= github.com/containers/image/v5 v5.11.1/go.mod h1:HC9lhJ/Nz5v3w/5Co7H431kLlgzlVlOC+auD/er3OqE= diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go index 4a541b6e7a2b..ec4fa97240a6 100644 --- a/libpod/container_log_linux.go +++ b/libpod/container_log_linux.go @@ -8,12 +8,12 @@ import ( "fmt" "io" "math" + "strings" "time" "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/logs" journal "github.com/coreos/go-systemd/v22/sdjournal" - "github.com/hpcloud/tail/watch" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -89,21 +89,19 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption } }() go func() { - for { - state, err := c.State() - if err != nil { - until <- time.Time{} - logrus.Error(err) - break - } - time.Sleep(watch.POLL_DURATION) - if state != define.ContainerStateRunning && state != define.ContainerStatePaused { - until <- time.Time{} - break - } - } + // FIXME (#10323): we are facing a terrible + // race condition here. At the time the + // container dies and `c.Wait()` has returned, + // we may not have received all journald logs. + // So far there is no other way than waiting + // for a second. Ultimately, `r.Follow` is + // racy and we may have to implement our custom + // logic here. + c.Wait(ctx) + time.Sleep(time.Second) + until <- time.Time{} }() - follower := FollowBuffer{logChannel} + follower := journaldFollowBuffer{logChannel, options.Multi} err := r.Follow(until, follower) if err != nil { logrus.Debugf(err.Error()) @@ -124,7 +122,7 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption // because we are reusing bytes, we need to make // sure the old data doesn't get into the new line bytestr := string(bytes[:ec]) - logLine, err2 := logs.NewLogLine(bytestr) + logLine, err2 := logs.NewJournaldLogLine(bytestr, options.Multi) if err2 != nil { logrus.Error(err2) continue @@ -210,16 +208,18 @@ func formatterMessage(entry *journal.JournalEntry) (string, error) { if !ok { return "", fmt.Errorf("no MESSAGE field present in journal entry") } + msg = strings.TrimSuffix(msg, "\n") return msg, nil } -type FollowBuffer struct { +type journaldFollowBuffer struct { logChannel chan *logs.LogLine + withID bool } -func (f FollowBuffer) Write(p []byte) (int, error) { +func (f journaldFollowBuffer) Write(p []byte) (int, error) { bytestr := string(p) - logLine, err := logs.NewLogLine(bytestr) + logLine, err := logs.NewJournaldLogLine(bytestr, f.withID) if err != nil { return -1, err } diff --git a/libpod/logs/log.go b/libpod/logs/log.go index bba52408d2de..308053b47e5c 100644 --- a/libpod/logs/log.go +++ b/libpod/logs/log.go @@ -206,6 +206,36 @@ func NewLogLine(line string) (*LogLine, error) { return &l, nil } +// NewJournaldLogLine creates a LogLine from the specified line from journald. +// Note that if withID is set, the first item of the message is considerred to +// be the container ID and set as such. +func NewJournaldLogLine(line string, withID bool) (*LogLine, error) { + splitLine := strings.Split(line, " ") + if len(splitLine) < 4 { + return nil, errors.Errorf("'%s' is not a valid container log line", line) + } + logTime, err := time.Parse(LogTimeFormat, splitLine[0]) + if err != nil { + return nil, errors.Wrapf(err, "unable to convert time %s from container log", splitLine[0]) + } + var msg, id string + if withID { + id = splitLine[3] + msg = strings.Join(splitLine[4:], " ") + } else { + msg = strings.Join(splitLine[3:], " ") + // NO ID + } + l := LogLine{ + Time: logTime, + Device: splitLine[1], + ParseLogType: splitLine[2], + Msg: msg, + CID: id, + } + return &l, nil +} + // Partial returns a bool if the log line is a partial log type func (l *LogLine) Partial() bool { return l.ParseLogType == PartialLogType diff --git a/test/e2e/create_staticip_test.go b/test/e2e/create_staticip_test.go index 340ea31f3afd..2cf552274adb 100644 --- a/test/e2e/create_staticip_test.go +++ b/test/e2e/create_staticip_test.go @@ -60,8 +60,10 @@ var _ = Describe("Podman create with --ip flag", func() { }) It("Podman create with specified static IP has correct IP", func() { + // NOTE: we force the k8s-file log driver to make sure the + // tests are passing inside a container. ip := GetRandomIPAddress() - result := podmanTest.Podman([]string{"create", "--name", "test", "--ip", ip, ALPINE, "ip", "addr"}) + result := podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test", "--ip", ip, ALPINE, "ip", "addr"}) result.WaitWithDefaultTimeout() // Rootless static ip assignment without network should error if rootless.IsRootless() { @@ -83,10 +85,10 @@ var _ = Describe("Podman create with --ip flag", func() { It("Podman create two containers with the same IP", func() { SkipIfRootless("--ip not supported without network in rootless mode") ip := GetRandomIPAddress() - result := podmanTest.Podman([]string{"create", "--name", "test1", "--ip", ip, ALPINE, "sleep", "999"}) + result := podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test1", "--ip", ip, ALPINE, "sleep", "999"}) result.WaitWithDefaultTimeout() Expect(result.ExitCode()).To(Equal(0)) - result = podmanTest.Podman([]string{"create", "--name", "test2", "--ip", ip, ALPINE, "ip", "addr"}) + result = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test2", "--ip", ip, ALPINE, "ip", "addr"}) result.WaitWithDefaultTimeout() Expect(result.ExitCode()).To(Equal(0)) result = podmanTest.Podman([]string{"start", "test1"}) diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go index 1f1786dbeb92..e4db6b84579e 100644 --- a/test/e2e/create_test.go +++ b/test/e2e/create_test.go @@ -160,9 +160,12 @@ var _ = Describe("Podman create", func() { if podmanTest.Host.Arch == "ppc64le" { Skip("skip failing test on ppc64le") } + // NOTE: we force the k8s-file log driver to make sure the + // tests are passing inside a container. + mountPath := filepath.Join(podmanTest.TempDir, "secrets") os.Mkdir(mountPath, 0755) - session := podmanTest.Podman([]string{"create", "--name", "test", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) + session := podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"start", "test"}) @@ -173,7 +176,7 @@ var _ = Describe("Podman create", func() { Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(ContainSubstring("/create/test rw")) - session = podmanTest.Podman([]string{"create", "--name", "test_ro", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test,ro", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) + session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test_ro", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test,ro", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"start", "test_ro"}) @@ -184,7 +187,7 @@ var _ = Describe("Podman create", func() { Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(ContainSubstring("/create/test ro")) - session = podmanTest.Podman([]string{"create", "--name", "test_shared", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test,shared", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) + session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test_shared", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test,shared", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"start", "test_shared"}) @@ -200,7 +203,7 @@ var _ = Describe("Podman create", func() { mountPath = filepath.Join(podmanTest.TempDir, "scratchpad") os.Mkdir(mountPath, 0755) - session = podmanTest.Podman([]string{"create", "--name", "test_tmpfs", "--mount", "type=tmpfs,target=/create/test", ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) + session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test_tmpfs", "--mount", "type=tmpfs,target=/create/test", ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"start", "test_tmpfs"}) diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go index 4c66e2823c73..37e837b1d854 100644 --- a/test/e2e/run_networking_test.go +++ b/test/e2e/run_networking_test.go @@ -649,11 +649,13 @@ var _ = Describe("Podman run networking", func() { defer podmanTest.removeCNINetwork(netName) name := "nc-server" - run := podmanTest.Podman([]string{"run", "-d", "--name", name, "--net", netName, ALPINE, "nc", "-l", "-p", "8080"}) + run := podmanTest.Podman([]string{"run", "--log-driver", "k8s-file", "-d", "--name", name, "--net", netName, ALPINE, "nc", "-l", "-p", "8080"}) run.WaitWithDefaultTimeout() Expect(run.ExitCode()).To(Equal(0)) - run = podmanTest.Podman([]string{"run", "--rm", "--net", netName, "--uidmap", "0:1:4096", ALPINE, "sh", "-c", fmt.Sprintf("echo podman | nc -w 1 %s.dns.podman 8080", name)}) + // NOTE: we force the k8s-file log driver to make sure the + // tests are passing inside a container. + run = podmanTest.Podman([]string{"run", "--log-driver", "k8s-file", "--rm", "--net", netName, "--uidmap", "0:1:4096", ALPINE, "sh", "-c", fmt.Sprintf("echo podman | nc -w 1 %s.dns.podman 8080", name)}) run.WaitWithDefaultTimeout() Expect(run.ExitCode()).To(Equal(0)) diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 59220cf0178d..f27ded5d26bb 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -712,7 +712,7 @@ USER bin`, BB) It("podman run log-opt", func() { log := filepath.Join(podmanTest.TempDir, "/container.log") - session := podmanTest.Podman([]string{"run", "--rm", "--log-opt", fmt.Sprintf("path=%s", log), ALPINE, "ls"}) + session := podmanTest.Podman([]string{"run", "--rm", "--log-driver", "k8s-file", "--log-opt", fmt.Sprintf("path=%s", log), ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) _, err := os.Stat(log) diff --git a/test/e2e/toolbox_test.go b/test/e2e/toolbox_test.go index 986f856bf594..16300bebceda 100644 --- a/test/e2e/toolbox_test.go +++ b/test/e2e/toolbox_test.go @@ -215,7 +215,7 @@ var _ = Describe("Toolbox-specific testing", func() { useradd := fmt.Sprintf("useradd --home-dir %s --shell %s --uid %s %s", homeDir, shell, uid, username) passwd := fmt.Sprintf("passwd --delete %s", username) - session = podmanTest.Podman([]string{"create", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c", + session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c", fmt.Sprintf("%s; %s; echo READY; sleep 1000", useradd, passwd)}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -250,7 +250,7 @@ var _ = Describe("Toolbox-specific testing", func() { groupadd := fmt.Sprintf("groupadd --gid %s %s", gid, groupName) - session = podmanTest.Podman([]string{"create", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c", + session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c", fmt.Sprintf("%s; echo READY; sleep 1000", groupadd)}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -294,7 +294,7 @@ var _ = Describe("Toolbox-specific testing", func() { usermod := fmt.Sprintf("usermod --append --groups wheel --home %s --shell %s --uid %s --gid %s %s", homeDir, shell, uid, gid, username) - session = podmanTest.Podman([]string{"create", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c", + session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c", fmt.Sprintf("%s; %s; %s; echo READY; sleep 1000", useradd, groupadd, usermod)}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -339,6 +339,7 @@ var _ = Describe("Toolbox-specific testing", func() { // These should be most of the switches that Toolbox uses to create a "toolbox" container // https://github.com/containers/toolbox/blob/master/src/cmd/create.go session = podmanTest.Podman([]string{"create", + "--log-driver", "k8s-file", "--dns", "none", "--hostname", "toolbox", "--ipc", "host", diff --git a/test/system/035-logs.bats b/test/system/035-logs.bats index bac153b8e8b9..3dd88e5eba65 100644 --- a/test/system/035-logs.bats +++ b/test/system/035-logs.bats @@ -27,13 +27,22 @@ load helpers run_podman rm $cid } -@test "podman logs - multi" { +function _log_test_multi() { + local driver=$1 + skip_if_remote "logs does not support multiple containers when run remotely" + # Under k8s file, 'podman logs' returns just the facts, Ma'am. + # Under journald, there may be other cruft (e.g. container removals) + local etc= + if [[ $driver =~ journal ]]; then + etc='.*' + fi + # Simple helper to make the container starts, below, easier to read local -a cid doit() { - run_podman run --rm -d --name "$1" $IMAGE sh -c "$2"; + run_podman run --log-driver=$driver --rm -d --name "$1" $IMAGE sh -c "$2"; cid+=($(echo "${output:0:12}")) } @@ -47,24 +56,21 @@ load helpers run_podman logs -f c1 c2 is "$output" \ - "${cid[0]} a -${cid[1]} b -${cid[1]} c + "${cid[0]} a$etc +${cid[1]} b$etc +${cid[1]} c$etc ${cid[0]} d" "Sequential output from logs" } -@test "podman logs over journald" { +@test "podman logs - multi k8s-file" { + _log_test_multi k8s-file +} + +@test "podman logs - multi journald" { # We can't use journald on RHEL as rootless: rhbz#1895105 skip_if_journald_unavailable - msg=$(random_string 20) - - run_podman run --name myctr --log-driver journald $IMAGE echo $msg - - run_podman logs myctr - is "$output" "$msg" "check that log output equals the container output" - - run_podman rm myctr + _log_test_multi journald } # vim: filetype=sh diff --git a/test/system/070-build.bats b/test/system/070-build.bats index a2c8ae588c92..d2d56c051add 100644 --- a/test/system/070-build.bats +++ b/test/system/070-build.bats @@ -393,9 +393,9 @@ Labels.$label_name | $label_value "image tree: third line" is "${lines[3]}" "Image Layers" \ "image tree: fourth line" - is "${lines[4]}" ".* ID: [0-9a-f]\{12\} Size: .* Top Layer of: \[localhost/build_test:latest]" \ + is "${lines[4]}" ".* ID: [0-9a-f]\{12\} Size: .* Top Layer of: \[$IMAGE]" \ "image tree: first layer line" - is "${lines[-1]}" ".* ID: [0-9a-f]\{12\} Size: .* Top Layer of: \[$IMAGE]" \ + is "${lines[-1]}" ".* ID: [0-9a-f]\{12\} Size: .* Top Layer of: \[localhost/build_test:latest]" \ "image tree: last layer line" # FIXME: 'image tree --whatrequires' does not work via remote diff --git a/test/system/130-kill.bats b/test/system/130-kill.bats index 3770eac27c1f..1b02b497655b 100644 --- a/test/system/130-kill.bats +++ b/test/system/130-kill.bats @@ -8,7 +8,8 @@ load helpers @test "podman kill - test signal handling in containers" { # Start a container that will handle all signals by emitting 'got: N' local -a signals=(1 2 3 4 5 6 8 10 12 13 14 15 16 20 21 22 23 24 25 26 64) - run_podman run -d $IMAGE sh -c \ + # Force the k8s-file driver until #10323 is fixed. + run_podman run --log-driver=k8s-file -d $IMAGE sh -c \ "for i in ${signals[*]}; do trap \"echo got: \$i\" \$i; done; echo READY; while ! test -e /stop; do sleep 0.05; done; diff --git a/vendor/github.com/containers/common/libimage/events.go b/vendor/github.com/containers/common/libimage/events.go index bca736c7b943..c7733564db50 100644 --- a/vendor/github.com/containers/common/libimage/events.go +++ b/vendor/github.com/containers/common/libimage/events.go @@ -1,14 +1,18 @@ package libimage -import "time" +import ( + "time" -// EventType indicates the type of an event. Currrently, there is only one + "github.com/sirupsen/logrus" +) + +// EventType indicates the type of an event. Currently, there is only one // supported type for container image but we may add more (e.g., for manifest // lists) in the future. type EventType int const ( - // EventTypeUnknow is an unitialized EventType. + // EventTypeUnknown is an uninitialized EventType. EventTypeUnknown EventType = iota // EventTypeImagePull represents an image pull. EventTypeImagePull @@ -26,7 +30,7 @@ const ( EventTypeImageUntag // EventTypeImageMount represents an image being mounted. EventTypeImageMount - // EventTypeImageUnmounted represents an image being unmounted. + // EventTypeImageUnmount represents an image being unmounted. EventTypeImageUnmount ) @@ -41,3 +45,18 @@ type Event struct { // Type of the event. Type EventType } + +// writeEvent writes the specified event to the Runtime's event channel. The +// event is discarded if no event channel has been registered (yet). +func (r *Runtime) writeEvent(event *Event) { + select { + case r.eventChannel <- event: + // Done + case <-time.After(2 * time.Second): + // The Runtime's event channel has a buffer of size 100 which + // should be enough even under high load. However, we + // shouldn't block too long in case the buffer runs full (could + // be an honest user error or bug). + logrus.Warnf("Discarding libimage event which was not read within 2 seconds: %v", event) + } +} diff --git a/vendor/github.com/containers/common/libimage/image.go b/vendor/github.com/containers/common/libimage/image.go index 4728565bbc7b..11abfdee70ff 100644 --- a/vendor/github.com/containers/common/libimage/image.go +++ b/vendor/github.com/containers/common/libimage/image.go @@ -277,6 +277,10 @@ func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport, return errors.Errorf("cannot remove read-only image %q", i.ID()) } + if i.runtime.eventChannel != nil { + i.runtime.writeEvent(&Event{ID: i.ID(), Name: referencedBy, Time: time.Now(), Type: EventTypeImageRemove}) + } + // Check if already visisted this image. report, exists := rmMap[i.ID()] if exists { @@ -423,6 +427,9 @@ func (i *Image) Tag(name string) error { } logrus.Debugf("Tagging image %s with %q", i.ID(), ref.String()) + if i.runtime.eventChannel != nil { + i.runtime.writeEvent(&Event{ID: i.ID(), Name: name, Time: time.Now(), Type: EventTypeImageTag}) + } newNames := append(i.Names(), ref.String()) if err := i.runtime.store.SetNames(i.ID(), newNames); err != nil { @@ -454,6 +461,9 @@ func (i *Image) Untag(name string) error { name = ref.String() logrus.Debugf("Untagging %q from image %s", ref.String(), i.ID()) + if i.runtime.eventChannel != nil { + i.runtime.writeEvent(&Event{ID: i.ID(), Name: name, Time: time.Now(), Type: EventTypeImageUntag}) + } removedName := false newNames := []string{} @@ -593,6 +603,10 @@ func (i *Image) RepoDigests() ([]string, error) { // are directly passed down to the containers storage. Returns the fully // evaluated path to the mount point. func (i *Image) Mount(ctx context.Context, mountOptions []string, mountLabel string) (string, error) { + if i.runtime.eventChannel != nil { + i.runtime.writeEvent(&Event{ID: i.ID(), Name: "", Time: time.Now(), Type: EventTypeImageMount}) + } + mountPoint, err := i.runtime.store.MountImage(i.ID(), mountOptions, mountLabel) if err != nil { return "", err @@ -634,6 +648,9 @@ func (i *Image) Mountpoint() (string, error) { // Unmount the image. Use force to ignore the reference counter and forcefully // unmount. func (i *Image) Unmount(force bool) error { + if i.runtime.eventChannel != nil { + i.runtime.writeEvent(&Event{ID: i.ID(), Name: "", Time: time.Now(), Type: EventTypeImageUnmount}) + } logrus.Debugf("Unmounted image %s", i.ID()) _, err := i.runtime.store.UnmountImage(i.ID(), force) return err diff --git a/vendor/github.com/containers/common/libimage/image_tree.go b/vendor/github.com/containers/common/libimage/image_tree.go index 6583a7007395..b8b9cb21605d 100644 --- a/vendor/github.com/containers/common/libimage/image_tree.go +++ b/vendor/github.com/containers/common/libimage/image_tree.go @@ -35,36 +35,45 @@ func (i *Image) Tree(traverseChildren bool) (string, error) { fmt.Fprintf(sb, "No Image Layers") } - tree := gotree.New(sb.String()) - layerTree, err := i.runtime.layerTree() if err != nil { return "", err } - imageNode := layerTree.node(i.TopLayer()) // Traverse the entire tree down to all children. if traverseChildren { + tree := gotree.New(sb.String()) if err := imageTreeTraverseChildren(imageNode, tree); err != nil { return "", err } - } else { - // Walk all layers of the image and assemlbe their data. - for parentNode := imageNode; parentNode != nil; parentNode = parentNode.parent { - if parentNode.layer == nil { - break // we're done - } - var tags string - repoTags, err := parentNode.repoTags() - if err != nil { - return "", err - } - if len(repoTags) > 0 { - tags = fmt.Sprintf(" Top Layer of: %s", repoTags) - } - tree.Add(fmt.Sprintf("ID: %s Size: %7v%s", parentNode.layer.ID[:12], units.HumanSizeWithPrecision(float64(parentNode.layer.UncompressedSize), 4), tags)) + return tree.Print(), nil + } + + // Walk all layers of the image and assemlbe their data. Note that the + // tree is constructed in reverse order to remain backwards compatible + // with Podman. + contents := []string{} + for parentNode := imageNode; parentNode != nil; parentNode = parentNode.parent { + if parentNode.layer == nil { + break // we're done + } + var tags string + repoTags, err := parentNode.repoTags() + if err != nil { + return "", err + } + if len(repoTags) > 0 { + tags = fmt.Sprintf(" Top Layer of: %s", repoTags) } + content := fmt.Sprintf("ID: %s Size: %7v%s", parentNode.layer.ID[:12], units.HumanSizeWithPrecision(float64(parentNode.layer.UncompressedSize), 4), tags) + contents = append(contents, content) + } + contents = append(contents, sb.String()) + + tree := gotree.New(contents[len(contents)-1]) + for i := len(contents) - 2; i >= 0; i-- { + tree.Add(contents[i]) } return tree.Print(), nil @@ -80,14 +89,22 @@ func imageTreeTraverseChildren(node *layerNode, parent gotree.Tree) error { tags = fmt.Sprintf(" Top Layer of: %s", repoTags) } - newNode := parent.Add(fmt.Sprintf("ID: %s Size: %7v%s", node.layer.ID[:12], units.HumanSizeWithPrecision(float64(node.layer.UncompressedSize), 4), tags)) + content := fmt.Sprintf("ID: %s Size: %7v%s", node.layer.ID[:12], units.HumanSizeWithPrecision(float64(node.layer.UncompressedSize), 4), tags) - if len(node.children) <= 1 { - newNode = parent + var newTree gotree.Tree + if node.parent == nil || len(node.parent.children) <= 1 { + // No parent or no siblings, so we can go linear. + parent.Add(content) + newTree = parent + } else { + // Each siblings gets a new tree, so we can branch. + newTree = gotree.New(content) + parent.AddTree(newTree) } + for i := range node.children { child := node.children[i] - if err := imageTreeTraverseChildren(child, newNode); err != nil { + if err := imageTreeTraverseChildren(child, newTree); err != nil { return err } } diff --git a/vendor/github.com/containers/common/libimage/layer_tree.go b/vendor/github.com/containers/common/libimage/layer_tree.go index 7e0940339e55..4195b43c0e79 100644 --- a/vendor/github.com/containers/common/libimage/layer_tree.go +++ b/vendor/github.com/containers/common/libimage/layer_tree.go @@ -59,7 +59,7 @@ func (l *layerNode) repoTags() ([]string, error) { return nil, err } for _, tag := range repoTags { - if _, visted := visitedTags[tag]; visted { + if _, visited := visitedTags[tag]; visited { continue } visitedTags[tag] = true diff --git a/vendor/github.com/containers/common/libimage/load.go b/vendor/github.com/containers/common/libimage/load.go index c606aca5b28d..856813356a2e 100644 --- a/vendor/github.com/containers/common/libimage/load.go +++ b/vendor/github.com/containers/common/libimage/load.go @@ -4,6 +4,7 @@ import ( "context" "errors" "os" + "time" dirTransport "github.com/containers/image/v5/directory" dockerArchiveTransport "github.com/containers/image/v5/docker/archive" @@ -23,6 +24,10 @@ type LoadOptions struct { func (r *Runtime) Load(ctx context.Context, path string, options *LoadOptions) ([]string, error) { logrus.Debugf("Loading image from %q", path) + if r.eventChannel != nil { + r.writeEvent(&Event{ID: "", Name: path, Time: time.Now(), Type: EventTypeImageLoad}) + } + var ( loadedImages []string loadError error diff --git a/vendor/github.com/containers/common/libimage/manifest_list.go b/vendor/github.com/containers/common/libimage/manifest_list.go index 72a2cf55f20f..f902db5cb925 100644 --- a/vendor/github.com/containers/common/libimage/manifest_list.go +++ b/vendor/github.com/containers/common/libimage/manifest_list.go @@ -3,6 +3,7 @@ package libimage import ( "context" "fmt" + "time" "github.com/containers/common/libimage/manifests" imageCopy "github.com/containers/image/v5/copy" @@ -364,6 +365,10 @@ func (m *ManifestList) Push(ctx context.Context, destination string, options *Ma } } + if m.image.runtime.eventChannel != nil { + m.image.runtime.writeEvent(&Event{ID: m.ID(), Name: destination, Time: time.Now(), Type: EventTypeImagePush}) + } + // NOTE: we're using the logic in copier to create a proper // types.SystemContext. This prevents us from having an error prone // code duplicate here. diff --git a/vendor/github.com/containers/common/libimage/pull.go b/vendor/github.com/containers/common/libimage/pull.go index b92a5e15e065..f92b4d36c47b 100644 --- a/vendor/github.com/containers/common/libimage/pull.go +++ b/vendor/github.com/containers/common/libimage/pull.go @@ -5,10 +5,10 @@ import ( "fmt" "io" "strings" + "time" "github.com/containers/common/pkg/config" - dirTransport "github.com/containers/image/v5/directory" - dockerTransport "github.com/containers/image/v5/docker" + registryTransport "github.com/containers/image/v5/docker" dockerArchiveTransport "github.com/containers/image/v5/docker/archive" "github.com/containers/image/v5/docker/reference" ociArchiveTransport "github.com/containers/image/v5/oci/archive" @@ -42,7 +42,7 @@ type PullOptions struct { // policies (e.g., buildah-bud versus podman-build). Making the pull-policy // choice explicit is an attempt to prevent silent regressions. // -// The errror is storage.ErrImageUnknown iff the pull policy is set to "never" +// The error is storage.ErrImageUnknown iff the pull policy is set to "never" // and no local image has been found. This allows for an easier integration // into some users of this package (e.g., Buildah). func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullPolicy, options *PullOptions) ([]*Image, error) { @@ -56,7 +56,7 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP if err != nil { // If the image clearly refers to a local one, we can look it up directly. // In fact, we need to since they are not parseable. - if strings.HasPrefix(name, "sha256:") || (len(name) == 64 && !strings.Contains(name, "/.:@")) { + if strings.HasPrefix(name, "sha256:") || (len(name) == 64 && !strings.ContainsAny(name, "/.:@")) { if pullPolicy == config.PullPolicyAlways { return nil, errors.Errorf("pull policy is always but image has been referred to by ID (%s)", name) } @@ -76,10 +76,14 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP ref = dockerRef } - if options.AllTags && ref.Transport().Name() != dockerTransport.Transport.Name() { + if options.AllTags && ref.Transport().Name() != registryTransport.Transport.Name() { return nil, errors.Errorf("pulling all tags is not supported for %s transport", ref.Transport().Name()) } + if r.eventChannel != nil { + r.writeEvent(&Event{ID: "", Name: name, Time: time.Now(), Type: EventTypeImagePull}) + } + var ( pulledImages []string pullError error @@ -88,29 +92,17 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP // Dispatch the copy operation. switch ref.Transport().Name() { - // DOCKER/REGISTRY - case dockerTransport.Transport.Name(): + // DOCKER REGISTRY + case registryTransport.Transport.Name(): pulledImages, pullError = r.copyFromRegistry(ctx, ref, strings.TrimPrefix(name, "docker://"), pullPolicy, options) // DOCKER ARCHIVE case dockerArchiveTransport.Transport.Name(): pulledImages, pullError = r.copyFromDockerArchive(ctx, ref, &options.CopyOptions) - // OCI - case ociTransport.Transport.Name(): - pulledImages, pullError = r.copyFromDefault(ctx, ref, &options.CopyOptions) - - // OCI ARCHIVE - case ociArchiveTransport.Transport.Name(): - pulledImages, pullError = r.copyFromDefault(ctx, ref, &options.CopyOptions) - - // DIR - case dirTransport.Transport.Name(): - pulledImages, pullError = r.copyFromDefault(ctx, ref, &options.CopyOptions) - - // UNSUPPORTED + // ALL OTHER TRANSPORTS default: - return nil, errors.Errorf("unsupported transport %q for pulling", ref.Transport().Name()) + pulledImages, pullError = r.copyFromDefault(ctx, ref, &options.CopyOptions) } if pullError != nil { @@ -162,7 +154,12 @@ func (r *Runtime) copyFromDefault(ctx context.Context, ref types.ImageReference, imageName = "sha256:" + storageName[1:] } else { storageName = manifest.Annotations["org.opencontainers.image.ref.name"] - imageName = storageName + named, err := NormalizeName(storageName) + if err != nil { + return nil, err + } + imageName = named.String() + storageName = imageName } default: @@ -275,7 +272,7 @@ func (r *Runtime) copyFromRegistry(ctx context.Context, ref types.ImageReference } named := reference.TrimNamed(ref.DockerReference()) - tags, err := dockerTransport.GetRepositoryTags(ctx, &r.systemContext, ref) + tags, err := registryTransport.GetRepositoryTags(ctx, &r.systemContext, ref) if err != nil { return nil, err } @@ -399,7 +396,7 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str for _, candidate := range resolved.PullCandidates { candidateString := candidate.Value.String() logrus.Debugf("Attempting to pull candidate %s for %s", candidateString, imageName) - srcRef, err := dockerTransport.NewReference(candidate.Value) + srcRef, err := registryTransport.NewReference(candidate.Value) if err != nil { return nil, err } diff --git a/vendor/github.com/containers/common/libimage/push.go b/vendor/github.com/containers/common/libimage/push.go index 8ff5d5ffd44b..f1434b81d916 100644 --- a/vendor/github.com/containers/common/libimage/push.go +++ b/vendor/github.com/containers/common/libimage/push.go @@ -2,6 +2,7 @@ package libimage import ( "context" + "time" dockerArchiveTransport "github.com/containers/image/v5/docker/archive" "github.com/containers/image/v5/docker/reference" @@ -61,8 +62,12 @@ func (r *Runtime) Push(ctx context.Context, source, destination string, options destRef = dockerRef } + if r.eventChannel != nil { + r.writeEvent(&Event{ID: image.ID(), Name: destination, Time: time.Now(), Type: EventTypeImagePush}) + } + // Buildah compat: Make sure to tag the destination image if it's a - // Docker archive. This way, we preseve the image name. + // Docker archive. This way, we preserve the image name. if destRef.Transport().Name() == dockerArchiveTransport.Transport.Name() { if named, err := reference.ParseNamed(resolvedSource); err == nil { tagged, isTagged := named.(reference.NamedTagged) diff --git a/vendor/github.com/containers/common/libimage/runtime.go b/vendor/github.com/containers/common/libimage/runtime.go index 4e6bd2cf2e9e..c80e7ec7abba 100644 --- a/vendor/github.com/containers/common/libimage/runtime.go +++ b/vendor/github.com/containers/common/libimage/runtime.go @@ -20,6 +20,9 @@ import ( // RuntimeOptions allow for creating a customized Runtime. type RuntimeOptions struct { + // The base system context of the runtime which will be used throughout + // the entire lifespan of the Runtime. Certain options in some + // functions may override specific fields. SystemContext *types.SystemContext } @@ -41,6 +44,8 @@ func setRegistriesConfPath(systemContext *types.SystemContext) { // Runtime is responsible for image management and storing them in a containers // storage. type Runtime struct { + // Use to send events out to users. + eventChannel chan *Event // Underlying storage store. store storage.Store // Global system context. No pointer to simplify copying and modifying @@ -55,6 +60,18 @@ func (r *Runtime) systemContextCopy() *types.SystemContext { return &sys } +// EventChannel creates a buffered channel for events that the Runtime will use +// to write events to. Callers are expected to read from the channel in a +// timely manner. +// Can be called once for a given Runtime. +func (r *Runtime) EventChannel() chan *Event { + if r.eventChannel != nil { + return r.eventChannel + } + r.eventChannel = make(chan *Event, 100) + return r.eventChannel +} + // RuntimeFromStore returns a Runtime for the specified store. func RuntimeFromStore(store storage.Store, options *RuntimeOptions) (*Runtime, error) { if options == nil { @@ -99,6 +116,9 @@ func RuntimeFromStoreOptions(runtimeOptions *RuntimeOptions, storeOptions *stora // is considered to be an error condition. func (r *Runtime) Shutdown(force bool) error { _, err := r.store.Shutdown(force) + if r.eventChannel != nil { + close(r.eventChannel) + } return err } diff --git a/vendor/github.com/containers/common/libimage/save.go b/vendor/github.com/containers/common/libimage/save.go index c03437682b0f..c00c0107e47a 100644 --- a/vendor/github.com/containers/common/libimage/save.go +++ b/vendor/github.com/containers/common/libimage/save.go @@ -3,6 +3,7 @@ package libimage import ( "context" "strings" + "time" dirTransport "github.com/containers/image/v5/directory" dockerArchiveTransport "github.com/containers/image/v5/docker/archive" @@ -46,7 +47,7 @@ func (r *Runtime) Save(ctx context.Context, names []string, format, path string, // All formats support saving 1. default: if format != "docker-archive" { - return errors.Errorf("unspported format %q for saving multiple images (only docker-archive)", format) + return errors.Errorf("unsupported format %q for saving multiple images (only docker-archive)", format) } if len(options.AdditionalTags) > 0 { return errors.Errorf("cannot save multiple images with multiple tags") @@ -62,7 +63,7 @@ func (r *Runtime) Save(ctx context.Context, names []string, format, path string, return r.saveDockerArchive(ctx, names, path, options) } - return errors.Errorf("unspported format %q for saving images", format) + return errors.Errorf("unsupported format %q for saving images", format) } @@ -74,6 +75,10 @@ func (r *Runtime) saveSingleImage(ctx context.Context, name, format, path string return err } + if r.eventChannel != nil { + r.writeEvent(&Event{ID: image.ID(), Name: path, Time: time.Now(), Type: EventTypeImageSave}) + } + // Unless the image was referenced by ID, use the resolved name as a // tag. var tag string @@ -101,7 +106,7 @@ func (r *Runtime) saveSingleImage(ctx context.Context, name, format, path string options.ManifestMIMEType = manifest.DockerV2Schema2MediaType default: - return errors.Errorf("unspported format %q for saving images", format) + return errors.Errorf("unsupported format %q for saving images", format) } if err != nil { @@ -160,6 +165,9 @@ func (r *Runtime) saveDockerArchive(ctx context.Context, names []string, path st } } localImages[image.ID()] = local + if r.eventChannel != nil { + r.writeEvent(&Event{ID: image.ID(), Name: path, Time: time.Now(), Type: EventTypeImageSave}) + } } writer, err := dockerArchiveTransport.NewWriter(r.systemContextCopy(), path) diff --git a/vendor/github.com/containers/common/libimage/search.go b/vendor/github.com/containers/common/libimage/search.go index b36b6d2a3226..4d1b842e76bf 100644 --- a/vendor/github.com/containers/common/libimage/search.go +++ b/vendor/github.com/containers/common/libimage/search.go @@ -7,7 +7,7 @@ import ( "strings" "sync" - dockerTransport "github.com/containers/image/v5/docker" + registryTransport "github.com/containers/image/v5/docker" "github.com/containers/image/v5/pkg/sysregistriesv2" "github.com/containers/image/v5/transports/alltransports" "github.com/containers/image/v5/types" @@ -193,7 +193,7 @@ func (r *Runtime) searchImageInRegistry(ctx context.Context, term, registry stri return results, nil } - results, err := dockerTransport.SearchRegistry(ctx, sys, registry, term, limit) + results, err := registryTransport.SearchRegistry(ctx, sys, registry, term, limit) if err != nil { return []SearchResult{}, err } @@ -255,7 +255,7 @@ func (r *Runtime) searchImageInRegistry(ctx context.Context, term, registry stri func searchRepositoryTags(ctx context.Context, sys *types.SystemContext, registry, term string, options *SearchOptions) ([]SearchResult, error) { dockerPrefix := "docker://" imageRef, err := alltransports.ParseImageName(fmt.Sprintf("%s/%s", registry, term)) - if err == nil && imageRef.Transport().Name() != dockerTransport.Transport.Name() { + if err == nil && imageRef.Transport().Name() != registryTransport.Transport.Name() { return nil, errors.Errorf("reference %q must be a docker reference", term) } else if err != nil { imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", dockerPrefix, fmt.Sprintf("%s/%s", registry, term))) @@ -263,7 +263,7 @@ func searchRepositoryTags(ctx context.Context, sys *types.SystemContext, registr return nil, errors.Errorf("reference %q must be a docker reference", term) } } - tags, err := dockerTransport.GetRepositoryTags(ctx, sys, imageRef) + tags, err := registryTransport.GetRepositoryTags(ctx, sys, imageRef) if err != nil { return nil, errors.Errorf("error getting repository tags: %v", err) } @@ -288,18 +288,18 @@ func searchRepositoryTags(ctx context.Context, sys *types.SystemContext, registr return paramsArr, nil } -func (f *SearchFilter) matchesStarFilter(result dockerTransport.SearchResult) bool { +func (f *SearchFilter) matchesStarFilter(result registryTransport.SearchResult) bool { return result.StarCount >= f.Stars } -func (f *SearchFilter) matchesAutomatedFilter(result dockerTransport.SearchResult) bool { +func (f *SearchFilter) matchesAutomatedFilter(result registryTransport.SearchResult) bool { if f.IsAutomated != types.OptionalBoolUndefined { return result.IsAutomated == (f.IsAutomated == types.OptionalBoolTrue) } return true } -func (f *SearchFilter) matchesOfficialFilter(result dockerTransport.SearchResult) bool { +func (f *SearchFilter) matchesOfficialFilter(result registryTransport.SearchResult) bool { if f.IsOfficial != types.OptionalBoolUndefined { return result.IsOfficial == (f.IsOfficial == types.OptionalBoolTrue) } diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go index 371dd366762d..ee59575272be 100644 --- a/vendor/github.com/containers/common/pkg/config/config.go +++ b/vendor/github.com/containers/common/pkg/config/config.go @@ -232,7 +232,7 @@ type EngineConfig struct { // will fall back to containers/image defaults. ImageParallelCopies uint `toml:"image_parallel_copies,omitempty"` - // ImageDefaultFormat sepecified the manifest Type (oci, v2s2, or v2s1) + // ImageDefaultFormat specified the manifest Type (oci, v2s2, or v2s1) // to use when pulling, pushing, building container images. By default // image pulled and pushed match the format of the source image. // Building/committing defaults to OCI. @@ -425,6 +425,12 @@ type NetworkConfig struct { // to attach pods to. DefaultNetwork string `toml:"default_network,omitempty"` + // DefaultSubnet is the subnet to be used for the default CNI network. + // If a network with the name given in DefaultNetwork is not present + // then a new network using this subnet will be created. + // Must be a valid IPv4 CIDR block. + DefaultSubnet string `toml:"default_subnet,omitempty"` + // NetworkConfigDir is where CNI network configuration files are stored. NetworkConfigDir string `toml:"network_config_dir,omitempty"` } diff --git a/vendor/github.com/containers/common/pkg/config/containers.conf b/vendor/github.com/containers/common/pkg/config/containers.conf index 00edd543831e..f696843f5900 100644 --- a/vendor/github.com/containers/common/pkg/config/containers.conf +++ b/vendor/github.com/containers/common/pkg/config/containers.conf @@ -157,7 +157,7 @@ default_sysctls = [ # Logging driver for the container. Available options: k8s-file and journald. # -# log_driver = "k8s-file" +# log_driver = "journald" # Maximum size allowed for the container log file. Negative numbers indicate # that no size limit is imposed. If positive, it must be >= 8192 to match or @@ -243,6 +243,12 @@ default_sysctls = [ # The network name of the default CNI network to attach pods to. # default_network = "podman" +# The default subnet for the default CNI network given in default_network. +# If a network with that name does not exist, a new network using that name and +# this subnet will be created. +# Must be a valid IPv4 CIDR prefix. +#default_subnet = "10.88.0.0/16" + # Path to the directory where CNI configuration files are located. # # network_config_dir = "/etc/cni/net.d/" @@ -254,7 +260,7 @@ default_sysctls = [ # Manifest Type (oci, v2s2, or v2s1) to use when pulling, pushing, building # container images. By default image pulled and pushed match the format of the -# source image. Building/commiting defaults to OCI. +# source image. Building/committing defaults to OCI. # image_default_format = "" # Cgroup management implementation used for the runtime. diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go index 34a360bf57fc..4177761607b4 100644 --- a/vendor/github.com/containers/common/pkg/config/default.go +++ b/vendor/github.com/containers/common/pkg/config/default.go @@ -102,7 +102,7 @@ const ( // SystemdCgroupsManager represents systemd native cgroup manager SystemdCgroupsManager = "systemd" // DefaultLogDriver is the default type of log files - DefaultLogDriver = "k8s-file" + DefaultLogDriver = "journald" // DefaultLogSizeMax is the default value for the maximum log size // allowed for a container. Negative values mean that no limit is imposed. DefaultLogSizeMax = -1 @@ -114,6 +114,9 @@ const ( // DefaultSignaturePolicyPath is the default value for the // policy.json file. DefaultSignaturePolicyPath = "/etc/containers/policy.json" + // DefaultSubnet is the subnet that will be used for the default CNI + // network. + DefaultSubnet = "10.88.0.0/16" // DefaultRootlessSignaturePolicyPath is the location within // XDG_CONFIG_HOME of the rootless policy.json file. DefaultRootlessSignaturePolicyPath = "containers/policy.json" @@ -204,6 +207,7 @@ func DefaultConfig() (*Config, error) { }, Network: NetworkConfig{ DefaultNetwork: "podman", + DefaultSubnet: DefaultSubnet, NetworkConfigDir: cniConfig, CNIPluginDirs: cniBinDir, }, diff --git a/vendor/github.com/containers/common/pkg/filters/filters.go b/vendor/github.com/containers/common/pkg/filters/filters.go index 53f420db29af..e26e056adf90 100644 --- a/vendor/github.com/containers/common/pkg/filters/filters.go +++ b/vendor/github.com/containers/common/pkg/filters/filters.go @@ -96,7 +96,7 @@ func PrepareFilters(r *http.Request) (map[string][]string, error) { return filterMap, nil } -// MatchLabelFilters matches labels and returs true if they are valid +// MatchLabelFilters matches labels and returns true if they are valid func MatchLabelFilters(filterValues []string, labels map[string]string) bool { outer: for _, filterValue := range filterValues { diff --git a/vendor/github.com/containers/common/pkg/secrets/filedriver/filedriver.go b/vendor/github.com/containers/common/pkg/secrets/filedriver/filedriver.go index 37edc16be317..80fcf54583dc 100644 --- a/vendor/github.com/containers/common/pkg/secrets/filedriver/filedriver.go +++ b/vendor/github.com/containers/common/pkg/secrets/filedriver/filedriver.go @@ -33,7 +33,7 @@ type Driver struct { func NewDriver(rootPath string) (*Driver, error) { fileDriver := new(Driver) fileDriver.secretsDataFilePath = filepath.Join(rootPath, secretsDataFile) - // the lockfile functions requre that the rootPath dir is executable + // the lockfile functions require that the rootPath dir is executable if err := os.MkdirAll(rootPath, 0700); err != nil { return nil, err } diff --git a/vendor/github.com/containers/common/pkg/secrets/secrets.go b/vendor/github.com/containers/common/pkg/secrets/secrets.go index 5e0fb3e9d7a0..d27bb7472c9b 100644 --- a/vendor/github.com/containers/common/pkg/secrets/secrets.go +++ b/vendor/github.com/containers/common/pkg/secrets/secrets.go @@ -99,7 +99,7 @@ func NewManager(rootPath string) (*SecretsManager, error) { if !filepath.IsAbs(rootPath) { return nil, errors.Wrapf(errInvalidPath, "path must be absolute: %s", rootPath) } - // the lockfile functions requre that the rootPath dir is executable + // the lockfile functions require that the rootPath dir is executable if err := os.MkdirAll(rootPath, 0700); err != nil { return nil, err } diff --git a/vendor/github.com/containers/common/pkg/secrets/secretsdb.go b/vendor/github.com/containers/common/pkg/secrets/secretsdb.go index 22db97c12ae0..1395d103cb40 100644 --- a/vendor/github.com/containers/common/pkg/secrets/secretsdb.go +++ b/vendor/github.com/containers/common/pkg/secrets/secretsdb.go @@ -76,7 +76,7 @@ func (s *SecretsManager) getNameAndID(nameOrID string) (name, id string, err err } // ID prefix may have been given, iterate through all IDs. - // ID and partial ID has a max lenth of 25, so we return if its greater than that. + // ID and partial ID has a max length of 25, so we return if its greater than that. if len(nameOrID) > secretIDLength { return "", "", errors.Wrapf(errNoSuchSecret, "no secret with name or id %q", nameOrID) } diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go index af0a1269eb56..df095f22079d 100644 --- a/vendor/github.com/containers/common/version/version.go +++ b/vendor/github.com/containers/common/version/version.go @@ -1,4 +1,4 @@ package version // Version is the version of the build. -const Version = "0.37.2-dev" +const Version = "0.38.1-dev" diff --git a/vendor/modules.txt b/vendor/modules.txt index a494d2fbe2b3..2ea648e124f3 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -90,7 +90,7 @@ github.com/containers/buildah/pkg/overlay github.com/containers/buildah/pkg/parse github.com/containers/buildah/pkg/rusage github.com/containers/buildah/util -# github.com/containers/common v0.37.2-0.20210503193405-42134aa138ce +# github.com/containers/common v0.38.1-0.20210510140555-24645399a050 github.com/containers/common/libimage github.com/containers/common/libimage/manifests github.com/containers/common/pkg/apparmor