def _zeroLogicalVolume(self, name, size, perform_on_nodes=False): """Blanks a logical volume by filling it with null data""" # Obtain the path of the logical volume lv_path = self._getLogicalVolumePath(name) # Create command arguments command_args = [ 'dd', 'if=/dev/zero', 'of=%s' % lv_path, 'bs=1M', 'count=%s' % size, 'conv=fsync', 'oflag=direct' ] try: # Create logical volume on local node System.runCommand(command_args) if perform_on_nodes and self._is_cluster_master: def remoteCommand(node): remote_disk = self.get_remote_object(remote_node=node, registered=False) remote_disk.zeroLogicalVolume(name=name, size=size) cluster = self._get_registered_object('cluster') cluster.run_remote_command( callback_method=remoteCommand, nodes=self.vm_object._get_remote_nodes()) except MCVirtCommandException, e: raise ExternalStorageCommandErrorException( "Error whilst zeroing logical volume:\n" + str(e))
def _activateLogicalVolume(self, name, perform_on_nodes=False): """Activates a logical volume on the node/cluster""" # Obtain logical volume path lv_path = self._getLogicalVolumePath(name) # Create command arguments command_args = ['lvchange', '-a', 'y', '--yes', lv_path] try: # Run on the local node System.runCommand(command_args) if perform_on_nodes and self._is_cluster_master: def remoteCommand(node): remote_disk = self.get_remote_object(remote_node=node, registered=False) remote_disk.activateLogicalVolume(name=name) cluster = self._get_registered_object('cluster') cluster.run_remote_command( callback_method=remoteCommand, nodes=self.vm_object._get_remote_nodes()) except MCVirtCommandException, e: raise ExternalStorageCommandErrorException( "Error whilst activating logical volume:\n" + str(e))
def _removeLogicalVolume(self, name, ignore_non_existent=False, perform_on_nodes=False): """Removes a logical volume from the node/cluster""" # Create command arguments command_args = ['lvremove', '-f', self._getLogicalVolumePath(name)] try: # Determine if logical volume exists before attempting to remove it if (not (ignore_non_existent and not self._checkLogicalVolumeExists(name))): System.runCommand(command_args) if perform_on_nodes and self._is_cluster_master: def remoteCommand(node): remote_disk = self.get_remote_object(remote_node=node, registered=False) remote_disk.removeLogicalVolume( name=name, ignore_non_existent=ignore_non_existent) cluster = self._get_registered_object('cluster') cluster.run_remote_command( callback_method=remoteCommand, nodes=self.vm_object._get_remote_nodes()) except MCVirtCommandException, e: raise ExternalStorageCommandErrorException( "Error whilst removing disk logical volume:\n" + str(e))
def _createLogicalVolume(self, name, size, perform_on_nodes=False): """Creates a logical volume on the node/cluster""" volume_group = self._getVolumeGroup() # Create command list command_args = [ '/sbin/lvcreate', volume_group, '--name', name, '--size', '%sM' % size ] try: # Create on local node System.runCommand(command_args) if perform_on_nodes and self._is_cluster_master: def remoteCommand(node): remote_disk = self.get_remote_object(remote_node=node, registered=False) remote_disk.createLogicalVolume(name=name, size=size) cluster = self._get_registered_object('cluster') cluster.run_remote_command( callback_method=remoteCommand, nodes=self.vm_object._get_remote_nodes()) except MCVirtCommandException, e: # Remove any logical volumes that had been created if one of them fails self._removeLogicalVolume(name, ignore_non_existent=True, perform_on_nodes=perform_on_nodes) raise ExternalStorageCommandErrorException( "Error whilst creating disk logical volume:\n" + str(e))
def increaseSize(self, increase_size): """Increases the size of a VM hard drive, given the size to increase the drive by""" self._get_registered_object('auth').assert_permission( PERMISSIONS.MODIFY_VM, self.vm_object) # Ensure disk exists self._ensure_exists() # Ensure VM is stopped from mcvirt.virtual_machine.virtual_machine import PowerStates if (self.vm_object._getPowerState() is not PowerStates.STOPPED): raise VmAlreadyStartedException( 'VM must be stopped before increasing disk size') # Ensure that VM has not been cloned and is not a clone if (self.vm_object.getCloneParent() or self.vm_object.getCloneChildren()): raise VmIsCloneException( 'Cannot increase the disk of a cloned VM or a clone.') command_args = ('lvextend', '-L', '+%sM' % increase_size, self._getDiskPath()) try: System.runCommand(command_args) except MCVirtCommandException, e: raise ExternalStorageCommandErrorException( "Error whilst extending logical volume:\n" + str(e))
def _resize_logical_volume(self, name, size, perform_on_nodes=False): """Creates a logical volume on the node/cluster""" # Create command list command_args = [ '/sbin/lvresize', '--size', '%sM' % size, self._getLogicalVolumePath(name) ] try: # Create on local node System.runCommand(command_args) if perform_on_nodes and self._is_cluster_master: def remoteCommand(node): remote_disk = self.get_remote_object(remote_node=node, registered=False) remote_disk.resize_logical_volume(name=name, size=size) cluster = self._get_registered_object('cluster') cluster.run_remote_command( callback_method=remoteCommand, nodes=self.vm_object._get_remote_nodes()) except MCVirtCommandException, e: raise ExternalStorageCommandErrorException( "Error whilst resizing disk logical volume:\n" + str(e))
def _get_logical_volume_size(self, name): """Obtains the size of a logical volume""" # Use 'lvs' to obtain the size of the disk command_args = ('lvs', '--nosuffix', '--noheadings', '--units', 'm', '--options', 'lv_size', self._getLogicalVolumePath(name)) try: _, command_output, _ = System.runCommand(command_args) except MCVirtCommandException, e: raise ExternalStorageCommandErrorException( "Error whilst obtaining the size of the logical volume:\n" + str(e))
def clone(self, destination_vm_object): """Clone a VM, using snapshotting, attaching it to the new VM object""" self._ensure_exists() new_disk = Local(vm_object=destination_vm_object, driver=self.driver, disk_id=self.disk_id) self._register_object(new_disk) new_logical_volume_name = new_disk._getDiskName() disk_size = self.getSize() # Perform a logical volume snapshot command_args = ('lvcreate', '-L', '%sM' % disk_size, '-s', '-n', new_logical_volume_name, self._getDiskPath()) try: System.runCommand(command_args) except MCVirtCommandException, e: raise ExternalStorageCommandErrorException( "Error whilst cloning disk logical volume:\n" + str(e))
def duplicate(self, destination_vm_object): """Clone the hard drive and attach it to the new VM object""" self._ensure_exists() # Create new disk object, using the same type, size and disk_id new_disk_object = self.__class__(vm_object=destination_vm_object, disk_id=self.disk_id, driver=self.driver) self._register_object(new_disk_object) new_disk_object.create(self.getSize()) source_drbd_block_device = self._getDiskPath() destination_drbd_block_device = new_disk_object._getDiskPath() # Use dd to duplicate the old disk to the new disk command_args = ('dd', 'if=%s' % source_drbd_block_device, 'of=%s' % destination_drbd_block_device, 'bs=1M') try: System.runCommand(command_args) except MCVirtCommandException, e: new_disk_object.delete() raise ExternalStorageCommandErrorException( "Error whilst duplicating disk logical volume:\n" + str(e))