summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVratislav Podzimek <vpodzime@redhat.com>2012-10-04 12:37:24 +0200
committerVratislav Podzimek <vpodzime@redhat.com>2012-10-12 15:46:48 +0200
commit4b98eab34f310c2704ec24b417bdf919c413fa1d (patch)
tree5a09fb8239a9a83598600f061e07cfe8b9e79abb
parent4dbff52bd69a20a49881a90ac5f0cb8a8dc3eac2 (diff)
downloadanaconda-4b98eab34f310c2704ec24b417bdf919c413fa1d.tar.gz
anaconda-4b98eab34f310c2704ec24b417bdf919c413fa1d.tar.xz
anaconda-4b98eab34f310c2704ec24b417bdf919c413fa1d.zip
Work with VConsole keymap and X layouts separately
We need to set VConsole keymap and X layouts separately. We may get them all from kickstart, but if not, we have to convert the given one to the missing one and save the configuration. If X11 configuration is written before the server is started, it is loaded. This way we can get rid of using XklWrapper in main anaconda script. Also we need to write one more configuration file. And it's better to try to write all configuration files ignoring errors and in case some error(s) appeared, raise exception at the end of the procedure. Resolves: rhbz#853877 Resolves: rhbz#856362 Resolves: rhbz#859867
-rwxr-xr-xanaconda16
-rw-r--r--anaconda.spec.in2
-rwxr-xr-xpyanaconda/keyboard.py139
-rw-r--r--pyanaconda/kickstart.py3
-rw-r--r--pyanaconda/ui/gui/spokes/keyboard.py8
-rw-r--r--pyanaconda/ui/gui/spokes/welcome.py6
6 files changed, 112 insertions, 62 deletions
diff --git a/anaconda b/anaconda
index 90fad452f..5d2ec72d5 100755
--- a/anaconda
+++ b/anaconda
@@ -580,20 +580,6 @@ def setupDisplay(anaconda, opts):
# with X running we can initialize the UI interface
anaconda.initInterface()
- # setup layouts
- if anaconda.displayMode == 'g' and anaconda.ksdata.keyboard.layouts_list:
- from pyanaconda.keyboard import XklWrapper, XklWrapperError
-
- layouts = anaconda.ksdata.keyboard.layouts_list
- xklwrapper = XklWrapper.get_instance()
-
- try:
- xklwrapper.replace_layouts(layouts)
-
- except XklWrapperError as xklerr:
- msg = "Failed to activate layouts %s" % ",".join(layouts)
- log.error(msg)
-
anaconda.instClass.configure(anaconda)
def prompt_for_ssh():
@@ -856,7 +842,7 @@ if __name__ == "__main__":
ksdata.keyboard.keyboard = opts.keymap
if ksdata.keyboard.keyboard:
- keyboard.activate_console_keymap(ksdata.keyboard.keyboard)
+ keyboard.activate_keyboard(ksdata.keyboard)
# Some post-install parts of anaconda are implemented as kickstart
# scripts. Add those to the ksdata now.
diff --git a/anaconda.spec.in b/anaconda.spec.in
index d59c555c5..ded94903b 100644
--- a/anaconda.spec.in
+++ b/anaconda.spec.in
@@ -26,7 +26,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
%define intltoolver 0.31.2-3
%define libnlver 1.0
%define libselinuxver 1.6
-%define pykickstartver 1.99.18
+%define pykickstartver 1.99.20
%define rpmpythonver 4.2-0.61
%define slangver 2.0.6-2
%define yumver 3.4.3-32
diff --git a/pyanaconda/keyboard.py b/pyanaconda/keyboard.py
index 42e8380ef..f4f4f7587 100755
--- a/pyanaconda/keyboard.py
+++ b/pyanaconda/keyboard.py
@@ -31,7 +31,6 @@ for listing and various modifications of keyboard layouts settings.
"""
import os
-import re
import dbus
from pyanaconda import iutil
@@ -98,7 +97,7 @@ def get_layouts_xorg_conf(keyboard):
layouts = list()
variants = list()
- for layout_variant in keyboard.layouts_list:
+ for layout_variant in keyboard.x_layouts:
(layout, variant) = _parse_layout_variant(layout_variant)
layouts.append(layout)
variants.append(variant)
@@ -131,83 +130,149 @@ def get_layouts_xorg_conf(keyboard):
return ret
-def write_layouts_config(keyboard, root):
+def write_keyboard_config(keyboard, root, convert=True, weight=0):
"""
Function that writes files with layouts configuration to
- $root/etc/X11/xorg.conf.d/01-anaconda-layouts.conf and
- $root/etc/sysconfig/keyboard.
+ $root/etc/X11/xorg.conf.d/01-anaconda-layouts.conf,
+ $root/etc/sysconfig/keyboard and $root/etc/vconsole.conf.
@param keyboard: ksdata.keyboard object
@param root: path to the root of the installed system
+ @param convert: whether to convert specified values to get the missing
+ ones
+ @param weight: weight (prefix) of the xorg.conf file written out
"""
+ localed = LocaledWrapper()
+
+ if convert:
+ # populate vc_keymap and x_layouts if they are missing
+ if keyboard.x_layouts and not keyboard.vc_keymap:
+ keyboard.vc_keymap = \
+ localed.set_and_convert_layout(keyboard.x_layouts[0])
+
+ if not keyboard.vc_keymap:
+ keyboard.vc_keymap = "us"
+
+ if not keyboard.x_layouts:
+ c_lay_var = localed.set_and_convert_keymap(keyboard.vc_keymap)
+ keyboard.x_layouts.append(c_lay_var)
+
xconf_dir = os.path.normpath(root + "/etc/X11/xorg.conf.d")
- xconf_file = "01-anaconda-keyboard.conf"
+ xconf_file = "%0.2d-anaconda-keyboard.conf" % weight
sysconf_dir = os.path.normpath(root + "/etc/sysconfig")
sysconf_file = "keyboard"
+ vcconf_dir = os.path.normpath(root + "/etc")
+ vcconf_file = "vconsole.conf"
+
+ errors = []
+
try:
if not os.path.isdir(xconf_dir):
os.makedirs(xconf_dir)
except OSError as oserr:
- raise KeyboardConfigError("Cannot create directory xorg.conf.d")
+ errors.append("Cannot create directory xorg.conf.d")
- try:
- with open(os.path.join(xconf_dir, xconf_file), "w") as fobj:
- fobj.write(get_layouts_xorg_conf(keyboard))
+ if keyboard.x_layouts:
+ try:
+ with open(os.path.join(xconf_dir, xconf_file), "w") as fobj:
+ fobj.write(get_layouts_xorg_conf(keyboard))
+ except IOError as ioerr:
+ errors.append("Cannot write X keyboard configuration file")
+
+ if keyboard.vc_keymap:
+ try:
+ with open(os.path.join(sysconf_dir, sysconf_file), "w") as fobj:
+ fobj.write('vconsole.keymap="%s"\n' % keyboard.vc_keymap)
- with open(os.path.join(sysconf_dir, sysconf_file), "w") as fobj:
- fobj.write('vconsole.keymap="%s"\n' % keyboard.keyboard)
+ except IOError as ioerr:
+ errors.append("Cannot write sysconfig keyboard configuration file")
- except IOError as ioerr:
- raise KeyboardConfigError("Cannot write keyboard configuration files")
+ try:
+ with open(os.path.join(vcconf_dir, vcconf_file), "w") as fobj:
+ fobj.write('KEYMAP="%s"\n' % keyboard.vc_keymap)
+ except IOError as ioerr:
+ errors.append("Cannot write vconsole configuration file")
-def activate_console_keymap(keymap):
+ if errors:
+ raise KeyboardConfigError("\n".join(errors))
+
+def _try_to_load_keymap(keymap):
"""
- Try to setup a given keymap as a console keymap. If there is no such
- keymap, try to setup a basic variant (e.g. 'cz' instead of 'cz (qwerty)').
+ Method that tries to load keymap and returns boolean indicating if it was
+ successfull or not. It can be used to test if given string is VConsole
+ keymap or not, but in case it is given valid keymap, IT REALLY LOADS IT!.
- @param keymap: a keymap
@type keymap: string
@raise KeyboardConfigError: if loadkeys command is not available
- @return: False if failed to activate both the given keymap and its basic
- variant, True otherwise
+ @return: True if given string was a valid keymap and thus was loaded,
+ False otherwise
"""
+ # BUG: systemd-localed should be able to tell us if we are trying to
+ # activate invalid keymap. Then we will be able to get rid of this
+ # fuction
+
+ ret = 0
+
try:
- #TODO: replace with calling systemd-localed methods once it can load
- # X layouts
ret = iutil.execWithRedirect("loadkeys", [keymap], stdout="/dev/tty5",
stderr="/dev/tty5")
except OSError as oserr:
msg = "'loadkeys' command not available (%s)" % oserr.strerror
raise KeyboardConfigError(msg)
- if ret != 0:
- log.error("Failed to activate keymap %s" % keymap)
+ return ret == 0
- #failed to activate the given keymap, extract and try
- #the basic keymap -- e.g. 'cz-cp1250' -> 'cz'
- parts = re.split(r'[- _(]', keymap, 1)
- if len(parts) == 0:
- log.error("Failed to extract basic keymap from: %s" % keymap)
- return False
+def activate_keyboard(keyboard):
+ """
+ Try to setup VConsole keymap and X11 layouts as specified in kickstart.
- keymap = parts[0]
+ @param keyboard: ksdata.keyboard object
+ @type keyboard: ksdata.keyboard object
- ret = iutil.execWithRedirect("loadkeys", [keymap], stdout="/dev/tty5",
- stderr="/dev/tty5")
+ """
+
+ localed = LocaledWrapper()
+ c_lay_var = ""
+ c_keymap = ""
- if ret != 0:
- log.error("Failed to activate basic variant %s" % keymap)
+ if keyboard._keyboard and not (keyboard.vc_keymap or keyboard.x_layouts):
+ # we were give only one value in old format of the keyboard command
+ # try to guess if we were given VConsole keymap or X11 layout
+ is_keymap = _try_to_load_keymap(keyboard._keyboard)
+
+ if is_keymap:
+ keyboard.vc_keymap = keyboard._keyboard
else:
- log.error("Activated basic variant %s, instead" % keymap)
+ keyboard.x_layouts.append(keyboard._keyboard)
- return ret == 0
+ if keyboard.vc_keymap:
+ valid_keymap = _try_to_load_keymap(keyboard.vc_keymap)
+ if not valid_keymap:
+ log.error("'%s' is not a valid VConsole keymap, not loading" % \
+ keyboard.vc_keymap)
+ else:
+ # activate VConsole keymap and get converted layout and variant
+ c_lay_var = localed.set_and_convert_keymap(keyboard.vc_keymap)
+
+ if not keyboard.x_layouts and c_lay_var:
+ keyboard.x_layouts.append(c_lay_var)
+
+ if keyboard.x_layouts:
+ c_keymap = localed.set_and_convert_layout(keyboard.x_layouts[0])
+
+ if not keyboard.vc_keymap:
+ keyboard.vc_keymap = c_keymap
+
+ # write out full configuration that will be loaded by X server
+ # (systemd-localed writes configuration with only one layout)
+ write_keyboard_config(keyboard, root="/", convert=False, weight=99)
def item_str(s):
"""Convert a zero-terminated byte array to a proper str"""
diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py
index 156f94d7c..1dd0aebeb 100644
--- a/pyanaconda/kickstart.py
+++ b/pyanaconda/kickstart.py
@@ -1366,8 +1366,7 @@ class ZFCP(commands.zfcp.F14_ZFCP):
class Keyboard(commands.keyboard.F18_Keyboard):
def execute(self, *args):
- if self.layouts_list:
- keyboard.write_layouts_config(self, ROOT_PATH)
+ keyboard.write_keyboard_config(self, ROOT_PATH)
###
### HANDLERS
diff --git a/pyanaconda/ui/gui/spokes/keyboard.py b/pyanaconda/ui/gui/spokes/keyboard.py
index a64a63c4c..3dce1d7b7 100644
--- a/pyanaconda/ui/gui/spokes/keyboard.py
+++ b/pyanaconda/ui/gui/spokes/keyboard.py
@@ -174,9 +174,9 @@ class KeyboardSpoke(NormalSpoke):
def apply(self):
# Clear and repopulate self.data with actual values
- self.data.keyboard.layouts_list = list()
+ self.data.keyboard.x_layouts = list()
for row in self._store:
- self.data.keyboard.layouts_list.append(row[0])
+ self.data.keyboard.x_layouts.append(row[0])
# FIXME: Set the keyboard layout here, too.
@property
@@ -397,8 +397,8 @@ class KeyboardSpoke(NormalSpoke):
self._downButton.set_sensitive(True)
def _add_data_layouts(self):
- if self.data.keyboard.layouts_list:
- for layout in self.data.keyboard.layouts_list:
+ if self.data.keyboard.x_layouts:
+ for layout in self.data.keyboard.x_layouts:
self._addLayout(self._store, layout)
else:
self._addLayout(self._store, "us")
diff --git a/pyanaconda/ui/gui/spokes/welcome.py b/pyanaconda/ui/gui/spokes/welcome.py
index f89c30d56..3fa3a63e2 100644
--- a/pyanaconda/ui/gui/spokes/welcome.py
+++ b/pyanaconda/ui/gui/spokes/welcome.py
@@ -64,7 +64,7 @@ class LanguageMixIn(object):
if lang_timezone:
self.data.timezone.timezone = lang_timezone
- if self.data.keyboard.layouts_list:
+ if self.data.keyboard.x_layouts:
#do not add layouts if there are any specified in the kickstart
return
@@ -80,8 +80,8 @@ class LanguageMixIn(object):
new_layouts.append(language_layout)
for layout in new_layouts:
- if layout not in self.data.keyboard.layouts_list:
- self.data.keyboard.layouts_list.append(layout)
+ if layout not in self.data.keyboard.x_layouts:
+ self.data.keyboard.x_layouts.append(layout)
if flags.can_touch_runtime_system("add runtime X layout"):
self._xklwrapper.add_layout(layout)