Implement functions 'RemoveDisk' and 'DetachInstDisk'. The first one
removes a disk from the config file and the second one detaches a disk
from an instance. A wrapper 'RemoveInstDisk' is provided in order to
detach a disk from an instance and remove it at once (since ganeti
doesn't support dangling disks yet).

Signed-off-by: Ilias Tsitsimpis <[email protected]>
---
 lib/config.py | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/lib/config.py b/lib/config.py
index 4df28c5..872ae33 100644
--- a/lib/config.py
+++ b/lib/config.py
@@ -464,6 +464,70 @@ class ConfigWriter(object):
     self._UnlockedAddDisk(disk)
     self._UnlockedAttachInstDisk(instance, disk, idx)
 
+  def _UnlockedDetachInstDisk(self, instance, disk):
+    """Detach a disk from an instance.
+
+    This function is for internal use, when the config lock is already held.
+
+    @type instance: L{objects.Instance}
+    @param instance: the instance object
+    @type disk: L{objects.Disk}
+    @param disk: the disk object
+
+    """
+    if not isinstance(instance, objects.Instance) or \
+        not isinstance(disk, objects.Disk):
+      raise errors.ProgrammerError(
+        "Invalid type passed to _UnlockedDetachInstDisk")
+    if instance.uuid not in self._ConfigData().instances:
+      raise errors.ConfigurationError("Instance %s doesn't exist"
+                                      % instance.uuid)
+    if disk.uuid not in self._ConfigData().disks:
+      raise errors.ConfigurationError("Disk %s doesn't exist" % disk.uuid)
+
+    # Check if disk is attached to the instance
+    if disk.uuid not in instance.disks:
+      raise errors.ProgrammerError("Disk %s is not attached to an instance"
+                                   % disk.uuid)
+
+    idx = instance.disks.index(disk.uuid)
+    instance.disks.remove(disk.uuid)
+    inst_disks = self._UnlockedGetInstanceDisks(instance)
+    _UpdateIvNames(idx, inst_disks[idx:])
+    instance.serial_no += 1
+    instance.mtime = time.time()
+
+    # Update instance object
+    self._ConfigData().instances[instance.uuid] = instance
+
+  def _UnlockedRemoveDisk(self, disk_uuid):
+    """Remove the disk from the configuration.
+
+    This function is for internal use, when the config lock is already held.
+
+    """
+    if disk_uuid not in self._ConfigData().disks:
+      raise errors.ConfigurationError("Unknown disk '%s'" % disk_uuid)
+
+    # Remove disk from config file
+    del self._ConfigData().disks[disk_uuid]
+    self._ConfigData().cluster.serial_no += 1
+
+  @_ConfigSync()
+  def RemoveInstDisk(self, instance, disk_uuid):
+    """Detach a disk from an instance and remove it from the config.
+
+    @type disk_uuid: string
+    @param disk_uuid: the uuid of the disk we want to remove
+
+    """
+    if disk_uuid not in self._ConfigData().disks:
+      raise errors.ConfigurationError("Unknown disk '%s'" % disk_uuid)
+
+    disk = self._ConfigData().disks[disk_uuid]
+    self._UnlockedDetachInstDisk(instance, disk)
+    self._UnlockedRemoveDisk(disk_uuid)
+
   def _UnlockedGetDiskInfo(self, disk_uuid):
     """Returns information about an instance.
 
-- 
1.9.1

Reply via email to