hardware_query/
virtualization.rs

1//! Virtualization and container detection module
2//!
3//! This module provides detection and analysis of virtualized environments,
4//! including containers, virtual machines, and their impact on hardware performance.
5
6use crate::Result;
7use serde::{Deserialize, Serialize};
8use std::collections::HashMap;
9
10/// Virtualization environment information
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct VirtualizationInfo {
13    /// Type of virtualization environment
14    pub environment_type: VirtualizationType,
15    /// Hypervisor name and version (if applicable)
16    pub hypervisor: Option<String>,
17    /// Container runtime information (if applicable)
18    pub container_runtime: Option<ContainerRuntime>,
19    /// Resource limits imposed by the virtualization layer
20    pub resource_limits: ResourceLimits,
21    /// GPU passthrough capabilities
22    pub gpu_passthrough: GPUPassthroughInfo,
23    /// Performance impact factor (0.0 to 1.0, where 1.0 is native performance)
24    pub performance_impact: f64,
25    /// Nested virtualization support
26    pub nested_virtualization: bool,
27    /// Security features enabled
28    pub security_features: Vec<SecurityFeature>,
29    /// Platform-specific virtualization details
30    pub platform_specific: HashMap<String, String>,
31}
32
33/// Type of virtualization environment
34#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
35pub enum VirtualizationType {
36    /// Running on bare metal
37    Native,
38    /// Docker container
39    Docker,
40    /// Kubernetes pod
41    Kubernetes,
42    /// LXC/LXD container
43    LXC,
44    /// Podman container
45    Podman,
46    /// Full virtual machine
47    VirtualMachine,
48    /// Windows Subsystem for Linux
49    WSL,
50    /// Windows Subsystem for Linux 2
51    WSL2,
52    /// Wine compatibility layer
53    Wine,
54    /// macOS virtualization
55    MacOSVirtualization,
56    /// Unknown virtualization
57    Unknown,
58}
59
60/// Container runtime information
61#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct ContainerRuntime {
63    /// Runtime name (docker, containerd, cri-o, etc.)
64    pub name: String,
65    /// Runtime version
66    pub version: Option<String>,
67    /// Container ID
68    pub container_id: Option<String>,
69    /// Container image
70    pub image: Option<String>,
71    /// Container orchestrator (if any)
72    pub orchestrator: Option<String>,
73    /// Security context
74    pub security_context: SecurityContext,
75}
76
77/// Security context for containers
78#[derive(Debug, Clone, Serialize, Deserialize)]
79pub struct SecurityContext {
80    /// Running as privileged container
81    pub privileged: bool,
82    /// User namespace mapping
83    pub user_namespace: bool,
84    /// AppArmor/SELinux profile
85    pub security_profile: Option<String>,
86    /// Capabilities granted
87    pub capabilities: Vec<String>,
88    /// Resource isolation level
89    pub isolation_level: IsolationLevel,
90}
91
92/// Container isolation level
93#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
94pub enum IsolationLevel {
95    /// Full isolation
96    Full,
97    /// Partial isolation
98    Partial,
99    /// Minimal isolation
100    Minimal,
101    /// No isolation (dangerous)
102    None,
103}
104
105/// Resource limits imposed by virtualization
106#[derive(Debug, Clone, Serialize, Deserialize)]
107pub struct ResourceLimits {
108    /// CPU limits
109    pub cpu_limits: CPULimits,
110    /// Memory limits
111    pub memory_limits: MemoryLimits,
112    /// I/O limits
113    pub io_limits: IOLimits,
114    /// Network limits
115    pub network_limits: NetworkLimits,
116    /// GPU access restrictions
117    pub gpu_limits: GPULimits,
118}
119
120/// CPU resource limits
121#[derive(Debug, Clone, Serialize, Deserialize)]
122pub struct CPULimits {
123    /// Maximum CPU cores available
124    pub max_cores: Option<u32>,
125    /// CPU quota percentage
126    pub quota_percent: Option<f32>,
127    /// CPU shares/weight
128    pub shares: Option<u32>,
129    /// CPU affinity mask
130    pub affinity_mask: Option<String>,
131    /// Specific CPU features disabled
132    pub disabled_features: Vec<String>,
133}
134
135/// Memory resource limits
136#[derive(Debug, Clone, Serialize, Deserialize)]
137pub struct MemoryLimits {
138    /// Maximum memory in bytes
139    pub max_memory_bytes: Option<u64>,
140    /// Maximum swap in bytes
141    pub max_swap_bytes: Option<u64>,
142    /// Memory reservation in bytes
143    pub reservation_bytes: Option<u64>,
144    /// OOM killer disabled
145    pub oom_kill_disabled: bool,
146    /// NUMA policy restrictions
147    pub numa_policy: Option<String>,
148}
149
150/// I/O resource limits
151#[derive(Debug, Clone, Serialize, Deserialize)]
152pub struct IOLimits {
153    /// Maximum read IOPS
154    pub max_read_iops: Option<u64>,
155    /// Maximum write IOPS
156    pub max_write_iops: Option<u64>,
157    /// Maximum read bandwidth (bytes/sec)
158    pub max_read_bps: Option<u64>,
159    /// Maximum write bandwidth (bytes/sec)
160    pub max_write_bps: Option<u64>,
161    /// Block device weights
162    pub device_weights: HashMap<String, u32>,
163}
164
165/// Network resource limits
166#[derive(Debug, Clone, Serialize, Deserialize)]
167pub struct NetworkLimits {
168    /// Maximum bandwidth (bits/sec)
169    pub max_bandwidth_bps: Option<u64>,
170    /// Network namespace isolation
171    pub network_namespace: bool,
172    /// Port mapping restrictions
173    pub port_restrictions: Vec<PortRestriction>,
174    /// Network policies
175    pub network_policies: Vec<String>,
176}
177
178/// Port access restriction
179#[derive(Debug, Clone, Serialize, Deserialize)]
180pub struct PortRestriction {
181    /// Port number or range
182    pub port: String,
183    /// Protocol (TCP/UDP)
184    pub protocol: String,
185    /// Access type (allow/deny)
186    pub access: AccessType,
187}
188
189/// Access control type
190#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
191pub enum AccessType {
192    Allow,
193    Deny,
194}
195
196/// GPU access limitations
197#[derive(Debug, Clone, Serialize, Deserialize)]
198pub struct GPULimits {
199    /// GPU access allowed
200    pub gpu_access: bool,
201    /// Specific GPU devices accessible
202    pub accessible_devices: Vec<String>,
203    /// GPU memory limits
204    pub memory_limits: HashMap<String, u64>,
205    /// Compute capability restrictions
206    pub capability_restrictions: Vec<String>,
207}
208
209/// GPU passthrough information
210#[derive(Debug, Clone, Serialize, Deserialize)]
211pub struct GPUPassthroughInfo {
212    /// GPU passthrough available
213    pub available: bool,
214    /// Type of GPU passthrough
215    pub passthrough_type: GPUPassthroughType,
216    /// Passed-through devices
217    pub devices: Vec<PassthroughDevice>,
218    /// Performance overhead
219    pub performance_overhead: f64,
220}
221
222/// Type of GPU passthrough
223#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
224pub enum GPUPassthroughType {
225    /// Full GPU passthrough
226    Full,
227    /// SR-IOV virtual functions
228    SRIOV,
229    /// GPU sharing/virtualization
230    Shared,
231    /// Software-only GPU emulation
232    Emulated,
233    /// No GPU access
234    None,
235}
236
237/// Passthrough device information
238#[derive(Debug, Clone, Serialize, Deserialize)]
239pub struct PassthroughDevice {
240    /// Device ID
241    pub device_id: String,
242    /// Device name
243    pub device_name: String,
244    /// PCI address
245    pub pci_address: Option<String>,
246    /// Driver used
247    pub driver: Option<String>,
248}
249
250/// Security features enabled in virtualization
251#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
252pub enum SecurityFeature {
253    /// Secure Boot enabled
254    SecureBoot,
255    /// Intel TXT/AMD SVM
256    TrustedExecution,
257    /// Intel VT-d/AMD-Vi
258    IOMMU,
259    /// Kernel Guard Technology
260    KGT,
261    /// Control Flow Integrity
262    CFI,
263    /// Address Space Layout Randomization
264    ASLR,
265    /// Data Execution Prevention
266    DEP,
267    /// Hypervisor-protected Code Integrity
268    HVCI,
269    /// Memory Protection Keys
270    MPK,
271    /// Intel CET
272    CET,
273}
274
275impl VirtualizationInfo {
276    /// Detect current virtualization environment
277    pub fn detect() -> Result<Self> {
278        let environment_type = Self::detect_environment_type()?;
279        let hypervisor = Self::detect_hypervisor()?;
280        let container_runtime = Self::detect_container_runtime()?;
281        let resource_limits = Self::detect_resource_limits()?;
282        let gpu_passthrough = Self::detect_gpu_passthrough()?;
283        let performance_impact = Self::calculate_performance_impact(&environment_type);
284        let nested_virtualization = Self::detect_nested_virtualization()?;
285        let security_features = Self::detect_security_features()?;
286        let platform_specific = Self::gather_platform_specific_info()?;
287
288        Ok(Self {
289            environment_type,
290            hypervisor,
291            container_runtime,
292            resource_limits,
293            gpu_passthrough,
294            performance_impact,
295            nested_virtualization,
296            security_features,
297            platform_specific,
298        })
299    }
300
301    /// Check if running in any virtualized environment
302    pub fn is_virtualized(&self) -> bool {
303        self.environment_type != VirtualizationType::Native
304    }
305
306    /// Check if running in a container
307    pub fn is_containerized(&self) -> bool {
308        matches!(
309            self.environment_type,
310            VirtualizationType::Docker
311                | VirtualizationType::Kubernetes
312                | VirtualizationType::LXC
313                | VirtualizationType::Podman
314        )
315    }
316
317    /// Check if running in a virtual machine
318    pub fn is_virtual_machine(&self) -> bool {
319        matches!(
320            self.environment_type,
321            VirtualizationType::VirtualMachine | VirtualizationType::WSL | VirtualizationType::WSL2
322        )
323    }
324
325    /// Get estimated performance compared to bare metal
326    pub fn get_performance_factor(&self) -> f64 {
327        self.performance_impact
328    }
329
330    /// Check if GPU acceleration is available
331    pub fn has_gpu_access(&self) -> bool {
332        self.gpu_passthrough.available || self.resource_limits.gpu_limits.gpu_access
333    }
334
335    /// Get security recommendations for the current environment
336    pub fn get_security_recommendations(&self) -> Vec<String> {
337        let mut recommendations = Vec::new();
338
339        if self.is_containerized() {
340            if let Some(runtime) = &self.container_runtime {
341                if runtime.security_context.privileged {
342                    recommendations.push(
343                        "Consider running container in non-privileged mode for better security"
344                            .to_string(),
345                    );
346                }
347
348                if !runtime.security_context.user_namespace {
349                    recommendations.push(
350                        "Enable user namespace mapping for better isolation".to_string(),
351                    );
352                }
353
354                if runtime.security_context.security_profile.is_none() {
355                    recommendations.push(
356                        "Apply AppArmor/SELinux security profile".to_string(),
357                    );
358                }
359            }
360        }
361
362        if self.is_virtual_machine() && !self.security_features.contains(&SecurityFeature::SecureBoot) {
363            recommendations.push("Enable Secure Boot for enhanced security".to_string());
364        }
365
366        if self.gpu_passthrough.available
367            && matches!(
368                self.gpu_passthrough.passthrough_type,
369                GPUPassthroughType::Full
370            )
371        {
372            recommendations.push(
373                "GPU passthrough detected - ensure IOMMU isolation is properly configured"
374                    .to_string(),
375            );
376        }
377
378        recommendations
379    }
380
381    fn detect_environment_type() -> Result<VirtualizationType> {
382        // Platform-specific detection logic would go here
383        // For now, implement basic detection
384
385        // Check for common container indicators
386        if Self::check_docker_container()? {
387            return Ok(VirtualizationType::Docker);
388        }
389
390        if Self::check_kubernetes_pod()? {
391            return Ok(VirtualizationType::Kubernetes);
392        }
393
394        if Self::check_wsl()? {
395            return Ok(VirtualizationType::WSL);
396        }
397
398        // Check for VM indicators
399        if Self::check_virtual_machine()? {
400            return Ok(VirtualizationType::VirtualMachine);
401        }
402
403        Ok(VirtualizationType::Native)
404    }
405
406    fn check_docker_container() -> Result<bool> {
407        // Check for /.dockerenv file
408        Ok(std::path::Path::new("/.dockerenv").exists())
409    }
410
411    fn check_kubernetes_pod() -> Result<bool> {
412        // Check for Kubernetes environment variables
413        Ok(std::env::var("KUBERNETES_SERVICE_HOST").is_ok())
414    }
415
416    fn check_wsl() -> Result<bool> {
417        // Check for WSL indicators
418        #[cfg(target_os = "linux")]
419        {
420            if let Ok(version) = std::fs::read_to_string("/proc/version") {
421                return Ok(version.to_lowercase().contains("microsoft"));
422            }
423        }
424        Ok(false)
425    }
426
427    fn check_virtual_machine() -> Result<bool> {
428        // Basic VM detection - would be enhanced with platform-specific checks
429        Ok(false)
430    }
431
432    fn detect_hypervisor() -> Result<Option<String>> {
433        // Platform-specific hypervisor detection
434        Ok(None)
435    }
436
437    fn detect_container_runtime() -> Result<Option<ContainerRuntime>> {
438        // Container runtime detection
439        Ok(None)
440    }
441
442    fn detect_resource_limits() -> Result<ResourceLimits> {
443        // Resource limits detection
444        Ok(ResourceLimits {
445            cpu_limits: CPULimits {
446                max_cores: None,
447                quota_percent: None,
448                shares: None,
449                affinity_mask: None,
450                disabled_features: Vec::new(),
451            },
452            memory_limits: MemoryLimits {
453                max_memory_bytes: None,
454                max_swap_bytes: None,
455                reservation_bytes: None,
456                oom_kill_disabled: false,
457                numa_policy: None,
458            },
459            io_limits: IOLimits {
460                max_read_iops: None,
461                max_write_iops: None,
462                max_read_bps: None,
463                max_write_bps: None,
464                device_weights: HashMap::new(),
465            },
466            network_limits: NetworkLimits {
467                max_bandwidth_bps: None,
468                network_namespace: false,
469                port_restrictions: Vec::new(),
470                network_policies: Vec::new(),
471            },
472            gpu_limits: GPULimits {
473                gpu_access: true,
474                accessible_devices: Vec::new(),
475                memory_limits: HashMap::new(),
476                capability_restrictions: Vec::new(),
477            },
478        })
479    }
480
481    fn detect_gpu_passthrough() -> Result<GPUPassthroughInfo> {
482        // GPU passthrough detection
483        Ok(GPUPassthroughInfo {
484            available: false,
485            passthrough_type: GPUPassthroughType::None,
486            devices: Vec::new(),
487            performance_overhead: 0.0,
488        })
489    }
490
491    fn calculate_performance_impact(env_type: &VirtualizationType) -> f64 {
492        match env_type {
493            VirtualizationType::Native => 1.0,
494            VirtualizationType::Docker | VirtualizationType::LXC | VirtualizationType::Podman => 0.95,
495            VirtualizationType::Kubernetes => 0.92,
496            VirtualizationType::WSL2 => 0.90,
497            VirtualizationType::VirtualMachine => 0.85,
498            VirtualizationType::WSL => 0.80,
499            VirtualizationType::Wine => 0.75,
500            _ => 0.70,
501        }
502    }
503
504    fn detect_nested_virtualization() -> Result<bool> {
505        // Nested virtualization detection
506        Ok(false)
507    }
508
509    fn detect_security_features() -> Result<Vec<SecurityFeature>> {
510        // Security features detection
511        Ok(Vec::new())
512    }
513
514    fn gather_platform_specific_info() -> Result<HashMap<String, String>> {
515        // Platform-specific information gathering
516        Ok(HashMap::new())
517    }
518}
519
520impl std::fmt::Display for VirtualizationType {
521    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
522        match self {
523            VirtualizationType::Native => write!(f, "Native"),
524            VirtualizationType::Docker => write!(f, "Docker"),
525            VirtualizationType::Kubernetes => write!(f, "Kubernetes"),
526            VirtualizationType::LXC => write!(f, "LXC"),
527            VirtualizationType::Podman => write!(f, "Podman"),
528            VirtualizationType::VirtualMachine => write!(f, "Virtual Machine"),
529            VirtualizationType::WSL => write!(f, "WSL"),
530            VirtualizationType::WSL2 => write!(f, "WSL2"),
531            VirtualizationType::Wine => write!(f, "Wine"),
532            VirtualizationType::MacOSVirtualization => write!(f, "macOS Virtualization"),
533            VirtualizationType::Unknown => write!(f, "Unknown"),
534        }
535    }
536}