示例#1
0
def _start_transfer(read_handle, write_handle, timeout_secs):
    # read_handle/write_handle could be an NFC lease, so we need to
    # periodically update its progress
    read_updater = _create_progress_updater(read_handle)
    write_updater = _create_progress_updater(write_handle)

    timer = timeout.Timeout(timeout_secs)
    try:
        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()
        if read_updater:
            read_updater.stop()
        if write_updater:
            write_updater.stop()
        read_handle.close()
        write_handle.close()
示例#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()
示例#3
0
    def __init__(self, message=None, details=None, **kwargs):

        if message is not None and isinstance(message, list):
            # we need this to protect against developers using
            # this method like VimFaultException
            raise ValueError(_("exception message must not be a list"))

        if details is not None and not isinstance(details, dict):
            raise ValueError(_("details must be a dict"))

        self.kwargs = kwargs
        self.details = details
        self.cause = None

        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('Exception in string format operation')
                for name, value in six.iteritems(kwargs):
                    LOG.error("%(name)s: %(value)s",
                              {'name': name, 'value': value})
                # at least get the core message out if something happened
                message = self.msg_fmt

        self.message = message
        super(VMwareDriverException, self).__init__(message)
示例#4
0
 def connect(self, method, content_length, cookie):
     try:
         if self._scheme == 'http':
             conn = httplib.HTTPConnection(self._server)
         elif self._scheme == 'https':
             # TODO(browne): This needs to be changed to use python requests
             conn = httplib.HTTPSConnection(self._server)  # nosec
         else:
             excep_msg = _("Invalid scheme: %s.") % self._scheme
             LOG.error(excep_msg)
             raise ValueError(excep_msg)
         conn.putrequest(method, '/folder/%s?%s' % (self.path, self._query))
         conn.putheader('User-Agent', constants.USER_AGENT)
         conn.putheader('Content-Length', content_length)
         conn.putheader('Cookie', cookie)
         conn.endheaders()
         LOG.debug("Created HTTP connection to transfer the file with "
                   "URL = %s.", str(self))
         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.") % str(self)
     LOG.exception(excep_msg)
     raise exceptions.VimConnectionException(excep_msg, excep)
