feat: Add Docker image update system (TrueNAS Scale inspired)
- Implement UpdateService for image version checking and atomic updates - Add DockerComposeManager for centralized docker-compose management - Create 12 docker-compose references in /home/innotex/Docker - Add 13 new API endpoints (6 for images, 7 for compose management) - Add comprehensive documentation and examples
This commit is contained in:
141
backend/app/api/endpoints/compose.py
Normal file
141
backend/app/api/endpoints/compose.py
Normal file
@@ -0,0 +1,141 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from typing import List
|
||||
from app.core.security import get_current_user, User
|
||||
from app.services.compose_manager import DockerComposeManager
|
||||
from pydantic import BaseModel
|
||||
|
||||
router = APIRouter()
|
||||
compose_manager = DockerComposeManager()
|
||||
|
||||
|
||||
class ComposeFile(BaseModel):
|
||||
name: str
|
||||
file: str
|
||||
path: str
|
||||
exists: bool
|
||||
|
||||
|
||||
@router.get("/compose/list", response_model=List[ComposeFile])
|
||||
async def list_compose_files(current_user: User = Depends(get_current_user)):
|
||||
"""Liste tous les docker-compose disponibles dans /home/innotex/Docker"""
|
||||
return compose_manager.discover_compose_files()
|
||||
|
||||
|
||||
@router.get("/compose/{compose_name}/status")
|
||||
async def get_compose_status(
|
||||
compose_name: str,
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
"""Récupère l'état des conteneurs d'un docker-compose"""
|
||||
result = compose_manager.get_compose_status(f"docker-compose.{compose_name}.yml")
|
||||
|
||||
if result.get("status") == "error":
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=result.get("message", "Erreur inconnue")
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@router.post("/compose/{compose_name}/start")
|
||||
async def start_compose(
|
||||
compose_name: str,
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
"""Démarre les conteneurs d'un docker-compose"""
|
||||
result = compose_manager.start_compose(f"docker-compose.{compose_name}.yml")
|
||||
|
||||
if result.get("status") == "error":
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=result.get("message", "Erreur inconnue")
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@router.post("/compose/{compose_name}/stop")
|
||||
async def stop_compose(
|
||||
compose_name: str,
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
"""Arrête les conteneurs d'un docker-compose"""
|
||||
result = compose_manager.stop_compose(f"docker-compose.{compose_name}.yml")
|
||||
|
||||
if result.get("status") == "error":
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=result.get("message", "Erreur inconnue")
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@router.post("/compose/{compose_name}/down")
|
||||
async def down_compose(
|
||||
compose_name: str,
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
"""Arrête et supprime les conteneurs d'un docker-compose"""
|
||||
result = compose_manager.down_compose(f"docker-compose.{compose_name}.yml")
|
||||
|
||||
if result.get("status") == "error":
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=result.get("message", "Erreur inconnue")
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@router.post("/compose/{compose_name}/restart")
|
||||
async def restart_compose(
|
||||
compose_name: str,
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
"""Redémarre les conteneurs d'un docker-compose"""
|
||||
result = compose_manager.restart_compose(f"docker-compose.{compose_name}.yml")
|
||||
|
||||
if result.get("status") == "error":
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=result.get("message", "Erreur inconnue")
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@router.post("/compose/{compose_name}/pull")
|
||||
async def pull_images(
|
||||
compose_name: str,
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
"""Pull (met à jour) les images d'un docker-compose"""
|
||||
result = compose_manager.pull_compose_images(f"docker-compose.{compose_name}.yml")
|
||||
|
||||
if result.get("status") == "error":
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=result.get("message", "Erreur inconnue")
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@router.get("/compose/{compose_name}/logs")
|
||||
async def get_logs(
|
||||
compose_name: str,
|
||||
tail: int = 100,
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
"""Récupère les logs d'un docker-compose"""
|
||||
result = compose_manager.logs_compose(f"docker-compose.{compose_name}.yml", tail=tail)
|
||||
|
||||
if result.get("status") == "error":
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=result.get("message", "Erreur inconnue")
|
||||
)
|
||||
|
||||
return result
|
||||
Reference in New Issue
Block a user