prepare intranet for first Dokploy deployment
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
date.timezone = Europe/Berlin
|
||||
upload_max_filesize = 64M
|
||||
post_max_size = 70M
|
||||
memory_limit = 512M
|
||||
max_execution_time = 180
|
||||
display_errors = Off
|
||||
log_errors = On
|
||||
session.cookie_httponly = 1
|
||||
session.cookie_samesite = Lax
|
||||
session.cookie_secure = 1
|
||||
expose_php = Off
|
||||
@@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env python3
|
||||
import fcntl
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import time
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
PYTHON = '/opt/intranet-venv/bin/python'
|
||||
ROOT = Path('/opt/intranet/worker')
|
||||
STATE_DIR = Path('/data/state')
|
||||
PDF_OUTPUT = Path(os.getenv('PDF_OUTPUT', '/data/pdf/terminuebersicht.pdf'))
|
||||
INTERVAL = int(os.getenv('CALENDAR_INTERVAL_SECONDS', '60'))
|
||||
|
||||
|
||||
def required(name: str) -> str:
|
||||
value = os.getenv(name, '').strip()
|
||||
if not value:
|
||||
raise RuntimeError(f'Missing environment variable: {name}')
|
||||
return value
|
||||
|
||||
|
||||
def run(cmd, cwd=None):
|
||||
print('+', ' '.join(map(str, cmd)), flush=True)
|
||||
subprocess.run(cmd, cwd=cwd, check=True, env=os.environ.copy())
|
||||
|
||||
|
||||
def prepare_ssh_key() -> Path:
|
||||
source = Path(os.getenv('STRATO_SSH_KEY_FILE', '/run/secrets/strato_ed25519'))
|
||||
if not source.is_file():
|
||||
raise RuntimeError(f'SSH key file missing: {source}')
|
||||
target = Path('/tmp/strato_ed25519')
|
||||
shutil.copyfile(source, target)
|
||||
target.chmod(0o600)
|
||||
return target
|
||||
|
||||
|
||||
def calendar_sync():
|
||||
run([PYTHON, str(ROOT / 'ckal_upload_client/client.py')], cwd=ROOT / 'ckal_upload_client')
|
||||
run([PYTHON, str(ROOT / 'pdf_python/create_pdf.py')], cwd=ROOT / 'pdf_python')
|
||||
run(['/bin/bash', str(ROOT / 'pdf_python/pdf_to_png.sh')], cwd=ROOT / 'pdf_python')
|
||||
|
||||
required('STRATO_SSH_USER')
|
||||
required('STRATO_REMOTE_PATH')
|
||||
host = os.getenv('STRATO_SSH_HOST', 'ssh.strato.de')
|
||||
port = os.getenv('STRATO_SSH_PORT', '22')
|
||||
known_hosts = Path(os.getenv('STRATO_KNOWN_HOSTS_FILE', '/run/secrets/known_hosts'))
|
||||
if not known_hosts.is_file():
|
||||
raise RuntimeError(f'known_hosts missing: {known_hosts}')
|
||||
key = prepare_ssh_key()
|
||||
if not PDF_OUTPUT.is_file() or PDF_OUTPUT.stat().st_size == 0:
|
||||
raise RuntimeError(f'PDF missing/empty: {PDF_OUTPUT}')
|
||||
|
||||
run([
|
||||
'/usr/bin/scp', '-O', '-q', '-P', port,
|
||||
'-i', str(key),
|
||||
'-o', 'IdentitiesOnly=yes',
|
||||
'-o', 'BatchMode=yes',
|
||||
'-o', 'StrictHostKeyChecking=yes',
|
||||
'-o', f'UserKnownHostsFile={known_hosts}',
|
||||
str(PDF_OUTPUT),
|
||||
f"{required('STRATO_SSH_USER')}@{host}:{required('STRATO_REMOTE_PATH')}",
|
||||
])
|
||||
print('Calendar Sync erfolgreich', flush=True)
|
||||
|
||||
|
||||
def brandschutz_once_per_month():
|
||||
now = datetime.now()
|
||||
if now.day != 1 or now.hour < 8:
|
||||
return
|
||||
|
||||
marker = STATE_DIR / 'brandschutz-last-attempt'
|
||||
month = now.strftime('%Y-%m')
|
||||
if marker.exists() and marker.read_text().strip() == month:
|
||||
return
|
||||
|
||||
# At-most-once: erst markieren, dann ausführen. Bei Fehler manuell prüfen und Marker löschen.
|
||||
marker.write_text(month + '\n')
|
||||
print(f'Brandschutz-Lauf {month}', flush=True)
|
||||
run(['/usr/local/bin/php', '/var/www/html/intranet_repo/projects/brandschutz/brandschutz_cron.php'])
|
||||
|
||||
|
||||
def main():
|
||||
STATE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
lock_handle = (STATE_DIR / 'scheduler.lock').open('w')
|
||||
try:
|
||||
fcntl.flock(lock_handle.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
except BlockingIOError as exc:
|
||||
raise RuntimeError('Ein anderer Scheduler läuft bereits.') from exc
|
||||
|
||||
if INTERVAL < 30:
|
||||
raise RuntimeError('CALENDAR_INTERVAL_SECONDS muss >= 30 sein.')
|
||||
for name in ('CKAL_USERNAME', 'CKAL_PASSWORD', 'CKAL_CALENDAR_URL'):
|
||||
required(name)
|
||||
PDF_OUTPUT.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
next_run = 0.0
|
||||
while True:
|
||||
try:
|
||||
brandschutz_once_per_month()
|
||||
except Exception as exc:
|
||||
print(f'FEHLER Brandschutz: {exc}', flush=True)
|
||||
|
||||
now_mono = time.monotonic()
|
||||
if now_mono >= next_run:
|
||||
try:
|
||||
calendar_sync()
|
||||
except Exception as exc:
|
||||
print(f'FEHLER Calendar Sync: {exc}', flush=True)
|
||||
next_run = time.monotonic() + INTERVAL
|
||||
|
||||
(STATE_DIR / 'heartbeat').write_text(str(int(time.time())) + '\n')
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user