[PATCH] Give users way to select DD ISO interactively (#1036765)

Vratislav Podzimek vpodzime at redhat.com
Mon Jan 20 16:38:46 UTC 2014


In loader there have been menus that allowed interactive selection of driver
disk ISO file by choosing from disks, partitions and finally ISO files. This
patch does the same in our DD dracut code.

Signed-off-by: Vratislav Podzimek <vpodzime at redhat.com>
---
 dracut/driver-updates | 119 +++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 109 insertions(+), 10 deletions(-)

diff --git a/dracut/driver-updates b/dracut/driver-updates
index cdcddc9..6d1770c 100755
--- a/dracut/driver-updates
+++ b/dracut/driver-updates
@@ -541,6 +541,102 @@ def network_driver(dd_path):
     # Scan for new OEMDRV devices
     dd_scan(skip_dds)
 
+def simple_choice_menu(items, question):
+    """ Let user choose from the list of items. """
+
+    ret = None
+    while not ret:
+        for i, item in enumerate(items):
+            print "%2d) %s" % (i+1, item)
+        ans = raw_input(question)
+        try:
+            choice = int(ans) - 1
+            ret = items[choice]
+        except ValueError, IndexError:
+            if ans == "q":
+                return None
+            else:
+                continue
+
+    # put blank line below the menu
+    print
+
+    return ret
+
+def select_iso():
+    """ Let user select device, partition and dd iso. """
+
+    dev_prefix = "/dev/"
+    _ret, out = run_cmd(["blkid", "-o", "device"])
+    stripped_lines = (line.strip() for line in out.splitlines())
+    devices = [line[len(dev_prefix):] for line in stripped_lines]
+
+    prefixes_devices = dict()
+    for dev in devices:
+        no_nums = dev.rstrip("0123456789")
+        if no_nums not in prefixes_devices:
+            prefixes_devices[no_nums] = [dev]
+        else:
+            prefixes_devices[no_nums].append(dev)
+
+    top_level_devs = set()
+    for prefix, devs in prefixes_devices.iteritems():
+        if len(devs) > 1:
+            top_level_devs.add(prefix)
+        else:
+            top_level_devs.add(devs[0])
+
+    # let user choose from top_level devs
+    top_level_devs = sorted(top_level_devs)
+    print "Driver disk device selection (some choices may lead to additional menus)"
+    print "========================================================================"
+    top_dev = simple_choice_menu(top_level_devs,
+                                 "Select device from above (or 'q' to quit): ")
+    if not top_dev:
+        return
+
+    # let user choose from sub devices
+    sub_devs = sorted(dev for dev in devices if dev.startswith(top_dev))
+    if len(sub_devs) == 1:
+        iso_dev = sub_devs[0]
+    else:
+        iso_dev = simple_choice_menu(sub_devs,
+                                     "Select device from above (or 'q' to quit): ")
+        if not iso_dev:
+            return
+
+    mnt = "/media/DD-search"
+    if not os.path.isdir(mnt):
+        os.makedirs(mnt)
+    if not mount_device("/dev/" + iso_dev, mnt):
+        print "===Cannot mount the chosen device!===\n"
+        select_iso()
+        return
+
+    isos = list()
+    for _path, _dirs, files in os.walk(mnt):
+        isos += (iso_file for iso_file in files if iso_file.endswith(".iso"))
+
+    if not isos:
+        print "===No ISO files found on %s!===\n" % iso_dev
+        umount(mnt)
+        select_iso()
+        return
+    else:
+        # mount writes out some mounting information, add blank line
+        print
+
+    # let user choose the ISO file
+    print "Choose driver disk ISO file"
+    print "==========================="
+    dd_iso = simple_choice_menu(isos,
+                                "Select ISO file from above (or 'q' to quit): ")
+
+    if not dd_iso:
+        return
+
+    select_dd("/media/DD-search/" + dd_iso)
+    umount(mnt)
 
 def dd_scan(skip_dds=None):
     """ Scan the system for OEMDRV devices and and specified by dd=/dev/<device>
@@ -564,16 +660,19 @@ def dd_scan(skip_dds=None):
         dd_todo.update(dd_devs)
         log.info("Checking devices %s" % ", ".join(dd_todo))
 
-    # Process each Driver Disk, checking for new disks after each one
-    while dd_todo:
-        device = dd_todo.pop()
-        log.info("Checking device %s" % device)
-        select_dd(device)
-        dd_finished.update([device])
-        new_oemdrv = set(oemdrv_list()).difference(dd_finished, dd_todo)
-        if new_oemdrv:
-            log.info("Found new OEMDRV device(s) - %s" % ", ".join(new_oemdrv))
-        dd_todo.update(new_oemdrv)
+    if not dd_todo:
+        select_iso()
+    else:
+        # Process each Driver Disk, checking for new disks after each one
+        while dd_todo:
+            device = dd_todo.pop()
+            log.info("Checking device %s" % device)
+            select_dd(device)
+            dd_finished.update([device])
+            new_oemdrv = set(oemdrv_list()).difference(dd_finished, dd_todo)
+            if new_oemdrv:
+                log.info("Found new OEMDRV device(s) - %s" % ", ".join(new_oemdrv))
+            dd_todo.update(new_oemdrv)
 
 
 if __name__ == '__main__':
-- 
1.8.4.2



More information about the anaconda-patches mailing list