Creating a Custom Repository

Updated

October 30, 2026

Creating a Custom Repository

In this chapter, we create a functional, standalone repository for our custom distribution. We will construct a packaging tool called byol-pkg that packages directories into compressed archives, generates indexed repository metadata, and serves them over HTTP.

+-----------------------------------------------------------+
|               The byol-pkg Repository Structure           |
|                                                           |
|  /srv/repo/                                               |
|  ├── x86_64/                                              |
|  │   ├── index.json          # Main repository catalog    |
|  │   ├── index.json.minisig  # Cryptographic signature    |
|  │   ├── bash-5.2.21-1.tar.zst                            |
|  │   └── coreutils-9.4-1.tar.zst                          |
|  └── repo.conf               # Client repository pointer  |
+-----------------------------------------------------------+

Step 1: Defining the Package Manifest

Every package built in our distribution will include a PACKAGE.toml manifest:

# PACKAGE.toml
[package]
name = "bash"
version = "5.2.21"
release = 1
architecture = "x86_64"
summary = "The GNU Bourne Again SHell"
license = "GPL-3.0-or-later"

[dependencies]
runtime = ["glibc>=2.38", "ncurses>=6.4"]

[files]
prefix = "/usr"

Step 2: Packaging Script (byol-pack)

Here is a clean POSIX shell script that packages a target directory tree into a signed BYOL archive:

#!/bin/sh
# byol-pack: Assembles a package payload into a compressed archive
set -eu

PKG_DIR="$1"     # Directory containing staged binary files
MANIFEST="$2"    # Path to PACKAGE.toml
OUTPUT_DIR="$3"  # Destination directory

PKG_NAME=$(grep '^name =' "$MANIFEST" | cut -d '"' -f 2)
PKG_VER=$(grep '^version =' "$MANIFEST" | cut -d '"' -f 2)
PKG_REL=$(grep '^release =' "$MANIFEST" | awk '{print $3}')
PKG_ARCH=$(grep '^architecture =' "$MANIFEST" | cut -d '"' -f 2)

ARCHIVE_NAME="${PKG_NAME}-${PKG_VER}-${PKG_REL}-${PKG_ARCH}.byol.tar.zst"

echo "[byol-pack] Creating package: $ARCHIVE_NAME"
cp "$MANIFEST" "$PKG_DIR/.PACKAGE"

# Create reproducible tar archive compressed with zstd
tar --sort=name --owner=root:0 --group=root:0 \
    -C "$PKG_DIR" -cf - . | zstd -19 -o "$OUTPUT_DIR/$ARCHIVE_NAME"

echo "[byol-pack] Package generated at $OUTPUT_DIR/$ARCHIVE_NAME"

Step 3: Indexing the Repository (byol-index)

A repository indexing script parses all .byol.tar.zst packages in the directory, extracts their .PACKAGE manifest, computes SHA256 checksums, and outputs index.json:

#!/bin/sh
# byol-index: Generates repository metadata catalog
set -eu

REPO_DIR="$1"
cd "$REPO_DIR"

echo "{\"packages\": {" > index.json.tmp
FIRST=1

for pkg in *.byol.tar.zst; do
    [ -f "$pkg" ] || continue
    [ "$FIRST" -eq 0 ] && echo "," >> index.json.tmp
    FIRST=0

    # Extract manifest without decompressing entire package
    MANIFEST=$(tar --zstd -xf "$pkg" .PACKAGE -O)
    NAME=$(echo "$MANIFEST" | grep '^name =' | cut -d '"' -f 2)
    VER=$(echo "$MANIFEST" | grep '^version =' | cut -d '"' -f 2)
    SHA256=$(sha256sum "$pkg" | awk '{print $1}')
    SIZE=$(stat -c%s "$pkg")

    cat <<JSON >> index.json.tmp
    "$NAME": {
      "name": "$NAME",
      "version": "$VER",
      "filename": "$pkg",
      "sha256": "$SHA256",
      "size": $SIZE
    }
JSON
    rm -f .PACKAGE
done

echo "}}" >> index.json.tmp
mv index.json.tmp index.json
echo "[byol-index] Repository metadata catalog generated at $REPO_DIR/index.json"

Step 4: Serving Over HTTP

To test your custom repository locally:

$ python3 -m http.server 8080 --directory /srv/repo/x86_64

Your package manager can now fetch and verify packages via http://localhost:8080/index.json.