initial commit
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
"""Container management API routes."""
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, Body, Depends, Query
|
||||
|
||||
from app.docker_client import DockerManager, get_docker_manager
|
||||
from app.models import (
|
||||
ContainerCreate,
|
||||
ContainerCreateResponse,
|
||||
ContainerListResponse,
|
||||
ContainerLogsResponse,
|
||||
ContainerResponse,
|
||||
ContainerStatsResponse,
|
||||
MessageResponse,
|
||||
)
|
||||
from app.security import validate_container_request
|
||||
|
||||
router = APIRouter(prefix="/containers", tags=["containers"])
|
||||
|
||||
|
||||
@router.get("", response_model=ContainerListResponse)
|
||||
async def list_containers(
|
||||
all: bool = Query(True, description="Include stopped containers"),
|
||||
docker: DockerManager = Depends(get_docker_manager),
|
||||
) -> ContainerListResponse:
|
||||
"""
|
||||
List all containers managed by this API.
|
||||
|
||||
Only containers created through this API (with managed labels) will be returned.
|
||||
"""
|
||||
containers = docker.list_managed(all_containers=all)
|
||||
return ContainerListResponse(containers=containers, count=len(containers))
|
||||
|
||||
|
||||
@router.post("/create", response_model=ContainerCreateResponse)
|
||||
async def create_container(
|
||||
request: ContainerCreate = Body(...),
|
||||
docker: DockerManager = Depends(get_docker_manager),
|
||||
) -> ContainerCreateResponse:
|
||||
"""
|
||||
Create a new container.
|
||||
|
||||
The container will be labeled as managed by this API and will only be accessible
|
||||
through this API's endpoints.
|
||||
|
||||
Security restrictions apply:
|
||||
- Privileged mode is not allowed
|
||||
- Host network mode is not allowed
|
||||
- Host PID mode is not allowed
|
||||
- Certain volume mounts are blocked
|
||||
- Device mappings are not allowed
|
||||
"""
|
||||
# Validate security
|
||||
validate_container_request(request)
|
||||
|
||||
# Create the container
|
||||
return docker.create_container(request)
|
||||
|
||||
|
||||
@router.get("/{container_id}", response_model=ContainerResponse)
|
||||
async def inspect_container(
|
||||
container_id: str,
|
||||
docker: DockerManager = Depends(get_docker_manager),
|
||||
) -> ContainerResponse:
|
||||
"""
|
||||
Get detailed information about a container.
|
||||
|
||||
Only managed containers can be inspected.
|
||||
"""
|
||||
return docker.inspect_container(container_id)
|
||||
|
||||
|
||||
@router.post("/{container_id}/start", response_model=MessageResponse)
|
||||
async def start_container(
|
||||
container_id: str,
|
||||
docker: DockerManager = Depends(get_docker_manager),
|
||||
) -> MessageResponse:
|
||||
"""
|
||||
Start a stopped container.
|
||||
|
||||
Only managed containers can be started.
|
||||
"""
|
||||
docker.start_container(container_id)
|
||||
return MessageResponse(message="Container started", container_id=container_id)
|
||||
|
||||
|
||||
@router.post("/{container_id}/stop", response_model=MessageResponse)
|
||||
async def stop_container(
|
||||
container_id: str,
|
||||
timeout: int = Query(10, ge=0, description="Seconds to wait before killing"),
|
||||
docker: DockerManager = Depends(get_docker_manager),
|
||||
) -> MessageResponse:
|
||||
"""
|
||||
Stop a running container.
|
||||
|
||||
Only managed containers can be stopped.
|
||||
"""
|
||||
docker.stop_container(container_id, timeout=timeout)
|
||||
return MessageResponse(message="Container stopped", container_id=container_id)
|
||||
|
||||
|
||||
@router.post("/{container_id}/restart", response_model=MessageResponse)
|
||||
async def restart_container(
|
||||
container_id: str,
|
||||
timeout: int = Query(10, ge=0, description="Seconds to wait before killing"),
|
||||
docker: DockerManager = Depends(get_docker_manager),
|
||||
) -> MessageResponse:
|
||||
"""
|
||||
Restart a container.
|
||||
|
||||
Only managed containers can be restarted.
|
||||
"""
|
||||
docker.restart_container(container_id, timeout=timeout)
|
||||
return MessageResponse(message="Container restarted", container_id=container_id)
|
||||
|
||||
|
||||
@router.delete("/{container_id}", response_model=MessageResponse)
|
||||
async def remove_container(
|
||||
container_id: str,
|
||||
force: bool = Query(False, description="Force removal of running container"),
|
||||
v: bool = Query(False, description="Remove associated volumes"),
|
||||
docker: DockerManager = Depends(get_docker_manager),
|
||||
) -> MessageResponse:
|
||||
"""
|
||||
Remove a container.
|
||||
|
||||
Only managed containers can be removed.
|
||||
"""
|
||||
docker.remove_container(container_id, force=force, v=v)
|
||||
return MessageResponse(message="Container removed", container_id=container_id)
|
||||
|
||||
|
||||
@router.get("/{container_id}/logs", response_model=ContainerLogsResponse)
|
||||
async def get_container_logs(
|
||||
container_id: str,
|
||||
stdout: bool = Query(True, description="Include stdout"),
|
||||
stderr: bool = Query(True, description="Include stderr"),
|
||||
tail: int = Query(100, ge=0, description="Number of lines from end (0 for all)"),
|
||||
since: Optional[int] = Query(None, description="Unix timestamp to start from"),
|
||||
until: Optional[int] = Query(None, description="Unix timestamp to end at"),
|
||||
docker: DockerManager = Depends(get_docker_manager),
|
||||
) -> ContainerLogsResponse:
|
||||
"""
|
||||
Get logs from a container.
|
||||
|
||||
Only managed containers can have their logs retrieved.
|
||||
"""
|
||||
tail_value = "all" if tail == 0 else tail
|
||||
return docker.get_logs(
|
||||
container_id,
|
||||
stdout=stdout,
|
||||
stderr=stderr,
|
||||
tail=tail_value,
|
||||
since=since,
|
||||
until=until,
|
||||
)
|
||||
|
||||
|
||||
@router.get("/{container_id}/stats", response_model=ContainerStatsResponse)
|
||||
async def get_container_stats(
|
||||
container_id: str,
|
||||
docker: DockerManager = Depends(get_docker_manager),
|
||||
) -> ContainerStatsResponse:
|
||||
"""
|
||||
Get resource usage statistics for a container.
|
||||
|
||||
Returns CPU, memory, and network statistics.
|
||||
Only managed containers can have their stats retrieved.
|
||||
"""
|
||||
return docker.get_stats(container_id)
|
||||
Reference in New Issue
Block a user