Skip to content

Commit

Permalink
Fix partial kickstart software selection in GUI (#1404158)
Browse files Browse the repository at this point in the history
When groups are selected in %packages section in a kickstart file, mark
these groups in the Software spoke. However if user visits the Software
spoke it will erase kickstart settings and use user settings.

Kickstart file without user interaction is the only option how to
install groups and packages which are not inside of the selected
environment.

Related: rhbz#1404158
  • Loading branch information
jkonecny12 committed Mar 8, 2017
1 parent d282ab3 commit 02c7171
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 4 deletions.
39 changes: 39 additions & 0 deletions pyanaconda/packaging/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,25 @@ def verifyAvailableRepositories(self):
def languageGroups(self):
return []

def selectedGroups(self):
"""Return list of selected group names from kickstart.
NOTE:
This group names can be mix of group IDs and other valid identifiers.
If you want group IDs use `selectedGroupsIDs` instead.
:return: list of group names in a format specified by a kickstart file.
"""
return [grp.name for grp in self.data.packages.groupList]


def selectedGroupsIDs(self):
"""Return list of IDs for selected groups.
Implementation depends on a specific payload class.
"""
return self.selectedGroups()

def groupSelected(self, groupid):
return Group(groupid) in self.data.packages.groupList

Expand Down Expand Up @@ -1201,9 +1220,29 @@ def _refreshEnvironmentAddons(self):
def groups(self):
raise NotImplementedError()

def selectedGroupsIDs(self):
"""Return list of selected group IDs.
:return: List of selected group IDs.
:raise PayloadError: If translation is not supported by payload.
"""
try:
ret = []
for grp in self.selectedGroups():
ret.append(self.groupId(grp))
return ret
# Translation feature is not implemented for this payload.
except NotImplementedError:
raise PayloadError(("Can't translate group names to group ID - "
"Group translation is not implemented for %s payload." % self))

def groupDescription(self, groupid):
raise NotImplementedError()

def groupId(self, group):
"""Return group id for translation of groups from a kickstart file."""
raise NotImplementedError()

class PayloadManager(object):
"""Framework for starting and watching the payload thread.
Expand Down
18 changes: 18 additions & 0 deletions pyanaconda/packaging/yumpayload.py
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,24 @@ def groupDescription(self, groupid):

return (group.ui_name, group.ui_description)

def groupId(self, group_name):
"""Translate group name to group ID.
:param group_name: Valid identifier for group specification.
:returns: Group ID or empty string if nothing is found.
:raise NoSuchGroup: If group_name doesn't exists.
"""
groups = self._yumGroups
if not groups:
return ""

with _yum_lock:
if not groups.has_group(group_name):
raise NoSuchGroup(group_name)

group = groups.return_group(group_name)
return group.groupid

def _isGroupVisible(self, groupid):
groups = self._yumGroups
if not groups:
Expand Down
34 changes: 30 additions & 4 deletions pyanaconda/ui/gui/spokes/software.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from pyanaconda.ui.gui.spokes.lib.detailederror import DetailedErrorDialog
from pyanaconda.ui.gui.utils import gtk_action_wait, escape_markup
from pyanaconda.ui.categories.software import SoftwareCategory
from pyanaconda.packaging import PayloadError

import logging
log = logging.getLogger("anaconda")
Expand Down Expand Up @@ -94,6 +95,9 @@ def __init__(self, *args, **kwargs):
self._fakeRadio = Gtk.RadioButton(group=None)
self._fakeRadio.set_active(True)

# are we taking values (group list) from a kickstart file?
self._kickstarted = flags.automatedInstall and self.data.packages.seen

# Payload event handlers
def _downloading_package_md(self):
hubQ.send_message(self.__class__.__name__, _("Downloading package metadata..."))
Expand Down Expand Up @@ -156,7 +160,12 @@ def _payload_error(self):
hubQ.send_message(self.__class__.__name__, payloadMgr.error)

def _apply(self):
if self.environment and not (flags.automatedInstall and self.data.packages.seen):
# Environment have to be set by GUI but not by kickstart
if not self.environment:
log.debug("Environment is not set, skip user packages settings")
return

if not self._kickstarted:
addons = self._get_selected_addons()

self._selectFlag = False
Expand All @@ -177,6 +186,10 @@ def _apply(self):
target=self.checkSoftwareSelection))

def apply(self):
# user changed groups or/and environment, it is no longer kickstarted
if self.environment:
self._kickstarted = False

self._apply()

def checkSoftwareSelection(self):
Expand Down Expand Up @@ -210,7 +223,7 @@ def completed(self):
return self.environment_valid
# if we don't have environment we need to at least have the %packages
# section in kickstart
elif flags.automatedInstall and self.data.packages.seen:
elif self._kickstarted:
return True
# no environment and no %packages section -> manual intervention is needed
else:
Expand Down Expand Up @@ -265,7 +278,7 @@ def status(self):

# kickstart installation
if flags.automatedInstall:
if self.data.packages.seen:
if self._kickstarted:
# %packages section is present in kickstart but environment is not set
if self.environment is None:
return _("Custom software selected")
Expand Down Expand Up @@ -298,7 +311,20 @@ def initialize(self):
def _initialize(self):
threadMgr.wait(constants.THREAD_PAYLOAD)

if not flags.automatedInstall or not self.data.packages.seen:
# Select groups which should be selected by kickstart
try:
for group in self.payload.selectedGroupsIDs():
if self.environment and self.payload.environmentOptionIsDefault(self.environment, group):
self._addonStates[group] = self._ADDON_DEFAULT
else:
self._addonStates[group] = self._ADDON_SELECTED
except PayloadError as e:
# Group translation is not supported
log.warning(e)
# It's better to have all or nothing selected from kickstart
self._addonStates = {}

if not self._kickstarted:
# having done all the slow downloading, we need to do the first refresh
# of the UI here so there's an environment selected by default. This
# happens inside the main thread by necessity. We can't do anything
Expand Down

0 comments on commit 02c7171

Please sign in to comment.