Skip to main content

A Python wrapper for Linux quotactl(2) APIs

Project description

PyQuota

PyQuota is a Python wrapper for the Linux quotactl(2) APIs.

Requirements

  • Linux with quota support (kernel built with CONFIG_QUOTA)
  • Privilege: root or CAP_SYS_ADMIN for quota operations
  • Kernel: >= 2.4.22; project quota requires >= 4.1; Q_GETNEXTQUOTA requires >= 4.6

XFS-specific quotactl commands (e.g. Q_XQUOTAON) are not supported.

Future work: Linux 5.13+ adds quotactl_fd(), which uses a file descriptor instead of a device path (useful for filesystems without a block device, e.g. UBIFS). This wrapper does not yet support it.

Breaking changes (current release)

  • get_user_quota, get_next_user_quota, get_user_quota_info (and group/project) always return named tuples (Quota, NextQuota, QuotaInfo). The return_type parameter has been removed; results are tuple-compatible (indexing, unpacking).
  • get_user_quota_named and other *_named functions are removed; use the corresponding get_*.
  • get_user_quota_with_valid and other *_with_valid functions are replaced by get_*_quota_partial (and get_*_quota_info_partial), which return named tuples only (QuotaPartial, NextQuotaPartial, QuotaInfoPartial) with optional fields as None when not set.
  • QFMT_VFS_OLD, QFMT_VFS_V0, QFMT_VFS_V1 are no longer exported. Use QuotaFormat.VFS_OLD, QuotaFormat.VFS_V0, QuotaFormat.VFS_V1 for quota_on and for comparing with get_*_quota_format() return value.
  • DQF_ROOT_SQUASH, DQF_SYS_FILE are no longer exported. Use QuotaInfoFlags.ROOT_SQUASH, QuotaInfoFlags.SYS_FILE for set_*_quota_info(..., flags=...) (combine with |).
  • EACCES, EPERM, and other errno constants are no longer exported. Use QuotaErrno.EACCES, QuotaErrno.EPERM, etc. for comparing with APIError.errno.

Installation

pip install pyquota

From source (build deps: Python development headers, C compiler):

git clone https://github.com/tjumyk/pyquota.git && cd pyquota
pip install -e .

Units

  • Block limits (block_hard_limit, block_soft_limit): in 1024-byte disk quota blocks (quotactl(2))
  • Current block usage (block_current): in bytes
  • Inode limits/current: inodes (count)
  • Grace periods (block_grace, inode_grace in QuotaInfo): in seconds before soft limit becomes hard
  • Time limits (block_time, inode_time in Quota): Unix timestamps (seconds since epoch) when grace expires, or 0 if not over soft limit

API overview

quotactl command User quota Group quota Project quota
Q_QUOTAON user_quota_on group_quota_on project_quota_on
Q_QUOTAOFF user_quota_off group_quota_off project_quota_off
Q_GETQUOTA get_user_quota get_group_quota get_project_quota
Q_GETNEXTQUOTA get_next_user_quota get_next_group_quota get_next_project_quota
Q_SETQUOTA set_user_quota set_group_quota set_project_quota
Q_GETINFO get_user_quota_info get_group_quota_info get_project_quota_info
Q_SETINFO set_user_quota_info set_group_quota_info set_project_quota_info
Q_GETFMT get_user_quota_format get_group_quota_format get_project_quota_format
Q_SYNC sync_user_quotas sync_group_quotas sync_project_quotas

Return type: get_*_quota, get_next_*_quota, and get_*_quota_info return named tuples (Quota, NextQuota, QuotaInfo), which are tuple-compatible (indexing and unpacking work). QuotaInfo has .root_squash and .sys_file properties; use QuotaInfoFlags (IntEnum: ROOT_SQUASH, SYS_FILE) for set_*_quota_info(..., flags=...) (combine with |). iter_user_quotas(device, start_uid=0) (and iter_group_quotas, iter_project_quotas) yield NextQuota for each ID with quota; they use get_next_* under the hood, so get_next_* remains the primitive for a single "next" query. QuotaFormat (IntEnum: VFS_OLD, VFS_V0, VFS_V1) can be used for quota_on / format checks. Errors raised from the public API have .device and .id set when applicable. set_*_quota validates that limits are non-negative ints.

