feat (ui): exec fase 4
This commit is contained in:
@@ -35,6 +35,8 @@ _EXEC_SESSIONS = {} # session_id -> _ExecSessionState
|
||||
_EXEC_SESSIONS_LOCK = threading.Lock()
|
||||
_EXEC_SESSION_IDLE_TTL_SECONDS = 60 * 60
|
||||
_EXEC_SESSION_CLOSED_GC_SECONDS = 5 * 60
|
||||
_EXEC_SESSION_MAX_ACTIVE = 12
|
||||
_EXEC_INPUT_MAX_BYTES = 32 * 1024
|
||||
|
||||
|
||||
class ExecStartRequest(BaseModel):
|
||||
@@ -246,6 +248,27 @@ def _parse_stats_interval_seconds() -> float:
|
||||
return v
|
||||
|
||||
|
||||
def _parse_positive_int_env(name: str, default: int, minimum: int, maximum: int) -> int:
|
||||
raw = os.getenv(name, str(default))
|
||||
try:
|
||||
v = int(raw)
|
||||
except Exception:
|
||||
v = int(default)
|
||||
if v < minimum:
|
||||
v = minimum
|
||||
if v > maximum:
|
||||
v = maximum
|
||||
return v
|
||||
|
||||
|
||||
def _exec_max_active_sessions() -> int:
|
||||
return _parse_positive_int_env("EXEC_SESSION_MAX_ACTIVE", _EXEC_SESSION_MAX_ACTIVE, 1, 500)
|
||||
|
||||
|
||||
def _exec_max_input_bytes() -> int:
|
||||
return _parse_positive_int_env("EXEC_INPUT_MAX_BYTES", _EXEC_INPUT_MAX_BYTES, 64, 1024 * 1024)
|
||||
|
||||
|
||||
async def _stats_poller_loop():
|
||||
global _STATS_CACHE_BY_NAME, _STATS_CACHE_TS
|
||||
|
||||
@@ -592,6 +615,15 @@ def init_containers_router(
|
||||
req = ExecStartRequest()
|
||||
cmd = req.cmd or ["/bin/sh"]
|
||||
|
||||
with _EXEC_SESSIONS_LOCK:
|
||||
active = sum(1 for s in _EXEC_SESSIONS.values() if not s.closed)
|
||||
max_active = _exec_max_active_sessions()
|
||||
if active >= max_active:
|
||||
raise HTTPException(
|
||||
status_code=429,
|
||||
detail=f"Too many active exec sessions ({active}/{max_active})",
|
||||
)
|
||||
|
||||
create_url = f"{podman_api_base}/libpod/containers/{name}/exec"
|
||||
payload = {
|
||||
"AttachStdin": True,
|
||||
@@ -714,6 +746,12 @@ def init_containers_router(
|
||||
data = (req.data or "").encode("utf-8")
|
||||
if not data:
|
||||
return {"ok": True, "session_id": session_id, "bytes": 0}
|
||||
max_bytes = _exec_max_input_bytes()
|
||||
if len(data) > max_bytes:
|
||||
raise HTTPException(
|
||||
status_code=413,
|
||||
detail=f"Input too large ({len(data)} bytes > {max_bytes} bytes)",
|
||||
)
|
||||
|
||||
try:
|
||||
sess.sock.sendall(data)
|
||||
|
||||
Reference in New Issue
Block a user