favicon here hometagsblogmicrobio cvtech cvgpg keys

Exploring Efficient Ways To Package Rust Software in openSUSE

#packaging #rust #opensuse

Soc Virnyl Estela | 2024-08-22 | updated: 2024-11-10 |reading time: ~7min

Update I am moving over some logic as another package called roast. This is to prepare this vendoring alternative called obs-service-cargo-vendor-home-registry. The project is still worked on during my free time.

I have re-investigated possible solutions for confusing packaging in Rust. Currently, we are using cargo vendor to vendor package dependencies. This comes at a cost.

  • Back and forth copying of .cargo/config.toml for possible projects that use monorepo configurations i.e. workspace and real monorepos.
    • Examples of these are: zellij, wezterm and python-tokenizers
  • We always want to ensure Cargo.lock and I doubt the solution will not avoid this since lockfiles are always essential when building software with Rust.
  • Existing .cargo/config.toml from projects will be overridden with our generated .cargo/config.toml.

The first solution I thought of is a global .cargo/config.toml for projects. This has been done with python-tokenizers in openSUSE because it is possible to use --manifest-path to specify a manifest Cargo.toml file in the specfile for cargo invocations.

Seeing this, I realised, why not just use the $CARGO_HOME since we are pointing at a global cache anyway? This blog is about tracking my future project https://github.com/uncomfyhalomacro/obs-service-cargo-vendor-home-registry of which I plan to integrate into https://github.com/Firstyear/obs-service-cargo as an alternative vendor generating utility for Open Build Service or OBS.

Storage size eaten by CARGO_HOME vs cargo vendor comparison§

NOTE cargo fetch, cargo vendor, cargo build, and cargo generate-lockfile all update the CARGO_HOME or what we call the cargo home registry or just cargo home. We use cargo fetch here because it's designed to update the registry cache instead of other commands.

WARNING Behaviours between cargo fetch and cargo generate-lockfile cargo fetch updates the registry to latest version of crates and also regenerates Cargo.lock to reflect the versions unless --locked flag is passed where it tries to respect the versions of the crates from the existing Cargo.lock despite this contradicting description in the manpage that If a Cargo.lock file is available, this command will ensure that all of the git dependencies and/or registry dependencies are downloaded and locally available. Subsequent Cargo commands will be able to run offline after a cargo fetch unless the lock file changes.

However, cargo generate-lockfile updates the registry + updates the Cargo.lock which in my opinion is just a duplication of the other cargo sub-command cargo update. Why? Both do the same behaviour. Even the part where you pass --locked will give you the same error "error: the lock file /run/host/tmp/jay-1.4.0/Cargo.lock needs to be updated but --locked".

Here are the zstd compressed tarballs for the following after running the cargo commands

wezterm

  • cargo-vendor: 1.1GB
  • cargo-fetch: 1.3GB

jay

  • cargo-vendor: 24MB
  • cargo-fetch: 76MB

zellij

  • cargo-vendor: 66MB
  • cargo-fetch: 133MB

Why does it seem like cargo-fetch duplicates the contents in the tarball? Because it really does. The registry contains the following directory structure

.
└── registry
    ├── cache
    │   └── index.crates.io-6f17d22bba15001f
    ├── index
    │   └── index.crates.io-6f17d22bba15001f
    └── src
        └── index.crates.io-6f17d22bba15001f

8 directories, 0 files

One can remove the .cargo/registry/src directory as that contains the extracted crates and then create a tar.zst file using the following commands

# Assuming $CARGO_HOME is set to $PWD/.cargo
pushd .cargo
rm -rfv registry/src
popd
tar --zstd -cvf vendor.tar.zst .cargo/

How to get cache from $CARGO_HOME§

Any of these commands will generate the cargo home registry cache

  • build
  • generate-lockfile
  • vendor
  • fetch
  • update

Some commands are duplication of the other commands i.e. update and generate-lockfile. It's just that the former prefetches the latest crate versions while the latter doesn't.

To update the registry cache, one must either go with cargo fetch or even cargo vendor to avoid building or updating (unless update is set).