示例#5
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)
示例#6
0
    def __init__(self, ref, name, capacity=None, freespace=None,
                 type=None, datacenter=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
        :param type: (optional) datastore type
        :param datacenter: (optional) oslo_vmware Datacenter object
        """
        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
        self.type = type
        self.datacenter = datacenter
示例#7
0
 def __init__(self, ref, name):
     """Datacenter object holds ref and name together for convenience."""
     if name is None:
         raise ValueError(_("Datacenter name cannot be None"))
     if ref is None:
         raise ValueError(_("Datacenter reference cannot be None"))
     self.ref = ref
     self.name = name
示例#8
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
示例#9
0
 def __init__(self, ref, name):
     """Datacenter object holds ref and name together for convenience."""
     if name is None:
         raise ValueError(_("Datacenter name cannot be None"))
     if ref is None:
         raise ValueError(_("Datacenter reference cannot be None"))
     self.ref = ref
     self.name = name
示例#10
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
示例#11
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)
示例#12
0
class NsxvException(Exception):
    """Base Neutron Exception.

    To correctly use this class, inherit from it and define
    a 'message' property. That message will get printf'd
    with the keyword arguments provided to the constructor.
    """
    message = _("An unknown exception occurred.")

    def __init__(self, **kwargs):
        try:
            super(NsxvException, self).__init__(self.message % kwargs)
            self.msg = self.message % kwargs
        except Exception:
            with excutils.save_and_reraise_exception() as ctxt:
                if not self.use_fatal_exceptions():
                    ctxt.reraise = False
                    # at least get the core message out if something happened
                    super(NsxvException, self).__init__(self.message)

    def __unicode__(self):
        return unicode(self.msg)

    def use_fatal_exceptions(self):
        return False
示例#13
0
 def _create_write_connection(self, method, url,
                              file_size=None,
                              cookies=None,
                              overwrite=None,
                              content_type=None,
                              cacerts=False,
                              ssl_thumbprint=None):
     """Create HTTP connection to write to VMDK file."""
     LOG.debug("Creating HTTP connection to write to file with "
               "size = %(file_size)d and URL = %(url)s.",
               {'file_size': file_size,
                'url': url})
     try:
         conn = self._create_connection(url, method, cacerts,
                                        ssl_thumbprint)
         headers = {'User-Agent': USER_AGENT}
         if file_size:
             headers.update({'Content-Length': str(file_size)})
         if overwrite:
             headers.update({'Overwrite': overwrite})
         if cookies:
             headers.update({'Cookie':
                            self._build_vim_cookie_header(cookies)})
         if content_type:
             headers.update({'Content-Type': content_type})
         for key, value in headers.items():
             conn.putheader(key, value)
         conn.endheaders()
         return conn
     except requests.RequestException 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)
示例#14
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, details=None, **kwargs):
        self.kwargs = kwargs
        self.details = details

        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)
    def _create_connection(self,
                           url,
                           method,
                           cacerts=False,
                           ssl_thumbprint=None):
        _urlparse = urlparse.urlparse(url)
        scheme, netloc, path, params, query, fragment = _urlparse
        if scheme == 'http':
            conn = httplib.HTTPConnection(netloc)
        elif scheme == 'https':
            conn = httplib.HTTPSConnection(netloc)
            cert_reqs = None

            # cacerts can be either True or False or contain
            # actual certificates. If it is a boolean, then
            # we need to set cert_reqs and clear the cacerts
            if isinstance(cacerts, bool):
                if cacerts:
                    cert_reqs = ssl.CERT_REQUIRED
                else:
                    cert_reqs = ssl.CERT_NONE
                cacerts = None
            conn.set_cert(ca_certs=cacerts,
                          cert_reqs=cert_reqs,
                          assert_fingerprint=ssl_thumbprint)
        else:
            excep_msg = _("Invalid scheme: %s.") % scheme
            LOG.error(excep_msg)
            raise ValueError(excep_msg)

        if query:
            path = path + '?' + query
        conn.putrequest(method, path)
        return conn
 def test_vim_fault_exception(self):
     vfe = exceptions.VimFaultException([ValueError("example")], _("cause"))
     string = str(vfe)
     self.assertIn(string, [
         "cause\nFaults: [ValueError('example',)]",
         "cause\nFaults: [ValueError('example')]"
     ])
示例#17
0
        def _inner():
            """Task performing the file read-write operation."""
            self._running = True
            while self._running:
                try:
                    data = self._input_file.read(rw_handles.READ_CHUNKSIZE)
                    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)
示例#18
0
 def _create_write_connection(self, method, url,
                              file_size=None,
                              cookies=None,
                              overwrite=None,
                              content_type=None,
                              cacerts=False,
                              ssl_thumbprint=None):
     """Create HTTP connection to write to VMDK file."""
     LOG.debug("Creating HTTP connection to write to file with "
               "size = %(file_size)d and URL = %(url)s.",
               {'file_size': file_size,
                'url': url})
     try:
         conn = self._create_connection(url, method, cacerts,
                                        ssl_thumbprint)
         headers = {'User-Agent': USER_AGENT}
         if file_size:
             headers.update({'Content-Length': str(file_size)})
         if overwrite:
             headers.update({'Overwrite': overwrite})
         if cookies:
             headers.update({'Cookie':
                            self._build_vim_cookie_header(cookies)})
         if content_type:
             headers.update({'Content-Type': content_type})
         for key, value in six.iteritems(headers):
             conn.putheader(key, value)
         conn.endheaders()
         return conn
     except requests.RequestException 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)
示例#19
0
    def _create_connection(self, url, method, cacerts=False,
                           ssl_thumbprint=None):
        _urlparse = urlparse.urlparse(url)
        scheme, netloc, path, params, query, fragment = _urlparse
        if scheme == 'http':
            conn = httplib.HTTPConnection(netloc)
        elif scheme == 'https':
            conn = httplib.HTTPSConnection(netloc)
            cert_reqs = None

            # cacerts can be either True or False or contain
            # actual certificates. If it is a boolean, then
            # we need to set cert_reqs and clear the cacerts
            if isinstance(cacerts, bool):
                if cacerts:
                    cert_reqs = ssl.CERT_REQUIRED
                else:
                    cert_reqs = ssl.CERT_NONE
                cacerts = requests.certs.where()
            conn.set_cert(ca_certs=cacerts, cert_reqs=cert_reqs,
                          assert_fingerprint=ssl_thumbprint)
        else:
            excep_msg = _("Invalid scheme: %s.") % scheme
            LOG.error(excep_msg)
            raise ValueError(excep_msg)

        if query:
            path = path + '?' + query
        conn.putrequest(method, path)
        return conn
示例#20
0
class VMwareDriverException(Exception):
    """Base oslo.vmware 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.")

    if six.PY2:
        __str__ = lambda self: six.text_type(self).encode('utf8')
        __unicode__ = lambda self: self.description
    else:
        __str__ = lambda self: self.description

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

        if message is not None and isinstance(message, list):
            # we need this to protect against developers using
            # this method like VimFaultException
            raise ValueError(_("exception message must not be a list"))

        if details is not None and not isinstance(details, dict):
            raise ValueError(_("details must be a dict"))

        self.kwargs = kwargs
        self.details = details
        self.cause = None

        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('Exception in string format operation')
                for name, value in six.iteritems(kwargs):
                    LOG.error("%(name)s: %(value)s",
                              {'name': name, 'value': value})
                # at least get the core message out if something happened
                message = self.msg_fmt

        self.message = message
        super(VMwareDriverException, self).__init__(message)

    @property
    def msg(self):
        return self.message

    @property
    def description(self):
        # NOTE(jecarey): self.msg and self.cause may be i18n objects
        # that do not support str or concatenation, but can be used
        # as replacement text.
        descr = six.text_type(self.msg)
        if self.cause:
            descr += '\nCause: ' + six.text_type(self.cause)
        return descr
示例#21
0
        def _invoke_api(module, method, *args, **kwargs):
            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': _trunc_id(self._session_id),
                             'module': module,
                             'method': method})
                        LOG.debug(excep_msg)
                        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)
                        fault = excep.fault_list[0]
                        clazz = exceptions.get_fault_class(fault)
                        if clazz:
                            raise clazz(six.text_type(excep),
                                        details=excep.details)
                    raise

            except exceptions.VimConnectionException:
                with excutils.save_and_reraise_exception():
                    # Re-create the session during connection exception only
                    # if the session has expired. Otherwise, it could be
                    # a transient issue.
                    if not self.is_current_session_active():
                        LOG.debug("Re-creating session due to connection "
                                  "problems while invoking method "
                                  "%(module)s.%(method)s.",
                                  {'module': module,
                                   'method': method})
                        self._create_session()
