- Mount each student's own App Lab files into the app container so the agent can read/fix them: mount-user-workspace.sh binds ~/sketches (rw), ~/ArduinoApps/* (rw), ~/Arduino/libraries (ro) under /app/workspace via a root oneshot ordered before arduino-app-cli.service (the /app bind is rprivate, so binds must precede container start; App Lab has no app.yaml volumes field). Wired into provision-node-app, provision-fleet (systemd, best-effort sudo), and package-onboard-app (bundled under host-setup/). - uno-q-hardware skill: document the mux-aware i2c_scan output format (0x70:mux, 0x70.2=0x1d) and tell the agent its student's files live at /app/workspace. See USER-WORKSPACE.md. Co-Authored-By: Claude Opus 4.8 <[email protected]>
66 lines
2.7 KiB
Bash
Executable File
66 lines
2.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Expose each participant's own Arduino files INTO the apess-onboard app container
|
|
# so the agent can read, correct, and complete their implementation.
|
|
#
|
|
# WHY THIS EXISTS
|
|
# The App Lab container only bind-mounts the app's own directory
|
|
# (/home/arduino/ArduinoApps/apess-onboard -> /app). A student's real work lives
|
|
# elsewhere and is invisible to the agent:
|
|
# ~/sketches/<name>/<name>.ino App Lab "sketch editor" projects (primary)
|
|
# ~/ArduinoApps/<name>/ full App Lab apps
|
|
# ~/Arduino/libraries/ installed libraries
|
|
# App Lab has NO volumes field in app.yaml and generates the compose itself, so
|
|
# we can't declare these there. Instead we bind the user paths UNDERNEATH the app
|
|
# dir (which /app already maps). The catch: the /app bind is `rprivate`, so a
|
|
# submount added AFTER the container starts does NOT propagate in — the binds must
|
|
# exist BEFORE the app container is created. Hence a root oneshot ordered
|
|
# Before=arduino-app-cli.service (see apess-user-workspace.service).
|
|
#
|
|
# RESULT INSIDE THE CONTAINER
|
|
# /app/workspace/sketches/ <- ~/sketches (rw)
|
|
# /app/workspace/apps/<name>/ <- ~/ArduinoApps/<name> (rw, minus ourselves)
|
|
# /app/workspace/libraries/ <- ~/Arduino/libraries (ro, reference)
|
|
#
|
|
# Idempotent — safe to re-run. Requires root (mount(2) is privileged).
|
|
set -euo pipefail
|
|
|
|
USER_HOME=${USER_HOME:-/home/arduino}
|
|
APP_DIR=${APP_DIR:-$USER_HOME/ArduinoApps/apess-onboard}
|
|
WS="$APP_DIR/workspace"
|
|
SELF=$(basename "$APP_DIR")
|
|
|
|
if [ "$(id -u)" -ne 0 ]; then
|
|
echo "must run as root (mount is privileged) — try: sudo $0" >&2
|
|
exit 1
|
|
fi
|
|
|
|
bind() { # src dst [ro]
|
|
local src=$1 dst=$2 ro=${3:-}
|
|
if [ ! -d "$src" ]; then echo "skip (no source dir): $src"; return 0; fi
|
|
mkdir -p "$dst"
|
|
if mountpoint -q "$dst"; then echo "already mounted: $dst"; return 0; fi
|
|
mount --bind "$src" "$dst"
|
|
[ "$ro" = ro ] && mount -o remount,ro,bind "$dst"
|
|
echo "mounted: $src -> $dst${ro:+ (ro)}"
|
|
}
|
|
|
|
mkdir -p "$WS" "$WS/apps"
|
|
chown "$(stat -c '%u:%g' "$USER_HOME")" "$WS" "$WS/apps" 2>/dev/null || true
|
|
|
|
bind "$USER_HOME/sketches" "$WS/sketches"
|
|
bind "$USER_HOME/Arduino/libraries" "$WS/libraries" ro
|
|
|
|
# Each OTHER App Lab app — skip ourselves so we don't recursively self-mount.
|
|
if [ -d "$USER_HOME/ArduinoApps" ]; then
|
|
for d in "$USER_HOME/ArduinoApps"/*/; do
|
|
[ -d "$d" ] || continue
|
|
name=$(basename "$d")
|
|
[ "$name" = "$SELF" ] && continue
|
|
bind "$d" "$WS/apps/$name"
|
|
done
|
|
fi
|
|
|
|
echo "workspace ready: $WS"
|
|
echo "note: a NEW sibling app created after boot needs a re-run + app restart to appear"
|
|
echo " (rprivate /app); new *sketches* in ~/sketches appear live, no restart needed."
|