mirror of
https://github.com/containers/podman.git
synced 2025-05-22 17:46:52 +08:00
Merge pull request #14051 from giuseppe/volume-create-noquota-option
volume: add new option -o o=noquota
This commit is contained in:
@ -38,7 +38,8 @@ The `device` option sets the device to be mounted, and is equivalent to the `dev
|
|||||||
The `o` option sets options for the mount, and is equivalent to the `-o` flag to **mount(8)** with these exceptions:
|
The `o` option sets options for the mount, and is equivalent to the `-o` flag to **mount(8)** with these exceptions:
|
||||||
|
|
||||||
- The `o` option supports `uid` and `gid` options to set the UID and GID of the created volume that are not normally supported by **mount(8)**.
|
- The `o` option supports `uid` and `gid` options to set the UID and GID of the created volume that are not normally supported by **mount(8)**.
|
||||||
- The `o` option supports the `size` option to set the maximum size of the created volume and the `inodes` option to set the maximum number of inodes for the volume. Currently these flags are only supported on "xfs" file system mounted with the `prjquota` flag described in the **xfs_quota(8)** man page.
|
- The `o` option supports the `size` option to set the maximum size of the created volume, the `inodes` option to set the maximum number of inodes for the volume and `noquota` to completely disable quota support even for tracking of disk usage. Currently these flags are only supported on "xfs" file system mounted with the `prjquota` flag described in the **xfs_quota(8)** man page.
|
||||||
|
- The `o` option supports .
|
||||||
- Using volume options other then the UID/GID options with the **local** driver requires root privileges.
|
- Using volume options other then the UID/GID options with the **local** driver requires root privileges.
|
||||||
|
|
||||||
When not using the **local** driver, the given options are passed directly to the volume plugin. In this case, supported options are dictated by the plugin in question, not Podman.
|
When not using the **local** driver, the given options are passed directly to the volume plugin. In this case, supported options are dictated by the plugin in question, not Podman.
|
||||||
|
@ -1634,6 +1634,19 @@ func WithVolumeNoChown() VolumeCreateOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithVolumeDisableQuota prevents the volume from being assigned a quota.
|
||||||
|
func WithVolumeDisableQuota() VolumeCreateOption {
|
||||||
|
return func(volume *Volume) error {
|
||||||
|
if volume.valid {
|
||||||
|
return define.ErrVolumeFinalized
|
||||||
|
}
|
||||||
|
|
||||||
|
volume.config.DisableQuota = true
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// withSetAnon sets a bool notifying libpod that this volume is anonymous and
|
// withSetAnon sets a bool notifying libpod that this volume is anonymous and
|
||||||
// should be removed when containers using it are removed and volumes are
|
// should be removed when containers using it are removed and volumes are
|
||||||
// specified for removal.
|
// specified for removal.
|
||||||
|
@ -73,7 +73,7 @@ func (r *Runtime) newVolume(options ...VolumeCreateOption) (_ *Volume, deferredE
|
|||||||
return nil, errors.Wrapf(err, "invalid volume option %s for driver 'local'", key)
|
return nil, errors.Wrapf(err, "invalid volume option %s for driver 'local'", key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "o", "type", "uid", "gid", "size", "inodes":
|
case "o", "type", "uid", "gid", "size", "inodes", "noquota":
|
||||||
// Do nothing, valid keys
|
// Do nothing, valid keys
|
||||||
default:
|
default:
|
||||||
return nil, errors.Wrapf(define.ErrInvalidArg, "invalid mount option %s for driver 'local'", key)
|
return nil, errors.Wrapf(define.ErrInvalidArg, "invalid mount option %s for driver 'local'", key)
|
||||||
@ -111,8 +111,12 @@ func (r *Runtime) newVolume(options ...VolumeCreateOption) (_ *Volume, deferredE
|
|||||||
if err := LabelVolumePath(fullVolPath); err != nil {
|
if err := LabelVolumePath(fullVolPath); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if volume.config.DisableQuota {
|
||||||
|
if volume.config.Size > 0 || volume.config.Inodes > 0 {
|
||||||
|
return nil, errors.New("volume options size and inodes cannot be used without quota")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
projectQuotaSupported := false
|
projectQuotaSupported := false
|
||||||
|
|
||||||
q, err := quota.NewControl(r.config.Engine.VolumePath)
|
q, err := quota.NewControl(r.config.Engine.VolumePath)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
projectQuotaSupported = true
|
projectQuotaSupported = true
|
||||||
@ -120,7 +124,7 @@ func (r *Runtime) newVolume(options ...VolumeCreateOption) (_ *Volume, deferredE
|
|||||||
quota := quota.Quota{}
|
quota := quota.Quota{}
|
||||||
if volume.config.Size > 0 || volume.config.Inodes > 0 {
|
if volume.config.Size > 0 || volume.config.Inodes > 0 {
|
||||||
if !projectQuotaSupported {
|
if !projectQuotaSupported {
|
||||||
return nil, errors.New("Volume options size and inodes not supported. Filesystem does not support Project Quota")
|
return nil, errors.New("volume options size and inodes not supported. Filesystem does not support Project Quota")
|
||||||
}
|
}
|
||||||
quota.Size = volume.config.Size
|
quota.Size = volume.config.Size
|
||||||
quota.Inodes = volume.config.Inodes
|
quota.Inodes = volume.config.Inodes
|
||||||
@ -130,6 +134,7 @@ func (r *Runtime) newVolume(options ...VolumeCreateOption) (_ *Volume, deferredE
|
|||||||
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)
|
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
|
volume.config.MountPoint = fullVolPath
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,9 @@ type VolumeConfig struct {
|
|||||||
Size uint64 `json:"size"`
|
Size uint64 `json:"size"`
|
||||||
// Inodes maximum of the volume.
|
// Inodes maximum of the volume.
|
||||||
Inodes uint64 `json:"inodes"`
|
Inodes uint64 `json:"inodes"`
|
||||||
|
// DisableQuota indicates that the volume should completely disable using any
|
||||||
|
// quota tracking.
|
||||||
|
DisableQuota bool `json:"disableQuota,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// VolumeState holds the volume's mutable state.
|
// VolumeState holds the volume's mutable state.
|
||||||
|
@ -52,6 +52,9 @@ func (v *Volume) needsMount() bool {
|
|||||||
if _, ok := v.config.Options["SIZE"]; ok {
|
if _, ok := v.config.Options["SIZE"]; ok {
|
||||||
index++
|
index++
|
||||||
}
|
}
|
||||||
|
if _, ok := v.config.Options["NOQUOTA"]; ok {
|
||||||
|
index++
|
||||||
|
}
|
||||||
// when uid or gid is set there is also the "o" option
|
// when uid or gid is set there is also the "o" option
|
||||||
// set so we have to ignore this one as well
|
// set so we have to ignore this one as well
|
||||||
if index > 0 {
|
if index > 0 {
|
||||||
|
@ -73,6 +73,11 @@ func VolumeOptions(opts map[string]string) ([]libpod.VolumeCreateOption, error)
|
|||||||
finalVal = append(finalVal, o)
|
finalVal = append(finalVal, o)
|
||||||
// set option "GID": "$gid"
|
// set option "GID": "$gid"
|
||||||
volumeOptions["GID"] = splitO[1]
|
volumeOptions["GID"] = splitO[1]
|
||||||
|
case "noquota":
|
||||||
|
logrus.Debugf("Removing noquota from options and adding WithVolumeDisableQuota")
|
||||||
|
libpodOptions = append(libpodOptions, libpod.WithVolumeDisableQuota())
|
||||||
|
// set option "NOQUOTA": "true"
|
||||||
|
volumeOptions["NOQUOTA"] = "true"
|
||||||
default:
|
default:
|
||||||
finalVal = append(finalVal, o)
|
finalVal = append(finalVal, o)
|
||||||
}
|
}
|
||||||
|
@ -309,6 +309,28 @@ else
|
|||||||
echo "Overlay test within limits failed"
|
echo "Overlay test within limits failed"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
before=`xfs_quota -x -c 'report -N -p' $TMPDIR | grep -c ^#`
|
||||||
|
podman $PODMANBASE volume create -o o=noquota test-no-quota
|
||||||
|
after=`xfs_quota -x -c 'report -N -p' $TMPDIR | grep -c ^#`
|
||||||
|
|
||||||
|
if [ $before != $after ];
|
||||||
|
then
|
||||||
|
echo "Test -o=noquota doesn't create a projid failed"
|
||||||
|
else
|
||||||
|
echo "Test -o=noquota doesn't create a projid passed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
before=`xfs_quota -x -c 'report -N -p' $TMPDIR | grep -c ^#`
|
||||||
|
podman $PODMANBASE volume create -o test-no-quota
|
||||||
|
after=`xfs_quota -x -c 'report -N -p' $TMPDIR | grep -c ^#`
|
||||||
|
|
||||||
|
if [ $before == $after ];
|
||||||
|
then
|
||||||
|
echo "Test without -o=noquota creates a projid failed"
|
||||||
|
else
|
||||||
|
echo "Test without -o=noquota creates a projid passed"
|
||||||
|
fi
|
||||||
|
|
||||||
########
|
########
|
||||||
# Expected to fail
|
# Expected to fail
|
||||||
########
|
########
|
||||||
|
Reference in New Issue
Block a user