Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions cloudinit/distros/raspberry_pi_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,34 @@

class Distro(debian.Distro):
def set_keymap(self, layout: str, model: str, variant: str, options: str):
"""Currently Raspberry Pi OS sys-mods only supports
setting the layout"""
super().set_keymap(layout, model, variant, options)

subp.subp(
[
"/usr/lib/raspberrypi-sys-mods/imager_custom",
"set_keymap",
layout,
]
"/usr/bin/raspi-config",
"nonint",
"update_labwc_keyboard",
],
)
subp.subp(
[
"/usr/bin/raspi-config",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we expect /usr/bin/raspi-config to always be present in RaspberrPi images? If not we may need a gating subp.which("/usr/bin/raspi-config") check.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, it is present on every image and if it isn't than you either don't have rpios or performed serious damage to the core system components.

"nonint",
"update_squeekboard",
"restart",
],
)
self.manage_service("restart", "keyboard-setup")

if subp.which("udevadm"):
subp.subp(
[
"udevadm",
"trigger",
"--subsystem-match=input",
"--action=change",
],
)

def apply_locale(self, locale, out_fn=None, keyname="LANG"):
try:
Expand Down
2 changes: 1 addition & 1 deletion config/cloud.cfg.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ cloud_init_modules:
{% endif %}
- bootcmd
- write_files
{% if variant not in ["netbsd", "openbsd"] %}
{% if variant not in ["netbsd", "openbsd", "raspberry-pi-os"] %}
Comment thread
paulober marked this conversation as resolved.
- growpart
- resizefs
{% endif %}
Expand Down
70 changes: 66 additions & 4 deletions tests/unittests/distros/test_raspberry_pi_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,75 @@


class TestRaspberryPiOS:
@mock.patch("cloudinit.distros.debian.Distro.set_keymap")
@mock.patch(M_PATH + "subp.subp")
def test_set_keymap_calls_imager_custom(self, m_subp):
@mock.patch(M_PATH + "subp.which", return_value=False)
def test_set_keymap_writes_file_and_runs_basics(
self, m_which, m_subp, m_set_keymap
):
cls = fetch("raspberry_pi_os")
distro = cls("raspberry-pi-os", {}, None)
distro.set_keymap("us", "pc105", "basic", "")
m_subp.assert_called_once_with(
["/usr/lib/raspberrypi-sys-mods/imager_custom", "set_keymap", "us"]

args = [
"gb",
"pc105",
"",
"grp:alt_shift_toggle",
]

# Avoid touching real services
with mock.patch.object(cls, "manage_service") as m_manage_service:
distro.set_keymap(*args)

m_manage_service.assert_called_once_with(
"restart", "keyboard-setup"
)

m_set_keymap.assert_called_once_with(*args)

# Two raspi-config calls are always expected
m_subp.assert_any_call(
["/usr/bin/raspi-config", "nonint", "update_labwc_keyboard"],
)
m_subp.assert_any_call(
[
"/usr/bin/raspi-config",
"nonint",
"update_squeekboard",
"restart",
],
)

# No optional tools available, so only the two calls above
assert m_subp.call_count == 2

@mock.patch("cloudinit.distros.debian.Distro.set_keymap")
@mock.patch(M_PATH + "subp.subp")
def test_set_keymap_triggers_udevadm_when_available(
self, m_subp, m_set_keymap
):
cls = fetch("raspberry_pi_os")
distro = cls("raspberry-pi-os", {}, None)

# Only udevadm available
def which_side_effect(name):
return name == "udevadm"

with mock.patch(M_PATH + "subp.which", side_effect=which_side_effect):
with mock.patch.object(cls, "manage_service"):
distro.set_keymap("de", "pc105", "nodeadkeys", "")

m_set_keymap.assert_called_once_with("de", "pc105", "nodeadkeys", "")

# Expect 3 subp calls: two raspi-config + one udevadm trigger
assert m_subp.call_count == 3
m_subp.assert_any_call(
[
"udevadm",
"trigger",
"--subsystem-match=input",
"--action=change",
],
)

@mock.patch(M_PATH + "subp.subp")
Expand Down