Merge "Add pci device etcd db api"

This commit is contained in:
Zuul 2017-12-05 02:54:55 +00:00 committed by Gerrit Code Review
commit b49990d037
3 changed files with 232 additions and 2 deletions

View File

@ -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')

View File

@ -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

View File

@ -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)