How to install PPA dependencies in Workshop

Zephyr 26.04 LTS publishes pinned Python dependencies, toolchains, and Zephyr modules through the ppa:arctic-tern/zephyr-toolchain-26.04 Personal Package Archive (PPA). A Workshop container uses the Ubuntu archive by default, so packages it installs do not carry the Canonical version pin.

This guide has two approaches. The persistent approach installs the same packages through an in-project SDK, which re-applies them on every refresh and survives workshop refresh. The ephemeral approach runs the commands in the container shell.

Prerequisites

Before starting, ensure you have these requirements satisfied:

Persistent install

The persistent approach places the same commands in an in-project SDK. The SDK setup hooks run on every workshop refresh, so the PPA and the pin survive.

On the host, create the in-project SDK directory and its files:

$ mkdir -p .workshop/zephyr-26-04-sdk/hooks
$ touch .workshop/zephyr-26-04-sdk/sdk.yaml
$ touch .workshop/zephyr-26-04-sdk/hooks/setup-base
$ chmod +x .workshop/zephyr-26-04-sdk/hooks/setup-base

Paste the PPA setup into .workshop/zephyr-26-04-sdk/hooks/setup-base. The hook runs as root, so the commands need no sudo:

#!/bin/bash
set -euo pipefail
# Add the PPA and its version pin.
add-apt-repository ppa:arctic-tern/zephyr-toolchain-26.04
apt update
apt install -y zephyr-ppa-pin-26-04
# Install the base, build-test, and run-test dependencies.
apt install -y \
  gcovr junitparser mypy openocd patool pykwalify reuse west \
  python3-anytree python3-can python3-canopen python3-cbor python3-colorama \
  python3-coverage python3-dotenv python3-intelhex python3-jsonschema \
  python3-junitparser python3-mypy python3-natsort python3-numpy \
  python3-numpy-dev python3-opencv python3-packaging python3-packaging-whl \
  python3-ply python3-psutil python3-pyelftools python3-pykwalify \
  python3-pylink-square python3-pyocd python3-pytest python3-pytest-subtests \
  python3-requests python3-semver python3-serial python3-spdx-tools \
  python3-tabulate python3-tqdm python3-yaml esptool
# Ensure hardware is detectable within the container.
usermod -a -G dialout workshop

Describe the SDK in .workshop/zephyr-26-04-sdk/sdk.yaml:

name: zephyr-26-04-sdk
summary: Zephyr 26.04 - PPA + venv

Register the in-project SDK in .workshop/zephyr-26-04.yaml:

sdks:
  ...  # existing SDKs
  - name: project-zephyr-26-04-sdk

Refresh the Workshop, then enter the shell:

$ workshop refresh zephyr-26-04
$ workshop shell zephyr-26-04

Ephemeral install

The ephemeral approach applies to the current container only. A workshop refresh removes the changes.

Open a shell in the Workshop:

$ workshop shell zephyr-26-04

Add the PPA and refresh the package index:

$ sudo add-apt-repository ppa:arctic-tern/zephyr-toolchain-26.04
$ sudo apt update

Install the version pin:

$ sudo apt install -y zephyr-ppa-pin-26-04

The pin package zephyr-ppa-pin-26-04 sets the apt preference of the PPA to 1001, higher than the 500 of the Ubuntu archive. With the pin installed, apt selects the PPA version of a package whenever both sources publish it. Install west to see the pin take effect, then check the policy:

$ sudo apt install -y west
$ apt-cache policy west

The PPA version must be the installed and candidate version, at preference 1001:

west:
  Installed: 1.5.0-1+ppa20260916171518
  Candidate: 1.5.0-1+ppa20260916171518
  Version table:
 *** 1.5.0-1+ppa20260916171518 1001
       1001 https://ppa.launchpadcontent.net/arctic-tern/zephyr-toolchain-26.04/ubuntu resolute/main amd64 Packages
        100 /var/lib/dpkg/status
     1.5.0-1 500
        500 http://archive.ubuntu.com/ubuntu resolute/universe amd64 Packages

To install every package that the PPA publishes, including the Zephyr modules and the full Zephyr SDK toolchains, install the package names from the downloaded PPA index. The install needs about 15 GB of free space. The index files are lz4-compressed, so install lz4 first:

$ sudo apt install -y lz4
$ sudo apt install -y $(
  for index in /var/lib/apt/lists/*zephyr-toolchain-26.04*_Packages*; do
    case "$index" in
      *.lz4) lz4 -dc "$index" ;;
      *)     cat "$index" ;;
    esac
  done |
  awk '/^Package:/ { print $2 }' | sort -u
)

To install only the base, build-test, and run-test dependencies, exclude the Zephyr modules and install the package list explicitly:

$ sudo apt install -y \
  gcovr junitparser mypy openocd patool pykwalify reuse west \
  python3-anytree python3-can python3-canopen python3-cbor python3-colorama \
  python3-coverage python3-dotenv python3-intelhex python3-jsonschema \
  python3-junitparser python3-mypy python3-natsort python3-numpy \
  python3-numpy-dev python3-opencv python3-packaging python3-packaging-whl \
  python3-ply python3-psutil python3-pyelftools python3-pykwalify \
  python3-pylink-square python3-pyocd python3-pytest python3-pytest-subtests \
  python3-requests python3-semver python3-serial python3-spdx-tools \
  python3-tabulate python3-tqdm python3-yaml esptool

Note

ESP32 boards need the apt copy of esptool from the PPA. The pip copy builds and flashes, but west espressif monitor requires the apt package. Both install commands include it.

Grant the container user access to serial devices:

$ sudo usermod -a -G dialout workshop

Exit the shell and re-enter it so the group change takes effect.

See also

Tutorial:

How-to:

Explanation: