Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
272ac94
docs(ci): add build-and-test-libremesh workflow documentation
ccasanueva7 Apr 29, 2026
e370db1
docs(ci-runner): add workflows table and troubleshooting section
ccasanueva7 Apr 29, 2026
d73f295
docs(labgrid): document helper scripts generate_places_yaml, resolve_…
ccasanueva7 Apr 29, 2026
e19b31f
docs(rack): add CI workflow quick reference section
ccasanueva7 Apr 29, 2026
ce95110
docs(firmware): add pre-built firmwares directory overview
ccasanueva7 Apr 29, 2026
317a120
docs(som): add CI firmware build workflow to automation section
ccasanueva7 Apr 29, 2026
b32008b
docs(rack): add switch and power scripts reference section
ccasanueva7 Apr 29, 2026
a66039e
docs(running-tests): add section on using CI-built firmware artifacts
ccasanueva7 Apr 29, 2026
e62534f
docs(developer): add section on triggering CI workflow from GitHub
ccasanueva7 Apr 29, 2026
003008b
docs(diseno): add lime-packages CI firmware build flow page
ccasanueva7 Apr 29, 2026
05e4489
docs(diseno): add lime-packages CI hardware test flow page
ccasanueva7 Apr 29, 2026
1247a95
docs(nav): add lime-packages CI flow pages to mkdocs nav
ccasanueva7 Apr 29, 2026
b1ad93b
docs(index): add quick actions table to home page
ccasanueva7 Apr 29, 2026
08d1fd3
docs(integration): add CI workflow entries to design reading guide
ccasanueva7 Apr 29, 2026
4675dc0
docs(demos): add index table to video demos page
ccasanueva7 Apr 29, 2026
5383aa6
docs(new-lab): add CI build and test link to related pages
ccasanueva7 Apr 29, 2026
824eb06
docs(routine): add CI runner verification section
ccasanueva7 Apr 29, 2026
4fbbe05
docs(operar): add virtual mesh local setup guide from vms/README
ccasanueva7 Apr 29, 2026
e693e99
Merge branch 'develop' into docs/ci-workflow
ccasanueva7 May 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions docs/configuracion/ci-runner.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,28 @@ To move the runner from one repo to another (or user to org):
## 6. Ownership transfer (if needed in near future)

When the repo transfers to an org, attached runners move with it. The systemd service name may still reference the old owner; this should not affect operation.

---

## 7. Workflows that use this runner

The following workflows in `fcefyn-testbed/fcefyn_testbed_utils` target this runner with `runs-on: [self-hosted, testbed-fcefyn]`:

| Workflow | Trigger | What it does on the runner |
|----------|---------|---------------------------|
| `build-and-test-libremesh.yml` | Manual (`workflow_dispatch`) | Downloads firmware artifact built on GitHub-hosted runners, reserves the DUT via labgrid, loads firmware, and runs libremesh-tests with pytest. |

The `build` job of that workflow runs on GitHub-hosted runners (no lab hardware needed). Only the `flash_and_test` job lands on this runner.

See [CI: Build & Test](../operar/ci-build-and-test.md) for full usage instructions.

---

## 8. Troubleshooting

| Symptom | Cause | Fix |
|---------|-------|-----|
| Runner shows **Offline** in GitHub | Service stopped | `sudo systemctl restart actions.runner.*` |
| `flash_and_test` job queued but never starts | Runner offline or label mismatch | Check runner labels include `testbed-fcefyn` |
| `PermissionError` on labgrid coordinator | Wrong `/etc/labgrid` ownership | See §4 above |
| Job fails at "Reserve DUT" | DUT locked by a previous run | `labgrid-client -p <place> unlock` |
5 changes: 5 additions & 0 deletions docs/demos.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

This section collects demo videos showing various operations on the testbed.

