[anaconda][master/rhel7-branch][3/3] Add GUI and TUI logic to handle unformatted DASDs. (#1064423)

Vratislav Podzimek vpodzime at redhat.com
Tue Mar 4 18:26:44 UTC 2014


On Mon, 2014-03-03 at 12:53 -0500, Samantha N. Bueno wrote:
> In both graphical and text, if a user selects unformatted DASDs from the
> local disk store, they are given an option to format them  when either
> clicking 'Done' or hitting 'c' to continue.
> 
> Following dasdfmt, storage initialization is run again in order
> to properly add the new DASDs to the devicetree and seen by the
> installer.
> 
> Resolves:rhbz#1064423
> ---
>  pyanaconda/constants.py             |  1 +
>  pyanaconda/ui/gui/spokes/storage.py | 79 ++++++++++++++++++++++++++++++++++++-
>  pyanaconda/ui/tui/spokes/storage.py | 68 +++++++++++++++++++++++++++++--
>  3 files changed, 142 insertions(+), 6 deletions(-)
> 
> diff --git a/pyanaconda/constants.py b/pyanaconda/constants.py
> index cf8a8ea..8de29a9 100644
> --- a/pyanaconda/constants.py
> +++ b/pyanaconda/constants.py
> @@ -131,6 +131,7 @@ THREAD_ISCSI_LOGIN = "AnaIscsiLoginThread"
>  THREAD_GEOLOCATION_REFRESH = "AnaGeolocationRefreshThread"
>  THREAD_DATE_TIME = "AnaDateTimeThread"
>  THREAD_TIME_INIT = "AnaTimeInitThread"
> +THREAD_DASDFMT = "AnaDasdfmtThread"
>  
>  # Geolocation constants
>  
> diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py
> index 6f719db..4db4ad0 100644
> --- a/pyanaconda/ui/gui/spokes/storage.py
> +++ b/pyanaconda/ui/gui/spokes/storage.py
> @@ -50,17 +50,20 @@ from pyanaconda.ui.gui.spokes.lib.cart import SelectedDisksDialog
>  from pyanaconda.ui.gui.spokes.lib.passphrase import PassphraseDialog
>  from pyanaconda.ui.gui.spokes.lib.detailederror import DetailedErrorDialog
>  from pyanaconda.ui.gui.spokes.lib.resize import ResizeDialog
> +from pyanaconda.ui.gui.spokes.lib.dasdfmt import DasdFormatDialog
>  from pyanaconda.ui.gui.categories.system import SystemCategory
> -from pyanaconda.ui.gui.utils import enlightbox, gtk_call_once, gtk_action_wait
> +from pyanaconda.ui.gui.utils import enlightbox, gtk_call_once, gtk_action_wait, gtk_action_nowait, ignoreEscape
>  
>  from pyanaconda.kickstart import doKickstartStorage, getAvailableDiskSpace
> +from blivet import storageInitialize, arch
>  from blivet.size import Size
>  from blivet.devices import MultipathDevice
> -from blivet.errors import StorageError
> +from blivet.errors import StorageError, DasdFormatError
>  from blivet.errors import SanityError
>  from blivet.errors import SanityWarning
>  from blivet.platform import platform
>  from blivet.devicelibs import swap as swap_lib
> +from blivet.devicelibs.dasd import make_unformatted_dasd_list, format_dasd
>  from pyanaconda.threads import threadMgr, AnacondaThread
>  from pyanaconda.product import productName
>  from pyanaconda.flags import flags
> @@ -292,6 +295,11 @@ class StorageSpoke(NormalSpoke, StorageChecker):
>          self.autoPartType = None
>          self.clearPartType = CLEARPART_TYPE_NONE
>  
> +        if self.data.zerombr.zerombr and arch.isS390():
> +            # run dasdfmt on any unformatted DASDs automatically
> +            threadMgr.add(AnacondaThread(name=constants.THREAD_DASDFMT,
> +                            target=self.run_dasdfmt))
> +
>          self._previous_autopart = False
>  
>          self._last_clicked_overview = None
> @@ -338,6 +346,7 @@ class StorageSpoke(NormalSpoke, StorageChecker):
>                  request.size = swap_lib.swapSuggestion(disk_space=disk_space)
>                  break
>  
> +    @gtk_action_nowait
>      def execute(self):
>          # Spawn storage execution as a separate thread so there's no big delay
>          # going back from this spoke to the hub while StorageChecker.run runs.
> @@ -348,6 +357,10 @@ class StorageSpoke(NormalSpoke, StorageChecker):
>      def _doExecute(self):
>          self._ready = False
>          hubQ.send_not_ready(self.__class__.__name__)
> +        # ugly and stupid, but on the off-chance dasdfmt is running, we can't
> +        # proceed further with this
> +        while threadMgr.get(constants.THREAD_DASDFMT):
> +            continue
I still think this could be replaced with
    threadMgr.wait(constants.THREAD_DASDFMT)
because it would do the same and this code is running in a non-main
thread.

>          hubQ.send_message(self.__class__.__name__, _("Saving storage configuration..."))
>          try:
>              doKickstartStorage(self.storage, self.data, self.instclass)
> @@ -400,6 +413,8 @@ class StorageSpoke(NormalSpoke, StorageChecker):
>  
>          if not self._confirmed:
>              msg = _("Not configured")
> +        elif threadMgr.get(constants.THREAD_DASDFMT):
> +            msg = _("Formatting DASDs")
>          elif flags.automatedInstall and not self.storage.rootDevice:
>              return msg
>          elif self.data.ignoredisk.onlyuse:
> @@ -672,6 +687,38 @@ class StorageSpoke(NormalSpoke, StorageChecker):
>              if not selected and name in self.selected_disks:
>                  self.selected_disks.remove(name)
>  
> +    def run_dasdfmt(self):
> +        """
> +        Though the same function exists in pyanaconda.ui.gui.spokes.lib.dasdfmt,
> +        this instance doesn't include any of the UI pieces and should only
> +        really be getting called on ks installations with "zerombr".
> +        """
> +        # wait for the initial storage thread to complete before taking any new
> +        # actions on storage devices
> +        threadMgr.wait(constants.THREAD_STORAGE)
> +
> +        to_format = make_unformatted_dasd_list(self.selected_disks)
> +        if not to_format:
> +            # nothing to do here; bail
> +            return
> +
> +        hubQ.send_message(self.__class__.__name__, _("Formatting DASDs"))
> +        for disk in to_format:
> +            try:
> +                format_dasd(disk)
> +            except DasdFormatError as err:
> +                # Log errors if formatting fails, but don't halt the installer
> +                log.error(str(err))
> +                continue
> +
> +        # now re-initialize storage to pick up the newly formatted disks
> +        protectedNames = [d.name for d in self.storage.protectedDevices]
> +        storageInitialize(self.storage, self.data, protectedNames)
> +
> +        # I really hate doing this, but the way is the way; probably the most
> +        # correct way to kajigger the storage spoke into becoming ready
> +        self.execute()
> +
>      # signal handlers
>      def on_summary_clicked(self, button):
>          # show the selected disks dialog
> @@ -760,6 +807,34 @@ class StorageSpoke(NormalSpoke, StorageChecker):
>              NormalSpoke.on_back_clicked(self, button)
>              return
>  
> +        if arch.isS390():
> +            # check for unformatted DASDs and launch dasdfmt if any discovered
> +            dasds = make_unformatted_dasd_list(self.selected_disks)
> +            if len(dasds) > 0:
> +                dialog = DasdFormatDialog(self.data, self.storage, dasds)
> +                ignoreEscape(dialog.window)
> +                rc = self.run_lightbox_dialog(dialog)
> +                if rc == 1:
> +                    # User hit OK on the dialog, indicating they stayed on the
> +                    # dialog until formatting completed and now needs to go back
> +                    # to the main storage spoke.
> +                    dialog.window.destroy()
I believe the dialog destroy's its own window in its run() method, no
need to do it again here.

> +                    # make sure we stay on the storage spoke and don't return to
> +                    # the summary hub
> +                    self.skipTo = "StorageSpoke"
> +                    # we have to manaually call refresh so changes are picked up
> +                    self.refresh()
> +                elif rc == 2:
> +                    # User clicked uri to return to hub.
> +                    NormalSpoke.on_back_clicked(self, button)
> +                    return
> +                elif rc != 2:
> +                    # User either hit cancel on the dialog or closed it via escape, so
> +                    # there was no formatting done.
> +                    # NOTE: rc == 2 means the user clicked on the link that takes them
> +                    # back to the hub.
> +                    return
> +
>          # Figure out if the existing disk labels will work on this platform
>          # you need to have at least one of the platform's labels in order for
>          # any of the free space to be useful.
> diff --git a/pyanaconda/ui/tui/spokes/storage.py b/pyanaconda/ui/tui/spokes/storage.py
> index 088684b..a8f8c2e 100644
> --- a/pyanaconda/ui/tui/spokes/storage.py
> +++ b/pyanaconda/ui/tui/spokes/storage.py
> @@ -1,6 +1,6 @@
>  # Text storage configuration spoke classes
>  #
> -# Copyright (C) 2012  Red Hat, Inc.
> +# Copyright (C) 2014  Red Hat, Inc.
This should be 2012-2014.

-- 
Vratislav Podzimek

Anaconda Rider | Red Hat, Inc. | Brno - Czech Republic



More information about the anaconda-patches mailing list