feat(web/website): init

This adds a new Website/Docs for Snix, using Thulite / Doks, which is
mostly hugo and a bit of npm.

Change-Id: Iea10d4068fa783ec0ddd6bcaba5c8d92b1a1168f
This commit is contained in:
Florian Klink 2025-03-16 13:36:18 +01:00
parent 2705517e6d
commit 91d8b86b39
55 changed files with 6205 additions and 0 deletions

View file

@ -0,0 +1,12 @@
---
title: "Components"
description: ""
summary: ""
date: 2023-09-07T16:12:37+02:00
lastmod: 2023-09-07T16:12:37+02:00
draft: false
weight: 30
toc: true
sidebar:
collapsed: false
---

View file

@ -0,0 +1,26 @@
---
title: "Architecture"
slug: architecture
description: ""
summary: ""
date: 2025-03-14T14:14:35+01:00
lastmod: 2025-03-14T14:14:35+01:00
draft: false
weight: 31
toc: true
---
Snix is more decoupled than the existing, monolithic Nix implementation.
In practice, we expect to gain several benefits from this, such as:
* Ability to use different builders
* Ability to use different store implementations
* No monopolisation of the implementation, allowing users to replace components
that they are unhappy with (up to and including the language evaluator)
* Less hidden intra-dependencies between tools due to explicit RPC/IPC
boundaries
In addition to many individual backend implementations, Builders and Store
backends also provide a gRPC server and clients, allowing to plug in your own
implementation.

View file

@ -0,0 +1,13 @@
---
title: "Builder"
description: ""
summary: ""
date: 2023-09-07T16:12:37+02:00
lastmod: 2023-09-07T16:12:37+02:00
draft: false
weight: 40
toc: true
sidebar:
collapsed: true
---

View file

@ -0,0 +1,17 @@
---
title: "OCI Builder"
slug: oci
description: ""
summary: ""
date: 2023-09-07T16:12:37+02:00
lastmod: 2023-09-07T16:12:37+02:00
draft: false
weight: 42
toc: true
sidebar:
collapsed: true
---
The OCI builder creates a OCI Runtime specification out of the received
`BuildRequest`, then mounts the specified inputs using snix-castore, and then
invokes `runc`.

View file

@ -0,0 +1,35 @@
---
title: "Protocol"
slug: protocol
description: ""
summary: ""
date: 2025-03-14T14:14:35+01:00
lastmod: 2025-03-14T14:14:35+01:00
draft: false
weight: 41
toc: true
---
One goal of the builder protocol is to not be too tied to the Nix implementation
itself, allowing it to be used for other builds/workloads in the future.
This means the builder protocol is versatile enough to express the environment a
Nix build expects, while not being aware of "what any of this means".
For example, it is not aware of how certain environment variables are set in a
nix build, but allows specifying environment variables that should be set.
It's also not aware of what nix store paths are. Instead, it allows:
- specifying a list of paths expected to be produced during the build
- specifying a list of castore root nodes to be present in a specified
`inputs_dir`.
- specifying which paths are write-able during build.
In case all specified paths are produced, and the command specified in
`command_args` succeeds, the build is considered to be successful.
This happens to be sufficient to *also* express how Nix builds works.
Check `build/protos/build.proto` for a detailed description of the individual
fields, and the tests in `glue/src/tvix_build.rs` for some examples.

View file