| Demo | Topic |
|------|-------|
| [Remote access to the HIL testbed](#remote-access-to-the-hil-testbed) | Administrator access and lab infrastructure recovery |
| [Developer remote access through Labgrid](#developer-remote-access-through-labgrid) | Developer SSH + multi-node mesh test run |

---

## Remote access to the HIL testbed
Expand Down
3 changes: 3 additions & 0 deletions docs/diseno/integration-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,6 @@ sequenceDiagram
| Set up the WireGuard tunnel and contribute hardware to openwrt-tests | [openwrt-tests onboarding](openwrt-tests-onboarding.md) |
| VLAN design, `switch-vlan` CLI, switch configuration | [Lab architecture](lab-architecture.md) |
| Virtual mesh tests with QEMU and vwifi | [Virtual mesh](virtual-mesh.md) |
| Build and test lime-packages from a PR via CI | [CI: Build & Test](../operar/ci-build-and-test.md) |
| Understand the lime-packages fork CI build pipeline | [lime-packages CI build](lime-packages-ci-flow.md) |
| Understand the lime-packages fork CI test pipeline | [lime-packages CI tests](lime-packages-test-flow.md) |
2 changes: 2 additions & 0 deletions docs/diseno/lime-packages-ci-flow.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

# lime-packages CI: firmware build pipeline

How the **fcefyn-testbed/lime-packages** fork builds per-device LibreMesh
Expand Down Expand Up @@ -271,3 +272,4 @@ consumes this artifact.
To add a new board to this pipeline see the [add-device guide][add].

[add]: lime-packages-add-device.md

2 changes: 1 addition & 1 deletion docs/diseno/lime-packages-test-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,4 +376,4 @@ The workflow only references `environment: physical-lab` by name. All
governance (teams, rulesets, environment reviewers) lives in GitHub
repository/org settings, not in the YAML. Any organisation adopting
this workflow creates its own `physical-lab` environment and teams
without modifying the workflow file.
without modifying the workflow file.
1 change: 1 addition & 0 deletions docs/diseno/new-lab-contribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,4 @@ A lab can contribute to both paths at once: the infrastructure is shared. Scenar
- [Switch](../configuracion/switch-config.md) - VLAN layout, `switch.conf` multi-user setup, `switch-vlan` invocation.
- [Lab architecture](lab-architecture.md) - per-lab coordinator, VLAN scheduling, locking.
- [CI runner](../configuracion/ci-runner.md) - self-hosted runner setup (Scenario B).
- [CI: Build & Test](../operar/ci-build-and-test.md) - automated firmware build and test workflow using the self-hosted runner.
13 changes: 13 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,16 @@ Relationship between orchestration host, switch, gateway, DUTs, power, and seria
![High-level diagram of the testbed and main components](img/diagrams/general-design-overview.png)

The design builds on the **remote lab** model from [openwrt-tests](https://github.com/aparcar/openwrt-tests), but scope is not limited to **adding devices** to that network. It also **reuses and extends** the approach with **local infrastructure**, along the same axes (orchestration, network, power, serial) with a focus on **LibreMesh** testing.

---

## Quick actions

| I want to… | Go to |
|---|---|
| Run tests on lab hardware from my machine | [Developer quickstart](operar/developer-remote-access.md) |
| Build a LibreMesh firmware and test it automatically | [CI: Build & Test](operar/ci-build-and-test.md) |
| SSH into a DUT | [SSH access to DUTs](operar/dut-ssh-access.md) |
| Check the rack layout and device IPs | [Rack quick reference](operar/rack-cheatsheets.md) |
| Build firmware manually | [Build firmware](operar/build-firmware-manual.md) |
| Add a new device to the lab | [Adding a DUT](operar/dut-onboarding.md) |
30 changes: 30 additions & 0 deletions docs/operar/build-firmware-manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,34 @@ Firmware appears under `bin/` as in standard OpenWrt.

---

## Pre-built firmwares (`firmwares/`)

The `firmwares/` directory in this repo contains pre-built images ready to use in the lab without compiling. Useful for quick tests or when the build pipeline is unavailable.

```
firmwares/
├── belkin_rt3200/
│ ├── libremesh/ ← LibreMesh images (initramfs + sysupgrade)
│ └── openwrt/ ← Stock OpenWrt images
├── bananapi_bpi-r4/
├── librerouter_librerouter-v1/
├── openwrt_one/
├── tplink-wdr3500/
└── qemu/
```

Each device folder has:

| File pattern | Purpose |
|---|---|
| `*initramfs*.bin` / `*initramfs*.itb` | TFTP boot — loads into RAM, flash untouched |
| `*sysupgrade*.bin` / `*sysupgrade*.itb` | Flash write via `sysupgrade` |
| `*sdcard*.img.gz` | SD card image (Banana Pi R4 only) |

To use a pre-built initramfs in tests, set `LG_IMAGE` to the file path. See [Running tests](lab-running-tests.md).

---

## Automatic builds via PR (lime-packages fork)

The **fcefyn-testbed/lime-packages** fork includes `.github/workflows/build-firmware.yml`: on pull requests (and manual dispatch), GitHub Actions builds a **local lime_packages feed** with the OpenWrt SDK, then one **firmware image per row** in `.github/ci/targets.yml` using ImageBuilder. Successful runs upload **`firmware-<device>.*`** and **`lime-feed-<arch>`** artifacts.
Expand All @@ -192,3 +220,5 @@ For architecture, caching, and feed indexing details, see:
- [lime-packages CI: hardware tests](../diseno/lime-packages-test-flow.md) (downstream **libremesh-tests** on the `testbed-fcefyn` self-hosted runner)

Manual procedures above still apply when you build outside CI or need a custom `menuconfig` / full Buildroot tree.

For the automated CI workflow that builds and tests firmware directly in this repo, see [CI: Build & Test](ci-build-and-test.md).
167 changes: 167 additions & 0 deletions docs/operar/ci-build-and-test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# CI: Build & Test LibreMesh

This workflow builds a LibreMesh firmware image from source and runs automated
tests on a physical device in the FCEFYN lab.

It is triggered **manually** — it does not run automatically on every commit.
You decide when to run it and with which parameters.

---

## When to use it

Run this workflow when you want to:

- Test a specific version or branch of
[lime-packages](https://github.com/libremesh/lime-packages) on real hardware
- Verify that a set of packages installs and boots correctly on a lab device
- Produce a firmware image with custom packages for a specific device

---

## How to run it

1. Go to the repository on GitHub
2. Click the **Actions** tab
3. Select **Build LibreMesh and Test on DUT** in the left panel
4. Click **Run workflow**
5. Fill in the inputs (see below) and click the green **Run workflow** button

---

## Inputs

| Input | Required | Default | Description |
|-------|----------|---------|-------------|
| `duts` | yes | `belkin_rt3200` | Device(s) to build and test. Comma-separated. Use `all` for every lab device. |
| `lime_ref` | yes | `v2024.1` | Branch, tag, or commit SHA of lime-packages to build from. |
| `openwrt_version` | no | `23.05.5` | OpenWrt version to use. Must be compatible with `lime_ref`. |
| `extra_packages` | no | _(empty)_ | Space-separated packages to add or remove from the base set. Prefix with `-` to remove. Example: `luci-app-dawn -lime-proto-batadv` |
| `config_file` | no | _(empty)_ | Repo-relative path to a config file to inject as `/etc/config/<name>` in the firmware. Example: `firmware/configs/belkin_rt3200.conf` |

### Supported devices

| `duts` value | Hardware | OpenWrt target |
|---|---|---|
| `belkin_rt3200` | Belkin RT3200 / Linksys E8450 | `mediatek/mt7622` |
| `openwrt_one` | OpenWrt One | `mediatek/filogic` |
| `bananapi_r4` | Banana Pi R4 | `mediatek/filogic` |
| `librerouter` | LibreRouter v1 | `ath79/generic` |

### OpenWrt / lime-packages compatibility

| `openwrt_version` | Compatible `lime_ref` |
|---|---|
| `23.05.5` | `v2024.1` |
| `24.10.5` | `master` or newer tags |
| `25.12.0` | `master` or newer tags |

---

## What happens when you run it

The workflow has three jobs that run in sequence:

### 1. Resolve matrix (~5 seconds, GitHub-hosted)

Parses the `duts` input and builds a job matrix so each device runs in
parallel. For example, `"belkin_rt3200,librerouter"` becomes two independent
build jobs.

### 2. Build (~20–25 min per device, GitHub-hosted)

For each device, two Docker containers run back to back:

**Step 1 — OpenWrt SDK**
Downloads `ghcr.io/openwrt/sdk:<target>-<subtarget>-v<openwrt_version>` and
compiles the lime-packages listed below from source, using the exact git ref
you specified in `lime_ref`. This is the slow step.

Packages compiled:

- `lime-system`
- `lime-proto-babeld`
- `lime-proto-batadv`
- `lime-proto-anygw`
- `lime-hwd-openwrt-wan`
- `lime-app`
- `shared-state` + `shared-state-babeld_hosts` + `shared-state-bat_hosts` + `shared-state-nodes_and_links`
- `babeld-auto-gw-mode`
- anything you add via `extra_packages`

**Step 2 — OpenWrt ImageBuilder**
Downloads `ghcr.io/openwrt/imagebuilder:<target>-<subtarget>-v<openwrt_version>`
and assembles the compiled `.ipk` packages into a complete firmware image
(`.bin` or `.itb`). This step takes ~2–3 minutes.

The firmware is uploaded as a GitHub Actions artifact named
`firmware-<dut>-<lime_ref>-<short_sha>` and kept for 7 days.

### 3. Flash and test (lab self-hosted runner, `testbed-fcefyn`)

Runs on the physical T430 machine in the FCEFYN lab.

1. Downloads the firmware artifact from step 2
2. Reserves the target device via [labgrid](https://labgrid.readthedocs.io)
(waits if the device is busy)
3. Loads the firmware onto the device
4. Runs the [libremesh-tests](https://github.com/fcefyn-testbed/libremesh-tests)
test suite with pytest
5. Releases the device when done (even if tests fail)

---

## Examples

**Test the latest stable lime-packages on the Belkin RT3200:**
```
duts: belkin_rt3200
lime_ref: v2024.1
openwrt_version: 23.05.5
```

**Test a feature branch on all devices:**
```
duts: all
lime_ref: my-feature-branch
openwrt_version: 24.10.5
```

**Add a package and remove another:**
```
duts: belkin_rt3200
lime_ref: v2024.1
extra_packages: luci-app-dawn -lime-proto-batadv
```

**Inject a custom network config:**
```
duts: belkin_rt3200
lime_ref: v2024.1
config_file: firmware/configs/belkin_rt3200.conf
```

---

## Testing the build locally with `act`

[act](https://github.com/nektos/act) lets you run the build job on your own
machine without pushing to GitHub. Only the `build` job works locally — the
`flash_and_test` job requires physical lab hardware and is automatically
skipped.

```bash
act workflow_dispatch \
--workflows .github/workflows/build-and-test-libremesh.yml \
--job build \
--input duts="belkin_rt3200" \
--input lime_ref="v2024.1" \
--input openwrt_version="23.05.5" \
--input config_file="" \
--input extra_packages="" \
-P ubuntu-latest=catthehacker/ubuntu:act-22.04 \
--artifact-server-path /tmp/act-artifacts
```

The firmware is saved to `/tmp/act-artifacts` and to `./images/` in the repo
root (not committed).
19 changes: 18 additions & 1 deletion docs/operar/developer-remote-access.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,24 @@ ZeroTier is **not** required for developer access. It is used only by lab admins

---

## 10. Reference
## 10. Triggering the CI workflow as a developer

Instead of running tests manually, you can trigger the full build + test pipeline from GitHub:

1. Go to [fcefyn-testbed/fcefyn_testbed_utils → Actions → Build LibreMesh and Test on DUT](https://github.com/fcefyn-testbed/fcefyn_testbed_utils/actions/workflows/build-and-test-libremesh.yml)
2. Click **Run workflow** and fill in:
- `duts`: the device you want to test
- `lime_ref`: the lime-packages branch, tag, or commit you want to validate
- `openwrt_version`: must be compatible with `lime_ref`
3. The build runs on GitHub's servers (~20 min). The `flash_and_test` job then runs automatically on the lab hardware.

This does **not** require SSH access to the lab. The only requirement is having a GitHub account with access to the repository.

For full workflow documentation: [CI: Build & Test](ci-build-and-test.md).

---

## 11. Reference

- [Running tests (host-side)](lab-running-tests.md)
- [SSH access to DUTs](dut-ssh-access.md) - VLAN lifecycle and mesh SSH
Expand Down
23 changes: 23 additions & 0 deletions docs/operar/lab-routine-operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,26 @@ systemctl status arduino-relay-daemon
# Restart exporter
sudo systemctl restart labgrid-exporter
```

---

## Verify CI runner {: #verify-ci-runner }

```bash
# Check runner service
sudo systemctl status actions.runner.*

# Restart runner
sudo systemctl restart actions.runner.*
```

The runner should show **Idle** in GitHub → Settings → Actions → Runners.
If a `flash_and_test` job is queued but never starts, check that the runner is online
and that the DUT is not locked by a previous run:

```bash
labgrid-client reservations # check for stale reservations
labgrid-client -p <place> unlock # release if needed
```

See [CI runner](../configuracion/ci-runner.md) for full setup and troubleshooting.
18 changes: 18 additions & 0 deletions docs/operar/lab-running-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,24 @@ The test suite locates `labnet.yaml` via `LABNET_PATH`, `OPENWRT_TESTS_DIR/labne

---

## Using CI-built firmware in tests

The `build-and-test-libremesh.yml` workflow builds a firmware artifact and runs `flash_and_test` automatically. If you want to run the tests manually with a firmware built by CI:

1. Go to GitHub → Actions → **Build LibreMesh and Test on DUT** → select a run
2. Download the artifact `firmware-<dut>-<lime_ref>-<sha>`
3. Extract the `.bin` or `.itb` file and point `LG_IMAGE` to it:

```bash
LG_PLACE=labgrid-fcefyn-belkin_rt3200_1 \
LG_IMAGE=/path/to/openwrt-23.05.5-mediatek-mt7622-linksys_e8450-squashfs-sysupgrade.bin \
uv run pytest tests/ -v
```

Artifacts are kept for 7 days. For automated end-to-end runs, trigger the workflow directly — it handles the full build → flash → test pipeline without manual steps.

---

## Remote coordinator access (openwrt-tests)

```bash
Expand Down
Loading
Loading