These are the patches related to my school project focusing on random data entropy in the installation process. The make use of the related blivet patches.
PATCH 1/2 tells blivet which callbacks should be used instead of it directly using and understanding our progress handling.
PATCH 2/2 adds callback for the case where there is not enough entropy in the kernel pool. The user may help by moving mouse or typing on keyboard. The functionality is shown in this video preview: http://vpodzime.fedorapeople.org/ensure_entropy.webm
Just please note that I used 1500 bits of entropy as the minimal level, which is much higher than what is actually needed. I believe that using a reasonable value (like 256 bits in the blivet patches) would mean this dialog will hardly ever appear. Another note -- unfortunately, the dialog cannot be lightboxed, because the place where the callbacks are passed to blivet has no reference to the UI and bypassing that would mean a lot of hacks and changes.
Vratislav Podzimek (2): Use callbacks for blivet Inform user we are waiting for random data entropy
anaconda.spec.in | 2 +- po/POTFILES.in | 3 + pyanaconda/install.py | 14 ++++- pyanaconda/progress.py | 8 +++ pyanaconda/ui/gui/spokes/lib/entropy_dialog.glade | 61 +++++++++++++++++++++ pyanaconda/ui/gui/spokes/lib/entropy_dialog.py | 57 +++++++++++++++++++ pyanaconda/ui/lib/entropy.py | 67 +++++++++++++++++++++++ 7 files changed, 209 insertions(+), 3 deletions(-) create mode 100644 pyanaconda/ui/gui/spokes/lib/entropy_dialog.glade create mode 100644 pyanaconda/ui/gui/spokes/lib/entropy_dialog.py create mode 100644 pyanaconda/ui/lib/entropy.py
Signed-off-by: Vratislav Podzimek vpodzime@redhat.com --- anaconda.spec.in | 2 +- pyanaconda/install.py | 11 +++++++++-- pyanaconda/progress.py | 8 ++++++++ 3 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/anaconda.spec.in b/anaconda.spec.in index dcf6d01..efdafd2 100644 --- a/anaconda.spec.in +++ b/anaconda.spec.in @@ -75,7 +75,7 @@ BuildRequires: s390utils-devel %endif
Requires: anaconda-widgets = %{version}-%{release} -Requires: python-blivet >= 0.12 +Requires: python-blivet >= 0.15 Requires: gnome-icon-theme-symbolic Requires: python-meh >= %{mehver} Requires: libreport-anaconda >= 2.0.21-1 diff --git a/pyanaconda/install.py b/pyanaconda/install.py index dd39442..008e2e9 100644 --- a/pyanaconda/install.py +++ b/pyanaconda/install.py @@ -23,7 +23,7 @@ from pyanaconda.constants import ROOT_PATH, THREAD_PAYLOAD from blivet import turnOnFilesystems from pyanaconda.bootloader import writeBootLoader -from pyanaconda.progress import progress_report, progressQ +from pyanaconda.progress import progress_report, progress_message, progress_step, progressQ from pyanaconda.users import createLuserConf, getPassAlgo, Users from pyanaconda import flags from pyanaconda import timezone @@ -135,7 +135,14 @@ def doInstall(storage, payload, ksdata, instClass): # Do partitioning. payload.preStorage()
- turnOnFilesystems(storage, mountOnly=flags.flags.dirInstall) + # callbacks for blivet + callbacks = {"CreateFormatPre": progress_message, + "CreateFormatPost": progress_step, + "ResizeFormatPre": progress_message, + "ResizeFormatPost": progress_step, + } + + turnOnFilesystems(storage, mountOnly=flags.flags.dirInstall, callbacks=callbacks) if not flags.flags.livecdInstall and not flags.flags.dirInstall: storage.write()
diff --git a/pyanaconda/progress.py b/pyanaconda/progress.py index c29b355..7d9277f 100644 --- a/pyanaconda/progress.py +++ b/pyanaconda/progress.py @@ -50,3 +50,11 @@ def progress_report(message): log.info(message) yield progressQ.send_step() + +def progress_message(message): + progressQ.send_message(message) + log.info(message) + +def progress_step(message): + log.info(message) + progressQ.send_step()
Also give a hint how to help.
Signed-off-by: Vratislav Podzimek vpodzime@redhat.com --- po/POTFILES.in | 3 + pyanaconda/install.py | 3 + pyanaconda/ui/gui/spokes/lib/entropy_dialog.glade | 61 +++++++++++++++++++++ pyanaconda/ui/gui/spokes/lib/entropy_dialog.py | 57 +++++++++++++++++++ pyanaconda/ui/lib/entropy.py | 67 +++++++++++++++++++++++ 5 files changed, 191 insertions(+) create mode 100644 pyanaconda/ui/gui/spokes/lib/entropy_dialog.glade create mode 100644 pyanaconda/ui/gui/spokes/lib/entropy_dialog.py create mode 100644 pyanaconda/ui/lib/entropy.py
diff --git a/po/POTFILES.in b/po/POTFILES.in index 1b01520..e232a64 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -32,6 +32,7 @@ pyanaconda/ui/__init__.py
# Common stuff pyanaconda/ui/lib/space.py +pyanaconda/ui/lib/entropy.py
# Text interface pyanaconda/ui/tui/hubs/progress.py @@ -76,6 +77,7 @@ pyanaconda/ui/gui/spokes/lib/passphrase.py pyanaconda/ui/gui/spokes/lib/refresh.py pyanaconda/ui/gui/spokes/lib/resize.py pyanaconda/ui/gui/spokes/lib/summary.py +pyanaconda/ui/gui/spokes/lib/entropy.py
# Interface files. pyanaconda/ui/gui/spokes/advanced_user.glade @@ -99,6 +101,7 @@ pyanaconda/ui/gui/spokes/lib/passphrase.glade pyanaconda/ui/gui/spokes/lib/refresh.glade pyanaconda/ui/gui/spokes/lib/resize.glade pyanaconda/ui/gui/spokes/lib/summary.glade +pyanaconda/ui/gui/spokes/lib/entropy_dialog.glade pyanaconda/ui/gui/main.glade pyanaconda/ui/gui/hubs/summary.glade pyanaconda/ui/gui/hubs/progress.glade diff --git a/pyanaconda/install.py b/pyanaconda/install.py index 008e2e9..3b2ea25 100644 --- a/pyanaconda/install.py +++ b/pyanaconda/install.py @@ -29,6 +29,7 @@ from pyanaconda import flags from pyanaconda import timezone from pyanaconda.i18n import _ from pyanaconda.threads import threadMgr +from pyanaconda.ui.lib.entropy import wait_for_entropy import logging log = logging.getLogger("anaconda")
@@ -140,6 +141,8 @@ def doInstall(storage, payload, ksdata, instClass): "CreateFormatPost": progress_step, "ResizeFormatPre": progress_message, "ResizeFormatPost": progress_step, + "WaitForEntropy": lambda msg, ent: wait_for_entropy(msg, ent, + ksdata), }
turnOnFilesystems(storage, mountOnly=flags.flags.dirInstall, callbacks=callbacks) diff --git a/pyanaconda/ui/gui/spokes/lib/entropy_dialog.glade b/pyanaconda/ui/gui/spokes/lib/entropy_dialog.glade new file mode 100644 index 0000000..5f9f828 --- /dev/null +++ b/pyanaconda/ui/gui/spokes/lib/entropy_dialog.glade @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <!-- interface-requires gtk+ 3.0 --> + <object class="GtkWindow" id="entropyDialog"> + <property name="can_focus">False</property> + <property name="type">popup</property> + <property name="modal">True</property> + <property name="window_position">center</property> + <child> + <object class="GtkFrame" id="frame1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label_xalign">0</property> + <property name="shadow_type">etched-out</property> + <child> + <object class="GtkBox" id="mainBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">6</property> + <property name="margin_right">6</property> + <property name="margin_top">6</property> + <property name="margin_bottom">6</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="messageLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="valign">center</property> + <property name="vexpand">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">The system doesn't have enough random data entropy for the actions it needs to execute. To shorten the time of waiting for enough entropy, please move your mouse or type on the keyboard.</property> + <property name="wrap">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkProgressBar" id="progressBar"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="show_text">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + <child type="label_item"> + <placeholder/> + </child> + </object> + </child> + </object> +</interface> diff --git a/pyanaconda/ui/gui/spokes/lib/entropy_dialog.py b/pyanaconda/ui/gui/spokes/lib/entropy_dialog.py new file mode 100644 index 0000000..ff6e154 --- /dev/null +++ b/pyanaconda/ui/gui/spokes/lib/entropy_dialog.py @@ -0,0 +1,57 @@ +# Dialog for waiting for enough random data entropy +# +# Copyright (C) 2013 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): Vratislav Podzimek vpodzime@redhat.com +# + +# pylint: disable-msg=E0611 +from gi.repository import Gtk, GLib + +from pyanaconda.ui.gui import GUIObject +from blivet.util import get_current_entropy + +__all__ = ["EntropyDialog"] + +class EntropyDialog(GUIObject): + builderObjects = ["entropyDialog"] + mainWidgetName = "entropyDialog" + uiFile = "spokes/lib/entropy_dialog.glade" + + def __init__(self, data, desired_entropy): + GUIObject.__init__(self, data) + self._desired_entropy = desired_entropy + self._progress_bar = self.builder.get_object("progressBar") + + def run(self): + self.window.show_all() + GLib.timeout_add(250, self._update_progress) + Gtk.main() + self.window.destroy() + + def _update_progress(self): + current_entropy = get_current_entropy() + current_fraction = min(float(current_entropy) / self._desired_entropy, 1.0) + self._progress_bar.set_fraction(current_fraction) + + if current_entropy >= self._desired_entropy: + Gtk.main_quit() + # remove the method from idle queue + return False + else: + # keep updating + return True diff --git a/pyanaconda/ui/lib/entropy.py b/pyanaconda/ui/lib/entropy.py new file mode 100644 index 0000000..514a642 --- /dev/null +++ b/pyanaconda/ui/lib/entropy.py @@ -0,0 +1,67 @@ +# +# Copyright (C) 2013 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): Vratislav Podzimek vpodzime@redhat.com +# + +""" +Helper module with functions for informing user we are waiting for random +data entropy. + +""" + +# pylint: disable-msg=E0611 +from gi.repository import Gtk +from pyanaconda.ui.gui.spokes.lib.entropy_dialog import EntropyDialog +from pyanaconda.ui.gui.utils import gtk_action_wait +from pyanaconda.progress import progress_message + +from pyanaconda.i18n import _ + +def wait_for_entropy(msg, desired_entropy, ksdata): + """ + Show UI dialog/message for waiting for desired random data entropy. + + :param ksdata: kickstart data + :type ksdata: pykickstart.base.BaseHandler + :param desired_entropy: entropy level to wait for + :type desired_entropy: int + + """ + + progress_message(_("The system needs more random data entropy")) + + (succ, args) = Gtk.init_check(None) + if succ: + # Gtk initialized, run GUI dialog + _gui_wait(ksdata, desired_entropy) + else: + _tui_wait(msg) + +@gtk_action_wait +def _gui_wait(ksdata, desired_entropy): + """Show dialog with waiting for entropy""" + + dialog = EntropyDialog(ksdata, desired_entropy) + dialog.run() + +def _tui_wait(msg): + """Tell user we are waiting for entropy""" + + # TODO: need to be improved -- turn off echo and encourage user to help with + # the entropy + pass
anaconda-patches@lists.fedorahosted.org