diff --git a/qubesadmin/storage.py b/qubesadmin/storage.py index a57ad85..b7c5805 100644 --- a/qubesadmin/storage.py +++ b/qubesadmin/storage.py @@ -270,6 +270,16 @@ class Pool(object): return self.name < other.name return NotImplemented + @property + def usage_details(self): + ''' Storage pool usage details (current - not cached) ''' + pool_usage_data = self.app.qubesd_call( + 'dom0', 'admin.pool.UsageDetails', self.name, None) + pool_usage_data = pool_usage_data.decode('utf-8') + assert pool_usage_data.endswith('\n') + pool_usage_data = pool_usage_data[:-1] + return dict(l.split('=', 1) for l in pool_usage_data.splitlines()) + @property def config(self): ''' Storage pool config ''' @@ -287,7 +297,7 @@ class Pool(object): def size(self): ''' Storage pool size, in bytes''' try: - return int(self.config['size']) + return int(self.usage_details['data_size']) except KeyError: # pool driver does not provide size information return None @@ -296,7 +306,7 @@ class Pool(object): def usage(self): ''' Space used in the pool, in bytes ''' try: - return int(self.config['usage']) + return int(self.usage_details['data_usage']) except KeyError: # pool driver does not provide usage information return None diff --git a/qubesadmin/tests/app.py b/qubesadmin/tests/app.py index 49ca2d7..dfe3814 100644 --- a/qubesadmin/tests/app.py +++ b/qubesadmin/tests/app.py @@ -27,9 +27,10 @@ import multiprocessing try: import unittest.mock as mock + from unittest.mock import call except ImportError: import mock -from mock import call + from mock import call import tempfile diff --git a/qubesadmin/tests/storage.py b/qubesadmin/tests/storage.py index 7de7615..6123c5b 100644 --- a/qubesadmin/tests/storage.py +++ b/qubesadmin/tests/storage.py @@ -303,6 +303,36 @@ class TestPool(qubesadmin.tests.QubesTestCase): }) self.assertAllCalled() + def test_011_usage(self): + self.app.expected_calls[('dom0', 'admin.pool.List', None, None)] = \ + b'0\x00file\nlvm\n' + self.app.expected_calls[('dom0', 'admin.pool.UsageDetails', 'lvm', None)] = \ + b'0\x00data_size=204800\n' \ + b'data_usage=102400\n' \ + b'metadata_size=1024\n' \ + b'metadata_usage=50\n' + pool = self.app.pools['lvm'] + self.assertEqual(pool.usage_details, { + 'data_size': '204800', + 'data_usage': '102400', + 'metadata_size': '1024', + 'metadata_usage': '50', + }) + self.assertAllCalled() + + def test_012_size_and_usage(self): + self.app.expected_calls[('dom0', 'admin.pool.List', None, None)] = \ + b'0\x00file\nlvm\n' + self.app.expected_calls[('dom0', 'admin.pool.UsageDetails', 'lvm', None)] = \ + b'0\x00data_size=204800\n' \ + b'data_usage=102400\n' \ + b'metadata_size=1024\n' \ + b'metadata_usage=50\n' + pool = self.app.pools['lvm'] + self.assertEqual(pool.size, 204800) + self.assertEqual(pool.usage, 102400) + self.assertAllCalled() + def test_020_volumes(self): self.app.expected_calls[('dom0', 'admin.pool.List', None, None)] = \ b'0\x00file\nlvm\n'