Files
linux-on-android-without-root/provision/init-phone.sh
T
StefanandClaude Opus 5 488851101e Vollupgrade vor alle Paketinstallationen ziehen
Termux verträgt keine Teilupgrades: die Pakete werden gegeneinander gebaut, und
ein einzeln nachinstalliertes trifft sonst auf veraltete Abhängigkeiten. Genau
daran ist proot-distro gescheitert — es trug die Shebang-Zeile python3.13,
während eine andere Fassung installiert war.

'pkg update && pkg upgrade -y' läuft deshalb jetzt an beiden Einstiegspunkten,
jeweils vor der ersten Einzelinstallation: in init-phone.sh gleich zu Beginn, und
in 00-bootstrap-termux.sh für alle, die ohne init-phone einsteigen.

--force-confold, damit die Rückfrage nach Konfigurationsdateien den Lauf nicht
mitten in der Nacht anhält. Überspringbar mit HPOS_OHNE_UPGRADE=1 für knappes
Datenvolumen; ein Fehlschlag bricht nicht ab, wird aber deutlich als erste
Stelle zum Nachsehen benannt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-10 21:48:04 +02:00

178 lines
7.6 KiB
Bash
Executable File

#!/data/data/com.termux/files/usr/bin/bash
# HPOS — Startpunkt auf dem Telefon.
#
# Dieses Skript ist absichtlich das EINZIGE, was per adb aufs Telefon kommt.
# Alles Weitere holt es sich per git. Der Grund: danach ist das Repo auf dem
# Telefon eine Arbeitskopie, keine Kopie. Aktualisieren heißt dann schlicht
#
# cd ~/hpos && git pull
#
# statt jedes Mal wieder den PC anzuwerfen und Dateien zu schieben.
#
# Aufruf in Termux:
# bash /sdcard/hpos-init.sh
# bash /sdcard/hpos-init.sh https://beispiel/anderes-repo.git
set -uo pipefail
REPO="${1:-${HPOS_REPO:-@@REPO_URL@@}}"
ZIEL="$HOME/hpos"
if [ -t 1 ]; then
C_OK=$'\033[32m'; C_WARN=$'\033[33m'; C_ERR=$'\033[31m'
C_HEAD=$'\033[1;36m'; C_DIM=$'\033[2m'; C_OFF=$'\033[0m'
else
C_OK=""; C_WARN=""; C_ERR=""; C_HEAD=""; C_DIM=""; C_OFF=""
fi
kopf() { printf '\n%s══ %s ══%s\n' "$C_HEAD" "$*" "$C_OFF"; }
ok() { printf '%s ✓%s %s\n' "$C_OK" "$C_OFF" "$*"; }
warn() { printf '%s !%s %s\n' "$C_WARN" "$C_OFF" "$*"; }
fehl() { printf '%s ✗%s %s\n' "$C_ERR" "$C_OFF" "$*"; }
hinweis() { printf '%s %s%s\n' "$C_DIM" "$*" "$C_OFF"; }
case "$REPO" in
@@*) fehl "Keine Repo-Adresse hinterlegt."
hinweis "Aufruf mit Adresse: bash /sdcard/hpos-init.sh <url>"
exit 1 ;;
esac
# Benutzernamen aus der Adresse entfernen. Lesen geht anonym; steht ein Name in
# der URL, fragt git trotzdem nach einem Passwort — auf einer Bildschirmtastatur
# eine unnötige Quälerei. Zum Schreiben braucht man ihn ohnehin nur auf dem PC.
REPO_ROH="$REPO"
REPO=$(printf '%s' "$REPO" | sed -E 's#^(https?://)[^/@]+@#\1#')
[ "$REPO" != "$REPO_ROH" ] && ANONYM=1 || ANONYM=0
kopf "HPOS — Ersteinrichtung auf dem Telefon"
hinweis "Repo: $REPO"
[ "$ANONYM" = 1 ] && hinweis "(Benutzername entfernt — gelesen wird anonym)"
# ── Vollupgrade ──────────────────────────────────────────────────────────────
# Muss VOR jedem anderen Paket laufen. Termux verträgt keine Teilupgrades: die
# Pakete werden gegeneinander gebaut, und ein einzeln nachinstalliertes trifft
# sonst auf veraltete Abhängigkeiten. Genau daran ist proot-distro gescheitert —
# es trug die Shebang-Zeile python3.13, während eine andere Fassung installiert war.
#
# Überspringbar mit HPOS_OHNE_UPGRADE=1, etwa bei knappem Datenvolumen.
kopf "Termux auf einen Stand bringen"
if [ "${HPOS_OHNE_UPGRADE:-0}" = 1 ]; then
warn "Übersprungen (HPOS_OHNE_UPGRADE=1)"
hinweis "Bei Problemen mit proot-distro ist das die erste Stelle zum Nachsehen."
else
hinweis "Das dauert und lädt einiges. Es erspart aber genau die Fehler,"
hinweis "die sonst erst Stunden später als kaputtes proot-distro auffallen."
export DEBIAN_FRONTEND=noninteractive
# --force-confold: vorhandene Konfigurationsdateien behalten, statt mitten im
# Lauf eine Rückfrage zu stellen, die niemand beantwortet.
if pkg update -y && pkg upgrade -y -o Dpkg::Options::=--force-confold; then
ok "Termux ist aktuell"
else
warn "Das Upgrade lief nicht sauber durch."
hinweis "Weiter geht es trotzdem — aber merken, falls später etwas klemmt."
hinweis "Von Hand nachziehen: pkg update && pkg upgrade -y"
fi
fi
# ── git ──────────────────────────────────────────────────────────────────────
kopf "git"
if command -v git >/dev/null 2>&1; then
ok "bereits vorhanden ($(git --version))"
else
if pkg install -y git; then ok "installiert"
else fehl "Installation von git fehlgeschlagen"; exit 1; fi
fi
# Das Telefon liest nur. Es soll nie versehentlich versuchen zurückzuschreiben —
# ein Push von hier wäre weder gewollt noch möglich.
git config --global credential.helper "" 2>/dev/null || true
# ── Rückfallebene: Archiv statt Klon ─────────────────────────────────────────
# Gitea, Forgejo und GitHub bieten den Baum zusätzlich als Tarball an. Der Weg
# dorthin geht nicht über upload-pack und funktioniert deshalb auch dann noch,
# wenn der Klon am Server scheitert. Das Ergebnis ist aber nur ein Abzug: kein
# .git, kein 'git pull'. Es ist eine Notlösung, keine Alternative.
archiv_holen() {
local basis zweig="${HPOS_ZWEIG:-main}" url tmp
basis="${REPO%.git}"
command -v curl >/dev/null 2>&1 || pkg install -y curl >/dev/null 2>&1
command -v tar >/dev/null 2>&1 || pkg install -y tar >/dev/null 2>&1
tmp=$(mktemp -d)
for url in "$basis/archive/$zweig.tar.gz" \
"$basis/archive/refs/heads/$zweig.tar.gz"; do
hinweis "Versuche Archiv: $url"
if curl -sfL -o "$tmp/a.tar.gz" "$url" && tar tzf "$tmp/a.tar.gz" >/dev/null 2>&1; then
mkdir -p "$ZIEL"
# --strip-components=1: die Archive enthalten alles unter einem
# Wurzelverzeichnis, das wir nicht mit übernehmen wollen.
if tar xzf "$tmp/a.tar.gz" -C "$ZIEL" --strip-components=1; then
rm -rf "$tmp"
ok "Archiv entpackt nach $ZIEL"
return 0
fi
fi
done
rm -rf "$tmp"
return 1
}
# ── Holen oder aktualisieren ─────────────────────────────────────────────────
kopf "Repo"
if [ -d "$ZIEL/.git" ]; then
ok "Arbeitskopie vorhanden — aktualisiere"
if git -C "$ZIEL" pull --ff-only; then
ok "aktuell"
else
warn "git pull fehlgeschlagen."
hinweis "Lokale Änderungen? Dann: cd ~/hpos && git stash && git pull"
exit 1
fi
else
# --depth reicht nicht: für 'git pull' später brauchen wir eine vollwertige
# Arbeitskopie, kein abgeschnittenes Archiv.
if git clone "$REPO" "$ZIEL"; then
ok "geklont nach $ZIEL"
else
fehl "git clone fehlgeschlagen."
hinweis "Adresse war: $REPO"
echo
# Ein scheiternder Klon bei erreichbarem Repo hat fast immer eine
# serverseitige Ursache: upload-pack stirbt beim Schnüren des Pakets,
# während die Objekte selbst heil sind. Erkennbar daran, dass sich ein
# Archiv weiterhin erzeugen lässt — und genau das ist die Rückfallebene.
if archiv_holen; then
warn "Über ein Archiv geholt, NICHT als Arbeitskopie."
hinweis "'git pull' funktioniert damit nicht. Sobald der Server wieder"
hinweis "Pakete ausliefert: rm -rf ~/hpos && bash /sdcard/hpos-init.sh"
else
fehl "Auch die Rückfallebene über das Archiv hat nicht geklappt."
hinweis "Ist das Repo öffentlich lesbar? Ohne das braucht es Zugangsdaten,"
hinweis "und die gehören nicht aufs Telefon."
exit 1
fi
fi
fi
chmod +x "$ZIEL"/spike/*.sh "$ZIEL"/spike/inner/*.sh 2>/dev/null || true
# ── Weiter ───────────────────────────────────────────────────────────────────
kopf "Fertig"
cat <<TEXT
Das Repo liegt jetzt unter ~/hpos und ist eine Arbeitskopie.
Aktualisieren später:
cd ~/hpos && git pull
Nächster Schritt:
cd ~/hpos
bash spike/00-bootstrap-termux.sh
Danach die Beweise der Reihe nach — S1 zuerst, weil er der wackligste ist:
bash spike/01-s1-plasma-mobile.sh
bash spike/02-s2-mikrofon.sh
bash spike/03-s3-pipewire-kamera.sh
bash spike/04-s4-intent-handoff.sh
TEXT