feature: the router serves S3-compatible object storage with versitygw, with one S3 account per user and buckets owned by users.
Release / release (push) Successful in 14s

This commit is contained in:
slawek committed 2026-10-29 19:24:24 +01:00
1 parent d99e4ea425
commit 1eac15e640
20 files changed
+1115 -25

No files matched your search

@@ -1,7 +1,8 @@
"""The backups of the router, for vpn-router-backup and the web service.
A backup is a consistent copy of the state that setup cannot make again, staged in STAGING: the
trees of TREES, the folders of the web sites among them, the files of site_to_site psk_file outside them under files/,
trees of TREES, the folders of the web sites and the accounts of the object storage among them, with backup.s3 its
buckets, the files of site_to_site psk_file outside them under files/,
the directory as slapcat writes it (ldap/vpn-router.ldif), with backup.metrics the database as pg_dump writes it
(postgresql/vpn-router.dump), the databases of the web sites and of the name server (DUMPS) once they exist, and
manifest.json. The trees and the directory are copied while
@@ -36,6 +37,7 @@ import vpnrouter
import vpnrouter_auth
import vpnrouter_dns
import vpnrouter_ldap
import vpnrouter_s3
import vpnrouter_sites
import vpnrouter_users
@@ -51,9 +53,10 @@ PBS_CLIENT = pathlib.Path('/usr/bin/proxmox-backup-client')
UNIT = 'vpn-router-backup.service'
TIMER = 'vpn-router-backup.timer'
#: The state a backup copies: directories and files, each where it is on the system.
#: The state a backup copies: directories and files, each where it is on the system; with backup.s3 also the buckets
#: of the object storage (vpnrouter_s3.DATA_DIR).
TREES = ('/etc/vpn-router', '/etc/wireguard', '/etc/ufw', '/etc/default/ufw', '/etc/vpn-router-manager',
str(vpnrouter_sites.SITES_DIR))
str(vpnrouter_sites.SITES_DIR), str(vpnrouter_s3.IAM_DIR))
#: The databases a backup always dumps, each while it exists: the dump -> the database and its password file.
DUMPS = {'postgresql/vpn-router-sites.dump': (vpnrouter_sites.DATABASE, vpnrouter_sites.DATABASE_SECRET),
@@ -73,7 +76,7 @@ PERIODS = {'keep_hourly': '%Y-%m-%d %H', 'keep_daily': '%Y-%m-%d', 'keep_weekly'
#: The units a restore stops while it replaces the directory and the database, and the ones it restarts after setup.
RESTORE_STOPS = ('vpn-router-web.service', 'vpn-router-metrics.service', 'vpn-router-webdav.service', 'pdns.service',
'slapd.service')
'vpn-router-s3.service', 'slapd.service')
RESTORE_RESTARTS = ('wg-quick@wg0.service', 'openvpn-server@vpn-router.service', 'strongswan.service',
'vpn-router-manager.service')
@@ -220,7 +223,8 @@ def stage(cfg):
"""Copy what a backup holds to STAGING, emptied first, and return the manifest."""
shutil.rmtree(STAGING, ignore_errors=True)
STAGING.mkdir(parents=True, mode=0o700)
trees = [tree for tree in TREES if os.path.exists(tree)]
trees = [tree for tree in (*TREES, *((str(vpnrouter_s3.DATA_DIR),) if cfg['backup']['s3'] else ()))
if os.path.exists(tree)]
files = psk_files(cfg)
vpnrouter_users.LOCK_FILE.parent.mkdir(parents=True, exist_ok=True)
with vpnrouter.config_lock(), open(vpnrouter_users.LOCK_FILE, 'w') as users: