container.py
Overview
The container.py module is a core part of the InfiniFlow application responsible for managing sandboxed container environments used to safely execute code snippets in supported languages, specifically Python and Node.js. It provides asynchronous lifecycle management of Docker containers, including creation, allocation, release, recreation after crashes, and teardown.
This file ensures efficient container pooling, safe concurrent access, and resource constraint enforcement, enabling isolated and repeatable execution of user or system code within sandboxed containers. The container management supports concurrency via asyncio primitives and enforces memory limits and security configurations for sandbox containers.
Classes and Functions
Module-level Variables
_CONTAINER_QUEUES: dict[SupportLanguage, Queue]
Queues holding the names of available containers by language._CONTAINER_LOCK: asyncio.Lock
An asyncio lock to synchronize access to container queues._CONTAINER_EXECUTION_SEMAPHORES: dict[SupportLanguage, asyncio.Semaphore]
Semaphores to limit concurrent container execution per language.
async def init_containers(size: int) -> tuple[int, int]
Initializes the container pools for each supported language by creating a fixed number (size) of Docker containers for Python and Node.js.
Parameters:
size(int): Number of containers to create per language.
Returns:
Tuple
(success_count, total_task_count), where success_count is the number of containers successfully created, andtotal_task_countis the total number of container creation tasks attempted.
Usage Example:
success, total = await init_containers(5)
print(f"Created {success}/{total} containers successfully.")
Details:
Clears existing container queues.
Creates asyncio semaphores to limit concurrency.
Launches container preparation coroutines concurrently for Python and Node.js containers.
Uses
_prepare_containerinternally to create and enqueue containers.
async def teardown_containers()
Gracefully removes all containers from both Python and Node.js queues by stopping and deleting the corresponding Docker containers.
Returns: None
Details:
Acquires
_CONTAINER_LOCKto synchronize queue access.Iteratively removes containers using
docker rm -f <container_name>.Ensures cleanup of all containers managed by this module.
async def _prepare_container(name: str, language: SupportLanguage) -> bool
Internal helper to prepare a single container instance.
Parameters:
name(str): Docker container name.language(SupportLanguage): Programming language of the container.
Returns:
Trueif container is successfully prepared and enqueued; otherwiseFalse.
Details:
Removes any existing container with the same name (ignoring errors).
Calls
create_containerto spin up a new container.On success, adds container name to the appropriate queue.
async def create_container(name: str, language: SupportLanguage) -> bool
Creates and starts a container asynchronously with the appropriate runtime, resource limits, and base image.
Parameters:
name(str): Container name.language(SupportLanguage): Language type for selecting base Docker image.
Returns:
Trueif container creation and basic setup succeed; elseFalse.
Implementation Details:
Builds Docker run command with options:
Read-only filesystem.
Temporary filesystems on
/workspaceand/tmp.User set to
nobodyfor security.Memory limits from env var
SANDBOX_MAX_MEMORYor default256m.Optional Seccomp profile if enabled via env var.
Uses runtime
runsc(gVisor) for container isolation.Selects base image via env vars
SANDBOX_BASE_PYTHON_IMAGEorSANDBOX_BASE_NODEJS_IMAGE.For Node.js containers, copies
/app/node_modulesinto/workspaceafter startup (to prepare dependencies).Verifies container is running using
container_is_running().
Usage Example:
success = await create_container("sandbox_python_1", SupportLanguage.PYTHON)
if success:
print("Container created successfully.")
async def recreate_container(name: str, language: SupportLanguage) -> bool
Recreates a container by forcefully removing the existing one and creating a new container with the same name and language.
Parameters:
name(str): Container name.language(SupportLanguage): Container language.
Returns:
Trueif recreation succeeds; elseFalse.
Usage Example:
await recreate_container("sandbox_nodejs_3", SupportLanguage.NODEJS)
async def release_container(name: str, language: SupportLanguage)
Releases a container back into the available pool if it is still running; otherwise, attempts to recreate it before returning it to the pool.
Parameters:
name(str): Container name to release.language(SupportLanguage): Language of the container.
Returns: None
Details:
Uses
_CONTAINER_LOCKto synchronize queue operations.Checks container status via
container_is_running.If crashed, attempts recreation.
Logs relevant info on success or failure.
async def allocate_container_blocking(language: SupportLanguage, timeout=10) -> str
Attempts to allocate an available container from the pool for the given language, blocking asynchronously until timeout if none are immediately available.
Parameters:
language(SupportLanguage): Language of the container requested.timeout(float): Max wait time in seconds.
Returns:
Container name (
str) if allocated successfully; empty string""if timeout occurs without allocation.
Details:
Polls the language queue for container names.
Checks container health before returning.
Attempts recreation if container is not running.
Usage Example:
container_name = await allocate_container_blocking(SupportLanguage.PYTHON, timeout=5)
if container_name:
print(f"Allocated container: {container_name}")
else:
print("No container available within timeout.")
async def container_is_running(name: str) -> bool
Checks asynchronously whether the specified container is currently running.
Parameters:
name(str): Container name.
Returns:
Trueif container is running;Falseotherwise.
Details:
Runs
docker inspectcommand with Go template to get.State.Runningstatus.Handles exceptions gracefully returning
False.
Implementation Details & Algorithms
Container Pooling:
Uses Pythonqueue.Queueto maintain a pool of container names per language. Containers are recycled by releasing them back to the queue after use.Concurrency Control:
Employs anasyncio.Lockto synchronize queue operations ensuring thread-safe access. Usesasyncio.Semaphoreper language to limit concurrent container usage.Container Creation:
Containers are created with strict security and resource constraints, including read-only filesystem, tmpfs mounts, user restrictions, memory limits, and optional seccomp profiles.Container Health Checking:
Before allocation or release, containers are checked for running status to avoid handing out crashed containers.Crash Recovery:
If a container crashes or becomes unresponsive, it is recreated automatically to maintain pool integrity.Async Docker Commands:
All system calls to Docker CLI are run asynchronously viaasync_run_commandutility.
Interaction with Other System Components
models.enums.SupportLanguage:
Enum defining supported languages (PYTHON,NODEJS) used throughout for language-specific container handling.util.env_setting_enabled:
Utility to check environment flags (e.g., enabling seccomp profiles).util.is_valid_memory_limit:
Validates memory limit strings for Docker.utils.common.async_run_command:
Async utility to run shell commands, crucial for Docker CLI interactions.core.logger.logger:
Used for structured logging of container lifecycle events and errors.This module is likely used by higher-level request handlers or execution managers in InfiniFlow that require sandboxed environments to run user code safely and efficiently.
Visual Diagram
classDiagram
class ContainerManager {
<<module>>
- _CONTAINER_QUEUES: dict[SupportLanguage, Queue]
- _CONTAINER_LOCK: asyncio.Lock
- _CONTAINER_EXECUTION_SEMAPHORES: dict[SupportLanguage, asyncio.Semaphore]
+ init_containers(size: int) tuple[int, int]
+ teardown_containers()
- _prepare_container(name: str, language: SupportLanguage) bool
+ create_container(name: str, language: SupportLanguage) bool
+ recreate_container(name: str, language: SupportLanguage) bool
+ release_container(name: str, language: SupportLanguage)
+ allocate_container_blocking(language: SupportLanguage, timeout=10) str
+ container_is_running(name: str) bool
}
ContainerManager ..> SupportLanguage : uses
ContainerManager ..> async_run_command : calls
ContainerManager ..> logger : logs events
Summary
The container.py module in InfiniFlow efficiently manages isolated Docker containers for executing Python and Node.js code in a sandboxed environment. It supports asynchronous operations to create, allocate, release, recreate, and teardown containers with robust concurrency control and health checking. By leveraging Docker features and asyncio synchronization primitives, it ensures secure, scalable, and performant container lifecycle management critical for multi-tenant code execution workloads.