def _attach_volume_vmdk(self, connection_info, instance, mountpoint): """Attach vmdk volume storage to VM instance.""" instance_name = instance['name'] vm_ref = vm_util.get_vm_ref(self._session, instance) data = connection_info['data'] # Get volume details from volume ref volume_ref = self._get_volume_ref(data['volume']) volume_device = self._get_vmdk_base_volume_device(volume_ref) volume_vmdk_path = volume_device.backing.fileName # Get details required for adding disk device such as # adapter_type, disk_type hw_devices = self._session._call_method(vim_util, 'get_dynamic_property', vm_ref, 'VirtualMachine', 'config.hardware.device') (vmdk_file_path, adapter_type, disk_type) = vm_util.get_vmdk_path_and_adapter_type(hw_devices) # Attach the disk to virtual machine instance self.attach_disk_to_vm(vm_ref, instance, adapter_type, disk_type, vmdk_path=volume_vmdk_path) # Store the uuid of the volume_device self._update_volume_details(vm_ref, instance, data['volume_id']) LOG.info(_("Mountpoint %(mountpoint)s attached to " "instance %(instance_name)s"), {'mountpoint': mountpoint, 'instance_name': instance_name}, instance=instance)
def test_get_vmdk_path_and_adapter_type_with_nomatch(self): n_filename = "[test_datastore] diuu/diuu.vmdk" devices = self._vmdk_path_and_adapter_type_devices(n_filename) vmdk_info = vm_util.get_vmdk_path_and_adapter_type(devices, uuid="uuid") adapter_type = vmdk_info[1] self.assertEqual("lsiLogicsas", adapter_type) self.assertIsNone(vmdk_info[0])
def _detach_volume_vmdk(self, connection_info, instance): """Detach volume storage to VM instance.""" vm_ref = vm_util.get_vm_ref(self._session, instance) # Detach Volume from VM LOG.debug("_detach_volume_vmdk: %s", connection_info, instance=instance) data = connection_info['data'] volume_ref = self._get_volume_ref(data['volume']) device = self._get_vmdk_backed_disk_device(vm_ref, data) # Get details required for adding disk device such as # adapter_type, disk_type hw_devices = self._session._call_method(vim_util, 'get_dynamic_property', volume_ref, 'VirtualMachine', 'config.hardware.device') (vmdk_file_path, adapter_type, disk_type) = vm_util.get_vmdk_path_and_adapter_type(hw_devices) # IDE does not support disk hotplug if (instance.vm_state == vm_states.ACTIVE and adapter_type == constants.ADAPTER_TYPE_IDE): msg = _('%s does not support disk hotplug.') % adapter_type raise exception.Invalid(msg) self._consolidate_vmdk_volume(instance, vm_ref, device, volume_ref, adapter_type=adapter_type, disk_type=disk_type) self.detach_disk_from_vm(vm_ref, instance, device) LOG.debug("Detached VMDK: %s", connection_info, instance=instance)
def _attach_volume_iscsi(self, connection_info, instance, mountpoint): """Attach iscsi volume storage to VM instance.""" instance_name = instance['name'] vm_ref = vm_util.get_vm_ref(self._session, instance) # Attach Volume to VM LOG.debug("Attach_volume: %(connection_info)s, %(instance_name)s, " "%(mountpoint)s", {'connection_info': connection_info, 'instance_name': instance_name, 'mountpoint': mountpoint}, instance=instance) data = connection_info['data'] # Discover iSCSI Target device_name = self._iscsi_discover_target(data)[0] if device_name is None: raise exception.StorageError( reason=_("Unable to find iSCSI Target")) # Get the vmdk file name that the VM is pointing to hardware_devices = self._session._call_method(vim_util, "get_dynamic_property", vm_ref, "VirtualMachine", "config.hardware.device") (vmdk_file_path, adapter_type, disk_type) = vm_util.get_vmdk_path_and_adapter_type(hardware_devices) self.attach_disk_to_vm(vm_ref, instance, adapter_type, 'rdmp', device_name=device_name) LOG.info(_("Mountpoint %(mountpoint)s attached to " "instance %(instance_name)s"), {'mountpoint': mountpoint, 'instance_name': instance_name}, instance=instance)
def _attach_volume_vmdk(self, connection_info, instance): """Attach vmdk volume storage to VM instance.""" vm_ref = vm_util.get_vm_ref(self._session, instance) LOG.debug("_attach_volume_vmdk: %s", connection_info, instance=instance) data = connection_info['data'] volume_ref = self._get_volume_ref(data['volume']) # Get details required for adding disk device such as # adapter_type, disk_type hw_devices = self._session._call_method(vim_util, 'get_dynamic_property', volume_ref, 'VirtualMachine', 'config.hardware.device') (volume_vmdk_path, adapter_type, disk_type) = vm_util.get_vmdk_path_and_adapter_type(hw_devices) # IDE does not support disk hotplug if (instance.vm_state == vm_states.ACTIVE and adapter_type == constants.ADAPTER_TYPE_IDE): msg = _('%s does not support disk hotplug.') % adapter_type raise exception.Invalid(msg) # Attach the disk to virtual machine instance self.attach_disk_to_vm(vm_ref, instance, adapter_type, disk_type, vmdk_path=volume_vmdk_path) # Store the uuid of the volume_device self._update_volume_details(vm_ref, instance, data['volume_id']) LOG.debug("Attached VMDK: %s", connection_info, instance=instance)
def _attach_volume_vmdk(self, connection_info, instance): """Attach vmdk volume storage to VM instance.""" vm_ref = vm_util.get_vm_ref(self._session, instance) LOG.debug("_attach_volume_vmdk: %s", connection_info, instance=instance) data = connection_info['data'] volume_ref = self._get_volume_ref(data['volume']) # Get details required for adding disk device such as # adapter_type, disk_type hw_devices = self._session._call_method(vim_util, 'get_dynamic_property', volume_ref, 'VirtualMachine', 'config.hardware.device') (volume_vmdk_path, adapter_type, disk_type) = vm_util.get_vmdk_path_and_adapter_type(hw_devices) # IDE does not support disk hotplug if (instance.vm_state == vm_states.ACTIVE and adapter_type == constants.ADAPTER_TYPE_IDE): msg = _('%s does not support disk hotplug.') % adapter_type raise exception.Invalid(msg) # Attach the disk to virtual machine instance self.attach_disk_to_vm(vm_ref, instance, adapter_type, disk_type, vmdk_path=volume_vmdk_path) # Store the uuid of the volume_device self._update_volume_details(vm_ref, instance, data['volume_id']) LOG.debug("Attached VMDK: %s", connection_info, instance=instance)
def test_get_vmdk_path_and_adapter_type(self): filename = '[test_datastore] test_file.vmdk' devices = self._vmdk_path_and_adapter_type_devices(filename) vmdk_info = vm_util.get_vmdk_path_and_adapter_type(devices) adapter_type = vmdk_info[1] self.assertEqual('lsiLogicsas', adapter_type) self.assertEqual(vmdk_info[0], filename)
def _attach_volume_vmdk(self, connection_info, instance, mountpoint): """Attach vmdk volume storage to VM instance.""" instance_name = instance['name'] vm_ref = vm_util.get_vm_ref(self._session, instance) data = connection_info['data'] # Get volume details from volume ref volume_ref = self._get_volume_ref(data['volume']) volume_device = self._get_vmdk_base_volume_device(volume_ref) volume_vmdk_path = volume_device.backing.fileName # Get details required for adding disk device such as # adapter_type, disk_type hw_devices = self._session._call_method(vim_util, 'get_dynamic_property', vm_ref, 'VirtualMachine', 'config.hardware.device') (vmdk_file_path, adapter_type, disk_type) = vm_util.get_vmdk_path_and_adapter_type(hw_devices) # Attach the disk to virtual machine instance self.attach_disk_to_vm(vm_ref, instance, adapter_type, disk_type, vmdk_path=volume_vmdk_path) # Store the uuid of the volume_device self._update_volume_details(vm_ref, instance, data['volume_id']) LOG.info(_("Mountpoint %(mountpoint)s attached to " "instance %(instance_name)s"), {'mountpoint': mountpoint, 'instance_name': instance_name}, instance=instance)
def _attach_volume_iscsi(self, connection_info, instance, mountpoint): """Attach iscsi volume storage to VM instance.""" instance_name = instance['name'] vm_ref = vm_util.get_vm_ref(self._session, instance) # Attach Volume to VM LOG.debug("Attach_volume: %(connection_info)s, %(instance_name)s, " "%(mountpoint)s", {'connection_info': connection_info, 'instance_name': instance_name, 'mountpoint': mountpoint}, instance=instance) data = connection_info['data'] # Discover iSCSI Target device_name = self._iscsi_discover_target(data)[0] if device_name is None: raise exception.StorageError( reason=_("Unable to find iSCSI Target")) # Get the vmdk file name that the VM is pointing to hardware_devices = self._session._call_method(vim_util, "get_dynamic_property", vm_ref, "VirtualMachine", "config.hardware.device") (vmdk_file_path, adapter_type, disk_type) = vm_util.get_vmdk_path_and_adapter_type(hardware_devices) self.attach_disk_to_vm(vm_ref, instance, adapter_type, 'rdmp', device_name=device_name) LOG.info(_("Mountpoint %(mountpoint)s attached to " "instance %(instance_name)s"), {'mountpoint': mountpoint, 'instance_name': instance_name}, instance=instance)
def _consolidate_vmdk_volume(self, instance, vm_ref, device, volume_ref): """Consolidate volume backing VMDK files if needed. The volume's VMDK file attached to an instance can be moved by SDRS if enabled on the cluster. By this the VMDK files can get copied onto another datastore and the copy on this new location will be the latest version of the VMDK file. So at the time of detach, we need to consolidate the current backing VMDK file with the VMDK file in the new location. We need to ensure that the VMDK chain (snapshots) remains intact during the consolidation. SDRS retains the chain when it copies VMDK files over, so for consolidation we relocate the backing with move option as moveAllDiskBackingsAndAllowSharing and then delete the older version of the VMDK file attaching the new version VMDK file. In the case of a volume boot the we need to ensure that the volume is on the datastore of the instance. """ original_device = self._get_vmdk_base_volume_device(volume_ref) original_device_path = original_device.backing.fileName current_device_path = device.backing.fileName if original_device_path == current_device_path: # The volume is not moved from its original location. # No consolidation is required. LOG.debug("The volume has not been displaced from " "its original location: %s. No consolidation " "needed.", current_device_path) return # The volume has been moved from its original location. # Need to consolidate the VMDK files. LOG.info(_("The volume's backing has been relocated to %s. Need to " "consolidate backing disk file."), current_device_path) # Pick the resource pool on which the instance resides. # Move the volume to the datastore where the new VMDK file is present. res_pool = self._get_res_pool_of_vm(vm_ref) datastore = device.backing.datastore self._relocate_vmdk_volume(volume_ref, res_pool, datastore) # Delete the original disk from the volume_ref self.detach_disk_from_vm(volume_ref, instance, original_device, destroy_disk=True) # Attach the current disk to the volume_ref # Get details required for adding disk device such as # adapter_type, disk_type hw_devices = self._session._call_method(vim_util, 'get_dynamic_property', volume_ref, 'VirtualMachine', 'config.hardware.device') (vmdk_file_path, adapter_type, disk_type) = vm_util.get_vmdk_path_and_adapter_type(hw_devices) # Attach the current volume to the volume_ref self.attach_disk_to_vm(volume_ref, instance, adapter_type, disk_type, vmdk_path=current_device_path)
def test_get_vmdk_path_and_adapter_type(self): filename = "[test_datastore] test_file.vmdk" devices = self._vmdk_path_and_adapter_type_devices(filename) vmdk_info = vm_util.get_vmdk_path_and_adapter_type(devices) adapter_type = vmdk_info[1] self.assertEqual("lsiLogicsas", adapter_type) self.assertEqual(vmdk_info[0], filename)
def _consolidate_vmdk_volume(self, instance, vm_ref, device, volume_ref): """Consolidate volume backing VMDK files if needed. The volume's VMDK file attached to an instance can be moved by SDRS if enabled on the cluster. By this the VMDK files can get copied onto another datastore and the copy on this new location will be the latest version of the VMDK file. So at the time of detach, we need to consolidate the current backing VMDK file with the VMDK file in the new location. We need to ensure that the VMDK chain (snapshots) remains intact during the consolidation. SDRS retains the chain when it copies VMDK files over, so for consolidation we relocate the backing with move option as moveAllDiskBackingsAndAllowSharing and then delete the older version of the VMDK file attaching the new version VMDK file. In the case of a volume boot the we need to ensure that the volume is on the datastore of the instance. """ original_device = self._get_vmdk_base_volume_device(volume_ref) original_device_path = original_device.backing.fileName current_device_path = device.backing.fileName if original_device_path == current_device_path: # The volume is not moved from its original location. # No consolidation is required. LOG.debug("The volume has not been displaced from " "its original location: %s. No consolidation " "needed.", current_device_path) return # The volume has been moved from its original location. # Need to consolidate the VMDK files. LOG.info(_("The volume's backing has been relocated to %s. Need to " "consolidate backing disk file."), current_device_path) # Pick the resource pool on which the instance resides. # Move the volume to the datastore where the new VMDK file is present. res_pool = self._get_res_pool_of_vm(vm_ref) datastore = device.backing.datastore self._relocate_vmdk_volume(volume_ref, res_pool, datastore) # Delete the original disk from the volume_ref self.detach_disk_from_vm(volume_ref, instance, original_device, destroy_disk=True) # Attach the current disk to the volume_ref # Get details required for adding disk device such as # adapter_type, disk_type hw_devices = self._session._call_method(vim_util, 'get_dynamic_property', volume_ref, 'VirtualMachine', 'config.hardware.device') (vmdk_file_path, adapter_type, disk_type) = vm_util.get_vmdk_path_and_adapter_type(hw_devices) # Attach the current volume to the volume_ref self.attach_disk_to_vm(volume_ref, instance, adapter_type, disk_type, vmdk_path=current_device_path)
def test_get_vmdk_path_and_adapter_type_with_nomatch(self): n_filename = '[test_datastore] diuu/diuu.vmdk' devices = self._vmdk_path_and_adapter_type_devices(n_filename) vmdk_info = vm_util.get_vmdk_path_and_adapter_type(devices, uuid='uuid') adapter_type = vmdk_info[1] self.assertEqual('lsiLogicsas', adapter_type) self.assertIsNone(vmdk_info[0])
def test_get_vmdk_path_and_adapter_type_with_match(self): n_filename = '[test_datastore] uuid/uuid.vmdk' devices = self._vmdk_path_and_adapter_type_devices(n_filename) vmdk_info = vm_util.get_vmdk_path_and_adapter_type( devices, uuid='uuid') adapter_type = vmdk_info[1] self.assertEqual('lsiLogicsas', adapter_type) self.assertEqual(n_filename, vmdk_info[0])
def attach_volume(self, connection_info, instance, mountpoint): """Attach volume storage to VM instance.""" instance_name = instance['name'] vm_ref = vm_util.get_vm_ref_from_name(self._session, instance_name) if vm_ref is None: raise exception.InstanceNotFound(instance_id=instance_name) # Attach Volume to VM LOG.debug( _("Attach_volume: %(connection_info)s, %(instance_name)s, " "%(mountpoint)s"), { 'connection_info': connection_info, 'instance_name': instance_name, 'mountpoint': mountpoint }) driver_type = connection_info['driver_volume_type'] if driver_type not in ['iscsi']: raise exception.VolumeDriverNotFound(driver_type=driver_type) data = connection_info['data'] mount_unit = volume_util.mountpoint_to_number(mountpoint) # Discover iSCSI Target device_name, uuid = self.discover_st(data) if device_name is None: raise volume_util.StorageError(_("Unable to find iSCSI Target")) # Get the vmdk file name that the VM is pointing to hardware_devices = self._session._call_method( vim_util, "get_dynamic_property", vm_ref, "VirtualMachine", "config.hardware.device") vmdk_file_path, controller_key, adapter_type, disk_type, unit_number \ = vm_util.get_vmdk_path_and_adapter_type(hardware_devices) # Figure out the correct unit number if unit_number < mount_unit: unit_number = mount_unit else: unit_number = unit_number + 1 self.attach_disk_to_vm(vm_ref, instance_name, adapter_type, disk_type="rdmp", controller_key=controller_key, unit_number=unit_number, device_name=device_name) LOG.info( _("Mountpoint %(mountpoint)s attached to " "instance %(instance_name)s"), { 'mountpoint': mountpoint, 'instance_name': instance_name })
def test_get_vmdk_path_and_adapter_type(self): # Test the adapter_type returned for a lsiLogic sas controller controller_key = 1000 filename = '[test_datastore] test_file.vmdk' disk = fake.VirtualDisk() disk.controllerKey = controller_key disk_backing = fake.VirtualDiskFlatVer2BackingInfo() disk_backing.fileName = filename disk.backing = disk_backing controller = fake.VirtualLsiLogicSASController() controller.key = controller_key devices = [disk, controller] vmdk_info = vm_util.get_vmdk_path_and_adapter_type(devices) adapter_type = vmdk_info[2] self.assertEqual('lsiLogicsas', adapter_type)
def _get_vm_and_vmdk_attribs(): # Get the vmdk file name that the VM is pointing to hardware_devices = self._session._call_method(vim_util, "get_dynamic_property", vm_ref, "VirtualMachine", "config.hardware.device") (vmdk_file_path_before_snapshot, controller_key, adapter_type, disk_type, unit_number) = vm_util.get_vmdk_path_and_adapter_type( hardware_devices) datastore_name = vm_util.split_datastore_path( vmdk_file_path_before_snapshot)[0] os_type = self._session._call_method(vim_util, "get_dynamic_property", vm_ref, "VirtualMachine", "summary.config.guestId") return (vmdk_file_path_before_snapshot, adapter_type, disk_type, datastore_name, os_type)
def test_get_vmdk_path_and_adapter_type(self): # Test the adapter_type returned for a lsiLogic sas controller controller_key = 1000 filename = '[test_datastore] test_file.vmdk' disk = fake.VirtualDisk() disk.controllerKey = controller_key disk_backing = fake.VirtualDiskFlatVer2BackingInfo() disk_backing.fileName = filename disk.backing = disk_backing controller = fake.VirtualLsiLogicSASController() controller.key = controller_key devices = [disk, controller] vmdk_info = vm_util.get_vmdk_path_and_adapter_type(devices) adapter_type = vmdk_info[2] self.assertEqual('lsiLogicsas', adapter_type)
def _get_vm_and_vmdk_attribs(): # Get the vmdk file name that the VM is pointing to hardware_devices = self._session._call_method( vim_util, "get_dynamic_property", vm_ref, "VirtualMachine", "config.hardware.device") (vmdk_file_path_before_snapshot, controller_key, adapter_type, disk_type, unit_number ) = vm_util.get_vmdk_path_and_adapter_type(hardware_devices) datastore_name = vm_util.split_datastore_path( vmdk_file_path_before_snapshot)[0] os_type = self._session._call_method(vim_util, "get_dynamic_property", vm_ref, "VirtualMachine", "summary.config.guestId") return (vmdk_file_path_before_snapshot, adapter_type, disk_type, datastore_name, os_type)
def attach_volume(self, connection_info, instance, mountpoint): """Attach volume storage to VM instance.""" instance_name = instance["name"] vm_ref = vm_util.get_vm_ref_from_name(self._session, instance_name) if vm_ref is None: raise exception.InstanceNotFound(instance_id=instance_name) # Attach Volume to VM LOG.debug( _("Attach_volume: %(connection_info)s, %(instance_name)s, " "%(mountpoint)s"), {"connection_info": connection_info, "instance_name": instance_name, "mountpoint": mountpoint}, ) driver_type = connection_info["driver_volume_type"] if driver_type not in ["iscsi"]: raise exception.VolumeDriverNotFound(driver_type=driver_type) data = connection_info["data"] mount_unit = volume_util.mountpoint_to_number(mountpoint) # Discover iSCSI Target device_name, uuid = self.discover_st(data) if device_name is None: raise volume_util.StorageError(_("Unable to find iSCSI Target")) # Get the vmdk file name that the VM is pointing to hardware_devices = self._session._call_method( vim_util, "get_dynamic_property", vm_ref, "VirtualMachine", "config.hardware.device" ) vmdk_file_path, controller_key, adapter_type, disk_type, unit_number = vm_util.get_vmdk_path_and_adapter_type( hardware_devices ) # Figure out the correct unit number if unit_number < mount_unit: unit_number = mount_unit else: unit_number = unit_number + 1 self.attach_disk_to_vm( vm_ref, instance_name, adapter_type, disk_type="rdmp", controller_key=controller_key, unit_number=unit_number, device_name=device_name, ) LOG.info( _("Mountpoint %(mountpoint)s attached to " "instance %(instance_name)s"), {"mountpoint": mountpoint, "instance_name": instance_name}, )
def _attach_volume_iscsi(self, connection_info, instance, mountpoint): """Attach iscsi volume storage to VM instance.""" instance_name = instance['name'] vm_ref = vm_util.get_vm_ref(self._session, instance) # Attach Volume to VM LOG.debug(_("Attach_volume: %(connection_info)s, %(instance_name)s, " "%(mountpoint)s"), {'connection_info': connection_info, 'instance_name': instance_name, 'mountpoint': mountpoint}) data = connection_info['data'] mount_unit = volume_util.mountpoint_to_number(mountpoint) # Discover iSCSI Target device_name, uuid = self.discover_st(data) if device_name is None: raise volume_util.StorageError(_("Unable to find iSCSI Target")) # Get the vmdk file name that the VM is pointing to hardware_devices = self._session._call_method(vim_util, "get_dynamic_property", vm_ref, "VirtualMachine", "config.hardware.device") vmdk_file_path, controller_key, adapter_type, disk_type, unit_number \ = vm_util.get_vmdk_path_and_adapter_type(hardware_devices) # Figure out the correct unit number if unit_number < mount_unit: unit_number = mount_unit else: unit_number = unit_number + 1 self.attach_disk_to_vm(vm_ref, instance, adapter_type, 'rdmp', controller_key=controller_key, unit_number=unit_number, device_name=device_name) LOG.info(_("Mountpoint %(mountpoint)s attached to " "instance %(instance_name)s"), {'mountpoint': mountpoint, 'instance_name': instance_name})
def _detach_volume_vmdk(self, connection_info, instance): """Detach volume storage to VM instance.""" vm_ref = vm_util.get_vm_ref(self._session, instance) # Detach Volume from VM LOG.debug("_detach_volume_vmdk: %s", connection_info, instance=instance) data = connection_info['data'] volume_ref = self._get_volume_ref(data['volume']) device = self._get_vmdk_backed_disk_device(vm_ref, data) # Get details required for adding disk device such as # adapter_type, disk_type hw_devices = self._session._call_method(vim_util, 'get_dynamic_property', volume_ref, 'VirtualMachine', 'config.hardware.device') (vmdk_file_path, adapter_type, disk_type) = vm_util.get_vmdk_path_and_adapter_type(hw_devices) # IDE does not support disk hotplug if (instance.vm_state == vm_states.ACTIVE and adapter_type == constants.ADAPTER_TYPE_IDE): msg = _('%s does not support disk hotplug.') % adapter_type raise exception.Invalid(msg) self._consolidate_vmdk_volume(instance, vm_ref, device, volume_ref, adapter_type=adapter_type, disk_type=disk_type) self.detach_disk_from_vm(vm_ref, instance, device) LOG.debug("Detached VMDK: %s", connection_info, instance=instance)