Example #1
0
    def write(self, data):
        """Write data to the file.

        :param data: data to be written
        :raises: VimConnectionException, VimException
        """
        LOG.debug("Writing data to VMDK file with URL = %s.", self._url)

        try:
            self._file_handle.send(data)
            self._bytes_written += len(data)
            LOG.debug(
                "Total %(bytes_written)d bytes written to VMDK file "
                "with URL = %(url)s.", {
                    'bytes_written': self._bytes_written,
                    'url': self._url
                })
        except (socket.error, httplib.NotConnected) as excep:
            excep_msg = _("Connection error occurred while writing data to"
                          " %s.") % self._url
            LOG.exception(excep_msg)
            raise exceptions.VimConnectionException(excep_msg, excep)
        except Exception as excep:
            # TODO(vbala) We need to catch and raise specific exceptions
            # related to connection problems, invalid request and invalid
            # arguments.
            excep_msg = _("Error occurred while writing data to"
                          " %s.") % self._url
            LOG.exception(excep_msg)
            raise exceptions.VimException(excep_msg, excep)
Example #2
0
        def _inner():
            if initial_delay:
                greenthread.sleep(initial_delay)

            try:
                while self._running:
                    start = timeutils.utcnow()
                    self.f(*self.args, **self.kw)
                    end = timeutils.utcnow()
                    if not self._running:
                        break
                    delay = interval - timeutils.delta_seconds(start, end)
                    if delay <= 0:
                        LOG.warn(_('task run outlasted interval by %s sec'),
                                 -delay)
                    greenthread.sleep(delay if delay > 0 else 0)
            except LoopingCallDone as e:
                self.stop()
                done.send(e.retvalue)
            except Exception:
                LOG.exception(_('in fixed duration looping call'))
                done.send_exception(*sys.exc_info())
                return
            else:
                done.send(True)
Example #3
0
    def update_progress(self):
        """Updates progress to lease.

        This call back to the lease is essential to keep the lease alive
        across long running read operations.

        :raises: VimException, VimFaultException, VimAttributeException,
                 VimSessionOverLoadException, VimConnectionException
        """
        percent = int(float(self._bytes_read) / self._vmdk_size * 100)
        LOG.debug(_("Calling VIM API to update read progress of VMDK file"
                    " with URL = %(url)s to %(percent)d%%."),
                  {'url': self._url,
                   'percent': percent})
        try:
            self._session.invoke_api(self._session.vim,
                                     'HttpNfcLeaseProgress',
                                     self._lease,
                                     percent=percent)
            LOG.debug(_("Updated read progress of VMDK file with "
                        "URL = %(url)s to %(percent)d%%."),
                      {'url': self._url,
                       'percent': percent})
        except exceptions.VimException as excep:
            LOG.exception(_("Error occurred while updating the read progress "
                            "of VMDK file with URL = %s."),
                          self._url)
            raise excep
Example #4
0
        def _inner():
            """Task performing the file read-write operation."""
            self._running = True
            while self._running:
                try:
                    data = self._input_file.read(None)
                    if not data:
                        LOG.debug(_("File read-write task is done."))
                        self.stop()
                        self._done.send(True)
                    self._output_file.write(data)

                    # update lease progress if applicable
                    if hasattr(self._input_file, "update_progress"):
                        self._input_file.update_progress()
                    if hasattr(self._output_file, "update_progress"):
                        self._output_file.update_progress()

                    greenthread.sleep(FILE_READ_WRITE_TASK_SLEEP_TIME)
                except Exception as excep:
                    self.stop()
                    excep_msg = _("Error occurred during file read-write "
                                  "task.")
                    LOG.exception(excep_msg)
                    excep = exceptions.ImageTransferException(excep_msg, excep)
                    self._done.send_exception(excep)
Example #5
0
    def read(self, chunk_size):
        """Read a chunk of data from the VMDK file.

        :param chunk_size: size of read chunk
        :returns: the data
        :raises: VimException
        """
        LOG.debug(_("Reading data from VMDK file with URL = %s."), self._url)

        try:
            data = self._file_handle.read(READ_CHUNKSIZE)
            self._bytes_read += len(data)
            LOG.debug(_("Total %(bytes_read)d bytes read from VMDK file "
                        "with URL = %(url)s."),
                      {'bytes_read': self._bytes_read,
                       'url': self._url})
            return data
        except Exception as excep:
            # TODO(vbala) We need to catch and raise specific exceptions
            # related to connection problems, invalid request and invalid
            # arguments.
            excep_msg = _("Error occurred while reading data from"
                          " %s.") % self._url
            LOG.exception(excep_msg)
            raise exceptions.VimException(excep_msg, excep)
