Parse vpmem related flavor extra spec
Support parsing extra specs properties as below: hw:pmem=4GB,SMALL In the compute API layer, if the only vpmem is requested without explicitly specifiy the instance NUMA topology, then one cell NUMA topology will be added to instance. And then translate it to placement resource request. Change-Id: Ifeeb7710fb39befbd0d0693ca2b4c3aa79878127 Partially-Implements: blueprint virtual-persistent-memory Co-Authored-By: He Jie Xu <hejie.xu@intel.com>
This commit is contained in:
parent
c39ad2383c
commit
ae59c331cc
|
@ -124,6 +124,8 @@ class ResourceRequest(object):
|
|||
|
||||
self._translate_memory_encryption(request_spec.flavor, image)
|
||||
|
||||
self._translate_vpmems_request(request_spec.flavor)
|
||||
|
||||
self.strip_zeros()
|
||||
|
||||
def _process_extra_specs(self, flavor):
|
||||
|
@ -179,6 +181,24 @@ class ResourceRequest(object):
|
|||
LOG.debug("Added %s=1 to requested resources",
|
||||
orc.MEM_ENCRYPTION_CONTEXT)
|
||||
|
||||
def _translate_vpmems_request(self, flavor):
|
||||
"""When the hw:pmem extra spec is present, require hosts which can
|
||||
provide enough vpmem resources.
|
||||
"""
|
||||
vpmem_labels = hw.get_vpmems(flavor)
|
||||
if not vpmem_labels:
|
||||
# No vpmems required
|
||||
return
|
||||
amount_by_rc = collections.defaultdict(int)
|
||||
for vpmem_label in vpmem_labels:
|
||||
resource_class = orc.normalize_name(
|
||||
"PMEM_NAMESPACE_" + vpmem_label)
|
||||
amount_by_rc[resource_class] += 1
|
||||
for resource_class, amount in amount_by_rc.items():
|
||||
self._add_resource(None, resource_class, amount)
|
||||
LOG.debug("Added resource %s=%d to requested resources",
|
||||
resource_class, amount)
|
||||
|
||||
@property
|
||||
def group_policy(self):
|
||||
return self._group_policy
|
||||
|
|
|
@ -945,6 +945,26 @@ class TestUtils(TestUtilsBase):
|
|||
rr = utils.ResourceRequest(rs)
|
||||
self.assertResourceRequestsEqual(expected, rr)
|
||||
|
||||
def test_resource_request_with_vpmems(self):
|
||||
flavor = objects.Flavor(
|
||||
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0,
|
||||
extra_specs={'hw:pmem': '4GB, 4GB,SMALL'})
|
||||
|
||||
expected = FakeResourceRequest()
|
||||
expected._rg_by_id[None] = objects.RequestGroup(
|
||||
use_same_provider=False,
|
||||
resources={
|
||||
'VCPU': 1,
|
||||
'MEMORY_MB': 1024,
|
||||
'DISK_GB': 15,
|
||||
'CUSTOM_PMEM_NAMESPACE_4GB': 2,
|
||||
'CUSTOM_PMEM_NAMESPACE_SMALL': 1
|
||||
},
|
||||
)
|
||||
rs = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
||||
rr = utils.ResourceRequest(rs)
|
||||
self.assertResourceRequestsEqual(expected, rr)
|
||||
|
||||
def test_resource_request_add_group_inserts_the_group(self):
|
||||
flavor = objects.Flavor(
|
||||
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0)
|
||||
|
|
|
@ -1302,6 +1302,16 @@ class NUMATopologyTest(test.NoDBTestCase):
|
|||
},
|
||||
"expect": exception.ImageCPUPinningForbidden,
|
||||
},
|
||||
{
|
||||
"flavor": objects.Flavor(vcpus=4, memory_mb=2048, extra_specs={
|
||||
"hw:pmem": '2GB'}),
|
||||
"image": {},
|
||||
"expect": objects.InstanceNUMATopology(cells=
|
||||
[
|
||||
objects.InstanceNUMACell(
|
||||
id=0, cpuset=set([0, 1, 2, 3]), memory=2048),
|
||||
]),
|
||||
},
|
||||
]
|
||||
|
||||
for testitem in testdata:
|
||||
|
|
|
@ -1683,8 +1683,9 @@ def numa_get_constraints(flavor, image_meta):
|
|||
|
||||
nodes = _get_numa_node_count_constraint(flavor, image_meta)
|
||||
pagesize = _get_numa_pagesize_constraint(flavor, image_meta)
|
||||
vpmems = get_vpmems(flavor)
|
||||
|
||||
if nodes or pagesize:
|
||||
if nodes or pagesize or vpmems:
|
||||
nodes = nodes or 1
|
||||
|
||||
cpu_list = _get_numa_cpu_constraint(flavor, image_meta)
|
||||
|
@ -2074,6 +2075,13 @@ def get_vpmems(flavor):
|
|||
:param flavor: a flavor object to read extra specs from
|
||||
:returns: a vpmem label list
|
||||
"""
|
||||
# TODO(Luyao) Return vpmem label list when the whole
|
||||
# vpmem feature is supported.
|
||||
return []
|
||||
vpmems_info = flavor.get('extra_specs', {}).get('hw:pmem')
|
||||
if not vpmems_info:
|
||||
return []
|
||||
vpmem_labels = vpmems_info.split(',')
|
||||
formed_labels = []
|
||||
for label in vpmem_labels:
|
||||
formed_label = label.strip()
|
||||
if formed_label:
|
||||
formed_labels.append(formed_label)
|
||||
return formed_labels
|
||||
|
|
Loading…
Reference in New Issue