mirror of
https://github.com/virt-manager/virt-manager.git
synced 2024-12-23 17:34:21 +03:00
f107e39989
Init a shared log instance in virtinst/logger.py, and use that throughout the code base, so we aren't calling directly into 'logging'. This helps protect our logging output from being cluttered with other library output, as happens with some 'requests' usage
201 lines
4.9 KiB
Python
201 lines
4.9 KiB
Python
#
|
|
# Copyright 2006-2013 Red Hat, Inc.
|
|
#
|
|
# This work is licensed under the GNU GPLv2 or later.
|
|
# See the COPYING file in the top-level directory.
|
|
#
|
|
|
|
import os
|
|
import re
|
|
|
|
from .logger import log
|
|
|
|
|
|
_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
|
|
s = s.strip()
|
|
if s.startswith("#"):
|
|
continue
|
|
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 '"' in s:
|
|
delim = '"'
|
|
elif '=' in s:
|
|
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
|
|
|
|
if "VIRTINST_TEST_SUITE" in os.environ:
|
|
return default
|
|
|
|
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:
|
|
log.debug("Found keymap=%s in %s", kt, path)
|
|
break
|
|
log.debug("Didn't find keymap in '%s'", path)
|
|
except Exception as e:
|
|
log.debug("Error parsing '%s': %s", path, str(e))
|
|
|
|
if kt is None:
|
|
log.debug("Did not parse any usable keymapping.")
|
|
return default
|
|
|
|
kt = kt.lower()
|
|
keymap = sanitize_keymap(kt)
|
|
if not keymap:
|
|
log.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
|
|
keytable = {
|
|
"ar": "ar",
|
|
"da": "da", "dk": "da",
|
|
"de": "de",
|
|
"de-ch": "de-ch",
|
|
"en-gb": "en-gb", "gb": "en-gb", "uk": "en-gb",
|
|
"en-us": "en-us", "us": "en-us",
|
|
"es": "es",
|
|
"et": "et",
|
|
"fi": "fi", "se_fi": "fi",
|
|
"fo": "fo",
|
|
"fr": "fr",
|
|
"fr-be": "fr-be", "be": "fr-be",
|
|
"fr-ca": "fr-ca", "ca": "fr-ca",
|
|
"fr-ch": "fr-ch", "fr_ch": "fr-ch",
|
|
"hr": "hr",
|
|
"hu": "hu",
|
|
"is": "is",
|
|
"it": "it",
|
|
"ja": "ja", "jp106": "ja", "jp": "ja",
|
|
"lt": "lt",
|
|
"lv": "lv",
|
|
"mk": "mk",
|
|
"nl": "nl",
|
|
"nl-be": "nl-be",
|
|
"no": "no",
|
|
"pl": "pl",
|
|
"pt": "pt",
|
|
"pt-br": "pt-br", "br": "pt-br", "br-abnt2": "pt-br",
|
|
"ru": "ru",
|
|
"sl": "sl",
|
|
"sv": "sv",
|
|
"th": "th",
|
|
"tr": "tr",
|
|
}
|
|
|
|
|
|
_cached_keymap = None
|
|
|
|
|
|
def default_keymap():
|
|
global _cached_keymap
|
|
if _cached_keymap is None:
|
|
_cached_keymap = _default_keymap()
|
|
return _cached_keymap
|
|
|
|
|
|
def sanitize_keymap(kt):
|
|
"""
|
|
Make sure the passed keymap roughly matches something in keytable
|
|
"""
|
|
if kt.lower() in keytable:
|
|
return keytable[kt]
|
|
|
|
# Try a more intelligent lookup: strip out all '-' and '_', sort
|
|
# the keytable keys putting the longest first, then compare
|
|
# by string prefix
|
|
clean_kt = kt.replace("-", "").replace("_", "")
|
|
sorted_keys = sorted(list(keytable.keys()), key=len)
|
|
|
|
for key in sorted_keys:
|
|
origkey = key
|
|
key = key.replace("-", "").replace("_", "")
|
|
|
|
if clean_kt.startswith(key):
|
|
return keytable[origkey]
|
|
|
|
return None
|