Example #6
0
    def _create_connection(self, url, file_size, cookies):
        """Create HTTP connection to write to the file with given URL."""
        LOG.debug(_("Creating HTTP connection to write to file with "
                    "size = %(file_size)d and URL = %(url)s."),
                  {'file_size': file_size,
                   'url': url})
        _urlparse = urlparse.urlparse(url)
        scheme, netloc, path, params, query, fragment = _urlparse

        try:
            if scheme == 'http':
                conn = httplib.HTTPConnection(netloc)
            elif scheme == 'https':
                conn = httplib.HTTPSConnection(netloc)
            else:
                excep_msg = _("Invalid scheme: %s.") % scheme
                LOG.error(excep_msg)
                raise ValueError(excep_msg)

            conn.putrequest('PUT', path + '?' + query)
            conn.putheader('User-Agent', USER_AGENT)
            conn.putheader('Content-Length', file_size)
            conn.putheader('Cookie', self._build_vim_cookie_header(cookies))
            conn.endheaders()
            LOG.debug(_("Created HTTP connection to write to file with "
                        "URL = %s."), url)
            return conn
        except (httplib.InvalidURL, httplib.CannotSendRequest,
                httplib.CannotSendHeader) as excep:
            excep_msg = _("Error occurred while creating HTTP connection "
                          "to write to file with URL = %s.") % url
            LOG.exception(excep_msg)
            raise exceptions.VimConnectionException(excep_msg, excep)
Example #7
0
    def write(self, data):
        """Write data to the file.

        :param data: data to be written
        :raises: VimConnectionException, VimException
        """
        LOG.debug("Writing data to VMDK file with URL = %s.", self._url)

        try:
            self._file_handle.send(data)
            self._bytes_written += len(data)
            LOG.debug("Total %(bytes_written)d bytes written to VMDK file "
                      "with URL = %(url)s.",
                      {'bytes_written': self._bytes_written,
                       'url': self._url})
        except (socket.error, httplib.NotConnected) as excep:
            excep_msg = _("Connection error occurred while writing data to"
                          " %s.") % self._url
            LOG.exception(excep_msg)
            raise exceptions.VimConnectionException(excep_msg, excep)
        except Exception as excep:
            # TODO(vbala) We need to catch and raise specific exceptions
            # related to connection problems, invalid request and invalid
            # arguments.
            excep_msg = _("Error occurred while writing data to"
                          " %s.") % self._url
            LOG.exception(excep_msg)
            raise exceptions.VimException(excep_msg, excep)
Example #8
0
        def _inner():
            if initial_delay:
                greenthread.sleep(initial_delay)

            try:
                while self._running:
                    start = timeutils.utcnow()
                    self.f(*self.args, **self.kw)
                    end = timeutils.utcnow()
                    if not self._running:
                        break
                    delay = interval - timeutils.delta_seconds(start, end)
                    if delay <= 0:
                        LOG.warn(
                            _('task run outlasted interval by %s sec') %
                            -delay)
                    greenthread.sleep(delay if delay > 0 else 0)
            except LoopingCallDone as e:
                self.stop()
                done.send(e.retvalue)
            except Exception:
                LOG.exception(_('in fixed duration looping call'))
                done.send_exception(*sys.exc_info())
                return
            else:
                done.send(True)
Example #9
0
    def _create_connection(self, url, file_size, cookies):
        """Create HTTP connection to write to the file with given URL."""
        LOG.debug("Creating HTTP connection to write to file with "
                  "size = %(file_size)d and URL = %(url)s.",
                  {'file_size': file_size,
                   'url': url})
        _urlparse = urlparse.urlparse(url)
        scheme, netloc, path, params, query, fragment = _urlparse

        try:
            if scheme == 'http':
                conn = httplib.HTTPConnection(netloc)
            elif scheme == 'https':
                conn = httplib.HTTPSConnection(netloc)
            else:
                excep_msg = _("Invalid scheme: %s.") % scheme
                LOG.error(excep_msg)
                raise ValueError(excep_msg)

            conn.putrequest('PUT', path + '?' + query)
            conn.putheader('User-Agent', USER_AGENT)
            conn.putheader('Content-Length', file_size)
            conn.putheader('Cookie', self._build_vim_cookie_header(cookies))
            conn.endheaders()
            LOG.debug("Created HTTP connection to write to file with "
                      "URL = %s.", url)
            return conn
        except (httplib.InvalidURL, httplib.CannotSendRequest,
                httplib.CannotSendHeader) as excep:
            excep_msg = _("Error occurred while creating HTTP connection "
                          "to write to file with URL = %s.") % url
            LOG.exception(excep_msg)
            raise exceptions.VimConnectionException(excep_msg, excep)
Example #10
0
def download_stream_optimized_image(context, timeout_secs, image_service,
                                    image_id, **kwargs):
    """Download stream optimized image from image service to VMware server.

    :param context: image service write context
    :param timeout_secs: time in seconds to wait for the download to complete
    :param image_service: image service handle
    :param image_id: ID of the image to be downloaded
    :param kwargs: keyword arguments to configure the destination
                   VMDK write handle
    :returns: managed object reference of the VM created for import to VMware
              server
    :raises: VimException, VimFaultException, VimAttributeException,
             VimSessionOverLoadException, VimConnectionException,
             ImageTransferException, ValueError
    """
    LOG.debug(_("Downloading image: %s from image service as a stream "
                "optimized file."),
              image_id)

    # TODO(vbala) catch specific exceptions raised by download call
    read_iter = image_service.download(context, image_id)
    read_handle = rw_handles.ImageReadHandle(read_iter)
    imported_vm = download_stream_optimized_data(context, timeout_secs,
                                                 read_handle, **kwargs)

    LOG.debug(_("Downloaded image: %s from image service as a stream "
                "optimized file."),
              image_id)
    return imported_vm
