⚠️ Branch in progress. This branch (lib-rs) is a from-scratch rewrite of upac's core library in Rust, built around composefs instead of OSTree. The FFI/orchestration engine is done; the actual command bodies, the hook system, and packaging are still being implemented — expect gaps andtodo!()s.
A modular package management library for Linux systems with composefs-based atomic deploys.
Upac is a package manager for Linux-compatible systems. It manages the updating, removal, and installation of various package formats using per-format decoders, and keeps every change behind an atomic, composefs-backed deploy so the system can always be rolled back to a previous commit.
upac-cli (binary: up) is a command-line frontend written in Rust that dynamically loads libupac.so and drives it through its C ABI.
upac-lib is the core library, also written in Rust, designed to be embedded into package managers through a stable C ABI. It handles installation, database management (via redb), and composefs-based system snapshotting — without imposing any policy on how packages are fetched or what format they come in.
The library is intentionally split into independent components: decoders handle format-specific unpacking, the core library handles installation and database operations, and everything crosses the FFI boundary through a shared upac-abi crate.
Full architecture and design decisions live in the project design note:
doc/UPAC_project_note.en.md— English (canonical)doc/UPAC_project_note.md— Russian
It covers the disk layout, the deploy/rollback model, the /etc merge, GC, the FFI boundary, and the planned module structure.
up pkg install <path> # installs a package into the system using the matching decoder, with checksum verification
up pkg remove <name> # removes an installed package by name (alias: uninstall)
up pkg update <name> # updates an installed package to a new version
up pkg list # lists installed packages
up pkg diff # diffs installed package versions against a commit or another package set
up pkg search # searches package metadata
up file add <path> # tracks a standalone file outside of a package
up file remove <path> # untracks a standalone file
up file diff # diffs tracked files against a commit
up file search # searches tracked files by path
up commit new # creates a new commit of the current deploy state
up commit list # lists commit history
up commit rollback <id> # reverts the system state to a specified commit ID| Crate | Path | License | Role |
|---|---|---|---|
upac-abi |
lib/abi |
LGPL-3.0-or-later | C-ABI types, error codes, and conversions shared between upac-lib and its consumers |
upac-macro |
lib/macro |
LGPL-3.0-or-later | Derive macros for C-ABI struct plumbing, used internally by upac-lib/upac-abi |
upac-lib |
lib/lib |
LGPL-3.0-or-later | Core library: composefs-based atomic deploys, redb package database, exposed via a C ABI (libupac.so) |
upac-cli |
user/upac-cli |
GPL-3.0-only | CLI frontend (binary up) |
upac-sign-cli |
user/sign-cli |
GPL-3.0-only | CLI for signing upac hook files and other artifacts with Ed25519 certificates (binary up-si) |
The core library exposes a C-compatible ABI through libupac.so. All strings cross the boundary as { ptr, len } pairs rather than null-terminated C strings. All functions return an integer error code.
Decoders are separate shared libraries, still written in Zig, that handle format-specific package unpacking. Each decoder receives a package path, an output directory, and a SHA-256 checksum; it verifies the checksum, extracts the package, parses the metadata, and returns a PackageMeta struct.
| Decoder | Formats | Distributions |
|---|---|---|
libupac-alpm.so |
.pkg.tar.zst, .pkg.tar.xz, .pkg.tar.gz |
Arch Linux, Manjaro, etc. |
libupac-rpm.so |
.rpm |
Fedora, RHEL, openSUSE, etc. |
libupac-deb.so |
.deb |
Debian, Ubuntu, etc. |
libupac-xbps.so |
.xbps |
Void Linux |
Adding support for a new package format means writing a new decoder .so — the core library does not need to change.
A command-line frontend written in Rust that dynamically loads libupac.so and the appropriate decoder at runtime. Subcommands are grouped under pkg (packages), file (standalone tracked files), and commit (deploy history/rollback).
- Rust (stable — pinned via
rust-toolchain.toml) - Zig ≥ 0.16.0 — for the decoders under
decoders/ libblkid,libmount(util-linux) — used byupac-libfor filesystem/mount handling
cargo build --workspacecd decoders/alpm
zig buildNote: packaging (Arch/RPM/deb) and the old
make-based build pipeline from the Zig implementation have not been ported to this branch yet.