about
orb is a source-based package manager focused strongly on simplicity. Its database is backed solely by the filesystem and requires no extra dependencies, making it explorable by the user and therefore trivial to maintain.
It uses a simple directory structure under /src
containing the package sources, similar to the BSD ports system. In orb,
this location is called the source tree.
orb itself is written entirely in POSIX sh(1); it uses only a handful of core utilities. This means that it is easily portable to many systems and extremely light on dependencies.
orb features a unique approach to package management. Instead of
installing packages into the root filesystem, it places them into
separate directories in /store
. This is, unsurprisingly,
referred to as the store. These are then linked to from
/opt
, the selection. This serves to hold a list
of packages currently selected for use (whereas the store is merely a
collection of all available packages and versions thereof).
After this, orb does nothing more. Actually adding the contents of the packages to the user's environment is considered out of scope, better suited to tools such as GNU stow, or other solutions such as orbit's RPATH variable.
Similarly, orb does not provide functionality to fetch or maintain the source tree. This is a task which is delegated to the distribution.
This approach has several benefits:
- couples package file ownership to filesystem
- makes package versions easily interchangeable
- keeps resources neatly separated
The result: a simple and robust system.
setting up orb
orb is very simple to set up. You need available on your system a POSIX-compliant shell, sudo(1), wget(1), sha256sum(1), and sha512sum(1).
Certain parts of orb (such as fetching source tarballs and building packages) are run under an unprivileged user account. orb expects the users fetch and build to exist on the system, as well as groups of the same name. These should be system accounts.
Directories should be set up as follows:
/opt | root:root | 0755 |
/src | root:src | 0755 |
/store | root:root | 0755 |
/var/cache/orb | fetch:fetch | 0750 |
/var/tmp/orb | build:build | 0750 |
/etc/orb | root:src | 0750 |
Whilst technically not required by orb, we recommend setting up a src group as shown above. orb itself will only ever need read access to the source tree.
The file /etc/orb/config
is a shell script which is sourced at
startup. Any variables defined here will be made available to build.sh
and install.sh.
the source tree
The source tree contains a list of directories, each of which contain information about a specific package (known hereunto as a recipe). This includes metadata, dependency listings, directions on source retrieval, miscellaneous files and patches, and directives to orb for building and installing the package.
The structure of a recipe is as follows:
info/ | package metadata |
build.sh | build instructions |
install.sh | install instructions |
deps/ | dependency information |
files/ | patches and miscellaneous files |
sources/ | source URLs and checksums |
With the exception of the info/
directory, none of these are
required. Detailed information on each of them may be found below.
info/
This directory contains a set of files containing metadata about the package:
version | the version of the package |
description | a short, one-line description of the package |
homepage | the homepage of the package |
All of these files are required. If there is no designated homepage as such, the URL of the package's source repository will suffice.
build.sh
This file is a shell script which automates the build process of the package, and carries out additional related tasks such as extracting, configuring, and patching. It need not contain a shebang nor be set executable. Actions done here are run as the orb build user.
There are several environment variables available to the script:
ORB_PKG_ROOT | the prefix in which the package is installed |
N | the name of the package |
V | the version of the package |
install.sh
This file is a shell script which automates the install process of
the package. Actions done here are run as root. The rules for build.sh
also apply.
deps/
This directory contains dependency information for the package.
Dependencies are separated into three files, each containing one package name per line:
build | packages which are needed to build the package |
core | packages which trigger a rebuild when updated |
run | packages which are needed at runtime by the package |
files/
This directory is used to store miscellaneous files and patches for the package.
sources/
This directory contains pairs of files in the following form:
<file> | the url from which to download <file> |
<file>.sha512 | the 512-bit SHA-2 hash of <file> |
It is an error to not provide a hash for a url, or vice-versa. The
url will undergo shell expansion, meaning it does not need to be updated
every time the version changes. The variables N and V
are available, with the same meaning as in build.sh
.
inner workings
Documented here are the minutiƦ of orb: small details of importance only to developers, or users who wish to know their system inside-out, upside-down, and inverted through the fourth dimension.
hashing
In order for orb to detect when packages need to be rebuilt (say, due to a version bump, or a change in a build script), it needs some way of determining if there currently exists a version of the package in the store built from the current version in the source tree.
A trivial way of accomplishing this (and the method which orb uses) is to take a cryptographic hash of the recipe and store it along with the built package. This way, any changes to the build scripts, metadata (including version numbers), patches, and anything else will result in a new hash, meaning there will not be an equivalent package in the store -- thus triggering a rebuild. orb uses a 256-bit SHA-2 function to do this, since it provides a good amount of integrity while simultaneously not posing too much of a risk to the visual cortex.
Since one may only hash files, and not directories, orb instead derives the hash by hashing the directory hierarchy, along with the hashes of every file in it. In this manner, orb can detect both changes to the directory structure, and modifications of the actual files within.
the store
The store contains a list of directories, one for each package built on the system, each containing a set of . Inside of each of these are more directories, each the root of an installation of the respective package. These root directories are named after the hash of the recipe for the package at the time of their build.
The store contains a list of symbolic links to the currently installed
version of a package. The packages themselves reside in /store
, each
package folder containing one or more hash directories. These hash directories
correspond directly to the hash of a package revision in the source tree.
The hash directories themselves contain all files belonging to the package version in question. This makes each directory there a distinct subset of the effective system root.
For example:
% find /store/manpager/16b952[...]cf0558/
/store/manpager/16b952[...]cf0558/
/store/manpager/16b952[...]cf0558/bin/
/store/manpager/16b952[...]cf0558/bin/manpager
/store/manpager/16b952[...]cf0558/share/
/store/manpager/16b952[...]cf0558/share/man/
/store/manpager/16b952[...]cf0558/share/man/man1/
/store/manpager/16b952[...]cf0558/share/man/man1/manpager.1
% readlink /opt/manpager
/store/manpager/16b52[...]cf0558
the world file
orb keeps track of whether a package was installed as a dependency
or explicitly installed by the user. Whenever a package is
installed explicitly, orb will record the name of that package in
/etc/orb/world
, known as the world file.
fetching sources
To fetch a source file, orb goes through the following steps:
- Expand the source URL
- Download the file using wget(1), and save it to a temporary directory
- Verify the downloaded file using sha512sum(1)
- If the verification succeeds, move the downloaded file to the cache
build process
To build a package, orb copies all necessary sources into the
temporary build directory /var/tmp/orb
, unpacks them there,
and then runs the package's build.sh script as the build
user.
After build.sh exits successfully, orb runs the install.sh script as root, placing the resulting files into the store. Then, orb updates the symlink in the selection to match the newly installed package.
Once the package is installed, orb removes all leftover files from the temporary build directory.
installed packages
Installing a package simply involves making a symlink from the database TODO