Example #11
0
def download_flat_image(context, timeout_secs, image_service, image_id,
                        **kwargs):
    """Download flat image from the image service to VMware server.

    :param context: image service write context
    :param timeout_secs: time in seconds to wait for the download to complete
    :param image_service: image service handle
    :param image_id: ID of the image to be downloaded
    :param kwargs: keyword arguments to configure the destination
                   file write handle
    :raises: VimConnectionException, ImageTransferException, ValueError
    """
    LOG.debug(_("Downloading image: %s from image service as a flat file."),
              image_id)

    # TODO(vbala) catch specific exceptions raised by download call
    read_iter = image_service.download(context, image_id)
    read_handle = rw_handles.ImageReadHandle(read_iter)
    file_size = int(kwargs.get('image_size'))
    write_handle = rw_handles.FileWriteHandle(kwargs.get('host'),
                                              kwargs.get('data_center_name'),
                                              kwargs.get('datastore_name'),
                                              kwargs.get('cookies'),
                                              kwargs.get('file_path'),
                                              file_size)
    _start_transfer(context,
                    timeout_secs,
                    read_handle,
                    file_size,
                    write_file_handle=write_handle)
    LOG.debug(_("Downloaded image: %s from image service as a flat file."),
              image_id)
Example #12
0
        def _inner():
            if initial_delay:
                greenthread.sleep(initial_delay)

            try:
                while self._running:
                    idle = self.f(*self.args, **self.kw)
                    if not self._running:
                        break

                    if periodic_interval_max is not None:
                        idle = min(idle, periodic_interval_max)
                    LOG.debug(
                        _('Dynamic looping call sleeping for %.02f '
                          'seconds'), idle)
                    greenthread.sleep(idle)
            except LoopingCallDone as e:
                self.stop()
                done.send(e.retvalue)
            except Exception:
                LOG.exception(_('in dynamic looping call'))
                done.send_exception(*sys.exc_info())
                return
            else:
                done.send(True)
Example #13
0
 def __init__(self, fault_list, message, cause=None, details=None):
     super(VimFaultException, self).__init__(message, cause)
     if not isinstance(fault_list, list):
         raise ValueError(_("fault_list must be a list"))
     if details is not None and not isinstance(details, dict):
         raise ValueError(_("details must be a dict"))
     self.fault_list = fault_list
     self.details = details
Example #14
0
 def __init__(self, datastore_name, *paths):
     if datastore_name is None or datastore_name == '':
         raise ValueError(_("Datastore name cannot be empty"))
     self._datastore_name = datastore_name
     self._rel_path = ''
     if paths:
         if None in paths:
             raise ValueError(_("Path component cannot be None"))
         self._rel_path = posixpath.join(*paths)
Example #15
0
 def __init__(self, datastore_name, *paths):
     if datastore_name is None or datastore_name == '':
         raise ValueError(_("Datastore name cannot be empty"))
     self._datastore_name = datastore_name
     self._rel_path = ''
     if paths:
         if None in paths:
             raise ValueError(_("Path component cannot be None"))
         self._rel_path = posixpath.join(*paths)
Example #16
0
        def _invoke_api(module, method, *args, **kwargs):
            LOG.debug("Invoking method %(module)s.%(method)s.",
                      {'module': module,
                       'method': method})
            try:
                api_method = getattr(module, method)
                return api_method(*args, **kwargs)
            except exceptions.VimFaultException as excep:
                # If this is due to an inactive session, we should re-create
                # the session and retry.
                if exceptions.NOT_AUTHENTICATED in excep.fault_list:
                    # The NotAuthenticated fault is set by the fault checker
                    # due to an empty response. An empty response could be a
                    # valid response; for e.g., response for the query to
                    # return the VMs in an ESX server which has no VMs in it.
                    # Also, the server responds with an empty response in the
                    # case of an inactive session. Therefore, we need a way to
                    # differentiate between these two cases.
                    if self._is_current_session_active():
                        LOG.debug("Returning empty response for "
                                  "%(module)s.%(method)s invocation.",
                                  {'module': module,
                                   'method': method})
                        return []
                    else:
                        # empty response is due to an inactive session
                        excep_msg = (
                            _("Current session: %(session)s is inactive; "
                              "re-creating the session while invoking "
                              "method %(module)s.%(method)s.") %
                            {'session': self._session_id,
                             'module': module,
                             'method': method})
                        LOG.warn(excep_msg, exc_info=True)
                        self._create_session()
                        raise exceptions.VimConnectionException(excep_msg,
                                                                excep)
                else:
                    # no need to retry for other VIM faults like
                    # InvalidArgument
                    # Raise specific exceptions here if possible
                    if excep.fault_list:
                        LOG.debug("Fault list: %s", excep.fault_list)
                        raise exceptions.get_fault_class(excep.fault_list[0])
                    raise

            except exceptions.VimConnectionException:
                with excutils.save_and_reraise_exception():
                    # Re-create the session during connection exception.
                    LOG.warn(_("Re-creating session due to connection "
                               "problems while invoking method "
                               "%(module)s.%(method)s."),
                             {'module': module,
                              'method': method},
                             exc_info=True)
                    self._create_session()
