Add skript 'update_quota2_mariadb.sh'.
This commit is contained in:
Executable
+96
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Batch-update quota2 table for all active mailboxes from doveadm quota get."""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
DOVEADM = '/usr/local/dovecot/bin/doveadm'
|
||||
MYSQL = 'mysql'
|
||||
DB_USER = 'postfix'
|
||||
DB_PASS = 'T3CJnFMJNX9wmhNs'
|
||||
DB_SOCKET = '/run/mysqld/mysqld.sock'
|
||||
DB_NAME = 'postfix'
|
||||
|
||||
|
||||
def mysql_query(sql):
|
||||
return subprocess.run(
|
||||
[MYSQL, '-u', DB_USER, '-p' + DB_PASS, '--socket', DB_SOCKET,
|
||||
DB_NAME, '-sNe', sql],
|
||||
capture_output=True, text=True)
|
||||
|
||||
|
||||
def get_users(limit=None):
|
||||
query = 'SELECT username FROM mailbox WHERE active = 1 ORDER BY username;'
|
||||
if limit:
|
||||
query = 'SELECT username FROM mailbox WHERE active = 1 ORDER BY username LIMIT %d;' % limit
|
||||
r = mysql_query(query)
|
||||
return [u.strip() for u in r.stdout.strip().split('\n') if u.strip()]
|
||||
|
||||
|
||||
def get_quota(user):
|
||||
result = subprocess.run(
|
||||
[DOVEADM, 'quota', 'get', '-u', user],
|
||||
capture_output=True, text=True
|
||||
)
|
||||
bytes_val = None
|
||||
messages_val = None
|
||||
for line in result.stdout.splitlines():
|
||||
parts = line.split()
|
||||
if len(parts) < 4:
|
||||
continue
|
||||
if parts[2] == 'STORAGE' and parts[1] != 'Type':
|
||||
try:
|
||||
bytes_val = int(parts[3]) * 1024
|
||||
except ValueError:
|
||||
bytes_val = 0
|
||||
elif parts[2] == 'MESSAGE' and parts[1] != 'Type':
|
||||
try:
|
||||
messages_val = int(parts[3])
|
||||
except ValueError:
|
||||
messages_val = 0
|
||||
return bytes_val, messages_val
|
||||
|
||||
|
||||
def upsert_quota2(user, bytes_val, messages_val):
|
||||
sql = ("REPLACE INTO quota2 (username, bytes, messages) VALUES ('"
|
||||
+ user.replace("'", "\'") + "', "
|
||||
+ str(bytes_val) + ", " + str(messages_val) + ");")
|
||||
mysql_query(sql)
|
||||
|
||||
|
||||
def main():
|
||||
dry_run = '--dry-run' in sys.argv
|
||||
limit = None
|
||||
if '--limit' in sys.argv:
|
||||
idx = sys.argv.index('--limit')
|
||||
try:
|
||||
limit = int(sys.argv[idx + 1])
|
||||
except (IndexError, ValueError):
|
||||
print('Usage: update_quota2.sh [--dry-run] [--limit N]')
|
||||
sys.exit(1)
|
||||
|
||||
users = get_users(limit)
|
||||
total = len(users)
|
||||
print('Processing %d mailboxes...' % total)
|
||||
|
||||
ok = 0
|
||||
skip = 0
|
||||
for i, user in enumerate(users, 1):
|
||||
bytes_val, messages_val = get_quota(user)
|
||||
if bytes_val is None or messages_val is None:
|
||||
print(' [%d/%d] SKIP %s (no quota data)' % (i, total, user))
|
||||
skip += 1
|
||||
continue
|
||||
if dry_run:
|
||||
print(' [%d/%d] DRY %s: %d bytes, %d messages' % (i, total, user, bytes_val, messages_val))
|
||||
else:
|
||||
upsert_quota2(user, bytes_val, messages_val)
|
||||
if i % 50 == 0 or i == total:
|
||||
print(' [%d/%d] done' % (i, total))
|
||||
ok += 1
|
||||
|
||||
print('Done: %d updated, %d skipped.' % (ok, skip))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user