Turris OS and OpenWrt Upstream Feeds: How Close Are We Already?

TOS 9.1 already moved this way

When Turris OS 9.1 shipped, one of the quieter changes was unfreezing the upstream OpenWrt feeds. Packages that Turris was previously rebuilding from source just to stay in version parity now flow straight from OpenWrt’s own repositories. No redundant CI build, no lag waiting for the team to catch up. For that slice of packages, the system already behaves roughly the way the forum thread describes.

But “roughly” is carrying some weight there.

How Turris currently rebuilds everything

Turris OS 9.x is built on OpenWrt 24.10. CZ.NIC maintains two parallel layers on top of it: their OpenWrt fork, which carries a handful of patches to the base system, and a separate packages repo — turris-cz/os-packages — that holds Turris-specific software and selective backports from upstream.

Historically, that packages repo included a lot of stuff that was functionally identical to upstream OpenWrt. Same source, same version, just rebuilt. The rebuild guaranteed binary compatibility with the Turris kernel and target, but it also meant CZ.NIC was running CI jobs for packages that could in principle just be fetched from OpenWrt’s servers. The 9.1 feed unfreeze addresses exactly that.

What the proposal is actually asking for

The forum suggestion is to flip the default fully: point the Turris updater at OpenWrt’s package feeds as the primary source, then layer a Turris-specific repo on top at higher priority so Turris-modified packages shadow the upstream versions where needed.

The Turris updater, pkgupdate, already supports tiered priorities. In the Lua configuration, Repository() accepts a priority integer — default is 50, higher wins. A setup like this would work:

Repository('openwrt', 'https://downloads.openwrt.org/releases/24.10/packages/armv7-el/')
Repository('turris', 'https://repo.turris.cz/hbs/packages', {priority = 60})

The mechanism is already there. What’s missing is a clean organizational split to make it safe to actually flip.

The hard part: patched packages

Not every package in the Turris repo is a straight copy of upstream. Some carry local patches — a security fix that hasn’t been merged yet, a hardware workaround, a config default tuned for Turris behavior. Pull those from an upstream binary feed and you silently drop the Turris changes. No error. Just gone.

That’s the real problem to solve. Any implementation of the upstream-feed model needs a clear, maintained inventory of which packages are pure pass-through and which carry local modifications. Pass-through packages can safely consume upstream binaries. Patched packages have to stay in the Turris build, at least until their patches land upstream.

Upstream is the key word. The cleanest long-term outcome isn’t “Turris maintains a permanent shadow repo” — it’s “Turris fixes things upstream first, and the shadow repo shrinks over time.”

Kernel modules are a separate issue

Userspace packages — daemons, tools, libraries — are generally safe to pull from upstream binaries as long as the C library ABI matches the release. On the ARM targets Turris devices use, this is usually fine against a matching OpenWrt 24.10 build.

Kernel modules are different. They have to match the exact kernel version and config they were compiled against. If Turris’s kernel diverges from the upstream 24.10 kernel even slightly — a backported security patch, a different Kconfig option — a kernel module package pulled from OpenWrt’s feed can fail to load at runtime. Wireless drivers, netfilter helpers, filesystem modules: all of these have to stay in the Turris build pipeline regardless of what happens with the rest of the package set.

What a complete implementation would look like

The path forward is mostly an organizational change, not a technical one. The updater infrastructure already supports it.

  • Classify each package in turris-cz/os-packages as either upstream-identical or Turris-patched
  • Drop upstream-identical userspace packages from the Turris build; the updater pulls them from OpenWrt directly
  • Keep patched packages in the local repo, served at higher priority to shadow the upstream version
  • New patches go upstream first; once merged and picked up by an OpenWrt release, the local override gets removed
  • Kernel-module packages stay in the Turris build regardless, because ABI has to match the Turris kernel exactly

TOS 9.1’s feed unfreeze is step one. The rest is about methodically shrinking the local override list rather than letting it grow as a parallel maintenance burden forever.

Sources


Similar Posts