Skip to content

Commit

Permalink
Fix problems with the hdiso method (#1274855)
Browse files Browse the repository at this point in the history
(1) Be more lenient when it comes to deciding if the hdiso method has changed.

The user can specify "/dev/sda1" or "sda", and they can give the file name with
or without a leading slash.  anaconda internally follows different rules, which
leads to situations where we compare "/dev/sda1" to "sda1" and device things
have changed.  Of course, they haven't.

(2) The user may also specify the HDISO source via inst.repo=hd:/dev/disk/by-uuid
which we completely fail to handle.  Fix that.

(3) If the user gives us a bad value for inst.repo= (like an invalid path,
perhaps from a typo), handle it in the UI with an error instead of raising a
traceback that doesn't make much sense.

(4) Fix two problems caused by cherry-picked patches.

(5) The big one - if you boot up via some method that also involves mounting the
install.img from an HDISO source, the install.img will keep all our mount points
tied up.  There's not really any way to fix this because there's no way to
unmount the install.img, and there's nowhere to move it to that doesn't involve
eating up more memory.  Thus, just prevent people from changing the source when
in this situation and slap a tooltip up explaining why.

Resolves: rhbz#1274855
(cherry picked from commit 77c1fc4)
  • Loading branch information
clumens authored and bcl committed Nov 9, 2015
1 parent b7b4f4d commit c016e60
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 12 deletions.
4 changes: 4 additions & 0 deletions pyanaconda/packaging/__init__.py
Expand Up @@ -878,8 +878,12 @@ def _setupInstallDevice(self, storage, checkmount):
needmount = False
# We don't setup an install_device here
# because we can't tear it down

isodevice = storage.devicetree.resolveDevice(devspec)
if needmount:
if not isodevice:
raise PayloadSetupError("device for HDISO install %s does not exist" % devspec)

self._setupMedia(isodevice)
url = "file://" + INSTALL_TREE
self.install_device = isodevice
Expand Down
6 changes: 5 additions & 1 deletion pyanaconda/packaging/yumpayload.py
Expand Up @@ -516,7 +516,11 @@ def updateBaseRepo(self, fallback=True, root=None, checkmount=True):
retrieval fails.
"""
log.info("configuring base repo")
url, mirrorlist, sslverify = self._setupInstallDevice(self.storage, checkmount)

try:
url, mirrorlist, sslverify = self._setupInstallDevice(self.storage, checkmount)
except PayloadSetupError:
self.data.method.method = None

releasever = None
method = self.data.method
Expand Down
32 changes: 23 additions & 9 deletions pyanaconda/ui/gui/spokes/source.py
Expand Up @@ -47,7 +47,7 @@
from pyanaconda import constants
from pyanaconda import nm

from blivet.util import get_mount_paths
from blivet.util import get_mount_device, get_mount_paths

__all__ = ["SourceSpoke"]

Expand Down Expand Up @@ -300,7 +300,7 @@ class IsoChooser(GUIObject):

def __init__(self, data):
GUIObject.__init__(self, data)
self._chooser = self.builder.get_object("isoChooserDialog")
self._chooser = self.builder.get_object("isoChooser")

# pylint: disable=arguments-differ
def refresh(self, currentFile=""):
Expand Down Expand Up @@ -409,8 +409,8 @@ def _method_changed(self):
# The / gets stripped off by payload.ISOImage
self.data.method.dir = "/" + self._currentIsoFile
if (old_source.method == "harddrive" and
old_source.partition == self.data.method.partition and
old_source.dir == self.data.method.dir):
self.storage.devicetree.resolveDevice(old_source.partition) == part and
old_source.dir in [self._currentIsoFile, "/" + self._currentIsoFile]):
return False

# Make sure anaconda doesn't touch this device.
Expand Down Expand Up @@ -744,6 +744,10 @@ def refresh(self):
added = False
active = 0
idx = 0

if self.data.method.method == "harddrive":
methodDev = self.storage.devicetree.resolveDevice(self.data.method.partition)

for dev in potentialHdisoSources(self.storage.devicetree):
# path model size format type uuid of format
dev_info = { "model" : self._sanitize_model(dev.disk.model),
Expand All @@ -759,7 +763,7 @@ def refresh(self):
dev_info["label"] = "\n" + dev_info["label"]

store.append([dev, "%(model)s %(path)s (%(size)s MB) %(format)s %(label)s" % dev_info])
if self.data.method.method == "harddrive" and self.data.method.partition in [dev.path, dev.name]:
if self.data.method.method == "harddrive" and dev == methodDev:
active = idx
added = True
idx += 1
Expand Down Expand Up @@ -845,10 +849,20 @@ def refresh(self):
# Setup the addon repos
self._reset_repoStore()

# Then, some widgets get enabled/disabled/greyed out depending on
# how others are set up. We can use the signal handlers to handle
# that condition here too.
self.on_protocol_changed(self._protocolComboBox)
if self.data.method.method == "harddrive" and \
get_mount_device(constants.DRACUT_ISODIR) == get_mount_device(constants.DRACUT_REPODIR):
# If the stage2 image is mounted from an HDISO source, there's really
# no way we can tear down that source to allow the user to change it.
# Thus, this portion of the spoke should be insensitive.
for widget in [self._autodetectButton, self._autodetectBox, self._isoButton,
self._isoBox, self._networkButton, self._networkBox]:
widget.set_sensitive(False)
widget.set_tooltip_text(_("The installation source is in use by the installer and cannot be changed."))
else:
# Then, some widgets get enabled/disabled/greyed out depending on
# how others are set up. We can use the signal handlers to handle
# that condition here too.
self.on_protocol_changed(self._protocolComboBox)

if not nm.nm_is_connected():
self._networkButton.set_sensitive(False)
Expand Down
10 changes: 8 additions & 2 deletions pyanaconda/ui/tui/spokes/source.py
Expand Up @@ -32,12 +32,12 @@

from pyanaconda.constants import THREAD_SOURCE_WATCHER, THREAD_PAYLOAD
from pyanaconda.constants import THREAD_STORAGE_WATCHER
from pyanaconda.constants import THREAD_CHECK_SOFTWARE, ISO_DIR, DRACUT_ISODIR
from pyanaconda.constants import THREAD_CHECK_SOFTWARE, ISO_DIR, DRACUT_ISODIR, DRACUT_REPODIR
from pyanaconda.constants_text import INPUT_PROCESSED

from pyanaconda.ui.helpers import SourceSwitchHandler

from blivet.util import get_mount_paths
from blivet.util import get_mount_device, get_mount_paths

import re
import os
Expand Down Expand Up @@ -143,6 +143,12 @@ def refresh(self, args=None):

threadMgr.wait(THREAD_PAYLOAD)

if self.data.method.method == "harddrive" and \
get_mount_device(DRACUT_ISODIR) == get_mount_device(DRACUT_REPODIR):
message = _("The installation source is in use by the installer and cannot be changed.")
self._window += [TextWidget(message), ""]
return True

_methods = [_("CD/DVD"), _("local ISO file"), _("Network")]
if args == 3:
text = [TextWidget(_(p)) for p in self._protocols]
Expand Down

0 comments on commit c016e60

Please sign in to comment.