v1.16.11: selinux is an unconditional dependency, breaking source builds on distros that don't package libselinux
- Dominant language
- Rust
- Stars
- 2.3k
- Forks
- 230
- Avg merge
- 3d 12h
- Merged PRs (30d)
- 38
Description
**Note: Used a bit of AI to help with the issue. Glad to respond if you need more info.**
Building bootc from source with `make bin install-all` regressed in v1.16.11 on distributions that do not ship libselinux development headers. v1.16.10 builds fine.
### Cause
v1.16.11 added `selinux` to the workspace and consumes it unconditionally:
- `Cargo.toml:76` (`[workspace.dependencies]`) — `selinux = "=0.5.0"`. Not present in v1.16.10.
- `crates/lib/Cargo.toml:54` — `selinux = { workspace = true }`, with no `optional = true` and no feature gate.
So every build of `crates/lib` now requires libselinux at link time, whether or not the target system has SELinux.
### Failure
```
error: failed to run custom build command for `selinux-sys v0.6.15`
selinux-sys: Failed to find 'selinux/selinux.h'. Please make sure the C header
files of libselinux are installed and accessible: Kind(NotFound)
make: *** [Makefile:44: manpages] Error 1
```
It surfaces in the `manpages` target because that is the first thing to build the lib, but `make bin` fails the same way.
### Why this is hard to work around downstream
Arch Linux packages neither `libselinux` nor `libsepol` in its official repositories, so there is no package to install:
```
$ curl -s 'https://archlinux.org/packages/search/json/?name=libselinux' | jq .count
0
$ curl -s 'https://archlinux.org/packages/search/json/?name=libsepol' | jq .count
0
```
That leaves adding a third-party repository, or building both libraries from source, purely to satisfy a link-time dependency on a system where SELinux is never enabled.
Worth noting this arrived in a patch release, so it reached anyone auto-updating within the 1.16 range.
### Suggested fix
Gate it behind a cargo feature. `crates/lib` already uses this pattern for `install-to-disk`, `rhsm` and `docgen`:
```toml
# crates/lib/Cargo.toml
selinux = { workspace = true, optional = true }
[features]
default = ["install-to-disk", "selinux"]
selinux = ["dep:selinux"]
```
That keeps current behaviour for everyone by default and lets non-SELinux distros opt out. If the SELinux call sites are not easily made conditional, even a documented statement that libselinux is now a hard build requirement would help downstreams decide what to do.
### Environment
bootc v1.16.11, built from source in an `archlinux:latest` container, rust from the Arch repositories. Context is an Arch-based bootc image; happy to test a patch.
Contributor guide
Research direction
Start with Cargo.toml:76 and crates/lib/Cargo.toml:54, then inspect the SELinux call sites and the existing install-to-disk, rhsm, and docgen feature patterns. Verify the default build preserves current SELinux behavior, while a non-SELinux build can run make bin install-all without requiring libselinux headers.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- build-system
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 75/100