There was a previous bug, where kickstart install didn't stop to prompt for a
LUKS password because sanityCheck didn't check if one was there. Unfortunately,
in GUI there are places where sanityCheck is called before user has a chance
to set a password and sometimes before there is any reason even to give them
a chance without making them extremely busy knocking down password dialogs.
I admit I'm still deeply in favor of making prompting for LUKS password have
nothing to do with flow through custom and storage screens. A separate hardware
security hub is still an exciting idea to me. Alternatively, if they check
encrypt checkbox, enable a button "Set LUKS Password" which they can click at
any time, but must have clicked before leaving storage spoke.
Requires some blivet changes, will bump version as appropriate.
The breakdown is:
Removed unused...trivial.
Add sanityCheck...pretty mechanical.
Adapt StorageChecker class...pretty mechanical.
Adapt to new blivet.sanityCheck()...pretty mechanical.
Do not consider no available...a real change, here.
Remove some unnecessary resets...a simple change, but I may be wrong.
Handle LUKS passphrase...pretty important, but fairly obvious, I think. The
important addition is actually setting the passphrase on the format object
where necessary.
Make sure LUKS devices can...this is important, because not only must we
prompt for a passphrase before sanity checking, but also we must actually
set the value for the luks format device.
mulhern (8):
Removed unused ErrorRecoveryFailure import (#1060255)
Add sanityCheck functionality back into AutoPart.execute() (#1060255)
Adapt StorageChecker class for changed return type of sanityCheck
(#1060255)
Adapt to new blivet.sanityCheck() return type (#1060255)
Do not consider no available LUKS passphrase an error in do_autopart
(#1060255)
Remove some unnecessary resets (#1060255)
Handle LUKS passphrase before doing sanity check (#1060255)
Make sure LUKS devices can say they have a key (#1060255)
pyanaconda/kickstart.py | 2 ++
pyanaconda/ui/gui/spokes/custom.py | 57 ++++++++++++++++++++++++++-----------
pyanaconda/ui/gui/spokes/storage.py | 22 ++++++++++----
pyanaconda/ui/tui/spokes/storage.py | 10 ++++---
4 files changed, 65 insertions(+), 26 deletions(-)
--
1.8.3.1
Show replies by date
Related: rhbz#1060255
It's not used and blivet never raises it.
Signed-off-by: mulhern <amulhern(a)redhat.com>
---
pyanaconda/ui/gui/spokes/custom.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py
index b2fdc9b..d878002 100644
--- a/pyanaconda/ui/gui/spokes/custom.py
+++ b/pyanaconda/ui/gui/spokes/custom.py
@@ -61,7 +61,6 @@ from blivet.partitioning import doAutoPartition
from blivet.errors import StorageError
from blivet.errors import NoDisksError
from blivet.errors import NotEnoughFreeSpaceError
-from blivet.errors import ErrorRecoveryFailure
from blivet.errors import CryptoError
from blivet.errors import MDRaidError
from blivet.devicelibs import mdraid
--
1.8.3.1
Related: rhbz#1060255
Since doAutoPartition no longer calls blivet.sanityCheck() need to add in
the call explicitly using partitioning.sanityCheck() in order to get the
correct exception thrown.
Signed-off-by: mulhern <amulhern(a)redhat.com>
---
pyanaconda/kickstart.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py
index 2251b2a..347f925 100644
--- a/pyanaconda/kickstart.py
+++ b/pyanaconda/kickstart.py
@@ -238,6 +238,7 @@ class Authconfig(commands.authconfig.FC3_Authconfig):
class AutoPart(commands.autopart.F20_AutoPart):
def execute(self, storage, ksdata, instClass):
from blivet.partitioning import doAutoPartition
+ from blivet.partitioning import sanityCheck
if not self.autopart:
return
@@ -258,6 +259,7 @@ class AutoPart(commands.autopart.F20_AutoPart):
storage.autoPartType = self.type
doAutoPartition(storage, ksdata)
+ sanityCheck(storage)
class Bootloader(commands.bootloader.F19_Bootloader):
def __init__(self, *args, **kwargs):
--
1.8.3.1
Related: rhbz#1060255
sanityCheck returns lists of SanityErrors with string messages,
not lists of strings. Adapt checkStorage appropriately.
Signed-off-by: mulhern <amulhern(a)redhat.com>
---
pyanaconda/ui/gui/spokes/storage.py | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py
index f14a681..905db6e 100644
--- a/pyanaconda/ui/gui/spokes/storage.py
+++ b/pyanaconda/ui/gui/spokes/storage.py
@@ -217,6 +217,11 @@ class InstallOptions2Dialog(InstallOptionsDialogBase):
self._add_modify_watcher("options2_label1")
class StorageChecker(object):
+ """An abstract class for logging storage errors and warnings.
+
+ Treats all errors as strings, so they are not very informative about
+ their meaning.
+ """
errors = []
warnings = []
_mainSpokeClass = "StorageSpoke"
@@ -230,13 +235,15 @@ class StorageChecker(object):
hubQ.send_not_ready(self._mainSpokeClass)
hubQ.send_message(self._mainSpokeClass, _("Checking storage
configuration..."))
- (StorageChecker.errors,
- StorageChecker.warnings) = self.storage.sanityCheck()
+ (errors, warnings) = self.storage.sanityCheck()
+ errors = [error.message for error in errors]
+ warnings = [warning.message for warning in warnings]
+ (StorageChecker.errors, StorageChecker.warnings) = (errors, warnings)
hubQ.send_ready(self._mainSpokeClass, True)
for e in StorageChecker.errors:
log.error(e)
for w in StorageChecker.warnings:
- log.warn(w)
+ log.warning(w)
class StorageSpoke(NormalSpoke, StorageChecker):
builderObjects = ["storageWindow", "addSpecializedImage"]
--
1.8.3.1
Related: rhbz#1060255
blivet.sanityCheck() returns lists of SanityErrors with string messages,
not lists of strings. Change StorageSpoke.execute() appropriately.
Also change log.warn to log.warning.
Signed-off-by: mulhern <amulhern(a)redhat.com>
---
pyanaconda/ui/tui/spokes/storage.py | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/pyanaconda/ui/tui/spokes/storage.py b/pyanaconda/ui/tui/spokes/storage.py
index 05cf122..914ef01 100644
--- a/pyanaconda/ui/tui/spokes/storage.py
+++ b/pyanaconda/ui/tui/spokes/storage.py
@@ -307,11 +307,13 @@ class StorageSpoke(NormalTUISpoke):
(self.errors, self.warnings) = self.storage.sanityCheck()
self._ready = True
for e in self.errors:
- log.error(e)
- print e
+ msg = e.message
+ log.error(msg)
+ print(msg)
for w in self.warnings:
- log.warn(w)
- print w
+ msg = w.message
+ log.warning(msg)
+ print(msg)
def initialize(self):
NormalTUISpoke.initialize(self)
--
1.8.3.1
Resolves: rhbz#1060255
doAutoPart no longer runs sanityCheck.
So, the new strategy is:
1) Run doAutoPart and catch any actual Errors.
2) When all that is done, run sanityCheck and deal with those errors.
Signed-off-by: mulhern <amulhern(a)redhat.com>
---
pyanaconda/ui/gui/spokes/custom.py | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py
index d878002..b15ef15 100644
--- a/pyanaconda/ui/gui/spokes/custom.py
+++ b/pyanaconda/ui/gui/spokes/custom.py
@@ -63,6 +63,7 @@ from blivet.errors import NoDisksError
from blivet.errors import NotEnoughFreeSpaceError
from blivet.errors import CryptoError
from blivet.errors import MDRaidError
+from blivet.errors import LUKSDeviceWithoutKeyError
from blivet.devicelibs import mdraid
from blivet.devices import LUKSDevice
@@ -2627,7 +2628,13 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
self._removeButton.set_sensitive(True)
def _do_autopart(self):
- # There are never any non-existent devices around when this runs.
+ """Helper function for on_create_clicked.
+ Assumes a non-final context in which at least some errors
+ discovered by sanityCheck are not considered fatal because they
+ will be dealt with later.
+
+ Note: There are never any non-existent devices around when this runs.
+ """
log.debug("running automatic partitioning")
self.__storage.doAutoPart = True
self.clear_errors()
@@ -2663,6 +2670,22 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
self.__storage.doAutoPart = False
log.debug("finished automatic partitioning")
+ (errors, warnings) = self.__storage.sanityCheck()
+ errors = [error for error in errors if not isinstance(error,
LUKSDeviceWithoutKeyError)]
+ for error in errors:
+ log.error(error.message)
+ for warning in warnings:
+ log.warning(warning.message)
+
+ if errors:
+ messages = "\n".join(error.message for error in errors)
+ log.error("doAutoPartition failed: %s" % messages)
+ self._reset_storage()
+ self._error = messages
+ self.set_error(_("Automatic partitioning failed. Click "
+ "for details."))
+ self.window.show_all()
+
def on_create_clicked(self, button, autopartTypeCombo):
# Then do autopartitioning. We do not do any clearpart first. This is
# custom partitioning, so you have to make your own room.
--
1.8.3.1
Related: rhbz#1060255
These are unnecessary now that doAutoPartition() no longer calls
sanityCheck().
Signed-off-by: mulhern <amulhern(a)redhat.com>
---
pyanaconda/ui/gui/spokes/storage.py | 3 ---
1 file changed, 3 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py
index 905db6e..2fef10d 100644
--- a/pyanaconda/ui/gui/spokes/storage.py
+++ b/pyanaconda/ui/gui/spokes/storage.py
@@ -377,9 +377,6 @@ class StorageSpoke(NormalSpoke, StorageChecker):
self.data.bootloader.bootDrive = ""
else:
if self.autopart:
- # this was already run as part of doAutoPartition. dumb.
- StorageChecker.errors = []
- StorageChecker.warnings = []
self.run()
finally:
self._ready = True
--
1.8.3.1
Resolves: rhbz#1060255
The sanity check checks that a LUKS passphrase has been set, so we want to give
the user the opportunity to set that passphrase if the occasion calls for it.
Signed-off-by: mulhern <amulhern(a)redhat.com>
---
pyanaconda/ui/gui/spokes/custom.py | 31 +++++++++++++++++--------------
1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py
index b15ef15..21bc4e4 100644
--- a/pyanaconda/ui/gui/spokes/custom.py
+++ b/pyanaconda/ui/gui/spokes/custom.py
@@ -1985,6 +1985,23 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
self.__storage.devicetree.pruneActions()
self.__storage.devicetree.sortActions()
+ new_luks = [d for d in self.__storage.devices
+ if d.format.type == "luks" and not d.format.exists]
+ if new_luks:
+ dialog = PassphraseDialog(self.data)
+ with enlightbox(self.window, dialog.window):
+ rc = dialog.run()
+
+ if rc == 0:
+ # Cancel. Leave the old passphrase set if there was one.
+ return
+
+ self.passphrase = dialog.passphrase
+
+ for luks in new_luks:
+ if not luks.format.hasKey:
+ luks.format.passphrase = self.passphrase
+
# If back has been clicked on once already and no other changes made on the
screen,
# run the storage check now. This handles displaying any errors in the info
bar.
if not self._back_already_clicked:
@@ -2002,20 +2019,6 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
# Cancel. Stay on the custom screen.
return
- # Then if they did anything that resulted in new LUKS devices, we need
- # to prompt for passphrases.
- new_luks = any(d for d in self.__storage.devices
- if d.format.type == "luks" and not d.format.exists)
- if new_luks:
- dialog = PassphraseDialog(self.data)
- with enlightbox(self.window, dialog.window):
- rc = dialog.run()
-
- if rc == 0:
- # Cancel. Leave the old passphrase set if there was one.
- return
-
- self.passphrase = dialog.passphrase
NormalSpoke.on_back_clicked(self, button)
--
1.8.3.1
Resolves: rhbz#1060255
If we're prompting for a passphrase then we should set up the LUKS devices
with something so that they don't fail the sanity check.
Signed-off-by: mulhern <amulhern(a)redhat.com>
---
pyanaconda/ui/gui/spokes/storage.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py
index 2fef10d..6232af1 100644
--- a/pyanaconda/ui/gui/spokes/storage.py
+++ b/pyanaconda/ui/gui/spokes/storage.py
@@ -726,6 +726,12 @@ class StorageSpoke(NormalSpoke, StorageChecker):
return False
self.passphrase = dialog.passphrase
+
+ for device in self.storage.devices:
+ if device.format.type == "luks" and not device.format.exists:
+ if not device.format.hasKey:
+ device.format.passphrase = self.passphrase
+
return True
def on_back_clicked(self, button):
--
1.8.3.1