mirror of
https://github.com/containers/podman.git
synced 2025-05-20 08:36:23 +08:00
Merge pull request #10222 from vrothberg/image-tree
podman image tree: restore previous behavior
This commit is contained in:
2
go.mod
2
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
|
||||
|
3
go.sum
3
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=
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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"})
|
||||
|
@ -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"})
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
27
vendor/github.com/containers/common/libimage/events.go
generated
vendored
27
vendor/github.com/containers/common/libimage/events.go
generated
vendored
@ -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)
|
||||
}
|
||||
}
|
||||
|
17
vendor/github.com/containers/common/libimage/image.go
generated
vendored
17
vendor/github.com/containers/common/libimage/image.go
generated
vendored
@ -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
|
||||
|
61
vendor/github.com/containers/common/libimage/image_tree.go
generated
vendored
61
vendor/github.com/containers/common/libimage/image_tree.go
generated
vendored
@ -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
|
||||
}
|
||||
}
|
||||
|
2
vendor/github.com/containers/common/libimage/layer_tree.go
generated
vendored
2
vendor/github.com/containers/common/libimage/layer_tree.go
generated
vendored
@ -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
|
||||
|
5
vendor/github.com/containers/common/libimage/load.go
generated
vendored
5
vendor/github.com/containers/common/libimage/load.go
generated
vendored
@ -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
|
||||
|
5
vendor/github.com/containers/common/libimage/manifest_list.go
generated
vendored
5
vendor/github.com/containers/common/libimage/manifest_list.go
generated
vendored
@ -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.
|
||||
|
45
vendor/github.com/containers/common/libimage/pull.go
generated
vendored
45
vendor/github.com/containers/common/libimage/pull.go
generated
vendored
@ -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
|
||||
}
|
||||
|
7
vendor/github.com/containers/common/libimage/push.go
generated
vendored
7
vendor/github.com/containers/common/libimage/push.go
generated
vendored
@ -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)
|
||||
|
20
vendor/github.com/containers/common/libimage/runtime.go
generated
vendored
20
vendor/github.com/containers/common/libimage/runtime.go
generated
vendored
@ -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
|
||||
}
|
||||
|
||||
|
14
vendor/github.com/containers/common/libimage/save.go
generated
vendored
14
vendor/github.com/containers/common/libimage/save.go
generated
vendored
@ -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)
|
||||
|
14
vendor/github.com/containers/common/libimage/search.go
generated
vendored
14
vendor/github.com/containers/common/libimage/search.go
generated
vendored
@ -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)
|
||||
}
|
||||
|
8
vendor/github.com/containers/common/pkg/config/config.go
generated
vendored
8
vendor/github.com/containers/common/pkg/config/config.go
generated
vendored
@ -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"`
|
||||
}
|
||||
|
10
vendor/github.com/containers/common/pkg/config/containers.conf
generated
vendored
10
vendor/github.com/containers/common/pkg/config/containers.conf
generated
vendored
@ -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.
|
||||
|
6
vendor/github.com/containers/common/pkg/config/default.go
generated
vendored
6
vendor/github.com/containers/common/pkg/config/default.go
generated
vendored
@ -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,
|
||||
},
|
||||
|
2
vendor/github.com/containers/common/pkg/filters/filters.go
generated
vendored
2
vendor/github.com/containers/common/pkg/filters/filters.go
generated
vendored
@ -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 {
|
||||
|
2
vendor/github.com/containers/common/pkg/secrets/filedriver/filedriver.go
generated
vendored
2
vendor/github.com/containers/common/pkg/secrets/filedriver/filedriver.go
generated
vendored
@ -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
|
||||
}
|
||||
|
2
vendor/github.com/containers/common/pkg/secrets/secrets.go
generated
vendored
2
vendor/github.com/containers/common/pkg/secrets/secrets.go
generated
vendored
@ -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
|
||||
}
|
||||
|
2
vendor/github.com/containers/common/pkg/secrets/secretsdb.go
generated
vendored
2
vendor/github.com/containers/common/pkg/secrets/secretsdb.go
generated
vendored
@ -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)
|
||||
}
|
||||
|
2
vendor/github.com/containers/common/version/version.go
generated
vendored
2
vendor/github.com/containers/common/version/version.go
generated
vendored
@ -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"
|
||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -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
|
||||
|
Reference in New Issue
Block a user