diff --git a/etc/ironic/rootwrap.d/ironic-utils.filters b/etc/ironic/rootwrap.d/ironic-utils.filters index ab60e7a1fd..0ee273b1e4 100644 --- a/etc/ironic/rootwrap.d/ironic-utils.filters +++ b/etc/ironic/rootwrap.d/ironic-utils.filters @@ -4,7 +4,7 @@ [Filters] # ironic/drivers/modules/deploy_utils.py iscsiadm: CommandFilter, iscsiadm, root -sfdisk: CommandFilter, sfdisk, root +parted: CommandFilter, parted, root dd: CommandFilter, dd, root blkid: CommandFilter, blkid, root diff --git a/ironic/drivers/modules/deploy_utils.py b/ironic/drivers/modules/deploy_utils.py index 4cae95b47a..bad6458477 100644 --- a/ironic/drivers/modules/deploy_utils.py +++ b/ironic/drivers/modules/deploy_utils.py @@ -80,21 +80,25 @@ def delete_iscsi(portal_address, portal_port, target_iqn): def make_partitions(dev, root_mb, swap_mb, ephemeral_mb): """Create partitions for root and swap on a disk device.""" - # Lead in with 1MB to allow room for the partition table itself, otherwise - # the way sfdisk adjusts doesn't shift the partition up to compensate, and - # we lose the space. - # http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/raring/util-linux/ - # raring/view/head:/fdisk/sfdisk.c#L1940 + cmd = [] + + def add_partition(start, size, fs_type=''): + end = start + size + cmd.extend(['mkpart', 'primary', fs_type, str(start), str(end)]) + return end + + offset = 1 if ephemeral_mb: - stdin_command = ('1,%d,83;\n,%d,82;\n,%d,83;\n0,0;\n' % - (ephemeral_mb, swap_mb, root_mb)) + offset = add_partition(offset, ephemeral_mb) + offset = add_partition(offset, swap_mb, fs_type='linux-swap') + offset = add_partition(offset, root_mb) else: - stdin_command = ('1,%d,83;\n,%d,82;\n0,0;\n0,0;\n' % - (root_mb, swap_mb)) - utils.execute('sfdisk', '-uM', dev, process_input=stdin_command, - run_as_root=True, - attempts=3, - check_exit_code=[0]) + offset = add_partition(offset, root_mb) + offset = add_partition(offset, swap_mb, fs_type='linux-swap') + + utils.execute('parted', '-a', 'optimal', '-s', dev, '--', 'mklabel', + 'msdos', 'unit', 'MiB', *cmd, run_as_root=True, attempts=3, + check_exit_code=[0]) # avoid "device is busy" time.sleep(3) diff --git a/ironic/tests/drivers/test_deploy_utils.py b/ironic/tests/drivers/test_deploy_utils.py index ed1ea75791..d81ba8e29a 100644 --- a/ironic/tests/drivers/test_deploy_utils.py +++ b/ironic/tests/drivers/test_deploy_utils.py @@ -20,6 +20,7 @@ import os import tempfile from ironic.common import exception +from ironic.common import utils as common_utils from ironic.drivers.modules import deploy_utils as utils from ironic.tests import base as tests_base @@ -400,3 +401,38 @@ class WorkOnDiskTestCase(tests_base.TestCase): self.assertEqual(self.mock_ibd.call_args_list, calls) self.mock_mp.assert_called_once_with(self.dev, self.root_mb, self.swap_mb, ephemeral_mb) + + +@mock.patch.object(common_utils, 'execute') +class MakePartitionsTestCase(tests_base.TestCase): + + def setUp(self): + super(MakePartitionsTestCase, self).setUp() + self.dev = 'fake-dev' + self.root_mb = 1024 + self.swap_mb = 512 + self.ephemeral_mb = 0 + self.parted_static_cmd = ['parted', '-a', 'optimal', '-s', self.dev, + '--', 'mklabel', 'msdos', 'unit', 'MiB'] + + def test_make_partitions(self, mock_exc): + expected_mkpart = ['mkpart', 'primary', '', '1', '1025', + 'mkpart', 'primary', 'linux-swap', '1025', '1537'] + cmd = self.parted_static_cmd + expected_mkpart + utils.make_partitions(self.dev, self.root_mb, self.swap_mb, + self.ephemeral_mb) + mock_exc.assert_called_once_with(*cmd, + run_as_root=True, attempts=3, + check_exit_code=[0]) + + def test_make_partitions_with_ephemeral(self, mock_exc): + self.ephemeral_mb = 2048 + expected_mkpart = ['mkpart', 'primary', '', '1', '2049', + 'mkpart', 'primary', 'linux-swap', '2049', '2561', + 'mkpart', 'primary', '', '2561', '3585'] + cmd = self.parted_static_cmd + expected_mkpart + utils.make_partitions(self.dev, self.root_mb, self.swap_mb, + self.ephemeral_mb) + mock_exc.assert_called_once_with(*cmd, + run_as_root=True, attempts=3, + check_exit_code=[0])