curtin-dev team mailing list archive
-
curtin-dev team
-
Mailing list archive
-
Message #02524
[Merge] ~mwhudson/curtin:FR-2659-add-device-action into curtin:master
Michael Hudson-Doyle has proposed merging ~mwhudson/curtin:FR-2659-add-device-action into curtin:master.
Commit message:
block_meta: add 'device' action to directly refer to a block device
Requested reviews:
curtin developers (curtin-dev)
For more details, see:
https://code.launchpad.net/~mwhudson/curtin/+git/curtin/+merge/429603
--
Your team curtin developers is requested to review the proposed merge of ~mwhudson/curtin:FR-2659-add-device-action into curtin:master.
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):
elif vol.get('type') == 'image':
volume_path = vol['dev']
+ elif vol.get('type') == 'device':
+ volume_path = vol['path']
+
else:
raise NotImplementedError("cannot determine the path to storage \
volume '%s' with type '%s'" % (volume, vol.get('type')))
@@ -584,6 +587,11 @@ def image_handler(info, storage_config, context):
context.handlers['disk'](info, storage_config, context)
+def device_handler(info, storage_config, context):
+ context.id_to_device[info['id']] = info['path']
+ context.handlers['disk'](info, storage_config, context)
+
+
def dasd_handler(info, storage_config, context):
""" Prepare the specified dasd device per configuration
@@ -2036,6 +2044,7 @@ def meta_custom(args):
command_handlers = {
'dasd': dasd_handler,
+ 'device': device_handler,
'disk': disk_handler,
'partition': partition_handler,
'format': format_handler,
@@ -2096,7 +2105,7 @@ def meta_custom(args):
with open(device_map_path, 'w') as fp:
json.dump(context.id_to_device, fp)
- if args.testmode:
+ if args.testmode and DEVS:
util.subp(['losetup', '--detach'] + list(DEVS))
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:
- Bcache Command (``bcache``)
- Zpool Command (``zpool``) **Experimental**
- ZFS Command (``zfs``)) **Experimental**
+- Device "Command" (``device``)
Any action that refers to a block device (so things like ``partition``
and ``dm_crypt`` but not ``lvm_volgroup`` or ``mount``, for example)
@@ -1175,6 +1176,22 @@ passed to the ZFS dataset creation command.
canmount: noauto
mountpoint: /
+Device "Command"
+~~~~~~~~~~~~~~~~
+
+This is a special command that can be used to refer to an arbitrary
+block device. It can be useful when you want to refer to a device that
+has been set up outside curtin for some reason -- partitioning or
+formatting or including in a RAID array or LVM volume group, for example.
+
+**path**: *path to device node*
+
+Path or symlink to the device node in /dev.
+
+The device action also supports the **ptable** attribute, to allow an
+arbitrary device node to be partitioned.
+
+
Additional Examples
-------------------
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:
}
def _add(self, *, type, **kw):
- if type != 'image' and self.cur_image is None:
+ if type not in ['image', 'device'] and self.cur_image is None:
raise Exception("no current image")
action = {'id': 'id' + str(len(self.config))}
action.update(type=type, **kw)
@@ -172,6 +172,11 @@ class StorageConfigBuilder:
self.cur_image = action['id']
return action
+ def add_device(self, *, path, **kw):
+ action = self._add(type='device', path=path, **kw)
+ self.cur_image = action['id']
+ return action
+
def add_part(self, *, size, **kw):
fstype = kw.pop('fstype', None)
part = self._add(type='partition', device=self.cur_image, size=size,
@@ -1188,3 +1193,15 @@ table-length: 256'''.encode()
sfdisk_info = block.sfdisk_info(dev)
# default is 128
self.assertEqual(256, int(sfdisk_info['table-length']))
+
+ def test_device_action(self):
+ self.img = self.tmp_path('image.img')
+ with open(self.img, 'w') as fp:
+ fp.truncate(10 << 20)
+ with loop_dev(self.img) as dev:
+ config = StorageConfigBuilder(version=2)
+ config.add_device(path=dev, ptable='gpt')
+ config.add_part(number=1, offset=1 << 20, size=1 << 20)
+ self.run_bm(config.render())
+ self.assertPartitions(
+ PartData(number=1, offset=1 << 20, size=1 << 20))
Follow ups