From 5147e8d4764e368ab8ccea7433b02e4ff9d6c901 Mon Sep 17 00:00:00 2001 From: maxnet Date: Wed, 12 Jan 2022 15:37:32 +0100 Subject: Add new config module to set keyboard layout (#1176) Adds a new module to allow setting keyboard layout, for use-cases in which cloud-init is used to configure OS images meant for physical computers instead of the cloud. This initial release only implements support for Linux distributions that allow layout to be set through systemd's localectl. LP: #1951593 --- cloudinit/config/cc_keyboard.py | 125 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 cloudinit/config/cc_keyboard.py (limited to 'cloudinit/config') diff --git a/cloudinit/config/cc_keyboard.py b/cloudinit/config/cc_keyboard.py new file mode 100644 index 00000000..17eb9a54 --- /dev/null +++ b/cloudinit/config/cc_keyboard.py @@ -0,0 +1,125 @@ +# Copyright (c) 2022 Floris Bos +# +# Author: Floris Bos +# +# This file is part of cloud-init. See LICENSE file for license information. + +"""keyboard: set keyboard layout""" + +from textwrap import dedent + +from cloudinit import distros +from cloudinit import log as logging +from cloudinit.config.schema import get_meta_doc, validate_cloudconfig_schema +from cloudinit.settings import PER_INSTANCE + +frequency = PER_INSTANCE + +# FIXME: setting keyboard layout should be supported by all OSes. +# But currently only implemented for Linux distributions that use systemd. +osfamilies = ["arch", "debian", "redhat", "suse"] +distros = distros.Distro.expand_osfamily(osfamilies) + +DEFAULT_KEYBOARD_MODEL = "pc105" + +meta = { + "id": "cc_keyboard", + "name": "Keyboard", + "title": "Set keyboard layout", + "description": dedent( + """\ + Handle keyboard configuration. + """ + ), + "distros": distros, + "examples": [ + dedent( + """\ + # Set keyboard layout to "us" + keyboard: + layout: us + """ + ), + dedent( + """\ + # Set specific keyboard layout, model, variant, options + keyboard: + layout: de + model: pc105 + variant: nodeadkeys + options: compose:rwin + """ + ), + ], + "frequency": frequency, +} + + +schema = { + "type": "object", + "properties": { + "keyboard": { + "type": "object", + "properties": { + "layout": { + "type": "string", + "description": dedent( + """\ + Required. Keyboard layout. Corresponds to XKBLAYOUT. + """ + ), + }, + "model": { + "type": "string", + "default": DEFAULT_KEYBOARD_MODEL, + "description": dedent( + """\ + Optional. Keyboard model. Corresponds to XKBMODEL. + """ + ), + }, + "variant": { + "type": "string", + "description": dedent( + """\ + Optional. Keyboard variant. Corresponds to XKBVARIANT. + """ + ), + }, + "options": { + "type": "string", + "description": dedent( + """\ + Optional. Keyboard options. Corresponds to XKBOPTIONS. + """ + ), + }, + }, + "required": ["layout"], + "additionalProperties": False, + } + }, +} + +__doc__ = get_meta_doc(meta, schema) + +LOG = logging.getLogger(__name__) + + +def handle(name, cfg, cloud, log, args): + if "keyboard" not in cfg: + LOG.debug( + "Skipping module named %s, no 'keyboard' section found", name + ) + return + validate_cloudconfig_schema(cfg, schema) + kb_cfg = cfg["keyboard"] + layout = kb_cfg["layout"] + model = kb_cfg.get("model", DEFAULT_KEYBOARD_MODEL) + variant = kb_cfg.get("variant", "") + options = kb_cfg.get("options", "") + LOG.debug("Setting keyboard layout to '%s'", layout) + cloud.distro.set_keymap(layout, model, variant, options) + + +# vi: ts=4 expandtab -- cgit v1.2.3