1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use std::path::PathBuf;
use std::sync::Arc;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::config::VmSpec;
use crate::network::NetworkAllocation;
/// Unique VM identifier (UUID string).
pub type VmId = String;
/// Lifecycle state of a single VM.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum VmState {
/// Resources allocated; process not yet started.
Created,
/// Firecracker booted and guest is running.
Running,
/// Guest execution paused (snapshot-ready).
Paused,
/// Guest has shut down or was stopped.
Stopped,
/// An unrecoverable error occurred.
Failed,
}
impl std::fmt::Display for VmState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Created => write!(f, "created"),
Self::Running => write!(f, "running"),
Self::Paused => write!(f, "paused"),
Self::Stopped => write!(f, "stopped"),
Self::Failed => write!(f, "failed"),
}
}
}
/// Per-VM runtime state.
pub struct VmInstance {
/// Unique identifier.
pub id: VmId,
/// Human-readable name.
pub name: String,
/// Original creation spec.
pub spec: VmSpec,
/// Current lifecycle state.
pub state: VmState,
/// Handle to the Firecracker process (present while the process is alive).
pub process: Option<fc_sdk::FirecrackerProcess>,
/// Post-boot API handle (present once the VM has booted).
/// Wrapped in `Arc` so the manager can share the handle without re-constructing it.
pub vm: Option<Arc<fc_sdk::Vm>>,
/// Allocated network resources.
pub network: Option<NetworkAllocation>,
/// Path to the Firecracker API socket for this VM.
pub socket_path: PathBuf,
/// When the VM record was created.
pub created_at: DateTime<Utc>,
/// When the VM last transitioned to `Running`.
pub started_at: Option<DateTime<Utc>>,
}
impl VmInstance {
/// Create a new instance in the `Created` state.
pub fn new(id: VmId, name: String, spec: VmSpec, socket_path: PathBuf) -> Self {
Self {
id,
name,
spec,
state: VmState::Created,
process: None,
vm: None,
network: None,
socket_path,
created_at: Utc::now(),
started_at: None,
}
}
}
/// Lightweight summary for list operations.
#[derive(Debug, Clone)]
pub struct VmSummary {
pub id: VmId,
pub name: String,
pub state: VmState,
pub vcpus: u64,
pub memory_mib: u64,
pub ip_address: Option<String>,
pub created_at: DateTime<Utc>,
}
/// Detailed VM information for inspect operations.
#[derive(Debug, Clone)]
pub struct VmInfo {
pub id: VmId,
pub name: String,
pub state: VmState,
pub spec: VmSpec,
pub network: Option<NetworkAllocation>,
pub socket_path: PathBuf,
pub created_at: DateTime<Utc>,
pub started_at: Option<DateTime<Utc>>,
}
/// Metrics snapshot for a VM.
#[derive(Debug, Clone)]
pub struct VmMetrics {
pub vm_id: VmId,
/// Balloon target in MiB (None if no balloon device).
pub balloon_target_mib: Option<i64>,
/// Actual balloon size in MiB.
pub balloon_actual_mib: Option<i64>,
}