Partial validity: When the kernel may return incomplete data, use get_*_quota_partial or get_*_quota_info_partial. They return named tuples (QuotaPartial, etc.) where fields the kernel did not set are None (interpreted from the kernel’s valid mask per man 2 quotactl). Use e.g. if q.block_hard_limit is not None:. According to the man page, the kernel currently always fills all fields and sets the valid mask to QIF_ALL/IIF_ALL on get; the valid mask is used on set to indicate which fields the caller provides. The partial API exists for forward compatibility if a kernel ever returns incomplete data.

Usage

import pyquota as pq

# Turn on user quota for a filesystem (QuotaFormat)
pq.user_quota_on("/dev/sda1", pq.QuotaFormat.VFS_V0, "/aquota.user")

# Turn off user quota
pq.user_quota_off("/dev/sda1")

# Get quota (returns Quota named tuple; tuple-compatible)
quota = pq.get_user_quota("/dev/sda1", 1000)
print(quota.block_hard_limit, quota.block_current)

# Get next user with quota (kernel >= 4.6), or iterate all
next_quota = pq.get_next_user_quota("/dev/sda1", 1000)  # next_quota.id is the uid
for nq in pq.iter_user_quotas("/dev/sda1"):
    print(nq.id, nq.block_current)

# Set user quota (hard 100MB, soft 90MB, no inode limits)
pq.set_user_quota("/dev/sda1", 1000, 102400, 92160, 0, 0)

# Or take the four limit fields from a Quota (e.g. from get_user_quota)
q = pq.get_user_quota("/dev/sda1", 1000)
pq.set_user_quota("/dev/sda1", 1000, limits_from=q)

# Quotafile info (tuple-like; .root_squash and .sys_file for flags)
info = pq.get_user_quota_info("/dev/sda1")
print(info.block_grace, info.inode_grace)
print(info.root_squash, info.sys_file)

pq.set_user_quota_info("/dev/sda1", 604800, 604800, 0)  # 1 week grace, no flags

# Format: compare with QuotaFormat.VFS_OLD, .VFS_V0, .VFS_V1
fmt = pq.get_user_quota_format("/dev/sda1")

# Sync quota usage to disk
pq.sync_user_quotas("/dev/sda1")
pq.sync_user_quotas(None)  # all filesystems with active user quotas

Replace user with group or project for group/project quotas. Project quota requires kernel >= 4.1.

Error handling

Errors from the C API are raised as pyquota.APIError (or a subclass) with messages matching the quotactl(2) ERRORS section. Each instance has an errno attribute; compare with QuotaErrno (IntEnum: EACCES, EPERM, ENOENT, etc.). When raised from the public API (get/set/iter, quota_on/off, etc.), device and id are set when applicable. Subclasses: PermissionError (EPERM), NotFoundError (ENOENT, ESRCH), InvalidError (EINVAL, etc.); catch pq.APIError or use e.errno.

import pyquota as pq

try:
    pq.get_user_quota("/dev/sda1", 1000)
except pq.PermissionError:
    print("Need root or CAP_SYS_ADMIN")
except pq.NotFoundError as e:
    print("Not found:", e)
except pq.APIError as e:
    print(e, "errno:", e.errno)
    if e.errno == pq.QuotaErrno.EPERM:
        print("Permission denied")

Invalid arguments (e.g. empty device path, negative ID, non-int or negative limits in set_*_quota) raise ValueError or TypeError before calling the kernel.

Reference

See the man page for detailed semantics of each command. Type stubs (.pyi) are provided for IDE completion and type checkers. API documentation is built with Sphinx and published at https://tjumyk.github.io/pyquota/ when available.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyquota-0.1.3.tar.gz (19.0 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pyquota-0.1.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (40.3 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

