Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,22 @@ jobs:
install -d -m 700 /etc/NetworkManager/system-connections
install -m 600 /src/files/dpea-eth0.nmconnection \
/etc/NetworkManager/system-connections/dpea-eth0.nmconnection
# Simulate the real RPi OS Desktop base, which already ships stock avahi.
# A bare Trixie container does NOT, so without this the avahi-dpea
# file-overwrite conflict (a missing Replaces:) stays hidden here and only
# surfaces on the real image build. Installing stock avahi first makes CI
# reproduce that conflict, which is the whole point of this gate.
apt-get install -y avahi-daemon libnss-mdns
bash /src/customize.sh
echo "===== assertions ====="
fail=0
command -v uv >/dev/null && echo "OK uv $(uv --version)" || { echo "FAIL uv"; fail=1; }
dpkg -s avahi-dpea >/dev/null 2>&1 && echo "OK avahi-dpea installed" || { echo "FAIL avahi-dpea"; fail=1; }
# It must actually take OVER the stock daemon binary, not just install
# alongside it. Replaces: transfers file ownership to avahi-dpea.
dpkg -S /usr/sbin/avahi-daemon 2>/dev/null | grep -q '^avahi-dpea:' \
&& echo "OK /usr/sbin/avahi-daemon owned by avahi-dpea" \
|| { echo "FAIL avahi-daemon binary not replaced by avahi-dpea"; fail=1; }
for line in "dtparam=i2c_arm=on" "dtparam=spi=on" "enable_uart=1" "dtoverlay=disable-bt"; do
grep -qx "$line" /boot/firmware/config.txt && echo "OK config: $line" || { echo "FAIL config: $line"; fail=1; }
done
Expand Down
17 changes: 15 additions & 2 deletions customize.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#!/bin/bash -e
#!/bin/bash
# DPEA image customizations. Runs INSIDE the mounted image chroot (see build-image.sh),
# and inside the CI validation container (see .github/workflows/validate.yml).
# Expects /tmp/packages.txt already copied in, and the NetworkManager profile
# already placed at /etc/NetworkManager/system-connections/dpea-eth0.nmconnection.

# Both callers invoke this as `bash customize.sh`, which ignores the shebang's
# flags, so set the strict flags in the body or a failed step is silently skipped.
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive

# --- shared non-Python system packages ---
Expand All @@ -25,7 +28,17 @@ grep -q '^i2c-dev' /etc/modules || echo 'i2c-dev' >> /etc/modules
AVAHI_DEB_URL="${AVAHI_DEB_URL:-https://github.com/dpengineering/avahi_0.8/releases/latest/download/avahi-dpea_0.8_arm64.deb}"
if curl -fLsS "$AVAHI_DEB_URL" -o /tmp/avahi.deb; then
apt-get install -y /tmp/avahi.deb
echo 'avahi-daemon hold' | dpkg --set-selections || true
# The stock RPi OS Desktop base already ships avahi, so the .deb must overwrite
# its files (it declares Replaces: for them). A dpkg file-overwrite conflict can
# leave the package uninstalled while apt still exits 0, so assert it is actually
# present instead of trusting the exit code.
dpkg -s avahi-dpea >/dev/null 2>&1 \
|| { echo "ERROR: avahi-dpea did not install (dpkg file conflict / missing Replaces:?)" >&2; exit 1; }
# Refresh the linker cache so the patched libavahi-core (mDNS on 5358) it just
# dropped in is the one the daemon loads, not the stock lib it overwrote.
ldconfig
# Hold both so an apt upgrade cannot restore the stock 5353 build over ours.
apt-mark hold avahi-daemon avahi-dpea >/dev/null 2>&1 || true
rm -f /tmp/avahi.deb
else
echo "ERROR: prebuilt 5358 avahi .deb not found at $AVAHI_DEB_URL" >&2
Expand Down
14 changes: 11 additions & 3 deletions hardware-smoke-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,27 @@
# real device nodes, the serial mapping, live mDNS port, and the eth0 address.

set -u
pass=0; fail=0
pass=0; fail=0; skipped=0
chk(){ if eval "$2" >/dev/null 2>&1; then echo "PASS $1"; pass=$((pass+1)); else echo "FAIL $1"; fail=$((fail+1)); fi; }
skip(){ echo "SKIP $1 ($2)"; skipped=$((skipped+1)); }

chk "uv installed" "command -v uv"
chk "I2C device node present" "ls /dev/i2c-*"
chk "SPI device node present" "ls /dev/spidev*"
chk "/dev/serial0 -> ttyAMA0" "[ \"\$(readlink -f /dev/serial0)\" = /dev/ttyAMA0 ]"
chk "avahi listening on 5358" "ss -lun | grep -q ':5358'"
chk "avahi NOT on 5353" "! ss -lun | grep -q ':5353'"
chk "eth0 holds 172.17.21.2" "ip -4 addr show eth0 | grep -q '172.17.21.2'"
# The eth0 static (172.17.21.2) only activates when the link has carrier. Running
# this over wifi with no ethernet cable is not an image defect, so SKIP rather than
# FAIL when eth0 has no carrier; plug a cable (or the direct laptop link) and re-run.
if [ "$(cat /sys/class/net/eth0/carrier 2>/dev/null || echo 0)" = 1 ]; then
chk "eth0 holds 172.17.21.2" "ip -4 addr show eth0 | grep -q '172.17.21.2'"
else
skip "eth0 holds 172.17.21.2" "no ethernet carrier; plug a cable and re-run"
fi

echo "----"
echo "$pass passed, $fail failed"
echo "$pass passed, $fail failed, $skipped skipped"
echo
echo "Manual direct-cable check: set another machine's ethernet to 172.17.21.1,"
echo "then from it: ping 172.17.21.2 and ssh <user>@172.17.21.2"
Expand Down
Loading