[PATCH] Disable the "Closest mirror" option if there's no fastestmirror plugin (#876135).
by Chris Lumens
The goal here is to not allow selecting the Closest mirror option on trees that
do not include a repo config file supporting it. This seems to be the easiest
way to do it, though I have not been able to test it thoroughly due to trees
being broken in other ways. It does not break the standard Fedora case, though.
Additionally, I've moved Closest mirror to the last option in the combo box so
it can be removed without having to move all the other options around.
---
pyanaconda/packaging/__init__.py | 7 +++++++
pyanaconda/packaging/yumpayload.py | 5 +++++
pyanaconda/ui/gui/spokes/source.glade | 2 +-
pyanaconda/ui/gui/spokes/source.py | 30 +++++++++++++++++++++---------
4 files changed, 34 insertions(+), 10 deletions(-)
diff --git a/pyanaconda/packaging/__init__.py b/pyanaconda/packaging/__init__.py
index f095dea..fb72e82 100644
--- a/pyanaconda/packaging/__init__.py
+++ b/pyanaconda/packaging/__init__.py
@@ -146,6 +146,13 @@ class Payload(object):
""" The identifier of the current base repo. """
return None
+ @property
+ def mirrorEnabled(self):
+ """Is the closest/fastest mirror option enabled? This does not make
+ sense for those payloads that do not support this concept.
+ """
+ return True
+
def getRepo(self, repo_id):
""" Return the package repo object. """
raise NotImplementedError()
diff --git a/pyanaconda/packaging/yumpayload.py b/pyanaconda/packaging/yumpayload.py
index 3209fe4..2dd81e1 100644
--- a/pyanaconda/packaging/yumpayload.py
+++ b/pyanaconda/packaging/yumpayload.py
@@ -410,6 +410,11 @@ reposdir=%s
return base_repo_name
+ @property
+ def mirrorEnabled(self):
+ with _yum_lock:
+ return "fastestmirror" in self._yum.plugins.enabledPlugins
+
def getRepo(self, repo_id):
""" Return the yum repo object. """
with _yum_lock:
diff --git a/pyanaconda/ui/gui/spokes/source.glade b/pyanaconda/ui/gui/spokes/source.glade
index 78ec539..2cc41f2 100644
--- a/pyanaconda/ui/gui/spokes/source.glade
+++ b/pyanaconda/ui/gui/spokes/source.glade
@@ -755,11 +755,11 @@
<property name="can_focus">False</property>
<property name="active">0</property>
<items>
- <item translatable="yes">Closest mirror</item>
<item translatable="yes">http://</item>
<item translatable="yes">https://</item>
<item translatable="yes">ftp://</item>
<item translatable="yes">nfs</item>
+ <item translatable="yes">Closest mirror</item>
</items>
<signal name="changed" handler="on_protocol_changed" swapped="no"/>
</object>
diff --git a/pyanaconda/ui/gui/spokes/source.py b/pyanaconda/ui/gui/spokes/source.py
index accd19a..e9ecc7c 100644
--- a/pyanaconda/ui/gui/spokes/source.py
+++ b/pyanaconda/ui/gui/spokes/source.py
@@ -53,6 +53,13 @@ BASEREPO_SETUP_MESSAGE = N_("Setting up installation source...")
METADATA_DOWNLOAD_MESSAGE = N_("Downloading package metadata...")
METADATA_ERROR_MESSAGE = N_("Error downloading package metadata...")
+# These need to be in the same order as the items in protocolComboBox in source.glade.
+PROTOCOL_HTTP = 0
+PROTOCOL_HTTPS = 1
+PROTOCOL_FTP = 2
+PROTOCOL_NFS = 3
+PROTOCOL_MIRROR = 4
+
# Repo Store Columns
REPO_ENABLED_COL = 0
REPO_NAME_COL = 1
@@ -554,6 +561,11 @@ class SourceSpoke(NormalSpoke):
added = False
+ # If there's no fallback mirror to use, we should just disable that option
+ # in the UI.
+ if not self.payload.mirrorEnabled:
+ self._protocolComboBox.remove(PROTOCOL_MIRROR)
+
# If we've previously set up to use a CD/DVD method, the media has
# already been mounted by payload.setup. We can't try to mount it
# again. So just use what we already know to create the selector.
@@ -621,7 +633,7 @@ class SourceSpoke(NormalSpoke):
# We default to the mirror list, and then if the method tells us
# something different later, we can change it.
- self._protocolComboBox.set_active(0)
+ self._protocolComboBox.set_active(PROTOCOL_MIRROR)
self._urlEntry.set_sensitive(False)
# Set up the default state of UI elements.
@@ -630,13 +642,13 @@ class SourceSpoke(NormalSpoke):
proto = self.data.method.url or self.data.method.mirrorlist
if proto.startswith("http:"):
- self._protocolComboBox.set_active(1)
+ self._protocolComboBox.set_active(PROTOCOL_HTTP)
l = 7
elif proto.startswith("https:"):
- self._protocolComboBox.set_active(2)
+ self._protocolComboBox.set_active(PROTOCOL_HTTPS)
l = 8
elif proto.startswith("ftp:"):
- self._protocolComboBox.set_active(3)
+ self._protocolComboBox.set_active(PROTOCOL_FTP)
l = 6
self._urlEntry.set_sensitive(True)
@@ -644,7 +656,7 @@ class SourceSpoke(NormalSpoke):
self._mirrorlistCheckbox.set_active(bool(self.data.method.mirrorlist))
elif self.data.method.method == "nfs":
self._networkButton.set_active(True)
- self._protocolComboBox.set_active(4)
+ self._protocolComboBox.set_active(PROTOCOL_NFS)
self._urlEntry.set_text("%s:%s" % (self.data.method.server, self.data.method.dir))
self._urlEntry.set_sensitive(True)
@@ -683,16 +695,16 @@ class SourceSpoke(NormalSpoke):
return not flags.livecdInstall
def _mirror_active(self):
- return self._protocolComboBox.get_active() == 0
+ return self._protocolComboBox.get_active() == PROTOCOL_MIRROR
def _http_active(self):
- return self._protocolComboBox.get_active() in [1, 2]
+ return self._protocolComboBox.get_active() in [PROTOCOL_HTTP, PROTOCOL_HTTPS]
def _ftp_active(self):
- return self._protocolComboBox.get_active() == 3
+ return self._protocolComboBox.get_active() == PROTOCOL_FTP
def _nfs_active(self):
- return self._protocolComboBox.get_active() == 4
+ return self._protocolComboBox.get_active() == PROTOCOL_NFS
def _get_selected_partition(self):
store = self.builder.get_object("partitionStore")
--
1.8.1.2
11 years, 1 month
[PATCH] Add signal handlers for controlling password entry visibility.
by Chris Lumens
It'd be nice to have passwords readable when editing them, and then hidden
when done editing. Since this is a thing we might want to do all over the
place, I've added signal handlers pretty high up in the object hierarchy.
---
pyanaconda/ui/gui/__init__.py | 18 ++++++++++++++++++
pyanaconda/ui/gui/spokes/custom.glade | 2 ++
pyanaconda/ui/gui/spokes/lib/passphrase.glade | 4 ++++
pyanaconda/ui/gui/spokes/lib/passphrase.py | 2 +-
pyanaconda/ui/gui/spokes/password.glade | 4 ++++
pyanaconda/ui/gui/spokes/source.glade | 4 ++++
pyanaconda/ui/gui/spokes/user.glade | 4 ++++
7 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/pyanaconda/ui/gui/__init__.py b/pyanaconda/ui/gui/__init__.py
index f8efb7f..1a5a3b5 100644
--- a/pyanaconda/ui/gui/__init__.py
+++ b/pyanaconda/ui/gui/__init__.py
@@ -198,6 +198,24 @@ class GUIObject(common.UIObject):
"""
self.window.set_warning(msg)
+ def on_password_focused(self, entry, event, *args):
+ """When a password entry is focused, this callback allows for showing
+ the contents of the entry. Along with on_password_unfocused, this
+ has the effect of hiding the entry when the user's not directly
+ editing it, and showing it when they are.
+ """
+ entry.set_visibility(True)
+ return False
+
+ def on_password_unfocused(self, entry, event, *args):
+ """When a password entry is unfocused, this callback allows for hiding
+ the contents of the entry. Along with on_password_focused, this
+ has the effect of hiding the entry when the user's not directly
+ editing it, and showing it when they are.
+ """
+ entry.set_visibility(False)
+ return False
+
class QuitDialog(GUIObject):
builderObjects = ["quitDialog"]
mainWidgetName = "quitDialog"
diff --git a/pyanaconda/ui/gui/spokes/custom.glade b/pyanaconda/ui/gui/spokes/custom.glade
index a91e505..e400211 100644
--- a/pyanaconda/ui/gui/spokes/custom.glade
+++ b/pyanaconda/ui/gui/spokes/custom.glade
@@ -1072,6 +1072,8 @@ until you click on the main menu's 'Begin Installation' button.</property>
<property name="visibility">False</property>
<property name="invisible_char">●</property>
<accelerator key="p" signal="grab-focus" modifiers="GDK_MOD1_MASK"/>
+ <signal name="focus-in-event" handler="on_password_focused" swapped="no"/>
+ <signal name="focus-out-event" handler="on_password_unfocused" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
diff --git a/pyanaconda/ui/gui/spokes/lib/passphrase.glade b/pyanaconda/ui/gui/spokes/lib/passphrase.glade
index cb08899..145ba71 100644
--- a/pyanaconda/ui/gui/spokes/lib/passphrase.glade
+++ b/pyanaconda/ui/gui/spokes/lib/passphrase.glade
@@ -116,6 +116,8 @@
<property name="width_chars">32</property>
<signal name="changed" handler="on_passphrase_changed" swapped="no"/>
<signal name="focus-out-event" handler="on_passphrase_editing_done" swapped="no"/>
+ <signal name="focus-out-event" handler="on_password_unfocused" swapped="no"/>
+ <signal name="focus-in-event" handler="on_password_focused" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
@@ -149,6 +151,8 @@
<property name="width_chars">32</property>
<signal name="changed" handler="on_confirm_changed" swapped="no"/>
<signal name="focus-out-event" handler="on_confirm_editing_done" swapped="no"/>
+ <signal name="focus-out-event" handler="on_password_unfocused" swapped="no"/>
+ <signal name="focus-in-event" handler="on_password_focused" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
diff --git a/pyanaconda/ui/gui/spokes/lib/passphrase.py b/pyanaconda/ui/gui/spokes/lib/passphrase.py
index ecf2484..3ae8616 100644
--- a/pyanaconda/ui/gui/spokes/lib/passphrase.py
+++ b/pyanaconda/ui/gui/spokes/lib/passphrase.py
@@ -155,7 +155,7 @@ class PassphraseDialog(GUIObject):
if sensitive:
self._confirm_entry.grab_focus()
- return True
+ return False
def on_confirm_changed(self, entry):
if not self._save_button.get_sensitive() and \
diff --git a/pyanaconda/ui/gui/spokes/password.glade b/pyanaconda/ui/gui/spokes/password.glade
index 75ac957..7670f09 100644
--- a/pyanaconda/ui/gui/spokes/password.glade
+++ b/pyanaconda/ui/gui/spokes/password.glade
@@ -85,6 +85,8 @@
<property name="can_focus">True</property>
<property name="visibility">False</property>
<property name="invisible_char">●</property>
+ <signal name="focus-in-event" handler="on_password_focused" swapped="no"/>
+ <signal name="focus-out-event" handler="on_password_unfocused" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
@@ -100,6 +102,8 @@
<property name="visibility">False</property>
<property name="invisible_char">●</property>
<property name="activates_default">True</property>
+ <signal name="focus-in-event" handler="on_password_focused" swapped="no"/>
+ <signal name="focus-out-event" handler="on_password_unfocused" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
diff --git a/pyanaconda/ui/gui/spokes/source.glade b/pyanaconda/ui/gui/spokes/source.glade
index 44cd9e3..78ec539 100644
--- a/pyanaconda/ui/gui/spokes/source.glade
+++ b/pyanaconda/ui/gui/spokes/source.glade
@@ -437,6 +437,8 @@
<property name="can_focus">True</property>
<property name="visibility">False</property>
<property name="invisible_char">●</property>
+ <signal name="focus-in-event" handler="on_password_focused" swapped="no"/>
+ <signal name="focus-out-event" handler="on_password_unfocused" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
@@ -1149,6 +1151,8 @@
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
<signal name="changed" handler="on_repoProxy_changed" swapped="no"/>
+ <signal name="focus-in-event" handler="on_password_focused" swapped="no"/>
+ <signal name="focus-out-event" handler="on_password_unfocused" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
diff --git a/pyanaconda/ui/gui/spokes/user.glade b/pyanaconda/ui/gui/spokes/user.glade
index 64098b3..60b1a7b 100644
--- a/pyanaconda/ui/gui/spokes/user.glade
+++ b/pyanaconda/ui/gui/spokes/user.glade
@@ -173,6 +173,8 @@
<property name="visibility">False</property>
<property name="invisible_char">●</property>
<signal name="changed" handler="_checkPassword" swapped="no"/>
+ <signal name="focus-in-event" handler="on_password_focused" swapped="no"/>
+ <signal name="focus-out-event" handler="on_password_unfocused" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
@@ -188,6 +190,8 @@
<property name="visibility">False</property>
<property name="invisible_char">●</property>
<signal name="changed" handler="_checkPassword" swapped="no"/>
+ <signal name="focus-in-event" handler="on_password_focused" swapped="no"/>
+ <signal name="focus-out-event" handler="on_password_unfocused" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
--
1.8.1.2
11 years, 1 month
[master] GtkWindowGroup for Anaconda
by Vratislav Podzimek
PATCH 1/3 fixes a potential issue with Gtk no longer raising an exception if it
fails to initialize and simplifies the code a bit by using one global import
instead of multiple local ones.
PATCH 2/3 adds a GtkWindowGroup used for all GUIObjects and ligthboxes we
create.
PATCH 3/3 makes use of the window group to properly lightbox the dialogs that
cannot be lightboxed before. I've tried tens of runs on my HW to test if the bug
with hidden dialogs with focus really doesnt' come back with that patch. But any
further testing would be appreciated.
Vratislav Podzimek (3):
We can import Gtk globally now
Create and use GtkWindowGroup for our windows
Enlightbox dialogs in the custom spoke
pyanaconda/ui/gui/__init__.py | 23 ++++++++++-------------
pyanaconda/ui/gui/spokes/custom.py | 15 +++------------
pyanaconda/ui/gui/utils.py | 2 ++
3 files changed, 15 insertions(+), 25 deletions(-)
--
1.7.11.7
11 years, 1 month
[PATCH] Fix console= persistence, remove serial (#928269)
by Will Woods
The 'serial' option was supposed to have been removed, but it got left
behind in a few places. Somehow it mutated into an argument to keep the
user-set "console=XXX" argument in the installed system?
This patch should straighten things out to match the intended behavior:
* "serial" is deprecated and ignored; try "console=ttyS0" instead.
* If you use "console=XXX" it will be preserved in the installed system.
* If multiple "console=XXX" args are used, the *last* one is preserved.
It might be kind of useful to be able to override this but I really
can't think of a use case for that right now, so I'm leaving it out.
You can always just remove it with a sed oneliner¹ or something.
Here's what the patch actually changes:
- Adds iutil.get_active_console()
- Uses that to fix iutil.isConsoleOnVirtualTerminal()²
- Sets BootLoader.console whenever 'console=XXX' is present, instead of
only when flags.serial is set
- Uses iutil.isConsoleOnVirtualTerminal() instead of flags.serial to
determine when it's OK to use GRUB splash
- Removes flags.serial, since it's now completely unused.
¹ e.g. `sed 's/console=\S*\s*//' /etc/grub*.cfg`
² Note the "XXX PJFIX", which means pjones owes me a beer.
---
anaconda | 4 ----
pyanaconda/bootloader.py | 14 +++++++-------
pyanaconda/flags.py | 1 -
pyanaconda/iutil.py | 17 +++++++++++------
4 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/anaconda b/anaconda
index a982214..b553de3 100755
--- a/anaconda
+++ b/anaconda
@@ -245,7 +245,6 @@ def parseOptions(argv=None, cmdline=None):
op.add_option("--headless", dest="isHeadless", action="store_true", default=False)
op.add_option("--nofb")
op.add_option("--resolution", dest="runres", default=None)
- op.add_option("--serial", action="store_true", default=False)
op.add_option("--usefbx", dest="xdriver", action="store_const", const="fbdev")
op.add_option("--vnc", action="store_true", default=False)
op.add_option("--vncconnect")
@@ -441,9 +440,6 @@ def setupDisplay(anaconda, opts, addon_paths=None):
if len(cargs[1]) > 0:
vncS.vncconnectport = cargs[1]
- if opts.serial:
- flags.serial = True
-
if opts.xdriver:
anaconda.xdriver = opts.xdriver
anaconda.writeXdriver(root="/")
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index 0d45d38..f5bda35 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -97,7 +97,9 @@ def parse_serial_opt(arg):
bits, and "f" is flow control ("r" for RTS or
omit it). Default is "9600n8".
but note that everything after the baud rate is optional, so these are
- all valid: 9600, 19200n, 38400n8, 9600e7r"""
+ all valid: 9600, 19200n, 38400n8, 9600e7r.
+ Also note that the kernel assumes 1 stop bit; this can't be changed.
+ """
opts = serial_opts()
m = re.match('\d+', arg)
if m is None:
@@ -877,11 +879,9 @@ class BootLoader(object):
def _set_console(self):
""" Set console options based on boot arguments. """
- if flags.serial:
- console = flags.cmdline.get("console", "ttyS0").split(",", 1)
- self.console = console[0]
- if len(console) > 1:
- self.console_options = console[1]
+ console = flags.cmdline.get("console", "")
+ console = os.path.basename(console)
+ self.console, x, self.console_options = console.partition(",")
def write_config_console(self, config):
"""Write console-related configuration lines."""
@@ -1129,7 +1129,7 @@ class GRUB(BootLoader):
self.write_config_console(config)
- if not flags.serial:
+ if iutil.isConsoleOnVirtualTerminal(self.console):
splash = "splash.xpm.gz"
splash_path = os.path.normpath("%s/boot/%s/%s" % (ROOT_PATH,
self.splash_dir,
diff --git a/pyanaconda/flags.py b/pyanaconda/flags.py
index f3aa78b..5ba291c 100644
--- a/pyanaconda/flags.py
+++ b/pyanaconda/flags.py
@@ -49,7 +49,6 @@ class Flags(object):
self.dlabel = 0
self.ibft = 1
self.iscsi = 0
- self.serial = 0
self.usevnc = 0
self.vncquestion = True
self.mpath = 1
diff --git a/pyanaconda/iutil.py b/pyanaconda/iutil.py
index 51e9853..eecaf36 100644
--- a/pyanaconda/iutil.py
+++ b/pyanaconda/iutil.py
@@ -257,12 +257,17 @@ def mkdirChain(dir):
log.error("could not create directory %s: %s" % (dir, e.strerror))
-def isConsoleOnVirtualTerminal():
- # XXX PJFIX is there some way to ask the kernel this instead?
- # XXX we don't want to have to import storage from here
- if os.uname()[4].startswith("s390"):
- return False
- return not flags.serial
+def get_active_console(dev="console"):
+ while True:
+ try:
+ dev = open("/sys/class/tty/%s/active" % dev).read().split()[-1]
+ except (IOError, IndexError):
+ break
+ return dev
+
+def isConsoleOnVirtualTerminal(dev="console"):
+ console = get_active_console(dev)
+ return console.rstrip('01243456789') == 'tty'
def strip_markup(text):
if text.find("<") == -1:
--
1.8.1.4
11 years, 1 month
[PATCH] Add a Spoke.changed attribute.
by Chris Lumens
Previously, we were checking whether a spoke changed to avoid needlessly
running apply/execute from within those methods on each spoke. This is
something the hub could do instead, though.
As a practical improvement, this means going into the storage spoke, changing
nothing, and then leaving means it won't attempt to redo storage. The user
can still outsmart this check, though, but I think for most people it will be
fine.
Note that not all spoke do these checks yet. I have updated those that do.
---
pyanaconda/ui/common.py | 11 ++++++++++-
pyanaconda/ui/gui/hubs/__init__.py | 8 ++++----
pyanaconda/ui/gui/spokes/software.py | 20 +++++++++++++++-----
pyanaconda/ui/gui/spokes/source.py | 13 ++++++-------
pyanaconda/ui/gui/spokes/storage.py | 19 +++++++++++++++++++
pyanaconda/ui/tui/hubs/summary.py | 3 ++-
6 files changed, 56 insertions(+), 18 deletions(-)
diff --git a/pyanaconda/ui/common.py b/pyanaconda/ui/common.py
index 8248bd5..2bae250 100644
--- a/pyanaconda/ui/common.py
+++ b/pyanaconda/ui/common.py
@@ -232,6 +232,15 @@ class Spoke(UIObject):
raise NotImplementedError
@property
+ def changed(self):
+ """Have the values on the spoke changed since the last time it was
+ run? If not, the apply and execute methods will be skipped. This
+ is to avoid the spoke doing potentially long-lived and destructive
+ actions that are completely unnecessary.
+ """
+ return True
+
+ @property
def configured(self):
"""This method returns a list of textual ids that should
be written into the after-install customization status
@@ -257,7 +266,7 @@ class Spoke(UIObject):
Spokes are mandatory unless marked as not being so.
"""
return True
-
+
def execute(self):
"""Cause the data object to take effect on the target system. This will
usually be as simple as calling one or more of the execute methods on
diff --git a/pyanaconda/ui/gui/hubs/__init__.py b/pyanaconda/ui/gui/hubs/__init__.py
index 446f168..53143d4 100644
--- a/pyanaconda/ui/gui/hubs/__init__.py
+++ b/pyanaconda/ui/gui/hubs/__init__.py
@@ -116,7 +116,7 @@ class Hub(GUIObject, common.Hub):
Gtk.main()
action.window.set_transient_for(None)
- if not action.skipTo or (action.skipTo and action.applyOnSkip):
+ if action.changed and (not action.skipTo or (action.skipTo and action.applyOnSkip)):
action.apply()
action.execute()
@@ -128,7 +128,7 @@ class Hub(GUIObject, common.Hub):
"""
ret = {}
-
+
# Collect all the categories this hub displays, then collect all the
# spokes belonging to all those categories.
categories = sorted(filter(lambda c: c.displayOnHub == self.__class__, collect_categories(self.paths["categories"])),
@@ -206,7 +206,7 @@ class Hub(GUIObject, common.Hub):
spoke.selector.connect("key-release-event", self._on_spoke_clicked, spoke)
# If this is a kickstart install, attempt to execute any provided ksdata now.
- if flags.automatedInstall and spoke.ready:
+ if flags.automatedInstall and spoke.ready and spoke.changed:
spoke.execute()
selectors.append(spoke.selector)
@@ -327,7 +327,7 @@ class Hub(GUIObject, common.Hub):
# _createBox skipped. Now that it's become ready, do it. Note
# that we also provide a way to skip this processing (see comments
# communication.py) to prevent getting caught in a loop.
- if not args[1]:
+ if not args[1] and spoke.changed:
spoke.execute()
if self.continuePossible:
diff --git a/pyanaconda/ui/gui/spokes/software.py b/pyanaconda/ui/gui/spokes/software.py
index e9cf708..55af428 100644
--- a/pyanaconda/ui/gui/spokes/software.py
+++ b/pyanaconda/ui/gui/spokes/software.py
@@ -71,11 +71,6 @@ class SoftwareSelectionSpoke(NormalSpoke):
addons = self._get_selected_addons()
- # Don't redo dep solving if nothing's changed.
- if row[2] == self._origEnvironment and set(addons) == set(self._origAddons) and \
- self.txid_valid:
- return
-
self._selectFlag = False
self.payload.data.packages.groupList = []
self.payload.selectEnvironment(row[2])
@@ -123,6 +118,21 @@ class SoftwareSelectionSpoke(NormalSpoke):
return self._get_selected_environment() is not None and processingDone
@property
+ def changed(self):
+ row = self._get_selected_environment()
+ if not row:
+ return True
+
+ addons = self._get_selected_addons()
+
+ # Don't redo dep solving if nothing's changed.
+ if row[2] == self._origEnvironment and set(addons) == set(self._origAddons) and \
+ self.txid_valid:
+ return False
+
+ return True
+
+ @property
def mandatory(self):
return True
diff --git a/pyanaconda/ui/gui/spokes/source.py b/pyanaconda/ui/gui/spokes/source.py
index 1a2b280..accd19a 100644
--- a/pyanaconda/ui/gui/spokes/source.py
+++ b/pyanaconda/ui/gui/spokes/source.py
@@ -278,13 +278,8 @@ class SourceSpoke(NormalSpoke):
if flags.askmethod:
flags.askmethod = False
- method_changed = self._method_changed()
- repos_changed = self._update_payload_repos()
-
- if method_changed or repos_changed:
- threadMgr.add(AnacondaThread(name=constants.THREAD_PAYLOAD_MD,
- target=self.getRepoMetadata))
- self.clear_info()
+ threadMgr.add(AnacondaThread(name=constants.THREAD_PAYLOAD_MD, target=self.getRepoMetadata))
+ self.clear_info()
def _method_changed(self):
""" Check to see if the install method has changed.
@@ -452,6 +447,10 @@ class SourceSpoke(NormalSpoke):
hubQ.send_ready(self.__class__.__name__, False)
@property
+ def changed(self):
+ return self._method_changed() or self._update_payload_repos()
+
+ @property
def completed(self):
if flags.automatedInstall and (not self.data.method.method or not self.payload.baseRepo):
return False
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py
index 17634d7..8b6fbaa 100644
--- a/pyanaconda/ui/gui/spokes/storage.py
+++ b/pyanaconda/ui/gui/spokes/storage.py
@@ -406,6 +406,14 @@ class StorageSpoke(NormalSpoke, StorageChecker):
hubQ.send_ready(self.__class__.__name__, True)
@property
+ def changed(self):
+ disksChanged = set(self._initial_selected_disks) != set(self.selected_disks)
+ bootloaderChanged = self.data.bootloader.bootDrive is None or \
+ self._initial_bootloader_disk != self.data.bootloader.bootDrive
+
+ return disksChanged or bootloaderChanged
+
+ @property
def completed(self):
retval = (threadMgr.get(constants.THREAD_EXECUTE_STORAGE) is None and
threadMgr.get(constants.THREAD_CHECK_STORAGE) is None and
@@ -513,6 +521,12 @@ class StorageSpoke(NormalSpoke, StorageChecker):
self._update_summary()
+ # This list is used to determine if anything has changed in storage
+ # configuration since the user entered the spoke. If not, we shouldn't
+ # do anything when Done is clicked.
+ self._initial_selected_disks = self.selected_disks[:]
+ self._initial_bootloader_disk = self.data.bootloader.bootDrive
+
if self.errors:
self.set_warning(_("Error checking storage configuration. Click for details."))
elif self.warnings:
@@ -696,6 +710,11 @@ class StorageSpoke(NormalSpoke, StorageChecker):
return True
def on_back_clicked(self, button):
+ # Did the user change anything? If not, this method is a no-op.
+ if not self.changed:
+ NormalSpoke.on_back_clicked(self, button)
+ return
+
# Remove all non-existing devices if autopart was active when we last
# refreshed.
if self._previous_autopart:
diff --git a/pyanaconda/ui/tui/hubs/summary.py b/pyanaconda/ui/tui/hubs/summary.py
index 965fdc1..ab8bb39 100644
--- a/pyanaconda/ui/tui/hubs/summary.py
+++ b/pyanaconda/ui/tui/hubs/summary.py
@@ -45,7 +45,8 @@ class SummaryHub(TUIHub):
print('')
for spoke in spokes:
- spoke.execute()
+ if spoke.changed:
+ spoke.execute()
# override the prompt so that we can skip user input on kickstarts
# where all the data is in hand. If not in hand, do the actual prompt.
--
1.8.1.2
11 years, 1 month
[PATCH] [PATCH] Clean up tracebacks saved in pstore space (#950709)
by Peter Jones
These variables are tracebacks from some old installation, and they
should have been reaped by that installation. Removing these also means
that in some (buggy) situations, installation may eventually converge on
working after re-trying several times :/
The cases it'll actually make installation work where it didn't before
/may/ require an intervening reboot, depending on the implementation of
the hardware.
Signed-off-by: Peter Jones <pjones(a)redhat.com>
---
anaconda | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/anaconda b/anaconda
index a982214..e5715fc 100755
--- a/anaconda
+++ b/anaconda
@@ -641,6 +641,13 @@ def prompt_for_ssh():
else:
stdoutLog.info(_("Please ssh install@<host> to continue installation."))
+def cleanPStore():
+ try:
+ for root, dirs, files in os.walk("/sys/fs/pstore"):
+ for f in filter(lambda x: x.startswith("dump-"), files):
+ os.unlink("%s/%s" % (root,f))
+ except OSError:
+ pass
if __name__ == "__main__":
print "Starting installer, one moment..."
@@ -1011,6 +1018,8 @@ if __name__ == "__main__":
if anaconda.rescue:
rescue.doRescue(anaconda.intf, anaconda.rescue_mount, ksdata)
+ else:
+ cleanPStore()
networkInitialize(ksdata)
if not flags.dirInstall:
--
1.8.1.4
11 years, 1 month
[PATCH] Clean up tracebacks saved in pstore space (#950709)
by Peter Jones
These variables are tracebacks from some old installation, and they
should have been reaped by that installation. Removing these also means
that in some (buggy) situations, installation may eventually converge on
working after re-trying several times :/
The cases it'll actually make installation work where it didn't before
/may/ require an intervening reboot, depending on the implementation of
the hardware.
Signed-off-by: Peter Jones <pjones(a)redhat.com>
---
dracut/clean-pstore.sh | 13 +++++++++++++
dracut/module-setup.sh | 1 +
2 files changed, 14 insertions(+)
create mode 100644 dracut/clean-pstore.sh
diff --git a/dracut/clean-pstore.sh b/dracut/clean-pstore.sh
new file mode 100644
index 0000000..6f7a85b
--- /dev/null
+++ b/dracut/clean-pstore.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+if [ ! -d /sys/fs/pstore ]; then
+ return 0
+fi
+
+if getargbool 0 rescue inst.rescue emergency ; then
+ return 0
+fi
+
+rm -f /sys/fs/pstore/dump-*
+
+return 0
diff --git a/dracut/module-setup.sh b/dracut/module-setup.sh
index 6743671..a58b3ec 100755
--- a/dracut/module-setup.sh
+++ b/dracut/module-setup.sh
@@ -23,6 +23,7 @@ install() {
inst_hook cmdline 26 "$moddir/parse-anaconda-kickstart.sh"
inst_hook cmdline 27 "$moddir/parse-anaconda-repo.sh"
inst_hook cmdline 28 "$moddir/parse-anaconda-net.sh"
+ inst_hook pre-udev 29 "$moddir/clean-pstore.sh"
inst_hook pre-udev 30 "$moddir/anaconda-modprobe.sh"
inst_hook pre-udev 40 "$moddir/repo-genrules.sh"
inst_hook pre-udev 40 "$moddir/kickstart-genrules.sh"
--
1.8.1.4
11 years, 1 month
[PATCH] updates to boot-options.txt
by Will Woods
- Better formatting for network options section
- Add the syntax for setting MTU
- Move upgradeany to "removed"
- List `ksdevice` as deprecated, with its replacements
---
docs/boot-options.txt | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/docs/boot-options.txt b/docs/boot-options.txt
index b6922a0..33c78da 100644
--- a/docs/boot-options.txt
+++ b/docs/boot-options.txt
@@ -152,13 +152,14 @@ Bring up *only one interface* using the given autoconf method, e.g.
`ip=<ip>::<gateway>:<netmask>:<hostname>:<interface>:none`::
Bring up the given interface with a static network config, where:
+[horizontal]
`<ip>`::: The client IP address. IPv6 addresses may be specified by putting
them in square brackets, like so: `[2001:DB8::1]`.
`<gateway>`::: The default gateway. IPv6 addresses are accepted here too.
`<netmask>`::: The netmask (e.g. `255.255.255.0`) or prefix (e.g. `64`).
`<hostname>`::: Hostname for the client machine. _Optional_.
-`ip=<ip>::<gateway>:<netmask>:<hostname>:<interface>:<autoconf>`::
+`ip=<ip>::<gateway>:<netmask>:<hostname>:<interface>:<autoconf>:<mtu>`::
Bring up the given interface with the given autoconf method, but override the
automatically obtained IP/gateway/etc. with the provided values.
+
@@ -313,11 +314,6 @@ Intentionally raise an exception to make the installer crash with a traceback.
This is for testing our crash-handling code. _Don't use it unless you want the
installer to crash._
-=== inst.upgradeany ===
-Normally the installer does a sanity check of `/etc/redhat-release` and
-refuses to upgrade anything too old for it to handle. You can use this to
-force it to upgrade anyway. _Use at your own risk._
-
Deprecated Options
------------------
@@ -342,6 +338,15 @@ These can be provided as part of the <<network,`ip`>> option.
A PXE-supplied BOOTIF option will be used automatically, so there's no need
for this.
+=== ksdevice ===
+[horizontal]
+_Not present_:: The first device with a usable link is used
+`ksdevice=link`:: Ignored (this is the same as the default behavior)
+`ksdevice=bootif`:: Ignored (this is the default if `BOOTIF=` is present)
+`ksdevice=ibft`:: Replaced with `ip=ibft`
+`ksdevice=<MAC>`:: Replaced with `BOOTIF=${MAC/:/-}`
+`ksdevice=<DEV>`:: Replaced with <<network,`bootdev=$MAC`>>
+
=== blacklist, nofirewire ===
`modprobe` handles blacklisting kernel modules on its own; try
@@ -372,9 +377,6 @@ Use `console=ttyS0` or similar instead. See <<console,console>> for details.
Plain `updates` is no longer supported. Use `inst.updates=hd:<dev>[:<img>]`,
discussed above.
-=== ksdevice=link ===
-This is the default behavior when using ip autoconf.
-
=== essid, wepkey, wpakey ===
Dracut doesn't support wireless networking, so these don't do anything.
@@ -399,6 +401,9 @@ works fine these days, so this was no longer necessary.
ipv6 is built into the kernel and can't be removed. You should be able to
disable it with `ipv6.disable`, though.
+=== upgradeany ===
+Anaconda doesn't handle upgrades anymore.
+
Future Options
--------------
These options are not present in Fedora 17 but will return in a future
--
1.8.1.4
11 years, 1 month