From cf3cfb3a66066cfdc1ad15ac35b204d4a7b0301f Mon Sep 17 00:00:00 2001 From: Ivan Kolodyazhny Date: Wed, 9 Sep 2015 16:59:55 +0300 Subject: [PATCH] Filter hosts with pool in snapshot_get_by_host Snapshots use host field from the volume record. We need to ignore pool if it is not specified in a host param for snapshot_get_by_host method. Also snapshot_get_by_host will return empty list if host is None or an empty string like a volume filer does. Change-Id: I0d9eef8675d8dada3a0b6886dbb3f5807eecee73 Closes-Bug: #1493856 --- cinder/db/sqlalchemy/api.py | 20 +++++++++++++++++--- cinder/tests/unit/test_db_api.py | 24 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/cinder/db/sqlalchemy/api.py b/cinder/db/sqlalchemy/api.py index c6e70ff5b..622b7eb0d 100644 --- a/cinder/db/sqlalchemy/api.py +++ b/cinder/db/sqlalchemy/api.py @@ -2159,9 +2159,23 @@ def snapshot_get_by_host(context, host, filters=None): if filters: query = query.filter_by(**filters) - return query.join(models.Snapshot.volume).filter( - models.Volume.host == host).options( - joinedload('snapshot_metadata')).all() + # As a side effect of the introduction of pool-aware scheduler, + # newly created volumes will have pool information appended to + # 'host' field of a volume record. So a volume record in DB can + # now be either form below: + # Host + # Host#Pool + if host and isinstance(host, six.string_types): + session = get_session() + with session.begin(): + host_attr = getattr(models.Volume, 'host') + conditions = [host_attr == host, + host_attr.op('LIKE')(host + '#%')] + query = query.join(models.Snapshot.volume).filter( + or_(*conditions)).options(joinedload('snapshot_metadata')) + return query.all() + elif not host: + return [] @require_context diff --git a/cinder/tests/unit/test_db_api.py b/cinder/tests/unit/test_db_api.py index 3a6b2c1e9..d732f61ee 100644 --- a/cinder/tests/unit/test_db_api.py +++ b/cinder/tests/unit/test_db_api.py @@ -1149,6 +1149,30 @@ class DBAPISnapshotTestCase(BaseTest): 'host2', {'fake_key': 'fake'}), ignored_keys='volume') + def test_snapshot_get_by_host_with_pools(self): + db.volume_create(self.ctxt, {'id': 1, 'host': 'host1#pool1'}) + db.volume_create(self.ctxt, {'id': 2, 'host': 'host1#pool2'}) + + snapshot1 = db.snapshot_create(self.ctxt, {'id': 1, 'volume_id': 1}) + snapshot2 = db.snapshot_create(self.ctxt, {'id': 2, 'volume_id': 2}) + + self._assertEqualListsOfObjects([snapshot1, snapshot2], + db.snapshot_get_by_host( + self.ctxt, + 'host1'), + ignored_keys='volume') + self._assertEqualListsOfObjects([snapshot1], + db.snapshot_get_by_host( + self.ctxt, + 'host1#pool1'), + ignored_keys='volume') + + self._assertEqualListsOfObjects([], + db.snapshot_get_by_host( + self.ctxt, + 'host1#pool0'), + ignored_keys='volume') + def test_snapshot_get_all_by_project(self): db.volume_create(self.ctxt, {'id': 1}) db.volume_create(self.ctxt, {'id': 2})