示例#22
0
        def _invoke_api(module, method, *args, **kwargs):
            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': _trunc_id(self._session_id),
                             'module': module,
                             'method': method})
                        LOG.debug(excep_msg)
                        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)
                        fault = excep.fault_list[0]
                        clazz = exceptions.get_fault_class(fault)
                        if clazz:
                            raise clazz(six.text_type(excep),
                                        details=excep.details)
                    raise

            except exceptions.VimConnectionException:
                with excutils.save_and_reraise_exception():
                    # Re-create the session during connection exception only
                    # if the session has expired. Otherwise, it could be
                    # a transient issue.
                    if not self.is_current_session_active():
                        LOG.debug("Re-creating session due to connection "
                                  "problems while invoking method "
                                  "%(module)s.%(method)s.",
                                  {'module': module,
                                   'method': method})
                        self._create_session()
示例#23
0
def register_fault_class(name, exception):
    fault_class = _fault_classes_registry.get(name)
    if not issubclass(exception, VimException):
        raise TypeError(_("exception should be a subclass of "
                          "VimException"))
    if fault_class:
        LOG.debug('Overriding exception for %s', name)
    _fault_classes_registry[name] = exception
示例#24
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
        """
        try:
            state = self.invoke_api(vim_util,
                                    'get_object_property',
                                    self.vim,
                                    lease,
                                    'state',
                                    skip_op_id=True)
        except exceptions.VimException:
            with excutils.save_and_reraise_exception():
                LOG.exception(
                    "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)
示例#25
0
class NsxvApiException(NsxvException):
    message = _("An unknown exception %(status)s occurred: %(response)s.")

    def __init__(self, **kwargs):
        super(NsxvApiException, self).__init__(**kwargs)

        self.status = kwargs.get('status')
        self.header = kwargs.get('header')
        self.response = kwargs.get('response')
示例#26
0
class VMwareDriverConfigurationException(VMwareDriverException):
    """Base class for all configuration exceptions.
    """
    msg_fmt = _("VMware Driver configuration fault.")

    def __init__(self, message=None, details=None, **kwargs):
        super(VMwareDriverConfigurationException, self).__init__(
            message, details, **kwargs)
        _print_deprecation_warning(self.__class__)
示例#27
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 = message
        self.cause = cause
示例#28
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 = message
        self.cause = cause
示例#29
0
    def get_imported_vm(self):
        """"Get managed object reference of the VM created for import.

        :raises: VimException
        """
        if self._get_progress() < 100:
            excep_msg = _("Incomplete VMDK upload to %s.") % self._url
            LOG.exception(excep_msg)
            raise exceptions.ImageTransferException(excep_msg)
        return self._vm_ref
示例#30
0
    def write(self, data):
        """Write data to the file.

        :param data: data to be written
        :raises: VimConnectionException, VimException
        """
        try:
            self._file_handle.send(data)
        except requests.RequestException 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)
    def write(self, data):
        """Write data to the file.

        :param data: data to be written
        :raises: VimConnectionException, VimException
        """
        try:
            self._file_handle.send(data)
        except requests.RequestException 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)
示例#32
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())
示例#33
0
 def _find_vmdk_url(self, lease_info, host, port):
     """Find the URL corresponding to a VMDK file in lease info."""
     url = None
     for deviceUrl in lease_info.deviceUrl:
         if deviceUrl.disk:
             url = self._fix_esx_url(deviceUrl.url, host, port)
             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
示例#34
0
 def _find_vmdk_url(self, lease_info, host, port):
     """Find the URL corresponding to a VMDK file in lease info."""
     url = None
     for deviceUrl in lease_info.deviceUrl:
         if deviceUrl.disk:
             url = self._fix_esx_url(deviceUrl.url, host, port)
             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
示例#35
0
    def join(self, *paths):
        """Join one or more path components intelligently into a datastore path.

        If any component is an absolute path, all previous components are
        thrown away, and joining continues. The return value is the
        concatenation of the paths with exactly one slash ('/') inserted
        between components, unless p is empty.

        :return: A datastore path
        """
        if paths:
            if None in paths:
                raise ValueError(_("Path component cannot be None"))
            return DatastorePath(self.datastore, self._rel_path, *paths)
        return self
示例#36
0
    def build_url(self, scheme, server, rel_path, datacenter_name=None):
        """Constructs and returns a DatastoreURL.

        :param scheme: scheme of the URL (http, https).
        :param server: hostname or ip
        :param rel_path: relative path of the file on the datastore
        :param datacenter_name: (optional) datacenter name
        :return: a DatastoreURL object
        """
        if self.datacenter is None and datacenter_name is None:
            raise ValueError(_("datacenter must be set to build url"))
        if datacenter_name is None:
            datacenter_name = self.datacenter.name
        return DatastoreURL(scheme, server, rel_path, datacenter_name,
                            self.name)
示例#37
0
 def _create_read_connection(self, url, cookies=None, cacerts=False,
                             ssl_thumbprint=None):
     LOG.debug("Opening URL: %s for reading.", url)
     try:
         conn = self._create_connection(url, 'GET', cacerts, ssl_thumbprint)
         vim_cookie = self._build_vim_cookie_header(cookies)
         conn.putheader('User-Agent', USER_AGENT)
         conn.putheader('Cookie', vim_cookie)
         conn.endheaders()
         return conn.getresponse()
     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)
示例#38
0
 def _create_read_connection(self, url, cookies=None, cacerts=False):
     LOG.debug("Opening URL: %s for reading.", url)
     try:
         headers = {'User-Agent': USER_AGENT}
         if cookies:
             headers.update({'Cookie':
                             self._build_vim_cookie_header(cookies)})
         response = requests.get(url, headers=headers, stream=True,
                                 verify=cacerts)
         return response.raw
     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)
示例#39
0
 def _create_read_connection(self, url, cookies=None, cacerts=False,
                             ssl_thumbprint=None):
     LOG.debug("Opening URL: %s for reading.", url)
     try:
         conn = self._create_connection(url, 'GET', cacerts, ssl_thumbprint)
         vim_cookie = self._build_vim_cookie_header(cookies)
         conn.putheader('User-Agent', USER_AGENT)
         conn.putheader('Cookie', vim_cookie)
         conn.endheaders()
         return conn.getresponse()
     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)
    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
        """
        try:
            data = self._file_handle.read(READ_CHUNKSIZE)
            self._bytes_read += len(data)
            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)
