From 943f1ccf04421d1986d336745c8054864a33e91c Mon Sep 17 00:00:00 2001
From: Yolanda Robla <yroblamo@redhat.com>
Date: Mon, 1 May 2017 09:19:49 +0200
Subject: [PATCH] Refactor block_device: isolate the getval call

Add a new getval call that allows to retrieve values
from the block device. Also isolating the block device
information into a 'blockdev' dictionary entry, to better
return it with the getval command.

This is a refactor from the original code at
I3600c6a3d663c697b59d91bd3fbb5e408af345e4.

Change-Id: I93d33669a3a0ae644eab9f9b955bb5a9470cadeb
Co-Authored-By: Andreas Florath <andreas@florath.net>
---
 diskimage_builder/block_device/blockdevice.py | 39 ++++++++++++-------
 .../block_device/level0/localloop.py          | 11 ++++--
 .../block_device/level1/partitioning.py       |  7 ++--
 diskimage_builder/lib/disk-image-create       | 18 ++++++---
 4 files changed, 50 insertions(+), 25 deletions(-)

diff --git a/diskimage_builder/block_device/blockdevice.py b/diskimage_builder/block_device/blockdevice.py
index 45a2ed4f0..571aab3e3 100644
--- a/diskimage_builder/block_device/blockdevice.py
+++ b/diskimage_builder/block_device/blockdevice.py
@@ -40,6 +40,10 @@ class BlockDevice(object):
        call it is possible to e.g. query information from the (partially
        automatic generated) internal state like root-label.
 
+    cmd_getval: retrieve information about the (internal) block device
+       state like the block image device (for bootloader) or the
+       root-label (for writing fstab).
+
     cmd_create: creates all the different aspects of the block
        device. When this call is successful, the complete block level
        device is set up, filesystems are created and are mounted at
@@ -209,6 +213,28 @@ class BlockDevice(object):
         logger.info("Wrote final block device config to [%s]"
                     % self.config_json_file_name)
 
+    def cmd_getval(self):
+        """Retrieve value from block device level
+
+        This is needed for backward compatibility (non python) access
+        to (internal) configuration.
+        """
+        symbol = self.args.symbol
+        logger.info("Getting value for [%s]" % symbol)
+        if symbol == 'image-block-partition':
+            # If there is no partition needed, pass back directly the
+            # image.
+            if 'root' in self.state['blockdev']:
+                print("%s" % self.state['blockdev']['root']['device'])
+            else:
+                print("%s" % self.state['blockdev']['image0']['device'])
+            return 0
+        if symbol == 'image-path':
+            print("%s" % self.state['blockdev']['image0']['image'])
+            return 0
+        logger.error("Invalid symbol [%s] for getval" % symbol)
+        return 1
+
     def cmd_create(self):
         """Creates the block device"""
 
@@ -226,15 +252,6 @@ class BlockDevice(object):
                 rollback_cb()
             sys.exit(1)
 
-        # To be compatible with the current implementation, echo the
-        # result to stdout.
-        # If there is no partition needed, pass back directly the
-        # image.
-        if 'root' in result:
-            print("%s" % result['root']['device'])
-        else:
-            print("%s" % result['image0']['device'])
-
         self.write_state(result)
 
         logger.info("create() finished")
@@ -250,10 +267,6 @@ class BlockDevice(object):
         for node in reverse_order:
             node.umount(self.state)
 
-        # To be compatible with the current implementation, echo the
-        # result to stdout.
-        print("%s" % self.state['image0']['image'])
-
         return 0
 
     def cmd_cleanup(self):
diff --git a/diskimage_builder/block_device/level0/localloop.py b/diskimage_builder/block_device/level0/localloop.py
index 11249a05e..de18e972e 100644
--- a/diskimage_builder/block_device/level0/localloop.py
+++ b/diskimage_builder/block_device/level0/localloop.py
@@ -111,17 +111,20 @@ class LocalLoop(NodePluginBase):
         block_device = self._loopdev_attach(self.filename)
         rollback.append(lambda: self._loopdev_detach(block_device))
 
-        result[self.name] = {"device": block_device,
-                             "image": self.filename}
+        if 'blockdev' not in result:
+            result['blockdev'] = {}
+
+        result['blockdev'][self.name] = {"device": block_device,
+                                         "image": self.filename}
         logger.debug("Created loop  name [%s] device [%s] image [%s]"
                      % (self.name, block_device, self.filename))
         return
 
     def umount(self, state):
