summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.zuul.yaml2
-rw-r--r--glance_store/_drivers/cinder.py10
-rw-r--r--glance_store/_drivers/http.py13
-rw-r--r--glance_store/_drivers/swift/utils.py31
-rw-r--r--glance_store/tests/etc/glance-swift.conf16
-rw-r--r--glance_store/tests/unit/common/test_cinder_utils.py1
-rw-r--r--glance_store/tests/unit/test_cinder_base.py27
-rw-r--r--glance_store/tests/unit/test_http_store.py9
-rw-r--r--glance_store/tests/unit/test_swift_store.py71
-rw-r--r--glance_store/tests/unit/test_swift_store_multibackend.py71
-rw-r--r--glance_store/tests/unit/test_swift_store_utils.py25
-rw-r--r--releasenotes/notes/bug-1620999-8b76a0ad14826197.yaml7
-rw-r--r--releasenotes/source/index.rst1
-rw-r--r--releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po120
-rw-r--r--releasenotes/source/zed.rst6
15 files changed, 371 insertions, 39 deletions
diff --git a/.zuul.yaml b/.zuul.yaml
index 95243df..11ddd58 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -149,7 +149,7 @@
templates:
- check-requirements
- lib-forward-testing-python3
- - openstack-python3-zed-jobs
+ - openstack-python3-jobs
- publish-openstack-docs-pti
- release-notes-jobs-python3
check:
diff --git a/glance_store/_drivers/cinder.py b/glance_store/_drivers/cinder.py
index 8a50862..3509348 100644
--- a/glance_store/_drivers/cinder.py
+++ b/glance_store/_drivers/cinder.py
@@ -30,6 +30,7 @@ from keystoneauth1 import session as ksa_session
from keystoneauth1 import token_endpoint as ksa_token_endpoint
from oslo_concurrency import processutils
from oslo_config import cfg
+from oslo_utils import strutils
from oslo_utils import units
from glance_store import capabilities
@@ -747,9 +748,16 @@ class Store(glance_store.driver.Store):
else:
attachment = self.volume_api.attachment_create(client, volume_id,
mode=attach_mode)
+ LOG.debug('Attachment %(attachment_id)s created successfully.',
+ {'attachment_id': attachment['id']})
attachment = self.volume_api.attachment_update(
client, attachment['id'], connector_prop,
mountpoint='glance_store')
+ LOG.debug('Attachment %(attachment_id)s updated successfully with '
+ 'connection info %(conn_info)s',
+ {'attachment_id': attachment.id,
+ 'conn_info': strutils.mask_dict_password(
+ attachment.connection_info)})
volume = volume.manager.get(volume_id)
connection_info = attachment.connection_info
@@ -794,6 +802,8 @@ class Store(glance_store.driver.Store):
# Complete the attachment (marking the volume "in-use") after
# the connection with os-brick is complete
self.volume_api.attachment_complete(client, attachment.id)
+ LOG.debug('Attachment %(attachment_id)s completed successfully.',
+ {'attachment_id': attachment.id})
if (connection_info['driver_volume_type'] == 'rbd' and
not conn.do_local_attach):
yield device['path']
diff --git a/glance_store/_drivers/http.py b/glance_store/_drivers/http.py
index 79d3ab7..0d55e4b 100644
--- a/glance_store/_drivers/http.py
+++ b/glance_store/_drivers/http.py
@@ -105,18 +105,26 @@ class StoreLocation(glance_store.location.StoreLocation):
self.user = self.specs.get('user')
self.password = self.specs.get('password')
self.path = self.specs.get('path')
+ self.query = self.spec.get('query')
def _get_credstring(self):
if self.user:
return '%s:%s@' % (self.user, self.password)
return ''
+ def _get_query_string(self):
+ if self.query:
+ return "?%s" % self.query
+ return ""
+
def get_uri(self):
- return "%s://%s%s%s" % (
+ return "%s://%s%s%s%s" % (
self.scheme,
self._get_credstring(),
self.netloc,
- self.path)
+ self.path,
+ self._get_query_string()
+ )
def parse_uri(self, uri):
"""
@@ -164,6 +172,7 @@ class StoreLocation(glance_store.location.StoreLocation):
self.netloc = netloc
self.path = path
+ self.query = pieces.query
def http_response_iterator(conn, response, size):
diff --git a/glance_store/_drivers/swift/utils.py b/glance_store/_drivers/swift/utils.py
index da034b4..812ef2f 100644
--- a/glance_store/_drivers/swift/utils.py
+++ b/glance_store/_drivers/swift/utils.py
@@ -98,11 +98,6 @@ Related options:
"""),
]
-_config_defaults = {'user_domain_id': 'default',
- 'user_domain_name': 'default',
- 'project_domain_id': 'default',
- 'project_domain_name': 'default'}
-
class SwiftConfigParser(configparser.ConfigParser):
@@ -121,7 +116,7 @@ class SwiftConfigParser(configparser.ConfigParser):
return value
-CONFIG = SwiftConfigParser(defaults=_config_defaults)
+CONFIG = SwiftConfigParser()
LOG = logging.getLogger(__name__)
@@ -193,15 +188,25 @@ class SwiftParams(object):
for ref in account_references:
reference = {}
try:
- for param in ('auth_address',
- 'user',
- 'key',
- 'project_domain_id',
- 'project_domain_name',
- 'user_domain_id',
- 'user_domain_name'):
+ for param in ('auth_address', 'user', 'key'):
reference[param] = CONFIG.get(ref, param)
+ reference['project_domain_name'] = CONFIG.get(
+ ref, 'project_domain_name', fallback=None)
+ reference['project_domain_id'] = CONFIG.get(
+ ref, 'project_domain_id', fallback=None)
+ if (reference['project_domain_name'] is None and
+ reference['project_domain_id'] is None):
+ reference['project_domain_id'] = 'default'
+
+ reference['user_domain_name'] = CONFIG.get(
+ ref, 'user_domain_name', fallback=None)
+ reference['user_domain_id'] = CONFIG.get(
+ ref, 'user_domain_id', fallback=None)
+ if (reference['user_domain_name'] is None and
+ reference['user_domain_id'] is None):
+ reference['user_domain_id'] = 'default'
+
try:
reference['auth_version'] = CONFIG.get(ref, 'auth_version')
except configparser.NoOptionError:
diff --git a/glance_store/tests/etc/glance-swift.conf b/glance_store/tests/etc/glance-swift.conf
index 916d676..47f53f3 100644
--- a/glance_store/tests/etc/glance-swift.conf
+++ b/glance_store/tests/etc/glance-swift.conf
@@ -16,6 +16,22 @@ user = "user3"
key = "key3"
auth_address = "http://example.com"
+[ref4]
+user = user4
+key = key4
+user_domain_id = userdomainid
+project_domain_id = projdomainid
+auth_version = 3
+auth_address = "http://example.com"
+
+[ref5]
+user = user5
+key = key5
+user_domain_name = userdomain
+project_domain_name = projdomain
+auth_version = 3
+auth_address = "http://example.com"
+
[store_2]
user = tenant:user1
key = key1
diff --git a/glance_store/tests/unit/common/test_cinder_utils.py b/glance_store/tests/unit/common/test_cinder_utils.py
index 2f68afb..a7d982f 100644
--- a/glance_store/tests/unit/common/test_cinder_utils.py
+++ b/glance_store/tests/unit/common/test_cinder_utils.py
@@ -74,6 +74,7 @@ class CinderUtilsTestCase(base.BaseTestCase):
self.volume_api.attachment_create,
self.fake_client, self.fake_vol_id)
+ @mock.patch('time.sleep', new=mock.Mock())
def test_attachment_create_retries(self):
fake_attach_id = 'fake-attach-id'
diff --git a/glance_store/tests/unit/test_cinder_base.py b/glance_store/tests/unit/test_cinder_base.py
index d9e6c2d..c602549 100644
--- a/glance_store/tests/unit/test_cinder_base.py
+++ b/glance_store/tests/unit/test_cinder_base.py
@@ -277,7 +277,8 @@ class TestCinderStoreBase(object):
mock.patch.object(socket,
'gethostname') as mock_get_host, \
mock.patch.object(socket,
- 'getaddrinfo') as mock_get_host_ip:
+ 'getaddrinfo') as mock_get_host_ip, \
+ mock.patch.object(cinder.strutils, 'mask_dict_password'):
fake_host = 'fake_host'
fake_addr_info = [[0, 1, 2, 3, ['127.0.0.1']]]
@@ -590,7 +591,11 @@ class TestCinderStoreBase(object):
expected_multihash = 'fake_hash'
fakebuffer = mock.MagicMock()
- fakebuffer.__len__.return_value = expected_volume_size
+
+ # CPython implementation detail: __len__ cannot return > sys.maxsize,
+ # which on a 32-bit system is 2*units.Gi - 1
+ # https://docs.python.org/3/reference/datamodel.html#object.__len__
+ fakebuffer.__len__.return_value = int(expected_volume_size / 2)
def get_fake_hash(type, secure=False):
if type == 'md5':
@@ -602,7 +607,7 @@ class TestCinderStoreBase(object):
expected_volume_id = str(uuid.uuid4())
expected_size = 0
image_file = mock.MagicMock(
- read=mock.MagicMock(side_effect=[fakebuffer, None]))
+ read=mock.MagicMock(side_effect=[fakebuffer, fakebuffer, None]))
fake_volume = mock.MagicMock(id=expected_volume_id, status='available',
size=1)
expected_checksum = 'fake_checksum'
@@ -666,13 +671,17 @@ class TestCinderStoreBase(object):
expected_volume_size = 2 * units.Gi
fakebuffer = mock.MagicMock()
- fakebuffer.__len__.return_value = expected_volume_size
+
+ # CPython implementation detail: __len__ cannot return > sys.maxsize,
+ # which on a 32-bit system is 2*units.Gi - 1
+ # https://docs.python.org/3/reference/datamodel.html#object.__len__
+ fakebuffer.__len__.return_value = int(expected_volume_size / 2)
expected_image_id = str(uuid.uuid4())
expected_volume_id = str(uuid.uuid4())
expected_size = 0
image_file = mock.MagicMock(
- read=mock.MagicMock(side_effect=[fakebuffer, None]))
+ read=mock.MagicMock(side_effect=[fakebuffer, fakebuffer, None]))
fake_volume = mock.MagicMock(id=expected_volume_id, status='available',
size=1)
verifier = None
@@ -703,13 +712,17 @@ class TestCinderStoreBase(object):
expected_volume_size = 2 * units.Gi
fakebuffer = mock.MagicMock()
- fakebuffer.__len__.return_value = expected_volume_size
+
+ # CPython implementation detail: __len__ cannot return > sys.maxsize,
+ # which on a 32-bit system is 2*units.Gi - 1
+ # https://docs.python.org/3/reference/datamodel.html#object.__len__
+ fakebuffer.__len__.return_value = int(expected_volume_size / 2)
expected_image_id = str(uuid.uuid4())
expected_volume_id = str(uuid.uuid4())
expected_size = 0
image_file = mock.MagicMock(
- read=mock.MagicMock(side_effect=[fakebuffer, None]))
+ read=mock.MagicMock(side_effect=[fakebuffer, fakebuffer, None]))
fake_volume = mock.MagicMock(
id=expected_volume_id, status='available', size=1,
delete=mock.MagicMock(side_effect=Exception()))
diff --git a/glance_store/tests/unit/test_http_store.py b/glance_store/tests/unit/test_http_store.py
index 4eafb88..ca3a9c6 100644
--- a/glance_store/tests/unit/test_http_store.py
+++ b/glance_store/tests/unit/test_http_store.py
@@ -184,6 +184,15 @@ class TestHttpStore(base.StoreBaseTest,
self.assertRaises(exceptions.BadStoreUri,
location.get_location_from_uri, uri)
+ def test_http_store_location_get_uri(self):
+ """Test for HTTP URI with and without query"""
+ uris = ["http://netloc/path/to/file.tar.gz"
+ "http://netloc/path/to/file.tar.gz?query=text",
+ ]
+ for uri in uris:
+ loc = location.get_location_from_uri(uri, conf=self.conf)
+ self.assertEqual(uri, loc.store_location.get_uri())
+
def test_http_get_raises_remote_service_unavailable(self):
"""Test http store raises RemoteServiceUnavailable."""
uri = "http://netloc/path/to/file.tar.gz"
diff --git a/glance_store/tests/unit/test_swift_store.py b/glance_store/tests/unit/test_swift_store.py
index eb57138..2c21752 100644
--- a/glance_store/tests/unit/test_swift_store.py
+++ b/glance_store/tests/unit/test_swift_store.py
@@ -1462,15 +1462,72 @@ class TestStoreAuthV3(TestStoreAuthV1):
loc = location.get_location_from_uri(uri, conf=self.conf)
ctxt = mock.MagicMock()
store.init_client(location=loc.store_location, context=ctxt)
- # check that keystone was initialized correctly
- tenant = None if store.auth_version == '1' else "tenant"
- username = "tenant:user1" if store.auth_version == '1' else "user1"
mock_identity.V3Password.assert_called_once_with(
auth_url=loc.store_location.swift_url + '/',
- username=username, password="key",
- project_name=tenant,
- project_domain_id='default', project_domain_name='default',
- user_domain_id='default', user_domain_name='default',)
+ username="user1", password="key",
+ project_name="tenant",
+ project_domain_id='default', project_domain_name=None,
+ user_domain_id='default', user_domain_name=None,)
+ mock_session.Session.assert_called_once_with(
+ auth=mock_identity.V3Password(), verify=True)
+ mock_client.Client.assert_called_once_with(
+ session=mock_session.Session())
+
+ @mock.patch("glance_store._drivers.swift.store.ks_identity")
+ @mock.patch("glance_store._drivers.swift.store.ks_session")
+ @mock.patch("glance_store._drivers.swift.store.ks_client")
+ def test_init_client_single_tenant_with_domain_ids(self,
+ mock_client,
+ mock_session,
+ mock_identity):
+ """Test that keystone client was initialized correctly"""
+ # initialize client
+ conf = self.getConfig()
+ conf['default_swift_reference'] = 'ref4'
+ self.config(**conf)
+ store = Store(self.conf)
+ store.configure()
+ uri = "swift://%s:key@auth_address/glance/%s" % (
+ self.swift_store_user, FAKE_UUID)
+ loc = location.get_location_from_uri(uri, conf=self.conf)
+ ctxt = mock.MagicMock()
+ store.init_client(location=loc.store_location, context=ctxt)
+ mock_identity.V3Password.assert_called_once_with(
+ auth_url=loc.store_location.swift_url + '/',
+ username="user1", password="key",
+ project_name="tenant",
+ project_domain_id='projdomainid', project_domain_name=None,
+ user_domain_id='userdomainid', user_domain_name=None,)
+ mock_session.Session.assert_called_once_with(
+ auth=mock_identity.V3Password(), verify=True)
+ mock_client.Client.assert_called_once_with(
+ session=mock_session.Session())
+
+ @mock.patch("glance_store._drivers.swift.store.ks_identity")
+ @mock.patch("glance_store._drivers.swift.store.ks_session")
+ @mock.patch("glance_store._drivers.swift.store.ks_client")
+ def test_init_client_single_tenant_with_domain_names(self,
+ mock_client,
+ mock_session,
+ mock_identity):
+ """Test that keystone client was initialized correctly"""
+ # initialize client
+ conf = self.getConfig()
+ conf['default_swift_reference'] = 'ref5'
+ self.config(**conf)
+ store = Store(self.conf)
+ store.configure()
+ uri = "swift://%s:key@auth_address/glance/%s" % (
+ self.swift_store_user, FAKE_UUID)
+ loc = location.get_location_from_uri(uri, conf=self.conf)
+ ctxt = mock.MagicMock()
+ store.init_client(location=loc.store_location, context=ctxt)
+ mock_identity.V3Password.assert_called_once_with(
+ auth_url=loc.store_location.swift_url + '/',
+ username="user1", password="key",
+ project_name="tenant",
+ project_domain_id=None, project_domain_name='projdomain',
+ user_domain_id=None, user_domain_name='userdomain',)
mock_session.Session.assert_called_once_with(
auth=mock_identity.V3Password(), verify=True)
mock_client.Client.assert_called_once_with(
diff --git a/glance_store/tests/unit/test_swift_store_multibackend.py b/glance_store/tests/unit/test_swift_store_multibackend.py
index 10b5c46..d8bfcf7 100644
--- a/glance_store/tests/unit/test_swift_store_multibackend.py
+++ b/glance_store/tests/unit/test_swift_store_multibackend.py
@@ -1459,15 +1459,72 @@ class TestStoreAuthV3(TestStoreAuthV1):
uri, "swift1", conf=self.conf)
ctxt = mock.MagicMock()
store.init_client(location=loc.store_location, context=ctxt)
- # check that keystone was initialized correctly
- tenant = None if store.auth_version == '1' else "tenant"
- username = "tenant:user1" if store.auth_version == '1' else "user1"
mock_identity.V3Password.assert_called_once_with(
auth_url=loc.store_location.swift_url + '/',
- username=username, password="key",
- project_name=tenant,
- project_domain_id='default', project_domain_name='default',
- user_domain_id='default', user_domain_name='default',)
+ username="user1", password="key",
+ project_name="tenant",
+ project_domain_id='default', project_domain_name=None,
+ user_domain_id='default', user_domain_name=None,)
+ mock_session.Session.assert_called_once_with(
+ auth=mock_identity.V3Password(), verify=True)
+ mock_client.Client.assert_called_once_with(
+ session=mock_session.Session())
+
+ @mock.patch("glance_store._drivers.swift.store.ks_identity")
+ @mock.patch("glance_store._drivers.swift.store.ks_session")
+ @mock.patch("glance_store._drivers.swift.store.ks_client")
+ def test_init_client_single_tenant_with_domain_ids(self,
+ mock_client,
+ mock_session,
+ mock_identity):
+ """Test that keystone client was initialized correctly"""
+ conf = self.getConfig()
+ conf['default_swift_reference'] = 'ref4'
+ self.config(group="swift1", **conf)
+ store = Store(self.conf, backend="swift1")
+ store.configure()
+ uri = "swift://%s:key@auth_address/glance/%s" % (
+ self.swift_store_user, FAKE_UUID)
+ loc = location.get_location_from_uri_and_backend(
+ uri, "swift1", conf=self.conf)
+ ctxt = mock.MagicMock()
+ store.init_client(location=loc.store_location, context=ctxt)
+ mock_identity.V3Password.assert_called_once_with(
+ auth_url=loc.store_location.swift_url + '/',
+ username="user1", password="key",
+ project_name="tenant",
+ project_domain_id='projdomainid', project_domain_name=None,
+ user_domain_id='userdomainid', user_domain_name=None)
+ mock_session.Session.assert_called_once_with(
+ auth=mock_identity.V3Password(), verify=True)
+ mock_client.Client.assert_called_once_with(
+ session=mock_session.Session())
+
+ @mock.patch("glance_store._drivers.swift.store.ks_identity")
+ @mock.patch("glance_store._drivers.swift.store.ks_session")
+ @mock.patch("glance_store._drivers.swift.store.ks_client")
+ def test_init_client_single_tenant_with_domain_names(self,
+ mock_client,
+ mock_session,
+ mock_identity):
+ """Test that keystone client was initialized correctly"""
+ conf = self.getConfig()
+ conf['default_swift_reference'] = 'ref5'
+ self.config(group="swift1", **conf)
+ store = Store(self.conf, backend="swift1")
+ store.configure()
+ uri = "swift://%s:key@auth_address/glance/%s" % (
+ self.swift_store_user, FAKE_UUID)
+ loc = location.get_location_from_uri_and_backend(
+ uri, "swift1", conf=self.conf)
+ ctxt = mock.MagicMock()
+ store.init_client(location=loc.store_location, context=ctxt)
+ mock_identity.V3Password.assert_called_once_with(
+ auth_url=loc.store_location.swift_url + '/',
+ username="user1", password="key",
+ project_name="tenant",
+ project_domain_id=None, project_domain_name='projdomain',
+ user_domain_id=None, user_domain_name='userdomain')
mock_session.Session.assert_called_once_with(
auth=mock_identity.V3Password(), verify=True)
mock_client.Client.assert_called_once_with(
diff --git a/glance_store/tests/unit/test_swift_store_utils.py b/glance_store/tests/unit/test_swift_store_utils.py
index 94079ae..b7b25f7 100644
--- a/glance_store/tests/unit/test_swift_store_utils.py
+++ b/glance_store/tests/unit/test_swift_store_utils.py
@@ -98,6 +98,31 @@ class TestSwiftParams(base.StoreBaseTest):
swift_params['ref3']['auth_address']
)
+ def test_swift_store_config_without_domain(self):
+ swift_params = sutils.SwiftParams(self.conf).params
+ self.assertEqual('default', swift_params['ref1']['project_domain_id'])
+ self.assertIsNone(swift_params['ref1']['project_domain_name'])
+ self.assertEqual('default', swift_params['ref1']['user_domain_id'])
+ self.assertIsNone(swift_params['ref1']['user_domain_name'])
+
+ def test_swift_store_config_with_domain_ids(self):
+ swift_params = sutils.SwiftParams(self.conf).params
+ self.assertEqual('projdomainid',
+ swift_params['ref4']['project_domain_id'])
+ self.assertIsNone(swift_params['ref4']['project_domain_name'])
+ self.assertEqual('userdomainid',
+ swift_params['ref4']['user_domain_id'])
+ self.assertIsNone(swift_params['ref4']['user_domain_name'])
+
+ def test_swift_store_config_with_domain_names(self):
+ swift_params = sutils.SwiftParams(self.conf).params
+ self.assertIsNone(swift_params['ref5']['project_domain_id'])
+ self.assertEqual('projdomain',
+ swift_params['ref5']['project_domain_name'])
+ self.assertIsNone(swift_params['ref5']['user_domain_id'])
+ self.assertEqual('userdomain',
+ swift_params['ref5']['user_domain_name'])
+
class TestSwiftConfigParser(base.StoreBaseTest):
diff --git a/releasenotes/notes/bug-1620999-8b76a0ad14826197.yaml b/releasenotes/notes/bug-1620999-8b76a0ad14826197.yaml
new file mode 100644
index 0000000..7f5ae6e
--- /dev/null
+++ b/releasenotes/notes/bug-1620999-8b76a0ad14826197.yaml
@@ -0,0 +1,7 @@
+---
+fixes:
+ - |
+ Now the ``project_domain_name`` parameter and the ``user_domain_name``
+ parameter are properly used by swift backends. Previously these two
+ parameters were ignored and the ``*_domain_id`` parameters should be
+ set to use a keystone domain different from the default one.
diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst
index 81684b2..a77eb2d 100644
--- a/releasenotes/source/index.rst
+++ b/releasenotes/source/index.rst
@@ -6,6 +6,7 @@
:maxdepth: 1
unreleased
+ zed
yoga
xena
wallaby
diff --git a/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po b/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po
index 0690bdc..5d3712e 100644
--- a/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po
+++ b/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po
@@ -4,15 +4,16 @@
# Andi Chandler <andi@gowling.com>, 2019. #zanata
# Andi Chandler <andi@gowling.com>, 2020. #zanata
# Andi Chandler <andi@gowling.com>, 2021. #zanata
+# Andi Chandler <andi@gowling.com>, 2022. #zanata
msgid ""
msgstr ""
"Project-Id-Version: Glance_store Release Notes\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-12-10 18:01+0000\n"
+"POT-Creation-Date: 2022-09-12 22:27+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"PO-Revision-Date: 2021-09-18 07:44+0000\n"
+"PO-Revision-Date: 2022-09-15 08:54+0000\n"
"Last-Translator: Andi Chandler <andi@gowling.com>\n"
"Language-Team: English (United Kingdom)\n"
"Language: en_GB\n"
@@ -96,12 +97,33 @@ msgstr "2.3.0"
msgid "2.5.0"
msgstr "2.5.0"
+msgid "2.5.1"
+msgstr "2.5.1"
+
msgid "2.6.0"
msgstr "2.6.0"
msgid "2.7.0"
msgstr "2.7.0"
+msgid "2.7.1"
+msgstr "2.7.1"
+
+msgid "3.0.0"
+msgstr "3.0.0"
+
+msgid "3.0.0-4"
+msgstr "3.0.0-4"
+
+msgid "4.0.0"
+msgstr "4.0.0"
+
+msgid "4.0.1"
+msgstr "4.0.1"
+
+msgid "4.1.0"
+msgstr "4.1.0"
+
msgid ""
"A `BufferedReader`_ has been added to the Swift store driver in order to "
"enable better recovery from errors during uploads of large image files. "
@@ -341,6 +363,9 @@ msgstr ""
msgid "Bug 1934849_: s3 backend takes time exponentially"
msgstr "Bug 1934849_: s3 backend takes time exponentially"
+msgid "Bug 1954883_: [RBD] Image is unusable if deletion fails"
+msgstr "Bug 1954883_: [RBD] Image is unusable if deletion fails"
+
msgid "Bug Fixes"
msgstr "Bug Fixes"
@@ -379,6 +404,17 @@ msgstr ""
"``volumev2::publicURL`` to ``volumev3::publicURL``, so that the current v3 "
"API is used by default instead of the deprecated v2 API."
+msgid ""
+"Deployments which are using Ceph V2 clone feature (i.e. RBD backend for "
+"glance_store as well as cinder driver is RBD or nova is using RBD driver) "
+"and minimum ceph client version is greater than 'luminous' need to grant "
+"glance osd read access to the cinder and nova RBD pool."
+msgstr ""
+"Deployments which are using Ceph V2 clone feature (i.e. RBD backend for "
+"glance_store as well as Cinder driver is RBD or Nova is using the RBD "
+"driver) and minimum Ceph client version is greater than 'luminous' need to "
+"grant Glance OSD read access to the Cinder and Nova RBD pool."
+
msgid "Deprecation Notes"
msgstr "Deprecation Notes"
@@ -566,6 +602,17 @@ msgstr "New Features"
msgid "Newton Series Release Notes"
msgstr "Newton Series Release Notes"
+msgid ""
+"Now the ``project_domain_name`` parameter and the ``user_domain_name`` "
+"parameter are properly used by swift backends. Previously these two "
+"parameters were ignored and the ``*_domain_id`` parameters should be set to "
+"use a keystone domain different from the default one."
+msgstr ""
+"Now the ``project_domain_name`` parameter and the ``user_domain_name`` "
+"parameter are properly used by Swift backends. Previously these two "
+"parameters were ignored and the ``*_domain_id`` parameters should be set to "
+"use a Keystone domain different from the default one."
+
msgid "Ocata Series Release Notes"
msgstr "Ocata Series Release Notes"
@@ -634,6 +681,13 @@ msgstr ""
"py2.7 is OpenStack Train. The minimum version of Python now supported by "
"glance_store is Python 3.6."
+msgid ""
+"Python 3.6 & 3.7 support has been dropped. The minimum version of Python now "
+"supported is Python 3.8."
+msgstr ""
+"Python 3.6 & 3.7 support has been dropped. The minimum version of Python now "
+"supported is Python 3.8."
+
msgid "Queens Series Release Notes"
msgstr "Queens Series Release Notes"
@@ -1053,9 +1107,35 @@ msgstr "Victoria Series Release Notes"
msgid "Wallaby Series Release Notes"
msgstr "Wallaby Series Release Notes"
+msgid ""
+"When running Cinder and Glance with Cinder backend on the same host an os-"
+"brick shared location can be configured using the ``lock_path`` in the "
+"``[os_brick]`` configuration section."
+msgstr ""
+"When running Cinder and Glance with Cinder backend on the same host an os-"
+"brick shared location can be configured using the ``lock_path`` in the "
+"``[os_brick]`` configuration section."
+
+msgid ""
+"When using the cinder backend, a custom os-brick file lock location can be "
+"specified using the ``lock_path`` configuration option in the ``[os_brick]`` "
+"configuration section. Helpful when deploying on the same host as the "
+"Cinder service."
+msgstr ""
+"When using the Cinder backend, a custom os-brick file lock location can be "
+"specified using the ``lock_path`` configuration option in the ``[os_brick]`` "
+"configuration section. Helpful when deploying on the same host as the "
+"Cinder service."
+
msgid "Xena Series Release Notes"
msgstr "Xena Series Release Notes"
+msgid "Yoga Series Release Notes"
+msgstr "Yoga Series Release Notes"
+
+msgid "Zed Series Release Notes"
+msgstr "Zed Series Release Notes"
+
msgid ""
"`Add python 3.5 in classifier and envlist <https://git.openstack.org/cgit/"
"openstack/glance_store/commit/?id=963e2a0fd1c173556a2c40915ad26db28d8375a6>`_"
@@ -1092,6 +1172,42 @@ msgstr ""
"invalid volume type is configured."
msgid ""
+"`Bug #1955668 <https://bugs.launchpad.net/glance-store/+bug/1955668>`_: "
+"Fixed issue with glance cinder store passing hostname instead of IP address "
+"to os-brick while getting connector information."
+msgstr ""
+"`Bug #1955668 <https://bugs.launchpad.net/glance-store/+bug/1955668>`_: "
+"Fixed issue with glance cinder store passing hostname instead of IP address "
+"to os-brick while getting connector information."
+
+msgid ""
+"`Bug #1959913 <https://bugs.launchpad.net/glance-store/+bug/1959913>`_: "
+"Added wait between the volume being extended and the new size being detected "
+"while opening the volume device."
+msgstr ""
+"`Bug #1959913 <https://bugs.launchpad.net/glance-store/+bug/1959913>`_: "
+"Added wait between the volume being extended and the new size being detected "
+"while opening the volume device."
+
+msgid ""
+"`Bug #1969373 <https://bugs.launchpad.net/glance-store/+bug/1969373>`_: "
+"Cinder Driver: Correct the retry interval from fixed 1 second to exponential "
+"backoff for attaching a volume during image create/save operation."
+msgstr ""
+"`Bug #1969373 <https://bugs.launchpad.net/glance-store/+bug/1969373>`_: "
+"Cinder Driver: Correct the retry interval from fixed 1 second to exponential "
+"backoff for attaching a volume during image create/save operation."
+
+msgid ""
+"`Bug #1970698 <https://bugs.launchpad.net/glance-store/+bug/1970698>`_: "
+"Cinder: Fixed exception logging when the image create operation fails due to "
+"failing to attach volume to glance host."
+msgstr ""
+"`Bug #1970698 <https://bugs.launchpad.net/glance-store/+bug/1970698>`_: "
+"Cinder: Fixed exception logging when the image create operation fails due to "
+"failing to attach the volume to a Glance host."
+
+msgid ""
"`Correct error msg variable that could be unassigned <https://git.openstack."
"org/cgit/openstack/glance_store/commit/?"
"id=ccc9696e3f071383cd05d88ba2488f5a5ee98120>`_"
diff --git a/releasenotes/source/zed.rst b/releasenotes/source/zed.rst
new file mode 100644
index 0000000..9608c05
--- /dev/null
+++ b/releasenotes/source/zed.rst
@@ -0,0 +1,6 @@
+========================
+Zed Series Release Notes
+========================
+
+.. release-notes::
+ :branch: stable/zed