[master] UTC/localtime HW clock heuristic
by Vratislav Podzimek
PATCH [1/2] is just a minor change without any significant result.
PATCH [2/2] adds a heuristic to guess wheter HW clock uses UTC or local
time by searching for bootable NTFS partitions. It adds two threads, but
these are really lightweight and just handle the potential long storage
initialization.
Vratislav Podzimek (2):
Return bool value from the GRUB.has_windows method
Set system time from HW clock and guess if it is UTC
anaconda | 11 ++++++++-
pyanaconda/bootloader.py | 2 +-
pyanaconda/kickstart.py | 7 ------
pyanaconda/timezone.py | 38 ++++++++++++++++++++++++++++++
pyanaconda/ui/gui/spokes/datetime_spoke.py | 20 ++++++++++++++++
5 files changed, 69 insertions(+), 9 deletions(-)
--
1.7.11.7
10 years, 10 months
[master] Patch for exceptions in non-main thread in TUI
by Vratislav Podzimek
This patch provides a fix for the case when there is an exception
in a non-main thread in text mode. It is impossible to run the
exception handler in the non-main thread for many reasons. It competes
with the main thread for standard input, it cannot run libreport
because libreport forks, it cannot quit the installer because the main
thread would still be running and probably something else I didn't hit
yet. This builds on Martin's patch for processing our message queue in
text mode.
The only remaining problem is, that when the main thread runs raw_input
another call of raw_input from the exception handler is blocked until
the first one is finished. Thus one needs to hit ENTER before entering
any input for the exception handler. This can be fixed by telling
python-meh's exception handler that it should use our raw_input instead
of the built-in one but I am leaving this for an additional patch as it
needs some changes in python-meh (and thus new build).
Vratislav Podzimek (1):
Run exception handling in the main thread also in TUI
anaconda | 4 ++-
pyanaconda/exception.py | 74 ++++++++++++++++++++++++++++++++-----------
pyanaconda/ui/tui/__init__.py | 7 ++--
3 files changed, 64 insertions(+), 21 deletions(-)
--
1.7.11.7
11 years, 1 month
[PATCH] Teach TUI how to react on async events
by Martin Sivak
This involves couple of places:
- TUI is blocking and waiting for user input
- Progress HUB is in charge and is reading the progress queue
- any other part wanting to react to a message like READY, ..
This patch directly fixes the first two and adds a mechanism
to register callbacks that will react to the third one.
We (me and vpodzime) expect python-meh integration to use
this to file exception reports from text mode installation.
---
pyanaconda/ui/communication.py | 4 ++
pyanaconda/ui/tui/__init__.py | 3 +-
pyanaconda/ui/tui/hubs/progress.py | 12 +++-
pyanaconda/ui/tui/simpleline/base.py | 104 +++++++++++++++++++++++++++++++++--
pyanaconda/ui/tui/spokes/password.py | 5 +-
5 files changed, 117 insertions(+), 11 deletions(-)
diff --git a/pyanaconda/ui/communication.py b/pyanaconda/ui/communication.py
index 19e3a24..04bb512 100644
--- a/pyanaconda/ui/communication.py
+++ b/pyanaconda/ui/communication.py
@@ -37,9 +37,13 @@ hubQ = Queue.Queue()
# _READY - [spoke_name, justUpdate]
# _NOT_READY - [spoke_name]
# _MESSAGE - [spoke_name, string]
+# _INPUT - [string]
+# _EXCEPTION - [exc]
HUB_CODE_READY = 0
HUB_CODE_NOT_READY = 1
HUB_CODE_MESSAGE = 2
+HUB_CODE_INPUT = 3
+HUB_CODE_EXCEPTION = 4
# Convenience methods to put things into the queue without the user having to
# know the details of the queue.
diff --git a/pyanaconda/ui/tui/__init__.py b/pyanaconda/ui/tui/__init__.py
index 83c2beb..8da9846 100644
--- a/pyanaconda/ui/tui/__init__.py
+++ b/pyanaconda/ui/tui/__init__.py
@@ -21,6 +21,7 @@
from pyanaconda import ui
from pyanaconda.ui import common
+from pyanaconda.ui import communication
from pyanaconda.flags import flags
import simpleline as tui
from hubs.summary import SummaryHub
@@ -170,7 +171,7 @@ class TextUserInterface(ui.UserInterface):
"""Construct all the objects required to implement this interface.
This method must be provided by all subclasses.
"""
- self._app = tui.App(u"Anaconda", yes_or_no_question = YesNoDialog)
+ self._app = tui.App(u"Anaconda", yes_or_no_question=YesNoDialog, queue=communication.hubQ)
_hubs = self._list_hubs()
# First, grab a list of all the standalone spokes.
diff --git a/pyanaconda/ui/tui/hubs/progress.py b/pyanaconda/ui/tui/hubs/progress.py
index c80372e..72cb5dc 100644
--- a/pyanaconda/ui/tui/hubs/progress.py
+++ b/pyanaconda/ui/tui/hubs/progress.py
@@ -52,7 +52,17 @@ class ProgressHub(TUIHub):
while True:
# Attempt to get a message out of the queue for how we should update
# the progress bar. If there's no message, don't error out.
- (code, args) = q.get()
+ # Also flush the communication Queue at least once a second and
+ # process it's events so we can react to async evens (like a thread
+ # throwing an exception)
+ while True:
+ try:
+ (code, args) = q.get(timeout = 1)
+ break
+ except Queue.Empty:
+ pass
+ finally:
+ self.app.process_events()
if code == progress.PROGRESS_CODE_INIT:
# Text mode doesn't have a finite progress bar
diff --git a/pyanaconda/ui/tui/simpleline/base.py b/pyanaconda/ui/tui/simpleline/base.py
index e3039d2..f6ed9fb 100644
--- a/pyanaconda/ui/tui/simpleline/base.py
+++ b/pyanaconda/ui/tui/simpleline/base.py
@@ -22,6 +22,10 @@
__all__ = ["App", "UIScreen", "Widget"]
import readline
+import Queue
+import getpass
+from pyanaconda.threads import threadMgr, AnacondaThread
+from pyanaconda.ui.communication import HUB_CODE_INPUT
import gettext
_ = lambda x: gettext.ldgettext("anaconda", x)
@@ -36,7 +40,6 @@ class ExitMainLoop(Exception):
close."""
pass
-
class App(object):
"""This is the main class for TUI screen handling. It is responsible for
mainloop control and keeping track of the screen stack.
@@ -55,7 +58,7 @@ class App(object):
STOP_MAINLOOP = False
NOP = None
- def __init__(self, title, yes_or_no_question = None, width = 80):
+ def __init__(self, title, yes_or_no_question = None, width = 80, queue = None):
"""
:param title: application title for whenever we need to display app name
:type title: unicode
@@ -72,6 +75,20 @@ class App(object):
self._width = width
self.quit_question = yes_or_no_question
+ # async control queue
+ if queue:
+ self.queue = queue
+ else:
+ self.queue = Queue.Queue()
+
+ # ensure unique thread names
+ self._in_thread_counter = 0
+
+ # event handlers
+ # key: event id
+ # value: list of tuples (callback, data)
+ self._handlers = {}
+
# screen stack contains triplets
# UIScreen to show
# arguments for it's show method
@@ -81,6 +98,50 @@ class App(object):
# - False = already running loop, exit when window closes
self._screens = []
+ def register_event_handler(self, event, callback, data = None):
+ """This method registers a callback which will be called
+ when message "event" is encountered during process_events.
+
+ The callback has to accept two arguments:
+ - the received message in the form of (type, [arguments])
+ - the data registered with the handler
+
+ :param event: the id of the event we want to react on
+ :type event: number|string
+
+ :param callback: the callback function
+ :type callback: func(event_message, data)
+
+ :param data: optional data to pass to callback
+ :type data: anything
+ """
+ if not event in self._handlers:
+ self._handlers[event] = []
+ self._handlers[event].append((callback, data))
+
+ def _thread_input(self, queue, prompt, hidden):
+ """This method is responsible for interruptible user input. It is expected
+ to be used in a thread started on demand by the App class and returns the
+ input via the communication Queue.
+
+ :param queue: communication queue to be used
+ :type queue: Queue.Queue instance
+
+ :param prompt: prompt to be displayed
+ :type prompt: str
+
+ :param hidden: whether typed characters should be echoed or not
+ :type hidden: bool
+
+ """
+
+ if hidden:
+ data = getpass.getpass(prompt)
+ else:
+ data = raw_input(prompt)
+
+ queue.put((HUB_CODE_INPUT, [data]))
+
def switch_screen(self, ui, args = None):
"""Schedules a screen to replace the current one.
@@ -223,6 +284,9 @@ class App(object):
# run until there is nothing else to display
while self._screens:
+ # process asynchronous events
+ self.process_events()
+
# if redraw is needed, separate the content on the screen from the
# stuff we are about to display now
if self._redraw:
@@ -271,10 +335,38 @@ class App(object):
except ExitAllMainLoops:
raise
- def raw_input(self, prompt):
- """This method reads one input from user. Its basic form has only one line,
- but we might need to override it for more complex apps or testing."""
- return raw_input(prompt)
+ def process_events(self, return_at = None):
+ """This method processes incoming async messages and returns
+ when a specific message is encountered or when the queue
+ is empty.
+
+ If return_at message was specified, the received
+ message is returned.
+
+ If the message does not fit return_at, but handlers are
+ defined then it processes all handlers for this message
+ """
+ while return_at or not self.queue.empty():
+ event = self.queue.get()
+ if event[0] == return_at:
+ return event
+ elif event[0] in self._handlers:
+ for handler, data in self._handlers[event[0]]:
+ handler(event, data)
+
+ def raw_input(self, prompt, hidden=False):
+ """This method reads one input from user. Its basic form has only one
+ line, but we might need to override it for more complex apps or testing."""
+
+ thread_name = "AnaInputThread%d" % self._in_thread_counter
+ self._in_thread_counter += 1
+ input_thread = AnacondaThread(name=thread_name,
+ target=self._thread_input,
+ args=(self.queue, prompt, hidden))
+ input_thread.daemon = True
+ threadMgr.add(input_thread)
+ event = self.process_events(return_at=HUB_CODE_INPUT)
+ return event[1][0] # return the user input
def input(self, args, key):
"""Method called internally to process unhandled input key presses.
diff --git a/pyanaconda/ui/tui/spokes/password.py b/pyanaconda/ui/tui/spokes/password.py
index f812678..bd81603 100644
--- a/pyanaconda/ui/tui/spokes/password.py
+++ b/pyanaconda/ui/tui/spokes/password.py
@@ -25,7 +25,6 @@ from pyanaconda.ui.tui.simpleline import TextWidget
from pyanaconda.ui.tui import YesNoDialog
from pyanaconda.users import validatePassword
from pwquality import PWQError
-import getpass
import gettext
_ = lambda x: gettext.ldgettext("anaconda", x)
@@ -65,8 +64,8 @@ class PasswordSpoke(NormalTUISpoke):
def prompt(self, args = None):
"""Overriden prompt as password typing is special."""
- pw = getpass.getpass(_("Password: "))
- confirm = getpass.getpass(_("Password (confirm): "))
+ pw = self._app.raw_input(_("Password: "), hidden=True)
+ confirm = self._app.raw_input(_("Password (confirm): "), hidden=True)
error = None
# just returning an error is either blank or mismatched
--
1.7.11.7
11 years, 2 months
[PATCH 1/3] Point gobject-introspection at our updates directory for overrides.
by Chris Lumens
---
anaconda | 3 +++
1 file changed, 3 insertions(+)
diff --git a/anaconda b/anaconda
index d0dd05e..10d1abb 100755
--- a/anaconda
+++ b/anaconda
@@ -133,6 +133,7 @@ def set_x_resolution(runres):
def setupPythonUpdates():
from distutils.sysconfig import get_python_lib
+ import gi.overrides
# Temporary hack for F18 alpha to symlink updates and product directories
# into tmpfs. To be removed after beta in order to directly use content
@@ -166,6 +167,8 @@ def setupPythonUpdates():
# the updates directory.
symlink_updates(dest, d)
+ gi.overrides.__path__.insert(0, "/run/install/updates")
+
import glob
import shutil
for rule in glob.glob("/tmp/updates/*.rules"):
--
1.7.11.2
11 years, 2 months
[lorax 0/4] template cleanup
by Dan Horák
This is a cleanup for the template to reduce the number of ERROR messages
printed during a compose, not only on s390x.
Dan Horák (4):
no Xorg on s390x
specspo is dead for a long time
tools not existing on s390x
tigervnc-server-module depends on Xorg, which doesn't exist on s390x
share/runtime-install.tmpl | 16 ++++++++++++----
1 files changed, 12 insertions(+), 4 deletions(-)
--
1.7.7.6
11 years, 2 months
[PATCH 1/7] Make it a little more clear what's happening on the disk selection spoke (#903498).
by Chris Lumens
---
pyanaconda/ui/gui/spokes/storage.glade | 53 ++++++++++++++++++++++++++++++----
1 file changed, 48 insertions(+), 5 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/storage.glade b/pyanaconda/ui/gui/spokes/storage.glade
index ca19e72..8162383 100644
--- a/pyanaconda/ui/gui/spokes/storage.glade
+++ b/pyanaconda/ui/gui/spokes/storage.glade
@@ -885,6 +885,26 @@
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">18</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">6</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Select the device(s) you'd lke to install to. They will be left untouched until you click on the main menu's "Begin Installation" button.</property>
+ <property name="wrap">True</property>
+ <attributes>
+ <attribute name="font-desc" value="Cantarell 12"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -901,7 +921,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">0</property>
+ <property name="position">1</property>
</packing>
</child>
<child>
@@ -937,7 +957,24 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">1</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_right">24</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Disks left unselected here will not be touched.</property>
+ <attributes>
+ <attribute name="font-desc" value="Cantarell Italic 10"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
</packing>
</child>
<child>
@@ -952,16 +989,16 @@
<property name="column_spacing">6</property>
<child>
<object class="GtkButton" id="summary_button">
- <property name="label" translatable="yes">_Full disk summary and options...</property>
+ <property name="label" translatable="yes">_Full disk summary and bootloader...</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
+ <property name="no_show_all">True</property>
<property name="halign">start</property>
<property name="margin_left">18</property>
<property name="relief">none</property>
<property name="use_underline">True</property>
<property name="focus_on_click">False</property>
- <property name="no_show_all">True</property>
<property name="xalign">0</property>
<signal name="clicked" handler="on_summary_clicked" swapped="no"/>
</object>
@@ -1013,12 +1050,18 @@
<child>
<placeholder/>
</child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
- <property name="position">3</property>
+ <property name="position">4</property>
</packing>
</child>
</object>
--
1.7.11.2
11 years, 2 months
[PATCH] Put _isys.so to right place
by Vratislav Podzimek
We need it in the $UPDATES/pyanaconda/isys so that it can be imported
from the updated $UPDATES/pyanaconda/isys/__init__.py module.
Signed-off-by: Vratislav Podzimek <vpodzime(a)redhat.com>
---
scripts/makeupdates | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/makeupdates b/scripts/makeupdates
index c69cd0a..5591dc1 100755
--- a/scripts/makeupdates
+++ b/scripts/makeupdates
@@ -227,7 +227,7 @@ def copyUpdatedIsys(updates, cwd):
# $updatedir/run/install/updates.
tmpupdates = updates.rstrip('/')
if not tmpupdates.endswith("/run/install/updates/pyanaconda"):
- tmpupdates = os.path.join(tmpupdates, "run/install/updates/pyanaconda")
+ tmpupdates = os.path.join(tmpupdates, "run/install/updates/pyanaconda/isys")
isysmodule = os.path.realpath(cwd + '/pyanaconda/isys/.libs/_isys.so')
if os.path.isfile(isysmodule):
--
1.7.11.7
11 years, 2 months
[PATCH] Move Xorg to vt7
by Brian C. Lane
From: "Brian C. Lane" <bcl(a)redhat.com>
logind now starts a getty on tty6. We could just let it pick a free vt,
but there's a small chance that could interfere with our logging to ttyX
---
anaconda | 2 +-
pyanaconda/ui/gui/__init__.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/anaconda b/anaconda
index 4cf4b12..8c1bc11 100755
--- a/anaconda
+++ b/anaconda
@@ -544,7 +544,7 @@ def setupDisplay(anaconda, opts, addon_paths=None):
try:
proc = subprocess.Popen(["Xorg", "-br",
"-logfile", "/tmp/X.log",
- ":1", "vt6", "-s", "1440", "-ac",
+ ":1", "vt7", "-s", "1440", "-ac",
"-nolisten", "tcp", "-dpi", "96",
"-noreset"],
close_fds=True,
diff --git a/pyanaconda/ui/gui/__init__.py b/pyanaconda/ui/gui/__init__.py
index d79aba6..1e432d4 100644
--- a/pyanaconda/ui/gui/__init__.py
+++ b/pyanaconda/ui/gui/__init__.py
@@ -264,7 +264,7 @@ class GraphicalUserInterface(UserInterface):
@property
def tty_num(self):
- return 6
+ return 7
@property
def meh_interface(self):
--
1.8.0.2
11 years, 2 months
[PATCH 1/4] Remove the widget-specific TODO list.
by Chris Lumens
There's nothing important in here anymore, and we need to condense these lists
into one central place.
---
widgets/TODO | 24 ------------------------
1 file changed, 24 deletions(-)
delete mode 100644 widgets/TODO
diff --git a/widgets/TODO b/widgets/TODO
deleted file mode 100644
index fc1ffa5..0000000
--- a/widgets/TODO
+++ /dev/null
@@ -1,24 +0,0 @@
-BaseWindow -
-
-DiskOverview -
- - add utilization pie chart
-
-SpokeSelector -
- - status text should be white when a selector is focused
-
-SpokeWindow -
-
-StandaloneWindow -
-
-New Widgets -
-
-glade Integration -
- - add icons
- - audit all widgets for which signals and properties should be exposed in glade UI
-
-Build -
-
-Misc -
- - add test cases
- - coding standard document
- - can CSS live outside of C files?
--
1.7.11.2
11 years, 3 months