Example #17
0
 def close(self):
     """Get the response and close the connection."""
     LOG.debug(_("Closing write handle for %s."), self._url)
     try:
         self.conn.getresponse()
     except Exception:
         LOG.warn(_("Error occurred while reading the HTTP response."),
                  exc_info=True)
     super(FileWriteHandle, self).close()
     LOG.debug(_("Closed write handle for %s."), self._url)
Example #18
0
 def _create_and_wait_for_lease(self, session, vm_ref):
     """Create and wait for HttpNfcLease lease for VM export."""
     LOG.debug(_("Creating HttpNfcLease lease for exporting VM: %s."),
               vm_ref)
     lease = session.invoke_api(session.vim, 'ExportVm', vm_ref)
     LOG.debug(_("Lease: %(lease)s obtained for exporting VM: %(vm_ref)s."),
               {'lease': lease,
                'vm_ref': vm_ref})
     session.wait_for_lease_ready(lease)
     return lease
Example #19
0
        def _invoke_api(module, method, *args, **kwargs):
            LOG.debug(_("Invoking method %(module)s.%(method)s."),
                      {'module': module,
                       'method': method})
            try:
                api_method = getattr(module, method)
                return api_method(*args, **kwargs)
            except exceptions.VimFaultException as excep:
                # If this is due to an inactive session, we should re-create
                # the session and retry.
                if exceptions.NOT_AUTHENTICATED in excep.fault_list:
                    # The NotAuthenticated fault is set by the fault checker
                    # due to an empty response. An empty response could be a
                    # valid response; for e.g., response for the query to
                    # return the VMs in an ESX server which has no VMs in it.
                    # Also, the server responds with an empty response in the
                    # case of an inactive session. Therefore, we need a way to
                    # differentiate between these two cases.
                    if self._is_current_session_active():
                        LOG.debug(_("Returning empty response for "
                                    "%(module)s.%(method)s invocation."),
                                  {'module': module,
                                   'method': method})
                        return []
                    else:
                        # empty response is due to an inactive session
                        excep_msg = (
                            _("Current session: %(session)s is inactive; "
                              "re-creating the session while invoking "
                              "method %(module)s.%(method)s.") %
                            {'session': self._session_id,
                             'module': module,
                             'method': method})
                        LOG.warn(excep_msg, exc_info=True)
                        self._create_session()
                        raise exceptions.VimConnectionException(excep_msg,
                                                                excep)
                else:
                    # no need to retry for other VIM faults like
                    # InvalidArgument
                    # Raise specific exceptions here if possible
                    if excep.fault_list:
                        LOG.debug(_("Fault list: %s"), excep.fault_list)
                        raise exceptions.get_fault_class(excep.fault_list[0])
                    raise

            except exceptions.VimConnectionException:
                # Re-create the session during connection exception.
                LOG.warn(_("Re-creating session due to connection problems "
                           "while invoking method %(module)s.%(method)s."),
                         {'module': module,
                          'method': method},
                         exc_info=True)
                self._create_session()
                raise
Example #20
0
    def read(self, chunk_size):
        """Read an item from the image data iterator.

        The input chunk size is ignored since the client ImageBodyIterator
        uses its own chunk size.
        """
        try:
            data = self._iter.next()
            LOG.debug(_("Read %d bytes from the image iterator."), len(data))
            return data
        except StopIteration:
            LOG.debug(_("Completed reading data from the image iterator."))
            return ""
Example #21
0
 def _find_vmdk_url(self, lease_info, host):
     """Find the URL corresponding to a VMDK file in lease info."""
     LOG.debug(_("Finding VMDK URL from lease info."))
     url = None
     for deviceUrl in lease_info.deviceUrl:
         if deviceUrl.disk:
             url = self._fix_esx_url(deviceUrl.url, host)
             break
     if not url:
         excep_msg = _("Could not retrieve VMDK URL from lease info.")
         LOG.error(excep_msg)
         raise exceptions.VimException(excep_msg)
     LOG.debug(_("Found VMDK URL: %s from lease info."), url)
     return url
Example #22
0
 def __del__(self):
     """Log out and terminate the current session."""
     if self._session_id:
         LOG.info(_("Logging out and terminating the current session with "
                    "ID = %s."),
                  self._session_id)
         try:
             self.vim.Logout(self.vim.service_content.sessionManager)
         except Exception:
             LOG.exception(_("Error occurred while logging out and "
                             "terminating the current session with "
                             "ID = %s."),
                           self._session_id)
     else:
         LOG.debug(_("No session exists to log out."))