示例#41
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
        """
        try:
            data = self._file_handle.read(READ_CHUNKSIZE)
            self._bytes_read += len(data)
            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)
示例#42
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
    """
    metadata = image_service.show(context, image_id)
    container_format = metadata.get('container_format')

    LOG.debug(
        "Downloading image: %(id)s (container: %(container)s) from image"
        " service as a stream optimized file.", {
            'id': image_id,
            'container': container_format
        })

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

    if container_format == 'ova':
        read_handle = _get_vmdk_handle(read_handle)
        if read_handle is None:
            raise exceptions.ImageTransferException(
                _("No vmdk found in the OVA image %s.") % image_id)

    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
示例#43
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
        """
        fault_list = []
        details = {}
        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:
                        f_type = missing_elem.fault.fault
                        f_name = f_type.__class__.__name__
                        fault_list.append(f_name)
                        if f_name == exceptions.NO_PERMISSION:
                            details['object'] = f_type.object.value
                            details['privilegeId'] = f_type.privilegeId

        if fault_list:
            fault_string = _("Error occurred while calling "
                             "RetrievePropertiesEx.")
            raise exceptions.VimFaultException(fault_list,
                                               fault_string,
                                               details=details)
示例#44
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
    """
    metadata = image_service.show(context, image_id)
    container_format = metadata.get('container_format')

    LOG.debug("Downloading image: %(id)s (container: %(container)s) from image"
              " service as a stream optimized file.",
              {'id': image_id,
               'container': container_format})

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

    if container_format == 'ova':
        read_handle = _get_vmdk_handle(read_handle)
        if read_handle is None:
            raise exceptions.ImageTransferException(
                _("No vmdk found in the OVA image %s.") % image_id)

    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
