Browse Source

storage: fix resize and revert handling

 - fix coroutine calling from Admin API
 - fix off-by-one error in resize
 - adjust tests
Marek Marczykowski-Górecki 6 years ago
parent
commit
c6e09b5a99
4 changed files with 22 additions and 12 deletions
  1. 5 3
      qubes/api/admin.py
  2. 1 1
      qubes/storage/file.py
  3. 1 1
      qubes/storage/lvm.py
  4. 15 7
      qubes/tests/api_admin.py

+ 5 - 3
qubes/api/admin.py

@@ -305,9 +305,11 @@ class QubesAdminAPI(qubes.api.AbstractQubesAPI):
         assert untrusted_revision in snapshots
         revision = untrusted_revision
 
-        self.fire_event_for_permission(revision=revision)
+        self.fire_event_for_permission(volume=volume, revision=revision)
 
-        self.dest.storage.get_pool(volume).revert(revision)
+        ret = volume.revert(revision)
+        if asyncio.iscoroutine(ret):
+            yield from ret
         self.app.save()
 
     # write=True because this allow to clone VM - and most likely modify that
@@ -381,7 +383,7 @@ class QubesAdminAPI(qubes.api.AbstractQubesAPI):
 
         self.fire_event_for_permission(size=size)
 
-        self.dest.storage.resize(self.arg, size)
+        yield from self.dest.storage.resize(self.arg, size)
         self.app.save()
 
     @qubes.api.method('admin.vm.volume.Import', no_payload=True,

+ 1 - 1
qubes/storage/file.py

@@ -191,7 +191,7 @@ class FileVolume(qubes.storage.Volume):
             msg = 'Can not resize reađonly volume {!s}'.format(self)
             raise qubes.storage.StoragePoolException(msg)
 
-        if size <= self.size:
+        if size < self.size:
             raise qubes.storage.StoragePoolException(
                 'For your own safety, shrinking of %s is'
                 ' disabled. If you really know what you'

+ 1 - 1
qubes/storage/lvm.py

@@ -366,7 +366,7 @@ class ThinVolume(qubes.storage.Volume):
             msg = 'Can not resize reađonly volume {!s}'.format(self)
             raise qubes.storage.StoragePoolException(msg)
 
-        if size <= self.size:
+        if size < self.size:
             raise qubes.storage.StoragePoolException(
                 'For your own safety, shrinking of %s is'
                 ' disabled. If you really know what you'

+ 15 - 7
qubes/tests/api_admin.py

@@ -377,7 +377,7 @@ class TC_00_VMs(AdminAPITestCase):
         pass
 
     @unittest.skip('method not implemented yet')
-    def test_100_vm_volume_snapshot_invlid_volume(self):
+    def test_100_vm_volume_snapshot_invalid_volume(self):
         self.vm.volumes = unittest.mock.MagicMock()
         volumes_conf = {
             'keys.return_value': ['root', 'private', 'volatile', 'kernel'],
@@ -411,16 +411,21 @@ class TC_00_VMs(AdminAPITestCase):
             '__getitem__.return_value.revisions': ['rev1', 'rev2'],
         }
         self.vm.volumes.configure_mock(**volumes_conf)
+        del self.vm.volumes['private'].revert('rev1')._is_coroutine
         self.vm.storage = unittest.mock.Mock()
         value = self.call_mgmt_func(b'admin.vm.volume.Revert',
             b'test-vm1', b'private', b'rev1')
         self.assertIsNone(value)
-        self.assertEqual(self.vm.volumes.mock_calls,
-            [unittest.mock.call.keys(),
-                unittest.mock.call.__getattr__('__getitem__')('private')])
-        self.assertEqual(self.vm.storage.mock_calls,
-            [unittest.mock.call.get_pool(self.vm.volumes['private']),
-             unittest.mock.call.get_pool().revert('rev1')])
+        print(repr(self.vm.volumes.mock_calls))
+        self.assertEqual(self.vm.volumes.mock_calls, [
+            ('__getitem__', ('private', ), {}),
+            ('__getitem__().revert', ('rev1', ), {}),
+            ('keys', (), {}),
+            ('__getitem__', ('private', ), {}),
+            ('__getitem__().__hash__', (), {}),
+            ('__getitem__().revert', ('rev1', ), {}),
+            ])
+        self.assertEqual(self.vm.storage.mock_calls, [])
 
     def test_110_vm_volume_revert_invalid_rev(self):
         self.vm.volumes = unittest.mock.MagicMock()
@@ -445,6 +450,7 @@ class TC_00_VMs(AdminAPITestCase):
         }
         self.vm.volumes.configure_mock(**volumes_conf)
         self.vm.storage = unittest.mock.Mock()
+        self.vm.storage.resize.side_effect = self.dummy_coro
         value = self.call_mgmt_func(b'admin.vm.volume.Resize',
             b'test-vm1', b'private', b'1024000000')
         self.assertIsNone(value)
@@ -460,6 +466,7 @@ class TC_00_VMs(AdminAPITestCase):
         }
         self.vm.volumes.configure_mock(**volumes_conf)
         self.vm.storage = unittest.mock.Mock()
+        self.vm.storage.resize.side_effect = self.dummy_coro
         with self.assertRaises(AssertionError):
             self.call_mgmt_func(b'admin.vm.volume.Resize',
                 b'test-vm1', b'private', b'no-int-size')
@@ -474,6 +481,7 @@ class TC_00_VMs(AdminAPITestCase):
         }
         self.vm.volumes.configure_mock(**volumes_conf)
         self.vm.storage = unittest.mock.Mock()
+        self.vm.storage.resize.side_effect = self.dummy_coro
         with self.assertRaises(AssertionError):
             self.call_mgmt_func(b'admin.vm.volume.Resize',
                 b'test-vm1', b'private', b'-1')