Compare commits

...

3 Commits

2 changed files with 204 additions and 3 deletions
+96 -3
View File
@@ -1182,21 +1182,114 @@ else
echo_ok echo_ok
fi fi
echononl "\tMake file composer.json writable.."
chown ${HTTP_USER} ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION}/composer.json > $log_file 2>&1
if [[ $? -eq 0 ]]; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "\tcontinue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/nno]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Script terminated by user input.."
fi
echononl "\tCreate composer.lock file.."
if [[ ${PF_ADMIN_MAJOR_VERSION} -gt 3 ]] ; then
if $PHP_DEBIAN_INSTALLATION ; then
su ${HTTP_USER} -s /bin/bash -c "cd ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION} && \
php /usr/local/bin/composer config --json \
policy.advisories.ignore-id '[\"PKSA-qv5y-crcz-9nxw\",\"PKSA-kbc7-dq62-pt7d\"]'" \
> $log_file 2>&1
else
su ${HTTP_USER} -s /bin/bash -c "cd ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION} && \
/usr/local/php-${php_latest_ver}/bin/php /usr/local/bin/composer config --json \
policy.advisories.ignore-id '[\"PKSA-qv5y-crcz-9nxw\",\"PKSA-kbc7-dq62-pt7d\"]'" \
> $log_file 2>&1
fi
if [[ $? -eq 0 ]]; then
echo_ok
else
echo_failed
echo ""
echo -e "\tCommand was: "
if $PHP_DEBIAN_INSTALLATION ; then
cat <<EOF
su ${HTTP_USER} -s /bin/bash -c "cd ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION} && \
php /usr/local/bin/composer config --json \
policy.advisories.ignore-id '[\"PKSA-qv5y-crcz-9nxw\",\"PKSA-kbc7-dq62-pt7d\"]'" \
> $log_file 2>&1
EOF
else
cat <<EOF
su ${HTTP_USER} -s /bin/bash -c "cd ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION} && \
/usr/local/php-${php_latest_ver}/bin/php /usr/local/bin/composer config --json \
policy.advisories.ignore-id '[\"PKSA-qv5y-crcz-9nxw\",\"PKSA-kbc7-dq62-pt7d\"]'" \
> $log_file 2>&1
EOF
fi
echo ""
error "$(cat $log_file)"
echononl "\tcontinue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/nno]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Script terminated by user input.."
fi
fi
echononl "\tInstall PHP dependencies ( composer install --no-dev ... ).." echononl "\tInstall PHP dependencies ( composer install --no-dev ... ).."
if [[ ${PF_ADMIN_MAJOR_VERSION} -gt 3 ]] ; then if [[ ${PF_ADMIN_MAJOR_VERSION} -gt 3 ]] ; then
if $PHP_DEBIAN_INSTALLATION ; then if $PHP_DEBIAN_INSTALLATION ; then
su ${HTTP_USER} -c"cd ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION} su ${HTTP_USER} -c"cd ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION} && \
php /usr/local/bin/composer install --prefer-dist --no-interaction --no-dev" -s /bin/bash \ php /usr/local/bin/composer install --prefer-dist --no-interaction --no-dev" -s /bin/bash \
> $log_file 2>&1 > $log_file 2>&1
else else
su ${HTTP_USER} -c"cd ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION} su ${HTTP_USER} -c"cd ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION} && \
/usr/local/php-${php_latest_ver}/bin/php /usr/local/bin/composer --prefer-dist \ /usr/local/php-${php_latest_ver}/bin/php /usr/local/bin/composer --prefer-dist \
--no-interaction install --no-dev" -s /bin/bash > $log_file 2>&1 --no-interaction install --no-dev" -s /bin/bash > $log_file 2>&1
fi fi
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
echo_ok echo_ok
else else
echo_failed echo_failed
echo ""
echo -e "\tCommand was: "
if $PHP_DEBIAN_INSTALLATION ; then
cat <<EOF
su ${HTTP_USER} -c"cd ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION} && \\
php /usr/local/bin/composer --prefer-dist --no-interaction install --no-dev" -s /bin/bash \\
> $log_file 2>&1
EOF
else
cat <<EOF
su ${HTTP_USER} -c"cd ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION} && \\
/usr/local/php-${php_latest_ver}/bin/php /usr/local/bin/composer --prefer-dist \\
--no-interaction install --no-dev" -s /bin/bash > $log_file 2>&1
EOF
fi
echo ""
error "$(cat $log_file)" error "$(cat $log_file)"
echononl "\tcontinue anyway [yes/no]: " echononl "\tcontinue anyway [yes/no]: "
+108
View File
@@ -0,0 +1,108 @@
#!/usr/bin/env python3
"""
Batch-update the quota2 table for all active mailboxes.
Uses 'doveadm quota get' (must run as root) to read current usage and
writes it to quota2 via INSERT ... ON CONFLICT DO UPDATE.
Usage:
update_quota2.sh [--dry-run] [--limit N]
Options:
--dry-run Print what would be done without touching the database.
--limit N Process only the first N mailboxes (useful for testing).
"""
import subprocess
import sys
DOVEADM = '/usr/local/dovecot/bin/doveadm'
PSQL = 'psql'
DB_USER = 'postfix'
DB_NAME = 'postfix'
def get_users(limit=None):
query = 'SELECT username FROM mailbox WHERE active = true ORDER BY username;'
if limit:
query = ('SELECT username FROM mailbox WHERE active = true '
'ORDER BY username LIMIT %d;' % limit)
result = subprocess.run(
[PSQL, '-U', DB_USER, DB_NAME, '-tAF', '|', '-c', query],
capture_output=True, text=True
)
return [u.strip() for u in result.stdout.strip().split('\n') if u.strip()]
def get_quota(user):
"""Returns (bytes, messages) or (None, None) if not available."""
result = subprocess.run(
[DOVEADM, 'quota', 'get', '-u', user],
capture_output=True, text=True
)
bytes_val = 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 # KiB → bytes
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 = (
"INSERT INTO quota2 (username, bytes, messages) VALUES ('"
+ user.replace("'", "''")
+ "', " + str(bytes_val) + ", " + str(messages_val) + ") "
"ON CONFLICT (username) DO UPDATE "
"SET bytes = EXCLUDED.bytes, messages = EXCLUDED.messages;"
)
subprocess.run([PSQL, '-U', DB_USER, DB_NAME, '-c', sql],
capture_output=True)
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)
updated = skipped = 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))
skipped += 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))
updated += 1
print('Done: %d updated, %d skipped.' % (updated, skipped))
if __name__ == '__main__':
main()