diff options
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container_internal_linux.go | 14 | ||||
-rw-r--r-- | libpod/image/filters.go | 14 | ||||
-rw-r--r-- | libpod/image/prune.go | 24 | ||||
-rw-r--r-- | libpod/kube.go | 32 | ||||
-rw-r--r-- | libpod/network/netconflist.go | 29 | ||||
-rw-r--r-- | libpod/oci_conmon_linux.go | 5 | ||||
-rw-r--r-- | libpod/options.go | 9 | ||||
-rw-r--r-- | libpod/runtime_img.go | 18 | ||||
-rw-r--r-- | libpod/volume_internal_linux.go | 10 |
9 files changed, 71 insertions, 84 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 24319f4b5..94c6c3840 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -1503,16 +1503,24 @@ func (c *Container) makeBindMounts() error { } // Make /etc/localtime - if c.Timezone() != "" { + ctrTimezone := c.Timezone() + if ctrTimezone != "" { + // validate the format of the timezone specified if it's not "local" + if ctrTimezone != "local" { + _, err = time.LoadLocation(ctrTimezone) + if err != nil { + return errors.Wrapf(err, "error finding timezone for container %s", c.ID()) + } + } if _, ok := c.state.BindMounts["/etc/localtime"]; !ok { var zonePath string - if c.Timezone() == "local" { + if ctrTimezone == "local" { zonePath, err = filepath.EvalSymlinks("/etc/localtime") if err != nil { return errors.Wrapf(err, "error finding local timezone for container %s", c.ID()) } } else { - zone := filepath.Join("/usr/share/zoneinfo", c.Timezone()) + zone := filepath.Join("/usr/share/zoneinfo", ctrTimezone) zonePath, err = filepath.EvalSymlinks(zone) if err != nil { return errors.Wrapf(err, "error setting timezone for container %s", c.ID()) 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/prune.go b/libpod/image/prune.go index d6ae5feaf..7ee3e077e 100644 --- a/libpod/image/prune.go +++ b/libpod/image/prune.go @@ -3,11 +3,10 @@ package image import ( "context" "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,36 +15,19 @@ 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()) - if err != nil { - return nil, err - } - seconds, nanoseconds, err := timetype.ParseTimestamps(ts, 0) + until, err := util.ComputeUntilTimestamp([]string{filterValue}) 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 diff --git a/libpod/kube.go b/libpod/kube.go index 407c4ae00..b4dd4f10a 100644 --- a/libpod/kube.go +++ b/libpod/kube.go @@ -330,8 +330,6 @@ func containerToV1Container(c *Container) (v1.Container, []v1.Volume, *v1.PodDNS } if len(c.config.UserVolumes) > 0 { - // TODO When we until we can resolve what the volume name should be, this is disabled - // Volume names need to be coordinated "globally" in the kube files. volumeMounts, volumes, err := libpodMountsToKubeVolumeMounts(c) if err != nil { return kubeContainer, kubeVolumes, nil, err @@ -493,8 +491,7 @@ func libpodEnvVarsToKubeEnvVars(envs []string) ([]v1.EnvVar, error) { // libpodMountsToKubeVolumeMounts converts the containers mounts to a struct kube understands func libpodMountsToKubeVolumeMounts(c *Container) ([]v1.VolumeMount, []v1.Volume, error) { - // TODO when named volumes are supported in play kube, also parse named volumes here - _, mounts := c.sortUserVolumes(c.config.Spec) + namedVolumes, mounts := c.sortUserVolumes(c.config.Spec) vms := make([]v1.VolumeMount, 0, len(mounts)) vos := make([]v1.Volume, 0, len(mounts)) for _, m := range mounts { @@ -505,9 +502,34 @@ func libpodMountsToKubeVolumeMounts(c *Container) ([]v1.VolumeMount, []v1.Volume vms = append(vms, vm) vos = append(vos, vo) } + for _, v := range namedVolumes { + vm, vo := generateKubePersistentVolumeClaim(v) + vms = append(vms, vm) + vos = append(vos, vo) + } return vms, vos, nil } +// generateKubePersistentVolumeClaim converts a ContainerNamedVolume to a Kubernetes PersistentVolumeClaim +func generateKubePersistentVolumeClaim(v *ContainerNamedVolume) (v1.VolumeMount, v1.Volume) { + ro := util.StringInSlice("ro", v.Options) + + // To avoid naming conflicts with any host path mounts, add a unique suffix to the volume's name. + name := v.Name + "-pvc" + + vm := v1.VolumeMount{} + vm.Name = name + vm.MountPath = v.Dest + vm.ReadOnly = ro + + pvc := v1.PersistentVolumeClaimVolumeSource{ClaimName: v.Name, ReadOnly: ro} + vs := v1.VolumeSource{} + vs.PersistentVolumeClaim = &pvc + vo := v1.Volume{Name: name, VolumeSource: vs} + + return vm, vo +} + // generateKubeVolumeMount takes a user specified mount and returns // a kubernetes VolumeMount (to be added to the container) and a kubernetes Volume // (to be added to the pod) @@ -519,6 +541,8 @@ func generateKubeVolumeMount(m specs.Mount) (v1.VolumeMount, v1.Volume, error) { if err != nil { return vm, vo, err } + // To avoid naming conflicts with any persistent volume mounts, add a unique suffix to the volume's name. + name += "-host" vm.Name = name vm.MountPath = m.Destination if util.StringInSlice("ro", m.Options) { 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/oci_conmon_linux.go b/libpod/oci_conmon_linux.go index ef5f6fb0c..1c7089e5d 100644 --- a/libpod/oci_conmon_linux.go +++ b/libpod/oci_conmon_linux.go @@ -1268,7 +1268,10 @@ func prepareProcessExec(c *Container, options *ExecOptions, env []string, sessio return nil, err } - allCaps := capabilities.AllCapabilities() + allCaps, err := capabilities.BoundingSet() + if err != nil { + return nil, err + } if options.Privileged { pspec.Capabilities.Bounding = allCaps } else { diff --git a/libpod/options.go b/libpod/options.go index ffdb5abbf..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 } diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go index 90b11f8ca..13ac42e7d 100644 --- a/libpod/runtime_img.go +++ b/libpod/runtime_img.go @@ -313,15 +313,23 @@ func (r *Runtime) LoadImageFromSingleImageArchive(ctx context.Context, writer io func() (types.ImageReference, error) { return layout.NewReference(inputFile, "") }, + func() (types.ImageReference, error) { + // This item needs to be last to break out of loop and report meaningful error message + return nil, + errors.New("payload does not match any of the supported image formats (oci-archive, oci-dir, docker-archive, docker-dir)") + }, } { src, err := referenceFn() - if err == nil && src != nil { - newImages, err := r.ImageRuntime().LoadFromArchiveReference(ctx, src, signaturePolicy, writer) - if err == nil { - return getImageNames(newImages), nil - } + if err != nil { saveErr = err + continue + } + + newImages, err := r.ImageRuntime().LoadFromArchiveReference(ctx, src, signaturePolicy, writer) + if err == nil { + return getImageNames(newImages), nil } + saveErr = err } return "", errors.Wrapf(saveErr, "error pulling image") } 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. |