Esempio n. 1
0
def copy_stream_optimized_disk(
        context, timeout_secs, write_handle, **kwargs):
    """Copy virtual disk from VMware server to the given write handle.

    :param context: context
    :param timeout_secs: time in seconds to wait for the copy to complete
    :param write_handle: copy destination
    :param kwargs: keyword arguments to configure the source
                   VMDK read handle
    :raises: VimException, VimFaultException, VimAttributeException,
             VimSessionOverLoadException, VimConnectionException,
             ImageTransferException, ValueError
    """
    vmdk_file_path = kwargs.get('vmdk_file_path')
    LOG.debug("Copying virtual disk: %(vmdk_path)s to %(dest)s.",
              {'vmdk_path': vmdk_file_path,
               'dest': write_handle.name})
    file_size = kwargs.get('vmdk_size')
    read_handle = rw_handles.VmdkReadHandle(kwargs.get('session'),
                                            kwargs.get('host'),
                                            kwargs.get('port'),
                                            kwargs.get('vm'),
                                            kwargs.get('vmdk_file_path'),
                                            file_size)

    updater = loopingcall.FixedIntervalLoopingCall(read_handle.update_progress)
    try:
        updater.start(interval=NFC_LEASE_UPDATE_PERIOD)
        _start_transfer(read_handle, write_handle, timeout_secs)
    finally:
        updater.stop()
    LOG.debug("Downloaded virtual disk: %s.", vmdk_file_path)
Esempio n. 2
0
def _start_transfer(read_handle, write_handle, timeout_secs):
    # write_handle could be an NFC lease, so we need to periodically
    # update its progress
    update_cb = getattr(write_handle, 'update_progress', lambda: None)
    updater = loopingcall.FixedIntervalLoopingCall(update_cb)
    timer = timeout.Timeout(timeout_secs)
    try:
        updater.start(interval=NFC_LEASE_UPDATE_PERIOD)
        while True:
            data = read_handle.read(CHUNK_SIZE)
            if not data:
                break
            write_handle.write(data)
    except timeout.Timeout as excep:
        msg = (_('Timeout, read_handle: "%(src)s", write_handle: "%(dest)s"') %
               {'src': read_handle,
                'dest': write_handle})
        LOG.exception(msg)
        raise exceptions.ImageTransferException(msg, excep)
    except Exception as excep:
        msg = (_('Error, read_handle: "%(src)s", write_handle: "%(dest)s"') %
               {'src': read_handle,
                'dest': write_handle})
        LOG.exception(msg)
        raise exceptions.ImageTransferException(msg, excep)
    finally:
        timer.cancel()
        updater.stop()
        read_handle.close()
        write_handle.close()
Esempio n. 3
0
def upload_image(context, timeout_secs, image_service, image_id, owner_id,
                 **kwargs):
    """Upload the VM's disk file to image service.

    :param context: image service write context
    :param timeout_secs: time in seconds to wait for the upload to complete
    :param image_service: image service handle
    :param image_id: upload destination image ID
    :param kwargs: keyword arguments to configure the source
                   VMDK read handle
    :raises: VimException, VimFaultException, VimAttributeException,
             VimSessionOverLoadException, VimConnectionException,
             ImageTransferException, ValueError
    """

    LOG.debug("Uploading to image: %s.", image_id)
    file_size = kwargs.get('vmdk_size')
    read_handle = rw_handles.VmdkReadHandle(kwargs.get('session'),
                                            kwargs.get('host'),
                                            kwargs.get('port'),
                                            kwargs.get('vm'),
                                            kwargs.get('vmdk_file_path'),
                                            file_size)

    # TODO(vbala) Remove this after we delete the keyword argument 'is_public'
    # from all client code.
    if 'is_public' in kwargs:
        LOG.debug("Ignoring keyword argument 'is_public'.")

    if 'image_version' in kwargs:
        LOG.warning("The keyword argument 'image_version' is deprecated "
                    "and will be ignored in the next release.")

    image_ver = six.text_type(kwargs.get('image_version'))
    image_metadata = {
        'disk_format': 'vmdk',
        'name': kwargs.get('image_name'),
        'properties': {
            'vmware_image_version': image_ver,
            'vmware_disktype': 'streamOptimized',
            'owner_id': owner_id
        }
    }

    updater = loopingcall.FixedIntervalLoopingCall(read_handle.update_progress)
    store_id = kwargs.get('store_id')
    try:
        updater.start(interval=NFC_LEASE_UPDATE_PERIOD)
        image_service.update(context,
                             image_id,
                             image_metadata,
                             data=read_handle,
                             store_id=store_id)
    finally:
        updater.stop()
        read_handle.close()
    LOG.debug("Uploaded image: %s.", image_id)
