[Kimchi-devel] [PATCH 8/9 - v7] Fix tests and backend after remove 'storagepool' from templates
Rodrigo Trujillo
rodrigo.trujillo at linux.vnet.ibm.com
Wed Dec 2 18:38:10 UTC 2015
Backend and tests need some adjustments to perform all tasks and tests
after remove support to 'storagepool' in Templates.
Signed-off-by: Rodrigo Trujillo <rodrigo.trujillo at linux.vnet.ibm.com>
Signed-off-by: Aline Manera <alinefm at linux.vnet.ibm.com>
---
mockmodel.py | 2 +-
model/templates.py | 80 ++++++-------------------
tests/test_model.py | 59 +++++++++---------
tests/test_rest.py | 20 ++++---
tests/test_template.py | 33 ++++++----
tests/test_vmtemplate.py | 9 ++-
vmtemplate.py | 37 +++++++++---
7 files changed, 119 insertions(+), 121 deletions(-)
diff --git a/mockmodel.py b/src/wok/plugins/kimchi/mockmodel.py
index 2e58724..8263207 100644
--- a/mockmodel.py
+++ b/mockmodel.py
@@ -75,7 +75,7 @@ class MockModel(Model):
# test:///default driver
defaults = dict(osinfo.defaults)
defaults.update(mockmodel_defaults)
- defaults['disks'][0]['pool'] = DEFAULT_POOL
+ defaults['disks'][0]['pool'] = {'name': DEFAULT_POOL}
osinfo.defaults = dict(defaults)
self._mock_vgs = MockVolumeGroups()
diff --git a/model/templates.py b/src/wok/plugins/kimchi/model/templates.py
index 7b1412b..84cdd02 100644
--- a/model/templates.py
+++ b/model/templates.py
@@ -22,7 +22,7 @@ import libvirt
import os
import stat
-from wok.exception import InvalidOperation, InvalidParameter, MissingParameter
+from wok.exception import InvalidOperation, InvalidParameter
from wok.exception import NotFoundError, OperationFailed
from wok.utils import probe_file_permission_as_user, run_setfacl_set_attr
from wok.xmlutils.utils import xpath_get_text
@@ -34,43 +34,6 @@ from wok.plugins.kimchi.utils import pool_name_from_uri
from wok.plugins.kimchi.vmtemplate import VMTemplate
-def _check_disks_params(params, conn, objstore):
- if 'disks' not in params:
- return
-
- basic_disk = ['index', 'format', 'pool', 'size']
- ro_disk = ['index', 'format', 'pool', 'volume']
- base_disk = ['index', 'base', 'pool']
- for disk in params['disks']:
- keys = sorted(disk.keys())
- if ((keys == sorted(basic_disk)) or (keys == sorted(ro_disk)) or
- (keys == sorted(base_disk))):
- pass
- else:
- raise MissingParameter('KCHTMPL0028E')
-
- if disk.get('pool', {}).get('name') is None:
- raise MissingParameter('KCHTMPL0028E')
-
- pool_uri = disk['pool']['name']
- try:
- pool_name = pool_name_from_uri(pool_uri)
- conn.get().storagePoolLookupByName(pool_name.encode("utf-8"))
- except Exception:
- raise InvalidParameter("KCHTMPL0004E",
- {'pool': pool_uri,
- 'template': pool_name})
- if 'volume' in disk:
- kwargs = {'conn': conn, 'objstore': objstore}
- storagevolumes = __import__(
- "wok.plugins.kimchi.model.storagevolumes", fromlist=[''])
- pool_volumes = storagevolumes.StorageVolumesModel(
- **kwargs).get_list(pool_name)
- if disk['volume'] not in pool_volumes:
- raise InvalidParameter("KCHTMPL0019E", {'pool': pool_name,
- 'volume': disk['volume']})
-
-
class TemplatesModel(object):
def __init__(self, **kargs):
self.objstore = kargs['objstore']
@@ -91,9 +54,6 @@ class TemplatesModel(object):
{'filename': iso, 'user': user,
'err': excp})
- # Check disks information
- _check_disks_params(params, self.conn, self.objstore)
-
cpu_info = params.get('cpu_info')
if cpu_info:
topology = cpu_info.get('topology')
@@ -121,6 +81,15 @@ class TemplatesModel(object):
# Checkings will be done while creating this class, so any exception
# will be raised here
t = LibvirtVMTemplate(params, scan=True, conn=self.conn)
+
+ # Validate volumes
+ for disk in t.info.get('disks'):
+ volume = disk.get('volume')
+ # volume can be None
+ if 'volume' in disk.keys():
+ self.template_volume_validate(volume, disk['pool'])
+
+ # Store template on objectstore
name = params['name']
try:
with self.objstore as session:
@@ -141,10 +110,8 @@ class TemplatesModel(object):
def template_volume_validate(self, volume, pool):
kwargs = {'conn': self.conn, 'objstore': self.objstore}
- pool_type = xpath_get_text(pool.XMLDesc(0), "/pool/@type")[0]
- pool_name = unicode(pool.name(), 'utf-8')
-
- if pool_type in ['iscsi', 'scsi']:
+ pool_name = pool_name_from_uri(pool['name'])
+ if pool['type'] in ['iscsi', 'scsi']:
if not volume:
raise InvalidParameter("KCHTMPL0018E")
@@ -164,18 +131,14 @@ class TemplateModel(object):
self.templates = TemplatesModel(**kargs)
@staticmethod
- def get_template(name, objstore, conn, overrides=None):
+ def get_template(name, objstore, conn, overrides={}):
with objstore as session:
params = session.get('template', name)
- if overrides:
- if 'storagepool' in overrides:
- for i, disk in enumerate(params['disks']):
- params['disks'][i]['pool']['name'] = \
- overrides['storagepool']
- del overrides['storagepool']
- params.update(overrides)
-
- _check_disks_params(params, conn, objstore)
+ if overrides and 'storagepool' in overrides:
+ for i, disk in enumerate(params['disks']):
+ params['disks'][i]['pool']['name'] = overrides['storagepool']
+ del overrides['storagepool']
+ params.update(overrides)
return LibvirtVMTemplate(params, False, conn)
def lookup(self, name):
@@ -212,9 +175,6 @@ class TemplateModel(object):
new_t = copy.copy(old_t)
new_t.update(params)
- # Check disks information
- _check_disks_params(new_t, self.conn, self.objstore)
-
if not self._validate_updated_cpu_params(new_t):
raise InvalidParameter('KCHTMPL0025E')
@@ -251,9 +211,7 @@ class LibvirtVMTemplate(VMTemplate):
self.conn = conn
VMTemplate.__init__(self, args, scan)
- def _storage_validate(self, pool_uri=None):
- if pool_uri is None:
- pool_uri = self.info['storagepool']
+ def _storage_validate(self, pool_uri):
pool_name = pool_name_from_uri(pool_uri)
try:
conn = self.conn.get()
diff --git a/tests/test_model.py b/src/wok/plugins/kimchi/tests/test_model.py
index c5407d6..caacd91 100644
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -39,7 +39,6 @@ from wok.xmlutils.utils import xpath_get_text
from wok.plugins.kimchi import netinfo
from wok.plugins.kimchi import osinfo
-from wok.plugins.kimchi.config import get_kimchi_version
from wok.plugins.kimchi.config import kimchiPaths as paths
from wok.plugins.kimchi.model import model
from wok.plugins.kimchi.model.libvirtconnection import LibvirtConnection
@@ -77,13 +76,13 @@ def tearDownModule():
def _setDiskPoolDefault():
- osinfo.defaults['disks'][0]['pool'] = \
- '/plugins/kimchi/storagepools/default'
+ osinfo.defaults['disks'][0]['pool'] = {
+ 'name': '/plugins/kimchi/storagepools/default'}
def _setDiskPoolDefaultTest():
- osinfo.defaults['disks'][0]['pool'] = \
- '/plugins/kimchi/storagepools/default-pool'
+ osinfo.defaults['disks'][0]['pool'] = {
+ 'name': '/plugins/kimchi/storagepools/default-pool'}
class ModelTests(unittest.TestCase):
@@ -138,8 +137,9 @@ class ModelTests(unittest.TestCase):
vol = inst.storagevolume_lookup(u'default', vol_params['name'])
params = {'name': 'test', 'disks': [{'base': vol['path'],
- 'size': 1}],
- 'cdrom': UBUNTU_ISO}
+ 'size': 1, 'pool': {
+ 'name': '/plugins/kimchi/storagepools/default'}}],
+ 'cdrom': UBUNTU_ISO}
inst.templates_create(params)
rollback.prependDefer(inst.template_delete, 'test')
@@ -264,24 +264,20 @@ class ModelTests(unittest.TestCase):
self.assertEquals('finished', inst.task_lookup(task_id)['status'])
vol_path = inst.storagevolume_lookup('default', vol)['path']
- # Hack the model objstore to add a new template
- # It is needed as the image file must be a bootable image when
- # using model
- # As it is difficult to create one on test runtime, inject a
- # template with an empty image file to the objstore to test the
- # feature
+ # Create template based on IMG file
tmpl_name = "img-tmpl"
- tmpl_info = {"cpus": 1, "cdrom": "",
+ pool_uri = "/plugins/kimchi/storagepools/default"
+ tmpl_info = {"cpus": 1, "cdrom": "", "name": tmpl_name,
"graphics": {"type": "vnc", "listen": "127.0.0.1"},
"networks": ["default"], "memory": 1024, "folder": [],
"icon": "images/icon-vm.png",
"os_distro": "unknown", "os_version": "unknown",
- "disks": [{"base": vol_path, "size": 10, "pool": {
- "name": "/plugins/kimchi/storagepools/default"}}]}
+ "disks": [{"base": vol_path, "size": 10,
+ "format": "qcow2",
+ "pool": {"name": pool_uri}}]}
- with inst.objstore as session:
- session.store('template', tmpl_name, tmpl_info,
- get_kimchi_version())
+ inst.templates_create(tmpl_info)
+ rollback.prependDefer(inst.template_delete, tmpl_name)
params = {'name': 'kimchi-vm',
'template': '/plugins/kimchi/templates/img-tmpl'}
@@ -606,8 +602,9 @@ class ModelTests(unittest.TestCase):
inst = model.Model(objstore_loc=self.tmp_store)
with RollbackContext() as rollback:
- params = {'name': 'test', 'disks': [{'size': 1}],
- 'cdrom': UBUNTU_ISO}
+ params = {'name': 'test', 'disks': [{'size': 1, 'pool': {
+ 'name': '/plugins/kimchi/storagepools/default'}}],
+ 'cdrom': UBUNTU_ISO}
inst.templates_create(params)
rollback.prependDefer(inst.template_delete, 'test')
@@ -664,8 +661,9 @@ class ModelTests(unittest.TestCase):
self._create_template_conf_with_disk_format('vmdk')
rollback.prependDefer(self._restore_template_conf_file)
- params = {'name': 'test', 'disks': [{'size': 1}],
- 'cdrom': UBUNTU_ISO}
+ params = {'name': 'test', 'disks': [{'size': 1, 'pool': {
+ 'name': '/plugins/kimchi/storagepools/default'}}],
+ 'cdrom': UBUNTU_ISO}
inst.templates_create(params)
rollback.prependDefer(inst.template_delete, 'test')
@@ -690,9 +688,10 @@ class ModelTests(unittest.TestCase):
self._create_template_conf_with_disk_format(default_vol)
rollback.prependDefer(self._restore_template_conf_file)
- params = {'name': 'test',
- 'disks': [{'size': 1, 'format': user_vol}],
- 'cdrom': UBUNTU_ISO}
+ params = {'name': 'test', 'disks': [{
+ 'size': 1, 'format': user_vol,
+ 'pool': {'name': '/plugins/kimchi/storagepools/default'}}],
+ 'cdrom': UBUNTU_ISO}
inst.templates_create(params)
rollback.prependDefer(inst.template_delete, 'test')
@@ -715,8 +714,9 @@ class ModelTests(unittest.TestCase):
self._create_template_conf_with_disk_format(None)
rollback.prependDefer(self._restore_template_conf_file)
- params = {'name': 'test',
- 'disks': [{'size': 1}], 'cdrom': UBUNTU_ISO}
+ params = {'name': 'test', 'disks': [{'size': 1, 'pool': {
+ 'name': '/plugins/kimchi/storagepools/default'}}],
+ 'cdrom': UBUNTU_ISO}
inst.templates_create(params)
rollback.prependDefer(inst.template_delete, 'test')
@@ -770,7 +770,8 @@ class ModelTests(unittest.TestCase):
# only supports this format
orig_params = {'name': 'test', 'memory': 1024, 'cpus': 1,
'cdrom': UBUNTU_ISO,
- 'disks': [{'size': 1, 'format': 'qcow2'}]}
+ 'disks': [{'size': 1, 'format': 'qcow2', 'pool': {
+ 'name': '/plugins/kimchi/storagepools/default'}}]}
inst.templates_create(orig_params)
with RollbackContext() as rollback:
diff --git a/tests/test_rest.py b/src/wok/plugins/kimchi/tests/test_rest.py
index 2947df2..0305e82 100644
--- a/tests/test_rest.py
+++ b/tests/test_rest.py
@@ -18,6 +18,7 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+import copy
import json
import os
import re
@@ -47,6 +48,9 @@ ssl_port = None
cherrypy_port = None
fake_iso = '/tmp/fake.iso'
+DISKS = [{'size': 10, 'format': 'qcow2', 'index': 0, 'pool': {
+ 'name': '/plugins/kimchi/storagepools/default-pool'}}]
+
def setUpModule():
global test_server, model, host, port, ssl_port, cherrypy_port
@@ -267,7 +271,7 @@ class RestTests(unittest.TestCase):
def test_vm_lifecycle(self):
# Create a Template
- req = json.dumps({'name': 'test', 'disks': [{'size': 1}],
+ req = json.dumps({'name': 'test', 'disks': DISKS,
'icon': 'plugins/kimchi/images/icon-debian.png',
'cdrom': fake_iso})
resp = self.request('/plugins/kimchi/templates', req, 'POST')
@@ -291,7 +295,7 @@ class RestTests(unittest.TestCase):
+ '%s-0.img'
resp = self.request(vol_uri % vm['uuid'])
vol = json.loads(resp.read())
- self.assertEquals(1 << 30, vol['capacity'])
+ self.assertEquals(10 << 30, vol['capacity'])
self.assertEquals(['test-vm'], vol['used_by'])
# verify if poweroff command returns correct status
@@ -868,7 +872,7 @@ class RestTests(unittest.TestCase):
def test_vm_customise_storage(self):
# Create a Template
req = json.dumps({'name': 'test', 'cdrom': fake_iso,
- 'disks': [{'size': 1}]})
+ 'disks': DISKS})
resp = self.request('/plugins/kimchi/templates', req, 'POST')
self.assertEquals(201, resp.status)
@@ -905,7 +909,7 @@ class RestTests(unittest.TestCase):
% vm_info['uuid']
resp = self.request(vol_uri)
vol = json.loads(resp.read())
- self.assertEquals(1 << 30, vol['capacity'])
+ self.assertEquals(10 << 30, vol['capacity'])
# Delete the VM
resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE')
@@ -943,8 +947,8 @@ class RestTests(unittest.TestCase):
)
lun_name = json.loads(resp.read())[0]['name']
pool_name = tmpl_params['disks'][0]['pool']['name']
- tmpl_params['disks'] = [{'index': 0, 'volume': lun_name,
- 'pool': {'name': pool_name}}]
+ tmpl_params['disks'] = [{'index': 0, 'volume': lun_name, 'pool': {
+ 'name': pool_name}, 'format': 'raw'}]
req = json.dumps(tmpl_params)
resp = self.request('/plugins/kimchi/templates', req, 'POST')
self.assertEquals(201, resp.status)
@@ -1016,7 +1020,9 @@ class RestTests(unittest.TestCase):
# Create a Template
mock_base = '/tmp/mock.img'
open(mock_base, 'w').close()
- req = json.dumps({'name': 'test', 'disks': [{'base': mock_base}]})
+ disks = copy.deepcopy(DISKS)
+ disks[0]['base'] = mock_base
+ req = json.dumps({'name': 'test', 'disks': disks})
resp = self.request('/plugins/kimchi/templates', req, 'POST')
self.assertEquals(201, resp.status)
diff --git a/tests/test_template.py b/src/wok/plugins/kimchi/tests/test_template.py
index 7bd856e..0cc5ac8 100644
--- a/tests/test_template.py
+++ b/tests/test_template.py
@@ -120,16 +120,18 @@ class TemplateTests(unittest.TestCase):
# Create an image based template
open('/tmp/mock.img', 'w').close()
- t = {'name': 'test_img_template',
- 'disks': [{'base': '/tmp/mock.img'}]}
+ t = {'name': 'test_img_template', 'disks': [{
+ 'base': '/tmp/mock.img', 'format': 'qcow2',
+ 'pool': {'name': DEFAULT_POOL}, 'size': 1}]}
req = json.dumps(t)
resp = self.request('/plugins/kimchi/templates', req, 'POST')
self.assertEquals(201, resp.status)
os.remove('/tmp/mock.img')
# Test disk format
- t = {'name': 'test-format', 'cdrom': '/tmp/mock.iso',
- 'disks': [{'index': 0, 'size': 10, 'format': 'vmdk'}]}
+ t = {'name': 'test-format', 'cdrom': '/tmp/mock.iso', 'disks': [{
+ 'index': 0, 'size': 10, 'format': 'vmdk', 'pool': {
+ 'name': DEFAULT_POOL}}]}
req = json.dumps(t)
resp = self.request('/plugins/kimchi/templates', req, 'POST')
self.assertEquals(201, resp.status)
@@ -214,10 +216,11 @@ class TemplateTests(unittest.TestCase):
self.assertEquals(update_tmpl['cdrom'], cdrom_data['cdrom'])
# Update disks
- disk_data = {'disks': [{'index': 0, 'size': 10, 'format': 'raw',
- 'pool': DEFAULT_POOL},
+ disk_data = {'disks': [{'index': 0, 'size': 10,
+ 'format': 'raw', 'pool': {
+ 'name': DEFAULT_POOL}},
{'index': 1, 'size': 20, 'format': 'qcow2',
- 'pool': DEFAULT_POOL}]}
+ 'pool': {'name': DEFAULT_POOL}}]}
resp = self.request(new_tmpl_uri, json.dumps(disk_data), 'PUT')
self.assertEquals(200, resp.status)
resp = self.request(new_tmpl_uri)
@@ -236,7 +239,7 @@ class TemplateTests(unittest.TestCase):
'qed', 'raw', 'vmdk', 'vpc']
for disk_type in disk_types:
disk_data = {'disks': [{'index': 0, 'format': disk_type,
- 'size': 10, 'pool': DEFAULT_POOL}]}
+ 'size': 10, 'pool': {'name': DEFAULT_POOL}}]}
resp = self.request(new_tmpl_uri, json.dumps(disk_data), 'PUT')
self.assertEquals(200, resp.status)
@@ -350,9 +353,14 @@ class TemplateTests(unittest.TestCase):
if len(vols) > 0:
vol = vols[0]['name']
req = json.dumps({'disks': [{'volume': vol,
- 'pool': {'name': pool_uri}}]})
+ 'pool': {'name': pool_uri},
+ 'format': 'raw'}]})
+ elif pool['type'] == 'logical':
+ req = json.dumps({'disks': [{'pool': {'name': pool_uri},
+ 'format': 'raw', 'size': 10}]})
else:
- req = json.dumps({'disks': [{'pool': {'name': pool_uri}}]})
+ req = json.dumps({'disks': [{'pool': {'name': pool_uri},
+ 'format': 'qcow2', 'size': 10}]})
if req is not None:
resp = self.request('/plugins/kimchi/templates/test', req,
@@ -362,7 +370,7 @@ class TemplateTests(unittest.TestCase):
# Test disk template update with different pool
pool_uri = u'/plugins/kimchi/storagepools/kīмсhīUnitTestDirPool'
disk_data = {'disks': [{'size': 5, 'format': 'qcow2',
- 'pool': pool_uri}]}
+ 'pool': {'name': pool_uri}}]}
req = json.dumps(disk_data)
resp = self.request('/plugins/kimchi/templates/test', req, 'PUT')
self.assertEquals(200, resp.status)
@@ -393,7 +401,8 @@ class TemplateTests(unittest.TestCase):
'networks': ['nat-network'],
'disks': [{'pool': {
'name': '/plugins/kimchi/storagepools/dir-pool'},
- 'size': 2}]}
+ 'size': 2,
+ 'format': 'qcow2'}]}
req = json.dumps(t)
resp = self.request('/plugins/kimchi/templates', req, 'POST')
self.assertEquals(201, resp.status)
diff --git a/tests/test_vmtemplate.py b/src/wok/plugins/kimchi/tests/test_vmtemplate.py
index 0bca215..79e3b52 100644
--- a/tests/test_vmtemplate.py
+++ b/tests/test_vmtemplate.py
@@ -26,6 +26,11 @@ from wok.xmlutils.utils import xpath_get_text
from wok.plugins.kimchi.osinfo import get_template_default
from wok.plugins.kimchi.vmtemplate import VMTemplate
+DISKS = [{'size': 10, 'format': 'raw', 'index': 0, 'pool': {'name':
+ '/plugins/kimchi/storagepools/default-pool'}},
+ {'size': 5, 'format': 'qcow2', 'index': 1, 'pool': {'name':
+ '/plugins/kimchi/storagepools/default-pool'}}]
+
class VMTemplateTests(unittest.TestCase):
def setUp(self):
@@ -53,7 +58,7 @@ class VMTemplateTests(unittest.TestCase):
def test_construct_overrides(self):
graphics = {'type': 'spice', 'listen': '127.0.0.1'}
- args = {'name': 'test', 'disks': [{'size': 10}, {'size': 20}],
+ args = {'name': 'test', 'disks': DISKS,
'graphics': graphics, "cdrom": self.iso}
t = VMTemplate(args)
self.assertEquals(2, len(t.info['disks']))
@@ -62,7 +67,7 @@ class VMTemplateTests(unittest.TestCase):
def test_specified_graphics(self):
# Test specified listen
graphics = {'type': 'vnc', 'listen': '127.0.0.1'}
- args = {'name': 'test', 'disks': [{'size': 10}, {'size': 20}],
+ args = {'name': 'test', 'disks': DISKS,
'graphics': graphics, 'cdrom': self.iso}
t = VMTemplate(args)
self.assertEquals(graphics, t.info['graphics'])
diff --git a/vmtemplate.py b/src/wok/plugins/kimchi/vmtemplate.py
index 62d0e1a..b90f221 100644
--- a/vmtemplate.py
+++ b/vmtemplate.py
@@ -76,23 +76,40 @@ class VMTemplate(object):
graphics.update(graph_args)
args['graphics'] = graphics
+ default_disk = self.info['disks'][0]
# Override template values according to 'args'
self.info.update(args)
-
- # Find pool type for each disk
disks = self.info.get('disks')
- for disk in disks:
- pool_name = disk.get('pool', {}).get('name')
- if pool_name is None:
- raise MissingParameter('KCHTMPL0029E')
+
+ basic_disk = ['index', 'format', 'pool', 'size']
+ ro_disk = ['index', 'format', 'pool', 'volume']
+ base_disk = ['index', 'base', 'pool', 'size', 'format']
+
+ for index, disk in enumerate(disks):
+ disk_info = dict(default_disk)
pool_type = self._get_storage_type(disk['pool']['name'])
- disk['pool']['type'] = pool_type
+ if pool_type in ['iscsi', 'scsi']:
+ disk_info = {'index': 0, 'format': 'raw', 'volume': None}
+
+ disk_info.update(disk)
+ pool_name = disk_info.get('pool', {}).get('name')
+ if pool_name is None:
+ raise MissingParameter('KCHTMPL0028E')
+
+ keys = sorted(disk_info.keys())
+ if ((keys != sorted(basic_disk)) and (keys != sorted(ro_disk)) and
+ (keys != sorted(base_disk))):
+ raise MissingParameter('KCHTMPL0028E')
if pool_type in ['logical', 'iscsi', 'scsi']:
- if disk['format'] != 'raw':
+ if disk_info['format'] != 'raw':
raise InvalidParameter('KCHTMPL0029E')
+ disk_info['pool']['type'] = pool_type
+ disk_info['index'] = disk_info.get('index', index)
+ self.info['disks'][index] = disk_info
+
def _get_os_info(self, args, scan):
distro = version = 'unknown'
@@ -406,7 +423,9 @@ class VMTemplate(object):
return xml
def validate(self):
- self._storage_validate()
+ for disk in self.info.get('disks'):
+ pool_uri = disk.get('pool', {}).get('name')
+ self._storage_validate(pool_uri)
self._network_validate()
self._iso_validate()
--
2.1.0
More information about the Kimchi-devel
mailing list