コード例 #1
0
    def receive_image(self, image_id, datastore_id, imported_vm_name, metadata, manifest):
        """ Creates an image using the data from the imported vm.

        This is run at the destination host end of the host-to-host
        image transfer.
        """

        vm = self._vim_client.get_vm_obj_in_cache(imported_vm_name)
        vmx_os_path = datastore_to_os_path(vm.config.files.vmPathName)
        vm_dir = os.path.dirname(vmx_os_path)

        vm.Unregister()
        if self.check_image_dir(image_id, datastore_id):
            self._logger.info("Image %s on datastore %s already exists" % (image_id, datastore_id))
            raise DiskAlreadyExistException()
        self._move_image(image_id, datastore_id, vm_dir)

        # Save raw manifest
        manifest_path = os_image_manifest_path(datastore_id, image_id)
        with open(manifest_path, "w") as f:
            f.write(manifest)

        # Save raw metadata
        metadata_path = os_metadata_path(datastore_id, image_id, IMAGE_FOLDER_NAME)
        with open(metadata_path, "w") as f:
            f.write(metadata)

        self._create_image_timestamp_file_from_ids(datastore_id, image_id)
コード例 #2
0
    def _create_tmp_image(self, source_datastore, source_id, dest_datastore, dest_id):
        """ Copy an image into a temp location.
            1. Lock a tmp image destination file with an exclusive lock. This
            is to prevent the GC thread from garbage collecting directories
            that are actively being used.
            The temp directory name contains a random UUID to prevent
            collisions with concurrent copies
            2. Create the temp directory.
            3. Copy the metadata file over.
            4. Copy the vmdk over.

            @return the tmp image directory on success.
        """
        source = vmdk_path(source_datastore, source_id, IMAGE_FOLDER_NAME)
        temp_dest = tmp_image_path(dest_datastore, dest_id)
        ds_type = self._get_datastore_type(dest_datastore)
        tmp_image_dir_path = os.path.dirname(datastore_to_os_path(temp_dest))
        # Try grabbing the lock on the temp directory if it fails
        # (very unlikely) someone else is copying an image just retry
        # later.
        with FileBackedLock(tmp_image_dir_path, ds_type):
            source_meta = os_metadata_path(source_datastore, source_id, IMAGE_FOLDER_NAME)
            # Create the temp directory
            mkdir_p(tmp_image_dir_path)

            # Copy the metadata file if it exists.
            if os.path.exists(source_meta):
                try:
                    dest_meta = os.path.join(tmp_image_dir_path, metadata_filename(dest_id))
                    shutil.copy(source_meta, dest_meta)
                except:
                    self._logger.exception("Failed to copy metadata file %s", source_meta)
                    raise

            # Copy the manifest file if it exists
            source_manifest = os_image_manifest_path(source_datastore, source_id)
            if os.path.exists(source_manifest):
                try:
                    dest_manifest = os.path.join(tmp_image_dir_path, manifest_filename(dest_id))
                    shutil.copy(source_manifest, dest_manifest)
                except:
                    # Swallow it. Not critical.
                    pass

            # Create the timestamp file
            self._create_image_timestamp_file(tmp_image_dir_path)

            _vd_spec = self._prepare_virtual_disk_spec(
                vim.VirtualDiskManager.VirtualDiskType.thin, vim.VirtualDiskManager.VirtualDiskAdapterType.lsiLogic
            )

            self._manage_disk(
                vim.VirtualDiskManager.CopyVirtualDisk_Task, sourceName=source, destName=temp_dest, destSpec=_vd_spec
            )
        return tmp_image_dir_path
コード例 #3
0
    def _read_metadata(self, image_datastore, image_id):
        try:
            # Transfer raw metadata
            metadata_path = os_metadata_path(image_datastore, image_id,
                                             IMAGE_FOLDER_NAME_PREFIX)
            metadata = None
            if os.path.exists(metadata_path):
                with open(metadata_path, 'r') as f:
                    metadata = f.read()

            return metadata
        except:
            self._logger.exception("Failed to read metadata")
            raise
