From e94151c1c3dc0f27f14a594b331dbfb6d3bdf1be Mon Sep 17 00:00:00 2001 From: Michael Still Date: Tue, 14 Nov 2017 09:18:20 +1100 Subject: [PATCH] Convert users of tune2fs to privsep. xenapi likes enabling and disabling ext3 filesystem journals. They can do that via privsep now. Change-Id: Iad8198fbd01aa80bde0a6b295963391715c5cd48 blueprint: hurrah-for-privsep --- etc/nova/rootwrap.d/compute.filters | 3 - nova/privsep/fs.py | 10 ++++ nova/tests/unit/virt/xenapi/test_vm_utils.py | 59 ++++++++----------- nova/virt/xenapi/vm_utils.py | 5 +- ...-rocky-rootwrap-adds-644c43fbd86f9f8a.yaml | 5 ++ 5 files changed, 43 insertions(+), 39 deletions(-) create mode 100644 releasenotes/notes/privsep-rocky-rootwrap-adds-644c43fbd86f9f8a.yaml diff --git a/etc/nova/rootwrap.d/compute.filters b/etc/nova/rootwrap.d/compute.filters index 24de2873805a..0ef8c90194c3 100644 --- a/etc/nova/rootwrap.d/compute.filters +++ b/etc/nova/rootwrap.d/compute.filters @@ -2,9 +2,6 @@ # This file should be owned by (and only-writeable by) the root user [Filters] -# nova/virt/xenapi/vm_utils.py: tune2fs, -O ^has_journal, part_path -# nova/virt/xenapi/vm_utils.py: tune2fs, -j, partition_path -tune2fs: CommandFilter, tune2fs, root # nova/virt/libvirt/utils.py: 'blockdev', '--getsize64', path # nova/virt/disk/mount/nbd.py: 'blockdev', '--flushbufs', device diff --git a/nova/privsep/fs.py b/nova/privsep/fs.py index 06ef5a665b26..b5c9604d6ea7 100644 --- a/nova/privsep/fs.py +++ b/nova/privsep/fs.py @@ -210,3 +210,13 @@ def unprivileged_resize_partition(device, start, end, bootable): if bootable: processutils.execute('parted', '--script', device, 'set', '1', 'boot', 'on') + + +@nova.privsep.sys_admin_pctxt.entrypoint +def ext_journal_disable(device): + processutils.execute('tune2fs', '-O ^has_journal', device) + + +@nova.privsep.sys_admin_pctxt.entrypoint +def ext_journal_enable(device): + processutils.execute('tune2fs', '-j', device) diff --git a/nova/tests/unit/virt/xenapi/test_vm_utils.py b/nova/tests/unit/virt/xenapi/test_vm_utils.py index 75ab72a4ba3d..3ac280153d23 100644 --- a/nova/tests/unit/virt/xenapi/test_vm_utils.py +++ b/nova/tests/unit/virt/xenapi/test_vm_utils.py @@ -353,12 +353,6 @@ class ResizeHelpersTestCase(VMUtilsTestBase): vm_utils._repair_filesystem("fakepath") - def _call_tune2fs_remove_journal(self, path): - utils.execute("tune2fs", "-O ^has_journal", path, run_as_root=True) - - def _call_tune2fs_add_journal(self, path): - utils.execute("tune2fs", "-j", path, run_as_root=True) - def _call_parted_mkpart(self, path, start, end): utils.execute('parted', '--script', path, 'rm', '1', run_as_root=True) @@ -369,22 +363,26 @@ class ResizeHelpersTestCase(VMUtilsTestBase): utils.execute('parted', '--script', path, 'set', '1', 'boot', 'on', run_as_root=True) + @mock.patch('nova.privsep.fs.ext_journal_disable') + @mock.patch('nova.privsep.fs.ext_journal_enable') @mock.patch('nova.privsep.fs.resize_partition') @mock.patch.object(vm_utils, '_repair_filesystem') @mock.patch.object(utils, 'execute') - def test_resize_part_and_fs_down_succeeds(self, mock_execute, mock_repair, - mock_resize): + def test_resize_part_and_fs_down_succeeds( + self, mock_execute, mock_repair, mock_resize, + mock_disable_journal, mock_enable_journal): dev_path = '/dev/fake' partition_path = '%s1' % dev_path vm_utils._resize_part_and_fs('fake', 0, 20, 10, 'boot') mock_execute.assert_has_calls([ - mock.call('tune2fs', '-O ^has_journal', partition_path, - run_as_root=True), - mock.call('resize2fs', partition_path, '10s', run_as_root=True), - mock.call('tune2fs', '-j', partition_path, run_as_root=True)]) + mock.call('resize2fs', partition_path, '10s', run_as_root=True)]) mock_resize.assert_has_calls([ mock.call(dev_path, 0, 9, True)]) + mock_disable_journal.assert_has_calls([ + mock.call(partition_path)]) + mock_enable_journal.assert_has_calls([ + mock.call(partition_path)]) def test_log_progress_if_required(self): self.mox.StubOutWithMock(vm_utils.LOG, "debug") @@ -408,41 +406,36 @@ class ResizeHelpersTestCase(VMUtilsTestBase): self.mox.ReplayAll() vm_utils._log_progress_if_required(1, current, 2) - def test_resize_part_and_fs_down_fails_disk_too_big(self): - self.mox.StubOutWithMock(vm_utils, "_repair_filesystem") - self.mox.StubOutWithMock(utils, 'execute') - - dev_path = "/dev/fake" - partition_path = "%s1" % dev_path - new_sectors = 10 - vm_utils._repair_filesystem(partition_path) - self._call_tune2fs_remove_journal(partition_path) - mobj = utils.execute("resize2fs", - partition_path, - "%ss" % new_sectors, - run_as_root=True) - mobj.AndRaise(processutils.ProcessExecutionError) - self.mox.ReplayAll() + @mock.patch('nova.privsep.fs.ext_journal_disable') + @mock.patch.object(vm_utils, '_repair_filesystem') + @mock.patch.object(utils, 'execute', + side_effect=processutils.ProcessExecutionError) + def test_resize_part_and_fs_down_fails_disk_too_big( + self, mock_execute, mock_repair, mock_disable_journal): self.assertRaises(exception.ResizeError, vm_utils._resize_part_and_fs, "fake", 0, 20, 10, "boot") + @mock.patch('nova.privsep.fs.ext_journal_disable') + @mock.patch('nova.privsep.fs.ext_journal_enable') @mock.patch('nova.privsep.fs.resize_partition') @mock.patch.object(vm_utils, '_repair_filesystem') @mock.patch.object(utils, 'execute') - def test_resize_part_and_fs_up_succeeds(self, mock_execute, mock_repair, - mock_resize): + def test_resize_part_and_fs_up_succeeds( + self, mock_execute, mock_repair, mock_resize, + mock_disable_journal, mock_enable_journal): dev_path = '/dev/fake' partition_path = '%s1' % dev_path vm_utils._resize_part_and_fs('fake', 0, 20, 30, '') mock_execute.assert_has_calls([ - mock.call('tune2fs', '-O ^has_journal', partition_path, - run_as_root=True), - mock.call('resize2fs', partition_path, run_as_root=True), - mock.call('tune2fs', '-j', partition_path, run_as_root=True)]) + mock.call('resize2fs', partition_path, run_as_root=True)]) mock_resize.assert_has_calls([ mock.call(dev_path, 0, 29, False)]) + mock_disable_journal.assert_has_calls([ + mock.call(partition_path)]) + mock_enable_journal.assert_has_calls([ + mock.call(partition_path)]) def test_resize_disk_throws_on_zero_size(self): flavor = fake_flavor.fake_flavor_obj(self.context, root_gb=0) diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 1df21eda5e4c..0852f072df4f 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -2302,8 +2302,7 @@ def _resize_part_and_fs(dev, start, old_sectors, new_sectors, flags): _repair_filesystem(partition_path) # Remove ext3 journal (making it ext2) - utils.execute('tune2fs', '-O ^has_journal', partition_path, - run_as_root=True) + nova.privsep.fs.ext_journal_disable(partition_path) if new_sectors < old_sectors: # Resizing down, resize filesystem before partition resize @@ -2325,7 +2324,7 @@ def _resize_part_and_fs(dev, start, old_sectors, new_sectors, flags): utils.execute('resize2fs', partition_path, run_as_root=True) # Add back journal - utils.execute('tune2fs', '-j', partition_path, run_as_root=True) + nova.privsep.fs.ext_journal_enable(partition_path) def _log_progress_if_required(left, last_log_time, virtual_size): diff --git a/releasenotes/notes/privsep-rocky-rootwrap-adds-644c43fbd86f9f8a.yaml b/releasenotes/notes/privsep-rocky-rootwrap-adds-644c43fbd86f9f8a.yaml new file mode 100644 index 000000000000..f451f35b40f9 --- /dev/null +++ b/releasenotes/notes/privsep-rocky-rootwrap-adds-644c43fbd86f9f8a.yaml @@ -0,0 +1,5 @@ +--- +upgrade: + - | + The following commands are no longer required to be listed in your rootwrap + configuration: tune2fs.