android-emulator: api36-v2 — marker-file install idempotency + retries
Some checks failed
ci/woodpecker/push/k8s-portal Pipeline failed
ci/woodpecker/push/postmortem-todos Pipeline was successful
ci/woodpecker/push/pve-nfs-exports-sync Pipeline was successful
ci/woodpecker/push/build-cli Pipeline was successful
ci/woodpecker/push/registry-config-sync Pipeline was successful
ci/woodpecker/push/build-ci-image Pipeline was successful
ci/woodpecker/push/default Pipeline failed

First boot crashed mid-SDK-install, and the dir-existence check then
skipped reinstall forever: avdmanager saw the partial tree and died with
'Valid system image paths are: null' (CrashLoopBackOff). v2 tracks
install completion with a marker file written only after sdkmanager
succeeds + package.xml exists, wipes partial system-image trees before
reinstalling, and retries sdkmanager 3x.
This commit is contained in:
Viktor Barzin 2026-06-11 20:59:08 +00:00
parent 3fac45febc
commit 5e8a988858
3 changed files with 22 additions and 7 deletions

View file

@ -4,8 +4,8 @@
# cmdline-tools and the native libraries the emulator needs at runtime.
#
# Rebuild + push (rare — only when tool/library versions bump):
# docker build -t forgejo.viktorbarzin.me/viktor/android-emulator:api36-v1 .
# docker push forgejo.viktorbarzin.me/viktor/android-emulator:api36-v1
# docker build -t forgejo.viktorbarzin.me/viktor/android-emulator:api36-v2 .
# docker push forgejo.viktorbarzin.me/viktor/android-emulator:api36-v2
FROM eclipse-temurin:17-jdk-jammy
ENV DEBIAN_FRONTEND=noninteractive

View file

@ -15,13 +15,28 @@ SCREEN_GEOMETRY="${SCREEN_GEOMETRY:-1080x2280x24}"
mkdir -p "$ANDROID_USER_HOME"
# --- SDK packages on the PVC (idempotent; first boot downloads ~2.5GB) ------
if [ ! -x /sdk/platform-tools/adb ] || [ ! -x /sdk/emulator/emulator ] || \
[ ! -d "/sdk/system-images/android-${API_LEVEL}" ]; then
echo "Installing SDK packages into /sdk (first boot)..."
# A directory existing is NOT proof of a complete install (an interrupted
# sdkmanager leaves partial trees that avdmanager rejects with "Valid system
# image paths are: null") — so completion is tracked with a marker file
# written only after sdkmanager succeeds.
MARKER="/sdk/.sdk-install-complete-android-${API_LEVEL}"
if [ ! -f "$MARKER" ]; then
echo "Installing SDK packages into /sdk (first boot or prior partial install)..."
rm -rf "/sdk/system-images/android-${API_LEVEL}"
# (yes || true): yes dies of SIGPIPE (141) when sdkmanager stops reading,
# which set -o pipefail would otherwise turn into a fatal error.
(yes || true) | sdkmanager --sdk_root=/sdk --licenses >/dev/null
sdkmanager --sdk_root=/sdk "platform-tools" "emulator" "$SYSTEM_IMAGE"
for attempt in 1 2 3; do
if sdkmanager --sdk_root=/sdk "platform-tools" "emulator" "$SYSTEM_IMAGE"; then
break
fi
echo "sdkmanager attempt $attempt failed; retrying in 10s..." >&2
[ "$attempt" = 3 ] && exit 1
sleep 10
done
# the package manifest is what avdmanager actually validates against
test -f "/sdk/system-images/android-${API_LEVEL}/google_apis/x86_64/package.xml"
touch "$MARKER"
fi
# --- AVD (idempotent) --------------------------------------------------------