コード例 #4
0
    def _create_tmp_image(self, source_datastore, source_id, dest_datastore,
                          dest_id):
        """ Copy an image into a temp location.
            1. Lock a tmp image destination file with an exclusive lock. This
            is to prevent the GC thread from garbage collecting directories
            that are actively being used.
            The temp directory name contains a random UUID to prevent
            collisions with concurrent copies
            2. Create the temp directory.
            3. Copy the metadata file over.
            4. Copy the vmdk over.

            @return the tmp image directory on success.
        """
        source = vmdk_path(source_datastore, source_id, IMAGE_FOLDER_NAME)
        temp_dest = tmp_image_path(dest_datastore, dest_id)
        ds_type = self._get_datastore_type(dest_datastore)
        tmp_image_dir_path = os.path.dirname(datastore_to_os_path(temp_dest))
        # Try grabbing the lock on the temp directory if it fails
        # (very unlikely) someone else is copying an image just retry
        # later.
        with FileBackedLock(tmp_image_dir_path, ds_type):
            source_meta = os_metadata_path(source_datastore, source_id,
                                           IMAGE_FOLDER_NAME)
            # Create the temp directory
            mkdir_p(tmp_image_dir_path)

            # Copy the metadata file if it exists.
            if os.path.exists(source_meta):
                try:
                    shutil.copy(source_meta, tmp_image_dir_path)
                except:
                    self._logger.exception("Failed to copy metadata file %s",
                                           source_meta)
                    raise

            # Create the timestamp file
            self._create_image_timestamp_file(tmp_image_dir_path)

            _vd_spec = self._prepare_virtual_disk_spec(
                vim.VirtualDiskManager.VirtualDiskType.thin,
                vim.VirtualDiskManager.VirtualDiskAdapterType.lsiLogic)

            self._manage_disk(vim.VirtualDiskManager.CopyVirtualDisk_Task,
                              sourceName=source,
                              destName=temp_dest,
                              destSpec=_vd_spec)
        return tmp_image_dir_path
コード例 #5
0
    def _copy_to_tmp_image(self, source_datastore, source_id, dest_datastore, dest_id):
        """ Copy an image into a temp location.
            1. Lock a tmp image destination file with an exclusive lock. This
            is to prevent the GC thread from garbage collecting directories
            that are actively being used.
            The temp directory name contains a random UUID to prevent
            collisions with concurrent copies
            2. Create the temp directory.
            3. Copy the metadata file over.
            4. Copy the vmdk over.

            @return the tmp image directory on success.
        """
        ds_type = self._get_datastore_type(dest_datastore)
        if ds_type == DatastoreType.VSAN:
            tmp_image_dir = os_datastore_path(dest_datastore,
                                              compond_path_join(IMAGE_FOLDER_NAME_PREFIX, dest_id),
                                              compond_path_join(TMP_IMAGE_FOLDER_NAME_PREFIX, str(uuid.uuid4())))
        else:
            tmp_image_dir = os_datastore_path(dest_datastore,
                                              compond_path_join(TMP_IMAGE_FOLDER_NAME_PREFIX, str(uuid.uuid4())))

        # Create the temp directory
        self._vim_client.make_directory(tmp_image_dir)

        # Copy the metadata file if it exists.
        source_meta = os_metadata_path(source_datastore, source_id, IMAGE_FOLDER_NAME_PREFIX)
        if os.path.exists(source_meta):
            try:
                dest_meta = os.path.join(tmp_image_dir, metadata_filename(dest_id))
                shutil.copy(source_meta, dest_meta)
            except:
                self._logger.exception("Failed to copy metadata file %s", source_meta)
                raise

        # Create the timestamp file
        self._create_image_timestamp_file(tmp_image_dir)

        _vd_spec = self._prepare_virtual_disk_spec(
            vim.VirtualDiskManager.VirtualDiskType.thin,
            vim.VirtualDiskManager.VirtualDiskAdapterType.lsiLogic)

        self._manage_disk(vim.VirtualDiskManager.CopyVirtualDisk_Task,
                          sourceName=vmdk_path(source_datastore, source_id, IMAGE_FOLDER_NAME_PREFIX),
                          destName=os_to_datastore_path(os.path.join(tmp_image_dir, "%s.vmdk" % dest_id)),
                          destSpec=_vd_spec)
        return tmp_image_dir
