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
+38 -1
View File
@@ -5,9 +5,12 @@ from __future__ import annotations
from ipaddress import IPv4Address
from typing import Literal
from pydantic import BaseModel, ConfigDict, Field, SecretStr
from pydantic import BaseModel, ConfigDict, Field, SecretStr, model_validator
from .domain import VmRecord
from .errors import ValidationError
from .guest_agent import DEFAULT_TIMEOUT_SECONDS, MAX_COMMAND_BYTES, MAX_TIMEOUT_SECONDS
from .guest_exec import validate_exec
class HealthResponse(BaseModel):
@@ -112,6 +115,40 @@ class VmLogResponse(BaseModel):
truncated: bool
class VmExecRequest(BaseModel):
model_config = ConfigDict(extra="forbid")
command: str = Field(strict=True, min_length=1, max_length=MAX_COMMAND_BYTES, repr=False,
description="Command or multiline script interpreted by /bin/sh inside the guest; at most 64 KiB UTF-8")
sudo: bool = Field(default=False, strict=True, description="Run as guest root instead of the VM's configured login user")
timeout_seconds: float = Field(default=DEFAULT_TIMEOUT_SECONDS, strict=True, gt=0,
le=MAX_TIMEOUT_SECONDS, allow_inf_nan=False)
@model_validator(mode="before")
@classmethod
def validate_execution(cls, value: object) -> object:
# Use the domain error envelope: echoing NaN or unpaired surrogates in
# FastAPI's validation-error input can itself fail JSON serialization.
if not isinstance(value, dict) or set(value) - {"command", "sudo", "timeout_seconds"}:
raise ValidationError("execution requires an object with command, sudo, and timeout_seconds fields only")
validate_exec(value.get("command"), value.get("sudo", False), value.get("timeout_seconds", DEFAULT_TIMEOUT_SECONDS))
return value
class VmExecResponse(BaseModel):
exit_code: int | None
stdout: str
stderr: str
timed_out: bool
truncated: bool
class VmAgentInstallResponse(BaseModel):
id: str
status: Literal["installed"] = "installed"
restart_required: bool = True
class DiagnosticResponse(BaseModel):
name: str
ok: bool