Merge ~dbungert/curtin:ntfs into curtin:master

Proposed by Dan Bungert
Status: Merged
Approved by: Dan Bungert
Approved revision: 07442bc3a62fb78df096e5f717077270fde2e123
Merge reported by: Server Team CI bot
Merged at revision: not available
Proposed branch: ~dbungert/curtin:ntfs
Merge into: curtin:master
Diff against target: 158 lines (+60/-8)
3 files modified
curtin/commands/block_meta_v2.py (+5/-0)
doc/topics/storage.rst (+1/-1)
tests/integration/test_block_meta.py (+54/-7)
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Approve
Olivier Gayot Approve
Michael Hudson-Doyle Approve
Review via email: mp+420513@code.launchpad.net

Commit message

block/v2: resize of ntfs

To post a comment you must log in.
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

Nice and easy.

review: Approve
Revision history for this message
Olivier Gayot (ogayot) :
review: Approve
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/curtin/commands/block_meta_v2.py b/curtin/commands/block_meta_v2.py
index c1e3630..2efff25 100644
--- a/curtin/commands/block_meta_v2.py
+++ b/curtin/commands/block_meta_v2.py
@@ -60,6 +60,10 @@ def resize_ext(path, size):
60 util.subp(['resize2fs', path, f'{size_k}k'])60 util.subp(['resize2fs', path, f'{size_k}k'])
6161
6262
63def resize_ntfs(path, size):
64 util.subp(['ntfsresize', '-s', str(size), path])
65
66
63def perform_resize(kname, size, direction):67def perform_resize(kname, size, direction):
64 path = block.kname_to_path(kname)68 path = block.kname_to_path(kname)
65 fstype = _get_volume_fstype(path)69 fstype = _get_volume_fstype(path)
@@ -73,6 +77,7 @@ resizers = {
73 'ext2': resize_ext,77 'ext2': resize_ext,
74 'ext3': resize_ext,78 'ext3': resize_ext,
75 'ext4': resize_ext,79 'ext4': resize_ext,
80 'ntfs': resize_ntfs,
76}81}
7782
7883
diff --git a/doc/topics/storage.rst b/doc/topics/storage.rst
index e6dd13a..aa5ad13 100644
--- a/doc/topics/storage.rst
+++ b/doc/topics/storage.rst
@@ -445,7 +445,7 @@ If the ``preserve`` flag is set to true, curtin will adjust the size of the
445partition to the new size. When adjusting smaller, the size of the contents445partition to the new size. When adjusting smaller, the size of the contents
446must permit that. When adjusting larger, there must already be a gap beyond446must permit that. When adjusting larger, there must already be a gap beyond
447the partition in question.447the partition in question.
448Resize is supported on filesystems of types ext2, ext3, ext4.448Resize is supported on filesystems of types ext2, ext3, ext4, ntfs.
449449
450**name**: *<name>*450**name**: *<name>*
451451
diff --git a/tests/integration/test_block_meta.py b/tests/integration/test_block_meta.py
index be69bc0..76a974b 100644
--- a/tests/integration/test_block_meta.py
+++ b/tests/integration/test_block_meta.py
@@ -6,9 +6,11 @@ import json
6import sys6import sys
7import yaml7import yaml
8import os8import os
9import re
910
10from curtin import block, udev, util11from curtin import block, udev, util
1112
13from curtin.commands.block_meta import _get_volume_fstype
12from curtin.commands.block_meta_v2 import ONE_MIB_BYTES14from curtin.commands.block_meta_v2 import ONE_MIB_BYTES
1315
14from tests.unittests.helpers import CiTestCase16from tests.unittests.helpers import CiTestCase
@@ -35,9 +37,7 @@ def loop_dev(image, sector_size=512):
35PartData = namedtuple("PartData", ('number', 'offset', 'size'))37PartData = namedtuple("PartData", ('number', 'offset', 'size'))
3638
3739
38def _get_filesystem_size(dev, part_action, fstype='ext4'):40def _get_ext_size(dev, part_action):
39 if fstype not in ('ext2', 'ext3', 'ext4'):
40 raise Exception(f'_get_filesystem_size: no support for {fstype}')
41 num = part_action['number']41 num = part_action['number']
42 cmd = ['dumpe2fs', '-h', f'{dev}p{num}']42 cmd = ['dumpe2fs', '-h', f'{dev}p{num}']
43 out = util.subp(cmd, capture=True)[0]43 out = util.subp(cmd, capture=True)[0]
@@ -49,6 +49,37 @@ def _get_filesystem_size(dev, part_action, fstype='ext4'):
49 return int(block_count) * int(block_size)49 return int(block_count) * int(block_size)
5050
5151
52def _get_ntfs_size(dev, part_action):
53 num = part_action['number']
54 cmd = ['ntfsresize',
55 '--no-action',
56 '--force', # needed post-resize, which otherwise demands a CHKDSK
57 '--info', f'{dev}p{num}']
58 out = util.subp(cmd, capture=True)[0]
59 # Sample input:
60 # Current volume size: 41939456 bytes (42 MB)
61 volsize_matcher = re.compile(r'^Current volume size: ([0-9]+) bytes')
62 for line in out.splitlines():
63 m = volsize_matcher.match(line)
64 if m:
65 return int(m.group(1))
66 raise Exception('ntfs volume size not found')
67
68
69_get_fs_sizers = {
70 'ext2': _get_ext_size,
71 'ext3': _get_ext_size,
72 'ext4': _get_ext_size,
73 'ntfs': _get_ntfs_size,
74}
75
76
77def _get_filesystem_size(dev, part_action, fstype='ext4'):
78 if fstype not in _get_fs_sizers.keys():
79 raise Exception(f'_get_filesystem_size: no support for {fstype}')
80 return _get_fs_sizers[fstype](dev, part_action)
81
82
52def _get_extended_partition_size(dev, num):83def _get_extended_partition_size(dev, num):
53 # sysfs reports extended partitions as having 1K size84 # sysfs reports extended partitions as having 1K size
54 # sfdisk seems to have a better idea85 # sfdisk seems to have a better idea
@@ -139,6 +170,17 @@ class TestBlockMeta(IntegrationTestCase):
139 with self.open_file_on_part(dev, part_action, 'r') as fp:170 with self.open_file_on_part(dev, part_action, 'r') as fp:
140 self.assertEqual(self.data, fp.read())171 self.assertEqual(self.data, fp.read())
141172
173 def check_fssize(self, dev, part_action, fstype, expected):
174 tolerance = 0
175 if fstype == 'ntfs':
176 # Per ntfsresize manpage, the actual fs size is at least one sector
177 # less than requested.
178 # In these tests it has been consistently 7 sectors fewer.
179 tolerance = 512 * 10
180 actual_fssize = _get_filesystem_size(dev, part_action, fstype)
181 diff = expected - actual_fssize
182 self.assertTrue(0 <= diff <= tolerance, f'difference of {diff}')
183
142 def run_bm(self, config, *args, **kwargs):184 def run_bm(self, config, *args, **kwargs):
143 config_path = self.tmp_path('config.yaml')185 config_path = self.tmp_path('config.yaml')
144 with open(config_path, 'w') as fp:186 with open(config_path, 'w') as fp:
@@ -481,13 +523,13 @@ class TestBlockMeta(IntegrationTestCase):
481 fstype=fstype)523 fstype=fstype)
482 self.run_bm(config.render())524 self.run_bm(config.render())
483 with loop_dev(img) as dev:525 with loop_dev(img) as dev:
526 self.assertEqual(fstype, _get_volume_fstype(f'{dev}p1'))
484 self.create_data(dev, p1)527 self.create_data(dev, p1)
485 self.assertEqual(528 self.assertEqual(
486 summarize_partitions(dev), [529 summarize_partitions(dev), [
487 PartData(number=1, offset=1 << 20, size=start),530 PartData(number=1, offset=1 << 20, size=start),
488 ])531 ])
489 fs_size = _get_filesystem_size(dev, p1, fstype)532 self.check_fssize(dev, p1, fstype, start)
490 self.assertEqual(start, fs_size)
491533
492 config.set_preserve()534 config.set_preserve()
493 p1['resize'] = True535 p1['resize'] = True
@@ -499,8 +541,7 @@ class TestBlockMeta(IntegrationTestCase):
499 summarize_partitions(dev), [541 summarize_partitions(dev), [
500 PartData(number=1, offset=1 << 20, size=end),542 PartData(number=1, offset=1 << 20, size=end),
501 ])543 ])
502 fs_size = _get_filesystem_size(dev, p1, fstype)544 self.check_fssize(dev, p1, fstype, end)
503 self.assertEqual(end, fs_size)
504545
505 def test_resize_up_ext2(self):546 def test_resize_up_ext2(self):
506 self._do_test_resize(40, 80, 'ext2')547 self._do_test_resize(40, 80, 'ext2')
@@ -520,6 +561,12 @@ class TestBlockMeta(IntegrationTestCase):
520 def test_resize_down_ext4(self):561 def test_resize_down_ext4(self):
521 self._do_test_resize(80, 40, 'ext4')562 self._do_test_resize(80, 40, 'ext4')
522563
564 def test_resize_up_ntfs(self):
565 self._do_test_resize(40, 80, 'ntfs')
566
567 def test_resize_down_ntfs(self):
568 self._do_test_resize(80, 40, 'ntfs')
569
523 def test_resize_logical(self):570 def test_resize_logical(self):
524 img = self.tmp_path('image.img')571 img = self.tmp_path('image.img')
525 config = StorageConfigBuilder(version=2)572 config = StorageConfigBuilder(version=2)

Subscribers

People subscribed via source and target branches