コード例 #6
0
    def _copy_to_tmp_image(self, source_datastore, source_id, dest_datastore, dest_id):
        """ Copy an image into a temp location.
            1. Lock a tmp image destination file with an exclusive lock. This
            is to prevent the GC thread from garbage collecting directories
            that are actively being used.
            The temp directory name contains a random UUID to prevent
            collisions with concurrent copies
            2. Create the temp directory.
            3. Copy the metadata file over.
            4. Copy the vmdk over.

            @return the tmp image directory on success.
        """
        ds_type = self._get_datastore_type(dest_datastore)
        if ds_type == DatastoreType.VSAN:
            tmp_image_dir = os_datastore_path(dest_datastore,
                                              compond_path_join(IMAGE_FOLDER_NAME_PREFIX, dest_id),
                                              compond_path_join(TMP_IMAGE_FOLDER_NAME_PREFIX, str(uuid.uuid4())))
        else:
            tmp_image_dir = os_datastore_path(dest_datastore,
                                              compond_path_join(TMP_IMAGE_FOLDER_NAME_PREFIX, str(uuid.uuid4())))

        # Create the temp directory
        self._vim_client.make_directory(tmp_image_dir)

        # Copy the metadata file if it exists.
        source_meta = os_metadata_path(source_datastore, source_id, IMAGE_FOLDER_NAME_PREFIX)
        if os.path.exists(source_meta):
            try:
                dest_meta = os.path.join(tmp_image_dir, metadata_filename(dest_id))
                shutil.copy(source_meta, dest_meta)
            except:
                self._logger.exception("Failed to copy metadata file %s", source_meta)
                raise

        # Create the timestamp file
        self._create_image_timestamp_file(tmp_image_dir)

        _vd_spec = self._prepare_virtual_disk_spec(
            vim.VirtualDiskManager.VirtualDiskType.thin,
            vim.VirtualDiskManager.VirtualDiskAdapterType.lsiLogic)

        self._manage_disk(vim.VirtualDiskManager.CopyVirtualDisk_Task,
                          sourceName=vmdk_path(source_datastore, source_id, IMAGE_FOLDER_NAME_PREFIX),
                          destName=os_to_datastore_path(os.path.join(tmp_image_dir, "%s.vmdk" % dest_id)),
                          destSpec=_vd_spec)
        return tmp_image_dir
コード例 #7
0
    def _read_metadata(self, image_datastore, image_id):
        try:
            # Transfer raw manifest
            manifest_path = os_image_manifest_path(image_datastore, image_id)
            with open(manifest_path) as f:
                manifest = f.read()

            # Transfer raw metadata
            metadata_path = os_metadata_path(image_datastore, image_id,
                                             IMAGE_FOLDER_NAME)
            with open(metadata_path, 'r') as f:
                metadata = f.read()

            return manifest, metadata
        except:
            self._logger.exception("Failed to read metadata")
            raise
