Attempts to create an atomic package manager for everyone

Linux Package Manager in Rust (composefs, EROFS, BLS)

Hi everyone!

I'm working on UPAC, a universal, atomic, and content-addressed package manager and deployment engine for Linux, written in Rust!

Traditional package managers edit files in place on live systems, leading to non-reproducible states and broken systems on interrupted updates. Existing immutable solutions (like OSTree) often introduce high barriers for simple tasks or lock users into specific ecosystems.

UPAC aims to solve state management while keeping disk layouts, bootloaders, and package formats flexible!

Key Architectural Highlights

  • Content-Addressed & Immutable: Uses composefs + `EROFS` + `fs-verity` to build verifiable system images. Operations are atomic: a new image is prepared without touching the running system.
  • Smart 3-Way: /etc merge: automatically preserves user edits, applies package defaults, and leaves non-blocking .upac-new conflict markers without halting deployments.
  • Direct User Injections into /usr: Allows users to add standalone assets into /usr with full tracking in the package DB โ€” no full packaging boilerplate required.
  • Multi-Format Decoders via C-ABI: Decoders (deb, rpm, alpm, xbps) are decoupled into plugins (`dlopen` or statically compiled) behind a clean C-ABI.
  • Deterministic Boot & Auto-Rollback: Leverages BootNext (direct UKI) or LoaderEntryOneShot (BLS/systemd-boot) for single-attempt safe boots. If the new deployment fails before late confirmation, the firmware automatically falls back to the previous known-good deployment.

Project Structure

upac/
โ”œโ”€โ”€ lib/ Rust core & C-ABI
โ”œโ”€โ”€ cli/ Thin CLI frontend
โ”œโ”€โ”€ decoders/ Plugin crates for formats (alpm, deb, rpm, xbps)
โ”œโ”€โ”€ derive-static/ Proc-macro crate
โ””โ”€โ”€ tests/ Integration tests

Looking for Co-Developers & Contributors!

The specification and architecture are most fleshed out for base oackage manipulations, and ima moving forward with implementation. Since balancing full-time work and open-source can be tough, I'd love to connect with fellow Rust systems engineers interested in building this together!

Great areas to jump in on:

  1. Package Decoders (decoders/*): Implementing standalone decoders for .deb, .rpm, or .pkg.tar according to the plugin contract.
  2. The /etc 3-Way Merge Engine: Pure logic crate to merge live configs, base defaults, and new package defaults (handling overlayfs whiteouts).
  3. FFI & Plugin Loader: Dynamic loading (dlopen) and C-ABI wrappers.
  4. CLI & Event Hooks: Rendering progress and handling user callbacks.

If you're interested in low-level Linux systems, storage, or package management in Rust, check out the project or reach out!

Did not find a single .rs file there.


There are UB operations in some of the code; I'll illustrate with one example from cli/src/ffi.rs. I am slightly confused how they ended up like that. Feel free to ask questions over here if you need help with fixing it.

#[repr(C)]
pub struct CancelToken {
    _flag: u8,    // not in an UnsafeCell
    _hook: Option<unsafe extern "C" fn(*mut c_void)>,
    _hook_ctx: *mut c_void,
}

impl CancelToken {
    ...
    pub fn cancel(&self) {
        // &self means we have a read-only permission for CancelToken
        // over its ._flag, in particular

        unsafe {
            // uhm...
            let atomic_flag = &*(&self._flag as *const u8 as *const AtomicU8);

            // and this's a write to a place with no write permission
            atomic_flag.store(1, Ordering::Release);
            // any execution through this line has undefined behavior