All commands try to regenerate the Cargo.lock with the latest compatible MSRV. If --locked is passed, it will try to attempt to respect the versions in the Cargo.lock. However, if the version of a dependency in Cargo.lock got yanked and there is a newer version, then an operation with --locked will fail. Also, passing --locked to cargo-update is ambiguous as it will always almost fail since it tries to update the Cargo.lock.

Why not go with cargo vendor --sync§

Reason? Uncertainty of how that command respect Cargo.lock for each crate. I would rather have do

cargo fetch --locked --manifest-path=path/to/Cargo.toml

for each manifest found since one can flexibly turn --locked on and off.

Building now with $CARGO_HOME§

It's always has been possible to use $CARGO_HOME, specifically, $CARGO_HOME/registry.

There was an attempt in this repository, https://github.com/openSUSE-Rust/obs-service-cargo-vendor-home-registry.

Now, that project has been merged into https://github.com/openSUSE-Rust/obs-service-cargo.

You can see this working in https://build.opensuse.org/package/show/editors/kak-lsp. But we lied a bit here. We will explain that in the later sections.

Path dependencies in Cargo.toml needs to be revisited§

Membered crates (in workspace configurations) and local crates (both are local and in path actually) should also be taken consideration when vendoring dependencies.

For example, https://build.opensuse.org/package/show/science:machinelearning/python-tokenizers have two different dependencies that are actually related to each other.

The solution to this is to eagerly check their manifest and lockfiles. Hence, either with multiple vendor tarballs or a vendored $CARGO_HOME.

Lockfiles are always inconsistent§

See https://github.com/rust-lang/cargo/issues/7169. This is a glaring issue and not just for cargo install but almost all cargo commands such as cargo fetch. That's why in openSUSE, we try to include the lockfile as much as possible even if passing --locked. I think I would agree to this comment https://github.com/rust-lang/cargo/issues/7169#issuecomment-539226733.

Observation

  • cargo fetch --locked does not work because it tries to keep the registry cache updated
  • cargo vendor --locked works because I don't know why???

Now is the use of --sync idea thrown out the window?

For crates that don't ship with a lockfile, we will run eithercargo generate-lockfile or cargo update, former is more semantically correct to do as opposed to cargo update. But update makes sense the most because we are going to add update options on the new project anyway.

cargo-fetch vs cargo-update§

Two days ago as of writing, I filed a bug report regarding inconsistencies between cargo-fetch and cargo-vendor. Link to bug report https://github.com/rust-lang/cargo/issues/14795.

The inconsistency specifically is the way the two handle dependencies differently especially when it comes to cargo-fetch's --target flag.

I had high hopes that by default1, it gets all target architectures. But I was met with failed builds on not so commonly used architectures whereas vendored dependencies from cargo-vendor compiles. They fail because they cannot find their dependencies fetched from cargo-fetch.

I will just have to wait for a feedback regarding how cargo-fetch behaves as compared to cargo-vendor. I believe though that both should be at least similar in almost all aspects.

  1. This is still not a loss yet for me since most of the software I used in openSUSE are used by people who either use x86_64 and aarch64. I don't believe that the other architectures are used commonly so I have removed support.

Articles from blogs I follow around the net

[WFD 34] do you want me to do that?

i built an AI agent with persistent memory. now i need to figure out if it's remembering the truth or just what i wanted to hear.

via Ryana May Que — Writings for DiscussionMarch 02, 2026

Recently

The snow has been tough for my running schedule in February but it's starting to clear and temperatures have started to lift. Yesterday got in a solid 45 miles of cycling, including up to this point near the George Washington Bridge, and back on the Tappan…

via macwright.comMarch 01, 2026

Cryptography Engineering Has An Intrinsic Duty of Care

To understand my point, I need to first explain three different cryptography attack papers / blog posts. I promise this won’t be boring. Three Little Disclosures Misuse-Prone Ciphers For All In a blog post titled Carelessness versus craftsmanship in crypto…

via Dhole MomentsFebruary 25, 2026

What’s That String? That Time a Weird String Revealed a Whole Operation

