feat: Add guest execution agent and vsock support

- Introduced a standalone guest execution agent to facilitate command execution within the guest VM over Firecracker's vsock.
- Enhanced FirecrackerClient to support vsock configuration, validating guest CID and UDS path.
- Updated configuration to include vsock settings by default.
- Refactored FirecrackerProcessManager to manage runtime sockets more effectively.
- Implemented guest agent installation and provisioning in the image store.
- Added API endpoints for executing commands in the VM and installing the guest agent.
- Improved error handling for guest execution failures and agent availability.
This commit is contained in:
2026-09-25 17:39:06 +05:30
parent dca7f78dae
commit b0bf99a6ee
25 changed files with 1893 additions and 30 deletions
+12 -2
View File
@@ -9,7 +9,10 @@ import ssl
from typing import Any
from .app import Application, build_application
from .errors import ConfigurationError, ConflictError, NotFoundError, UvmError, ValidationError
from .errors import (
ConfigurationError, ConflictError, GuestAgentUnavailableError, GuestExecutionError,
NotFoundError, UvmError, ValidationError,
)
def create_api(application: Application | None = None, *, host: str | None = None) -> Any:
@@ -49,9 +52,12 @@ def create_api(application: Application | None = None, *, host: str | None = Non
@api.exception_handler(UvmError)
async def handle_uvm_error(_request: Any, error: UvmError) -> Any:
detail: dict[str, Any] = {"message": str(error)}
if isinstance(error, GuestExecutionError):
detail["outcome_unknown"] = error.outcome_unknown
return JSONResponse(
status_code=_http_status_for(error),
content={"error": {"message": str(error)}},
content={"error": detail},
)
api.include_router(health_router)
@@ -130,6 +136,10 @@ def _validate_server_settings(
def _http_status_for(error: UvmError) -> int:
if isinstance(error, GuestAgentUnavailableError):
return 503
if isinstance(error, GuestExecutionError):
return 502
if isinstance(error, NotFoundError):
return 404
if isinstance(error, ConflictError):