@ -0,0 +1,45 @@
---
title: "Reference Scanning"
summary: ""
date: 2025-03-14T14:14:35+01:00
lastmod: 2025-03-14T14:14:35+01:00
draft: false
weight: 45
toc: true
---
At the end of a build, Nix does scan a store path for references to other store
paths (*out of the set of all store paths present during the build*).
It does do this by (only) looking for a list of nixbase32-encoded hashes in
filenames (?), symlink targets and blob contents.
As outlined in the [Builder Protocol]({{< relref "protocol" >}}) page, we
don't want to introduce Nix specifics to the builder protocol, but if we simply
do refscanning on the coordinator side, that side would need to download the
produced inputs and scan them locally.
This is undesireable, as the builder already has all produced
outputs locally, and it'd make more sense for it do do it.
Instead, we want to describe reference scanning in a generic, non-Nix-specific
fashion.
## Proposal
One way to do this is to add an additional field `refscan_needles` to the
`BuildRequest` message.
If this is an non-empty list, all `outputs` are scanned for these.
The `Build` response message would then be extended with an `outputs_needles`
field, containing the same number of elements as the existing `outputs` field,
describing which `refscan_needles` are found for each output.
If there's needles found, they will be a list of indexes into the
`refscan_needles` field specified in the `BuildRequest` field.
For Nix, `refscan_needles` would be populated with the nixbase32 hash parts of
every input store path and output store path. The latter is necessary to scan
for references between multi-output derivations.
This is sufficient to construct the referred store paths in each build output on
the build client.

View file

@ -0,0 +1,98 @@
---
title: "Component Overview"
slug: overview
description: ""
summary: ""
date: 2025-03-14T14:14:35+01:00
lastmod: 2025-03-14T14:14:35+01:00
draft: false
weight: 32
toc: true
---
This diagram gives an overview over the different crates in the repository, the
different contained components and the dependencies in between them.
If you scroll further down, you find a textual description of what each component does.
Check the individual documentation pages for more details.
{{< inline-svg src="crate-diagram.svg" width="800px" height="800px" class="svg-inline-custom" >}}
## Castore
`snix-castore` is a content-addressed data storage / syncing engine.
It uses a merkle structure to store filesystem trees, as well as a chunked blob
storage for individual file contents.
It is not Nix-specific.
## Store
`snix-store` is a Nix store implementation using `snix-castore` for the
underlying data structure.
It only stores metadata like store path names, nar hashes, references,
signatures etc, and offloads content storage to `snix-castore`, by storing the
root node describing the contents.
There's also a CLI entrypoint that can be used to host a gRPC server endpoint,
copy into a store, or mount a store as a FUSE/virtiofs.
## Nix-Compat
`nix-compat` is a library providing access to various data formats, protocols
and concepts of Nix.
It does not depend on other Snix crates, making it a low-dependency crate to
include in other (non-snix) projects as well.
Other snix crates are usually the primary consumers and drive new functionality
in there - new formats etc. are usually "factored out into nix-compat".
## Builder
The builder consumes build requests from a client, runs builds and sends
logs/telemetry to the client.
There currently exists an OCI builder, as well as gRPC server adapter and client
implementations, allowing to run the builder both locally or remotely.
## Eval
`snix-eval` is a bytecode interpreter evaluator. It knows about basic Nix
language data structures and semantics, constructs bytecode and provides a VM
executing this bytecode.
It also provides some "core" builtins, though builtins are pluggable - you can
construct an evaluator and bring your own builtins.
It also defines the `EvalIO` trait and provides some very simple implementations
of it, which is how the evaluator does do IO.
## Glue
`snix-glue` provides some more builtins (those interacting with the Builder and
Store mostly).
It allows keeping `snix-eval` relatively simple.
## CLI
`snix-cli` is a REPL interface, constructing an Evaluator and populating it with
most builtins present in Nix. It is our main vehicle to evaluate Nixpkgs and
check for differences.
## Serde
`snix-serde` is a crate allowing (de)-serialisation of Rust data structures
to/from Nix. It allows you to use (a subset of) Nix as a configuration language
in/for your application.
## Tracing
`snix-tracing` contains some common tracing / logging / progress reporting code
that's used in various CLI entrypoints.
## Nar-Bridge
`nar-bridge` provides a Nix HTTP Binary cache server endpoint (read-write),
using `snix-[ca]store` to store the underlying data. It allows you to host your
own binary cache that Nix can talk to.
## Snixbolt
This uses `snix-eval`, providing a WASM bytecode explorer running in your
browser.