How it felt to work on this post. Shikanoko Nokonoko Koshitantan is written by Takashi Aoshima and published by Wit Studio. It all started with a slack message from boB Rudis: “Hey, I keep seeing this string. Any ideas?” d2=%3D%3DQXisTKpcCd4RnLsF3ckN3LlR…

via GreyNoise LabsFebruary 24, 2026

Designing Odin's Casting Syntax

Odin;s declaration syntax becomes second nature to everyone who uses the language but I do sometimes get asked ;Why are there two ways to do type conversions?; Enough that I had to make an FAQ entry..The reason that there are two ways to do type conversio…

via gingerBill - ArticlesFebruary 23, 2026

Status update, February 2026

Hi all! Lars has contributed an implementation independent test suite for the scfg configuration file format. This is quite nice for implementors, they get a base test suite for free. I’ve added support for it for libscfg, the C implementation. I’ve spent …

via emersionFebruary 21, 2026

Investigating the SuperNote Notebook Format

I'm a big fan of eink tablets. I read a lot, I write a lot, I prefer handwritten notes, it's a match made in heaven. I've been using a Kindle Scribe for the past several years - I probably used it as much or more than my phone. Recently, I upgraded to a Su…

via Cracking the ShellFebruary 20, 2026

Luxe, ocaml et volupté

Luxe, ocaml et volupté by Clément Delafargue on February 16, 2026 Tagged as: ocaml. After a couple years using rust as my primary language, I’ve got a new job where I’m using a variety of languages (including rust and typescript), but mostly go 1. So…

via Clément Delafargue - RSS feedFebruary 16, 2026

How To Add DRM To Your Backend (easy) [2026 WORKING]

How KineMaster stopped some modded clients from accessing their asset market

via maia blogFebruary 14, 2026

Push comes to shove tools

Your tools are extensions of your skills

via Ishan WritesFebruary 09, 2026

The cults of TDD and GenAI

I’ve gotten a lot of flack throughout my career over my disdain towards test-driven development (TDD). I have met a lot of people who swear by it! And, I have also met a lot of people who insisted that I adopt it, too, often with the implied threat of appe…

via Drew DeVault's blogJanuary 29, 2026

2025 in review

Come along with me as I review the past year. Heh, I often start these kinds of posts right at the start of the year, but it takes a few weeks longer than I ever expect to think them through.1 Two years of being independent After a second year of operati…

via seanmonstarJanuary 27, 2026

The Birthday Paradox, simulated

I'm a fan of simulating counterintuitive statistics. I recently did this with the Monty Hall problem and I really enjoyed how it turned out. A similarly interesting statistical puzzle is the birthday paradox: you only need to get 23 people in a room a room…

via pcloadletterJanuary 23, 2026

Merry Christmas, Ya Filthy Animals (2025)

It’s my last day of writing for the year, so I’m going to try keep this one quick – it was knocked out over three hours, so I hope you can forgive me if it’s a bit clumsier than my usual writing. For some strange reason, one of the few clear memories I hav…

via LudicityDecember 27, 2025

Why are people migrating away from GitHub?

I noticed some people migrating away from GitHub recently. I was curious to understand the rationale. Is it a blip or is it a sign of prolonged exodus?

via Rob O'Leary | BlogDecember 22, 2025

Yep, Passkeys Still Have Problems

It's now late into 2025, and just over a year since I wrote my last post on Passkeys. The prevailing dialogue that I see from thought leaders is "addressing common misconceptions" around Passkeys, the implication being that "you just don't understand it co…

via Firstyear's blog-a-logDecember 17, 2025

Hacking the World Poker Tour: Inside ClubWPT Gold’s Back Office

In June, 2025, Shubs Shah and I discovered a vulnerability in the online poker website ClubWPT Gold which would have allowed an attacker to fully access the core back office application that is used for all administrative site functionality.

via Blog | Sam CurryOctober 12, 2025

Testing multiple versions of Python in parallel

Daniel Roy Greenfeld wrote about how to test your code for multiple versions of Python using `uv`. I follow up with a small improvement to the Makefile.

via Technically PersonalJuly 21, 2025

Generated by openring-rs

favicon here hometagsblogmicrobio cvtech cvgpg keys