Jump to content

RidgeRun Yocto Developer Guide - Yocto SState Cache Server Builder Client

From RidgeRun Developer Wiki

Follow us on: YouTube Twitter LinkedIn Email Share this page

Share This Page


NVIDIA partner logo NXP partner logo




Yocto Sstate-Cache Builder Client

In this wiki you'll learn how to consume a Yocto sstate-cache mirror to download pre-built artifacts instead of compiling from scratch, reducing build times from hours to minutes.

CI/CD Platform: this project uses GitLab CI/CD Pipelines as its automation engine. All build, publish, and cleanup steps are defined in .gitlab-ci.yml and executed by GitLab Runners.

Overview

The builder client performs a Yocto build that is configured to fetch cached artifacts from a remote sstate-cache mirror. It also pins layer versions to the exact commits that were used when the cache was generated, ensuring full reproducibility and maximum cache hit rates.

How It Works

builder_client (this repo)
   │
   ├── 1. trigger_builder stage → triggers builder repo to refresh the cache
   │
   ├── 2. build stage
   │     ├── Clone builder repo (contains CI scripts)
   │     ├── Clone layers
   │     ├── Checkout to cached layer versions (pinned commits)
   │     ├── Configure SSTATE_MIRRORS in local.conf
   │     └── bitbake core-image-base (downloads from mirror instead of compiling)
   │
   └── 3. clean stage → removes workspace

Prerequisites

  • A GitLab runner tagged yocto-sstate-cache with:
    • Docker executor using the dchvs/yocto:scarthgap image.
    • Read access to the cached versions directory at /mnt/fat/var/yocto/mirror/<release>/cached_versions/.
    • The workspace directory /workdir/builder_client/ owned by ridgerun (UID 1000, GID 1000).
  • A populated sstate-cache mirror (generated by the builder project).
  • CI/CD variables DEPLOY_USER and DEPLOY_TOKEN configured in GitLab for cloning the builder repository.

Usage

1. Set CI/CD Variables

Configure these in GitLab → Settings → CI/CD → Variables:

Variable Scope Description
DEPLOY_USER Protected GitLab username with access to the builder repo.
DEPLOY_TOKEN Protected/Masked GitLab deploy token for the builder repo.

The following variables have sensible defaults in .gitlab-ci.yml (see Appendix A.1) but can be overridden:

Variable Default Description
YOCTO_RELEASE scarthgap Yocto release branch.
WORKSPACE /workdir/builder_client Working directory.
LAYERS_DIR /workdir/builder_client/layers Where layers are cloned.
CACHED_VERSIONS_DIR /mnt/fat/var/yocto/mirror/scarthgap/cached_versions Path to layer version snapshots from the builder.
SSTATE_CACHE_DIR /mnt/fat/var/yocto/mirror/scarthgap/sstate-cache Local path to the sstate-cache mirror.
SSTATE_MIRRORS_URL_BASE https://yocto_server/mirror Base URL for health checks.
SSTATE_MIRRORS_URL https://yocto_server/mirror/scarthgap/sstate-cache URL BitBake uses to download cached artifacts.

2. Trigger the Pipeline

The pipeline can be triggered in three ways:

  • Schedule (schedule): Set up a recurring schedule in GitLab → CI/CD → Schedules.
  • Downstream trigger (pipeline): Triggered by another project.
  • Manual (web): Run from the GitLab UI.

3. Pipeline Stages

Stage 1: trigger

Triggers the builder pipeline to regenerate the sstate-cache mirror with the latest layer sources. Uses strategy: depend, so this stage waits for the builder to finish successfully before proceeding.

Stage 2: build

  1. Clones the builder repository (which contains the CI helper scripts: check_sstate_server.sh, verify_workspace_ownership.sh).
  2. Validates the environment:
    • check_sstate_server.sh — confirms the mirror server is reachable.
    • verify_workspace_ownership.sh — ensures correct file ownership.
  3. Clones all required Yocto layers at the YOCTO_RELEASE branch.
  4. Pins layers to cached versions:
    • Reads the most recent cached_versions_<release>_<date>.txt file.
    • Checks out each layer to the exact commit hash recorded by the builder.
    • This ensures the local layer state matches what was used to generate the cache, maximizing sstate hits.
  5. Initializes the BitBake environment and registers all layers.
  6. Appends the sstate-cache mirror configuration to local.conf:
    #
    # RidgeRun sstate-cache mirror
    #
    SSTATE_MIRRORS = "file://.* ${SSTATE_MIRRORS_URL}/PATH;downloadfilename=PATH"
  7. Runs bitbake core-image-base for jetson-agx-orin-devkit and reports the sstate summary (cache hit/miss ratio).

