On Thu, 2013-12-19 at 16:48 -0800, Brian C. Lane wrote:
From: "Brian C. Lane" <bcl(a)redhat.com>
The completed spoke method can be called before the spoke has finished
initializing itself in cases where the spoke launches its initialize
method in a thread. This can lead to attributes being accessed before
they are ready (namely yum related items).
This adds a check for self.ready to the source and software completed
methods and re-orders the checks so that ready will short out access to
problem attributes like baseRepo.
It also adds some warning docstrings so we don't forget why this can
be a problem.
Resolves: rhbz#1044985
ACK
---
pyanaconda/ui/common.py | 4 ++++
pyanaconda/ui/gui/spokes/__init__.py | 4 ++++
pyanaconda/ui/gui/spokes/source.py | 5 ++++-
pyanaconda/ui/tui/spokes/software.py | 12 ++++++++----
pyanaconda/ui/tui/spokes/source.py | 2 +-
5 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/pyanaconda/ui/common.py b/pyanaconda/ui/common.py
index 6fc51ae..f73f3d2 100644
--- a/pyanaconda/ui/common.py
+++ b/pyanaconda/ui/common.py
@@ -282,6 +282,10 @@ class Spoke(UIObject):
spoke, and a highlighted message will be shown at the bottom of the
Hub. Installation will not be allowed to proceed until all mandatory
spokes are complete.
+
+ WARNING: This can be called before the spoke is finished initializing
+ if the spoke starts a thread. It should make sure it doesn't access
+ things until they are completely setup.
"""
return False
diff --git a/pyanaconda/ui/gui/spokes/__init__.py b/pyanaconda/ui/gui/spokes/__init__.py
index c1a35b3..3581668 100644
--- a/pyanaconda/ui/gui/spokes/__init__.py
+++ b/pyanaconda/ui/gui/spokes/__init__.py
@@ -43,6 +43,10 @@ class Spoke(GUIObject):
icon will be shown on the Hub beside the spoke, and a highlighted
message will be shown at the bottom of the Hub. Installation will not
be allowed to proceed until all spokes are complete.
+
+ WARNING: This can be called before the spoke is finished initializing
+ if the spoke starts a thread. It should make sure it doesn't access
+ things until they are completely setup.
"""
return False
diff --git a/pyanaconda/ui/gui/spokes/source.py b/pyanaconda/ui/gui/spokes/source.py
index 67aeab3..431acf1 100644
--- a/pyanaconda/ui/gui/spokes/source.py
+++ b/pyanaconda/ui/gui/spokes/source.py
@@ -485,7 +485,10 @@ class SourceSpoke(NormalSpoke):
@property
def completed(self):
- if flags.automatedInstall and (not self.data.method.method or not
self.payload.baseRepo):
+ """ WARNING: This can be called before _initialize is done, make
sure that it
+ doesn't access things that are not setup (eg. payload.*) until it is
ready
+ """
+ if flags.automatedInstall and self.ready and (not self.data.method.method or not
self.payload.baseRepo):
return False
else:
return not self._error and self.ready and (self.data.method.method or
self.payload.baseRepo)
diff --git a/pyanaconda/ui/tui/spokes/software.py b/pyanaconda/ui/tui/spokes/software.py
index 3c88445..e1ecfae 100644
--- a/pyanaconda/ui/tui/spokes/software.py
+++ b/pyanaconda/ui/tui/spokes/software.py
@@ -103,14 +103,18 @@ class SoftwareSpoke(NormalTUISpoke):
@property
def completed(self):
- """ Make sure our threads are done running and vars are set.
"""
- processingDone = not threadMgr.get(THREAD_CHECK_SOFTWARE) and \
- not self.errors and self.txid_valid
+ """ Make sure our threads are done running and vars are set.
+
+ WARNING: This can be called before the spoke is finished initializing
+ if the spoke starts a thread. It should make sure it doesn't access
+ things until they are completely setup.
+ """
+ processingDone = self.ready and not self.errors and self.txid_valid
if flags.automatedInstall:
return processingDone and self.payload.baseRepo and self.data.packages.seen
else:
- return self.payload.baseRepo and self.environment is not None and
processingDone
+ return processingDone and self.payload.baseRepo and self.environment is not
None
def refresh(self, args=None):
""" Refresh screen. """
diff --git a/pyanaconda/ui/tui/spokes/source.py b/pyanaconda/ui/tui/spokes/source.py
index b1aed2d..aefdb0f 100644
--- a/pyanaconda/ui/tui/spokes/source.py
+++ b/pyanaconda/ui/tui/spokes/source.py
@@ -221,7 +221,7 @@ class SourceSpoke(SourceSwitchHandler, EditTUISpoke):
@property
def completed(self):
- if flags.automatedInstall and (not self.data.method.method or not
self.payload.baseRepo):
+ if flags.automatedInstall and self.ready and (not self.data.method.method or not
self.payload.baseRepo):
return False
else:
return not self.errors and self.ready and (self.data.method.method or
self.payload.baseRepo)