From bf1f1ac5ff0d8f656088af82f52b5970dac11dd4 Mon Sep 17 00:00:00 2001 From: Rusty Bird Date: Sat, 20 Jan 2018 23:20:22 +0000 Subject: [PATCH 1/3] Fix wrong mocks of Volume.revisions It's a dict, not a list. --- qubes/tests/api_admin.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/qubes/tests/api_admin.py b/qubes/tests/api_admin.py index 501e4154..dcbe5522 100644 --- a/qubes/tests/api_admin.py +++ b/qubes/tests/api_admin.py @@ -381,7 +381,8 @@ class TC_00_VMs(AdminAPITestCase): self.vm.volumes = unittest.mock.MagicMock() volumes_conf = { 'keys.return_value': ['root', 'private', 'volatile', 'kernel'], - '__getitem__.return_value.revisions': ['rev1', 'rev2'], + '__getitem__.return_value.revisions': + {'rev2': '2018-02-22T22:22:22', 'rev1': '2018-01-11T11:11:11'}, } self.vm.volumes.configure_mock(**volumes_conf) value = self.call_mgmt_func(b'admin.vm.volume.ListSnapshots', @@ -413,7 +414,8 @@ class TC_00_VMs(AdminAPITestCase): self.vm.volumes = unittest.mock.MagicMock() volumes_conf = { 'keys.return_value': ['root', 'private', 'volatile', 'kernel'], - '__getitem__.return_value.revisions': ['rev1', 'rev2'], + '__getitem__.return_value.revisions': + {'rev2': '2018-02-22T22:22:22', 'rev1': '2018-01-11T11:11:11'}, } self.vm.volumes.configure_mock(**volumes_conf) with self.assertRaises(AssertionError): @@ -440,7 +442,8 @@ class TC_00_VMs(AdminAPITestCase): self.vm.volumes = unittest.mock.MagicMock() volumes_conf = { 'keys.return_value': ['root', 'private', 'volatile', 'kernel'], - '__getitem__.return_value.revisions': ['rev1', 'rev2'], + '__getitem__.return_value.revisions': + {'rev2': '2018-02-22T22:22:22', 'rev1': '2018-01-11T11:11:11'}, } self.vm.volumes.configure_mock(**volumes_conf) del self.vm.volumes['private'].revert('rev1')._is_coroutine @@ -462,7 +465,8 @@ class TC_00_VMs(AdminAPITestCase): self.vm.volumes = unittest.mock.MagicMock() volumes_conf = { 'keys.return_value': ['root', 'private', 'volatile', 'kernel'], - '__getitem__.return_value.revisions': ['rev1', 'rev2'], + '__getitem__.return_value.revisions': + {'rev2': '2018-02-22T22:22:22', 'rev1': '2018-01-11T11:11:11'}, } self.vm.volumes.configure_mock(**volumes_conf) self.vm.storage = unittest.mock.Mock() From fe77b0ec85e8b9b78814392e5b6bd0cb2303d25d Mon Sep 17 00:00:00 2001 From: Rusty Bird Date: Sat, 20 Jan 2018 23:20:23 +0000 Subject: [PATCH 2/3] Make 'qvm-volume revert' really use the latest revision admin.vm.volume.ListSnapshots returned volume revisions in undefined order, but 'qvm-volume revert' assumes the list to be in chronological order. Make that assumption true. --- qubes/api/admin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qubes/api/admin.py b/qubes/api/admin.py index 234c7fb9..2951ab4e 100644 --- a/qubes/api/admin.py +++ b/qubes/api/admin.py @@ -347,7 +347,8 @@ class QubesAdminAPI(qubes.api.AbstractQubesAPI): assert self.arg in self.dest.volumes.keys() volume = self.dest.volumes[self.arg] - revisions = [revision for revision in volume.revisions] + id_to_timestamp = volume.revisions + revisions = sorted(id_to_timestamp, key=id_to_timestamp.__getitem__) revisions = self.fire_event_for_filter(revisions) return ''.join('{}\n'.format(revision) for revision in revisions) From 4ae854fdaf5e091c0e75aa8490ca9f533ed9a1bd Mon Sep 17 00:00:00 2001 From: Rusty Bird Date: Sun, 21 Jan 2018 22:28:47 +0000 Subject: [PATCH 3/3] Don't fail create/clone if /var/lib/qubes/TYPE/NAME/ exists --- qubes/tests/vm/dispvm.py | 2 +- qubes/vm/qubesvm.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/qubes/tests/vm/dispvm.py b/qubes/tests/vm/dispvm.py index 43acfbc5..1e562858 100644 --- a/qubes/tests/vm/dispvm.py +++ b/qubes/tests/vm/dispvm.py @@ -93,7 +93,7 @@ class TC_00_DispVM(qubes.tests.QubesTestCase): self.assertEqual(dispvm.label, self.appvm.label) self.assertEqual(dispvm.auto_cleanup, True) mock_makedirs.assert_called_once_with( - '/var/lib/qubes/appvms/' + dispvm.name, mode=0o775) + '/var/lib/qubes/appvms/' + dispvm.name, mode=0o775, exist_ok=True) mock_symlink.assert_called_once_with( '/usr/share/icons/hicolor/128x128/devices/appvm-red.png', '/var/lib/qubes/appvms/{}/icon.png'.format(dispvm.name)) diff --git a/qubes/vm/qubesvm.py b/qubes/vm/qubesvm.py index 493ef397..41fa6472 100644 --- a/qubes/vm/qubesvm.py +++ b/qubes/vm/qubesvm.py @@ -1351,7 +1351,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM): ''' self.log.info('Creating directory: {0}'.format(self.dir_path)) - os.makedirs(self.dir_path, mode=0o775) + os.makedirs(self.dir_path, mode=0o775, exist_ok=True) if pool or pools: # pylint: disable=attribute-defined-outside-init @@ -1418,7 +1418,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM): assert not os.path.exists(self.dir_path), msg self.log.info('Creating directory: {0}'.format(self.dir_path)) - os.makedirs(self.dir_path, mode=0o775) + os.makedirs(self.dir_path, mode=0o775, exist_ok=True) if pool or pools: # pylint: disable=attribute-defined-outside-init