Merge ~mwhudson/curtin:FR-2659-add-device-action into curtin:master

Proposed by Michael Hudson-Doyle
Status: Merged
Approved by: Michael Hudson-Doyle
Approved revision: c6180379e7cd339de763b5dc4c6cb5a2d9c2d7a0
Merge reported by: Server Team CI bot
Merged at revision: not available
Proposed branch: ~mwhudson/curtin:FR-2659-add-device-action
Merge into: curtin:master
Diff against target: 119 lines (+45/-2)
3 files modified
curtin/commands/block_meta.py (+10/-1)
doc/topics/storage.rst (+17/-0)
tests/integration/test_block_meta.py (+18/-1)
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Approve
Dan Bungert Approve
Review via email: mp+429603@code.launchpad.net

Commit message

block_meta: add 'device' action to directly refer to a block device

To post a comment you must log in.
Revision history for this message
Dan Bungert (dbungert) :
review: Approve
Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

Thanks for the fast turnaround :)

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.py b/curtin/commands/block_meta.py
index d01333e..cef0e49 100644
--- a/curtin/commands/block_meta.py
+++ b/curtin/commands/block_meta.py
@@ -535,6 +535,9 @@ def get_path_to_storage_volume(volume, storage_config):
535 elif vol.get('type') == 'image':535 elif vol.get('type') == 'image':
536 volume_path = vol['dev']536 volume_path = vol['dev']
537537
538 elif vol.get('type') == 'device':
539 volume_path = vol['path']
540
538 else:541 else:
539 raise NotImplementedError("cannot determine the path to storage \542 raise NotImplementedError("cannot determine the path to storage \
540 volume '%s' with type '%s'" % (volume, vol.get('type')))543 volume '%s' with type '%s'" % (volume, vol.get('type')))
@@ -584,6 +587,11 @@ def image_handler(info, storage_config, context):
584 context.handlers['disk'](info, storage_config, context)587 context.handlers['disk'](info, storage_config, context)
585588
586589
590def device_handler(info, storage_config, context):
591 context.id_to_device[info['id']] = info['path']
592 context.handlers['disk'](info, storage_config, context)
593
594
587def dasd_handler(info, storage_config, context):595def dasd_handler(info, storage_config, context):
588 """ Prepare the specified dasd device per configuration596 """ Prepare the specified dasd device per configuration
589597
@@ -2036,6 +2044,7 @@ def meta_custom(args):
20362044
2037 command_handlers = {2045 command_handlers = {
2038 'dasd': dasd_handler,2046 'dasd': dasd_handler,
2047 'device': device_handler,
2039 'disk': disk_handler,2048 'disk': disk_handler,
2040 'partition': partition_handler,2049 'partition': partition_handler,
2041 'format': format_handler,2050 'format': format_handler,
@@ -2096,7 +2105,7 @@ def meta_custom(args):
2096 with open(device_map_path, 'w') as fp:2105 with open(device_map_path, 'w') as fp:
2097 json.dump(context.id_to_device, fp)2106 json.dump(context.id_to_device, fp)
20982107
2099 if args.testmode:2108 if args.testmode and DEVS:
2100 util.subp(['losetup', '--detach'] + list(DEVS))2109 util.subp(['losetup', '--detach'] + list(DEVS))
21012110
2102 if args.umount:2111 if args.umount:
diff --git a/doc/topics/storage.rst b/doc/topics/storage.rst
index 1225ee0..8eb738e 100644
--- a/doc/topics/storage.rst
+++ b/doc/topics/storage.rst
@@ -71,6 +71,7 @@ commands include:
71- Bcache Command (``bcache``)71- Bcache Command (``bcache``)
72- Zpool Command (``zpool``) **Experimental**72- Zpool Command (``zpool``) **Experimental**
73- ZFS Command (``zfs``)) **Experimental**73- ZFS Command (``zfs``)) **Experimental**
74- Device "Command" (``device``)
7475
75Any action that refers to a block device (so things like ``partition``76Any action that refers to a block device (so things like ``partition``
76and ``dm_crypt`` but not ``lvm_volgroup`` or ``mount``, for example)77and ``dm_crypt`` but not ``lvm_volgroup`` or ``mount``, for example)
@@ -1175,6 +1176,22 @@ passed to the ZFS dataset creation command.
1175 canmount: noauto1176 canmount: noauto
1176 mountpoint: /1177 mountpoint: /
11771178
1179Device "Command"
1180~~~~~~~~~~~~~~~~
1181
1182This is a special command that can be used to refer to an arbitrary
1183block device. It can be useful when you want to refer to a device that
1184has been set up outside curtin for some reason -- partitioning or
1185formatting or including in a RAID array or LVM volume group, for example.
1186
1187**path**: *path to device node*
1188
1189Path or symlink to the device node in /dev.
1190
1191The device action also supports the **ptable** attribute, to allow an
1192arbitrary device node to be partitioned.
1193
1194
11781195
1179Additional Examples1196Additional Examples
1180-------------------1197-------------------
diff --git a/tests/integration/test_block_meta.py b/tests/integration/test_block_meta.py
index fb14a03..f753a39 100644
--- a/tests/integration/test_block_meta.py
+++ b/tests/integration/test_block_meta.py
@@ -157,7 +157,7 @@ class StorageConfigBuilder:
157 }157 }
158158
159 def _add(self, *, type, **kw):159 def _add(self, *, type, **kw):
160 if type != 'image' and self.cur_image is None:160 if type not in ['image', 'device'] and self.cur_image is None:
161 raise Exception("no current image")161 raise Exception("no current image")
162 action = {'id': 'id' + str(len(self.config))}162 action = {'id': 'id' + str(len(self.config))}
163 action.update(type=type, **kw)163 action.update(type=type, **kw)
@@ -172,6 +172,11 @@ class StorageConfigBuilder:
172 self.cur_image = action['id']172 self.cur_image = action['id']
173 return action173 return action
174174
175 def add_device(self, *, path, **kw):
176 action = self._add(type='device', path=path, **kw)
177 self.cur_image = action['id']
178 return action
179
175 def add_part(self, *, size, **kw):180 def add_part(self, *, size, **kw):
176 fstype = kw.pop('fstype', None)181 fstype = kw.pop('fstype', None)
177 part = self._add(type='partition', device=self.cur_image, size=size,182 part = self._add(type='partition', device=self.cur_image, size=size,
@@ -1188,3 +1193,15 @@ table-length: 256'''.encode()
1188 sfdisk_info = block.sfdisk_info(dev)1193 sfdisk_info = block.sfdisk_info(dev)
1189 # default is 1281194 # default is 128
1190 self.assertEqual(256, int(sfdisk_info['table-length']))1195 self.assertEqual(256, int(sfdisk_info['table-length']))
1196
1197 def test_device_action(self):
1198 self.img = self.tmp_path('image.img')
1199 with open(self.img, 'w') as fp:
1200 fp.truncate(10 << 20)
1201 with loop_dev(self.img) as dev:
1202 config = StorageConfigBuilder(version=2)
1203 config.add_device(path=dev, ptable='gpt')
1204 config.add_part(number=1, offset=1 << 20, size=1 << 20)
1205 self.run_bm(config.render())
1206 self.assertPartitions(
1207 PartData(number=1, offset=1 << 20, size=1 << 20))

Subscribers

People subscribed via source and target branches