Migrate declarative configs to config/ dir and remove hardcoded paths

Replace all hardcoded /home/wall/vacuum-wall paths in lib/ with Path(__file__).resolve()
auto-discovery. Move config files from data/ to config/<subsystem>/config.json.
ACME now uses ACME_HOME env var and data/acme/ for cert storage. Systemd units
and sudoers use {{ USER_NAME }}, {{ PROJECT_DIR }}, {{ ACME_HOME }} Jinja2
template variables for install-time substitution. Remove sys.path.insert boot
strap from test files.
This commit is contained in:
2026-05-14 03:31:13 +00:00
parent 817b7c409c
commit d9797b6dac
16 changed files with 131 additions and 136 deletions
+6 -6
View File
@@ -21,21 +21,21 @@ server {
{% if cert.type == "acme" %}
# Certificate managed by acme.sh
{% if cert.email %} # ACME contact: {{ cert.email }}
{% endif %} ssl_certificate /home/vacuum-wall/.acme.sh/{{ domain }}/fullchain.cer;
ssl_certificate_key /home/vacuum-wall/.acme.sh/{{ domain }}/{{ domain }}.key;
{% endif %} ssl_certificate {{ acme_home }}/{{ domain }}/fullchain.cer;
ssl_certificate_key {{ acme_home }}/{{ domain }}/{{ domain }}.key;
{% elif cert.type == "file" %}
ssl_certificate {{ cert.path }};
ssl_certificate_key {{ cert.key_path }};
{% elif cert.type == "selfsigned" %}
ssl_certificate /home/wall/vacuum-wall/data/certs/{{ domain }}.crt;
ssl_certificate_key /home/wall/vacuum-wall/data/certs/{{ domain }}.key;
ssl_certificate {{ certs_dir }}/{{ domain }}.crt;
ssl_certificate_key {{ certs_dir }}/{{ domain }}.key;
{% endif %}
{% elif is_management %}
ssl_certificate /home/wall/vacuum-wall/data/certs/{{ domain }}.crt;
ssl_certificate_key /home/wall/vacuum-wall/data/certs/{{ domain }}.key;
ssl_certificate {{ certs_dir }}/{{ domain }}.crt;
ssl_certificate_key {{ certs_dir }}/{{ domain }}.key;
{% endif %}
# Shared SSL settings
+22 -22
View File
@@ -1,33 +1,33 @@
# Defaults directives
Defaults:vacuum-wall !requiretty
Defaults:vacuum-wall secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Defaults:{{ USER_NAME }} !requiretty
Defaults:{{ USER_NAME }} secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# Firewall management
vacuum-wall ALL=(root) NOPASSWD: /usr/bin/firewall-cmd *
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/bin/firewall-cmd *
# Nginx management
vacuum-wall ALL=(root) NOPASSWD: /usr/sbin/nginx -s reload
vacuum-wall ALL=(root) NOPASSWD: /usr/sbin/nginx -t
vacuum-wall ALL=(root) NOPASSWD: /usr/bin/cp -- * /etc/nginx/
vacuum-wall ALL=(root) NOPASSWD: /usr/bin/cp -- * /etc/nginx/conf.d/
vacuum-wall ALL=(root) NOPASSWD: /usr/bin/cp -- * /etc/nginx/snippets/
vacuum-wall ALL=(root) NOPASSWD: /usr/bin/rm /etc/nginx/conf.d/vacuum-wall.conf
vacuum-wall ALL=(root) NOPASSWD: /usr/bin/rm /etc/nginx/snippets/vacuum-wall-ssl.conf
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/sbin/nginx -s reload
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/sbin/nginx -t
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/bin/cp -- * /etc/nginx/
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/bin/cp -- * /etc/nginx/conf.d/
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/bin/cp -- * /etc/nginx/snippets/
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/bin/rm /etc/nginx/conf.d/vacuum-wall.conf
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/bin/rm /etc/nginx/snippets/vacuum-wall-ssl.conf
# Dnsmasq management
vacuum-wall ALL=(root) NOPASSWD: /usr/bin/systemctl reload dnsmasq
vacuum-wall ALL=(root) NOPASSWD: /usr/bin/systemctl is-active dnsmasq
vacuum-wall ALL=(root) NOPASSWD: /usr/bin/cp -- * /etc/dnsmasq.d/
vacuum-wall ALL=(root) NOPASSWD: /usr/bin/cat /var/lib/dnsmasq/dnsmasq.leases
vacuum-wall ALL=(root) NOPASSWD: /usr/bin/tee /etc/dnsmasq.d/vacuum-wall.conf
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/bin/systemctl reload dnsmasq
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/bin/systemctl is-active dnsmasq
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/bin/cp -- * /etc/dnsmasq.d/
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/bin/cat /var/lib/dnsmasq/dnsmasq.leases
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/bin/tee /etc/dnsmasq.d/vacuum-wall.conf
# WireGuard management
vacuum-wall ALL=(root) NOPASSWD: /usr/bin/wg-quick *
vacuum-wall ALL=(root) NOPASSWD: /usr/bin/wg *
vacuum-wall ALL=(root) NOPASSWD: /usr/bin/cp -- * /etc/wireguard/
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/bin/wg-quick *
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/bin/wg *
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/bin/cp -- * /etc/wireguard/
# Misc
vacuum-wall ALL=(root) NOPASSWD: /usr/bin/journalctl --unit=* -n *
vacuum-wall ALL=(root) NOPASSWD: /usr/bin/cat /var/log/nginx/*
vacuum-wall ALL=(root) NOPASSWD: /usr/bin/mkdir -p /etc/dnsmasq.d
vacuum-wall ALL=(root) NOPASSWD: /usr/bin/mkdir -p /etc/wireguard
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/bin/journalctl --unit=* -n *
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/bin/cat /var/log/nginx/*
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/bin/mkdir -p /etc/dnsmasq.d
{{ USER_NAME }} ALL=(root) NOPASSWD: /usr/bin/mkdir -p /etc/wireguard
+5 -3
View File
@@ -3,6 +3,8 @@ Description=Vacuum Wall ACME Certificate Renewal
[Service]
Type=oneshot
User=vacuum-wall
WorkingDirectory=/home/wall/vacuum-wall
ExecStart=/usr/local/bin/acme.sh --cron --home /home/vacuum-wall/.acme.sh
User={{ USER_NAME }}
WorkingDirectory={{ PROJECT_DIR }}
Environment=ACME_HOME={{ PROJECT_DIR }}/data/acme
Environment=HOME={{ PROJECT_DIR }}
ExecStart=/usr/local/bin/acme.sh --cron --home {{ ACME_HOME }}
+9 -7
View File
@@ -6,20 +6,21 @@ Wants=firewalld.service
[Service]
Type=simple
User=vacuum-wall
Group=vacuum-wall
WorkingDirectory=/home/wall/vacuum-wall
ExecStart=/home/wall/vacuum-wall/.venv/bin/python webui/server.py
User={{ USER_NAME }}
Group={{ USER_NAME }}
WorkingDirectory={{ PROJECT_DIR }}
ExecStart={{ PROJECT_DIR }}/.venv/bin/python webui/server.py
Restart=on-failure
RestartSec=5
Environment=PATH=/usr/local/bin:/usr/bin
Environment=PYTHONUNBUFFERED=1
Environment=ACME_HOME={{ PROJECT_DIR }}/data/acme
Environment=HOME={{ PROJECT_DIR }}
# Security hardening
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/home/wall/vacuum-wall/data /tmp
ReadWritePaths={{ PROJECT_DIR }}/config {{ PROJECT_DIR }}/data /tmp
PrivateTmp=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
@@ -33,7 +34,8 @@ LockPersonality=yes
SystemCallFilter=@system-service
PrivateDevices=yes
# Network - only loopback (nginx proxies to us)
ProtectHome=read-only
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
IPAddressDeny=all
IPAddressAllow=localhost