@@ -451,6 +451,22 @@ class ResourceDiskType(str, Enum):
451451 NVME = constants .STORAGE_INTERFACE_TYPE_NVME
452452
453453
454+ class VirtualizationHostType (str , Enum ):
455+ """
456+ Virtualization host type enumeration.
457+ Defines the type of hypervisor or virtualization platform being used.
458+ """
459+
460+ # Physical hardware without virtualization
461+ BareMetal = "BareMetal"
462+ # Microsoft Hyper-V hypervisor
463+ HyperV = "HyperV"
464+ # QEMU/KVM virtualization
465+ QEMU = "QEMU"
466+ # Cloud Hypervisor
467+ CloudHypervisor = "CloudHypervisor"
468+
469+
454470disk_controller_type_priority : List [DiskControllerType ] = [
455471 DiskControllerType .SCSI ,
456472 DiskControllerType .NVME ,
@@ -847,6 +863,104 @@ def _call_requirement_method(
847863 return value
848864
849865
866+ @dataclass_json ()
867+ @dataclass ()
868+ class VirtualizationSettings (FeatureSettings ):
869+ """
870+ Virtualization feature settings to specify the host type.
871+ Used to indicate the type of hypervisor or virtualization platform.
872+ """
873+
874+ type : str = constants .FEATURE_VIRTUALIZATION
875+ # Host type - specifies the virtualization platform being used
876+ # Default is None (no restrictions/requirements)
877+ host_type : Optional [
878+ Union [
879+ search_space .SetSpace [VirtualizationHostType ],
880+ VirtualizationHostType ,
881+ ]
882+ ] = field (
883+ default = None ,
884+ metadata = field_metadata (
885+ decoder = partial (
886+ search_space .decode_nullable_set_space ,
887+ base_type = VirtualizationHostType ,
888+ default_values = [],
889+ )
890+ ),
891+ )
892+
893+ def __eq__ (self , o : object ) -> bool :
894+ assert isinstance (o , VirtualizationSettings ), f"actual: { type (o )} "
895+ return super ().__eq__ (o ) and self .host_type == o .host_type
896+
897+ def __hash__ (self ) -> int :
898+ return hash (self ._get_key ())
899+
900+ def _get_key (self ) -> str :
901+ # Include host_type in key for different hash values
902+ host_type_str = str (self .host_type ) if self .host_type else "None"
903+ return f"{ self .type } _{ host_type_str } "
904+
905+ def __repr__ (self ) -> str :
906+ return f"type:{ self .type } , " f"host_type:{ self .host_type } "
907+
908+ def check (self , capability : Any ) -> search_space .ResultReason :
909+ result = super ().check (capability )
910+ assert isinstance (capability , VirtualizationSettings )
911+
912+ # Check host_type compatibility
913+ if self .host_type is not None :
914+ if capability .host_type is None :
915+ # Requirement specifies host_type but capability doesn't provide it
916+ result .add_reason (
917+ f"requirement specifies host_type { self .host_type } "
918+ f"but capability has no host_type specified"
919+ )
920+ else :
921+ # Both have host_type, check compatibility
922+ result .merge (
923+ search_space .check_setspace (self .host_type , capability .host_type )
924+ )
925+
926+ return result
927+
928+ def _call_requirement_method (
929+ self , method : search_space .RequirementMethod , capability : Any
930+ ) -> Any :
931+ assert isinstance (capability , VirtualizationSettings )
932+ value = type (self )()
933+
934+ # Handle host_type intersection/generation based on method
935+ if self .host_type is not None and capability .host_type is not None :
936+ # Convert single values to SetSpace if needed
937+ if isinstance (self .host_type , VirtualizationHostType ):
938+ self_host_type = search_space .SetSpace (
939+ is_allow_set = True , items = [self .host_type ]
940+ )
941+ else :
942+ self_host_type = self .host_type
943+
944+ if isinstance (capability .host_type , VirtualizationHostType ):
945+ cap_host_type = search_space .SetSpace (
946+ is_allow_set = True , items = [capability .host_type ]
947+ )
948+ else :
949+ cap_host_type = capability .host_type
950+
951+ # Use SetSpace methods directly
952+ if method == search_space .RequirementMethod .intersect :
953+ value .host_type = self_host_type .intersect (cap_host_type )
954+ elif method == search_space .RequirementMethod .generate_min_capability :
955+ value .host_type = self_host_type .generate_min_capability (cap_host_type )
956+ elif capability .host_type is not None :
957+ value .host_type = capability .host_type
958+ else :
959+ value .host_type = self .host_type
960+
961+ return value
962+
963+
850964@dataclass_json ()
851965@dataclass ()
852966class FeaturesSpace (
0 commit comments