On Thu, Mar 19, 2015 at 04:16:49PM +0100, 'Hrvoje Ribicic' via ganeti-devel 
wrote:
commit 28863008bdc4ae56440af23f8bbf92da250c588d
Merge: ac77262 1c5456b
Author: Hrvoje Ribicic <[email protected]>
Date:   Thu Mar 19 15:08:41 2015 +0000

   Merge branch 'stable-2.11' into stable-2.12

   * stable-2.11
     Improve speed of Xen hypervisor unit tests
     Improve Xen instance state handling

   * stable-2.10
     Make QA fail if KVM hotplugging fails
     Always preserve QA command output
     Don't lose stdout/stderr in AssertCommand
     qa_utils: Allow passing fail=None to AssertCommand
     qa_utils: Make AssertCommand return stdout/stderr as well
     Allow plain/DRBD conversions regardless of lack of disks
     Add support for ipolicy modifications to mock config

   Conflicts:
   lib/cmdlib/instance.py
   qa/qa_instance.py
   test/py/cmdlib/testsupport/config_mock.py
   Resolution:
   instance.py: Keep new testing logic, modify snode fetch.
   qa_instance.py: Reenable hotplug tests.
           config_mock.py: Combine all changes.

   Signed-off-by: Hrvoje Ribicic <[email protected]>

diff --cc lib/cmdlib/instance.py
index 8508ae8,5bb47db..d5b2c6b
--- a/lib/cmdlib/instance.py
+++ b/lib/cmdlib/instance.py
@@@ -3678,17 -3282,20 +3678,23 @@@ class LUInstanceSetParams(LogicalUnit)
     """Converts an instance from drbd to plain.

     """
+    secondary_nodes =
self.cfg.GetInstanceSecondaryNodes(self.instance.uuid)
-     assert len(secondary_nodes) == 1
++
     assert self.instance.disk_template == constants.DT_DRBD8
-    assert len(self.instance.secondary_nodes) == 1 or not
self.instance.disks
++    assert len(secondary_nodes) == 1 or not self.instance.disks

     pnode_uuid = self.instance.primary_node
-     snode_uuid = secondary_nodes[0]
+
+     # it will not be possible to calculate the snode_uuid later
+     snode_uuid = None
-    if self.instance.secondary_nodes:
-      snode_uuid = self.instance.secondary_nodes[0]
++    if secondary_nodes:
++      snode_uuid = secondary_nodes[0]
+
     feedback_fn("Converting template to plain")

-    old_disks = AnnotateDiskParams(self.instance, self.instance.disks,
self.cfg)
-    new_disks = [d.children[0] for d in self.instance.disks]
+    disks = self.cfg.GetInstanceDisks(self.instance.uuid)
+    old_disks = AnnotateDiskParams(self.instance, disks, self.cfg)
+    new_disks = [d.children[0] for d in disks]

     # copy over size, mode and name
     for parent, child in zip(old_disks, new_disks):
diff --cc qa/qa_instance.py
index b98cf0a,482f024..6cbe96e
--- a/qa/qa_instance.py
+++ b/qa/qa_instance.py
@@@ -611,23 -585,8 +630,14 @@@ def TestInstanceModify(instance)
       ])
   elif default_hv == constants.HT_KVM and \
     qa_config.TestEnabled("instance-device-hotplug"):
-     # FIXME: Fix issue 885 and then re-enable the tests below
-     #args.extend([
-     #  ["--net", "-1:add", "--hotplug"],
-     #  ["--net", "-1:modify,mac=aa:bb:cc:dd:ee:ff", "--hotplug",
"--force"],
-     #  ["--net", "-1:remove", "--hotplug"],
-     #  ])
-     args.extend([
-       ["--disk", "-1:add,size=1G", "--hotplug"],
-       ["--disk", "-1:remove", "--hotplug"],
-       ])
+     _TestKVMHotplug(instance)

+  url = "http://example.com/busybox.img";
+  args.extend([
+      ["--os-parameters", "os-image=" + url],
+      ["--os-parameters", "os-image=default"]
+      ])
+
   for alist in args:
     AssertCommand(["gnt-instance", "modify"] + alist + [instance.name])

diff --cc test/py/cmdlib/testsupport/config_mock.py
index 2fe8f67,f90a8e5..57ca73f
--- a/test/py/cmdlib/testsupport/config_mock.py
+++ b/test/py/cmdlib/testsupport/config_mock.py
@@@ -572,16 -549,27 +572,36 @@@ class ConfigMock(config.ConfigWriter)
     cluster.enabled_disk_templates = list(enabled_disk_templates)
     cluster.ipolicy[constants.IPOLICY_DTS] = list(enabled_disk_templates)

+  def ComputeDRBDMap(self):
+    return dict((node_uuid, {}) for node_uuid in self._ConfigData().nodes)
+
+  def AllocateDRBDMinor(self, node_uuids, inst_uuid):
+    return map(lambda _: 0, node_uuids)
+
+  def _UnlockedReleaseDRBDMinors(self, inst_uuid):
+    pass
+
+   def SetIPolicyField(self, category, field, value):
+     """Set a value of a desired ipolicy field.
+
+     @type category: one of L{constants.ISPECS_MAX},
L{constants.ISPECS_MIN},
+       L{constants.ISPECS_STD}
+     @param category: Whether to change the default value, or the upper or
lower
+       bound.
+     @type field: string
+     @param field: The field to change.
+     @type value: any
+     @param value: The value to assign.
+
+     """
+     if category not in [constants.ISPECS_MAX, constants.ISPECS_MIN,
+                         constants.ISPECS_STD]:
+       raise ValueError("Invalid ipolicy category %s" % category)
+
+     ipolicy_dict =
self.GetClusterInfo().ipolicy[constants.ISPECS_MINMAX][0]
+     ipolicy_dict[category][field] = value
+
-  def _OpenConfig(self, accept_foreign):
+  def _CreateConfig(self):
     self._config_data = objects.ConfigData(
       version=constants.CONFIG_VERSION,
       cluster=None,

LGTM, thanks

Reply via email to