Replace Deck video generation with selected external service lifecycle
This commit is contained in:
+1
-2
@@ -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
@@ -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
@@ -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):
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user