bluez: new sysext shipping the BlueZ Bluetooth userspace - #253
Open
ananthb wants to merge 2 commits into
Open
Conversation
Adds a bluez extension providing bluetoothd plus bluetoothctl, btmon, btmgmt and btattach, so Bluetooth can be used on Flatcar without baking BlueZ into the OS image. BlueZ has no upstream static or portable release and links glib, dbus and readline, so the binaries are bundled with their library closure (glibc and the dynamic loader included) from a Debian container and handed to tools/flix.sh, which patchelf's them onto a private loader/rpath. This is the same approach as qemu.sysext and tilde.sysext. Debian packages BlueZ, so the version parameter selects the suite (stable/testing) shipping it. The extension is userspace only. Bluetooth kernel modules must match the running kernel exactly, so they belong in the image; flatcar/scripts#4197 enables them. bluetooth.service is guarded by ConditionPathIsDirectory on /sys/class/bluetooth, so on an image without those modules the unit is skipped rather than failed, and the Upholds= drop-in does not retry it in a loop. The unit reloads D-Bus configuration before starting bluetoothd: the extension drops a new policy file into /usr/share/dbus-1/system.d, which a running dbus-daemon has not read yet, and without the reload bluetoothd cannot take the org.bluez name until the next reboot. Built and checked for both architectures against Debian stable (BlueZ 5.82): the bundled bluetoothd, bluetoothctl and btmon all run and report their version on an Alpine (musl, non-Debian) host, confirming the closure is self-contained. Signed-off-by: Ananth Bhaskararaman <antsub@gmail.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new bluez system extension to ship the BlueZ Bluetooth userspace (daemon + CLI tools) on Flatcar via the sysext-bakery, along with the needed systemd integration and documentation/version metadata.
Changes:
- Introduces
bluez.sysext/create.shto build BlueZ from Debian (stable/testing) and bundle the full shared-library closure. - Adds system integration files (systemd unit + start-on-merge drop-in, tmpfiles entry) so
bluetoothdcan run and persist state. - Registers the extension in version metadata and documentation, including a dedicated
docs/bluez.mdpage.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| release_build_versions.txt | Registers bluez versions (5.82, latest) for the bakery build matrix. |
| docs/index.md | Adds bluez to the published extensions index. |
| docs/bluez.md | New user documentation and Butane provisioning snippet for the BlueZ sysext. |
| bluez.sysext/test.sh | Adds the extension test entry point (currently empty). |
| bluez.sysext/files/usr/lib/tmpfiles.d/10-bluez.conf | Creates /var/lib/bluetooth for adapter state and pairing keys. |
| bluez.sysext/files/usr/lib/systemd/system/multi-user.target.d/10-bluez.conf | Ensures bluetooth.service is upheld by multi-user.target (start-on-merge behavior). |
| bluez.sysext/files/usr/lib/systemd/system/bluetooth.service | Defines the bluetoothd systemd unit (D-Bus service, guarded by sysfs presence). |
| bluez.sysext/create.sh | Implements the Debian-based build, suite/version selection, and closure bundling via tools/flix.sh. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Address review feedback: - bluetooth.service used WantedBy=bluetooth.target, following upstream BlueZ. systemd does ship that target, but nothing pulls it in by default, so 'systemctl enable bluetooth.service' would leave the service unstarted. Every other service unit in this repo uses multi-user.target; match that. - The docs pointed the sysupdate config at .../extensions/bluez/bluez.conf. That nested form does resolve (chrony and bird use it), but the flat .../extensions/<name>.conf form is what the other 28 docs use. Signed-off-by: Ananth Bhaskararaman <antsub@gmail.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 8 changed files in this pull request and generated no new comments.
Suppressed comments (1)
bluez.sysext/files/usr/lib/systemd/system/bluetooth.service:21
LimitNPROC=1is very likely too restrictive forbluetoothd(threads count toward RLIMIT_NPROC on Linux), and it also deviates from the repo’s established convention of setting this toinfinityfor long-running daemons (e.g.docker.sysext/files/usr/lib/systemd/system/docker.service:15,containerd.sysext/.../containerd.service:11). This could cause startup/runtime failures under GLib/D-Bus as soon as an additional thread/task is created.
LimitNPROC=1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a
bluezsysext shipping the BlueZ Bluetooth userspace:bluetoothdplusbluetoothctl,btmon,btmgmt,btattachand the legacy tools that are still packaged.This is the userspace half of adding Bluetooth support to Flatcar. The kernel half is flatcar/scripts#4197, which enables the Bluetooth modules in the image.
How it's built
BlueZ has no upstream static or portable release and links glib, dbus and readline, so the binaries are bundled with their full library closure (glibc and the dynamic loader included) from a Debian container and handed to
tools/flix.sh, which patchelf's them onto a private loader/rpath. Same approach asqemu.sysextandtilde.sysext.The Debian layout is probed rather than hardcoded:
bluetoothdmoved from/usr/libto/usr/libexecacross releases, and the deprecated tools (hciconfig,hcitool, …) are absent from newer ones.Behaviour on merge
bluetooth.serviceis upheld bymulti-user.targetand runsbluetoothdas a D-Bus service underorg.bluez.The unit is guarded by
ConditionPathIsDirectory=/sys/class/bluetooth. On an image without the Bluetooth modules the unit is skipped rather than failed. On an image that has them, the controller's driver autoloads on detection, the directory appears, and the daemon starts./var/lib/bluetooth(adapter settings and pairing keys) is created by a shipped tmpfiles snippet.Testing
Built for both architectures against Debian stable (BlueZ 5.82).
For each, I extracted the image and ran the bundled binaries on an Alpine (musl, non-Debian) host with only
/usr/local/bluezbind-mounted —bluetoothd,bluetoothctlandbtmonall start and report5.82, which confirms the library closure is genuinely self-contained and not falling back to host libraries.I also checked that the image contains no
/usr/sbin(per the warning in_skel.sysext/create.sh) and that the D-Bus policy, units and tmpfiles snippet land where they should.