Example #23
0
 def __del__(self):
     """Log out and terminate the current session."""
     if self._session_id:
         LOG.info(_("Logging out and terminating the current session with "
                    "ID = %s."),
                  self._session_id)
         try:
             self.vim.Logout(self.vim.service_content.sessionManager)
         except Exception:
             LOG.exception(_("Error occurred while logging out and "
                             "terminating the current session with "
                             "ID = %s."),
                           self._session_id)
     else:
         LOG.debug(_("No session exists to log out."))
Example #24
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('vm'),
                                            kwargs.get('vmdk_file_path'),
                                            file_size)

    # 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',
                      'is_public': kwargs.get('is_public'),
                      'name': kwargs.get('image_name'),
                      'status': 'active',
                      'container_format': 'bare',
                      'size': 0,
                      'properties': {'vmware_image_version':
                                     kwargs.get('image_version'),
                                     'vmware_disktype': 'streamOptimized',
                                     'owner_id': owner_id}}

    # Passing 0 as the file size since data size to be transferred cannot be
    # predetermined.
    _start_transfer(context,
                    timeout_secs,
                    read_handle,
                    0,
                    image_service=image_service,
                    image_id=image_id,
                    image_meta=image_metadata)
    LOG.debug(_("Uploaded image: %s."), image_id)
Example #25
0
    def __init__(self, session, host, vm_ref, vmdk_path, vmdk_size):
        """Initializes the VMDK read handle with the given parameters.

        During the read (export) operation, the VMDK file is converted to a
        stream-optimized sparse disk format. Therefore, the size of the VMDK
        file read may be smaller than the actual VMDK size.

        :param session: valid api session to ESX/VC server
        :param host: ESX/VC server IP address[:port] or host name[:port]
        :param vm_ref: managed object reference of the backing VM whose VMDK
                       is to be exported
        :param vmdk_path: path of the VMDK file to be exported
        :param vmdk_size: actual size of the VMDK file
        :raises: VimException, VimFaultException, VimAttributeException,
                 VimSessionOverLoadException, VimConnectionException
        """
        self._session = session
        self._vmdk_size = vmdk_size
        self._bytes_read = 0

        # Obtain lease for VM export
        self._lease = self._create_and_wait_for_lease(session, vm_ref)
        LOG.debug(_("Invoking VIM API for reading info of lease: %s."),
                  self._lease)
        lease_info = session.invoke_api(vim_util,
                                        'get_object_property',
                                        session.vim,
                                        self._lease,
                                        'info')

        # find URL of the VMDK file to be read and open connection
        self._url = self._find_vmdk_url(lease_info, host)
        self._conn = self._create_connection(session, self._url)
        FileHandle.__init__(self, self._conn)
Example #26
0
class VMwareDriverException(Exception):
    """Base VMware Driver Exception

    To correctly use this class, inherit from it and define
    a 'msg_fmt' property. That msg_fmt will get printf'd
    with the keyword arguments provided to the constructor.

    """
    msg_fmt = _("An unknown exception occurred.")

    def __init__(self, message=None, **kwargs):
        self.kwargs = kwargs

        if not message:
            try:
                message = self.msg_fmt % kwargs

            except Exception:
                # kwargs doesn't match a variable in the message
                # log the issue and the kwargs
                LOG.exception(_LE('Exception in string format operation'))
                for name, value in six.iteritems(kwargs):
                    LOG.error(_LE("%(name)s: %(value)s"), {
                        'name': name,
                        'value': value
                    })
                # at least get the core message out if something happened
                message = self.msg_fmt

        super(VMwareDriverException, self).__init__(message)
Example #27
0
    def close(self):
        """Releases the lease and close the connection.

        :raises: VimException, VimFaultException, VimAttributeException,
                 VimSessionOverLoadException, VimConnectionException
        """
        LOG.debug("Getting lease state for %s.", self._url)
        try:
            state = self._session.invoke_api(vim_util,
                                             'get_object_property',
                                             self._session.vim,
                                             self._lease,
                                             'state')
            LOG.debug("Lease for %(url)s is in state: %(state)s.",
                      {'url': self._url,
                       'state': state})
            if state == 'ready':
                LOG.debug("Releasing lease for %s.", self._url)
                self._session.invoke_api(self._session.vim,
                                         'HttpNfcLeaseComplete',
                                         self._lease)
                LOG.debug("Lease for %s released.", self._url)
            else:
                LOG.debug("Lease for %(url)s is in state: %(state)s; no "
                          "need to release.",
                          {'url': self._url,
                           'state': state})
        except exceptions.VimException:
            LOG.warn(_("Error occurred while releasing the lease for %s."),
                     self._url,
                     exc_info=True)
            raise
        super(VmdkReadHandle, self).close()
        LOG.debug("Closed VMDK read handle for %s.", self._url)
Example #28
0
    def write(self, data):
        """Write data into the queue.

        :param data: data to be written
        """
        LOG.debug(_("Writing %d data items into the queue."), len(data))
        self.put(data)
Example #29
0
 def close(self):
     """Close the file handle."""
     try:
         self._file_handle.close()
     except Exception:
         LOG.warn(_("Error occurred while closing the file handle"),
                  exc_info=True)
