summaryrefslogtreecommitdiff
path: root/cloudinit/config/cc_keyboard.py
blob: 17eb9a548eecd11519ca94c59267915d16b4fc7a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# Copyright (c) 2022 Floris Bos
#
# Author: Floris Bos <bos@je-eigen-domein.nl>
#
# 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