示例#45
0
        def _inner():
            """Task performing the image write operation.

            This method performs image data transfer through an update call.
            After the update, it waits until the image state becomes
            'active', 'killed' or unknown. If the final state is not 'active'
            an instance of ImageTransferException is thrown.

            :raises: ImageTransferException
            """
            LOG.debug("Calling image service update on image: %(image)s "
                      "with meta: %(meta)s",
                      {'image': self._image_id,
                       'meta': self._image_meta})

            try:
                self._image_service.update(self._context,
                                           self._image_id,
                                           self._image_meta,
                                           data=self._input_file)
                self._running = True
                while self._running:
                    LOG.debug("Retrieving status of image: %s.",
                              self._image_id)
                    image_meta = self._image_service.show(self._context,
                                                          self._image_id)
                    image_status = image_meta.get('status')
                    if image_status == 'active':
                        self.stop()
                        LOG.debug("Image: %s is now active.",
                                  self._image_id)
                        self._done.send(True)
                    elif image_status == 'killed':
                        self.stop()
                        excep_msg = (_("Image: %s is in killed state.") %
                                     self._image_id)
                        LOG.error(excep_msg)
                        excep = exceptions.ImageTransferException(excep_msg)
                        self._done.send_exception(excep)
                    elif image_status in ['saving', 'queued']:
                        LOG.debug("Image: %(image)s is in %(state)s state; "
                                  "sleeping for %(sleep)d seconds.",
                                  {'image': self._image_id,
                                   'state': image_status,
                                   'sleep': IMAGE_SERVICE_POLL_INTERVAL})
                        greenthread.sleep(IMAGE_SERVICE_POLL_INTERVAL)
                    else:
                        self.stop()
                        excep_msg = (_("Image: %(image)s is in unknown "
                                       "state: %(state)s.") %
                                     {'image': self._image_id,
                                      'state': image_status})
                        LOG.error(excep_msg)
                        excep = exceptions.ImageTransferException(excep_msg)
                        self._done.send_exception(excep)
            except Exception as excep:
                self.stop()
                excep_msg = (_("Error occurred while writing image: %s") %
                             self._image_id)
                LOG.exception(excep_msg)
                excep = exceptions.ImageTransferException(excep_msg, excep)
                self._done.send_exception(excep)