Example #30
0
 def close(self):
     """Close the file handle."""
     try:
         self._file_handle.close()
     except Exception:
         LOG.warn(_("Error occurred while closing the file handle"),
                  exc_info=True)
Example #31
0
 def _create_and_wait_for_lease(self, session, rp_ref, import_spec,
                                vm_folder_ref):
     """Create and wait for HttpNfcLease lease for vApp import."""
     LOG.debug(_("Creating HttpNfcLease lease for vApp import into resource"
                 " pool: %s."),
               rp_ref)
     lease = session.invoke_api(session.vim,
                                'ImportVApp',
                                rp_ref,
                                spec=import_spec,
                                folder=vm_folder_ref)
     LOG.debug(_("Lease: %(lease)s obtained for vApp import into resource"
                 " pool %(rp_ref)s."),
               {'lease': lease,
                'rp_ref': rp_ref})
     session.wait_for_lease_ready(lease)
     return lease
Example #32
0
def get_profile_id_by_name(session, profile_name):
    """Get the profile UUID corresponding to the given profile name.

    :param profile_name: profile name whose UUID needs to be retrieved
    :returns: profile UUID string or None if profile not found
    :raises: VimException, VimFaultException, VimAttributeException,
             VimSessionOverLoadException, VimConnectionException
    """
    LOG.debug(_("Retrieving profile ID for profile: %s."), profile_name)
    for profile in get_all_profiles(session):
        if profile.name == profile_name:
            profile_id = profile.profileId
            LOG.debug(_("Retrieved profile ID: %(id)s for profile: %(name)s."),
                      {'id': profile_id,
                       'name': profile_name})
            return profile_id
    return None
Example #33
0
def get_fault_class(name):
    """Get a named subclass of NovaException."""
    name = str(name)
    fault_class = _fault_classes_registry.get(name)
    if not fault_class:
        LOG.debug(_('Fault %s not matched.'), name)
        fault_class = VMwareDriverException
    return fault_class
Example #34
0
    def close(self):
        """Releases the lease and close the connection.

        :raises: VimException, VimFaultException, VimAttributeException,
                 VimSessionOverLoadException, VimConnectionException
        """
        LOG.debug(_("Getting lease state for %s."), self._url)
        try:
            state = self._session.invoke_api(vim_util,
                                             'get_object_property',
                                             self._session.vim,
                                             self._lease,
                                             'state')
            LOG.debug(_("Lease for %(url)s is in state: %(state)s."),
                      {'url': self._url,
                       'state': state})
            if state == 'ready':
                LOG.debug(_("Releasing lease for %s."), self._url)
                self._session.invoke_api(self._session.vim,
                                         'HttpNfcLeaseComplete',
                                         self._lease)
                LOG.debug(_("Lease for %s released."), self._url)
            else:
                LOG.debug(_("Lease for %(url)s is in state: %(state)s; no "
                            "need to release."),
                          {'url': self._url,
                           'state': state})
        except exceptions.VimException:
            LOG.warn(_("Error occurred while releasing the lease for %s."),
                     self._url,
                     exc_info=True)
            raise
        super(VmdkReadHandle, self).close()
        LOG.debug(_("Closed VMDK read handle for %s."), self._url)
Example #35
0
 def _create_connection(self, session, url):
     LOG.debug(_("Opening URL: %s for reading."), url)
     try:
         cookies = session.vim.client.options.transport.cookiejar
         headers = {'User-Agent': USER_AGENT,
                    'Cookie': self._build_vim_cookie_header(cookies)}
         request = urllib2.Request(url, None, headers)
         conn = urllib2.urlopen(request)
         LOG.debug(_("URL: %s opened for reading."), url)
         return conn
     except Exception as excep:
         # TODO(vbala) We need to catch and raise specific exceptions
         # related to connection problems, invalid request and invalid
         # arguments.
         excep_msg = _("Error occurred while opening URL: %s for "
                       "reading.") % url
         LOG.exception(excep_msg)
         raise exceptions.VimException(excep_msg, excep)
Example #36
0
    def __init__(self, message, cause=None):
        Exception.__init__(self)
        if isinstance(message, list):
            # we need this to protect against developers using
            # this method like VimFaultException
            raise ValueError(_("exception_summary must not be a list"))

        self.msg = str(message)
        self.cause = cause
Example #37
0
    def __init__(self, message, cause=None):
        Exception.__init__(self)
        if isinstance(message, list):
            # we need this to protect against developers using
            # this method like VimFaultException
            raise ValueError(_("exception_summary must not be a list"))

        self.msg = str(message)
        self.cause = cause
