mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-02-25 18:55:27 -06:00
hostkeymap: Centralize parsing, don't be so noisy
And add /etc/vconsole.conf parsing to close bug 882183
This commit is contained in:
parent
7c7f3ad0b2
commit
187ce92621
@ -18,10 +18,119 @@
|
||||
#
|
||||
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
_cached_keymap = None
|
||||
_ETC_VCONSOLE = "/etc/vconsole.conf"
|
||||
_KEYBOARD_DIR = "/etc/sysconfig/keyboard"
|
||||
_XORG_CONF = "/etc/X11/xorg.conf"
|
||||
_CONSOLE_SETUP_CONF = "/etc/default/console-setup"
|
||||
_KEYBOARD_DEFAULT = "/etc/default/keyboard"
|
||||
|
||||
|
||||
def _find_xkblayout(f):
|
||||
"""
|
||||
Reads a keyboard layout from a file that defines an XKBLAYOUT
|
||||
variable, e.g. /etc/default/{keyboard,console-setup}.
|
||||
The format of these files is such that they can be 'sourced'
|
||||
in a shell script.
|
||||
|
||||
Used for both /etc/default/keyboard and /etc/default/console-setup.
|
||||
The former is used by Debian 6.0 (Squeeze) and later. The latter is
|
||||
used by older versions of Debian, and Ubuntu.
|
||||
"""
|
||||
kt = None
|
||||
keymap_re = re.compile(r'\s*XKBLAYOUT="(?P<kt>[a-z-]+)"')
|
||||
for line in f:
|
||||
m = keymap_re.match(line)
|
||||
if m:
|
||||
kt = m.group('kt')
|
||||
break
|
||||
return kt
|
||||
|
||||
|
||||
def _xorg_keymap(f):
|
||||
"""
|
||||
Look in /etc/X11/xorg.conf for the host machine's keymap, and attempt to
|
||||
map it to a keymap supported by qemu
|
||||
"""
|
||||
kt = None
|
||||
keymap_re = re.compile(r'\s*Option\s+"XkbLayout"\s+"(?P<kt>[a-z-]+)"')
|
||||
for line in f:
|
||||
m = keymap_re.match(line)
|
||||
if m:
|
||||
kt = m.group('kt')
|
||||
break
|
||||
return kt
|
||||
|
||||
|
||||
def _sysconfig_keyboard(f):
|
||||
kt = None
|
||||
while 1:
|
||||
s = f.readline()
|
||||
if s == "":
|
||||
break
|
||||
if (re.search("KEYMAP", s) is not None or
|
||||
re.search("KEYTABLE", s) is not None or
|
||||
(re.search("KEYBOARD", s) is not None and
|
||||
re.search("KEYBOARDTYPE", s) is None)):
|
||||
if s.count('"'):
|
||||
delim = '"'
|
||||
elif s.count('='):
|
||||
delim = '='
|
||||
else:
|
||||
continue
|
||||
kt = s.split(delim)[1].strip()
|
||||
break
|
||||
return kt
|
||||
|
||||
|
||||
def _default_keymap():
|
||||
"""
|
||||
Look in various config files for the host machine's keymap, and attempt
|
||||
to map it to a keymap supported by qemu
|
||||
"""
|
||||
# Set keymap to same as hosts
|
||||
default = "en-us"
|
||||
keymap = None
|
||||
|
||||
kt = None
|
||||
for path, cb in [
|
||||
(_ETC_VCONSOLE, _sysconfig_keyboard),
|
||||
(_KEYBOARD_DIR, _sysconfig_keyboard),
|
||||
(_XORG_CONF, _xorg_keymap),
|
||||
(_KEYBOARD_DEFAULT, _find_xkblayout),
|
||||
(_CONSOLE_SETUP_CONF, _find_xkblayout)]:
|
||||
if not os.path.exists(path):
|
||||
continue
|
||||
|
||||
try:
|
||||
f = open(path, "r")
|
||||
kt = cb(f)
|
||||
f.close()
|
||||
if kt:
|
||||
logging.debug("Found keymap=%s in %s", kt, path)
|
||||
break
|
||||
logging.debug("Didn't find keymap in '%s'", path)
|
||||
except Exception, e:
|
||||
logging.debug("Error parsing '%s': %s", path, str(e))
|
||||
|
||||
if kt is None:
|
||||
logging.debug("Did not parse any usable keymapping.")
|
||||
return default
|
||||
|
||||
kt = kt.lower()
|
||||
keymap = sanitize_keymap(kt)
|
||||
if not keymap:
|
||||
logging.debug("Didn't match keymap '%s' in keytable!", kt)
|
||||
return default
|
||||
return keymap
|
||||
|
||||
|
||||
##################
|
||||
# Public helpers #
|
||||
##################
|
||||
|
||||
# Host keytable entry : keymap name in qemu/xen
|
||||
# Only use lower case entries: all lookups are .lower()'d
|
||||
@ -61,75 +170,8 @@ keytable = {
|
||||
"tr": "tr",
|
||||
}
|
||||
|
||||
KEYBOARD_DIR = "/etc/sysconfig/keyboard"
|
||||
XORG_CONF = "/etc/X11/xorg.conf"
|
||||
CONSOLE_SETUP_CONF = "/etc/default/console-setup"
|
||||
|
||||
|
||||
def find_xkblayout(path):
|
||||
"""
|
||||
Reads a keyboard layout from a file that defines an XKBLAYOUT
|
||||
variable, e.g. /etc/default/{keyboard,console-setup}.
|
||||
The format of these files is such that they can be 'sourced'
|
||||
in a shell script.
|
||||
"""
|
||||
|
||||
kt = None
|
||||
try:
|
||||
f = open(path, "r")
|
||||
except IOError, e:
|
||||
logging.debug('Could not open "%s": %s ', path, str(e))
|
||||
else:
|
||||
keymap_re = re.compile(r'\s*XKBLAYOUT="(?P<kt>[a-z-]+)"')
|
||||
for line in f:
|
||||
m = keymap_re.match(line)
|
||||
if m:
|
||||
kt = m.group('kt')
|
||||
break
|
||||
else:
|
||||
logging.debug("Didn't find keymap in '%s'!", path)
|
||||
f.close()
|
||||
return kt
|
||||
|
||||
|
||||
def _find_keymap_from_etc_default():
|
||||
"""
|
||||
Look under /etc/default for the host machine's keymap.
|
||||
|
||||
This checks both /etc/default/keyboard and /etc/default/console-setup.
|
||||
The former is used by Debian 6.0 (Squeeze) and later. The latter is
|
||||
used by older versions of Debian, and Ubuntu.
|
||||
"""
|
||||
|
||||
KEYBOARD_DEFAULT = "/etc/default/keyboard"
|
||||
paths = [KEYBOARD_DEFAULT, CONSOLE_SETUP_CONF]
|
||||
for path in paths:
|
||||
kt = find_xkblayout(path)
|
||||
if kt is not None:
|
||||
break
|
||||
return kt
|
||||
|
||||
|
||||
def _xorg_keymap():
|
||||
"""Look in /etc/X11/xorg.conf for the host machine's keymap, and attempt to
|
||||
map it to a keymap supported by qemu"""
|
||||
|
||||
kt = None
|
||||
try:
|
||||
f = open(XORG_CONF, "r")
|
||||
except IOError, e:
|
||||
logging.debug('Could not open "%s": %s ', XORG_CONF, str(e))
|
||||
else:
|
||||
keymap_re = re.compile(r'\s*Option\s+"XkbLayout"\s+"(?P<kt>[a-z-]+)"')
|
||||
for line in f:
|
||||
m = keymap_re.match(line)
|
||||
if m:
|
||||
kt = m.group('kt')
|
||||
break
|
||||
else:
|
||||
logging.debug("Didn't find keymap in '%s'!", XORG_CONF)
|
||||
f.close()
|
||||
return kt
|
||||
_cached_keymap = None
|
||||
|
||||
|
||||
def default_keymap():
|
||||
@ -139,52 +181,6 @@ def default_keymap():
|
||||
return _cached_keymap
|
||||
|
||||
|
||||
def _default_keymap():
|
||||
"""
|
||||
Look in various config files for the host machine's keymap, and attempt
|
||||
to map it to a keymap supported by qemu
|
||||
"""
|
||||
# Set keymap to same as hosts
|
||||
default = "en-us"
|
||||
keymap = None
|
||||
|
||||
kt = None
|
||||
try:
|
||||
f = open(KEYBOARD_DIR, "r")
|
||||
except IOError, e:
|
||||
logging.debug('Could not open "/etc/sysconfig/keyboard" ' + str(e))
|
||||
kt = _xorg_keymap()
|
||||
if not kt:
|
||||
kt = _find_keymap_from_etc_default()
|
||||
else:
|
||||
while 1:
|
||||
s = f.readline()
|
||||
if s == "":
|
||||
break
|
||||
if re.search("KEYTABLE", s) is not None or \
|
||||
(re.search("KEYBOARD", s) is not None and
|
||||
re.search("KEYBOARDTYPE", s) is None):
|
||||
if s.count('"'):
|
||||
delim = '"'
|
||||
elif s.count('='):
|
||||
delim = '='
|
||||
else:
|
||||
continue
|
||||
kt = s.split(delim)[1].strip()
|
||||
f.close()
|
||||
|
||||
if kt is None:
|
||||
logging.debug("Did not parse any usable keymapping.")
|
||||
return default
|
||||
|
||||
kt = kt.lower()
|
||||
keymap = sanitize_keymap(kt)
|
||||
if not keymap:
|
||||
logging.debug("Didn't match keymap '%s' in keytable!", kt)
|
||||
return default
|
||||
return keymap
|
||||
|
||||
|
||||
def sanitize_keymap(kt):
|
||||
"""
|
||||
Make sure the passed keymap roughly matches something in keytable
|
||||
|
Loading…
Reference in New Issue
Block a user