コード例 #8
0
    def receive_image(self, image_id, datastore_id, imported_vm_name, metadata):
        """ Creates an image using the data from the imported vm.

        This is run at the destination host end of the host-to-host
        image transfer.
        """

        self._vim_client.wait_for_vm_create(imported_vm_name)
        vm = self._vim_client.get_vm_obj_in_cache(imported_vm_name)
        self._logger.warning("receive_image found vm %s, %s" % (imported_vm_name, vm))
        vm_dir = os.path.dirname(datastore_to_os_path(vm.config.files.vmPathName))

        vm.Unregister()

        ds_type = self._get_datastore_type(datastore_id)
        if ds_type == DatastoreType.VSAN:
            # on VSAN datastore, vm_dir is [vsanDatastore] image_[image_id], we only need to
            # rename the vmdk file to [image_id].vmdk
            try:
                with FileBackedLock(vm_dir, ds_type, retry=300, wait_secs=0.01):  # wait lock for 3 seconds
                    if self._check_image_repair(image_id, datastore_id):
                        raise DiskAlreadyExistException("Image already exists")

                self._vim_client.move_file(os.path.join(vm_dir, vmdk_add_suffix(imported_vm_name)),
                                           os.path.join(vm_dir, vmdk_add_suffix(image_id)))
            except:
                self._logger.exception("Move image %s to %s failed" % (image_id, vm_dir))
                self._vim_client.delete_file(vm_dir)
                raise
        else:
            self._move_image(image_id, datastore_id, vm_dir)

        # Save raw metadata
        if metadata:
            metadata_path = os_metadata_path(datastore_id, image_id, IMAGE_FOLDER_NAME_PREFIX)
            with open(metadata_path, 'w') as f:
                f.write(metadata)

        self._create_image_timestamp_file_from_ids(datastore_id, image_id)
コード例 #9
0
    def receive_image(self, image_id, datastore_id, imported_vm_name, metadata):
        """ Creates an image using the data from the imported vm.

        This is run at the destination host end of the host-to-host
        image transfer.
        """

        self._vim_client.wait_for_vm_create(imported_vm_name)
        vm = self._vim_client.get_vm_obj_in_cache(imported_vm_name)
        self._logger.warning("receive_image found vm %s, %s" % (imported_vm_name, vm))
        vm_dir = os.path.dirname(datastore_to_os_path(vm.config.files.vmPathName))

        vm.Unregister()

        ds_type = self._get_datastore_type(datastore_id)
        if ds_type == DatastoreType.VSAN:
            # on VSAN datastore, vm_dir is [vsanDatastore] image_[image_id], we only need to
            # rename the vmdk file to [image_id].vmdk
            try:
                with FileBackedLock(vm_dir, ds_type, retry=300, wait_secs=0.01):  # wait lock for 3 seconds
                    if self._check_image_repair(image_id, datastore_id):
                        raise DiskAlreadyExistException("Image already exists")

                self._vim_client.move_file(os.path.join(vm_dir, vmdk_add_suffix(imported_vm_name)),
                                           os.path.join(vm_dir, vmdk_add_suffix(image_id)))
            except:
                self._logger.exception("Move image %s to %s failed" % (image_id, vm_dir))
                self._vim_client.delete_file(vm_dir)
                raise
        else:
            self._move_image(image_id, datastore_id, vm_dir)

        # Save raw metadata
        if metadata:
            metadata_path = os_metadata_path(datastore_id, image_id, IMAGE_FOLDER_NAME_PREFIX)
            with open(metadata_path, 'w') as f:
                f.write(metadata)

        self._create_image_timestamp_file_from_ids(datastore_id, image_id)
コード例 #10
0
 def get_image_metadata(self, image_id, datastore):
     metadata_path = os_metadata_path(datastore, image_id,
                                      IMAGE_FOLDER_NAME)
     self._logger.info("Loading metadata %s" % metadata_path)
     return self._load_json(metadata_path)
コード例 #11
0
 def get_image_metadata(self, image_id, datastore):
     metadata_path = os_metadata_path(datastore,
                                      image_id,
                                      IMAGE_FOLDER_NAME)
     self._logger.info("Loading metadata %s" % metadata_path)
     return self._load_json(metadata_path)