CI helper scripts (check_sstate_server.sh, verify_workspace_ownership.sh) are provided by the builder repository, which is cloned at the start of the build stage.

Stage 3: clean

Removes the workspace directory. Runs regardless of build outcome (when: always).

4. Interpreting the Sstate Summary

The build output includes a line like:

Sstate summary: Wanted 1234 Found 1200 Missed 34 Current 0 (97% match, 3% missed)
  • Found: Artifacts successfully downloaded from the mirror.
  • Missed: Artifacts that had to be built locally (layer drift, new recipes, etc.).
  • A high match rate (>90%) indicates the cache is effective.

5. Adding a New Machine Target

Add another bitbake line in the build stage:

- MACHINE=jetson-agx-orin-devkit            bitbake core-image-base | grep "Sstate summary"
- MACHINE=<new-machine>                     bitbake core-image-base | grep "Sstate summary"

The new machine must also be built by the builder project for its artifacts to exist in the mirror.

6. Using the Mirror in a Local Build

You can use the same sstate-cache mirror outside of CI. Add this to your local.conf:

BB_SIGNATURE_HANDLER = "OEBasicHash"
BB_HASHSERVE = ""
SSTATE_MIRRORS = "file://.* https://yocto_server/mirror/scarthgap/sstate-cache/PATH;downloadfilename=PATH"

Then ensure your layers are checked out to the same commits listed in the latest cached_versions_*.txt file for maximum cache hits.

File Reference

File Purpose
.gitlab-ci.yml Main pipeline definition.

CI helper scripts (check_sstate_server.sh, verify_workspace_ownership.sh) are provided by the builder repository, which is cloned at the start of the build stage.

Troubleshooting

Symptom Cause Fix
ERROR: the sstate-cache server ... is not reachable Mirror server is down. Check Nginx and SSTATE_MIRRORS_URL_BASE.
No cached versions file found Builder has never run, or CACHED_VERSIONS_DIR is wrong. Run the builder pipeline first.
Low sstate hit rate (<50%) Layers drifted from cached versions. Verify the cached versions checkout ran successfully. Rebuild the cache via the builder.
Error: /workdir/builder_client is not owned by ridgerun Wrong volume permissions. Run chown 1000:1000 /workdir/builder_client on the runner host.
trigger_builder stage fails Missing DEPLOY_USER/DEPLOY_TOKEN or wrong branch. Verify CI/CD variables and that the builder repo has the YOCTO_RELEASE branch.

Appendix A: Source Code Reference

A.1 .gitlab-ci.yml

image: dchvs/yocto:scarthgap

stages:
  - trigger
  - build
  - clean

default:
  tags:
    - yocto-sstate-cache

variables:
  USER: "ridgerun"
  UID: "1000"
  GID: "1000"
  YOCTO_RELEASE: "scarthgap"
  WORKSPACE: "/workdir/builder_client"
  LAYERS_DIR: "/workdir/builder_client/layers"
  CACHED_VERSIONS_DIR: "/mnt/fat/var/yocto/mirror/scarthgap/cached_versions"
  SSTATE_CACHE_DIR: "/mnt/fat/var/yocto/mirror/scarthgap/sstate-cache"
  SSTATE_MIRRORS_URL_BASE: "https://yocto_server/mirror"
  SSTATE_MIRRORS_URL: "https://yocto_server/mirror/scarthgap/sstate-cache"

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "schedule"
    - if: $CI_PIPELINE_SOURCE == "pipeline"
    - if: $CI_PIPELINE_SOURCE == "web"

