2019-12-04 01:48:41 -05:00
|
|
|
import configparser
|
|
|
|
import io
|
2019-12-30 05:34:34 -05:00
|
|
|
import logging
|
2019-12-04 01:48:41 -05:00
|
|
|
import os
|
|
|
|
import pathlib
|
|
|
|
import re
|
|
|
|
|
|
|
|
|
2019-12-30 05:34:34 -05:00
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
2019-12-04 01:48:41 -05:00
|
|
|
_font_re = re.compile(r'(\.(psfu?|fnt))?(\.gz)?$', re.IGNORECASE)
|
|
|
|
_kbd_re = re.compile(r'(\.map)?(\.gz)?$')
|
|
|
|
|
|
|
|
|
2019-12-30 05:34:34 -05:00
|
|
|
class Console(object):
|
|
|
|
def __init__(self, chroot_base, console_xml):
|
|
|
|
self.xml = console_xml
|
|
|
|
self.chroot_base = chroot_base
|
2019-12-30 12:59:52 -05:00
|
|
|
self._cfg = configparser.ConfigParser(allow_no_value = True, interpolation = None)
|
|
|
|
self._cfg.optionxform = str
|
2019-12-30 05:34:34 -05:00
|
|
|
self.keyboard = Keyboard(self.xml.find('keyboard'))
|
|
|
|
self.font = Font(self.xml.find('text'))
|
|
|
|
self._cfg['BASE'] = {}
|
|
|
|
for i in (self.keyboard, self.font):
|
|
|
|
self._cfg['BASE'].update(i.settings)
|
|
|
|
|
|
|
|
def writeConf(self):
|
|
|
|
for x in (self.font, self.keyboard):
|
|
|
|
x.verify()
|
|
|
|
cfg = os.path.join(self.chroot_base, 'etc', 'vconsole.conf')
|
|
|
|
# We have to strip out the section from the ini.
|
|
|
|
cfgbuf = io.StringIO()
|
|
|
|
self._cfg.write(cfgbuf, space_around_delimiters = False)
|
|
|
|
cfgbuf.seek(0, 0)
|
|
|
|
with open(cfg, 'w') as fh:
|
|
|
|
for line in cfgbuf.readlines():
|
|
|
|
if line.startswith('[BASE]') or line.strip() == '':
|
|
|
|
continue
|
|
|
|
fh.write(line)
|
|
|
|
os.chmod(cfg, 0o0644)
|
|
|
|
os.chown(cfg, 0, 0)
|
|
|
|
_logger.info('Wrote: {0}'.format(cfg))
|
|
|
|
return(None)
|
|
|
|
|
|
|
|
|
2019-12-04 01:48:41 -05:00
|
|
|
class Font(object):
|
|
|
|
def __init__(self, font_xml):
|
|
|
|
self.xml = font_xml
|
|
|
|
self.settings = {}
|
|
|
|
if self.xml:
|
|
|
|
chk = {'FONT': self.xml.find('font'),
|
|
|
|
'FONT_MAP': self.xml.find('map'),
|
|
|
|
'FONT_UNIMAP': self.xml.find('unicodeMap')}
|
|
|
|
for setting, xml in chk.items():
|
|
|
|
if xml:
|
|
|
|
self.settings[setting] = xml.text.strip()
|
2019-12-30 05:34:34 -05:00
|
|
|
_logger.debug('Rendered settings: {0}'.format(self.settings))
|
2019-12-04 01:48:41 -05:00
|
|
|
|
|
|
|
def verify(self, chroot_base = '/'):
|
|
|
|
if 'FONT' not in self.settings.keys():
|
2019-12-30 05:34:34 -05:00
|
|
|
_logger.warning('Attempted to verify settings with no chosen font.')
|
2019-12-04 01:48:41 -05:00
|
|
|
return(None)
|
|
|
|
fontdir = pathlib.Path(chroot_base).joinpath('usr', 'share', 'kbd', 'consolefonts')
|
|
|
|
fontnames = [_font_re.sub('', p.stem) for p in fontdir.iterdir() if not p.stem.startswith(('README.',
|
|
|
|
'partialfonts',
|
|
|
|
'ERRORS'))]
|
2019-12-30 05:34:34 -05:00
|
|
|
_logger.debug('Rendered list of supported console fonts on target system: {0}'.format(','.join(fontnames)))
|
2019-12-04 01:48:41 -05:00
|
|
|
if self.settings['FONT'] not in fontnames:
|
2019-12-30 05:34:34 -05:00
|
|
|
_logger.error('Console font {0} not installed on target system.'.format(self.settings['FONT']))
|
|
|
|
raise ValueError('Specified console font not available on target system')
|
2019-12-04 01:48:41 -05:00
|
|
|
return(True)
|
|
|
|
|
|
|
|
|
|
|
|
class Keyboard(object):
|
2019-12-10 06:59:47 -05:00
|
|
|
def __init__(self, chroot_base, keyboard_xml):
|
2019-12-04 01:48:41 -05:00
|
|
|
self.xml = keyboard_xml
|
2019-12-10 06:59:47 -05:00
|
|
|
self.chroot_base = chroot_base
|
2019-12-04 01:48:41 -05:00
|
|
|
self.settings = {}
|
|
|
|
if self.xml:
|
|
|
|
chk = {'KEYMAP': self.xml.find('map'),
|
|
|
|
'KEYMAP_TOGGLE': self.xml.find('toggle')}
|
|
|
|
for setting, xml in chk.items():
|
|
|
|
if xml:
|
|
|
|
self.settings[setting] = xml.text.strip()
|
2019-12-30 05:34:34 -05:00
|
|
|
_logger.debug('Rendered settings: {0}'.format(self.settings))
|
2019-12-04 01:48:41 -05:00
|
|
|
|
2019-12-10 06:59:47 -05:00
|
|
|
def verify(self):
|
2019-12-04 01:48:41 -05:00
|
|
|
kbdnames = []
|
|
|
|
for i in ('KEYMAP', 'KEYMAP_TOGGLE'):
|
|
|
|
if i in self.settings.keys():
|
|
|
|
kbdnames.append(self.settings[i])
|
|
|
|
if not kbdnames:
|
2019-12-30 05:34:34 -05:00
|
|
|
_logger.warning('Attempted to verify settings with no chosen keyboard map(s).')
|
2019-12-04 01:48:41 -05:00
|
|
|
return(None)
|
2019-12-10 06:59:47 -05:00
|
|
|
keymapdir = os.path.join(self.chroot_base, 'usr', 'share', 'kbd', 'keymaps')
|
2019-12-04 01:48:41 -05:00
|
|
|
kbdmaps = []
|
|
|
|
for root, dirs, files in os.walk(keymapdir, topdown = True):
|
|
|
|
if root.endswith('/include'):
|
|
|
|
dirs[:] = []
|
|
|
|
files[:] = []
|
|
|
|
continue
|
|
|
|
for f in files:
|
|
|
|
if f.endswith('.inc'):
|
|
|
|
continue
|
|
|
|
kbdmaps.append(_kbd_re.sub('', f))
|
2019-12-30 05:34:34 -05:00
|
|
|
_logger.debug('Rendered list of supported keyboard maps on target system: {0}'.format(','.join(kbdmaps)))
|
2019-12-04 01:48:41 -05:00
|
|
|
for k in kbdnames:
|
|
|
|
if k not in kbdmaps:
|
2019-12-30 05:34:34 -05:00
|
|
|
_logger.error('Keyboard map {0} not installed on target system.'.format(k))
|
|
|
|
raise ValueError('Specified keyboard map not available on target system')
|
2019-12-04 01:48:41 -05:00
|
|
|
return(True)
|