Add Simple Storage resource support
Simple Storage resource is a storage model used to represent the properties of a storage controller and its directly attached devices. As of this patch, the Simple Storage emulation is only supported for the libvirt driver for storage devices that are configured as a Volume via libvirt and attached to a VM/domain. Story: #2005948 Task: #34313 Change-Id: If10bd04d517600c3a69bb43fe0ea50f2efd62422
This commit is contained in:
parent
578f058f18
commit
69cfa3a4f0
@ -85,6 +85,62 @@ You should be able to flip its power state via the Redfish call:
|
||||
You can have as many domains as you need. The domains can be concurrently
|
||||
managed over Redfish and some other tool like *Virtual BMC*.
|
||||
|
||||
|
||||
Simple Storage resource
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For emulating the *Simple Storage* resource, some additional preparation is
|
||||
required on the host side.
|
||||
|
||||
First, you need to create, build and start a libvirt storage pool using virsh:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
virsh pool-define-as testPool dir - - - - "/testPool"
|
||||
virsh pool-build testPool
|
||||
virsh pool-start testPool
|
||||
virsh pool-autostart testPool
|
||||
|
||||
Next, create a storage volume in the above created storage pool:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
virsh vol-create-as testPool testVol 1G
|
||||
|
||||
Next, attach the created volume to the virtual machine/domain:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
virsh attach-disk vbmc-node /testPool/testVol sda
|
||||
|
||||
Now, query the *Simple Storage* resource collection for the `vbmc-node` domain
|
||||
in a closely similar format (with 'ide' and 'scsi', here, referring to the two
|
||||
Redfish Simple Storage Controllers available for this domain):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
curl http://localhost:8000/redfish/v1/vbmc-node/SimpleStorage
|
||||
{
|
||||
"@odata.type": "#SimpleStorageCollection.SimpleStorageCollection",
|
||||
"Name": "Simple Storage Collection",
|
||||
"Members@odata.count": 2,
|
||||
"Members": [
|
||||
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Systems/vbmc-node/SimpleStorage/ide"
|
||||
},
|
||||
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Systems/vbmc-node/SimpleStorage/scsi"
|
||||
}
|
||||
|
||||
],
|
||||
"Oem": {},
|
||||
"@odata.context": "/redfish/v1/$metadata#SimpleStorageCollection.SimpleStorageCollection",
|
||||
"@odata.id": "/redfish/v1/Systems/vbmc-node/SimpleStorage"
|
||||
}
|
||||
|
||||
|
||||
UEFI boot
|
||||
~~~~~~~~~
|
||||
|
||||
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Adds emulation support for Simple Storage resource to libvirt
|
||||
virtualization backend of the dynamic Redfish emulator. The emulation
|
||||
functionality assumes that the storage devices attached to a VM are
|
||||
configured as a libvirt Volume via a storage pool. Devices not configured
|
||||
as a Volume will not be considered for emulation purposes.
|
@ -626,6 +626,37 @@ def system_reset_bios(identity):
|
||||
return '', 204
|
||||
|
||||
|
||||
@app.route('/redfish/v1/Systems/<identity>/SimpleStorage',
|
||||
methods=['GET'])
|
||||
@ensure_instance_access
|
||||
@returns_json
|
||||
def simple_storage_collection(identity):
|
||||
with Resources() as resources:
|
||||
simple_storage_controllers = (
|
||||
resources.systems.get_simple_storage_collection(identity))
|
||||
|
||||
return flask.render_template(
|
||||
'simple_storage_collection.json', identity=identity,
|
||||
simple_storage_controllers=simple_storage_controllers)
|
||||
|
||||
|
||||
@app.route('/redfish/v1/Systems/<identity>/SimpleStorage/<simple_storage_id>',
|
||||
methods=['GET'])
|
||||
@ensure_instance_access
|
||||
@returns_json
|
||||
def simple_storage(identity, simple_storage_id):
|
||||
with Resources() as resources:
|
||||
simple_storage_controllers = (
|
||||
resources.systems.get_simple_storage_collection(identity))
|
||||
try:
|
||||
storage_controller = simple_storage_controllers[simple_storage_id]
|
||||
except KeyError:
|
||||
app.logger.debug('"%s" Simple Storage resource was not found')
|
||||
return 'Not found', 404
|
||||
return flask.render_template('simple_storage.json', identity=identity,
|
||||
simple_storage=storage_controller)
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser('sushy-emulator')
|
||||
parser.add_argument('--config',
|
||||
|
@ -192,3 +192,10 @@ class AbstractSystemsDriver(DriverBase):
|
||||
|
||||
:raises: `error.FishyError` if boot device can't be set
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_simple_storage_collection(self, identity):
|
||||
"""Get a dict of Simple Storage Controllers and their devices
|
||||
|
||||
:returns: dict of Simple Storage Controllers and their atributes
|
||||
"""
|
||||
|
@ -13,6 +13,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from collections import defaultdict
|
||||
from collections import namedtuple
|
||||
import logging
|
||||
import os
|
||||
@ -839,3 +840,96 @@ class LibvirtDriver(AbstractSystemsDriver):
|
||||
'%(error)s' % {'uri': self._uri, 'error': e})
|
||||
|
||||
raise error.FishyError(msg)
|
||||
|
||||
def _find_device_by_path(self, vol_path):
|
||||
"""Get device attributes using path
|
||||
|
||||
:param vol_path: path for the libvirt volume
|
||||
:returns: a dict (or None) of the corresponding device attributes
|
||||
"""
|
||||
with libvirt_open(self._uri, readonly=True) as conn:
|
||||
try:
|
||||
vol = conn.storageVolLookupByPath(vol_path)
|
||||
except libvirt.libvirtError as e:
|
||||
msg = ('Could not find storage volume by path '
|
||||
'"%(path)s" at libvirt URI "%(uri)s": '
|
||||
'%(err)s' %
|
||||
{'path': vol_path, 'uri': self._uri,
|
||||
'err': e})
|
||||
logger.debug(msg)
|
||||
return
|
||||
disk_device = {
|
||||
'Name': vol.name(),
|
||||
'CapacityBytes': vol.info()[1]
|
||||
}
|
||||
return disk_device
|
||||
|
||||
def _find_device_from_pool(self, pool_name, vol_name):
|
||||
"""Get device attributes from pool
|
||||
|
||||
:param pool_name: libvirt pool name
|
||||
:param vol_name: libvirt volume name
|
||||
:returns: a dict (or None) of the corresponding device attributes
|
||||
"""
|
||||
with libvirt_open(self._uri, readonly=True) as conn:
|
||||
try:
|
||||
pool = conn.storagePoolLookupByName(pool_name)
|
||||
except libvirt.libvirtError as e:
|
||||
msg = ('Error finding Storage Pool by name "%(name)s" at'
|
||||
'libvirt URI "%(uri)s": %(err)s' %
|
||||
{'name': pool_name, 'uri': self._uri, 'err': e})
|
||||
logger.debug(msg)
|
||||
return
|
||||
|
||||
try:
|
||||
vol = pool.storageVolLookupByName(vol_name)
|
||||
except libvirt.libvirtError as e:
|
||||
msg = ('Error finding Storage Volume by name "%(name)s" '
|
||||
'in Pool '"%(pName)s"' at libvirt URI "%(uri)s"'
|
||||
': %(err)s' %
|
||||
{'name': vol_name, 'pName': pool_name,
|
||||
'uri': self._uri, 'err': e})
|
||||
logger.debug(msg)
|
||||
return
|
||||
disk_device = {
|
||||
'Name': vol.name(),
|
||||
'CapacityBytes': vol.info()[1]
|
||||
}
|
||||
return disk_device
|
||||
|
||||
def get_simple_storage_collection(self, identity):
|
||||
"""Get a dict of simple storage controllers and their devices
|
||||
|
||||
Only those storage devices that are configured as a libvirt volume
|
||||
via a pool and attached to the domain will reflect as a device.
|
||||
Others are skipped.
|
||||
|
||||
:param identity: libvirt domain or ID
|
||||
:returns: dict of simple storage controller dict with their attributes
|
||||
"""
|
||||
domain = self._get_domain(identity, readonly=True)
|
||||
tree = ET.fromstring(domain.XMLDesc())
|
||||
simple_storage = defaultdict(lambda: defaultdict(DeviceList=list()))
|
||||
|
||||
for disk_element in tree.findall(".//disk/target[@bus]/.."):
|
||||
source_element = disk_element.find('source')
|
||||
if source_element is not None:
|
||||
disk_type = disk_element.attrib['type']
|
||||
ctl_type = disk_element.find('target').attrib['bus']
|
||||
disk_device = None
|
||||
if disk_type in ('file', 'block'):
|
||||
if disk_type == 'file':
|
||||
vol_path = source_element.attrib['file']
|
||||
else:
|
||||
vol_path = source_element.attrib['dev']
|
||||
disk_device = self._find_device_by_path(vol_path)
|
||||
elif disk_type == 'volume':
|
||||
pool_name = source_element.attrib['pool']
|
||||
vol_name = source_element.attrib['volume']
|
||||
disk_device = self._find_device_from_pool(pool_name,
|
||||
vol_name)
|
||||
if disk_device is not None:
|
||||
simple_storage[ctl_type]['Id'] = ctl_type
|
||||
simple_storage[ctl_type]['Name'] = ctl_type
|
||||
simple_storage[ctl_type]['DeviceList'].append(disk_device)
|
||||
return simple_storage
|
||||
|
@ -371,3 +371,6 @@ class OpenStackDriver(AbstractSystemsDriver):
|
||||
:raises: `error.FishyError` if boot device can't be set
|
||||
"""
|
||||
raise error.NotSupportedError('Not implemented')
|
||||
|
||||
def get_simple_storage_collection(self, identity):
|
||||
raise error.NotSupportedError('Not implemented')
|
||||
|
21
sushy_tools/emulator/templates/simple_storage.json
Normal file
21
sushy_tools/emulator/templates/simple_storage.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"@odata.type": "#SimpleStorage.v1_2_0.SimpleStorage",
|
||||
"Id": {{ simple_storage['Id']|string|tojson }},
|
||||
"Name": {{ "%s Controller"|format(simple_storage['Name'])|tojson }},
|
||||
"Devices": [
|
||||
{% for device in simple_storage['DeviceList'] %}
|
||||
{
|
||||
"@odata.type": "#SimpleStorage.v1_1_0.Device",
|
||||
"Name": {{ device['Name']|string|tojson }},
|
||||
"CapacityBytes": {{ device['CapacityBytes'] }},
|
||||
"Status": {
|
||||
"@odata.type": "#Resource.Status",
|
||||
"State": "Enabled",
|
||||
"Health": "OK"
|
||||
}
|
||||
}{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
],
|
||||
"@odata.context": "/redfish/v1/$metadata#SimpleStorage.SimpleStorage",
|
||||
"@odata.id": {{ "/redfish/v1/Systems/%s/SimpleStorage/%s"|format(identity, simple_storage['Id'])|tojson }}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
{
|
||||
"@odata.type": "#SimpleStorageCollection.SimpleStorageCollection",
|
||||
"Name": "Simple Storage Collection",
|
||||
"Members@odata.count": {{ simple_storage_controllers|length }},
|
||||
"Members": [
|
||||
{% for simple_storage in simple_storage_controllers %}
|
||||
{
|
||||
"@odata.id": {{ "/redfish/v1/Systems/%s/SimpleStorage/%s"|format(identity, simple_storage_controllers[simple_storage]['Id'])|tojson }}
|
||||
}{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
],
|
||||
"Oem": {},
|
||||
"@odata.context": "/redfish/v1/$metadata#SimpleStorageCollection.SimpleStorageCollection",
|
||||
"@odata.id": {{ "/redfish/v1/Systems/%s/SimpleStorage"|format(identity)|tojson }}
|
||||
}
|
||||
|
42
sushy_tools/tests/unit/emulator/domain_simple_storage.xml
Normal file
42
sushy_tools/tests/unit/emulator/domain_simple_storage.xml
Normal file
@ -0,0 +1,42 @@
|
||||
<domain type='qemu'>
|
||||
<name>QEmu-fedora-i686</name>
|
||||
<uuid>c7a5fdbd-cdaf-9455-926a-d65c16db1809</uuid>
|
||||
<memory>219200</memory>
|
||||
<currentMemory>219200</currentMemory>
|
||||
<vcpu>2</vcpu>
|
||||
<os>
|
||||
<type arch='x86_64' machine='pc'>hvm</type>
|
||||
<boot dev='cdrom'/>
|
||||
<loader type='rom'/>
|
||||
</os>
|
||||
<devices>
|
||||
<emulator>/usr/bin/qemu-system-x86_64</emulator>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='qcow2'/>
|
||||
<source file='/var/lib/libvirt/images/testVM1.img'/>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source file='/home/varsha/Documents/testPool/testVol1.img'/>
|
||||
<target dev='hdb' bus='ide'/>
|
||||
<address type='drive' controller='0' bus='0' target='0' unit='1'/>
|
||||
</disk>
|
||||
<disk type='block' device='disk'>
|
||||
<driver name='qemu' type='raw' cache='none' io='native'/>
|
||||
<source dev='/dev/sdb1'/>
|
||||
<target dev='vdc' bus='virtio'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
|
||||
</disk>
|
||||
<disk type='volume' device='disk'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source pool='blk-pool0' volume='blk-pool0-vol0'/>
|
||||
<target dev='hdk' bus='ide'/>
|
||||
</disk>
|
||||
<interface type='network'>
|
||||
<source network='default'/>
|
||||
</interface>
|
||||
<graphics type='vnc' port='-1'/>
|
||||
</devices>
|
||||
</domain>
|
@ -567,3 +567,81 @@ class LibvirtDriverTestCase(base.BaseTestCase):
|
||||
|
||||
nics = self.test_driver.get_nics(self.uuid)
|
||||
self.assertEqual([], nics)
|
||||
|
||||
@mock.patch('libvirt.openReadOnly', autospec=True)
|
||||
def test_get_simple_storage_collection(self, libvirt_mock):
|
||||
with open('sushy_tools/tests/unit/emulator/'
|
||||
'domain_simple_storage.xml', 'r') as f:
|
||||
data = f.read()
|
||||
|
||||
conn_mock = libvirt_mock.return_value
|
||||
dom_mock = conn_mock.lookupByUUID.return_value
|
||||
dom_mock.XMLDesc.return_value = data
|
||||
vol_mock = conn_mock.storageVolLookupByPath.return_value
|
||||
vol_mock.name.side_effect = ['testVM1.img', 'testVol1.img', 'sdb1']
|
||||
vol_mock.info.side_effect = [['testVM1.img', 100000],
|
||||
['testVol1.img', 200000],
|
||||
['sdb1', 150000]]
|
||||
pool_mock = conn_mock.storagePoolLookupByName.return_value
|
||||
pvol_mock = pool_mock.storageVolLookupByName.return_value
|
||||
pvol_mock.name.return_value = 'blk-pool0-vol0'
|
||||
pvol_mock.info.return_value = ['volType', 300000]
|
||||
|
||||
simple_storage_response = (self.test_driver
|
||||
.get_simple_storage_collection(self.uuid))
|
||||
|
||||
simple_storage_expected = {
|
||||
'virtio': {
|
||||
'Id': 'virtio',
|
||||
'Name': 'virtio',
|
||||
'DeviceList': [
|
||||
{
|
||||
'Name': 'testVM1.img',
|
||||
'CapacityBytes': 100000
|
||||
},
|
||||
{
|
||||
'Name': 'sdb1',
|
||||
'CapacityBytes': 150000
|
||||
}
|
||||
]
|
||||
},
|
||||
'ide': {
|
||||
'Id': 'ide',
|
||||
'Name': 'ide',
|
||||
'DeviceList': [
|
||||
{
|
||||
'Name': 'testVol1.img',
|
||||
'CapacityBytes': 200000
|
||||
},
|
||||
{
|
||||
'Name': 'blk-pool0-vol0',
|
||||
'CapacityBytes': 300000
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
self.assertEqual(simple_storage_response, simple_storage_expected)
|
||||
|
||||
@mock.patch('libvirt.openReadOnly', autospec=True)
|
||||
def test_get_simple_storage_collection_empty(self, libvirt_mock):
|
||||
with open('sushy_tools/tests/unit/emulator/domain.xml') as f:
|
||||
domain_xml = f.read()
|
||||
|
||||
conn_mock = libvirt_mock.return_value
|
||||
dom_mock = conn_mock.lookupByUUID.return_value
|
||||
dom_mock.XMLDesc.return_value = domain_xml
|
||||
vol_mock = conn_mock.storageVolLookupByPath.return_value
|
||||
vol_mock.name.side_effect = ['testVM1.img', 'testVol1.img', 'sdb1']
|
||||
vol_mock.info.side_effect = [['testType1', 100000],
|
||||
['testType2', 200000],
|
||||
['testType1', 150000]]
|
||||
pool_mock = conn_mock.storagePoolLookupByName.return_value
|
||||
pvol_mock = pool_mock.storageVolLookupByName.return_value
|
||||
pvol_mock.name.return_value = 'blk-pool0-vol0'
|
||||
pvol_mock.info.return_value = ['volType', 300000]
|
||||
|
||||
simple_storage_response = (self.test_driver
|
||||
.get_simple_storage_collection(self.uuid))
|
||||
|
||||
self.assertEqual({}, simple_storage_response)
|
||||
|
@ -256,3 +256,8 @@ class NovaDriverTestCase(base.BaseTestCase):
|
||||
nics = self.test_driver.get_nics(self.uuid)
|
||||
self.assertEqual([{'id': 'fa:16:3e:22:18:31',
|
||||
'mac': 'fa:16:3e:22:18:31'}], nics)
|
||||
|
||||
def test_get_simple_storage_collection(self):
|
||||
self.assertRaises(
|
||||
error.FishyError,
|
||||
self.test_driver.get_simple_storage_collection, self.uuid)
|
||||
|
@ -574,3 +574,147 @@ class EmulatorTestCase(base.BaseTestCase):
|
||||
self.assertEqual(204, response.status_code)
|
||||
|
||||
vmedia_mock.eject_image.called_once_with('CD')
|
||||
|
||||
def test_simple_storage_collection(self, resources_mock):
|
||||
resources_mock = resources_mock.return_value.__enter__.return_value
|
||||
systems_mock = resources_mock.systems
|
||||
systems_mock.get_simple_storage_collection.return_value = {
|
||||
'virtio': {
|
||||
'Id': 'virtio',
|
||||
'Name': 'virtio',
|
||||
'DeviceList': [
|
||||
{
|
||||
'Name': 'testVM1.img',
|
||||
'CapacityBytes': 100000
|
||||
},
|
||||
{
|
||||
'Name': 'sdb1',
|
||||
'CapacityBytes': 150000
|
||||
}
|
||||
]
|
||||
},
|
||||
'ide': {
|
||||
'Id': 'ide',
|
||||
'Name': 'ide',
|
||||
'DeviceList': [
|
||||
{
|
||||
'Name': 'testVol1.img',
|
||||
'CapacityBytes': 200000
|
||||
},
|
||||
{
|
||||
'Name': 'blk-pool0-vol0',
|
||||
'CapacityBytes': 300000
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
response = self.app.get('redfish/v1/Systems/' + self.uuid +
|
||||
'/SimpleStorage')
|
||||
|
||||
self.assertEqual(200, response.status_code)
|
||||
self.assertEqual('Simple Storage Collection',
|
||||
response.json['Name'])
|
||||
self.assertEqual(2, response.json['Members@odata.count'])
|
||||
self.assertEqual({'/redfish/v1/Systems/' + self.uuid +
|
||||
'/SimpleStorage/virtio',
|
||||
'/redfish/v1/Systems/' + self.uuid +
|
||||
'/SimpleStorage/ide'},
|
||||
{m['@odata.id'] for m in response.json['Members']})
|
||||
|
||||
def test_simple_storage_collection_empty(self, resources_mock):
|
||||
resources_mock = resources_mock.return_value.__enter__.return_value
|
||||
systems_mock = resources_mock.systems
|
||||
systems_mock.get_simple_storage_collection.return_value = []
|
||||
response = self.app.get('redfish/v1/Systems/' + self.uuid +
|
||||
'/SimpleStorage')
|
||||
|
||||
self.assertEqual(200, response.status_code)
|
||||
self.assertEqual('Simple Storage Collection',
|
||||
response.json['Name'])
|
||||
self.assertEqual(0, response.json['Members@odata.count'])
|
||||
self.assertEqual([], response.json['Members'])
|
||||
|
||||
def test_simple_storage(self, resources_mock):
|
||||
resources_mock = resources_mock.return_value.__enter__.return_value
|
||||
systems_mock = resources_mock.systems
|
||||
systems_mock.get_simple_storage_collection.return_value = {
|
||||
'virtio': {
|
||||
'Id': 'virtio',
|
||||
'Name': 'virtio',
|
||||
'DeviceList': [
|
||||
{
|
||||
'Name': 'testVM1.img',
|
||||
'CapacityBytes': 100000
|
||||
},
|
||||
{
|
||||
'Name': 'sdb1',
|
||||
'CapacityBytes': 150000
|
||||
}
|
||||
]
|
||||
},
|
||||
'ide': {
|
||||
'Id': 'ide',
|
||||
'Name': 'ide',
|
||||
'DeviceList': [
|
||||
{
|
||||
'Name': 'testVol1.img',
|
||||
'CapacityBytes': 200000
|
||||
},
|
||||
{
|
||||
'Name': 'blk-pool0-vol0',
|
||||
'CapacityBytes': 300000
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
response = self.app.get('/redfish/v1/Systems/' + self.uuid +
|
||||
'/SimpleStorage/virtio')
|
||||
|
||||
self.assertEqual(200, response.status_code)
|
||||
self.assertEqual('virtio', response.json['Id'])
|
||||
self.assertEqual('virtio Controller', response.json['Name'])
|
||||
self.assertEqual('testVM1.img', response.json['Devices'][0]['Name'])
|
||||
self.assertEqual(100000, response.json['Devices'][0]['CapacityBytes'])
|
||||
self.assertEqual('sdb1', response.json['Devices'][1]['Name'])
|
||||
self.assertEqual(150000, response.json['Devices'][1]['CapacityBytes'])
|
||||
self.assertEqual('/redfish/v1/Systems/' + self.uuid +
|
||||
'/SimpleStorage/virtio',
|
||||
response.json['@odata.id'])
|
||||
|
||||
def test_simple_storage_not_found(self, resources_mock):
|
||||
resources_mock = resources_mock.return_value.__enter__.return_value
|
||||
systems_mock = resources_mock.systems
|
||||
systems_mock.get_simple_storage_collection.return_value = {
|
||||
'virtio': {
|
||||
'Id': 'virtio',
|
||||
'Name': 'virtio',
|
||||
'DeviceList': [
|
||||
{
|
||||
'Name': 'testVM1.img',
|
||||
'CapacityBytes': 100000
|
||||
},
|
||||
{
|
||||
'Name': 'sdb1',
|
||||
'CapacityBytes': 150000
|
||||
}
|
||||
]
|
||||
},
|
||||
'ide': {
|
||||
'Id': 'ide',
|
||||
'Name': 'ide',
|
||||
'DeviceList': [
|
||||
{
|
||||
'Name': 'testVol1.img',
|
||||
'CapacityBytes': 200000
|
||||
},
|
||||
{
|
||||
'Name': 'blk-pool0-vol0',
|
||||
'CapacityBytes': 300000
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
response = self.app.get('/redfish/v1/Systems/' + self.uuid +
|
||||
'/SimpleStorage/scsi')
|
||||
|
||||
self.assertEqual(404, response.status_code)
|
||||
|
Loading…
Reference in New Issue
Block a user