build:
  stage: build
  timeout: 2h
  script:
    - bash

    - mkdir -p $WORKSPACE
    - cd $WORKSPACE

    - git clone https://${DEPLOY_USER}:${DEPLOY_TOKEN}@gitlab.ridgerun.com/tex/yocto/builder -b $YOCTO_RELEASE .

    - $WORKSPACE/.gitlab-ci/check_sstate_server.sh
    - $WORKSPACE/.gitlab-ci/verify_workspace_ownership.sh

    - mkdir -p $LAYERS_DIR/
    - cd $LAYERS_DIR/
    - git clone https://git.yoctoproject.org/poky -b $YOCTO_RELEASE
    - git clone https://git.openembedded.org/meta-openembedded -b $YOCTO_RELEASE
    - git clone https://github.com/OE4T/meta-tegra -b $YOCTO_RELEASE
    - git clone https://github.com/OE4T/meta-tegra-community -b $YOCTO_RELEASE
    - git clone https://git.yoctoproject.org/meta-virtualization -b $YOCTO_RELEASE
    - git clone https://git.yoctoproject.org/meta-selinux -b $YOCTO_RELEASE

    - |
      NEWEST_CACHED_VERSIONS_FILE=$(ls -t "$CACHED_VERSIONS_DIR"/cached_versions_${YOCTO_RELEASE}_*.txt 2>/dev/null | head -1)
      if [ -n "$NEWEST_CACHED_VERSIONS_FILE" ]; then
        echo "Using cached versions from: $NEWEST_CACHED_VERSIONS_FILE"
        while IFS=': ' read -r LAYER_NAME LAYER_HASH; do
          if [ -d "$LAYERS_DIR/$LAYER_NAME" ]; then
            git -C "$LAYERS_DIR/$LAYER_NAME" checkout "$LAYER_HASH"
          fi
        done < "$NEWEST_CACHED_VERSIONS_FILE"
      else
        echo "No cached versions file found"
        exit 1
      fi

    - cd $WORKSPACE
    - . $LAYERS_DIR/poky/oe-init-build-env $WORKSPACE/build/

    - bitbake-layers add-layer $LAYERS_DIR/poky/meta
    - bitbake-layers add-layer $LAYERS_DIR/poky/meta-poky
    - bitbake-layers add-layer $LAYERS_DIR/poky/meta-yocto-bsp
    - bitbake-layers add-layer $LAYERS_DIR/poky/meta-skeleton
    - bitbake-layers add-layer $LAYERS_DIR/meta-openembedded/meta-oe
    - bitbake-layers add-layer $LAYERS_DIR/meta-openembedded/meta-python
    - bitbake-layers add-layer $LAYERS_DIR/meta-openembedded/meta-networking
    - bitbake-layers add-layer $LAYERS_DIR/meta-openembedded/meta-gnome
    - bitbake-layers add-layer $LAYERS_DIR/meta-openembedded/meta-multimedia
    - bitbake-layers add-layer $LAYERS_DIR/meta-openembedded/meta-xfce
    - bitbake-layers add-layer $LAYERS_DIR/meta-openembedded/meta-initramfs
    - bitbake-layers add-layer $LAYERS_DIR/meta-openembedded/meta-perl
    - bitbake-layers add-layer $LAYERS_DIR/meta-openembedded/meta-filesystems
    - bitbake-layers add-layer $LAYERS_DIR/meta-openembedded/meta-webserver
    - bitbake-layers add-layer $LAYERS_DIR/meta-virtualization

    - bitbake-layers add-layer $LAYERS_DIR/meta-tegra
    - bitbake-layers add-layer $LAYERS_DIR/meta-tegra-community

    - |
      cat >> $WORKSPACE/build/conf/local.conf << EOF
      #
      # RidgeRun sstate-cache mirror
      #
      SSTATE_MIRRORS = "file://.* ${SSTATE_MIRRORS_URL}/PATH;downloadfilename=PATH"
      EOF

    - MACHINE=jetson-agx-orin-devkit            bitbake core-image-base | grep "Sstate summary"

    - echo "Build succeded"

trigger_builder:
  stage: trigger
  trigger:
    project: tex/yocto/builder
    branch: $YOCTO_RELEASE
    strategy: depend

cleanup_task:
  stage: clean
  when: always
  script:
    - |
      if [ -n "$WORKSPACE" ]; then
        rm -rf $WORKSPACE/
      fi




Cookies help us deliver our services. By using our services, you agree to our use of cookies.