diff --git a/COT/edit_hardware.py b/COT/edit_hardware.py
index 4b3ec67..d06d7ff 100644
--- a/COT/edit_hardware.py
+++ b/COT/edit_hardware.py
@@ -57,8 +57,8 @@ class COTEditHardware(COTSubmodule):
:attr:`nic_names`,
:attr:`serial_ports`,
:attr:`serial_connectivity`,
- :attr:`scsi_subtype`,
- :attr:`ide_subtype`,
+ :attr:`scsi_subtypes`,
+ :attr:`ide_subtypes`,
:attr:`virtual_system_type`
"""
@@ -88,10 +88,10 @@ def __init__(self, UI):
self._serial_ports = None
self.serial_connectivity = None
"""List of serial connection strings."""
- self.scsi_subtype = None
- """Subtype string for SCSI controllers"""
- self.ide_subtype = None
- """Subtype string for IDE controllers"""
+ self.scsi_subtypes = None
+ """Subtype string list for SCSI controllers"""
+ self.ide_subtypes = None
+ """Subtype string list for IDE controllers"""
self.virtual_system_type = None
"""Virtual system type"""
@@ -172,7 +172,7 @@ def nic_type(self):
.. deprecated:: 1.5
Use :attr:`nic_types` instead.
"""
- warnings.warn("Use nic_type instead", DeprecationWarning)
+ warnings.warn("Use nic_types instead", DeprecationWarning)
if self.nic_types is None:
return None
if len(self.nic_types) > 1:
@@ -210,6 +210,48 @@ def serial_ports(self, value):
self.vm.platform.validate_serial_count(value)
self._serial_ports = value
+ @property
+ def scsi_subtype(self):
+ """SCSI controller subtype string to set.
+
+ .. deprecated:: 1.5
+ Use :attr:`scsi_subtypes` instead.
+ """
+ warnings.warn("Use scsi_subtypes instead", DeprecationWarning)
+ if self.scsi_subtypes is None:
+ return None
+ if len(self.scsi_subtypes) > 1:
+ raise TypeError("scsi_subtypes has more than one element ({0}). "
+ "Use scsi_subtypes instead of scsi_subtype."
+ .format(self.scsi_subtypes))
+ return self.scsi_subtypes[0]
+
+ @scsi_subtype.setter
+ def scsi_subtype(self, value):
+ warnings.warn("Use scsi_subtypes instead", DeprecationWarning)
+ self.scsi_subtypes = [value]
+
+ @property
+ def ide_subtype(self):
+ """NIC type string to set.
+
+ .. deprecated:: 1.5
+ Use :attr:`ide_subtypes` instead.
+ """
+ warnings.warn("Use ide_subtypes instead", DeprecationWarning)
+ if self.ide_subtypes is None:
+ return None
+ if len(self.ide_subtypes) > 1:
+ raise TypeError("ide_subtypes has more than one element ({0}). "
+ "Use ide_subtypes instead of ide_subtype."
+ .format(self.ide_subtypes))
+ return self.ide_subtypes[0]
+
+ @ide_subtype.setter
+ def ide_subtype(self, value):
+ warnings.warn("Use ide_subtypes instead", DeprecationWarning)
+ self.ide_subtypes = [value]
+
def ready_to_run(self):
"""Check whether the module is ready to :meth:`run`.
@@ -228,8 +270,8 @@ def ready_to_run(self):
self.nic_names is None and
self.serial_ports is None and
self.serial_connectivity is None and
- self.scsi_subtype is None and
- self.ide_subtype is None and
+ self.scsi_subtypes is None and
+ self.ide_subtypes is None and
self.virtual_system_type is None
):
return (False, "No work requested! Please specify at least "
@@ -360,11 +402,11 @@ def run(self):
len(self.serial_connectivity)))
vm.set_serial_connectivity(self.serial_connectivity, self.profiles)
- if self.scsi_subtype is not None:
- vm.set_scsi_subtype(self.scsi_subtype, self.profiles)
+ if self.scsi_subtypes is not None:
+ vm.set_scsi_subtypes(self.scsi_subtypes, self.profiles)
- if self.ide_subtype is not None:
- vm.set_ide_subtype(self.ide_subtype, self.profiles)
+ if self.ide_subtypes is not None:
+ vm.set_ide_subtypes(self.ide_subtypes, self.profiles)
def create_subparser(self, parent, storage):
"""Add subparser for the CLI of this submodule.
@@ -385,10 +427,10 @@ def create_subparser(self, parent, storage):
"PACKAGE [-o OUTPUT] -v TYPE [TYPE2 ...]",
"PACKAGE [-o OUTPUT] \
[-p PROFILE [PROFILE2 ...] [--delete-all-other-profiles]] [-c CPUS] \
-[-m MEMORY] [-n NICS] [--nic-types [{e1000,virtio,vmxnet3} ...]] \
+[-m MEMORY] [-n NICS] [--nic-types TYPE [TYPE2 ...]] \
[-N NETWORK [NETWORK2 ...]] [-M MAC1 [MAC2 ...]] \
[--nic-names NAME1 [NAME2 ...]] [-s SERIAL_PORTS] [-S URI1 [URI2 ...]] \
-[--scsi-subtype SCSI_SUBTYPE] [--ide-subtype IDE_SUBTYPE]",
+[--scsi-subtypes TYPE [TYPE2 ...]] [--ide-subtypes TYPE [TYPE2 ...]]",
]),
help="Edit virtual machine hardware properties of an OVF",
description="Edit hardware properties of the specified OVF or OVA",
@@ -484,13 +526,15 @@ def create_subparser(self, parent, storage):
g = p.add_argument_group("disk and disk controller options")
- g.add_argument('--scsi-subtype',
- help='Set resource subtype (such as "lsilogic" or '
+ g.add_argument('--scsi-subtypes', action='append', nargs='+',
+ metavar=('TYPE', 'TYPE2'),
+ help='Set resource subtype(s) (such as "lsilogic" or '
'"virtio") for all SCSI controllers. If an empty '
"string is provided, any existing subtype will be "
"removed.")
- g.add_argument('--ide-subtype',
- help='Set resource subtype (such as "virtio") for '
+ g.add_argument('--ide-subtypes', action='append', nargs='+',
+ metavar=('TYPE', 'TYPE2'),
+ help='Set resource subtype(s) (such as "virtio") for '
"all IDE controllers. If an empty string is "
"provided, any existing subtype will be removed.")
diff --git a/COT/ovf.py b/COT/ovf.py
index 621a096..8fcc0cd 100644
--- a/COT/ovf.py
+++ b/COT/ovf.py
@@ -1325,26 +1325,28 @@ def get_serial_connectivity(self, profile):
return [item.get_value(self.ADDRESS) for item in
self.hardware.find_all_items('serial', profile_list=[profile])]
- def set_scsi_subtype(self, type, profile_list):
- """Set the device subtype for the SCSI controller(s).
+ def set_scsi_subtypes(self, type_list, profile_list):
+ """Set the device subtype(s) for the SCSI controller(s).
- :param str type: SCSI subtype string
+ :param list type_list: SCSI subtype string list
:param list profile_list: Change only the given profiles
"""
# TODO validate supported types by platform
self.hardware.set_value_for_all_items('scsi',
- self.RESOURCE_SUB_TYPE, type,
+ self.RESOURCE_SUB_TYPE,
+ " ".join(type_list),
profile_list)
- def set_ide_subtype(self, type, profile_list):
- """Set the device subtype for the IDE controller(s).
+ def set_ide_subtypes(self, type_list, profile_list):
+ """Set the device subtype(s) for the IDE controller(s).
- :param str type: IDE subtype string
+ :param list type_list: IDE subtype string list
:param list profile_list: Change only the given profiles
"""
# TODO validate supported types by platform
self.hardware.set_value_for_all_items('ide',
- self.RESOURCE_SUB_TYPE, type,
+ self.RESOURCE_SUB_TYPE,
+ " ".join(type_list),
profile_list)
def get_property_value(self, key):
diff --git a/COT/tests/test_edit_hardware.py b/COT/tests/test_edit_hardware.py
index 1dc8a98..3c50822 100644
--- a/COT/tests/test_edit_hardware.py
+++ b/COT/tests/test_edit_hardware.py
@@ -1164,6 +1164,7 @@ def test_set_scsi_subtype_all_profiles(self):
"""Set SCSI controller subtype under all profiles."""
self.instance.package = self.input_ovf
self.instance.scsi_subtype = "virtio"
+ self.assertEqual(self.instance.scsi_subtype, "virtio")
self.instance.run()
self.instance.finished()
self.check_diff("""
@@ -1177,6 +1178,9 @@ def test_clear_scsi_subtype_all_profiles(self):
"""Clear SCSI controller subtype under all profiles."""
self.instance.package = self.input_ovf
self.instance.scsi_subtype = ""
+ self.assertEqual(self.instance.scsi_subtype, "")
+ # TODO: this should really be an empty list or None
+ self.assertEqual(self.instance.scsi_subtypes, [""])
self.instance.run()
self.instance.finished()
self.check_diff("""
@@ -1188,7 +1192,10 @@ def test_clear_scsi_subtype_all_profiles(self):
def test_set_scsi_subtype_one_profile(self):
"""Set SCSI controller subtype under a single profile."""
self.instance.package = self.input_ovf
- self.instance.scsi_subtype = "virtio"
+ self.instance.scsi_subtypes = ['buslogic', 'lsilogic']
+ self.assertEqual(self.instance.scsi_subtypes, ['buslogic', 'lsilogic'])
+ with self.assertRaises(TypeError):
+ self.instance.scsi_subtype
self.instance.profiles = ['4CPU-4GB-3NIC']
self.instance.run()
self.instance.finished()
@@ -1201,7 +1208,7 @@ def test_set_scsi_subtype_one_profile(self):
+ SCSI Controller
+ SCSI Controller 0
+ 3
-+ virtio
++ buslogic lsilogic
+ 6
+
@@ -1210,6 +1217,8 @@ def test_set_scsi_subtype_one_profile(self):
def test_set_scsi_subtype_no_existing(self):
"""Set SCSI controller subtype for an OVF with none (no-op)."""
self.instance.package = self.minimal_ovf
+ self.assertEqual(self.instance.scsi_subtype, None)
+ self.assertEqual(self.instance.scsi_subtypes, None)
self.instance.scsi_subtype = "virtio"
self.instance.run()
self.assertLogged(**self.NO_ITEMS_NO_WORK)
@@ -1219,18 +1228,21 @@ def test_set_scsi_subtype_no_existing(self):
def test_set_ide_subtype_all_profiles(self):
"""Set IDE controller subtype across all profiles."""
self.instance.package = self.input_ovf
- self.instance.ide_subtype = "virtio"
+ self.instance.ide_subtypes = ["virtio", "foobar"]
+ self.assertEqual(self.instance.ide_subtypes, ["virtio", "foobar"])
+ with self.assertRaises(TypeError):
+ self.instance.ide_subtype
self.instance.run()
self.instance.finished()
# Since there is no pre-existing subtype, we just create it
# under each controller:
self.check_diff("""
4
-+ virtio
++ virtio foobar
5
...
5
-+ virtio
++ virtio foobar
5
""")
@@ -1238,6 +1250,8 @@ def test_set_ide_subtype_one_profile(self):
"""Set IDE controller subtype under a single profile."""
self.instance.package = self.input_ovf
self.instance.ide_subtype = "virtio"
+ self.assertEqual(self.instance.ide_subtype, "virtio")
+ self.assertEqual(self.instance.ide_subtypes, ["virtio"])
self.instance.profiles = ['4CPU-4GB-3NIC']
self.instance.run()
self.instance.finished()
@@ -1270,6 +1284,8 @@ def test_set_ide_subtype_one_profile(self):
def test_set_ide_subtype_no_existing(self):
"""Set IDE controller subtype for an OVF with none (no-op)."""
self.instance.package = self.minimal_ovf
+ self.assertEqual(self.instance.ide_subtype, None)
+ self.assertEqual(self.instance.ide_subtypes, None)
self.instance.ide_subtype = "virtio"
self.instance.run()
self.assertLogged(**self.NO_ITEMS_NO_WORK)
diff --git a/COT/vm_description.py b/COT/vm_description.py
index c1a52b5..21b492a 100644
--- a/COT/vm_description.py
+++ b/COT/vm_description.py
@@ -545,18 +545,42 @@ def get_serial_connectivity(self, profile):
def set_scsi_subtype(self, type, profile_list):
"""Set the device subtype for the SCSI controller(s).
+ .. deprecated:: 1.5
+ Use :func:`set_scsi_subtypes` instead.
+
:param str type: SCSI subtype string
:param list profile_list: Change only the given profiles
"""
- raise NotImplementedError("set_scsi_subtype not implemented!")
+ warnings.warn("Use set_scsi_subtypes() instead", DeprecationWarning)
+ self.set_scsi_subtypes([type], profile_list)
+
+ def set_scsi_subtypes(self, type_list, profile_list):
+ """Set the device subtype list for the SCSI controller(s).
+
+ :param list type_list: SCSI subtype string list
+ :param list profile_list: Change only the given profiles
+ """
+ raise NotImplementedError("set_scsi_subtypes not implemented!")
def set_ide_subtype(self, type, profile_list):
"""Set the device subtype for the IDE controller(s).
+ .. deprecated:: 1.5
+ Use :func:`set_ide_subtypes` instead.
+
:param str type: IDE subtype string
:param list profile_list: Change only the given profiles
"""
- raise NotImplementedError("set_ide_subtype not implemented!")
+ warnings.warn("Use set_ide_subtypes() instead", DeprecationWarning)
+ self.set_ide_subtypes([type], profile_list)
+
+ def set_ide_subtypes(self, type_list, profile_list):
+ """Set the device subtype list for the IDE controller(s).
+
+ :param list type: IDE subtype string list
+ :param list profile_list: Change only the given profiles
+ """
+ raise NotImplementedError("set_ide_subtypes not implemented!")
# API methods needed for edit-product
# API methods needed for edit-properties