Replace Deck video generation with selected external service lifecycle

This commit is contained in:
Mikei386
2026-09-29 14:24:52 +02:00
parent 71e8345606
commit badc7701fa
23 changed files with 219 additions and 636 deletions
+1 -2
View File
@@ -13,9 +13,8 @@ RUN git clone https://github.com/Comfy-Org/ComfyUI.git /opt/deck-comfy \
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends python3-dev && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY deploy/image-requirements.lock /app/deploy/image-requirements.lock
COPY deploy/video-requirements.lock /app/deploy/video-requirements.lock
COPY deploy/tts-requirements.lock /app/deploy/tts-requirements.lock
COPY api_compat.py stt.py execution_setup.py tts_runtime.py tts_test.py tts_worker.py auto_test.py chat_test.py endpoint.py inference.py docker_support.py image_encoder_node.py image_runtime.py image_test.py profiles.py capacity.py server.py runtime.py video.py video_worker.py video_runtime.py catalog.py hub_auth.py auth.py collect_hardware.py /app/
COPY api_compat.py stt.py execution_setup.py tts_runtime.py tts_test.py tts_worker.py auto_test.py chat_test.py endpoint.py inference.py docker_support.py image_encoder_node.py image_runtime.py image_test.py profiles.py capacity.py server.py runtime.py video.py catalog.py hub_auth.py auth.py collect_hardware.py /app/
COPY video-ui.js stt-ui.js tts-ui.js auto-test-ui.js chat-test-ui.js endpoint-ui.js docker-ui.js image-test-ui.js profiles-ui.js index.html app.js studio.js runtime-ui.js catalog-ui.js style.css login.html login.js access-ui.js network-ui.js /app/
COPY network/__init__.py network/client.py network/config.py network/rpc.py /app/network/
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 HOME=/tmp \
+47 -1
View File
@@ -1,6 +1,9 @@
#!/usr/bin/env python3
"""Root-owned local helper. Only inventory and fresh Docker install; no generic RPC."""
import argparse
import re
import urllib.request
import urllib.error
import json
import os
from pathlib import Path
@@ -97,8 +100,51 @@ class Manager:
self._checked(['/usr/bin/docker','compose','version','--short'])
self._phase('Docker bereit. Keine Anwendungen oder Modelle installiert.','complete')
except Exception as exc:self._phase(str(exc) if isinstance(exc,ValueError) else 'Docker-Installation fehlgeschlagen. Hostzustand vor erneutem Versuch prüfen.','failed')
def video_configs(self):
path=self.state/'video-services.json'
if not path.exists():return []
if path.is_symlink() or path.stat().st_uid!=0 or path.stat().st_mode&0o022:raise ValueError('Videodienste müssen durch root eingerichtet werden.')
configs=json.loads(path.read_text())
if not isinstance(configs,list) or len(configs)>20:raise ValueError('Ungültige Dienstliste.')
ids=set()
for config in configs:
if not re.fullmatch('[a-z0-9-]{1,40}',config.get('id','')) or config['id'] in ids or not re.fullmatch('[a-f0-9]{64}',config.get('container_id','')):raise ValueError('Ungültige Dienstzuordnung.')
ids.add(config['id'])
return configs
def video_status(self,config):
result=run(['/usr/bin/docker','inspect','--format','{{.State.Running}}',config['container_id']])
if result.returncode:return dict(id=config['id'],name=config['name'],running=None,ready=False,api_url=config['api_url'],message='Zugeordneter Container fehlt.')
running=result.stdout.strip()=='true';ready=False
if running:
class NoRedirect(urllib.request.HTTPRedirectHandler):
def redirect_request(self,*args,**kwargs):return None
try:
headers={}
if config.get('token_file'):headers['Authorization']='Bearer '+Path(config['token_file']).read_text().strip()
request=urllib.request.Request(config['health_url'],headers=headers)
with urllib.request.build_opener(NoRedirect).open(request,timeout=2) as response:ready=response.status==200
except (OSError,ValueError,urllib.error.URLError):pass
return dict(id=config['id'],name=config['name'],running=running,ready=ready,api_url=config['api_url'],message=config.get('message','Original-API des Dienstes.'))
def video_inventory(self):return {'services':[self.video_status(config) for config in self.video_configs()]}
def video_action(self,ident,start):
with self.lock:
configs=self.video_configs();config=next((c for c in configs if c['id']==ident),None)
if config is None:raise ValueError('Videodienst nicht freigegeben.')
status=self.video_status(config)
if start and status['running']:return status
if start:
if any(self.video_status(c)['running'] is not False for c in configs if c['id']!=ident):raise ValueError('Ein anderer Videodienst ist noch aktiv oder nicht prüfbar.')
probe=run(['/usr/bin/nvidia-smi','--query-compute-apps=pid','--format=csv,noheader,nounits'])
if probe.returncode or probe.stdout.strip():raise ValueError('GPU durch einen anderen Dienst belegt. Deck beendet keine fremden Modelle. Alten Router zuerst freigeben.')
result=run(['/usr/bin/docker','start',config['container_id']] if start else ['/usr/bin/docker','stop','--time','30',config['container_id']],timeout=45)
if result.returncode:raise ValueError('Videodienst konnte nicht gestartet oder beendet werden.')
return self.video_status(config)
def dispatch(self,data):
if not isinstance(data,dict) or set(data)!={'action'}:raise ValueError('Ungültige Helferanfrage.')
if not isinstance(data,dict):raise ValueError('Ungültige Helferanfrage.')
if set(data)=={'action','service'} and data['action'] in ('video-start','video-stop'):
return self.video_action(data['service'],data['action']=='video-start')
if set(data)!={'action'}:raise ValueError('Ungültige Helferanfrage.')
if data['action']=='video-status':return self.video_inventory()
if data['action']=='status':return self.status()
if data['action']=='install':return self.install()
raise ValueError('Aktion nicht erlaubt.')
+1 -1
View File
@@ -14,7 +14,7 @@ import urllib.request
ROOT = Path(__file__).resolve().parent.parent
LABEL = 'de.casaderoll.athena-deck.standalone'
FILES = ['deploy/video-requirements.lock','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','docker_support.py','docker-ui.js','deploy/docker_helper.py','deploy/setup_docker_helper.py','image_encoder_node.py','image_runtime.py','image_test.py','image-test-ui.js','profiles.py','profiles-ui.js','capacity.py','runtime.py','runtime-ui.js','video.py','video_worker.py','video_runtime.py','video-ui.js','catalog.py','hub_auth.py','catalog-ui.js','server.py','auth.py','collect_hardware.py','index.html','app.js','studio.js','style.css','login.html','login.js','access-ui.js','network-ui.js','network/__init__.py','network/client.py','network/config.py','network/rpc.py','deploy/Dockerfile','deploy/image-requirements.lock']
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','docker_support.py','docker-ui.js','deploy/docker_helper.py','deploy/setup_docker_helper.py','image_encoder_node.py','image_runtime.py','image_test.py','image-test-ui.js','profiles.py','profiles-ui.js','capacity.py','runtime.py','runtime-ui.js','video.py','video-ui.js','catalog.py','hub_auth.py','catalog-ui.js','server.py','auth.py','collect_hardware.py','index.html','app.js','studio.js','style.css','login.html','login.js','access-ui.js','network-ui.js','network/__init__.py','network/client.py','network/config.py','network/rpc.py','deploy/Dockerfile','deploy/image-requirements.lock']
def run(*args, check=True, interactive=False):
-63
View File
@@ -1,63 +0,0 @@
accelerate==1.15.0
annotated-doc==0.0.5
anyio==4.15.1
av==18.1.0
certifi==2026.7.22
click==8.5.0
cloudpickle==3.1.2
cuda-bindings==12.9.7
cuda-pathfinder==1.6.0
cuda-toolkit==12.8.1
einops==0.8.2
filelock==3.32.3
fsspec==2026.7.0
h11==0.16.0
hf-xet==1.6.0
httpcore==1.0.9
httpx==0.28.1
huggingface_hub==1.33.0
idna==3.20
Jinja2==3.1.6
markdown-it-py==4.2.0
MarkupSafe==3.0.3
mdurl==0.1.2
mpmath==1.3.0
networkx==3.6.1
numpy==2.5.2
nvidia-cublas-cu12==12.8.4.1
nvidia-cuda-cupti-cu12==12.8.90
nvidia-cuda-nvrtc-cu12==12.8.93
nvidia-cuda-runtime-cu12==12.8.90
nvidia-cudnn-cu12==9.19.0.56
nvidia-cufft-cu12==11.3.3.83
nvidia-cufile-cu12==1.13.1.3
nvidia-curand-cu12==10.3.9.90
nvidia-cusolver-cu12==11.7.3.90
nvidia-cusparse-cu12==12.5.8.93
nvidia-cusparselt-cu12==0.7.1
nvidia-nccl-cu12==2.28.9
nvidia-nvjitlink-cu12==12.8.93
nvidia-nvshmem-cu12==3.4.5
nvidia-nvtx-cu12==12.8.90
OpenImageIO==3.1.17.0
packaging==26.3
pillow==12.3.0
psutil==7.2.2
Pygments==2.21.0
PyYAML==6.0.3
regex==2026.9.29
rich==15.0.0
safetensors==0.8.0
scipy==1.18.1
setuptools==78.1.0
shellingham==1.5.4
sympy==1.14.0
tokenizers==0.22.2
torch==2.11.0+cu128
torchaudio==2.11.0+cu128
torchvision==0.26.0+cu128
tqdm==4.70.1
transformers==5.14.1
triton==3.6.0
typer==0.27.2
typing_extensions==4.16.0