left4me: schedule daily workshop-refresh via systemd-timers

Adds a left4me-workshop-refresh entry to the systemd-timers bundle,
firing nightly at 04:00 and invoking the new flask workshop-refresh
CLI that enqueues a refresh_workshop_items job. Owner of the job is
NULL (system-enqueued). The bw worker picks it up under existing
scheduler rules; idempotent against an already-queued/running refresh.

Also extends bundles/systemd-timers to accept an optional
environment_files key so the new unit can pull DATABASE_URL etc.
from /etc/left4me/{host,web}.env.
This commit is contained in:
CroneKorkN 2026-05-12 10:29:45 +02:00
parent 508111eb39
commit 7ad9bbcec3
Signed by: cronekorkn
SSH key fingerprint: SHA256:v0410ZKfuO1QHdgKBsdQNF64xmTxOF8osF1LIqwTcVw
2 changed files with 25 additions and 0 deletions

View file

@ -1,5 +1,6 @@
assert node.has_bundle('nftables')
assert node.has_bundle('systemd')
assert node.has_bundle('systemd-timers')
defaults = {
@ -76,6 +77,28 @@ defaults = {
'/etc/left4me',
},
},
'systemd-timers': {
# Daily re-fetch of Steam Workshop metadata + .vpk downloads for any
# item whose author published an update. The CLI just inserts a
# `refresh_workshop_items` job; the web worker picks it up next.
# Idempotent — a re-fire while a refresh is already queued/running
# is a no-op (see l4d2web/cli.py:workshop_refresh).
'left4me-workshop-refresh': {
'command': '/opt/left4me/.venv/bin/flask --app l4d2web.app:create_app workshop-refresh',
'when': '*-*-* 04:00:00',
'persistent': True,
'user': 'left4me',
'working_dir': '/opt/left4me/src',
'environment_files': (
'/etc/left4me/host.env',
'/etc/left4me/web.env',
),
'after': {
'network-online.target',
'left4me-web.service',
},
},
},
}

View file

@ -44,6 +44,8 @@ def systemd(metadata):
units[f'{name}.service']['Service']['KillMode'] = config['kill_mode']
if config.get('RuntimeMaxSec'):
units[f'{name}.service']['Service']['RuntimeMaxSec'] = config['RuntimeMaxSec']
if config.get('environment_files'):
units[f'{name}.service']['Service']['EnvironmentFile'] = config['environment_files']
services[f'{name}.timer'] = {}