[anaconda/rhel7 4/4] Clear bootDisk and bootloader stage info on errors (#1013482)

Brian C. Lane bcl at redhat.com
Thu Oct 3 23:38:19 UTC 2013


From: "Brian C. Lane" <bcl at redhat.com>

If there is an error picking a bootloader stage1 there are a number of
variables that need to be cleared so that stale information isn't used.
This adds a new .reset() method to the bootloader that resets stage1 and
stage2 related items. And calls it before raising stage1 related
BootLoaderErrors.

The ksdata bootloader's bootDisk also need to be reset. It should be
setup after any autopart or custom changes, not before. Now that
un-partitioned disks can be used there are cases where a disk's stage1
status may change. eg. If a raw formatted disk may be partitioned, it
can then be used for stage1.

Also catch any kickstart errors that may show up because of changes (eg.
deselecting the disk used in an --onpart)

Resolves: rhbz#1013482
---
 pyanaconda/bootloader.py            | 19 +++++++++++++------
 pyanaconda/kickstart.py             |  2 +-
 pyanaconda/ui/gui/spokes/custom.py  |  1 +
 pyanaconda/ui/gui/spokes/storage.py |  9 +++++----
 pyanaconda/ui/tui/spokes/storage.py |  4 +++-
 5 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index cf769ed..d127f28 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -274,20 +274,25 @@ class BootLoader(object):
         # default image
         self._default_image = None
 
+        self._update_only = False
+        self.skip_bootloader = False
+
+        self.errors = []
+        self.warnings = []
+
+        self.reset()
+
+    def reset(self):
+        """ Reset stage1 and stage2 values """
         # the device the bootloader will be installed on
         self.stage1_device = None
 
         # the "boot disk", meaning the disk stage1 _will_ go on
         self.stage1_disk = None
 
-        self._update_only = False
-        self.skip_bootloader = False
-
+        self.stage2_device = None
         self.stage2_is_preferred_stage1 = False
 
-        self.errors = []
-        self.warnings = []
-
     #
     # disk list access
     #
@@ -635,6 +640,7 @@ class BootLoader(object):
     def set_stage1_device(self, devices):
         self.stage1_device = None
         if not self.stage1_disk:
+            self.reset()
             raise BootLoaderError("need stage1 disk to set stage1 device")
 
         if self.stage2_is_preferred_stage1:
@@ -650,6 +656,7 @@ class BootLoader(object):
                 break
 
         if not self.stage1_device:
+            self.reset()
             raise BootLoaderError("failed to find a suitable stage1 device")
 
     #
diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py
index a736972..fd9ec1f 100644
--- a/pyanaconda/kickstart.py
+++ b/pyanaconda/kickstart.py
@@ -1677,12 +1677,12 @@ def doKickstartStorage(storage, ksdata, instClass):
     if not any(d for d in storage.disks
                if not d.format.hidden and not d.protected):
         return
-    ksdata.bootloader.execute(storage, ksdata, instClass)
     ksdata.autopart.execute(storage, ksdata, instClass)
     ksdata.partition.execute(storage, ksdata, instClass)
     ksdata.raid.execute(storage, ksdata, instClass)
     ksdata.volgroup.execute(storage, ksdata, instClass)
     ksdata.logvol.execute(storage, ksdata, instClass)
     ksdata.btrfs.execute(storage, ksdata, instClass)
+    # also calls ksdata.bootloader.execute
     storage.setUpBootLoader()
 
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py
index 37cc02b..9bca320 100644
--- a/pyanaconda/ui/gui/spokes/custom.py
+++ b/pyanaconda/ui/gui/spokes/custom.py
@@ -654,6 +654,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
         except BootLoaderError as e:
             log.error("storage configuration failed: %s" % e)
             StorageChecker.errors = str(e).split("\n")
+            self.data.bootloader.bootDrive = ""
 
         StorageChecker.run(self)
         hubQ.send_ready("StorageSpoke", True)
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py
index 2bc4a8b..ac54701 100644
--- a/pyanaconda/ui/gui/spokes/storage.py
+++ b/pyanaconda/ui/gui/spokes/storage.py
@@ -66,6 +66,7 @@ from pyanaconda import constants
 from pyanaconda.bootloader import BootLoaderError
 
 from pykickstart.constants import *
+from pykickstart.errors import KickstartValueError
 
 import sys
 
@@ -362,9 +363,8 @@ class StorageSpoke(NormalSpoke, StorageChecker):
 
         if self.data.bootloader.bootDrive and \
            self.data.bootloader.bootDrive not in self.selected_disks:
-            self.data.bootloader.bootDrive = None
-            self.storage.bootloader.stage1_disk = None
-            self.storage.bootloader.stage1_device = None
+            self.data.bootloader.bootDrive = ""
+            self.storage.bootloader.reset()
 
         self.data.clearpart.initAll = True
         self.data.clearpart.type = self.clearPartType
@@ -392,10 +392,11 @@ class StorageSpoke(NormalSpoke, StorageChecker):
         hubQ.send_message(self.__class__.__name__, _("Saving storage configuration..."))
         try:
             doKickstartStorage(self.storage, self.data, self.instclass)
-        except (StorageError, BootLoaderError) as e:
+        except (StorageError, BootLoaderError, KickstartValueError) as e:
             log.error("storage configuration failed: %s" % e)
             StorageChecker.errors = str(e).split("\n")
             hubQ.send_message(self.__class__.__name__, _("Failed to save storage configuration..."))
+            self.data.bootloader.bootDrive = ""
             self.data.ignoredisk.drives = []
             self.data.ignoredisk.onlyuse = []
             self.storage.config.update(self.data)
diff --git a/pyanaconda/ui/tui/spokes/storage.py b/pyanaconda/ui/tui/spokes/storage.py
index 91d595f..f0e4f26 100644
--- a/pyanaconda/ui/tui/spokes/storage.py
+++ b/pyanaconda/ui/tui/spokes/storage.py
@@ -37,6 +37,7 @@ from pyanaconda.i18n import _, P_
 from pyanaconda.bootloader import BootLoaderError
 
 from pykickstart.constants import CLEARPART_TYPE_ALL, CLEARPART_TYPE_LINUX, CLEARPART_TYPE_NONE
+from pykickstart.errors import KickstartValueError
 
 import logging
 log = logging.getLogger("anaconda")
@@ -252,10 +253,11 @@ class StorageSpoke(NormalTUISpoke):
         print(_("Generating updated storage configuration"))
         try:
             doKickstartStorage(self.storage, self.data, self.instclass)
-        except (StorageError, BootLoaderError) as e:
+        except (StorageError, BootLoaderError, KickstartValueError) as e:
             log.error("storage configuration failed: %s" % e)
             print _("storage configuration failed: %s") % e
             self.errors = [str(e)]
+            self.data.bootloader.bootDrive = ""
             self.data.clearpart.type = CLEARPART_TYPE_ALL
             self.data.clearpart.initAll = False
             self.storage.config.update(self.data)
-- 
1.8.3.1



More information about the anaconda-patches mailing list