Esempio n. 4
0
def upload_image(context, timeout_secs, image_service, image_id, owner_id,
                 **kwargs):
    """Upload the VM's disk file to image service.

    :param context: image service write context
    :param timeout_secs: time in seconds to wait for the upload to complete
    :param image_service: image service handle
    :param image_id: upload destination image ID
    :param kwargs: keyword arguments to configure the source
                   VMDK read handle
    :raises: VimException, VimFaultException, VimAttributeException,
             VimSessionOverLoadException, VimConnectionException,
             ImageTransferException, ValueError
    """

    LOG.debug("Uploading to image: %s.", image_id)
    file_size = kwargs.get('vmdk_size')
    read_handle = rw_handles.VmdkReadHandle(kwargs.get('session'),
                                            kwargs.get('host'),
                                            kwargs.get('port'),
                                            kwargs.get('vm'),
                                            kwargs.get('vmdk_file_path'),
                                            file_size)

    # TODO(vbala) Remove this after we delete the keyword argument 'is_public'
    # from all client code.
    if 'is_public' in kwargs:
        LOG.debug("Ignoring keyword argument 'is_public'.")

    # Set the image properties. It is important to set the 'size' to 0.
    # Otherwise, the image service client will use the VM's disk capacity
    # which will not be the image size after upload, since it is converted
    # to a stream-optimized sparse disk.
    image_metadata = {
        'disk_format': 'vmdk',
        'name': kwargs.get('image_name'),
        'size': 0,
        'properties': {
            'vmware_image_version': kwargs.get('image_version'),
            'vmware_disktype': 'streamOptimized',
            'owner_id': owner_id
        }
    }
    updater = loopingcall.FixedIntervalLoopingCall(read_handle.update_progress)
    try:
        updater.start(interval=NFC_LEASE_UPDATE_PERIOD)
        image_service.update(context,
                             image_id,
                             image_metadata,
                             data=read_handle)
    finally:
        updater.stop()
        read_handle.close()
    LOG.debug("Uploaded image: %s.", image_id)
Esempio n. 5
0
    def wait_for_lease_ready(self, lease):
        """Waits for the given lease to be ready.

        This method return when the lease is ready. In case of any error,
        appropriate exception is raised.

        :param lease: lease to be checked for
        :raises: VimException, VimFaultException, VimAttributeException,
                 VimSessionOverLoadException, VimConnectionException
        """
        loop = loopingcall.FixedIntervalLoopingCall(self._poll_lease, lease)
        evt = loop.start(self._task_poll_interval)
        LOG.debug("Waiting for the lease: %s to be ready.", lease)
        evt.wait()
Esempio n. 6
0
    def wait_for_task(self, task):
        """Waits for the given task to complete and returns the result.

        The task is polled until it is done. The method returns the task
        information upon successful completion. In case of any error,
        appropriate exception is raised.

        :param task: managed object reference of the task
        :returns: task info upon successful completion of the task
        :raises: VimException, VimFaultException, VimAttributeException,
                 VimSessionOverLoadException, VimConnectionException
        """
        loop = loopingcall.FixedIntervalLoopingCall(self._poll_task, task)
        evt = loop.start(self._task_poll_interval)
        LOG.debug("Waiting for the task: %s to complete.", task)
        return evt.wait()
Esempio n. 7
0
def _create_progress_updater(handle):
    if isinstance(handle, rw_handles.VmdkHandle):
        updater = loopingcall.FixedIntervalLoopingCall(handle.update_progress)
        updater.start(interval=NFC_LEASE_UPDATE_PERIOD)
        return updater