def test_get_resources_interfaces_no_vm_link(self): node = factory.make_Node() iface = factory.make_Interface( INTERFACE_TYPE.PHYSICAL, name="eth0", numa_node=node.default_numanode, sriov_max_vf=8, ) pod = factory.make_Pod( pod_type="lxd", host=node, ) resources = get_vm_host_resources(pod) self.assertEqual( resources.interfaces, [ VMHostNetworkInterface( id=iface.id, name="eth0", numa_index=0, virtual_functions=VMHostResource( allocated_tracked=0, allocated_other=0, free=8, ), ), ], )
def test_get_resources_interfaces_not_sriov(self): node = factory.make_Node() iface = factory.make_Interface( INTERFACE_TYPE.PHYSICAL, name="eth0", numa_node=node.default_numanode, sriov_max_vf=8, ) project = factory.make_string() pod = factory.make_Pod( pod_type="lxd", parameters={"project": project}, host=node, ) VirtualMachineInterface.objects.create( vm=factory.make_VirtualMachine(bmc=pod, project=project), host_interface=iface, attachment_type=InterfaceAttachType.BRIDGE, ) resources = get_vm_host_resources(pod) self.assertEqual( resources.interfaces, [ VMHostNetworkInterface( id=iface.id, name="eth0", numa_index=0, virtual_functions=VMHostResource( allocated_tracked=0, allocated_other=0, free=8, ), ), ], )
def test_get_resources_no_detailed(self): pod = factory.make_Pod(pod_type="lxd", host=factory.make_Node()) factory.make_VirtualMachine(bmc=pod) resources = get_vm_host_resources(pod, detailed=False) # NUMA info and VMs list are not included when not in detailed mode self.assertEqual(resources.numa, []) self.assertEqual(resources.vms, [])
def test_get_resources_hugepages_round(self): node = factory.make_Node() numa_node0 = node.default_numanode numa_node0.cores = [0, 1] numa_node0.memory = 4096 numa_node0.save() numa_node1 = factory.make_NUMANode( node=node, cores=[2, 3], memory=8192 ) factory.make_NUMANodeHugepages( numa_node=numa_node0, page_size=2048 * MB, total=4096 * MB ) factory.make_NUMANodeHugepages( numa_node=numa_node1, page_size=4096 * MB, total=8192 * MB ) pod = factory.make_Pod(pod_type="lxd") pod.hints.nodes.add(node) factory.make_VirtualMachine( memory=2048, pinned_cores=[0, 2], hugepages_backed=True, bmc=pod, machine=factory.make_Node(system_id="vm0"), ) resources = get_vm_host_resources(pod) self.assertEqual( [asdict(r) for r in resources], [ { "cores": {"allocated": [0], "free": [1]}, "memory": { "general": {"allocated": 0, "free": 0}, "hugepages": [ { "allocated": 2048 * MB, "free": 2048 * MB, "page_size": 2048 * MB, } ], }, "node_id": 0, "vms": [{"pinned_cores": [0], "system_id": "vm0"}], }, { "cores": {"allocated": [2], "free": [3]}, "memory": { "general": {"allocated": 0, "free": 0}, "hugepages": [ { "allocated": 4096 * MB, "free": 4096 * MB, "page_size": 4096 * MB, } ], }, "node_id": 1, "vms": [{"pinned_cores": [2], "system_id": "vm0"}], }, ], )
def test_get_resources_no_host(self): pod = factory.make_Pod(pod_type="lxd", host=None) factory.make_VirtualMachine( memory=1024, pinned_cores=[0, 2], bmc=pod, ) self.assertEqual(get_vm_host_resources(pod), [])
def test_get_resources_unaligned(self): node = factory.make_Node() numa_node0 = node.default_numanode numa_node0.cores = [0, 1] numa_node0.memory = 4096 numa_node0.save() factory.make_NUMANode(node=node, cores=[2, 3], memory=2048) pod = factory.make_Pod(pod_type="lxd") pod.hints.nodes.add(node) factory.make_VirtualMachine( memory=2048, pinned_cores=[0, 2], hugepages_backed=False, bmc=pod, machine=factory.make_Node(system_id="vm0"), ) resources = get_vm_host_resources(pod) self.assertEqual( [asdict(r) for r in resources], [ { "cores": { "allocated": [0], "free": [1] }, "memory": { "general": { "allocated": 1024 * MB, "free": 3072 * MB }, "hugepages": [], }, "node_id": 0, "vms": [{ "pinned_cores": [0], "system_id": "vm0" }], }, { "cores": { "allocated": [2], "free": [3] }, "memory": { "general": { "allocated": 1024 * MB, "free": 1024 * MB }, "hugepages": [], }, "node_id": 1, "vms": [{ "pinned_cores": [2], "system_id": "vm0" }], }, ], )
def test_get_resources_numa_aligned(self): node = factory.make_Node() numa_node0 = node.default_numanode numa_node0.cores = [0, 3] numa_node0.memory = 4096 numa_node0.save() factory.make_NUMANode(node=node, cores=[1, 4], memory=1024) factory.make_NUMANode(node=node, cores=[2, 5], memory=2048) pod = factory.make_Pod(pod_type="lxd", host=node) vm0 = factory.make_VirtualMachine( memory=1024, pinned_cores=[0], hugepages_backed=False, bmc=pod, ) vm1 = factory.make_VirtualMachine( memory=1024, pinned_cores=[2, 5], hugepages_backed=False, bmc=pod, ) resources = get_vm_host_resources(pod) self.assertEqual( [asdict(r) for r in resources.numa], [ { "cores": {"allocated": [0], "free": [3]}, "memory": { "general": {"allocated": 1024 * MB, "free": 3072 * MB}, "hugepages": [], }, "interfaces": [], "node_id": 0, "vms": [vm0.id], }, { "cores": {"allocated": [], "free": [1, 4]}, "memory": { "general": {"allocated": 0, "free": 1024 * MB}, "hugepages": [], }, "interfaces": [], "node_id": 1, "vms": [], }, { "cores": {"allocated": [2, 5], "free": []}, "memory": { "general": {"allocated": 1024 * MB, "free": 1024 * MB}, "hugepages": [], }, "interfaces": [], "node_id": 2, "vms": [vm1.id], }, ], )
def test_get_resources_vms(self): node = factory.make_Node() numa_node0 = node.default_numanode numa_node0.cores = [0, 1, 2, 3] numa_node0.memory = 4096 numa_node0.save() project = factory.make_string() pod = factory.make_Pod(pod_type="lxd", parameters={"project": project}, host=node) node = factory.make_Node(bmc=pod) vm0 = factory.make_VirtualMachine( machine=node, memory=1024, pinned_cores=[0, 1], hugepages_backed=False, bmc=pod, project=project, ) vm1 = factory.make_VirtualMachine( memory=1024, unpinned_cores=2, hugepages_backed=True, bmc=pod, project=project, ) # another VM, in a different project factory.make_VirtualMachine( memory=1024, unpinned_cores=2, bmc=pod, project=factory.make_string(), ) resources = get_vm_host_resources(pod) self.assertCountEqual( resources.vms, [ VMHostVirtualMachineResources( id=vm0.id, system_id=node.system_id, pinned_cores=[0, 1], unpinned_cores=0, memory=1024 * MB, hugepages_backed=False, ), VMHostVirtualMachineResources( id=vm1.id, system_id=None, pinned_cores=[], unpinned_cores=2, memory=1024 * MB, hugepages_backed=True, ), ], )
def test_get_resources_no_host(self): pod = factory.make_Pod(pod_type="lxd", host=None) factory.make_VirtualMachine( memory=1024, pinned_cores=[0, 2], bmc=pod, ) resources = get_vm_host_resources(pod) self.assertEqual(resources.cores.free, 0) self.assertEqual(resources.cores.allocated, 0) self.assertEqual(resources.memory.general.free, 0) self.assertEqual(resources.memory.general.allocated, 0) self.assertEqual(resources.memory.hugepages.free, 0) self.assertEqual(resources.memory.hugepages.allocated, 0) self.assertEqual(resources.numa, []) self.assertEqual(resources.vms, [])
def test_get_resources_global_resources_pinned_cores_overlap(self): node = factory.make_Node() numa_node0 = node.default_numanode numa_node0.cores = [0, 1] numa_node0.memory = 4096 numa_node0.save() factory.make_NUMANode(node=node, cores=[2, 3], memory=2048) pod = factory.make_Pod(pod_type="lxd", host=node) factory.make_VirtualMachine( pinned_cores=[0, 1], bmc=pod, ) factory.make_VirtualMachine( pinned_cores=[1, 2], bmc=pod, ) resources = get_vm_host_resources(pod) self.assertEqual(resources.cores.free, 0) self.assertEqual(resources.cores.allocated, 4)
def dehydrate_numa_pinning(self, obj): """Dehydrate NUMA pinning info.""" if obj.host is None: return [] resources = [ dataclasses.asdict(entry) for entry in get_vm_host_resources(obj) ] # XXX fake data for host and VMs interfaces for now fake_interfaces = [ { "id": 100, "name": "eth4", "virtual_functions": { "allocated": 4, "free": 12, }, }, { "id": 200, "name": "eth5", "virtual_functions": { "allocated": 14, "free": 2, }, }, ] fake_vm_networks = [ { "guest_nic_id": 101, "host_nic_id": 100, }, { "guest_nic_id": 102, "host_nic_id": 100, }, ] for entry in resources: entry["interfaces"] = fake_interfaces for vm in entry["vms"]: vm["networks"] = fake_vm_networks return resources
def test_get_resources_no_host(self): pod = factory.make_Pod( pod_type="lxd", host=None, cores=8, memory=4096, ) node = factory.make_Node(bmc=pod) vm = factory.make_VirtualMachine( machine=node, memory=1024, pinned_cores=[0, 2], hugepages_backed=False, bmc=pod, ) resources = get_vm_host_resources(pod) self.assertEqual(resources.cores.free, 6) self.assertEqual(resources.cores.allocated, 2) self.assertEqual(resources.memory.general.free, 3072 * MB) self.assertEqual(resources.memory.general.allocated, 1024 * MB) self.assertEqual(resources.memory.hugepages.free, 0) self.assertEqual(resources.memory.hugepages.allocated, 0) self.assertEqual(resources.numa, []) self.assertEqual( resources.vms, [ VMHostVirtualMachineResources( id=vm.id, system_id=node.system_id, pinned_cores=[0, 2], unpinned_cores=0, memory=1024 * MB, hugepages_backed=False, ), ], )
def dehydrate_resources(self, obj, for_list=False): """Dehydrate resources info.""" return dataclasses.asdict( get_vm_host_resources(obj, detailed=not for_list) )
def test_get_resources_numa_unaligned_hugepages(self): node = factory.make_Node() numa_node0 = node.default_numanode numa_node0.cores = [0, 1] numa_node0.memory = 4096 numa_node0.save() numa_node1 = factory.make_NUMANode(node=node, cores=[2, 3], memory=4096) factory.make_NUMANodeHugepages(numa_node=numa_node0, page_size=1024 * MB, total=1024 * MB) factory.make_NUMANodeHugepages(numa_node=numa_node1, page_size=1024 * MB, total=4096 * MB) pod = factory.make_Pod(pod_type="lxd") pod.hints.nodes.add(node) vm = factory.make_VirtualMachine( memory=2048, pinned_cores=[0, 2], hugepages_backed=True, bmc=pod, ) resources = get_vm_host_resources(pod) self.assertEqual( [asdict(r) for r in resources.numa], [ { "cores": { "allocated": [0], "free": [1] }, "memory": { "general": { "allocated": 0, "free": 3072 * MB }, "hugepages": [{ "allocated": 1024 * MB, "free": 0, "page_size": 1024 * MB, }], }, "interfaces": [], "node_id": 0, "vms": [vm.id], }, { "cores": { "allocated": [2], "free": [3] }, "memory": { "general": { "allocated": 0, "free": 0 }, "hugepages": [{ "allocated": 1024 * MB, "free": 3072 * MB, "page_size": 1024 * MB, }], }, "interfaces": [], "node_id": 1, "vms": [vm.id], }, ], )
def test_get_resources_interfaces(self): node = factory.make_Node() if0 = factory.make_Interface( INTERFACE_TYPE.PHYSICAL, name="eth0", numa_node=node.default_numanode, sriov_max_vf=8, ) if1 = factory.make_Interface( INTERFACE_TYPE.PHYSICAL, name="eth1", numa_node=factory.make_NUMANode(node=node), sriov_max_vf=4, ) project = factory.make_string() pod = factory.make_Pod( pod_type="lxd", parameters={"project": project}, host=node, ) vm0 = factory.make_VirtualMachine(bmc=pod, project=project) for _ in range(3): VirtualMachineInterface.objects.create( vm=vm0, host_interface=if0, attachment_type=InterfaceAttachType.SRIOV, ) vm1 = factory.make_VirtualMachine(bmc=pod, project=factory.make_string()) for _ in range(2): VirtualMachineInterface.objects.create( vm=vm1, host_interface=if0, attachment_type=InterfaceAttachType.SRIOV, ) vm2 = factory.make_VirtualMachine(bmc=pod) for _ in range(2): VirtualMachineInterface.objects.create( vm=vm2, host_interface=if1, attachment_type=InterfaceAttachType.SRIOV, ) resources = get_vm_host_resources(pod) self.assertCountEqual( resources.interfaces, [ VMHostNetworkInterface( id=if0.id, name="eth0", numa_index=0, virtual_functions=VMHostResource( allocated_tracked=3, allocated_other=2, free=3, ), ), VMHostNetworkInterface( id=if1.id, name="eth1", numa_index=1, virtual_functions=VMHostResource( allocated_tracked=0, allocated_other=2, free=2, ), ), ], )
def test_get_resources_global_resources(self): node = factory.make_Node() numa_node0 = node.default_numanode numa_node0.cores = [0, 1] numa_node0.memory = 4096 numa_node0.save() factory.make_NUMANode(node=node, cores=[2, 3], memory=2048) factory.make_NUMANode(node=node, cores=[4, 5], memory=2048) factory.make_NUMANode(node=node, cores=[6, 7], memory=2048) factory.make_NUMANodeHugepages(numa_node=numa_node0, page_size=1024 * MB, total=2048 * MB) project = factory.make_string() pod = factory.make_Pod(pod_type="lxd", parameters={"project": project}, host=node) pool1 = factory.make_PodStoragePool(pod=pod) pool2 = factory.make_PodStoragePool(pod=pod) vm1 = factory.make_VirtualMachine( memory=1024, pinned_cores=[0, 1], hugepages_backed=False, bmc=pod, project=project, ) disk1 = factory.make_VirtualMachineDisk(vm=vm1, backing_pool=pool1) vm2 = factory.make_VirtualMachine( memory=1024, pinned_cores=[2], hugepages_backed=False, bmc=pod, ) disk2 = factory.make_VirtualMachineDisk(vm=vm2, backing_pool=pool2) factory.make_VirtualMachine( memory=1024, unpinned_cores=2, hugepages_backed=True, project=project, bmc=pod, ) factory.make_VirtualMachine(memory=2048, unpinned_cores=1, hugepages_backed=False, bmc=pod) resources = get_vm_host_resources(pod) self.assertEqual(resources.vm_count.tracked, 2) self.assertEqual(resources.vm_count.other, 2) self.assertEqual(resources.cores.free, 2) self.assertEqual(resources.cores.allocated, 6) self.assertEqual(resources.cores.allocated_tracked, 4) self.assertEqual(resources.cores.allocated_other, 2) self.assertEqual(resources.memory.general.free, 6144 * MB) self.assertEqual(resources.memory.general.allocated, 4096 * MB) self.assertEqual(resources.memory.general.allocated_tracked, 1024 * MB) self.assertEqual(resources.memory.general.allocated_other, 3072 * MB) self.assertEqual(resources.memory.hugepages.free, 1024 * MB) self.assertEqual(resources.memory.hugepages.allocated, 1024 * MB) self.assertEqual(resources.memory.hugepages.allocated_tracked, 1024 * MB) self.assertEqual(resources.memory.hugepages.allocated_other, 0) self.assertEqual(resources.storage.allocated_tracked, disk1.size) self.assertEqual(resources.storage.allocated_other, disk2.size) self.assertEqual( resources.storage.free, pool1.storage + pool2.storage - disk1.size - disk2.size, )