def init_for_create(self, vm_id, datastore, memory, cpus, metadata=None, env=None): """Initialize VMConfigSpec for creating a new VM. """ vm_path = datastore_path(datastore, compond_path_join(VM_FOLDER_NAME_PREFIX, vm_id)) vm_flags = vim.vm.FlagInfo() vm_flags.diskUuidEnabled = True filled_metadata = {} meta_config = metadata.get("configuration") if metadata else {} if meta_config: # The metadata object contains creation configuration details # that can be augmented by the env map. The only env map entries # honored are the ones whose key is listed in the "parameters" # section of the metadata structure. filled_metadata = meta_config.copy() param_names = [p["name"] for p in metadata.get("parameters", [])] if env: for k, v in env.items(): if k in param_names: filled_metadata[k] = v else: self._logger.warning("Skipped unexpected env: %s" % k) self._cfg_spec = vim.vm.ConfigSpec() self._cfg_spec.name = vm_id self._cfg_spec.guestId = filled_metadata.get('guestOS', 'otherGuest') self._cfg_spec.memoryMB = memory self._cfg_spec.numCPUs = cpus self._cfg_spec.files = vim.vm.FileInfo(vmPathName=vm_path) self._cfg_spec.deviceChange = [] self._cfg_spec.flags = vm_flags self._metadata = filled_metadata
def test_finalize_image(self): """ Integration test for atomic image create """ img_id = "test-create-image" tmp_img_id = "-tmp-" + img_id tmp_image, ds = self._create_test_image(tmp_img_id) tmp_image_path = datastore_path(ds.name, "image_" + tmp_img_id) src_vmdk = vmdk_path(ds.id, tmp_img_id, IMAGE_FOLDER_NAME_PREFIX) dst_vmdk = "%s/%s.vmdk" % (tmp_image_path, img_id) try: self._manage_disk( vim.VirtualDiskManager.MoveVirtualDisk_Task, sourceName=src_vmdk, destName=dst_vmdk, force=True) except: logger.error("Error moving vmdk %s" % src_vmdk, exc_info=True) self._manage_disk( vim.VirtualDiskManager.DeleteVirtualDisk_Task, name=src_vmdk) raise dst_image = Image(img_id, ds) 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.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) 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.DESTINATION_ALREADY_EXIST) # cleanup self._delete_image(dst_image)
def test_finalize_image(self): """ Integration test for atomic image create """ img_id = "test-create-image" tmp_img_id = "-tmp-" + img_id tmp_image, ds = self._create_test_image(tmp_img_id) tmp_image_path = datastore_path(ds.name, "image_" + tmp_img_id) src_vmdk = vmdk_path(ds.id, tmp_img_id, IMAGE_FOLDER_NAME_PREFIX) dst_vmdk = "%s/%s.vmdk" % (tmp_image_path, img_id) try: self._manage_disk(vim.VirtualDiskManager.MoveVirtualDisk_Task, sourceName=src_vmdk, destName=dst_vmdk, force=True) except: logger.error("Error moving vmdk %s" % src_vmdk, exc_info=True) self._manage_disk(vim.VirtualDiskManager.DeleteVirtualDisk_Task, name=src_vmdk) raise dst_image = Image(img_id, ds) 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.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) 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.DESTINATION_ALREADY_EXIST) # cleanup self._delete_image(dst_image)
def send_image_to_host(self, source_image_id, source_datastore, destination_image_id, destination_datastore, destination_host, destination_port): self._logger.info("transfer_image: connecting to remote agent") if self._auth_enabled: remote_agent_client = DirectClient("Host", Host.Client, destination_host, destination_port, 60, certfile=SSL_CERT_FILE, keyfile=SSL_KEY_FILE, capath=CA_PATH, ciphers=SSL_CIPHERS, validate=True) else: remote_agent_client = DirectClient("Host", Host.Client, destination_host, destination_port, 60, validate=False) remote_agent_client.connect() self._logger.info("transfer_image: getting ticket") nfc_ticket = self._get_nfc_ticket(remote_agent_client, destination_datastore) self._logger.info("transfer_image: creating remote image") if destination_image_id is None: destination_image_id = source_image_id upload_folder = self._create_remote_image(remote_agent_client, destination_image_id, destination_datastore) try: source_file_path = datastore_path(source_datastore, compond_path_join(IMAGE_FOLDER_NAME_PREFIX, source_image_id), vmdk_add_suffix(source_image_id)) destination_file_path = os.path.join(upload_folder, vmdk_add_suffix(destination_image_id)) self._logger.info("transfer_image: nfc copy image %s => (%s)%s, sslThumbprint=%s, ticket=%s", source_file_path, destination_host, destination_file_path, nfc_ticket.ssl_thumbprint, nfc_ticket.session_id) self._host_client.nfc_copy(source_file_path, destination_host, destination_file_path, nfc_ticket.ssl_thumbprint, nfc_ticket.session_id) self._logger.info("transfer_image: finalizing remote image") self._finalize_remote_image(remote_agent_client, destination_image_id, destination_datastore, upload_folder) except: self._logger.info("transfer_image: cleaning up failed transfer") self._cleanup_remote_image(remote_agent_client, destination_datastore, upload_folder) raise
def send_image_to_host(self, source_image_id, source_datastore, destination_image_id, destination_datastore, destination_host, destination_port): self._logger.info("transfer_image: connecting to remote agent") if self._auth_enabled: remote_agent_client = DirectClient("Host", Host.Client, destination_host, destination_port, 60, certfile=SSL_CERT_FILE, keyfile=SSL_KEY_FILE, capath=CA_PATH, ciphers=SSL_CIPHERS, validate=True) else: remote_agent_client = DirectClient("Host", Host.Client, destination_host, destination_port, 60, validate=False) remote_agent_client.connect() self._logger.info("transfer_image: getting ticket") nfc_ticket = self._get_nfc_ticket(remote_agent_client, destination_datastore) self._logger.info("transfer_image: creating remote image") if destination_image_id is None: destination_image_id = source_image_id upload_folder = self._create_remote_image(remote_agent_client, destination_image_id, destination_datastore) try: source_file_path = datastore_path( source_datastore, compond_path_join(IMAGE_FOLDER_NAME_PREFIX, source_image_id), vmdk_add_suffix(source_image_id)) destination_file_path = os.path.join( upload_folder, vmdk_add_suffix(destination_image_id)) self._logger.info( "transfer_image: nfc copy image %s => (%s)%s, sslThumbprint=%s, ticket=%s", source_file_path, destination_host, destination_file_path, nfc_ticket.ssl_thumbprint, nfc_ticket.session_id) self._host_client.nfc_copy(source_file_path, destination_host, destination_file_path, nfc_ticket.ssl_thumbprint, nfc_ticket.session_id) self._logger.info("transfer_image: finalizing remote image") self._finalize_remote_image(remote_agent_client, destination_image_id, destination_datastore, upload_folder) except: self._logger.info("transfer_image: cleaning up failed transfer") self._cleanup_remote_image(remote_agent_client, destination_datastore, upload_folder) raise
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 create_vm_spec(self, vm_id, datastore, memoryMB, cpus, metadata, env): vm_path = datastore_path(datastore, compond_path_join(VM_FOLDER_NAME_PREFIX, vm_id)) spec = self._client.CreateVMSpec(vm_id, vm_path, memoryMB, cpus) return AttacheVmConfigSpec(self._client, spec)
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 create_vm_spec(self, vm_id, datastore, memoryMB, cpus, metadata, env): vm_path = datastore_path( datastore, compond_path_join(VM_FOLDER_NAME_PREFIX, vm_id)) spec = self._client.CreateVMSpec(vm_id, vm_path, memoryMB, cpus) return AttacheVmConfigSpec(self._client, spec)