-        self._loopdev_detach(state[self.name]['device'])
+        self._loopdev_detach(state['blockdev'][self.name]['device'])
 
     def cleanup(self, state):
         pass
 
     def delete(self, state):
-        self._image_delete(state[self.name]['image'])
+        self._image_delete(state['blockdev'][self.name]['image'])
diff --git a/diskimage_builder/block_device/level1/partitioning.py b/diskimage_builder/block_device/level1/partitioning.py
index 2d79ddb5c..c3c30317a 100644
--- a/diskimage_builder/block_device/level1/partitioning.py
+++ b/diskimage_builder/block_device/level1/partitioning.py
@@ -198,8 +198,8 @@ class Partitioning(PluginBase):
         self._exec_sudo(["kpartx", "-avs", device_path])
 
     def create(self, result, rollback):
-        image_path = result[self.base]['image']
-        device_path = result[self.base]['device']
+        image_path = result['blockdev'][self.base]['image']
+        device_path = result['blockdev'][self.base]['device']
         logger.info("Creating partition on [%s] [%s]" %
                     (self.base, image_path))
 
@@ -229,7 +229,8 @@ class Partitioning(PluginBase):
                 logger.debug("Create partition [%s] [%d]" %
                              (part_name, part_no))
                 partition_device_name = device_path + "p%d" % part_no
-                result[part_name] = {'device': partition_device_name}
+                result['blockdev'][part_name] \
+                    = {'device': partition_device_name}
                 partition_devices.add(partition_device_name)
 
         self.already_created = True
diff --git a/diskimage_builder/lib/disk-image-create b/diskimage_builder/lib/disk-image-create
index cadac5a35..711582092 100644
--- a/diskimage_builder/lib/disk-image-create
+++ b/diskimage_builder/lib/disk-image-create
@@ -419,19 +419,24 @@ fi
 DIB_BLOCK_DEVICE_SCRIPT=$(which dib-block-device)
 
 if [ -z ${IMAGE_BLOCK_DEVICE} ] ; then
-    # For compatibily reasons in addition to the YAML configuration
+    # For compatibility reasons in addition to the YAML configuration
     # there is the need to handle the old environment variables.
     echo "image-size: ${DIB_IMAGE_SIZE}KiB" >> ${DIB_BLOCK_DEVICE_PARAMS_YAML}
 
-    # After changeing the parameters, there is the need to
+    # After changing the parameters, there is the need to
     # re-run dib-block-device init because some value might
     # change based on the new set parameters.
     dib-block-device --phase=init \
                      --params="${DIB_BLOCK_DEVICE_PARAMS_YAML}"
 
     # values to dib-block-device: using the YAML config and
-    IMAGE_BLOCK_DEVICE=$(dib-block-device --phase=create \
-                                          --params="${DIB_BLOCK_DEVICE_PARAMS_YAML}")
+    dib-block-device --phase=create \
+                     --params="${DIB_BLOCK_DEVICE_PARAMS_YAML}"
+
+    # It's called 'DEVICE' but it's the partition.
+    IMAGE_BLOCK_DEVICE=$(dib-block-device \
+                             --phase=getval --symbol=image-block-partition \
+                             --params="${DIB_BLOCK_DEVICE_PARAMS_YAML}")
 fi
 export IMAGE_BLOCK_DEVICE
 LOOPDEV=${IMAGE_BLOCK_DEVICE}
@@ -496,10 +501,13 @@ fi
 # space before converting the image to some other format.
 export EXTRA_UNMOUNT=""
 unmount_image
-TMP_IMAGE_PATH=$(dib-block-device --phase=umount \
+TMP_IMAGE_PATH=$(dib-block-device --phase=getval --symbol=image-path \
                                   --params="${DIB_BLOCK_DEVICE_PARAMS_YAML}")
 export TMP_IMAGE_PATH
 
+dib-block-device --phase=umount \
+                 --params="${DIB_BLOCK_DEVICE_PARAMS_YAML}"
+
 dib-block-device --phase=cleanup \
                  --params="${DIB_BLOCK_DEVICE_PARAMS_YAML}"