Skip to content

Commit

Permalink
Fix duplicate entries in share_server_backend_details
Browse files Browse the repository at this point in the history
share_server_backend_details_set() add entries in db table without
checking existing entries with given combinaton of share_server_id
and key. This causes duplicate records. Fix it by validating presence
of share server id and key.

Closes-bug: #2024658
Change-Id: I58dcd9716cf95d0d696c13a4c831df787726bcda
(cherry picked from commit 37278df)
(cherry picked from commit 5fddd2d)
  • Loading branch information
kpawar89 committed Jul 12, 2023
1 parent 315fc65 commit ecd14b4
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 10 deletions.
42 changes: 32 additions & 10 deletions manila/db/sqlalchemy/api.py
Expand Up @@ -4717,20 +4717,42 @@ def share_server_get_all_unused_deletable(context, host, updated_before):
return result


def _share_server_backend_details_get_item(context,
share_server_id,
key, session=None):
result = (_share_server_backend_details_get_query(
context, share_server_id, session=session).filter_by(key=key).first())
if not result:
raise exception.ShareServerBackendDetailsNotFound()
return result


def _share_server_backend_details_get_query(context,
share_server_id,
session=None):
return (model_query(
context, models.ShareServerBackendDetails, session=session,
read_deleted="no").
filter_by(share_server_id=share_server_id))


@require_context
def share_server_backend_details_set(context, share_server_id, server_details):
share_server_get(context, share_server_id)
session = get_session()

for meta_key, meta_value in server_details.items():
meta_ref = models.ShareServerBackendDetails()
meta_ref.update({
'key': meta_key,
'value': meta_value,
'share_server_id': share_server_id
})
session = get_session()
with session.begin():
meta_ref.save(session)
with session.begin():
for meta_key, meta_value in server_details.items():
item = {"value": meta_value}
try:
meta_ref = _share_server_backend_details_get_item(
context, share_server_id, meta_key, session=session)
except exception.ShareServerBackendDetailsNotFound:
meta_ref = models.ShareServerBackendDetails()
item.update({"key": meta_key,
"share_server_id": share_server_id})
meta_ref.update(item)
meta_ref.save(session=session)
return server_details


Expand Down
4 changes: 4 additions & 0 deletions manila/exception.py
Expand Up @@ -305,6 +305,10 @@ class ShareServerNotReady(ManilaException):
"within %(time)s seconds.")


class ShareServerBackendDetailsNotFound(NotFound):
message = _("Share server backend details does not exist.")


class ServiceNotFound(NotFound):
message = _("Service %(service_id)s could not be found.")

Expand Down
8 changes: 8 additions & 0 deletions manila/tests/db/sqlalchemy/test_api.py
Expand Up @@ -3526,6 +3526,14 @@ def test_backend_details_set(self):
db_api.share_server_get(self.ctxt, server['id'])['backend_details']
)

details.update({'value2': '4'})
db_api.share_server_backend_details_set(self.ctxt, server['id'],
details)
self.assertDictEqual(
details,
db_api.share_server_get(self.ctxt, server['id'])['backend_details']
)

def test_backend_details_set_not_found(self):
fake_id = 'FAKE_UUID'
self.assertRaises(exception.ShareServerNotFound,
Expand Down
@@ -0,0 +1,8 @@
---
fixes:
- |
Share server backend details set function adds db records without
checking existing entries. This results in duplicate records for the
combination of given share server id and key. Fixed it by updating records
if already exist else creating new. See the `launchpad bug 2024658
<https://bugs.launchpad.net/manila/+bug/2024658>`_ for more details.

0 comments on commit ecd14b4

Please sign in to comment.