36 lines
1.7 KiB
Python
36 lines
1.7 KiB
Python
"""Foreground read-only OBS mount; systemd owns lifecycle and retries."""
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
|
|
try:
|
|
projects = json.loads(subprocess.check_output(
|
|
['sops', 'decrypt', '--extract', '["leafcloud"]', '--output-type', 'json', sys.argv[1]],
|
|
stderr=subprocess.DEVNULL))
|
|
if not projects:
|
|
raise ValueError('No projects')
|
|
env = os.environ.copy()
|
|
upstreams = []
|
|
for index, (project, credentials) in enumerate(projects.items()):
|
|
if not re.fullmatch(r'[A-Za-z0-9_-]+', project):
|
|
raise ValueError('Invalid project name')
|
|
remote = f'obs_project_{index}'
|
|
options = dict(type='s3', provider='Other', region='europe-nl-ams1',
|
|
endpoint='https://leafcloud.store', force_path_style='true',
|
|
access_key_id=credentials['access_key_id'],
|
|
secret_access_key=credentials['secret_access_key'])
|
|
env.update({f'RCLONE_CONFIG_{remote.upper()}_{key.upper()}': str(value)
|
|
for key, value in options.items()})
|
|
upstreams.append(f'{project}={remote}:')
|
|
env['RCLONE_CONFIG_OBS_TYPE'] = 'combine'
|
|
env['RCLONE_CONFIG_OBS_UPSTREAMS'] = ' '.join(upstreams)
|
|
mount = Path(sys.argv[2])
|
|
mount.mkdir(parents=True, exist_ok=True)
|
|
os.execvpe('rclone', ['rclone', 'mount', 'obs:', str(mount), '--config', '/dev/null',
|
|
'--read-only', '--vfs-cache-mode', 'off', '--buffer-size', '8M'], env)
|
|
except (subprocess.CalledProcessError, KeyError, ValueError, OSError):
|
|
raise SystemExit('OBS mount unavailable: check company SOPS provisioning and the machine age key.')
|