示例#46
0
def _start_transfer(context, timeout_secs, read_file_handle, max_data_size,
                    write_file_handle=None, image_service=None, image_id=None,
                    image_meta=None):
    """Start the image transfer.

    The image reader reads the data from the image source and writes to the
    blocking queue. The image source is always a file handle (VmdkReadHandle
    or ImageReadHandle); therefore, a FileReadWriteTask is created for this
    transfer. The image writer reads the data from the blocking queue and
    writes it to the image destination. The image destination is either a
    file or VMDK in VMware datastore or an image in the image service.

    If the destination is a file or VMDK in VMware datastore, the method
    creates a FileReadWriteTask which reads from the blocking queue and
    writes to either FileWriteHandle or VmdkWriteHandle. In the case of
    image service as the destination, an instance of ImageWriter task is
    created which reads from the blocking queue and writes to the image
    service.

    :param context: write context needed for the image service
    :param timeout_secs: time in seconds to wait for the transfer to complete
    :param read_file_handle: handle to read data from
    :param max_data_size: maximum transfer size
    :param write_file_handle: handle to write data to; if this is None, then
                              param image_service  and param image_id should
                              be set.
    :param image_service: image service handle
    :param image_id: ID of the image in the image service
    :param image_meta: image meta-data
    :raises: ImageTransferException, ValueError
    """

    # Create the blocking queue
    blocking_queue = BlockingQueue(BLOCKING_QUEUE_SIZE, max_data_size)

    # Create the image reader
    reader = FileReadWriteTask(read_file_handle, blocking_queue)

    # Create the image writer
    if write_file_handle:
        # File or VMDK in VMware datastore is the image destination
        writer = FileReadWriteTask(blocking_queue, write_file_handle)
    elif image_service and image_id:
        # Image service image is the destination
        writer = ImageWriter(context,
                             blocking_queue,
                             image_service,
                             image_id,
                             image_meta)
    else:
        excep_msg = _("No image destination given.")
        LOG.error(excep_msg)
        raise ValueError(excep_msg)

    # Start the reader and writer
    LOG.debug("Starting image transfer with reader: %(reader)s and writer: "
              "%(writer)s",
              {'reader': reader,
               'writer': writer})
    reader.start()
    writer.start()
    timer = timeout.Timeout(timeout_secs)
    try:
        # Wait for the reader and writer to complete
        reader.wait()
        writer.wait()
    except (timeout.Timeout, exceptions.ImageTransferException) as excep:
        excep_msg = (_("Error occurred during image transfer with reader: "
                       "%(reader)s and writer: %(writer)s") %
                     {'reader': reader,
                      'writer': writer})
        LOG.exception(excep_msg)
        reader.stop()
        writer.stop()

        if isinstance(excep, exceptions.ImageTransferException):
            raise
        raise exceptions.ImageTransferException(excep_msg, excep)
    finally:
        timer.cancel()
        read_file_handle.close()
        if write_file_handle:
            write_file_handle.close()
