Skip to content

Commit

Permalink
Merge pull request #987 from jkonecny12/rhel7-fix-1404158
Browse files Browse the repository at this point in the history
Rhel7 fix 1404158
  • Loading branch information
jkonecny12 committed Mar 15, 2017
2 parents 5dbd93c + 59bf385 commit beeaa50
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 38 deletions.
41 changes: 41 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,31 @@ 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))
except PayloadError as ex:
raise PayloadError(("Can't translate group names to group ID - %s", str(ex)))

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
19 changes: 19 additions & 0 deletions pyanaconda/packaging/yumpayload.py
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,25 @@ 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.
:raise NoSuchGroup: If group_name doesn't exists.
:raise PayloadError: When Yum's groups are not available.
"""
groups = self._yumGroups
if not groups:
raise PayloadError("Yum's groups are not available")

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
89 changes: 51 additions & 38 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 @@ -65,9 +66,6 @@ def __init__(self, *args, **kwargs):
self._tx_id = None
self._selectFlag = False

self.selectedGroups = []
self.excludedGroups = []

self._environmentListBox = self.builder.get_object("environmentListBox")
self._addonListBox = self.builder.get_object("addonListBox")

Expand Down Expand Up @@ -97,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 @@ -159,16 +160,21 @@ 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 needs to be set during a GUI installation, but is not required
# for a kickstart install (even partial)
if not self.environment:
log.debug("Environment is not set, skip user packages settings")
return

if not self._kickstarted:
addons = self._get_selected_addons()
for group in addons:
if group not in self.selectedGroups:
self.selectedGroups.append(group)

self._selectFlag = False
self.payload.data.packages.groupList = []
self.payload.selectEnvironment(self.environment)
for group in self.selectedGroups:
log.debug("Environment selected for installation: %s", self.environment)
log.debug("Groups selected for installation: %s", addons)
for group in addons:
self.payload.selectGroup(group)

# And then save these values so we can check next time.
Expand All @@ -181,6 +187,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 @@ -214,7 +224,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 @@ -269,7 +279,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 @@ -302,7 +312,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 All @@ -320,12 +343,6 @@ def _initialize(self):
# report that software spoke initialization has been completed
self.initialize_done()

def _parseEnvironments(self):
# Set all of the add-on selection states to the default
self._addonStates = {}
for grp in self.payload.groups:
self._addonStates[grp] = self._ADDON_DEFAULT

@gtk_action_wait
def _first_refresh(self):
self.refresh()
Expand Down Expand Up @@ -449,7 +466,6 @@ def _allAddons(self):

def _get_selected_addons(self):
retval = []

addons = self._allAddons()

for (ndx, row) in enumerate(self._addonListBox.get_children()):
Expand All @@ -464,6 +480,19 @@ def _get_selected_addons(self):

return retval

def _mark_addon_selection(self, grpid, selected):
# Mark selection or return its state to the default state
if selected:
if self.payload.environmentOptionIsDefault(self.environment, grpid):
self._addonStates[grpid] = self._ADDON_DEFAULT
else:
self._addonStates[grpid] = self._ADDON_SELECTED
else:
if not self.payload.environmentOptionIsDefault(self.environment, grpid):
self._addonStates[grpid] = self._ADDON_DEFAULT
else:
self._addonStates[grpid] = self._ADDON_DESELECTED

def _clear_listbox(self, listbox):
for child in listbox.get_children():
listbox.remove(child)
Expand Down Expand Up @@ -494,14 +523,7 @@ def on_environment_activated(self, listbox, row):
button.set_active(True)
button.handler_unblock_by_func(self.on_radio_button_toggled)

# Remove all the groups that were selected by the previously
# selected environment.
if self.environment:
for groupid in self.payload.environmentGroups(self.environment):
if groupid in self.selectedGroups:
self.selectedGroups.remove(groupid)

# Then mark the clicked environment as selected and update the screen.
# Mark the clicked environment as selected and update the screen.
self.environment = self.payload.environments[row.get_index()]
self.refreshAddons()
self._addonListBox.show_all()
Expand All @@ -515,22 +537,13 @@ def on_addon_activated(self, listbox, row):
addons = self._allAddons()
group = addons[row.get_index()]

wasActive = group in self.selectedGroups
new_btn_val = not button.get_active()

button.handler_block_by_func(self.on_checkbox_toggled)
button.set_active(not wasActive)
button.set_active(new_btn_val)
button.handler_unblock_by_func(self.on_checkbox_toggled)

if wasActive:
self.selectedGroups.remove(group)
self._addonStates[group] = self._ADDON_DESELECTED
else:
self.selectedGroups.append(group)

if group in self.excludedGroups:
self.excludedGroups.remove(group)

self._addonStates[group] = self._ADDON_SELECTED
self._mark_addon_selection(group, new_btn_val)

def on_info_bar_clicked(self, *args):
if not self._errorMsgs:
Expand Down

0 comments on commit beeaa50

Please sign in to comment.