Add encrypted configuration backup and planned restore
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
FROM python:3.13-slim-bookworm
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends wireguard-tools iproute2 && rm -rf /var/lib/apt/lists/*
|
||||
RUN pip install --no-cache-dir cryptography==50.0.1
|
||||
WORKDIR /app
|
||||
COPY . /app
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 DECK_CONTAINER=1
|
||||
|
||||
@@ -198,6 +198,26 @@ class Agent:
|
||||
record = validate_record(data.get('credentials'))
|
||||
save(DATA/'auth.json', record)
|
||||
return {'saved':True}
|
||||
if action == 'backup-export':
|
||||
config = json.loads((DATA/'config.json').read_text()) if (DATA/'config.json').exists() else None
|
||||
return {'config': config, 'enabled': self.address is not None, 'mode': self.policy.mode}
|
||||
if action == 'backup-restore':
|
||||
if self.address or self.policy.mode != 'lan' or self.policy.pending:
|
||||
raise ValueError('Netzwerk-Restore nur im bestätigten LAN-Modus bei deaktiviertem Deck-Tunnel.')
|
||||
value = data.get('backup')
|
||||
if not isinstance(value, dict) or set(value) != {'config','enabled','mode'} or value['mode'] not in ('lan','both','tunnel') or type(value['enabled']) is not bool:
|
||||
raise ValueError('Ungültiger Netzwerk-Backupstand.')
|
||||
if value['config'] is not None:
|
||||
parse_config(value['config']);save(DATA/'config.json', value['config'])
|
||||
if value['enabled']:
|
||||
self.connect();save(DATA/'enabled.json', True)
|
||||
until=time.monotonic()+20
|
||||
while not self.connected()[0] and time.monotonic()<until:time.sleep(.5)
|
||||
if not self.connected()[0]:
|
||||
self.disconnect();save(DATA/'enabled.json',False)
|
||||
raise ValueError('WireGuard-Handshake fehlt; LAN-Zugang bleibt erhalten.')
|
||||
if value['mode'] != 'lan':self.policy.propose(value['mode'], True)
|
||||
return self.status(ingress)
|
||||
if action == 'status':
|
||||
return self.status(ingress)
|
||||
if action == 'import':
|
||||
|
||||
@@ -12,7 +12,7 @@ import sys
|
||||
|
||||
NAME = 'athena-deck-network'
|
||||
BASE = Path('/opt/athena-deck')
|
||||
FILES = {'deploy/tts-requirements.lock','stt.py','stt-ui.js','api_compat.py','execution_setup.py','tts_runtime.py','tts_test.py','tts_worker.py','tts-ui.js','auto_test.py','auto-test-ui.js','chat_test.py','chat-test-ui.js','endpoint.py','inference.py','endpoint-ui.js','image_runtime.py','image_encoder_node.py','docker_support.py','docker-ui.js','deploy/image-requirements.lock','image_test.py','image-test-ui.js','profiles.py','profiles-ui.js','capacity.py','runtime.py', 'runtime-ui.js', 'video.py','video_proxy.py','video-ui.js','catalog.py','hub_auth.py', 'catalog-ui.js', 'studio.js', 'auth.py', 'access-ui.js', 'server.py', 'collect_hardware.py', 'index.html', 'app.js', 'style.css', 'network-ui.js', 'login.html', 'login.js', 'network/__init__.py', 'network/config.py', 'network/policy.py', 'network/rpc.py', 'network/agent.py', 'network/client.py', 'network/Dockerfile', '.dockerignore'}
|
||||
FILES = {'backup.py','backup_codec.py','backup-ui.js','deploy/docker_backup.py','video_comfy.py','video_comfy_node.py','video_comfy_proxy.py','image_upload.py','prompt_enhancer.py','prompt_enhancer_worker.py','audio_policy.py','dashboard_data.py','dashboard_history.py','dashboard-ui.js','dashboard.css','themes.css','deploy/tts-requirements.lock','stt.py','stt-ui.js','api_compat.py','execution_setup.py','tts_runtime.py','tts_test.py','tts_worker.py','tts-ui.js','auto_test.py','auto-test-ui.js','chat_test.py','chat-test-ui.js','endpoint.py','inference.py','endpoint-ui.js','image_runtime.py','image_encoder_node.py','docker_support.py','docker-ui.js','deploy/image-requirements.lock','image_test.py','image-test-ui.js','profiles.py','profiles-ui.js','capacity.py','runtime.py', 'runtime-ui.js', 'video.py','video_proxy.py','video-ui.js','catalog.py','hub_auth.py', 'catalog-ui.js', 'studio.js', 'auth.py', 'access-ui.js', 'server.py', 'collect_hardware.py', 'index.html', 'app.js', 'style.css', 'network-ui.js', 'login.html', 'login.js', 'network/__init__.py', 'network/config.py', 'network/policy.py', 'network/rpc.py', 'network/agent.py', 'network/client.py', 'network/Dockerfile', '.dockerignore'}
|
||||
|
||||
def run(*args, **kwargs):
|
||||
return subprocess.run(args, capture_output=True, timeout=600, **kwargs)
|
||||
|
||||
Reference in New Issue
Block a user