feat(raspberry-pi-os): Add Raspberry Pi OS support#5827
Conversation
c475d72 to
683ffc8
Compare
|
Is there an option if a setting for |
|
Some additional context: This PR (and the linked GitHub PRs from other repos) are part of a wider desire to move to using cloud-init as the customisation scheme for Raspberry Pi OS, with associated infrastructure in Raspberry Pi Imager to ensure we maintain feature parity (if not an increased feature set) with the current 'firstrun' style customisation scheme. Going forward, assuming this PR is merged and our migration proceeds along happily enough, my plan is to recommend to each distro vendor supplying OS images to the Raspberry Pi Imager that they also adopt cloud-init as their customisation scheme. This may result in additional PRs adding distro features to cloud-init in a similar manner to this PR - but should absolutely improve the experience for end users across the board. |
| renderers: ['network-manager', 'networkd'] | ||
| {% elif variant == "raspberry-pi-os" %} | ||
| network: | ||
| dhcp_client_priority: [dhclient] |
There was a problem hiding this comment.
Upstream dhclient is abandoned. Is raspberry-pi-os's plan to support it forever?
There was a problem hiding this comment.
This was included as an error, and dhclient is not actually used by Raspberry Pi OS - instead, we use network-manager's built in DHCP client. I believe this has been corrected in the latest version of this PR.
| {% elif variant == "raspberry-pi-os" %} | ||
| network: | ||
| dhcp_client_priority: [dhclient] | ||
| renderers: ['netplan', 'network-manager', 'networkd', 'eni'] |
There was a problem hiding this comment.
Which of these does raspberry-pi-os support and plan to use?
There was a problem hiding this comment.
Which of these does raspberry-pi-os support and plan to use?
In the updated PR, this has been reduced to netplan & network-manager, both of which we want to offer.
fcd247a to
9bb2b18
Compare
|
There are some merge conflicts now. |
9bb2b18 to
7cdcb3c
Compare
Resolved. |
7cdcb3c to
cdbb40b
Compare
|
Hello! Thank you for this proposed change to cloud-init. This pull request is now marked as stale as it has not seen any activity in 14 days. If no activity occurs within the next 7 days, this pull request will automatically close. If you are waiting for code review and you are seeing this message, apologies! Please reply, tagging TheRealFalcon, and he will ensure that someone takes a look soon. (If the pull request is closed and you would like to continue working on it, please do tag TheRealFalcon to reopen it.) |
|
cdbb40b to
0769b9c
Compare
0769b9c to
1da5ee6
Compare
TheRealFalcon
left a comment
There was a problem hiding this comment.
Thanks for this contribution. I left some first pass inline comments.
In general, I would like to consolidate the config and modules as much as possible. When it comes to the config, let's put anything raspberry-pi specific under a rpi or similar top-level key. E.g.,
rpi:
enable_rpi_connect: true
interfaces:
...
piwiz:
...Do all the modules need to run at the boot stages they've been added? If not, can any of the modules be combined? E.g., cc_rpi_connect.py runs a single command. Can that command not be incorporated into the cc_rpi_userdata.py module?
| @@ -0,0 +1,129 @@ | |||
| # Copyright (C) 2024, Raspberry Pi Ltd. | |||
There was a problem hiding this comment.
I don't understand why this file is necessary. Cloud-init writes 50-cloud-init.yaml, but as far as I know, all network-manager -> netplan files start with '90-'. Doesn't this mean any changes made in network-manager will automatically override the default netplan config? Are you aware of cases where this doesn't work?
There was a problem hiding this comment.
If I remember correctly, the problem was if you edit the netplan generated NetworkManager (created by cloud-init) config in a desktop GUI the updated config will be written back to netplan with a generated UUID and not touching the original file. This ment changes made by a user are lost after a reboot because the cloud-init netplan config will always be preferred and overrides the NM generated one. By triggering the save operation for every cloud-init generated config after first boot and then removing the original file this issue can be resolved.
There was a problem hiding this comment.
I'm curious if things are different on raspberry-pi-os, but on my desktop at least, I see the network manager files get written with a '90-' first, e.g., 90-NM-141e654c-21b3-4e52-9505-e3c94be335c0.yaml so anything in that file would override what is in 50-cloud-init.yaml. If it doesn't work this way, I would think this would be a netplan bug, or the patch was applied incorrectly. Is this something you can check to see if you get different results?
There was a problem hiding this comment.
Ok I just checked without the netplan_nm_patch, and yes the updated config is written to 90-NM... and also visible in the UI. But after a reboot the 50-cloud-init will take over => changes are not effective.
There was a problem hiding this comment.
But 50-cloud-init.yaml shouldn't "take over" unless there's something wrong with your netplan implementation. I'm assuming 50-cloud-init.yaml has some level of base configuration and then the 90-* files are being layered on top? What does netplan get show when you're in this state? How is it different from what you would expect with how netplan's layering works?
I still don't think that a module is the best way to go about this. If you don't want cloud-init to write networking at all, then it'd be best to update your image accordingly. If you need different network-manager behavior, perhaps choose the network-manager renderer if netplan's layering isn't working correctly for you.
As a last resort, raspberry-pi-os.py could override _write_network_state() directly along with a long explaining why it's doing what it's doing.
There was a problem hiding this comment.
Just found out that my problem is related to a duplicate access-point issue that has been fixed with a PR for 0.107 the problem is 0.107 of libnetplan0 already requires libc6 >= 2.38. But everything except wifi works also without the netplan_nm_patch.
| {% if variant in ["ubuntu", "unknown", "debian"] %} | ||
| {% if variant in ["ubuntu", "unknown", "debian", "raspberry-pi-os"] %} | ||
| After=networking.service | ||
| {% if variant == "raspberry-pi-os" %} |
There was a problem hiding this comment.
Why is this section needed? After=NetworkManager... is already a few line below.
There was a problem hiding this comment.
I will have to dig into this again. But I think it was need because I've had huge problems getting the cloud-init network stage run after network manager is available but not to late so it wont get skipped.
| Before=sshd.service | ||
| Before=systemd-user-sessions.service | ||
| {% if variant in ["ubuntu", "unknown", "debian"] %} | ||
| {% if variant in ["ubuntu", "unknown", "debian", "raspberry-pi-os"] %} |
There was a problem hiding this comment.
I don't think raspberry-pi-os is needed in this section. Based on the line below you don't want Before=sysinit.target and the two after that are part of DefaultDependencies. Can you add raspberry-pi-os to the line about default dependencies?
There was a problem hiding this comment.
Thanks for the advice. I'll test it.
| LOG.error("Failed to configure serial console: %s", e) | ||
|
|
||
|
|
||
| def enable_ssh(cfg: Config, enable: bool) -> None: |
There was a problem hiding this comment.
Do we need the separate tool to enable SSH? Cloud-init has built in SSH support. Is there a reason we can't use that? If so, is there a reason that module can't be expanded to do what this tool is doing?
| {% endif %} | ||
| - locale | ||
| {% endif %} | ||
| {% if variant == "raspberry-pi-os" %} |
There was a problem hiding this comment.
rpi_interfaces was also defined in the network stage. Does this module need to run twice? Why?
There was a problem hiding this comment.
You're right, it doesn't. I'll remove the duplicate.
| "lxd", | ||
| "mcollective", | ||
| "mounts", | ||
| "netplan-nm-patch", |
There was a problem hiding this comment.
We only need the _ version of all the keys. The - versions exist in other modules for backwards compatibility only.
| @@ -0,0 +1,228 @@ | |||
| # Copyright (C) 2024, Raspberry Pi Ltd. | |||
There was a problem hiding this comment.
Much of this module is a bit strange to me. We're using a one-shot first-boot system configuration service (cloud-init) to configure how a one-shot first-boot system configuration service (piwiz) should work. Why would people want to use both in tandem? Does piwiz do anything that cloud-init currently can't? If not, then why not just use cloud-init for everything? If no user data is passed, I can see still starting piwiz so it can be used interactively, but if a user provides cloud-init user data, I see no reason to then also use a separate configuration service.
In particular, I think allowing username and password configuration multiple ways is very confusing. Cloud-init will create a default user automatically that can be overridden to provide a different user and password. Why would we then also expose additional cloud-init user data to allow piwiz to set the same thing? Let's have one configuration option for applying these things.
There was a problem hiding this comment.
Thank you for raising these points. The userconf-pi scripts handle more than just the setup wizard. They also rename the default user shipped with Raspbian OS and manage other configuration tasks that are specific to the OS. Overwriting the user setup logic directly in the distribution's Python script seemed more complex.
The module runes even if not configuration is supplied to ensure the scripts are launched correctly, especially since the systemd hook is disabled on builds with cloud-init, allowing for this behavior to be modified.
That said, your suggestion to streamline this makes sense. I agree that having multiple methods to configure the username and password can be confusing. While piwiz provides interactive setup capabilities, cloud-init is designed for automated configuration. Ideally, there should be a single clear configuration pathway.
If I find the time, I’ll look into the feasibility of removing the userconf module or aligning it more closely with cloud-init. This will likely require some adjustments on the OS side, but it’s worth exploring. I’ll revisit this and update you once I have a concrete solution.
|
Hello! Thank you for this proposed change to cloud-init. This pull request is now marked as stale as it has not seen any activity in 14 days. If no activity occurs within the next 7 days, this pull request will automatically close. If you are waiting for code review and you are seeing this message, apologies! Please reply, tagging TheRealFalcon, and he will ensure that someone takes a look soon. (If the pull request is closed and you would like to continue working on it, please do tag TheRealFalcon to reopen it.) |
|
Hi @TheRealFalcon, do you have any recommendation on how I can build cloud-init deb pkgs for testing. My current build script always results in (and I had to modify a requirements.txt as it always tries to locate python3-pyserial instead of python3-serial which should normally be auto-renamed by the config in the debs.json if I understand correctly): dpkg-buildpackage: info: host architecture arm64
debian/rules clean
Can't exec "debian/rules": Permission denied at /usr/bin/dpkg-buildpackage line 834.
dpkg-buildpackage: error: debian/rules clean subprocess failed with unknown status code -1
Stderr: debuild: fatal error at line 1182:
dpkg-buildpackage -us -uc -ui failedmy build.sh: #!/bin/bash
cd cloud-init
VARIANT=raspberry-pi-os
make deb VARIANT=raspberry-pi-os
dpkg-deb -R cloud-init_all.deb package_dir
make render-template VARIANT=raspberry-pi-os | tail -n +2 > package_dir/etc/cloud/cloud.cfg
SYSTEM_DIR="./package_dir/lib/systemd/system"
GENERATORS_DIR="./package_dir/lib/systemd/system-generators"
# Iterate over all .tmpl files in the ./systemd directory
for tmpl_file in ./systemd/*.tmpl; do
# Get the base name of the file without the directory and extension
base_name=$(basename "$tmpl_file" .tmpl)
# Check if the file is the generator file
if [ "$base_name" = "cloud-init-generator" ]; then
# Render the template and copy it to the system-generators directory
output_file="$GENERATORS_DIR/$base_name"
./tools/render-template --variant="${VARIANT}" "$tmpl_file" > "$output_file"
echo "Rendered generator template $tmpl_file to $output_file"
else
# Render the template and copy it to the system directory
output_file="$SYSTEM_DIR/$base_name"
./tools/render-template --variant="${VARIANT}" "$tmpl_file" > "$output_file"
echo "Rendered service template $tmpl_file to $output_file"
fi
done
make clean_packaging
dpkg-deb -b package_dir cloud-init-custom.deb
rm -rf package_dir
cp cloud-init-custom.deb ~/cloud-init/pi-gen/stage2/04-cloud-init/files
cd ..Platform: Debian 12 arm64 Many thanks, |
|
@paulober , for throwaway test debs, we have a script for that. Usage for me usually looks something like Would that work for you? |
Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>
Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>
Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>
Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>
Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>
Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>
Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>
Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>
Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>
Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>
Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>
Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>
Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>
Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>
Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>
|
@TheRealFalcon I now re-authored all commits. Let me know if you also need me to reword the commit messages. |
@ghollingworth , did it involve docusign? If not, it wasn't using the new process for organizations. If that happened, let me know and I can make sure the email domain is accepted. |
|
@ghollingworth, thanks for the confirmation. I'll make sure things get updated internally. @paulober, everything else looks good here. Thank you for all of the work and patience on this PR. Once I get the CLA worked out, I'll merge this. |
|
Hello! Thank you for this proposed change to cloud-init. This pull request is now marked as stale as it has not seen any activity in 14 days. If no activity occurs within the next 7 days, this pull request will automatically close. If you are waiting for code review and you are seeing this message, apologies! Please reply, tagging TheRealFalcon, and he will ensure that someone takes a look soon. (If the pull request is closed and you would like to continue working on it, please do tag TheRealFalcon to reopen it.) |
TheRealFalcon
left a comment
There was a problem hiding this comment.
@paulober , thanks for your patience on this one! We are finally good to merge!
This commit adds support for the Raspberry Pi OS distro. It includes a distro integration and detection including an additional configuration module (cc_raspberry_pi) for platform specific configuration. Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>
This commit adds support for the Raspberry Pi OS distro. It includes a distro integration and detection including an additional configuration module (cc_raspberry_pi) for platform specific configuration. Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>
This commit adds support for the Raspberry Pi OS distro. It includes a distro integration and detection including an additional configuration module (cc_raspberry_pi) for platform specific configuration. Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>
This commit adds support for the Raspberry Pi OS distro. It includes a distro integration and detection including an additional configuration module (cc_raspberry_pi) for platform specific configuration. Signed-off-by: paulober <44974737+paulober@users.noreply.github.com>

This commit adds support for the Raspberry Pi OS debian based distribution. It includes a distro definition, 3 modules and integration into other systems like config generation and docs.
tools/.github-cla-signerstests/unittests/cloudinit/example.pyshould be tested bytests/unittests/test_example.pytox -e py3tox -e doc.Proposed Commit Message
Additional Context
@tdewey-rpi, @XECDesign, @ghollingworth, @will-v-pi
Merge type