Example #38
0
    def _poll_lease(self, lease):
        """Poll the state of the given lease.

        When the lease is ready, the event (param done) is notified. In case
        of any error, appropriate exception is set in the event.

        :param lease: lease whose state is to be polled
        """
        LOG.debug("Invoking VIM API to read state of lease: %s.", lease)
        try:
            state = self.invoke_api(vim_util,
                                    'get_object_property',
                                    self.vim,
                                    lease,
                                    'state')
        except exceptions.VimException:
            with excutils.save_and_reraise_exception():
                LOG.exception(_LE("Error occurred while checking "
                                  "state of lease: %s."),
                              lease)
        else:
            if state == 'ready':
                LOG.debug("Lease: %s is ready.", lease)
                raise loopingcall.LoopingCallDone()
            elif state == 'initializing':
                LOG.debug("Lease: %s is initializing.", lease)
            elif state == 'error':
                LOG.debug("Invoking VIM API to read lease: %s error.",
                          lease)
                error_msg = self._get_error_message(lease)
                excep_msg = _("Lease: %(lease)s is in error state. Details: "
                              "%(error_msg)s.") % {'lease': lease,
                                                   'error_msg': error_msg}
                LOG.error(excep_msg)
                raise exceptions.VimException(excep_msg)
            else:
                # unknown state
                excep_msg = _("Unknown state: %(state)s for lease: "
                              "%(lease)s.") % {'state': state,
                                               'lease': lease}
                LOG.error(excep_msg)
                raise exceptions.VimException(excep_msg)
Example #39
0
    def _poll_lease(self, lease):
        """Poll the state of the given lease.

        When the lease is ready, the event (param done) is notified. In case
        of any error, appropriate exception is set in the event.

        :param lease: lease whose state is to be polled
        """
        LOG.debug("Invoking VIM API to read state of lease: %s.", lease)
        try:
            state = self.invoke_api(vim_util, 'get_object_property', self.vim,
                                    lease, 'state')
        except exceptions.VimException:
            with excutils.save_and_reraise_exception():
                LOG.exception(
                    _LE("Error occurred while checking "
                        "state of lease: %s."), lease)
        else:
            if state == 'ready':
                LOG.debug("Lease: %s is ready.", lease)
                raise loopingcall.LoopingCallDone()
            elif state == 'initializing':
                LOG.debug("Lease: %s is initializing.", lease)
            elif state == 'error':
                LOG.debug("Invoking VIM API to read lease: %s error.", lease)
                error_msg = self._get_error_message(lease)
                excep_msg = _("Lease: %(lease)s is in error state. Details: "
                              "%(error_msg)s.") % {
                                  'lease': lease,
                                  'error_msg': error_msg
                              }
                LOG.error(excep_msg)
                raise exceptions.VimException(excep_msg)
            else:
                # unknown state
                excep_msg = _("Unknown state: %(state)s for lease: "
                              "%(lease)s.") % {
                                  'state': state,
                                  'lease': lease
                              }
                LOG.error(excep_msg)
                raise exceptions.VimException(excep_msg)
Example #40
0
    def _create_connection(self, session, url, vmdk_size):
        """Create HTTP connection to write to VMDK file."""
        LOG.debug(
            "Creating HTTP connection to write to VMDK file with "
            "size = %(vmdk_size)d and URL = %(url)s.", {
                'vmdk_size': vmdk_size,
                'url': url
            })
        cookies = session.vim.client.options.transport.cookiejar
        _urlparse = urlparse.urlparse(url)
        scheme, netloc, path, params, query, fragment = _urlparse

        try:
            if scheme == 'http':
                conn = httplib.HTTPConnection(netloc)
            elif scheme == 'https':
                conn = httplib.HTTPSConnection(netloc)
            else:
                excep_msg = _("Invalid scheme: %s.") % scheme
                LOG.error(excep_msg)
                raise ValueError(excep_msg)

            if query:
                path = path + '?' + query
            conn.putrequest('PUT', path)
            conn.putheader('User-Agent', USER_AGENT)
            conn.putheader('Content-Length', str(vmdk_size))
            conn.putheader('Overwrite', 't')
            conn.putheader('Cookie', self._build_vim_cookie_header(cookies))
            conn.putheader('Content-Type', 'binary/octet-stream')
            conn.endheaders()
            LOG.debug(
                "Created HTTP connection to write to VMDK file with "
                "URL = %s.", url)
            return conn
        except (httplib.InvalidURL, httplib.CannotSendRequest,
                httplib.CannotSendHeader) as excep:
            excep_msg = _("Error occurred while creating HTTP connection "
                          "to write to VMDK file with URL = %s.") % url
            LOG.exception(excep_msg)
            raise exceptions.VimConnectionException(excep_msg, excep)
Example #41
0
    def _is_current_session_active(self):
        """Check if current session is active.

        :returns: True if the session is active; False otherwise
        """
        LOG.debug(_("Checking if the current session: %s is active."),
                  self._session_id)

        is_active = False
        try:
            is_active = self.vim.SessionIsActive(
                self.vim.service_content.sessionManager,
                sessionID=self._session_id,
                userName=self._session_username)
        except exceptions.VimException:
            LOG.warn(_("Error occurred while checking whether the "
                       "current session: %s is active."),
                     self._session_id,
                     exc_info=True)

        return is_active
