summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_internal_linux.go12
-rw-r--r--libpod/events/logfile.go4
-rw-r--r--libpod/image/docker_registry_options.go1
-rw-r--r--libpod/image/filters.go14
-rw-r--r--libpod/image/image_test.go80
-rw-r--r--libpod/image/prune.go31
-rw-r--r--libpod/image/pull.go8
-rw-r--r--libpod/image/testdata/registries.conf4
-rw-r--r--libpod/network/netconflist.go29
-rw-r--r--libpod/options.go22
-rw-r--r--libpod/runtime_ctr.go2
-rw-r--r--libpod/runtime_img.go3
-rw-r--r--libpod/volume_internal.go1
-rw-r--r--libpod/volume_internal_linux.go10
14 files changed, 98 insertions, 123 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 94c6c3840..a136fb72d 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -607,10 +607,16 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
availableUIDs, availableGIDs, err := rootless.GetAvailableIDMaps()
if err != nil {
- return nil, err
+ if os.IsNotExist(err) {
+ // The kernel-provided files only exist if user namespaces are supported
+ logrus.Debugf("user or group ID mappings not available: %s", err)
+ } else {
+ return nil, err
+ }
+ } else {
+ g.Config.Linux.UIDMappings = rootless.MaybeSplitMappings(g.Config.Linux.UIDMappings, availableUIDs)
+ g.Config.Linux.GIDMappings = rootless.MaybeSplitMappings(g.Config.Linux.GIDMappings, availableGIDs)
}
- g.Config.Linux.UIDMappings = rootless.MaybeSplitMappings(g.Config.Linux.UIDMappings, availableUIDs)
- g.Config.Linux.GIDMappings = rootless.MaybeSplitMappings(g.Config.Linux.GIDMappings, availableGIDs)
// Hostname handling:
// If we have a UTS namespace, set Hostname in the OCI spec.
diff --git a/libpod/events/logfile.go b/libpod/events/logfile.go
index 7a32ea311..0f00525e8 100644
--- a/libpod/events/logfile.go
+++ b/libpod/events/logfile.go
@@ -7,7 +7,7 @@ import (
"time"
"github.com/containers/podman/v3/pkg/util"
- "github.com/containers/storage"
+ "github.com/containers/storage/pkg/lockfile"
"github.com/pkg/errors"
)
@@ -20,7 +20,7 @@ type EventLogFile struct {
// Writes to the log file
func (e EventLogFile) Write(ee Event) error {
// We need to lock events file
- lock, err := storage.GetLockfile(e.options.LogFilePath + ".lock")
+ lock, err := lockfile.GetLockfile(e.options.LogFilePath + ".lock")
if err != nil {
return err
}
diff --git a/libpod/image/docker_registry_options.go b/libpod/image/docker_registry_options.go
index 0a2a375ae..d95234e3d 100644
--- a/libpod/image/docker_registry_options.go
+++ b/libpod/image/docker_registry_options.go
@@ -69,6 +69,7 @@ func GetSystemContext(signaturePolicyPath, authFilePath string, forceCompress bo
sc.AuthFilePath = authFilePath
sc.DirForceCompress = forceCompress
sc.DockerRegistryUserAgent = fmt.Sprintf("libpod/%s", podmanVersion.Version)
+ sc.BigFilesTemporaryDir = parse.GetTempDir()
return sc
}
diff --git a/libpod/image/filters.go b/libpod/image/filters.go
index 37d3cb6a5..d316c6956 100644
--- a/libpod/image/filters.go
+++ b/libpod/image/filters.go
@@ -9,6 +9,7 @@ import (
"time"
"github.com/containers/podman/v3/pkg/inspect"
+ "github.com/containers/podman/v3/pkg/util"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -78,23 +79,14 @@ func ReadOnlyFilter(readOnly bool) ResultFilter {
}
// LabelFilter allows you to filter by images labels key and/or value
-func LabelFilter(ctx context.Context, labelfilter string) ResultFilter {
+func LabelFilter(ctx context.Context, filter string) ResultFilter {
// We need to handle both label=key and label=key=value
return func(i *Image) bool {
- var value string
- splitFilter := strings.SplitN(labelfilter, "=", 2)
- key := splitFilter[0]
- if len(splitFilter) > 1 {
- value = splitFilter[1]
- }
labels, err := i.Labels(ctx)
if err != nil {
return false
}
- if len(strings.TrimSpace(labels[key])) > 0 && len(strings.TrimSpace(value)) == 0 {
- return true
- }
- return labels[key] == value
+ return util.MatchLabelFilters([]string{filter}, labels)
}
}
diff --git a/libpod/image/image_test.go b/libpod/image/image_test.go
index 3e6e7b9db..2b42d6394 100644
--- a/libpod/image/image_test.go
+++ b/libpod/image/image_test.go
@@ -9,10 +9,12 @@ import (
"github.com/containers/podman/v3/libpod/events"
"github.com/containers/podman/v3/pkg/util"
+ podmanVersion "github.com/containers/podman/v3/version"
"github.com/containers/storage"
"github.com/containers/storage/pkg/reexec"
"github.com/opencontainers/go-digest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
var (
@@ -93,6 +95,8 @@ func TestImage_NewFromLocal(t *testing.T) {
// Need images to be present for this test
ir, err := NewImageRuntimeFromOptions(so)
assert.NoError(t, err)
+ defer cleanup(workdir, ir)
+
ir.Eventer = events.NewNullEventer()
bb, err := ir.New(context.Background(), "docker.io/library/busybox:latest", "", "", writer, nil, SigningOptions{}, nil, util.PullImageMissing, nil)
assert.NoError(t, err)
@@ -106,13 +110,10 @@ func TestImage_NewFromLocal(t *testing.T) {
assert.NoError(t, err)
for _, name := range image.names {
newImage, err := ir.NewFromLocal(name)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, newImage.ID(), image.img.ID())
}
}
-
- // Shutdown the runtime and remove the temporary storage
- cleanup(workdir, ir)
}
// TestImage_New tests pulling the image by various names, tags, and from
@@ -125,30 +126,31 @@ func TestImage_New(t *testing.T) {
var names []string
workdir, err := mkWorkDir()
assert.NoError(t, err)
-
so := storage.StoreOptions{
RunRoot: workdir,
GraphRoot: workdir,
}
ir, err := NewImageRuntimeFromOptions(so)
assert.NoError(t, err)
+ defer cleanup(workdir, ir)
+
ir.Eventer = events.NewNullEventer()
// Build the list of pull names
names = append(names, bbNames...)
writer := os.Stdout
+ opts := DockerRegistryOptions{
+ RegistriesConfPath: "testdata/registries.conf",
+ }
// Iterate over the names and delete the image
// after the pull
for _, img := range names {
- newImage, err := ir.New(context.Background(), img, "", "", writer, nil, SigningOptions{}, nil, util.PullImageMissing, nil)
- assert.NoError(t, err)
+ newImage, err := ir.New(context.Background(), img, "", "", writer, &opts, SigningOptions{}, nil, util.PullImageMissing, nil)
+ require.NoError(t, err, img)
assert.NotEqual(t, newImage.ID(), "")
err = newImage.Remove(context.Background(), false)
assert.NoError(t, err)
}
-
- // Shutdown the runtime and remove the temporary storage
- cleanup(workdir, ir)
}
// TestImage_MatchRepoTag tests the various inputs we need to match
@@ -161,20 +163,24 @@ func TestImage_MatchRepoTag(t *testing.T) {
//Set up
workdir, err := mkWorkDir()
assert.NoError(t, err)
-
so := storage.StoreOptions{
RunRoot: workdir,
GraphRoot: workdir,
}
ir, err := NewImageRuntimeFromOptions(so)
- assert.NoError(t, err)
+ require.NoError(t, err)
+ defer cleanup(workdir, ir)
+
+ opts := DockerRegistryOptions{
+ RegistriesConfPath: "testdata/registries.conf",
+ }
ir.Eventer = events.NewNullEventer()
- newImage, err := ir.New(context.Background(), "busybox", "", "", os.Stdout, nil, SigningOptions{}, nil, util.PullImageMissing, nil)
- assert.NoError(t, err)
+ newImage, err := ir.New(context.Background(), "busybox", "", "", os.Stdout, &opts, SigningOptions{}, nil, util.PullImageMissing, nil)
+ require.NoError(t, err)
err = newImage.TagImage("foo:latest")
- assert.NoError(t, err)
+ require.NoError(t, err)
err = newImage.TagImage("foo:bar")
- assert.NoError(t, err)
+ require.NoError(t, err)
// Tests start here.
for _, name := range bbNames {
@@ -187,23 +193,19 @@ func TestImage_MatchRepoTag(t *testing.T) {
// foo should resolve to foo:latest
repoTag, err := newImage.MatchRepoTag("foo")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "localhost/foo:latest", repoTag)
// foo:bar should resolve to foo:bar
repoTag, err = newImage.MatchRepoTag("foo:bar")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "localhost/foo:bar", repoTag)
- // Shutdown the runtime and remove the temporary storage
- cleanup(workdir, ir)
}
// TestImage_RepoDigests tests RepoDigest generation.
func TestImage_RepoDigests(t *testing.T) {
dgst, err := digest.Parse("sha256:7173b809ca12ec5dee4506cd86be934c4596dd234ee82c0662eac04a8c2c71dc")
- if err != nil {
- t.Fatal(err)
- }
+ require.NoError(t, err)
for _, tt := range []struct {
name string
@@ -235,10 +237,7 @@ func TestImage_RepoDigests(t *testing.T) {
},
}
actual, err := image.RepoDigests()
- if err != nil {
- t.Fatal(err)
- }
-
+ require.NoError(t, err)
assert.Equal(t, test.expected, actual)
image = &Image{
@@ -248,10 +247,7 @@ func TestImage_RepoDigests(t *testing.T) {
},
}
actual, err = image.RepoDigests()
- if err != nil {
- t.Fatal(err)
- }
-
+ require.NoError(t, err)
assert.Equal(t, test.expected, actual)
})
}
@@ -298,3 +294,25 @@ func TestNormalizedTag(t *testing.T) {
}
}
}
+
+func TestGetSystemContext(t *testing.T) {
+ sc := GetSystemContext("", "", false)
+ assert.Equal(t, sc.SignaturePolicyPath, "")
+ assert.Equal(t, sc.AuthFilePath, "")
+ assert.Equal(t, sc.DirForceCompress, false)
+ assert.Equal(t, sc.DockerRegistryUserAgent, fmt.Sprintf("libpod/%s", podmanVersion.Version))
+ assert.Equal(t, sc.BigFilesTemporaryDir, "/var/tmp")
+
+ oldtmpdir := os.Getenv("TMPDIR")
+ os.Setenv("TMPDIR", "/mnt")
+ sc = GetSystemContext("/tmp/foo", "/tmp/bar", true)
+ assert.Equal(t, sc.SignaturePolicyPath, "/tmp/foo")
+ assert.Equal(t, sc.AuthFilePath, "/tmp/bar")
+ assert.Equal(t, sc.DirForceCompress, true)
+ assert.Equal(t, sc.BigFilesTemporaryDir, "/mnt")
+ if oldtmpdir != "" {
+ os.Setenv("TMPDIR", oldtmpdir)
+ } else {
+ os.Unsetenv("TMPDIR")
+ }
+}
diff --git a/libpod/image/prune.go b/libpod/image/prune.go
index d6ae5feaf..12727901a 100644
--- a/libpod/image/prune.go
+++ b/libpod/image/prune.go
@@ -2,12 +2,12 @@ package image
import (
"context"
+ "strconv"
"strings"
- "time"
"github.com/containers/podman/v3/libpod/events"
"github.com/containers/podman/v3/pkg/domain/entities/reports"
- "github.com/containers/podman/v3/pkg/timetype"
+ "github.com/containers/podman/v3/pkg/util"
"github.com/containers/storage"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -16,42 +16,31 @@ import (
func generatePruneFilterFuncs(filter, filterValue string) (ImageFilter, error) {
switch filter {
case "label":
- var filterArray = strings.SplitN(filterValue, "=", 2)
- var filterKey = filterArray[0]
- if len(filterArray) > 1 {
- filterValue = filterArray[1]
- } else {
- filterValue = ""
- }
return func(i *Image) bool {
labels, err := i.Labels(context.Background())
if err != nil {
return false
}
- for labelKey, labelValue := range labels {
- if labelKey == filterKey && (filterValue == "" || labelValue == filterValue) {
- return true
- }
- }
- return false
+ return util.MatchLabelFilters([]string{filterValue}, labels)
}, nil
case "until":
- ts, err := timetype.GetTimestamp(filterValue, time.Now())
+ until, err := util.ComputeUntilTimestamp([]string{filterValue})
if err != nil {
return nil, err
}
- seconds, nanoseconds, err := timetype.ParseTimestamps(ts, 0)
- if err != nil {
- return nil, err
- }
- until := time.Unix(seconds, nanoseconds)
return func(i *Image) bool {
if !until.IsZero() && i.Created().After((until)) {
return true
}
return false
}, nil
+ case "dangling":
+ danglingImages, err := strconv.ParseBool(filterValue)
+ if err != nil {
+ return nil, errors.Wrapf(err, "invalid filter dangling=%s", filterValue)
+ }
+ return ImageFilter(DanglingFilter(danglingImages)), nil
}
return nil, nil
}
diff --git a/libpod/image/pull.go b/libpod/image/pull.go
index 58160b52f..6517fbd07 100644
--- a/libpod/image/pull.go
+++ b/libpod/image/pull.go
@@ -245,6 +245,7 @@ func (ir *Runtime) pullImageFromHeuristicSource(ctx context.Context, inputName s
sc.OSChoice = dockerOptions.OSChoice
sc.ArchitectureChoice = dockerOptions.ArchitectureChoice
sc.VariantChoice = dockerOptions.VariantChoice
+ sc.SystemRegistriesConfPath = dockerOptions.RegistriesConfPath
}
if signaturePolicyPath == "" {
sc.SignaturePolicyPath = ir.SignaturePolicyPath
@@ -306,7 +307,12 @@ func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goa
}
}()
- systemRegistriesConfPath := registries.SystemRegistriesConfPath()
+ var systemRegistriesConfPath string
+ if dockerOptions != nil && dockerOptions.RegistriesConfPath != "" {
+ systemRegistriesConfPath = dockerOptions.RegistriesConfPath
+ } else {
+ systemRegistriesConfPath = registries.SystemRegistriesConfPath()
+ }
var (
images []string
diff --git a/libpod/image/testdata/registries.conf b/libpod/image/testdata/registries.conf
new file mode 100644
index 000000000..16622a1ac
--- /dev/null
+++ b/libpod/image/testdata/registries.conf
@@ -0,0 +1,4 @@
+short-name-mode="enforcing"
+
+[aliases]
+"busybox"="docker.io/library/busybox"
diff --git a/libpod/network/netconflist.go b/libpod/network/netconflist.go
index b358bc530..08816f2bd 100644
--- a/libpod/network/netconflist.go
+++ b/libpod/network/netconflist.go
@@ -225,7 +225,7 @@ func IfPassesFilter(netconf *libcni.NetworkConfigList, filters map[string][]stri
case "label":
// matches all labels
- result = matchPruneLabelFilters(netconf, filterValues)
+ result = util.MatchLabelFilters(filterValues, GetNetworkLabels(netconf))
case "driver":
// matches only for the DefaultNetworkDriver
@@ -260,9 +260,9 @@ func IfPassesPruneFilter(config *config.Config, netconf *libcni.NetworkConfigLis
for key, filterValues := range f {
switch strings.ToLower(key) {
case "label":
- return matchPruneLabelFilters(netconf, filterValues), nil
+ return util.MatchLabelFilters(filterValues, GetNetworkLabels(netconf)), nil
case "until":
- until, err := util.ComputeUntilTimestamp(key, filterValues)
+ until, err := util.ComputeUntilTimestamp(filterValues)
if err != nil {
return false, err
}
@@ -280,29 +280,6 @@ func IfPassesPruneFilter(config *config.Config, netconf *libcni.NetworkConfigLis
return false, nil
}
-func matchPruneLabelFilters(netconf *libcni.NetworkConfigList, filterValues []string) bool {
- labels := GetNetworkLabels(netconf)
- result := true
-outer:
- for _, filterValue := range filterValues {
- filterArray := strings.SplitN(filterValue, "=", 2)
- filterKey := filterArray[0]
- if len(filterArray) > 1 {
- filterValue = filterArray[1]
- } else {
- filterValue = ""
- }
- for labelKey, labelValue := range labels {
- if labelKey == filterKey && (filterValue == "" || labelValue == filterValue) {
- result = true
- continue outer
- }
- }
- result = false
- }
- return result
-}
-
func getCreatedTimestamp(config *config.Config, netconf *libcni.NetworkConfigList) (*time.Time, error) {
networkConfigPath, err := GetCNIConfigPathByNameOrID(config, netconf.Name)
if err != nil {
diff --git a/libpod/options.go b/libpod/options.go
index 85862cc17..24e9d74f4 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1577,8 +1577,6 @@ func WithVolumeLabels(labels map[string]string) VolumeCreateOption {
}
// WithVolumeOptions sets the options of the volume.
-// If the "local" driver has been selected, options will be validated. There are
-// currently 3 valid options for the "local" driver - o, type, and device.
func WithVolumeOptions(options map[string]string) VolumeCreateOption {
return func(volume *Volume) error {
if volume.valid {
@@ -1587,13 +1585,6 @@ func WithVolumeOptions(options map[string]string) VolumeCreateOption {
volume.config.Options = make(map[string]string)
for key, value := range options {
- switch key {
- case "type", "device", "o", "UID", "GID":
- volume.config.Options[key] = value
- default:
- return errors.Wrapf(define.ErrInvalidArg, "unrecognized volume option %q is not supported with local driver", key)
- }
-
volume.config.Options[key] = value
}
@@ -1627,19 +1618,6 @@ func WithVolumeGID(gid int) VolumeCreateOption {
}
}
-// WithVolumeNeedsChown sets the NeedsChown flag for the volume.
-func WithVolumeNeedsChown() VolumeCreateOption {
- return func(volume *Volume) error {
- if volume.valid {
- return define.ErrVolumeFinalized
- }
-
- volume.state.NeedsChown = true
-
- return nil
- }
-}
-
// withSetAnon sets a bool notifying libpod that this volume is anonymous and
// should be removed when containers using it are removed and volumes are
// specified for removal.
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 19690d79b..537618b65 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -392,7 +392,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
logrus.Debugf("Creating new volume %s for container", vol.Name)
// The volume does not exist, so we need to create it.
- volOptions := []VolumeCreateOption{WithVolumeName(vol.Name), WithVolumeUID(ctr.RootUID()), WithVolumeGID(ctr.RootGID()), WithVolumeNeedsChown()}
+ volOptions := []VolumeCreateOption{WithVolumeName(vol.Name), WithVolumeUID(ctr.RootUID()), WithVolumeGID(ctr.RootGID())}
if isAnonymous {
volOptions = append(volOptions, withSetAnon())
}
diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go
index 13ac42e7d..b427125db 100644
--- a/libpod/runtime_img.go
+++ b/libpod/runtime_img.go
@@ -9,6 +9,7 @@ import (
"net/url"
"os"
+ buildahDefine "github.com/containers/buildah/define"
"github.com/containers/buildah/imagebuildah"
"github.com/containers/image/v5/directory"
"github.com/containers/image/v5/docker/reference"
@@ -165,7 +166,7 @@ func (r *Runtime) newImageBuildCompleteEvent(idOrName string) {
}
// Build adds the runtime to the imagebuildah call
-func (r *Runtime) Build(ctx context.Context, options imagebuildah.BuildOptions, dockerfiles ...string) (string, reference.Canonical, error) {
+func (r *Runtime) Build(ctx context.Context, options buildahDefine.BuildOptions, dockerfiles ...string) (string, reference.Canonical, error) {
if options.Runtime == "" {
// Make sure that build containers use the same runtime as Podman (see #9365).
conf := util.DefaultContainerConfig()
diff --git a/libpod/volume_internal.go b/libpod/volume_internal.go
index c1dbe00fd..694cdd149 100644
--- a/libpod/volume_internal.go
+++ b/libpod/volume_internal.go
@@ -17,6 +17,7 @@ func newVolume(runtime *Runtime) *Volume {
volume.config.Labels = make(map[string]string)
volume.config.Options = make(map[string]string)
volume.state.NeedsCopyUp = true
+ volume.state.NeedsChown = true
return volume
}
diff --git a/libpod/volume_internal_linux.go b/libpod/volume_internal_linux.go
index 67ac41874..92391de1d 100644
--- a/libpod/volume_internal_linux.go
+++ b/libpod/volume_internal_linux.go
@@ -32,8 +32,10 @@ func (v *Volume) mount() error {
return nil
}
- // We cannot mount volumes as rootless.
- if rootless.IsRootless() {
+ // We cannot mount 'local' volumes as rootless.
+ if !v.UsesVolumeDriver() && rootless.IsRootless() {
+ // This check should only be applied to 'local' driver
+ // so Volume Drivers must be excluded
return errors.Wrapf(define.ErrRootless, "cannot mount volumes without root privileges")
}
@@ -137,8 +139,8 @@ func (v *Volume) unmount(force bool) error {
return nil
}
- // We cannot unmount volumes as rootless.
- if rootless.IsRootless() {
+ // We cannot unmount 'local' volumes as rootless.
+ if !v.UsesVolumeDriver() && rootless.IsRootless() {
// If force is set, just clear the counter and bail without
// error, so we can remove volumes from the state if they are in
// an awkward configuration.