feat: add terminal support for guest execution agent and enhance lifecycle management
This commit is contained in:
@@ -19,6 +19,7 @@ from .firecracker.config import build_config, write_config
|
||||
from .firecracker.process import FirecrackerProcessManager, ProcessInfo
|
||||
from .guest_agent import DEFAULT_TIMEOUT_SECONDS
|
||||
from .guest_exec import ExecResult, GuestSession, validate_exec
|
||||
from .guest_terminal import GuestTerminal, validate_size
|
||||
from .images import ImageStore
|
||||
from .integrity import load_manifest, verify_file
|
||||
from .known_hosts import KnownHostsManager
|
||||
@@ -61,6 +62,7 @@ class LifecycleService:
|
||||
known_hosts: KnownHostsManager,
|
||||
client_factory: Callable[[Path, float], FirecrackerClient] = FirecrackerClient,
|
||||
guest_connector: Callable[[Path, str, str, int], GuestSession] = GuestSession.connect,
|
||||
terminal_connector: Callable[[Path, str, str, int], GuestTerminal] = GuestTerminal.connect,
|
||||
clock: Callable[[], float] = time.time,
|
||||
) -> None:
|
||||
self._settings = settings
|
||||
@@ -71,6 +73,7 @@ class LifecycleService:
|
||||
self._known_hosts = known_hosts
|
||||
self._client_factory = client_factory
|
||||
self._guest_connector = guest_connector
|
||||
self._terminal_connector = terminal_connector
|
||||
self._clock = clock
|
||||
|
||||
def create(self, spec: VmSpec) -> VmRecord:
|
||||
@@ -520,6 +523,24 @@ class LifecycleService:
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
def open_terminal(self, vm_id: str, *, rows: int = 24, cols: int = 80) -> tuple[GuestTerminal, str]:
|
||||
"""Connect to the exact running VMM under the lock, then open its guest PTY."""
|
||||
require_root()
|
||||
validate_size(rows, cols)
|
||||
with self._state_store.operation_lock():
|
||||
vm = self._load_for_operation(vm_id, exact_id=True)
|
||||
self._not_deleting(vm)
|
||||
if (vm.status != "running" or vm.operation is not None or vm.pending_resize is not None
|
||||
or self._process.observe(vm) != "alive"):
|
||||
raise ConflictError("terminal sessions require a running VM with no pending lifecycle operation")
|
||||
terminal = self._terminal_connector(self._settings.guest_socket_path(vm.id), vm.id, vm.username, vm.pid)
|
||||
try:
|
||||
terminal.start(rows, cols)
|
||||
return terminal, vm.username
|
||||
except BaseException:
|
||||
terminal.close()
|
||||
raise
|
||||
|
||||
def install_guest_agent(self, vm_id: str) -> VmRecord:
|
||||
"""Explicitly install/upgrade the agent on a cleanly stopped private disk."""
|
||||
require_root()
|
||||
|
||||
Reference in New Issue
Block a user