diff options
author | Daniel J Walsh <dwalsh@redhat.com> | 2021-08-02 10:19:58 -0400 |
---|---|---|
committer | Daniel J Walsh <dwalsh@redhat.com> | 2021-08-02 10:32:45 -0400 |
commit | c0952c73341321b309174a4e83e2e74d509b98a8 (patch) | |
tree | 3fb791087398345300156da8fb3f42664422f605 /libpod | |
parent | 0e2a7be0ec825449a1b95bd5df13e2519c67dcb4 (diff) | |
download | podman-c0952c73341321b309174a4e83e2e74d509b98a8.tar.gz podman-c0952c73341321b309174a4e83e2e74d509b98a8.tar.bz2 podman-c0952c73341321b309174a4e83e2e74d509b98a8.zip |
Support size and inode options on builtin volumes
[NO TESTS NEEDED] Since it is difficult to setup xfs quota
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1982164
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/options.go | 26 | ||||
-rw-r--r-- | libpod/runtime_volume_linux.go | 23 | ||||
-rw-r--r-- | libpod/volume.go | 4 | ||||
-rw-r--r-- | libpod/volume_internal.go | 3 | ||||
-rw-r--r-- | libpod/volume_internal_linux.go | 2 |
5 files changed, 56 insertions, 2 deletions
diff --git a/libpod/options.go b/libpod/options.go index 17a36008d..b021b9f50 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -1645,6 +1645,32 @@ func WithVolumeUID(uid int) VolumeCreateOption { } } +// WithVolumeSize sets the maximum size of the volume +func WithVolumeSize(size uint64) VolumeCreateOption { + return func(volume *Volume) error { + if volume.valid { + return define.ErrVolumeFinalized + } + + volume.config.Size = size + + return nil + } +} + +// WithVolumeInodes sets the maximum inodes of the volume +func WithVolumeInodes(inodes uint64) VolumeCreateOption { + return func(volume *Volume) error { + if volume.valid { + return define.ErrVolumeFinalized + } + + volume.config.Inodes = inodes + + return nil + } +} + // WithVolumeGID sets the GID that the volume will be created as. func WithVolumeGID(gid int) VolumeCreateOption { return func(volume *Volume) error { diff --git a/libpod/runtime_volume_linux.go b/libpod/runtime_volume_linux.go index 3d5bc8bb2..40df98d7c 100644 --- a/libpod/runtime_volume_linux.go +++ b/libpod/runtime_volume_linux.go @@ -12,6 +12,7 @@ import ( "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/events" volplugin "github.com/containers/podman/v3/libpod/plugin" + "github.com/containers/storage/drivers/quota" "github.com/containers/storage/pkg/stringid" pluginapi "github.com/docker/go-plugins-helpers/volume" "github.com/pkg/errors" @@ -68,7 +69,7 @@ func (r *Runtime) newVolume(ctx context.Context, options ...VolumeCreateOption) // Validate options for key := range volume.config.Options { switch key { - case "device", "o", "type", "UID", "GID": + case "device", "o", "type", "UID", "GID", "SIZE", "INODES": // Do nothing, valid keys default: return nil, errors.Wrapf(define.ErrInvalidArg, "invalid mount option %s for driver 'local'", key) @@ -106,6 +107,26 @@ func (r *Runtime) newVolume(ctx context.Context, options ...VolumeCreateOption) if err := LabelVolumePath(fullVolPath); err != nil { return nil, err } + projectQuotaSupported := false + + q, err := quota.NewControl(r.config.Engine.VolumePath) + if err == nil { + projectQuotaSupported = true + } + quota := quota.Quota{} + if volume.config.Size > 0 || volume.config.Inodes > 0 { + if !projectQuotaSupported { + return nil, errors.New("Volume options size and inodes not supported. Filesystem does not support Project Quota") + } + quota.Size = volume.config.Size + quota.Inodes = volume.config.Inodes + } + if projectQuotaSupported { + if err := q.SetQuota(fullVolPath, quota); err != nil { + return nil, errors.Wrapf(err, "failed to set size quota size=%d inodes=%d for volume directory %q", volume.config.Size, volume.config.Inodes, fullVolPath) + } + } + volume.config.MountPoint = fullVolPath } diff --git a/libpod/volume.go b/libpod/volume.go index 506c45b5a..8f3dc4fcc 100644 --- a/libpod/volume.go +++ b/libpod/volume.go @@ -49,6 +49,10 @@ type VolumeConfig struct { UID int `json:"uid"` // GID the volume will be created as. GID int `json:"gid"` + // Size maximum of the volume. + Size uint64 `json:"size"` + // Inodes maximum of the volume. + Inodes uint64 `json:"inodes"` } // VolumeState holds the volume's mutable state. diff --git a/libpod/volume_internal.go b/libpod/volume_internal.go index 19008a253..f69f1c044 100644 --- a/libpod/volume_internal.go +++ b/libpod/volume_internal.go @@ -49,6 +49,9 @@ func (v *Volume) needsMount() bool { if _, ok := v.config.Options["GID"]; ok { index++ } + if _, ok := v.config.Options["SIZE"]; ok { + index++ + } // when uid or gid is set there is also the "o" option // set so we have to ignore this one as well if index > 0 { diff --git a/libpod/volume_internal_linux.go b/libpod/volume_internal_linux.go index 92391de1d..45cd22385 100644 --- a/libpod/volume_internal_linux.go +++ b/libpod/volume_internal_linux.go @@ -104,7 +104,7 @@ func (v *Volume) mount() error { logrus.Debugf("Running mount command: %s %s", mountPath, strings.Join(mountArgs, " ")) if output, err := mountCmd.CombinedOutput(); err != nil { - logrus.Debugf("Mount failed with %v", err) + logrus.Debugf("Mount %v failed with %v", mountCmd, err) return errors.Wrapf(errors.Errorf(string(output)), "error mounting volume %s", v.Name()) } |