Merge "Add option to choose partition alignment mode" into stable/mitaka
This commit is contained in:
commit
8e3a639c50
@ -163,6 +163,12 @@ opts = [
|
||||
'volumes. Devices in directories outside this hierarchy will be '
|
||||
'ignored.'
|
||||
),
|
||||
cfg.StrOpt(
|
||||
'partition_alignment',
|
||||
default='optimal',
|
||||
help='Set alignment for newly created partitions, valid alignment '
|
||||
'types are: none, cylinder, minimal, optimal'
|
||||
),
|
||||
cfg.StrOpt(
|
||||
'lvm_conf_path',
|
||||
default='/etc/lvm/lvm.conf',
|
||||
@ -217,7 +223,8 @@ class Manager(object):
|
||||
for parted in parteds:
|
||||
pu.make_label(parted.name, parted.label)
|
||||
for prt in parted.partitions:
|
||||
pu.make_partition(prt.device, prt.begin, prt.end, prt.type)
|
||||
pu.make_partition(prt.device, prt.begin, prt.end, prt.type,
|
||||
alignment=CONF.partition_alignment)
|
||||
utils.udevadm_trigger_blocks()
|
||||
for flag in prt.flags:
|
||||
pu.set_partition_flag(prt.device, prt.count, flag)
|
||||
|
@ -89,8 +89,10 @@ class Parted(base.Serializable):
|
||||
if not self.partitions:
|
||||
return 1
|
||||
if self.partitions[-1] == self.extended:
|
||||
return self.partitions[-1].begin
|
||||
return self.partitions[-1].end
|
||||
# NOTE(agordeev): this 1M room could be enough for minimal
|
||||
# partition alignment mode for the most of cases.
|
||||
return self.partitions[-1].begin + 1
|
||||
return self.partitions[-1].end + 1
|
||||
|
||||
def next_name(self):
|
||||
if self.next_type() == 'extended':
|
||||
|
@ -447,19 +447,21 @@ class TestManager(unittest2.TestCase):
|
||||
self.assertEqual(mock_pu_ml_expected_calls, mock_pu_ml.call_args_list)
|
||||
|
||||
mock_pu_mp_expected_calls = [
|
||||
mock.call('/dev/sda', 1, 25, 'primary'),
|
||||
mock.call('/dev/sda', 25, 225, 'primary'),
|
||||
mock.call('/dev/sda', 225, 425, 'primary'),
|
||||
mock.call('/dev/sda', 425, 625, 'primary'),
|
||||
mock.call('/dev/sda', 625, 20063, 'primary'),
|
||||
mock.call('/dev/sda', 20063, 65660, 'primary'),
|
||||
mock.call('/dev/sda', 65660, 65680, 'primary'),
|
||||
mock.call('/dev/sdb', 1, 25, 'primary'),
|
||||
mock.call('/dev/sdb', 25, 225, 'primary'),
|
||||
mock.call('/dev/sdb', 225, 65196, 'primary'),
|
||||
mock.call('/dev/sdc', 1, 25, 'primary'),
|
||||
mock.call('/dev/sdc', 25, 225, 'primary'),
|
||||
mock.call('/dev/sdc', 225, 65196, 'primary')]
|
||||
mock.call('/dev/sda', 1, 25, 'primary', alignment='optimal'),
|
||||
mock.call('/dev/sda', 26, 226, 'primary', alignment='optimal'),
|
||||
mock.call('/dev/sda', 227, 427, 'primary', alignment='optimal'),
|
||||
mock.call('/dev/sda', 428, 628, 'primary', alignment='optimal'),
|
||||
mock.call('/dev/sda', 629, 20067, 'primary', alignment='optimal'),
|
||||
mock.call('/dev/sda', 20068, 65665, 'primary',
|
||||
alignment='optimal'),
|
||||
mock.call('/dev/sda', 65666, 65686, 'primary',
|
||||
alignment='optimal'),
|
||||
mock.call('/dev/sdb', 1, 25, 'primary', alignment='optimal'),
|
||||
mock.call('/dev/sdb', 26, 226, 'primary', alignment='optimal'),
|
||||
mock.call('/dev/sdb', 227, 65198, 'primary', alignment='optimal'),
|
||||
mock.call('/dev/sdc', 1, 25, 'primary', alignment='optimal'),
|
||||
mock.call('/dev/sdc', 26, 226, 'primary', alignment='optimal'),
|
||||
mock.call('/dev/sdc', 227, 65198, 'primary', alignment='optimal')]
|
||||
self.assertEqual(mock_pu_mp_expected_calls, mock_pu_mp.call_args_list)
|
||||
|
||||
mock_pu_spf_expected_calls = [mock.call('/dev/sda', 1, 'bios_grub'),
|
||||
@ -1230,6 +1232,7 @@ class TestManagerMultipathPartition(unittest2.TestCase):
|
||||
test_nailgun.MPATH_DISK_KS_SPACES
|
||||
self.mgr = manager.Manager(data)
|
||||
|
||||
@mock.patch.object(mu, 'mdclean_all')
|
||||
@mock.patch.object(manager.utils, 'refresh_multipath')
|
||||
@mock.patch.object(hu, 'is_multipath_device')
|
||||
@mock.patch.object(manager.os.path, 'exists')
|
||||
@ -1240,7 +1243,7 @@ class TestManagerMultipathPartition(unittest2.TestCase):
|
||||
@mock.patch.object(hu, 'list_block_devices')
|
||||
def test_do_partitioning_mp(self, mock_hu_lbd, mock_fu_mf, mock_exec,
|
||||
mock_unbl, mock_bl, mock_os_path, mock_mp,
|
||||
mock_refresh_multipath):
|
||||
mock_refresh_multipath, mock_mdclean_all):
|
||||
mock_os_path.return_value = True
|
||||
mock_hu_lbd.return_value = test_nailgun.LIST_BLOCK_DEVICES_MPATH
|
||||
self.mgr._make_partitions = mock.MagicMock()
|
||||
@ -1300,14 +1303,19 @@ class TestManagerMultipathPartition(unittest2.TestCase):
|
||||
mock.call('/dev/sdc', 'gpt')])
|
||||
|
||||
self.assertEqual(mock_make_partition.mock_calls, [
|
||||
mock.call('/dev/mapper/12312', 1, 25, 'primary'),
|
||||
mock.call('/dev/mapper/12312', 25, 225, 'primary'),
|
||||
mock.call('/dev/mapper/12312', 225, 425, 'primary'),
|
||||
mock.call('/dev/mapper/12312', 425, 625, 'primary'),
|
||||
mock.call('/dev/mapper/12312', 625, 645, 'primary'),
|
||||
mock.call('/dev/sdc', 1, 25, 'primary'),
|
||||
mock.call('/dev/sdc', 25, 225, 'primary'),
|
||||
mock.call('/dev/sdc', 225, 425, 'primary')])
|
||||
mock.call('/dev/mapper/12312', 1, 25, 'primary',
|
||||
alignment='optimal'),
|
||||
mock.call('/dev/mapper/12312', 26, 226, 'primary',
|
||||
alignment='optimal'),
|
||||
mock.call('/dev/mapper/12312', 227, 427, 'primary',
|
||||
alignment='optimal'),
|
||||
mock.call('/dev/mapper/12312', 428, 628, 'primary',
|
||||
alignment='optimal'),
|
||||
mock.call('/dev/mapper/12312', 629, 649, 'primary',
|
||||
alignment='optimal'),
|
||||
mock.call('/dev/sdc', 1, 25, 'primary', alignment='optimal'),
|
||||
mock.call('/dev/sdc', 26, 226, 'primary', alignment='optimal'),
|
||||
mock.call('/dev/sdc', 227, 427, 'primary', alignment='optimal')])
|
||||
|
||||
self.assertEqual(mock_set_partition_flag.mock_calls, [
|
||||
mock.call('/dev/mapper/12312', 1, 'bios_grub'),
|
||||
|
@ -286,15 +286,15 @@ class TestParted(unittest2.TestCase):
|
||||
|
||||
def test_next_begin_last_extended_partition(self):
|
||||
self.prtd.partitions.append(
|
||||
objects.Partition('name', 'count', 'device', 'begin', 'end',
|
||||
objects.Partition('name', 'count', 'device', 1, 100,
|
||||
'extended'))
|
||||
self.assertEqual('begin', self.prtd.next_begin())
|
||||
self.assertEqual(2, self.prtd.next_begin())
|
||||
|
||||
def test_next_begin_no_last_extended_partition(self):
|
||||
self.prtd.partitions.append(
|
||||
objects.Partition('name', 'count', 'device', 'begin', 'end',
|
||||
objects.Partition('name', 'count', 'device', 1, 100,
|
||||
'primary'))
|
||||
self.assertEqual('end', self.prtd.next_begin())
|
||||
self.assertEqual(101, self.prtd.next_begin())
|
||||
|
||||
def test_next_count_no_logical(self):
|
||||
self.assertEqual(1, self.prtd.next_count('primary'))
|
||||
|
@ -134,6 +134,35 @@ class TestPartitionUtils(unittest2.TestCase):
|
||||
self.assertEqual(mock_exec_expected_calls, mock_exec.call_args_list)
|
||||
mock_rerd.assert_called_once_with('/dev/fake', out='out')
|
||||
|
||||
@mock.patch.object(utils, 'udevadm_settle')
|
||||
@mock.patch.object(pu, 'reread_partitions')
|
||||
@mock.patch.object(pu, 'info')
|
||||
@mock.patch.object(utils, 'execute')
|
||||
def test_make_partition_minimal(self, mock_exec, mock_info, mock_rerd,
|
||||
mock_udev):
|
||||
# should run parted OS command
|
||||
# in order to create new partition
|
||||
mock_exec.return_value = ('out', '')
|
||||
|
||||
mock_info.return_value = {
|
||||
'parts': [
|
||||
{'begin': 0, 'end': 1000, 'fstype': 'free'},
|
||||
]
|
||||
}
|
||||
pu.make_partition('/dev/fake', 100, 200, 'primary',
|
||||
alignment='minimal')
|
||||
mock_exec_expected_calls = [
|
||||
mock.call('parted', '-a', 'minimal', '-s', '/dev/fake', 'unit',
|
||||
'MiB', 'mkpart', 'primary', '100', '200',
|
||||
check_exit_code=[0, 1])]
|
||||
mock_udev.assert_called_once_with()
|
||||
self.assertEqual(mock_exec_expected_calls, mock_exec.call_args_list)
|
||||
mock_rerd.assert_called_once_with('/dev/fake', out='out')
|
||||
|
||||
def test_make_partition_wrong_alignment(self):
|
||||
self.assertRaises(errors.WrongPartitionSchemeError, pu.make_partition,
|
||||
'/dev/fake', 1, 10, 'primary', 'invalid')
|
||||
|
||||
@mock.patch.object(utils, 'execute')
|
||||
def test_make_partition_wrong_ptype(self, mock_exec):
|
||||
# should check if partition type is one of
|
||||
|
@ -19,6 +19,7 @@ from fuel_agent.openstack.common import log as logging
|
||||
from fuel_agent.utils import utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
PARTITION_ALIGMENT = ('none', 'cylinder', 'minimal', 'optimal')
|
||||
|
||||
|
||||
def parse_partition_info(output):
|
||||
@ -135,12 +136,27 @@ def set_gpt_type(dev, num, type_guid):
|
||||
dev, check_exit_code=[0])
|
||||
|
||||
|
||||
def make_partition(dev, begin, end, ptype):
|
||||
def make_partition(dev, begin, end, ptype, alignment='optimal'):
|
||||
"""Creates a partition on the device.
|
||||
|
||||
:param dev: A device file, e.g. /dev/sda.
|
||||
:param begin: Beginning of the partition.
|
||||
:param end: Ending of the partition.
|
||||
:param ptype: Partition type: primary or logical.
|
||||
:param alignment: Set alignment mode for newly created partitions,
|
||||
valid alignment types are: none, cylinder, minimal, optimal. For more
|
||||
information about this you can find in GNU parted manual.
|
||||
|
||||
:returns: None
|
||||
"""
|
||||
LOG.debug('Trying to create a partition: dev=%s begin=%s end=%s' %
|
||||
(dev, begin, end))
|
||||
if ptype not in ('primary', 'logical'):
|
||||
raise errors.WrongPartitionSchemeError(
|
||||
'Wrong partition type: %s' % ptype)
|
||||
if alignment not in PARTITION_ALIGMENT:
|
||||
raise errors.WrongPartitionSchemeError(
|
||||
'Wrong partition alignment requested: %s' % alignment)
|
||||
|
||||
# check begin >= end
|
||||
if begin >= end:
|
||||
@ -156,7 +172,7 @@ def make_partition(dev, begin, end, ptype):
|
||||
|
||||
utils.udevadm_settle()
|
||||
out, err = utils.execute(
|
||||
'parted', '-a', 'optimal', '-s', dev, 'unit', 'MiB',
|
||||
'parted', '-a', alignment, '-s', dev, 'unit', 'MiB',
|
||||
'mkpart', ptype, str(begin), str(end), check_exit_code=[0, 1])
|
||||
LOG.debug('Parted output: \n%s' % out)
|
||||
reread_partitions(dev, out=out)
|
||||
|
Loading…
Reference in New Issue
Block a user