Example #1
0
    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 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
Example #6
0
    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)