pyquota-0.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (37.1 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ i686manylinux: glibc 2.5+ i686

pyquota-0.1.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (42.0 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

pyquota-0.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (39.2 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ i686manylinux: glibc 2.5+ i686

pyquota-0.1.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (42.0 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

pyquota-0.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (39.2 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ i686manylinux: glibc 2.5+ i686

pyquota-0.1.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (41.6 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

pyquota-0.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (38.9 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ i686manylinux: glibc 2.5+ i686

File details

Details for the file pyquota-0.1.3.tar.gz.

File metadata

  • Download URL: pyquota-0.1.3.tar.gz
  • Upload date:
  • Size: 19.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyquota-0.1.3.tar.gz
Algorithm Hash digest
SHA256 334053a8945669f5fcf06db148d504b8f5013b9a7abddd94e8217be2813c7cf5
MD5 be1691f7d6ded39551e6fe6d8623239a
BLAKE2b-256 3e017f7be898e15e53e21fcff21c97050ef1492a918f5a0de083a44fcb8f4aec

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyquota-0.1.3.tar.gz:

Publisher: publish.yml on tjumyk/pyquota

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyquota-0.1.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyquota-0.1.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 bca505d3c2a5f00f259d622fc36ce66e9cd37be96010c8623b3deba35bd8ebd9
MD5 384dc9b2709688582372afd1ce3af0b5
BLAKE2b-256 fa10bc38a70306ed3cae5acde2fa42d17e68faea975f7686efde4e9a06ab3719

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyquota-0.1.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on tjumyk/pyquota

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyquota-0.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for pyquota-0.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 00a6dae9ae8c9961f252a1c4b906db65dc4ebe5a9b5e2f2147fc6d650a50553f
MD5 6df3799a47ef44f1f5f06d0be5fbf3c6
BLAKE2b-256 3021d2acf946a6fed3d48a736471beb42b03493e6d4fe4cbefdb3a2ba3cf7c54

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyquota-0.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl:

Publisher: publish.yml on tjumyk/pyquota

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyquota-0.1.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyquota-0.1.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5e02eb1af0c9bfcd54b054f54848b471670cebb2ade6ca8315265f1e4532e819
MD5 d5d9fdb96ebb2bf37c69cbabf69c5d2f
BLAKE2b-256 dd96d906e23a5ed59139e8ced2714006f82c070f9114b4dd92d51e886cb1ea38

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyquota-0.1.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on tjumyk/pyquota

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyquota-0.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for pyquota-0.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 01ed6f77a31de308046e9e0963ef7f379282dc5252735a586401339dbc3eccbd
MD5 3b909443158ae1093deee6fd6d154405
BLAKE2b-256 809efc932619bb23aa1f08f55281fab56f7cbaade75200256af9411b7350a7c4

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyquota-0.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl:

Publisher: publish.yml on tjumyk/pyquota

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyquota-0.1.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyquota-0.1.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 3775d416c9911bb9881d60168631c2d51a5ad5198a0da0ca320711ebcd82a1ac
MD5 e559537511e9ac96c02b273997c07048
BLAKE2b-256 47771f6508c4eef0ce47e7cb8ae7936fbf426f2843f198892c62f474d7072f19

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyquota-0.1.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on tjumyk/pyquota

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyquota-0.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for pyquota-0.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 767bcdd669ed9a3c9526b86ba2e39d7b2921ad398192571ca6f3d7038ae884b2
MD5 746b871d9c2564c061b8304595c7a813
BLAKE2b-256 10fd0d96a19f35848d73c118eaf30e3666ad39a8d40445cbfe6a2f4ca5617b50

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyquota-0.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl:

Publisher: publish.yml on tjumyk/pyquota

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyquota-0.1.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyquota-0.1.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5148bd51aa8fe549ca6f587cda82a87a10bfc614c3fb029da8ad5fd39a73f868
MD5 9ebcbfc5cd48fb666efa62258ba8b27b
BLAKE2b-256 2c547e0a056d9a1a86fd816d1baa911964da6cd8bdc3cf379fa0a96b358fcdcc

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyquota-0.1.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on tjumyk/pyquota

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyquota-0.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for pyquota-0.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 4710478a138c7b776e2b755ad42f598cb116f4b3699b8610bdf10979a62cdbbf
MD5 668634a5bb2434b97361816c8d7cf143
BLAKE2b-256 c7eb2b675273cc8b59b2fdb05dd6f57bcc3853ff2984b69dc9869a3d95818e4b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyquota-0.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl:

Publisher: publish.yml on tjumyk/pyquota

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page