flokli / nix-casync

A more efficient way to store and substitute Nix store paths
80 stars 4 forks source link

:warning: This project is archived: This was an experiment, and most of the findings make up their way into the Tvix Store protocol. Check my blog and Tvix for more updates!

nix-casync

A more efficient way to store and substitute Nix store paths.

Docs are a bit sparse right now, please refer to https://flokli.de/posts/2021-12-10-nix-casync-intro/ for a description on how this works.

Build

$ go build ./cmd/nix_casync/

Run

./nix_casync serve --cache-path=path/to/local

Uploading store paths

nix copy \
  --extra-experimental-features nix-command \
  --to "http://localhost:9000?compression=none" $storePath

Binary Cache

As of now, nix-casync can be used as a space-efficient binary cache.

You probably want to put some reverse proxy doing SSL in front of it, and add some protection on the PUT endpoints.

The following section describes some internal behaviour of nix-casync, and how it treats Narfiles and Narinfo files.

Narfiles

Narfiles can be uploaded with most of the compression mechanisms Nix supports.

The path it's uploaded at HTTP PUT /nar/….nar[.$suffix] doesn't really matter.

Files will be decompressed, chunked, and put in a content-addressed store.

Subsequently uploaded .narinfo files can refer to that file via the NarHash attribute, and downloads can happen via HTTP GET /nar/$narhash.nar[.$suffix].

For downloads, only a subset of compression algorithms (fast ones) are supported, as those are assembled on the fly and should really only be considered a poor-man's Content-Encoding.

Another note on compression

While it's possible to upload with narfile compression, as written above, this is only used to compress uploads into the binary cache.

This will have some unintuitive implications - if you upload a to /nar/$filehash.nar.zst, the upload won't be available on that location (but at /nar/$narhash.nar).

This also means HTTP HEAD requests to "compressed locations" will 404, and as a result, Nix clients might end up uploading the same .nar files multiple times. [^1]

If the binary cache is remote, it is preferable to use compression during upload to reduce bandwidth usage. In that case, using a fast compression algorithm, such as zstd is recommended.

By default, downloads are served with ZSTD Compression. This can be tweaked via the --nar-compression command line parameter.

Narinfo files

Narinfo files describe information about a store path, as well as some (redundant) information about the referred .nar file.

Internally, nix-casync splits data from .narinfo into NarMeta and PathInfo models.

When a Narfile is uploaded, the following checks are made:

[^1]: Nix won't upload the same store path multiple times, as it checks $outhash.narinfo for existence first - so this only applies to multiple .narinfo files referring to the same .nar file.