On Tue, 2014-11-11 at 13:47 -0500, David Shea wrote:
Add a unsetup method to Payload that is called by PayloadManager
when
setting up a payload fails. For dnf and tarpayload, just unset
some attributes during unsetup, for live unmount the tree, and for
yumpayload unset the _setup flag and expand the flag's use to disable
access to the yum comps magic properties.
This fixes a problem that is most troublesome with yum, where the setup
for a kickstart or command-line repo can fail, and a later variable
access in the software spoke will start yum downloading metadata from
somewhere else and setting half of the variables that we expect and
crashing. By invalidating the payload we avoid the accidental fallback
to the wrong repos.
---
pyanaconda/packaging/__init__.py | 8 ++++++++
pyanaconda/packaging/dnfpayload.py | 4 ++++
pyanaconda/packaging/livepayload.py | 13 +++++++++++++
pyanaconda/packaging/tarpayload.py | 4 ++++
pyanaconda/packaging/yumpayload.py | 7 +++++++
5 files changed, 36 insertions(+)
diff --git a/pyanaconda/packaging/__init__.py b/pyanaconda/packaging/__init__.py
index 9a82c77..df9b55c 100644
--- a/pyanaconda/packaging/__init__.py
+++ b/pyanaconda/packaging/__init__.py
@@ -138,6 +138,11 @@ class Payload(object):
self.storage = storage
self.instclass = instClass
+ def unsetup(self):
+ """ Invalidate a previously setup paylaod. """
+ self.storage = None
+ self.instclass = None
+
def preStorage(self):
""" Do any payload-specific work necessary before writing the
storage
configuration. This method need not be provided by all payloads.
@@ -1243,6 +1248,7 @@ class PayloadManager(object):
log.error("PayloadError: %s", e)
self._error = self.ERROR_SETUP
self._setState(self.STATE_ERROR)
+ payload.unsetup()
return
# Gather the group data
@@ -1255,6 +1261,7 @@ class PayloadManager(object):
log.error("No base repo configured")
self._error = self.ERROR_MD
self._setState(self.STATE_ERROR)
+ payload.unsetup()
return
try:
@@ -1271,6 +1278,7 @@ class PayloadManager(object):
log.error("MetadataError: %s", e)
self._error = self.ERROR_SOURCE
self._setState(self.STATE_ERROR)
+ payload.unsetup()
return
self._setState(self.STATE_FINISHED)
diff --git a/pyanaconda/packaging/dnfpayload.py b/pyanaconda/packaging/dnfpayload.py
index 08c3d2f..64affc9 100644
--- a/pyanaconda/packaging/dnfpayload.py
+++ b/pyanaconda/packaging/dnfpayload.py
@@ -189,6 +189,10 @@ class DNFPayload(packaging.PackagePayload):
self._base = None
self._configure()
+ def unsetup(self):
+ super(DNFPayload, self).unsetup()
+ self._base = None
+
def _add_repo(self, ksrepo):
"""Add a repo to the dnf repo object
diff --git a/pyanaconda/packaging/livepayload.py b/pyanaconda/packaging/livepayload.py
index 729d40c..4810837 100644
--- a/pyanaconda/packaging/livepayload.py
+++ b/pyanaconda/packaging/livepayload.py
@@ -83,6 +83,15 @@ class LiveImagePayload(ImagePayload):
source = iutil.eintr_retry_call(os.statvfs, INSTALL_TREE)
self.source_size = source.f_frsize * (source.f_blocks - source.f_bfree)
+ def unsetup(self):
+ super(LiveImagePayload, self).unsetup()
+
+ # Unmount a previously mounted live tree
+ try:
+ blivet.util.umount(INSTALL_TREE)
+ except OSError:
+ pass
+
def preInstall(self, packages=None, groups=None):
""" Perform pre-installation tasks. """
super(LiveImagePayload, self).preInstall(packages=packages, groups=groups)
@@ -274,6 +283,10 @@ class LiveImageKSPayload(LiveImagePayload):
log.debug("liveimg size is %s", self._min_size)
+ def unsetup(self):
+ # Skip LiveImagePayload's unsetup method
+ ImagePayload.unsetup(self)
+
def preInstall(self, *args, **kwargs):
""" Download image and loopback mount it.
diff --git a/pyanaconda/packaging/tarpayload.py b/pyanaconda/packaging/tarpayload.py
index 74db9b4..b6328e0 100644
--- a/pyanaconda/packaging/tarpayload.py
+++ b/pyanaconda/packaging/tarpayload.py
@@ -61,6 +61,10 @@ class TarPayload(ArchivePayload):
log.error("opening tar archive %s: %s", self.image_file, e)
raise PayloadError("invalid payload format")
+ def unsetup(self):
+ super(TarPayload, self).unsetup()
+ self.archive = None
+
@property
def requiredSpace(self):
byte_count = sum(m.size for m in self.archive.getmembers())
diff --git a/pyanaconda/packaging/yumpayload.py b/pyanaconda/packaging/yumpayload.py
index c183e19..43e7d3e 100644
--- a/pyanaconda/packaging/yumpayload.py
+++ b/pyanaconda/packaging/yumpayload.py
@@ -196,6 +196,10 @@ class YumPayload(PackagePayload):
self._writeYumConfig()
self._setup = True
+ def unsetup(self):
+ super(YumPayload, self).unsetup()
+ self._setup = False
+
def _resetYum(self, root=None, keep_cache=False, releasever=None):
""" Delete and recreate the payload's YumBase instance.
@@ -998,6 +1002,9 @@ reposdir=%s
@property
def _yumGroups(self):
""" yum.comps.Comps instance. """
+ if not self._setup:
+ return []
+
from yum.Errors import RepoError, GroupsError
with _yum_lock:
if not self._groups:
Looks good to me.
--
Vratislav Podzimek
Anaconda Rider | RHCE | Red Hat, Inc. | Brno - Czech Republic