diff --git a/.zuul.yaml b/.zuul.yaml index a9c3823d22dfbfadfe14cb8032b750d0d0401d73..ec981aad471603fef7c08b68a2f0ca71fe2deeaf 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -2,6 +2,6 @@ templates: - check-requirements - lib-forward-testing-python3 - - openstack-python3-yoga-jobs + - openstack-python3-zed-jobs - publish-openstack-docs-pti - release-notes-jobs-python3 diff --git a/doc/source/conf.py b/doc/source/conf.py index cc97524088cab3089e6bf7136209282a8201ee32..f187096f9ebfe203835486872c68a1126182fa85 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -33,7 +33,7 @@ openstackdocs_bug_tag = '' master_doc = 'index' # General information about the project. -copyright = u'2014, OpenStack Foundation' +copyright = '2014, OpenStack Foundation' # If true, '()' will be appended to :func: etc. cross-reference text. add_function_parentheses = True diff --git a/oslo_vmware/locale/en_GB/LC_MESSAGES/oslo_vmware.po b/oslo_vmware/locale/en_GB/LC_MESSAGES/oslo_vmware.po index e03de053b50ba5880a3eb294dc3bee9bc8bb3b34..8d2d5e587bbb4500e94b3abbd0420d47a953ec5b 100644 --- a/oslo_vmware/locale/en_GB/LC_MESSAGES/oslo_vmware.po +++ b/oslo_vmware/locale/en_GB/LC_MESSAGES/oslo_vmware.po @@ -2,15 +2,16 @@ # Andreas Jaeger , 2016. #zanata # Andi Chandler , 2017. #zanata # Andi Chandler , 2020. #zanata +# Andi Chandler , 2022. #zanata msgid "" msgstr "" "Project-Id-Version: oslo.vmware VERSION\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2020-09-22 12:46+0000\n" +"POT-Creation-Date: 2022-06-21 16:36+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2020-10-10 02:29+0000\n" +"PO-Revision-Date: 2022-07-05 09:38+0000\n" "Last-Translator: Andi Chandler \n" "Language-Team: English (United Kingdom)\n" "Language: en_GB\n" @@ -26,6 +27,10 @@ msgstr "Cannot delete file." msgid "Capacity is smaller than free space" msgstr "Capacity is smaller than free space" +#, python-format +msgid "Connection error occurred while reading data from %s." +msgstr "Connection error occurred while reading data from %s." + #, python-format msgid "Connection error occurred while writing data to %s." msgstr "Connection error occurred while writing data to %s." diff --git a/oslo_vmware/rw_handles.py b/oslo_vmware/rw_handles.py index a7b3e7256fec396e3f3162d7524b99dd450b46af..e988f2f6d195f9a50816ece4420b2c2e2aba8068 100644 --- a/oslo_vmware/rw_handles.py +++ b/oslo_vmware/rw_handles.py @@ -60,7 +60,7 @@ class FileHandle(object): self._file_handle = file_handle def _create_connection(self, url, method, cacerts=False, - ssl_thumbprint=None): + ssl_thumbprint=None, cookies=None): _urlparse = urlparse.urlparse(url) scheme, netloc, path, params, query, fragment = _urlparse if scheme == 'http': @@ -88,18 +88,20 @@ class FileHandle(object): if query: path = path + '?' + query conn.putrequest(method, path) + conn.putheader('User-Agent', USER_AGENT) + if cookies: + vim_cookie = self._build_vim_cookie_header(cookies) + conn.putheader('Cookie', vim_cookie) return conn 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 = self._create_connection(url, 'GET', cacerts, ssl_thumbprint, + cookies=cookies) conn.endheaders() - return conn.getresponse() + return conn except Exception as excep: # TODO(vbala) We need to catch and raise specific exceptions # related to connection problems, invalid request and invalid @@ -123,19 +125,13 @@ class FileHandle(object): 'url': url}) try: conn = self._create_connection(url, method, cacerts, - ssl_thumbprint) - headers = {'User-Agent': USER_AGENT} + ssl_thumbprint, cookies=cookies) if file_size: - headers.update({'Content-Length': str(file_size)}) + conn.putheader('Content-Length', str(file_size)) if overwrite: - headers.update({'Overwrite': overwrite}) - if cookies: - headers.update({'Cookie': - self._build_vim_cookie_header(cookies)}) + conn.putheader('Overwrite', overwrite) if content_type: - headers.update({'Content-Type': content_type}) - for key, value in headers.items(): - conn.putheader(key, value) + conn.putheader('Content-Type', content_type) conn.endheaders() return conn except requests.RequestException as excep: @@ -154,11 +150,12 @@ class FileHandle(object): def _build_vim_cookie_header(self, vim_cookies): """Build ESX host session cookie header.""" - cookie_header = "" + # As returned from DatastoreURL.get_transfer_ticket + if isinstance(vim_cookies, str): + return vim_cookies for vim_cookie in vim_cookies: - cookie_header = vim_cookie.name + '=' + vim_cookie.value - break - return cookie_header + return vim_cookie.name + '=' + vim_cookie.value + return "" def write(self, data): """Write data to the file. @@ -219,17 +216,21 @@ class FileHandle(object): class FileWriteHandle(FileHandle): """Write handle for a file in VMware server.""" - def __init__(self, host, port, data_center_name, datastore_name, cookies, - file_path, file_size, scheme='https', cacerts=False, + def __init__(self, host_or_url, port=None, data_center_name=None, + datastore_name=None, cookies=None, file_path=None, + file_size=None, scheme='https', cacerts=False, thumbprint=None): """Initializes the write handle with given parameters. - :param host: ESX/VC server IP address or host name + :param host_or_url: ESX/VC server IP address or host name or a complete + DatastoreURL :param port: port for connection :param data_center_name: name of the data center in the case of a VC server :param datastore_name: name of the datastore where the file is stored - :param cookies: cookies to build the vim cookie header + :param cookies: cookies to build the vim cookie header, or a string + with the prebuild vim cookie header + (See: DatastoreURL.get_transfer_ticket()) :param file_path: datastore path where the file is written :param file_size: size of the file in bytes :param scheme: protocol-- http or https @@ -237,10 +238,13 @@ class FileWriteHandle(FileHandle): :param thumbprint: expected SHA1 thumbprint of server's certificate :raises: VimConnectionException, ValueError """ - soap_url = self._get_soap_url(scheme, host, port) - param_list = {'dcPath': data_center_name, 'dsName': datastore_name} - self._url = '%s/folder/%s' % (soap_url, file_path) - self._url = self._url + '?' + urlparse.urlencode(param_list) + if not port and not data_center_name and not datastore_name: + self._url = host_or_url + else: + soap_url = self._get_soap_url(scheme, host_or_url, port) + param_list = {'dcPath': data_center_name, 'dsName': datastore_name} + self._url = '%s/folder/%s' % (soap_url, file_path) + self._url = self._url + '?' + urlparse.urlencode(param_list) self._conn = self._create_write_connection('PUT', self._url, @@ -286,6 +290,79 @@ class FileWriteHandle(FileHandle): return "File write handle for %s" % self._url +class FileReadHandle(FileHandle): + """Read handle for a file in VMware server.""" + + def __init__(self, host_or_url, port=None, data_center_name=None, + datastore_name=None, cookies=None, + file_path=None, scheme='https', cacerts=False, + thumbprint=None): + """Initializes the read handle with given parameters. + + :param host_or_url: ESX/VC server IP address or host name or a complete + DatastoreURL + :param port: port for connection + :param data_center_name: name of the data center in the case of a VC + server + :param datastore_name: name of the datastore where the file is stored + :param cookies: cookies to build the vim cookie header, or a string + with the prebuild vim cookie header + (See: DatastoreURL.get_transfer_ticket()) + :param file_path: datastore path where the file is written + :param scheme: protocol-- http or https + :param cacerts: CA bundle file to use for SSL verification + :param thumbprint: expected SHA1 thumbprint of server's certificate + :raises: VimConnectionException, ValueError + """ + if not port and not data_center_name and not datastore_name: + self._url = host_or_url + else: + soap_url = self._get_soap_url(scheme, host_or_url, port) + param_list = {'dcPath': data_center_name, 'dsName': datastore_name} + self._url = '%s/folder/%s' % (soap_url, file_path) + self._url = self._url + '?' + urlparse.urlencode(param_list) + + self._conn = self._create_read_connection(self._url, + cookies=cookies, + cacerts=cacerts, + ssl_thumbprint=thumbprint) + FileHandle.__init__(self, self._conn.getresponse()) + + def read(self, length): + """Read data from the file. + :param length: amount of data to be read + :raises: VimConnectionException, VimException + """ + try: + return self._file_handle.read(length) + except requests.RequestException as excep: + excep_msg = _("Connection error occurred while reading data from" + " %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 close(self): + """Closes the connection. + """ + self._conn.close() + super(FileReadHandle, self).close() + LOG.debug("Closed File read handle for %s.", self._url) + + def get_size(self): + return self._file_handle.getheader('Content-Length') + + def __str__(self): + return "File read handle for %s" % self._url + + class VmdkHandle(FileHandle): """VMDK handle based on HttpNfcLease.""" @@ -608,7 +685,8 @@ class VmdkReadHandle(VmdkHandle): self._conn = self._create_read_connection(url, cookies=cookies, ssl_thumbprint=thumbprint) - super(VmdkReadHandle, self).__init__(session, lease, url, self._conn) + super(VmdkReadHandle, self).__init__(session, lease, url, + self._conn.getresponse()) def read(self, chunk_size=READ_CHUNKSIZE): """Read a chunk of data from the VMDK file. @@ -639,6 +717,7 @@ class VmdkReadHandle(VmdkHandle): :raises: VimException, VimFaultException, VimAttributeException, VimSessionOverLoadException, VimConnectionException """ + self._conn.close() try: self._release_lease() except exceptions.ManagedObjectNotFoundException: diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst index 7200d329647c2d590c43fb89dd661f48fb5941f0..0da24e2114018359ca33d12d9574ee465dca5875 100644 --- a/releasenotes/source/index.rst +++ b/releasenotes/source/index.rst @@ -2,18 +2,19 @@ oslo.vmware Release Notes =========================== - .. toctree:: - :maxdepth: 1 +.. toctree:: + :maxdepth: 1 - unreleased - xena - wallaby - victoria - ussuri - train - stein - rocky - queens - pike - ocata - newton + unreleased + yoga + xena + wallaby + victoria + ussuri + train + stein + rocky + queens + pike + ocata + newton diff --git a/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po b/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po index 2e1db4a6ce2ea593b74fe12287019dcdea2f62e6..fd8edda64a4cde8d5f06850b97365671467d0518 100644 --- a/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po +++ b/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po @@ -2,15 +2,16 @@ # Andi Chandler , 2017. #zanata # Andi Chandler , 2018. #zanata # Andi Chandler , 2020. #zanata +# Andi Chandler , 2022. #zanata msgid "" msgstr "" "Project-Id-Version: oslo.vmware Release Notes\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-22 12:46+0000\n" +"POT-Creation-Date: 2022-05-11 15:56+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2020-10-10 02:29+0000\n" +"PO-Revision-Date: 2022-06-10 09:18+0000\n" "Last-Translator: Andi Chandler \n" "Language-Team: English (United Kingdom)\n" "Language: en_GB\n" @@ -103,6 +104,15 @@ msgstr "Ussuri Series Release Notes" msgid "Victoria Series Release Notes" msgstr "Victoria Series Release Notes" +msgid "Wallaby Series Release Notes" +msgstr "Wallaby Series Release Notes" + +msgid "Xena Series Release Notes" +msgstr "Xena Series Release Notes" + +msgid "Yoga Series Release Notes" +msgstr "Yoga Series Release Notes" + msgid "" "``ManagedObjectReference``'s ``value`` and ``_type`` attributes must not be " "used anymore in depending projects. Instead, ``vim_util.get_moref_value()`` " diff --git a/releasenotes/source/yoga.rst b/releasenotes/source/yoga.rst new file mode 100644 index 0000000000000000000000000000000000000000..7cd5e908a7de01e943ed55fdd485eb0e393ba1c3 --- /dev/null +++ b/releasenotes/source/yoga.rst @@ -0,0 +1,6 @@ +========================= +Yoga Series Release Notes +========================= + +.. release-notes:: + :branch: stable/yoga diff --git a/setup.cfg b/setup.cfg index 1f6663a77ca6f7899dab85c8d70726c6a04a5874..2ee470238301012ba62c230cf9bd3eb9ebe4ea04 100644 --- a/setup.cfg +++ b/setup.cfg @@ -6,7 +6,7 @@ description_file = author = OpenStack author_email = openstack-discuss@lists.openstack.org home_page = https://docs.openstack.org/oslo.vmware/latest/ -python_requires = >=3.6 +python_requires = >=3.8 classifier = Environment :: OpenStack Intended Audience :: Information Technology @@ -15,9 +15,8 @@ classifier = Operating System :: POSIX :: Linux Programming Language :: Python Programming Language :: Python :: 3 - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 Programming Language :: Python :: 3 :: Only Programming Language :: Python :: Implementation :: CPython