← Back to team overview

cloud-init-dev team mailing list archive

[Merge] lp:~daniel-thewatkins/cloud-init/lp1460715 into lp:cloud-init

 

Dan Watkins has proposed merging lp:~daniel-thewatkins/cloud-init/lp1460715 into lp:cloud-init.

Requested reviews:
  cloud init development team (cloud-init-dev)
Related bugs:
  Bug #1460715 in cloud-init: "MBR disk setup fails in wily because sfdisk no longer accepts M as a valid unit"
  https://bugs.launchpad.net/cloud-init/+bug/1460715

For more details, see:
https://code.launchpad.net/~daniel-thewatkins/cloud-init/lp1460715/+merge/274897
-- 
Your team cloud init development team is requested to review the proposed merge of lp:~daniel-thewatkins/cloud-init/lp1460715 into lp:cloud-init.
=== modified file 'cloudinit/config/cc_disk_setup.py'
--- cloudinit/config/cc_disk_setup.py	2015-07-22 19:14:33 +0000
+++ cloudinit/config/cc_disk_setup.py	2015-10-19 14:31:20 +0000
@@ -16,12 +16,14 @@
 #
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-from cloudinit.settings import PER_INSTANCE
-from cloudinit import util
 import logging
 import os
+import re
 import shlex
 
+from cloudinit import util
+from cloudinit.settings import PER_INSTANCE
+
 frequency = PER_INSTANCE
 
 # Define the commands to use
@@ -343,13 +345,16 @@
 
 
 def get_mbr_hdd_size(device):
-    size_cmd = [SFDISK_CMD, '--show-size', device]
-    size = None
+    size_cmd = [SFDISK_CMD, '-l', device]
     try:
-        size, _err = util.subp(size_cmd)
+        output, _ = util.subp(size_cmd)
     except Exception as e:
         raise Exception("Failed to get %s size\n%s" % (device, e))
 
+    match = re.search(r'(?P<sector_count>\d+) sectors', output)
+    if match is None:
+        raise Exception("Failed to get %s size\n%s" % (device, e))
+    size = match.groupdict()['sector_count']
     return int(size.strip())
 
 
@@ -492,7 +497,7 @@
                 raise Exception("Partition was incorrectly defined: %s" % part)
             percent, part_type = part
 
-        part_size = int((float(size) * (float(percent) / 100)) / 1024)
+        part_size = int(float(size) * (float(percent) / 100))
 
         if part_num == last_part_num:
             part_definition.append(",,%s" % part_type)
@@ -596,7 +601,7 @@
     types, i.e. gpt
     """
     # Create the partitions
-    prt_cmd = [SFDISK_CMD, "--Linux", "-uM", device]
+    prt_cmd = [SFDISK_CMD, device]
     try:
         util.subp(prt_cmd, data="%s\n" % layout)
     except Exception as e:

=== modified file 'tests/unittests/test_handler/test_handler_disk_setup.py'
--- tests/unittests/test_handler/test_handler_disk_setup.py	2015-03-18 13:32:54 +0000
+++ tests/unittests/test_handler/test_handler_disk_setup.py	2015-10-19 14:31:20 +0000
@@ -1,7 +1,24 @@
+import random
+
 from cloudinit.config import cc_disk_setup
 from ..helpers import ExitStack, mock, TestCase
 
 
+SFDISK_LIST_TEMPLATE = """\
+Disk /dev/sda: 10 GiB, 10737418240 bytes, {size_in_sectors} sectors
+Units: sectors of 1 * 512 = 512 bytes
+Sector size (logical/physical): 512 bytes / 4096 bytes
+I/O size (minimum/optimal): 4096 bytes / 4096 bytes
+Disklabel type: dos
+Disk identifier: 0x0008c631
+
+Device     Boot Start      End  Sectors Size Id Type
+/dev/sda1  *     2048 20971519 20969472  10G 83 Linux
+ubuntu@sfdisk-test-wily:~$ sudo sfdisk -l /dev/sda | head -n1
+Disk /dev/sda: 10 GiB, 10737418240 bytes, {size_in_sectors} sectors
+"""
+
+
 class TestIsDiskUsed(TestCase):
 
     def setUp(self):
@@ -28,3 +45,48 @@
         self.enumerate_disk.return_value = (mock.MagicMock() for _ in range(1))
         self.check_fs.return_value = (mock.MagicMock(), None, mock.MagicMock())
         self.assertFalse(cc_disk_setup.is_disk_used(mock.MagicMock()))
+
+
+class TestGetMbrHddSize(TestCase):
+
+    def setUp(self):
+        super(TestGetMbrHddSize, self).setUp()
+        self.patches = ExitStack()
+        self.subp = self.patches.enter_context(
+            mock.patch.object(cc_disk_setup.util, 'subp'))
+
+    def _configure_subp_mock(self, size_in_sectors):
+        self.subp.return_value = (
+            SFDISK_LIST_TEMPLATE.format(size_in_sectors=size_in_sectors), "")
+
+    def test_size_returned_correctly(self):
+        size = random.randint(1000000, 1000000000000)
+        self._configure_subp_mock(size)
+        self.assertEqual(size, cc_disk_setup.get_mbr_hdd_size('/dev/sda1'))
+
+
+class TestGetPartitionMbrLayout(TestCase):
+
+    def test_single_partition_using_boolean(self):
+        self.assertEqual('0,',
+                         cc_disk_setup.get_partition_mbr_layout(1000, True))
+
+    def test_single_partition_using_list(self):
+        disk_size = random.randint(1000000, 1000000000000)
+        self.assertEqual(
+            ',,83',
+            cc_disk_setup.get_partition_mbr_layout(disk_size, [100]))
+
+    def test_half_and_half(self):
+        disk_size = random.randint(1000000, 1000000000000)
+        expected_partition_size = int(float(disk_size) / 2)
+        self.assertEqual(
+            ',{0},83\n,,83'.format(expected_partition_size),
+            cc_disk_setup.get_partition_mbr_layout(disk_size, [50, 50]))
+
+    def test_thirds_with_different_partition_type(self):
+        disk_size = random.randint(1000000, 1000000000000)
+        expected_partition_size = int(float(disk_size) * 0.33)
+        self.assertEqual(
+            ',{0},83\n,,82'.format(expected_partition_size),
+            cc_disk_setup.get_partition_mbr_layout(disk_size, [33, [66, 82]]))


Follow ups