--- pyanaconda/packaging/__init__.py | 4 ++++ pyanaconda/packaging/livepayload.py | 4 ++++ 2 files changed, 8 insertions(+)
diff --git a/pyanaconda/packaging/__init__.py b/pyanaconda/packaging/__init__.py index a8388e7..7642d2f 100644 --- a/pyanaconda/packaging/__init__.py +++ b/pyanaconda/packaging/__init__.py @@ -523,6 +523,10 @@ class Payload(object):
:returns: None """ + if not os.path.exists(iutil.getSysroot() + "/usr/sbin/new-kernel-pkg"): + log.error("new-kernel-pkg does not exist - grubby wasn't installed? skipping") + return + for kernel in self.kernelVersionList: log.info("recreating initrd for %s", kernel) if not flags.imageInstall: diff --git a/pyanaconda/packaging/livepayload.py b/pyanaconda/packaging/livepayload.py index f582219..ed3f073 100644 --- a/pyanaconda/packaging/livepayload.py +++ b/pyanaconda/packaging/livepayload.py @@ -164,6 +164,10 @@ class LiveImagePayload(ImagePayload): threadMgr.wait(THREAD_LIVE_PROGRESS)
# Live needs to create the rescue image before bootloader is written + if not os.path.exists(iutil.getSysroot() + "/usr/sbin/new-kernel-pkg"): + log.error("new-kernel-pkg does not exist - grubby wasn't installed? skipping") + return + for kernel in self.kernelVersionList: log.info("Generating rescue image for %s", kernel) iutil.execInSysroot("new-kernel-pkg",
We can't really use dnf the same way we were using yum here. With yum, we were treating the transaction as a thing we could add and remove stuff from as much as we wanted and then when we were done, tell yum to go ahead and do it. dnf doesn't work that way - we need to keep track of the additions and removals in anaconda, and then when we are done tell dnf the result.
Thus:
(1) For groups, we implement selectEnvironment ourselves. Just check that the group is not in the excluded list when adding. Same for when iterating over the list of groups to add.
(2) For packages, make sure they're not in the excluded list when adding. For a package to remove that is part of a group we are installing, we are already passing the excluded list along to dnf. That should work.
(3) Remove _remove_package and _remove_group, since they don't (and won't) work. --- pyanaconda/packaging/__init__.py | 10 +++++++--- pyanaconda/packaging/dnfpayload.py | 40 +++++++------------------------------- 2 files changed, 14 insertions(+), 36 deletions(-)
diff --git a/pyanaconda/packaging/__init__.py b/pyanaconda/packaging/__init__.py index 7642d2f..4aad56c 100644 --- a/pyanaconda/packaging/__init__.py +++ b/pyanaconda/packaging/__init__.py @@ -1033,12 +1033,16 @@ class PackagePayload(Payload): def environmentDescription(self, environmentid): raise NotImplementedError()
- def selectEnvironment(self, environmentid): + def selectEnvironment(self, environmentid, excluded=None): if environmentid not in self.environments: raise NoSuchGroup(environmentid)
- # Select each group within the environment - for groupid in self.environmentGroups(environmentid, optional=False): + if excluded is None: + excluded = [] + + # Select each group within the environment, as long as that group was + # not explicitly excluded by the user. + for groupid in set(self.environmentGroups(environmentid, optional=False)) - set(excluded): self.selectGroup(groupid)
def environmentGroups(self, environmentid, optional=True): diff --git a/pyanaconda/packaging/dnfpayload.py b/pyanaconda/packaging/dnfpayload.py index 36598f5..288c49e 100644 --- a/pyanaconda/packaging/dnfpayload.py +++ b/pyanaconda/packaging/dnfpayload.py @@ -282,46 +282,36 @@ class DNFPayload(packaging.PackagePayload): elif self.data.packages.environment: env = self.data.packages.environment
+ excludedGroups = [group.name for group in self.data.packages.excludedGroupList] + if env: try: - self.selectEnvironment(env) + self.selectEnvironment(env, excludedGroups) log.info("selected env: %s", env) except packaging.NoSuchGroup as e: self._miss(e)
for group in self.data.packages.groupList: - if group.name == 'core': + if group.name == 'core' or group.name in excludedGroups: continue + default = group.include in (GROUP_ALL, GROUP_DEFAULT) optional = group.include == GROUP_ALL + try: self._select_group(group.name, default=default, optional=optional) log.info("selected group: %s", group.name) except packaging.NoSuchGroup as e: self._miss(e)
- for group in self.data.packages.excludedGroupList: - try: - self._deselect_group(group.name) - log.info("deselected group: %s", group.name) - except packaging.NoSuchGroup: - log.info("skipped removing nonexistant group: %s", group.name) - - for pkg_name in self.data.packages.packageList: + for pkg_name in set(self.data.packages.packageList) - set(self.data.packages.excludedList): try: self._install_package(pkg_name) log.info("selected package: '%s'", pkg_name) except packaging.NoSuchPackage as e: self._miss(e)
- for pkg_name in self.data.packages.excludedList: - try: - self._remove_package(pkg_name) - log.info("removed package: %s", pkg_name) - except packaging.NoSuchPackage: - log.info("skipped removing nonexistant package: %s", pkg_name) - self._select_kernel_package()
for pkg_name in self.requiredPackages: @@ -386,12 +376,6 @@ class DNFPayload(packaging.PackagePayload): except dnf.exceptions.MarkingError: raise packaging.NoSuchPackage(pkg_name, required=required)
- def _remove_package(self, pkg_name): - try: - return self._base.remove(pkg_name) - except dnf.exceptions.PackagesNotInstalledError: - raise packaging.NoSuchPackage(pkg_name) - def _miss(self, exn): if self.data.packages.handleMissing == KS_MISSING_IGNORE: return @@ -438,16 +422,6 @@ class DNFPayload(packaging.PackagePayload): # DNF raises this when it is already selected log.debug(e)
- def _deselect_group(self, group_id): - grp = self._base.comps.group_by_pattern(group_id) - if grp is None: - raise packaging.NoSuchGroup(group_id) - try: - self._base.group_remove(grp) - except dnf.exceptions.CompsError as e: - # DNF raises this when it is already not selected - log.debug(e) - def _select_kernel_package(self): kernels = self.kernelPackages for kernel in kernels:
--- Makefile.am | 4 ---- tests/pylint/runpylint.sh | 5 ++--- 2 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/Makefile.am b/Makefile.am index 7f7478b..5945109 100644 --- a/Makefile.am +++ b/Makefile.am @@ -128,10 +128,6 @@ updates: fi ; \ ( cd $(srcdir) && scripts/makeupdates $${opts} -b '$(abs_builddir)' )
-# UNIT TESTING TARGETS -unittests-logpicker: - PYTHONPATH=$(builddir)/pyanaconda/isys/.libs:tests/:$(srcdir):utils/ nosetests -v old_tests/logpicker_test - # GUI TESTING runglade: ANACONDA_DATA=$(srcdir)/data \ diff --git a/tests/pylint/runpylint.sh b/tests/pylint/runpylint.sh index 936fa5f..58e895d 100755 --- a/tests/pylint/runpylint.sh +++ b/tests/pylint/runpylint.sh @@ -117,10 +117,9 @@ fi # confused if [ -z "$FILES" ]; then # Test any file that either ends in .py or contains #!/usr/bin/python2 in - # the first line. Scan everything except old_tests + # the first line. FILES=$(findtestfiles ( -name '*.py' -o \ - -exec /bin/sh -c "head -1 {} | grep -q '#!/usr/bin/python2'" ; ) -print | \ - egrep -v '(|/)old_tests/') + -exec /bin/sh -c "head -1 {} | grep -q '#!/usr/bin/python2'" ; ) -print) fi
# run pylint in paralel
In python3, the standard Queue.py has been renamed to queue.py, so anything in the standard library that imports queue will get confused if pyanaconda is at the front of PYTHONPATH. It's best to just stay out of the way. --- pyanaconda/progress.py | 2 +- pyanaconda/queue.py | 78 ------------------------------------------ pyanaconda/queuefactory.py | 78 ++++++++++++++++++++++++++++++++++++++++++ pyanaconda/ui/communication.py | 2 +- 4 files changed, 80 insertions(+), 80 deletions(-) delete mode 100644 pyanaconda/queue.py create mode 100644 pyanaconda/queuefactory.py
diff --git a/pyanaconda/progress.py b/pyanaconda/progress.py index dc7a38c..f1d20ad 100644 --- a/pyanaconda/progress.py +++ b/pyanaconda/progress.py @@ -23,7 +23,7 @@ log = logging.getLogger("anaconda")
from contextlib import contextmanager
-from pyanaconda.queue import QueueFactory +from pyanaconda.queuefactory import QueueFactory
# A queue to be used for communicating progress information between a subthread # doing all the hard work and the main thread that does the GTK updates. This diff --git a/pyanaconda/queue.py b/pyanaconda/queue.py deleted file mode 100644 index 31f6a54..0000000 --- a/pyanaconda/queue.py +++ /dev/null @@ -1,78 +0,0 @@ -# -# queue.py: factory for creating communications channels -# -# Copyright (C) 2013 Red Hat, Inc. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# -# Author(s): Chris Lumens clumens@redhat.com - -import Queue -from pyanaconda.iutil import lowerASCII, upperASCII - -class QueueFactory(object): - """Constructs a new object wrapping a Queue.Queue, complete with constants - and sending functions for each type of message that can be put into the - queue. - - Creating a new object using this class is done like so: - - q = QueueFactory("progress") - - And then adding messages to it is done like so: - - q.addMessage("init", 0) - q.addMessage("step", 1) - - The first call will create a new constant named PROGRESS_CODE_INIT and a - method named send_init that takes zero arguments. The second call will - create a new constant named PROGRESS_CODE_STEP and a method named send_step - that takes one argument. - - Reusing names within the same class is not allowed. - """ - def __init__(self, name): - self.name = name - - self.__counter = 0 - self.__names = [] - - self.q = Queue.Queue() - - def _makeMethod(self, constant, methodName, argc): - def __method(*args): - if len(args) != argc: - raise TypeError("%s() takes exactly %d arguments (%d given)" % - (methodName, argc, len(args))) - - self.q.put((constant, args)) - - __method.__name__ = methodName - return __method - - def addMessage(self, name, argc): - if name in self.__names: - raise AttributeError("%s queue already has a message named %s" % (self.name, name)) - - # Add a constant. - const_name = upperASCII(self.name) + "_CODE_" + upperASCII(name) - setattr(self, const_name, self.__counter) - self.__counter += 1 - - # Add a convenience method for putting things into the queue. - method_name = "send_" + lowerASCII(name) - method = self._makeMethod(getattr(self, const_name), method_name, argc) - setattr(self, method_name, method) - - self.__names.append(name) diff --git a/pyanaconda/queuefactory.py b/pyanaconda/queuefactory.py new file mode 100644 index 0000000..31f6a54 --- /dev/null +++ b/pyanaconda/queuefactory.py @@ -0,0 +1,78 @@ +# +# queue.py: factory for creating communications channels +# +# Copyright (C) 2013 Red Hat, Inc. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# Author(s): Chris Lumens clumens@redhat.com + +import Queue +from pyanaconda.iutil import lowerASCII, upperASCII + +class QueueFactory(object): + """Constructs a new object wrapping a Queue.Queue, complete with constants + and sending functions for each type of message that can be put into the + queue. + + Creating a new object using this class is done like so: + + q = QueueFactory("progress") + + And then adding messages to it is done like so: + + q.addMessage("init", 0) + q.addMessage("step", 1) + + The first call will create a new constant named PROGRESS_CODE_INIT and a + method named send_init that takes zero arguments. The second call will + create a new constant named PROGRESS_CODE_STEP and a method named send_step + that takes one argument. + + Reusing names within the same class is not allowed. + """ + def __init__(self, name): + self.name = name + + self.__counter = 0 + self.__names = [] + + self.q = Queue.Queue() + + def _makeMethod(self, constant, methodName, argc): + def __method(*args): + if len(args) != argc: + raise TypeError("%s() takes exactly %d arguments (%d given)" % + (methodName, argc, len(args))) + + self.q.put((constant, args)) + + __method.__name__ = methodName + return __method + + def addMessage(self, name, argc): + if name in self.__names: + raise AttributeError("%s queue already has a message named %s" % (self.name, name)) + + # Add a constant. + const_name = upperASCII(self.name) + "_CODE_" + upperASCII(name) + setattr(self, const_name, self.__counter) + self.__counter += 1 + + # Add a convenience method for putting things into the queue. + method_name = "send_" + lowerASCII(name) + method = self._makeMethod(getattr(self, const_name), method_name, argc) + setattr(self, method_name, method) + + self.__names.append(name) diff --git a/pyanaconda/ui/communication.py b/pyanaconda/ui/communication.py index 6b819c5..df2f02c 100644 --- a/pyanaconda/ui/communication.py +++ b/pyanaconda/ui/communication.py @@ -18,7 +18,7 @@ # # Author(s): Chris Lumens clumens@redhat.com
-from pyanaconda.queue import QueueFactory +from pyanaconda.queuefactory import QueueFactory
# A queue to be used for communicating information from a spoke back to its # hub. This information includes things like marking spokes as ready and
----- Original Message -----
From: "Chris Lumens" clumens@redhat.com To: anaconda-patches@lists.fedorahosted.org Sent: Friday, February 20, 2015 5:31:40 PM Subject: [PATCH 1/4] Don't try to run new-kernel-pkg if it doesn't exist.
pyanaconda/packaging/__init__.py | 4 ++++ pyanaconda/packaging/livepayload.py | 4 ++++ 2 files changed, 8 insertions(+)
diff --git a/pyanaconda/packaging/__init__.py b/pyanaconda/packaging/__init__.py index a8388e7..7642d2f 100644 --- a/pyanaconda/packaging/__init__.py +++ b/pyanaconda/packaging/__init__.py @@ -523,6 +523,10 @@ class Payload(object):
:returns: None """
if not os.path.exists(iutil.getSysroot() +
"/usr/sbin/new-kernel-pkg"):
log.error("new-kernel-pkg does not exist - grubby wasn't
installed? skipping")
return
for kernel in self.kernelVersionList: log.info("recreating initrd for %s", kernel) if not flags.imageInstall:
diff --git a/pyanaconda/packaging/livepayload.py b/pyanaconda/packaging/livepayload.py index f582219..ed3f073 100644 --- a/pyanaconda/packaging/livepayload.py +++ b/pyanaconda/packaging/livepayload.py @@ -164,6 +164,10 @@ class LiveImagePayload(ImagePayload): threadMgr.wait(THREAD_LIVE_PROGRESS)
# Live needs to create the rescue image before bootloader is written
if not os.path.exists(iutil.getSysroot() +
"/usr/sbin/new-kernel-pkg"):
log.error("new-kernel-pkg does not exist - grubby wasn't
installed? skipping")
return
for kernel in self.kernelVersionList: log.info("Generating rescue image for %s", kernel) iutil.execInSysroot("new-kernel-pkg",
-- 2.2.2
All 4 look good to me, ACK!
anaconda-patches mailing list anaconda-patches@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/anaconda-patches
anaconda-patches@lists.fedorahosted.org