def test_place_on_datastore_tag(self): host_config_request = Host.GetConfigRequest() res = self.host_client.get_host_config(host_config_request) self.assertEqual(res.result, GetConfigResultCode.OK) datastores = res.hostConfig.datastores for datastore in datastores: tag = self._type_to_tag(datastore.type) if not tag: continue vm_wrapper = VmWrapper(self.host_client) # Test place disks with only datastore constraint disk = Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, capacity_gb=0) resource_constraints = self._create_constraints([datastore.id], []) vm_wrapper.place(vm_disks=[disk], vm_constraints=resource_constraints) # Test place disks with datastore and datastore tag constraint disk = Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, capacity_gb=0) resource_constraints = self._create_constraints([datastore.id], [tag]) vm_wrapper.place(vm_disks=[disk], vm_constraints=resource_constraints, expect=PlaceResultCode.OK) # Test place disks with the wrong datastore tag for other_tag in self._other_tags(tag): disk = Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, capacity_gb=0) resource_constraints = self._create_constraints([datastore.id], [other_tag]) vm_wrapper.place(vm_disks=[disk], vm_constraints=resource_constraints, expect=PlaceResultCode.NO_SUCH_RESOURCE)
def test_start_image_scanner(self): """ Test image scanner. Make sure the idle images are reported correctly. """ datastore = self._find_configured_datastore_in_host_config() image_id_1 = new_id() dst_image_1, _ = self._create_test_image(image_id_1) image_id_2 = new_id() dst_image_2, _ = self._create_test_image(image_id_2) disk_image_2 = DiskImage(image_id_2, CloneType.COPY_ON_WRITE) disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, image=disk_image_2, capacity_gb=0, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=2, flavor_info=self.DEFAULT_DISK_FLAVOR) ] vm_wrapper = VmWrapper(self.host_client) reservation = vm_wrapper.place_and_reserve(vm_disks=disks).reservation request = vm_wrapper.create_request(res_id=reservation) vm_wrapper.create(request=request) logger.info("Image scan, Vm id: %s" % vm_wrapper.id) # Start image scanner start_scan_request = StartImageScanRequest() start_scan_request.datastore_id = datastore.id start_scan_request.scan_rate = 600 start_scan_request.timeout = 30 start_scan_response = self.host_client.start_image_scan(start_scan_request) self.assertEqual(start_scan_response.result, StartImageOperationResultCode.OK) self._get_and_check_inactive_images(datastore.id, image_id_1, True) get_inactive_images_response = self._get_and_check_inactive_images(datastore.id, image_id_2, False) # Start image sweeper start_sweep_request = StartImageSweepRequest() start_sweep_request.datastore_id = datastore.id start_sweep_request.image_descs = get_inactive_images_response.image_descs start_sweep_request.sweep_rate = 600 start_sweep_request.timeout = 30 start_sweep_request.grace_period = 0 start_sweep_response = self.host_client.start_image_sweep(start_sweep_request) self.assertEqual(start_sweep_response.result, StartImageOperationResultCode.OK) self._get_and_check_deleted_images(datastore.id, image_id_1, True) # cleanup vm_wrapper.delete() self._delete_image(dst_image_1, DeleteDirectoryResultCode.DIRECTORY_NOT_FOUND) self._delete_image(dst_image_2)
def test_disk_uuids(self): # Create a vm without a root disk and blank disk then attach another # persistent disk. Then verify that only the uuids of the # ephemeral and persistent disks are updated to match their cloud ids. vm_wrapper = VmWrapper(self.host_client) disk_id_root = new_id() disk_id_ephemeral = new_id() disk_id_persistent = new_id() image = DiskImage("ttylinux", CloneType.COPY_ON_WRITE) disks = [ Disk(disk_id_root, self.DEFAULT_DISK_FLAVOR.name, False, True, image=image, capacity_gb=0, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(disk_id_ephemeral, self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), ] reservation = vm_wrapper.place_and_reserve(vm_disks=disks).reservation request = vm_wrapper.create_request(res_id=reservation) vm_id = vm_wrapper.create(request=request).vm.id # create one persistent disk disk = Disk(disk_id_persistent, self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR) reservation = vm_wrapper.place_and_reserve(disk=disk).reservation vm_wrapper.create_disk(disk, reservation, validate=True) vm_wrapper.attach_disks(vm_id, [disk_id_persistent]) vim_vm = self.vim_client.get_vm(vm_id) disk_uuid_map = dict([(dev.backing.uuid, dev.backing.fileName) for dev in vim_vm.config.hardware.device if isinstance(dev, vim.vm.device.VirtualDisk)]) # Assert that the UUID assigned to the ephemeral and persistent disks # matches their ids for disk_id in (disk_id_ephemeral, disk_id_persistent): self.assertTrue(disk_id in disk_uuid_map and disk_id in disk_uuid_map[disk_id]) # Assert that no such assignment is done for link-clone root disk. self.assertFalse(disk_id_root in disk_uuid_map) vm_wrapper.detach_disks(vm_id, [disk_id_persistent]) vm_wrapper.delete(request=vm_wrapper.delete_request()) vm_wrapper.delete_disks([disk_id_persistent], validate=True)
def test_force_delete_vm(self): vm_wrapper = VmWrapper(self.host_client) # create a vm without disk reservation = vm_wrapper.place_and_reserve().reservation request = vm_wrapper.create_request(res_id=reservation) vm_id = vm_wrapper.create(request=request).vm.id # create 2 disks disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR) ] for disk in disks: reservation = vm_wrapper.place_and_reserve(disk=disk).reservation vm_wrapper.create_disk(disk, reservation, validate=True) # attach disks disk_ids = [disk.id for disk in disks] vm_wrapper.attach_disks(vm_id, disk_ids) # delete vm fails without force vm_wrapper.delete(request=vm_wrapper.delete_request(), expect=Host.DeleteVmResultCode.OPERATION_NOT_ALLOWED) # delete vm with force succeeds vm_wrapper.delete(request=vm_wrapper.delete_request(force=True)) for disk_id in disk_ids: vm_wrapper.get_disk(disk_id, expect_found=False)
def test_detach_cdrom(self): """ Tests detach iso from VM. Verify Detaching a real iso from a VM. """ if not self._remote_iso_file: raise SkipTest("ISO file on server not provided") si = self.get_service_instance() file_manager = si.RetrieveContent().fileManager iso_path = self._generate_new_iso_ds_path() self._make_new_iso_copy(file_manager, iso_path) iso_path_2 = self._generate_new_iso_ds_path() self._make_new_iso_copy(file_manager, iso_path_2) vm_wrapper = VmWrapper(self.host_client) reservation = vm_wrapper.place_and_reserve().reservation request = vm_wrapper.create_request(res_id=reservation) vm_id = vm_wrapper.create(request=request).vm.id vm_wrapper.attach_iso(vm_id, iso_path, Host.AttachISOResultCode.OK) vm_wrapper.detach_iso(vm_id, True, Host.DetachISOResultCode.OK) vm_wrapper.attach_iso(vm_id, iso_path_2, Host.AttachISOResultCode.OK) # verify detach works when powered on vm_wrapper.power(Host.PowerVmOp.ON) vm_wrapper.detach_iso(vm_id, True, Host.DetachISOResultCode.OK) vm_wrapper.power(Host.PowerVmOp.OFF) vm_wrapper.delete(request=vm_wrapper.delete_request())
def test_detach_cdrom_failure(self): """ Tests failures of detach iso from VM. """ vm_wrapper = VmWrapper(self.host_client) reservation = vm_wrapper.place_and_reserve().reservation request = vm_wrapper.create_request(res_id=reservation) vm_id = vm_wrapper.create(request=request).vm.id # no prior attach of iso vm_wrapper.detach_iso(vm_id, True, Host.DetachISOResultCode.ISO_NOT_ATTACHED) # nonexistent VM id fake_id = str(uuid.uuid4()) vm_wrapper.detach_iso(fake_id, True, Host.DetachISOResultCode.VM_NOT_FOUND) # Attaching nonexistent iso path still should succeed as long # as a valid datastore path format is used random = str(uuid.uuid4()) vm_wrapper.attach_iso(vm_id, "[] /tmp/%s_nonexistent_.iso" % random, Host.AttachISOResultCode.OK) # Not supporting detach without delete yet. vm_wrapper.detach_iso(vm_id, False, Host.DetachISOResultCode.SYSTEM_ERROR) # But detach a non-exist iso should work. vm_wrapper.detach_iso(vm_id, True, Host.DetachISOResultCode.OK) vm_wrapper.delete(request=vm_wrapper.delete_request())
def test_attach_cdrom(self): """ Tests attach iso code path. 1. Attach an iso to a non existent VM. Check correct error 2. Attach a non existent iso file to a valid VM. Check correct error 3. Attach a real iso if specified to a VM. Verify it succeeds. Test should pass the iso path as [datastore_name]/path/to/iso.iso """ if not self._remote_iso_file: raise SkipTest("ISO file on server not provided") si = self.get_service_instance() file_manager = si.RetrieveContent().fileManager iso_path = self._generate_new_iso_ds_path() iso_path_2 = self._generate_new_iso_ds_path() vm_wrapper = VmWrapper(self.host_client) image = DiskImage("ttylinux", CloneType.COPY_ON_WRITE) disks = [ Disk(new_id(), "default", False, True, image=image, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), ] # Create disk and VM. reservation = vm_wrapper.place_and_reserve(vm_disks=disks).reservation request = vm_wrapper.create_request(res_id=reservation) vm_id = vm_wrapper.create(request=request).vm.id # Verify the result when the VM is not found. fake_id = str(uuid.uuid4()) vm_wrapper.attach_iso(fake_id, "/tmp/foo.iso", Host.AttachISOResultCode.VM_NOT_FOUND) # Verify the result when the the iso doesn't exist. vm_wrapper.attach_iso(vm_id, "/tmp/foo.iso", Host.AttachISOResultCode.SYSTEM_ERROR) self._make_new_iso_copy(file_manager, iso_path) self._make_new_iso_copy(file_manager, iso_path_2) # Doing enough attaches will indirectly verify that we do not grow the # device list on reattach. for i in xrange(3): # verify attach works vm_wrapper.attach_iso(vm_id, iso_path) # verify re-attach to another iso works vm_wrapper.attach_iso(vm_id, iso_path_2) vm_wrapper.power(Host.PowerVmOp.ON) # Verify reattach fails when vm is powered on. vm_wrapper.attach_iso(vm_id, iso_path, Host.AttachISOResultCode.ISO_ATTACHED_ERROR) vm_wrapper.power(Host.PowerVmOp.OFF) vm_wrapper.detach_iso(vm_id, True) vm_wrapper.attach_iso(vm_id, iso_path) vm_wrapper.detach_iso(vm_id, True) self.clear()
def test_create_image_from_vm(self): """ Integration test for creating an image from a VM """ img_id = "test-new-im-from-vm-%s" % new_id() tmp_img_id = "-tmp-" + img_id tmp_image, ds = self._create_test_image(tmp_img_id) tmp_image_path = datastore_path(ds.id, "image_" + tmp_img_id) src_vmdk = vmdk_path(ds.id, tmp_img_id, IMAGE_FOLDER_NAME_PREFIX) vm_wrapper = VmWrapper(self.host_client) try: self._manage_disk( vim.VirtualDiskManager.DeleteVirtualDisk_Task, name=src_vmdk) except: logger.error( "Error deleting vmdk when setting up tmp image %s" % src_vmdk, exc_info=True) raise dst_image = Image(img_id, ds) image = DiskImage("ttylinux", CloneType.COPY_ON_WRITE) disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, image=image, capacity_gb=0, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=2, flavor_info=self.DEFAULT_DISK_FLAVOR) ] reservation = vm_wrapper.place_and_reserve(vm_disks=disks).reservation request = vm_wrapper.create_request(res_id=reservation) vm_wrapper.create(request=request) # VM in wrong state vm_wrapper.power(Host.PowerVmOp.ON, Host.PowerVmOpResultCode.OK) time.sleep(10) vm_wrapper.create_image_from_vm( image_id=img_id, datastore=ds.id, tmp_image_path=tmp_image_path, expect=Host.CreateImageFromVmResultCode.INVALID_VM_POWER_STATE) vm_wrapper.power(Host.PowerVmOp.OFF, Host.PowerVmOpResultCode.OK) time.sleep(10) # Happy case vm_wrapper.create_image_from_vm( image_id=img_id, datastore=ds.id, tmp_image_path=tmp_image_path, expect=Host.CreateImageFromVmResultCode.OK) request = Host.GetImagesRequest(ds.id) response = self.host_client.get_images(request) assert_that(response.result, is_(GetImagesResultCode.OK)) assert_that(response.image_ids, has_item(img_id)) # Issue another create call and it should fail as the source doesn't # exist. req = FinalizeImageRequest(image_id=img_id, datastore=ds.id, tmp_image_path=tmp_image_path) response = self.host_client.finalize_image(req) self.assertEqual(response.result, FinalizeImageResultCode.IMAGE_NOT_FOUND) # Verify that we fail if the destination already exists. tmp_image, ds = self._create_test_image(tmp_img_id) vm_wrapper.create_image_from_vm( image_id=tmp_img_id, datastore=ds.id, tmp_image_path=tmp_image_path, expect=Host.CreateImageFromVmResultCode.IMAGE_ALREADY_EXIST) vm_wrapper.delete() # VM to create image from is gone. vm_wrapper.create_image_from_vm( image_id=img_id, datastore=ds.id, tmp_image_path=tmp_image_path, expect=Host.CreateImageFromVmResultCode.VM_NOT_FOUND) # Create a VM using the new image created vm_wrapper2 = VmWrapper(self.host_client) image = DiskImage(img_id, CloneType.COPY_ON_WRITE) disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, image=image, capacity_gb=0, flavor_info=self.DEFAULT_DISK_FLAVOR), ] reservation = vm_wrapper2.place_and_reserve(vm_disks=disks).reservation request = vm_wrapper2.create_request(res_id=reservation) vm_wrapper2.create(request=request) vm_wrapper2.power(Host.PowerVmOp.ON, Host.PowerVmOpResultCode.OK) vm_wrapper2.power(Host.PowerVmOp.OFF, Host.PowerVmOpResultCode.OK) vm_wrapper2.delete() # cleanup self._delete_image(dst_image)
def test_start_image_scanner(self): """ Test image scanner. Make sure the idle images are reported correctly. """ datastore = self._find_configured_datastore_in_host_config() image_id_1 = new_id() dst_image_1, _ = self._create_test_image(image_id_1) image_id_2 = new_id() dst_image_2, _ = self._create_test_image(image_id_2) disk_image_2 = DiskImage(image_id_2, CloneType.COPY_ON_WRITE) disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, image=disk_image_2, capacity_gb=0, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=2, flavor_info=self.DEFAULT_DISK_FLAVOR) ] vm_wrapper = VmWrapper(self.host_client) reservation = vm_wrapper.place_and_reserve(vm_disks=disks).reservation request = vm_wrapper.create_request(res_id=reservation) vm_wrapper.create(request=request) logger.info("Image scan, Vm id: %s" % vm_wrapper.id) # Start image scanner start_scan_request = StartImageScanRequest() start_scan_request.datastore_id = datastore.id start_scan_request.scan_rate = 600 start_scan_request.timeout = 30 start_scan_response = self.host_client.start_image_scan( start_scan_request) self.assertEqual(start_scan_response.result, StartImageOperationResultCode.OK) self._get_and_check_inactive_images(datastore.id, image_id_1, True) get_inactive_images_response = self._get_and_check_inactive_images( datastore.id, image_id_2, False) # Start image sweeper start_sweep_request = StartImageSweepRequest() start_sweep_request.datastore_id = datastore.id start_sweep_request.image_descs = get_inactive_images_response.image_descs start_sweep_request.sweep_rate = 600 start_sweep_request.timeout = 30 start_sweep_request.grace_period = 0 start_sweep_response = self.host_client.start_image_sweep( start_sweep_request) self.assertEqual(start_sweep_response.result, StartImageOperationResultCode.OK) self._get_and_check_deleted_images(datastore.id, image_id_1, True) # cleanup vm_wrapper.delete() self._delete_image(dst_image_1, DeleteDirectoryResultCode.DIRECTORY_NOT_FOUND) self._delete_image(dst_image_2)
def test_create_image_from_vm(self): """ Integration test for creating an image from a VM """ img_id = "test-new-im-from-vm-%s" % new_id() tmp_img_id = "-tmp-" + img_id tmp_image, ds = self._create_test_image(tmp_img_id) tmp_image_path = datastore_path(ds.id, "image_" + tmp_img_id) src_vmdk = vmdk_path(ds.id, tmp_img_id, IMAGE_FOLDER_NAME_PREFIX) vm_wrapper = VmWrapper(self.host_client) try: self._manage_disk(vim.VirtualDiskManager.DeleteVirtualDisk_Task, name=src_vmdk) except: logger.error("Error deleting vmdk when setting up tmp image %s" % src_vmdk, exc_info=True) raise dst_image = Image(img_id, ds) image = DiskImage("ttylinux", CloneType.COPY_ON_WRITE) disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, image=image, capacity_gb=0, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=2, flavor_info=self.DEFAULT_DISK_FLAVOR) ] reservation = vm_wrapper.place_and_reserve(vm_disks=disks).reservation request = vm_wrapper.create_request(res_id=reservation) vm_wrapper.create(request=request) # VM in wrong state vm_wrapper.power(Host.PowerVmOp.ON, Host.PowerVmOpResultCode.OK) time.sleep(10) vm_wrapper.create_image_from_vm( image_id=img_id, datastore=ds.id, tmp_image_path=tmp_image_path, expect=Host.CreateImageFromVmResultCode.INVALID_VM_POWER_STATE) vm_wrapper.power(Host.PowerVmOp.OFF, Host.PowerVmOpResultCode.OK) time.sleep(10) # Happy case vm_wrapper.create_image_from_vm( image_id=img_id, datastore=ds.id, tmp_image_path=tmp_image_path, expect=Host.CreateImageFromVmResultCode.OK) request = Host.GetImagesRequest(ds.id) response = self.host_client.get_images(request) assert_that(response.result, is_(GetImagesResultCode.OK)) assert_that(response.image_ids, has_item(img_id)) # Issue another create call and it should fail as the source doesn't # exist. req = FinalizeImageRequest(image_id=img_id, datastore=ds.id, tmp_image_path=tmp_image_path) response = self.host_client.finalize_image(req) self.assertEqual(response.result, FinalizeImageResultCode.IMAGE_NOT_FOUND) # Verify that we fail if the destination already exists. tmp_image, ds = self._create_test_image(tmp_img_id) vm_wrapper.create_image_from_vm( image_id=tmp_img_id, datastore=ds.id, tmp_image_path=tmp_image_path, expect=Host.CreateImageFromVmResultCode.IMAGE_ALREADY_EXIST) vm_wrapper.delete() # VM to create image from is gone. vm_wrapper.create_image_from_vm( image_id=img_id, datastore=ds.id, tmp_image_path=tmp_image_path, expect=Host.CreateImageFromVmResultCode.VM_NOT_FOUND) # Create a VM using the new image created vm_wrapper2 = VmWrapper(self.host_client) image = DiskImage(img_id, CloneType.COPY_ON_WRITE) disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, image=image, capacity_gb=0, flavor_info=self.DEFAULT_DISK_FLAVOR), ] reservation = vm_wrapper2.place_and_reserve(vm_disks=disks).reservation request = vm_wrapper2.create_request(res_id=reservation) vm_wrapper2.create(request=request) vm_wrapper2.power(Host.PowerVmOp.ON, Host.PowerVmOpResultCode.OK) vm_wrapper2.power(Host.PowerVmOp.OFF, Host.PowerVmOpResultCode.OK) vm_wrapper2.delete() # cleanup self._delete_image(dst_image)