Merge "Add pci device etcd db api"
This commit is contained in:
commit
b49990d037
@ -81,6 +81,8 @@ def translate_etcd_result(etcd_result, model_type):
|
|||||||
ret = models.ComputeNode(data)
|
ret = models.ComputeNode(data)
|
||||||
elif model_type == 'capsule':
|
elif model_type == 'capsule':
|
||||||
ret = models.Capsule(data)
|
ret = models.Capsule(data)
|
||||||
|
elif model_type == 'pcidevice':
|
||||||
|
ret = models.PciDevice(data)
|
||||||
else:
|
else:
|
||||||
raise exception.InvalidParameterValue(
|
raise exception.InvalidParameterValue(
|
||||||
_('The model_type value: %s is invalid.'), model_type)
|
_('The model_type value: %s is invalid.'), model_type)
|
||||||
@ -744,3 +746,126 @@ class EtcdAPI(object):
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
return translate_etcd_result(target, 'capsule')
|
return translate_etcd_result(target, 'capsule')
|
||||||
|
|
||||||
|
def get_pci_device_by_addr(self, node_id, dev_addr):
|
||||||
|
try:
|
||||||
|
filters = {'compute_node_uuid': node_id,
|
||||||
|
'address': dev_addr}
|
||||||
|
pcis = self.list_pcidevices(filters=filters)
|
||||||
|
except etcd.EtcdKeyNotFound:
|
||||||
|
raise exception.PciDeviceNotFound(node_id=node_id, address=None)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error('Error occurred while retrieving pci device: %s',
|
||||||
|
six.text_type(e))
|
||||||
|
raise
|
||||||
|
|
||||||
|
if len(pcis) == 0:
|
||||||
|
raise exception.PciDeviceNotFound(node_id=node_id, address=None)
|
||||||
|
return pcis
|
||||||
|
|
||||||
|
def get_pci_device_by_id(self, id):
|
||||||
|
try:
|
||||||
|
filters = {'id': id}
|
||||||
|
pcis = self.list_pcidevices(filters=filters)
|
||||||
|
except etcd.EtcdKeyNotFound:
|
||||||
|
raise exception.PciDeviceNotFoundById(id=id)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error('Error occurred while retrieving pci device: %s',
|
||||||
|
six.text_type(e))
|
||||||
|
raise
|
||||||
|
|
||||||
|
if len(pcis) == 0:
|
||||||
|
raise exception.PciDeviceNotFoundById(id=id)
|
||||||
|
return pcis
|
||||||
|
|
||||||
|
def list_pcidevices(self, filters=None, limit=None, marker=None,
|
||||||
|
sort_key=None, sort_dir=None):
|
||||||
|
try:
|
||||||
|
pcis = getattr(self.client.read('/pcidevices'), 'children', None)
|
||||||
|
except etcd.EtcdKeyNotFound:
|
||||||
|
return []
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error(
|
||||||
|
"Error occurred while reading from etcd server: %s",
|
||||||
|
six.text_type(e))
|
||||||
|
raise
|
||||||
|
|
||||||
|
pcis = []
|
||||||
|
for p in pcis:
|
||||||
|
if p.value is not None:
|
||||||
|
pcis.append(translate_etcd_result(p, 'pcidevice'))
|
||||||
|
filtered_pcis = self._filter_resources(pcis, filters)
|
||||||
|
return self._process_list_result(filtered_pcis, limit=limit,
|
||||||
|
sort_key=sort_key)
|
||||||
|
|
||||||
|
def get_all_pci_device_by_node(self, node_id):
|
||||||
|
try:
|
||||||
|
filters = {'compute_node_uuid': node_id}
|
||||||
|
pcis = self.list_pcidevices(filters=filters)
|
||||||
|
except etcd.EtcdKeyNotFound:
|
||||||
|
raise exception.PciDeviceNotFound(node_id=node_id, address=None)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error('Error occurred while retrieving pci device: %s',
|
||||||
|
six.text_type(e))
|
||||||
|
raise
|
||||||
|
|
||||||
|
if len(pcis) == 0:
|
||||||
|
raise exception.PciDeviceNotFound(node_id=node_id, address=None)
|
||||||
|
return pcis
|
||||||
|
|
||||||
|
def get_all_pci_device_by_parent_addr(self, node_id, parent_addr):
|
||||||
|
pcis = []
|
||||||
|
try:
|
||||||
|
filters = {'compute_node_uuid': node_id,
|
||||||
|
'parent_addr': parent_addr}
|
||||||
|
pcis = self.list_pcidevices(filters=filters)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error('Error occurred while retrieving pci device: %s',
|
||||||
|
six.text_type(e))
|
||||||
|
raise
|
||||||
|
|
||||||
|
return pcis
|
||||||
|
|
||||||
|
def get_all_pci_device_by_container_uuid(self, container_uuid):
|
||||||
|
pcis = []
|
||||||
|
try:
|
||||||
|
filters = {'container_uuid': container_uuid}
|
||||||
|
pcis = self.list_pcidevices(filters=filters)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error('Error occurred while retrieving pci device: %s',
|
||||||
|
six.text_type(e))
|
||||||
|
raise
|
||||||
|
|
||||||
|
return pcis
|
||||||
|
|
||||||
|
@lockutils.synchronized('etcd_pcidevice')
|
||||||
|
def destroy_pci_device(self, node_id, address):
|
||||||
|
pci_device = self.get_pci_device_by_addr(node_id, address)
|
||||||
|
self.client.delete('/pcidevices/' + pci_device.uuid)
|
||||||
|
|
||||||
|
@lockutils.synchronized('etcd_pcidevice')
|
||||||
|
def update_pci_device(self, node_id, address, values):
|
||||||
|
target = None
|
||||||
|
try:
|
||||||
|
target = self.get_pci_device_by_addr(node_id, address)
|
||||||
|
except Exception:
|
||||||
|
# If cannot get one, we write one to etcd later
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
if not target:
|
||||||
|
values.update({'node_id': node_id, 'address': address})
|
||||||
|
pci_device = models.PciDevice(values)
|
||||||
|
pci_device.save()
|
||||||
|
return pci_device
|
||||||
|
target_value = json.loads(target.value)
|
||||||
|
target_value.update(values)
|
||||||
|
target.value = json.dump_as_bytes(target_value)
|
||||||
|
self.client.update(target)
|
||||||
|
except etcd.EtcdKeyNotFound:
|
||||||
|
raise exception.PciDeviceNotFound(node_id=node_id, address=address)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error('Error occurred while updating pci device: %s',
|
||||||
|
six.text_type(e))
|
||||||
|
raise
|
||||||
|
return translate_etcd_result(target, 'pcidevice')
|
||||||
|
@ -256,3 +256,25 @@ class ComputeNode(Base):
|
|||||||
|
|
||||||
client.write(path, json.dump_as_bytes(self.as_dict()))
|
client.write(path, json.dump_as_bytes(self.as_dict()))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
class PciDevice(Base):
|
||||||
|
"""Represents a PciDevice. """
|
||||||
|
_path = '/pcidevices'
|
||||||
|
|
||||||
|
_fields = objects.PciDevice.fields.keys()
|
||||||
|
|
||||||
|
def __init__(self, pci_data):
|
||||||
|
self.path = PciDevice.path()
|
||||||
|
for f in PciDevice.fields():
|
||||||
|
setattr(self, f, None)
|
||||||
|
self.id = 1
|
||||||
|
self.update(pci_data)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def path(cls):
|
||||||
|
return cls._path
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def fields(cls):
|
||||||
|
return cls._fields
|
||||||
|
@ -11,12 +11,18 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
"""Tests for manipulating pci device via the DB API"""
|
"""Tests for manipulating pci device via the DB API"""
|
||||||
|
import mock
|
||||||
|
|
||||||
|
import etcd
|
||||||
|
from etcd import Client as etcd_client
|
||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
|
|
||||||
from zun.common import context
|
from zun.common import context
|
||||||
from zun.common import exception
|
from zun.common import exception
|
||||||
import zun.conf
|
import zun.conf
|
||||||
from zun.db import api as dbapi
|
from zun.db import api as dbapi
|
||||||
|
from zun.db.etcd import models
|
||||||
from zun.objects import fields as z_fields
|
from zun.objects import fields as z_fields
|
||||||
from zun.tests.unit.db import base
|
from zun.tests.unit.db import base
|
||||||
from zun.tests import uuidsentinel
|
from zun.tests import uuidsentinel
|
||||||
@ -197,8 +203,85 @@ class DbPciDeviceTestCase(base.DbTestCase, base.ModelsObjectComparatorMixin):
|
|||||||
v1['address'])
|
v1['address'])
|
||||||
|
|
||||||
|
|
||||||
|
fake_values = {'id': 1,
|
||||||
|
'uuid': 'bd45ca46351e64f91d5c32',
|
||||||
|
'compute_node_uuid': 'ef5ef3492b57c8b9bc0556a',
|
||||||
|
'address': 'fake_addr',
|
||||||
|
'vendor_id': 'fake_vendor',
|
||||||
|
'product_id': 'fake_product',
|
||||||
|
'dev_type': 'VF',
|
||||||
|
'dev_id': 'fake_dev_id',
|
||||||
|
'lable': 'fake_label',
|
||||||
|
'status': 'in-use',
|
||||||
|
'request_id': 'fake_request_id',
|
||||||
|
'extra_info': '',
|
||||||
|
'parent_addr': '11:22',
|
||||||
|
'container_uuid': 'Id64c317ff78e95af2fc046e9630d7ae016df9f2'}
|
||||||
|
|
||||||
|
|
||||||
class EtcdDbPciDeviceTestCase(base.DbTestCase):
|
class EtcdDbPciDeviceTestCase(base.DbTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
# Placeholder for etcd test case.
|
cfg.CONF.set_override('db_type', 'etcd')
|
||||||
pass
|
super(EtcdDbPciDeviceTestCase, self).setUp()
|
||||||
|
|
||||||
|
@mock.patch.object(etcd_client, 'read')
|
||||||
|
@mock.patch.object(etcd_client, 'write')
|
||||||
|
def test_update_pci_device(self, mock_write, mock_read):
|
||||||
|
mock_read.side_effect = etcd.EtcdKeyNotFound
|
||||||
|
values = fake_values
|
||||||
|
pcidevice = models.PciDevice(values)
|
||||||
|
updated = self.dbapi.update_pci_device(values['compute_node_uuid'],
|
||||||
|
values['address'], values)
|
||||||
|
self.assertEqual(pcidevice.as_dict(), updated.as_dict())
|
||||||
|
|
||||||
|
@mock.patch.object(etcd_client, 'read')
|
||||||
|
def test_list_pci_device(self, mock_read):
|
||||||
|
res = self.dbapi.list_pcidevices()
|
||||||
|
mock_read.assert_called_with('/pcidevices')
|
||||||
|
self.assertEqual([], res)
|
||||||
|
|
||||||
|
@mock.patch('zun.db.etcd.api.EtcdAPI.get_pci_device_by_addr')
|
||||||
|
@mock.patch.object(etcd_client, 'delete')
|
||||||
|
def test_destroy_pci_device(self, mock_delete, mock_get):
|
||||||
|
self.dbapi.destroy_pci_device('1', 'fake_address')
|
||||||
|
mock_delete.assert_called()
|
||||||
|
|
||||||
|
@mock.patch('zun.db.etcd.api.EtcdAPI.list_pcidevices')
|
||||||
|
def test_get_all_pci_device_by_container_uuid(self, mock_list):
|
||||||
|
filters = {'container_uuid': 'Id64c317ff78e95af2fc'}
|
||||||
|
mock_list.return_value = [models.PciDevice(fake_values)]
|
||||||
|
self.dbapi.get_all_pci_device_by_container_uuid('Id64c317ff78e95af2fc')
|
||||||
|
mock_list.assert_called_with(filters=filters)
|
||||||
|
|
||||||
|
@mock.patch('zun.db.etcd.api.EtcdAPI.list_pcidevices')
|
||||||
|
def test_get_all_pci_device_by_parent_addr(self, mock_list):
|
||||||
|
filters = {'compute_node_uuid': 'ef5ef3492b57c8b9bc0556a',
|
||||||
|
'parent_addr': '11:22'}
|
||||||
|
mock_list.return_value = [models.PciDevice(fake_values)]
|
||||||
|
self.dbapi.get_all_pci_device_by_parent_addr('ef5ef3492b57c8b9bc0556a',
|
||||||
|
'11:22')
|
||||||
|
mock_list.assert_called_with(filters=filters)
|
||||||
|
|
||||||
|
@mock.patch('zun.db.etcd.api.EtcdAPI.list_pcidevices')
|
||||||
|
def test_get_all_pci_device_by_node(self, mock_list):
|
||||||
|
filters = {'compute_node_uuid': 'ef5ef3492b57c8b9bc0556a'}
|
||||||
|
mock_list.return_value = [models.PciDevice(fake_values)]
|
||||||
|
self.dbapi.get_all_pci_device_by_node('ef5ef3492b57c8b9bc0556a')
|
||||||
|
mock_list.assert_called_with(filters=filters)
|
||||||
|
|
||||||
|
@mock.patch('zun.db.etcd.api.EtcdAPI.list_pcidevices')
|
||||||
|
def test_get_pci_device_by_id(self, mock_list):
|
||||||
|
filters = {'id': '1'}
|
||||||
|
mock_list.return_value = [models.PciDevice(fake_values)]
|
||||||
|
self.dbapi.get_pci_device_by_id('1')
|
||||||
|
mock_list.assert_called_with(filters=filters)
|
||||||
|
|
||||||
|
@mock.patch('zun.db.etcd.api.EtcdAPI.list_pcidevices')
|
||||||
|
def test_get_pci_device_by_addr(self, mock_list):
|
||||||
|
filters = {'compute_node_uuid': 'ef5ef3492b57c8b9bc0556a',
|
||||||
|
'address': 'fake_addr'}
|
||||||
|
mock_list.return_value = [models.PciDevice(fake_values)]
|
||||||
|
self.dbapi.get_pci_device_by_addr('ef5ef3492b57c8b9bc0556a',
|
||||||
|
'fake_addr')
|
||||||
|
mock_list.assert_called_with(filters=filters)
|
||||||
|
Loading…
Reference in New Issue
Block a user