← Back to team overview

curtin-dev team mailing list archive

[Merge] ~mwhudson/curtin:action-objects into curtin:master

 

Michael Hudson-Doyle has proposed merging ~mwhudson/curtin:action-objects into curtin:master.

Requested reviews:
  curtin developers (curtin-dev)

For more details, see:
https://code.launchpad.net/~mwhudson/curtin/+git/curtin/+merge/448042

block_meta: start to turn dictionaries into objects

and start with the most insignificant handlers


-- 
Your team curtin developers is requested to review the proposed merge of ~mwhudson/curtin:action-objects into curtin:master.
diff --git a/curtin/commands/block_meta.py b/curtin/commands/block_meta.py
index 421b048..11972b9 100644
--- a/curtin/commands/block_meta.py
+++ b/curtin/commands/block_meta.py
@@ -1,7 +1,7 @@
 # This file is part of curtin. See LICENSE file for copyright and license info.
 
 from collections import OrderedDict, namedtuple
-from curtin import (block, compat, config, paths, util)
+from curtin import (block, compat, config, paths, storage_actions, util)
 from curtin.block import schemas
 from curtin.block import (bcache, clear_holders, dasd, iscsi, lvm, mdadm, mkfs,
                           multipath, zfs)
@@ -659,10 +659,24 @@ def get_path_to_storage_volume(volume, storage_config):
 DEVS = set()
 
 
+@storage_actions.define("image")
+class Image:
+    path: str
+    size: int = storage_actions.size()
+    preserve: bool = False
+    sector_size: int = storage_actions.size(default=512)
+
+
+@storage_actions.define("device")
+class Device:
+    path: str
+
+
 def image_handler(info, storage_config, context):
-    path = info['path']
-    size = int(util.human2bytes(info['size']))
-    if info.get('preserve', False):
+    image: Image = storage_actions.asobject(info)
+    path = image.path
+    size = image.size
+    if image.preserve:
         actual_size = os.stat(path).st_size
         if size != actual_size:
             raise RuntimeError(
@@ -680,23 +694,24 @@ def image_handler(info, storage_config, context):
             raise
 
     cmd = ['losetup', '--show', '--find', path]
-    sector_size = int(util.human2bytes(info.get('sector_size', 512)))
+    sector_size = image.sector_size
     if sector_size != 512:
         compat.supports_large_sectors(fatal=True)
         cmd.extend(('--sector-size', str(sector_size)))
     try:
         dev = util.subp(cmd, capture=True)[0].strip()
     except BaseException:
-        if os.path.exists(path) and not info.get('preserve'):
+        if os.path.exists(path) and not image.preserve:
             os.unlink(path)
         raise
-    context.id_to_device[info['id']] = info['dev'] = dev
+    context.id_to_device[image.id] = info['dev'] = dev
     DEVS.add(dev)
     context.handlers['disk'](info, storage_config, context)
 
 
 def device_handler(info, storage_config, context):
-    context.id_to_device[info['id']] = info['path']
+    device: Device = storage_actions.asobject(info)
+    context.id_to_device[device.id] = device.path
     context.handlers['disk'](info, storage_config, context)
 
 
diff --git a/curtin/storage_actions.py b/curtin/storage_actions.py
new file mode 100644
index 0000000..c0f405e
--- /dev/null
+++ b/curtin/storage_actions.py
@@ -0,0 +1,33 @@
+import attrs
+
+from curtin import config, util
+
+_type_to_cls = {}
+
+
+def define(typ):
+    def wrapper(c):
+        c.type = attrs.ib(default=typ)
+        c.id = attrs.field()
+        c.__annotations__["id"] = str
+        c.__annotations__["type"] = str
+        c = attrs.define(eq=False, auto_attribs=True, kw_only=True)(c)
+        _type_to_cls[typ] = c
+        return c
+
+    return wrapper
+
+
+def _convert_size(s):
+    if isinstance(s, str):
+        return int(util.human2bytes(s))
+    return s
+
+
+def asobject(obj):
+    cls = _type_to_cls[obj["type"]]
+    return config.fromdict(cls, obj)
+
+
+def size(default=attrs.NOTHING):
+    return attrs.field(converter=_convert_size, default=default)