The Ur Project

Documenting the craft of stacking things so they remain stacked. For a very long time.

Architecture - The registry - part 5

This is possibly one of the shortest technical showcases, because registries are very, very simple :).

The concept

A registry is like a box with cards. On the cards are recipes. The cards are ordered, and they have an index. There are also sets that live in the registry.

The registry is nothing more than a file/directory structure to organize them and place content in the expected locations.

That's all there is to it. It's just declarative content - only.

The recipe

In one of the posts I made earlier I've shown you around recipe editing already, so at this point it should be relatively clear what a recipe is. It's just declarative content and possibly a few patches and drop-in files (sidecars) for various purposes.

Inside the registry itself, it just looks like this:

/
|-- recipes
|   |-- acl
|   |   |-- recipe.toml
|   |   `-- upstream-key.asc
|   |-- attr
|   |   |-- recipe.toml
|   |   `-- upstream-key.asc
|   |-- audit
|   |   |-- patches
|   |   |   |-- 0001-add-custom-makefile.patch
|   |   |   `-- 0002-tmpfiles-create-etc-audit-rules.d.patch
|   |   `-- recipe.toml
|   |-- autoconf
|   |   |-- recipe.toml
|   |   `-- upstream-key.asc
|   |-- automake
|   |   `-- recipe.toml
...

The recipe.toml is the meat of each recipe. Some recipes have various sidecars. You can see a few above.

The registry index

The registry.toml file sits top-level and contains a description and a name declaration, and then carries the index. These are the actual active recipes in the registry. There could be more recipes, but the index determines which ones are visible to dispatcher, and which ones are not. From the index you can see that the place where each recipe lives isn't hardcoded. You can actually make up your own directory structure. Mine is just a flat one:

[registry]
name = "base"
description = "Recipes for the buildroot and adjacent functionality"

[[recipe]]
path = "recipes/elfutils"

[[recipe]]
path = "recipes/filesystem"

[[recipe]]
path = "recipes/attr"

[[recipe]]
path = "recipes/automake"
...

Sets

Every distribution has a concept of package groups already. The Ur Project isn't new. Organizational grouping of packages is a very useful way to deal with dependency chains and make them manageable by humans, so we just call them sets in The Ur Project - that's the logical base name of the fundamental unit.

Sets are placed in a directory called sets that is top-level inside the registry structure, as follows:

/
`-- sets
    |-- build.toml
    `-- sys.toml

Here are the two sets in the base registry. Each of them looks like this:

[set]
name = "build"
description = "Build-essential floor -- the toolchain and probe build-systems every recipe compiles with"

members = [
    "autoconf",
    "automake",
    "bash",
    "binutils",
    "bison",
    "bzip2",
...

And there you have it. That's all there is to sets.

BTW, and we'll come back to this, but sets are a little more advanced than just being a macro for lots of packages. In The Ur Project, the package management understands what sets are and tracks when you install a set by "intent". The list of installed packages will show you which sets you installed, and uninstalling a set also works similarly in an intuitive way.

Using sets with the pkg tool is done by using it like this:

$ sudo pkg install +sys

After installing you can see it installed like this:

# pkg list
...
+sys                       -            Sandcastle-Base    [20/20 members, +12 dependencies]
...

More on sets in the next post in the series.

--sofar (aka Auke)