示例#47
0
 def __init__(self, fault_list, message, cause=None, details=None):
     super(VimFaultException, self).__init__(message, cause, details)
     if not isinstance(fault_list, list):
         raise ValueError(_("fault_list must be a list"))
     self.fault_list = fault_list
示例#48
0
        def request_handler(managed_object, **kwargs):
            """Handler for vSphere API calls.

            Invokes the API and parses the response for fault checking and
            other errors.

            :param managed_object: managed object reference argument of the
                                   API call
            :param kwargs: keyword arguments of the API call
            :returns: response of the API call
            :raises: VimException, VimFaultException, VimAttributeException,
                     VimSessionOverLoadException, VimConnectionException
            """
            try:
                if isinstance(managed_object, str):
                    # For strings, use string value for value and type
                    # of the managed object.
                    managed_object = vim_util.get_moref(managed_object,
                                                        managed_object)
                if managed_object is None:
                    return
                request = getattr(self.client.service, attr_name)
                response = request(managed_object, **kwargs)
                if (attr_name.lower() == 'retrievepropertiesex'):
                    Service._retrieve_properties_ex_fault_checker(response)
                return response
            except exceptions.VimFaultException:
                # Catch the VimFaultException that is raised by the fault
                # check of the SOAP response.
                raise

            except suds.WebFault as excep:
                fault_string = None
                if excep.fault:
                    fault_string = excep.fault.faultstring

                doc = excep.document
                detail = None
                if doc is not None:
                    detail = doc.childAtPath('/detail')
                    if not detail:
                        # NOTE(arnaud): this is needed with VC 5.1
                        detail = doc.childAtPath('/Envelope/Body/Fault/detail')
                fault_list = []
                details = {}
                if detail:
                    for fault in detail.getChildren():
                        fault_type = fault.get('type')
                        if fault_type.endswith(exceptions.SECURITY_ERROR):
                            fault_type = exceptions.NOT_AUTHENTICATED
                        fault_list.append(fault_type)
                        for child in fault.getChildren():
                            details[child.name] = child.getText()
                raise exceptions.VimFaultException(fault_list, fault_string,
                                                   excep, details)

            except AttributeError as excep:
                raise exceptions.VimAttributeException(
                    _("No such SOAP method %s.") % attr_name, excep)

            except (httplib.CannotSendRequest,
                    httplib.ResponseNotReady,
                    httplib.CannotSendHeader) as excep:
                raise exceptions.VimSessionOverLoadException(
                    _("httplib error in %s.") % attr_name, excep)

            except requests.RequestException as excep:
                raise exceptions.VimConnectionException(
                    _("requests error in %s.") % attr_name, excep)

            except Exception as excep:
                # TODO(vbala) should catch specific exceptions and raise
                # appropriate VimExceptions.

                # Socket errors which need special handling; some of these
                # might be caused by server API call overload.
                if (six.text_type(excep).find(ADDRESS_IN_USE_ERROR) != -1 or
                        six.text_type(excep).find(CONN_ABORT_ERROR)) != -1:
                    raise exceptions.VimSessionOverLoadException(
                        _("Socket error in %s.") % attr_name, excep)
                # Type error which needs special handling; it might be caused
                # by server API call overload.
                elif six.text_type(excep).find(RESP_NOT_XML_ERROR) != -1:
                    raise exceptions.VimSessionOverLoadException(
                        _("Type error in %s.") % attr_name, excep)
                else:
                    raise exceptions.VimException(
                        _("Exception in %s.") % attr_name, excep)
示例#49
0
 def test_exception_summary_string(self):
     e = exceptions.VimException(_("string"), ValueError("foo"))
     string = str(e)
     self.assertEqual("string\nCause: foo", string)
示例#50
0
 def test_vim_fault_exception(self):
     vfe = exceptions.VimFaultException([ValueError("example")], _("cause"))
     string = str(vfe)
     self.assertEqual("cause\nFaults: [ValueError('example',)]", string)