Example #42
0
    def _is_current_session_active(self):
        """Check if current session is active.

        :returns: True if the session is active; False otherwise
        """
        LOG.debug(_("Checking if the current session: %s is active."),
                  self._session_id)

        is_active = False
        try:
            is_active = self.vim.SessionIsActive(
                self.vim.service_content.sessionManager,
                sessionID=self._session_id,
                userName=self._session_username)
        except exceptions.VimException:
            LOG.warn(_("Error occurred while checking whether the "
                       "current session: %s is active."),
                     self._session_id,
                     exc_info=True)

        return is_active
Example #43
0
    def parse(cls, datastore_path):
        """Constructs a DatastorePath object given a datastore path string."""
        if not datastore_path:
            raise ValueError(_("Datastore path cannot be empty"))

        spl = datastore_path.split('[', 1)[1].split(']', 1)
        path = ""
        if len(spl) == 1:
            datastore_name = spl[0]
        else:
            datastore_name, path = spl
        return cls(datastore_name, path.strip())
Example #44
0
    def parse(cls, datastore_path):
        """Constructs a DatastorePath object given a datastore path string."""
        if not datastore_path:
            raise ValueError(_("Datastore path cannot be empty"))

        spl = datastore_path.split('[', 1)[1].split(']', 1)
        path = ""
        if len(spl) == 1:
            datastore_name = spl[0]
        else:
            datastore_name, path = spl
        return cls(datastore_name, path.strip())
Example #45
0
    def _poll_task(self, task):
        """Poll the given task until completion.

        If the task completes successfully, the method returns the task info
        using the input event (param done). In case of any error, appropriate
        exception is set in the event.

        :param task: managed object reference of the task
        """
        LOG.debug("Invoking VIM API to read info of task: %s.", task)
        try:
            task_info = self.invoke_api(vim_util,
                                        'get_object_property',
                                        self.vim,
                                        task,
                                        'info')
        except exceptions.VimException:
            with excutils.save_and_reraise_exception():
                LOG.exception(_("Error occurred while reading info of "
                                "task: %s."),
                              task)
        else:
            if task_info.state in ['queued', 'running']:
                if hasattr(task_info, 'progress'):
                    LOG.debug("Task: %(task)s progress is %(progress)s%%.",
                              {'task': task,
                               'progress': task_info.progress})
            elif task_info.state == 'success':
                LOG.debug("Task: %s status is success.", task)
                raise loopingcall.LoopingCallDone(task_info)
            else:
                error_msg = six.text_type(task_info.error.localizedMessage)
                excep_msg = _("Task: %(task)s failed with error: "
                              "%(error)s.") % {'task': task,
                                               'error': error_msg}
                LOG.error(excep_msg)
                error = task_info.error
                name = error.fault.__class__.__name__
                task_ex = exceptions.get_fault_class(name)(error_msg)
                raise task_ex
Example #46
0
    def _retrieve_properties_ex_fault_checker(response):
        """Checks the RetrievePropertiesEx API response for errors.

        Certain faults are sent in the SOAP body as a property of missingSet.
        This method raises VimFaultException when a fault is found in the
        response.

        :param response: response from RetrievePropertiesEx API call
        :raises: VimFaultException
        """
        LOG.debug(_("Checking RetrievePropertiesEx API response for faults."))
        fault_list = []
        if not response:
            # This is the case when the session has timed out. ESX SOAP
            # server sends an empty RetrievePropertiesExResponse. Normally
            # missingSet in the response objects has the specifics about
            # the error, but that's not the case with a timed out idle
            # session. It is as bad as a terminated session for we cannot
            # use the session. Therefore setting fault to NotAuthenticated
            # fault.
            LOG.debug(
                _("RetrievePropertiesEx API response is empty; setting "
                  "fault to %s."), exceptions.NOT_AUTHENTICATED)
            fault_list = [exceptions.NOT_AUTHENTICATED]
        else:
            for obj_cont in response.objects:
                if hasattr(obj_cont, 'missingSet'):
                    for missing_elem in obj_cont.missingSet:
                        fault_type = missing_elem.fault.fault.__class__
                        fault_list.append(fault_type.__name__)
        if fault_list:
            LOG.error(
                _("Faults %s found in RetrievePropertiesEx API "
                  "response."), fault_list)
            raise exceptions.VimFaultException(
                fault_list,
                _("Error occurred while calling"
                  " RetrievePropertiesEx."))
        LOG.debug(_("No faults found in RetrievePropertiesEx API response."))
Example #47
0
    def __init__(self, ref, name, capacity=None, freespace=None):
        """Datastore object holds ref and name together for convenience.

        :param ref: a vSphere reference to a datastore
        :param name: vSphere unique name for this datastore
        :param capacity: (optional) capacity in bytes of this datastore
        :param freespace: (optional) free space in bytes of datastore
        """
        if name is None:
            raise ValueError(_("Datastore name cannot be None"))
        if ref is None:
            raise ValueError(_("Datastore reference cannot be None"))
        if freespace is not None and capacity is None:
            raise ValueError(_("Invalid capacity"))
        if capacity is not None and freespace is not None:
            if capacity < freespace:
                raise ValueError(_("Capacity is smaller than free space"))

        self._ref = ref
        self._name = name
        self._capacity = capacity
        self._freespace = freespace