diff --git a/ha_install.md b/ha_install.md index f5a27eb..bddc9ee 100644 --- a/ha_install.md +++ b/ha_install.md @@ -37,9 +37,9 @@ Tabelle oben in einem Aufruf. Am einfachsten direkt auf der Instanz, im Add-on * bash <(curl -fsSL https://gitea.nothaft.cloud/paul/audi-app/raw/branch/main/homeassistant/install.sh) ``` -Bei privatem Repository mit Zugangstoken in der URL (`--repo https://:@…`); -von einem Rechner aus alternativ `--ziel /Volumes/config --von ~/Development/audi-app`. -`--hilfe` zeigt alle Optionen. +Bei privatem Repository braucht es Zugangsdaten — welche Wege es dafür gibt und warum die Wahl +Folgen hat, steht in **§1b**. Von einem Rechner aus alternativ +`--ziel /Volumes/config --von ~/Development/audi-app`. `--hilfe` zeigt alle Optionen. **Was es abnimmt:** pyscript installieren (neueste Version von GitHub), `pyscript/` und `www/` einspielen, den Belegleser mitliefern (er liegt in `data/`, ist aber Code), fehlende Datenbestände @@ -76,6 +76,70 @@ Das Skript wird durch die Integration also nicht überflüssig, sondern **schrum das einmalige Kopieren eines Ordners nach `custom_components/`. Alles andere — YAML, pyscript, Token, Datenordner — fällt weg. +## 1b. Zugang zum privaten Repository + +**Werkzeuge sind da.** Im offiziellen Home-Assistant-Container liegen `git` (2.54), `curl`, `unzip` +und `ssh` bereits vor — an der laufenden Instanz nachgesehen. Es muss also nichts nachinstalliert +werden. + +### Der Haken, der die Wahl bestimmt + +Die Selbstaktualisierung (`updateverwaltung.py`) ruft `git clone` **aus dem Home-Assistant-Prozess** +auf und benutzt dafür ausschließlich `einstellungen.UPDATE_REPO_URL`. Die Funktion `_git()` setzt +keine Umgebung — es gibt also weder einen Ort für einen SSH-Schlüssel noch für einen +Anmeldehelfer. Daraus folgt zweierlei: + +- **Ein vorher im Terminal ausgeführtes `git`-Login hilft der Aktualisierung nicht.** Unter + Home Assistant OS läuft das Add-on *Terminal & SSH* in einem **eigenen Container**; eine dort + angelegte `~/.git-credentials` sieht Home Assistant Core nie, geteilt ist nur `/config`. Bei einer + Container-Installation läge sie zwar im selben Container, verschwände aber beim nächsten + HA-Update, weil der Container dabei neu erstellt wird. + Für die **Installation selbst** genügt ein solcher Anmeldehelfer dagegen — `install.sh` klont ja + in derselben Sitzung, in der du ihn eingerichtet hast. +- **Was die Aktualisierung braucht, muss in der URL stehen** — und die landet im Klartext in + `pyscript/modules/einstellungen.py`, also in `/config` und damit in jeder Sicherung. + +### Die Optionen + +| Weg | Aufruf | Bewertung | +|---|---|---| +| **Token in der URL** *(empfohlen)* | `--repo https://:@gitea…/audi-app.git` | Einzeln widerrufbar, ohne das Kontopasswort zu ändern; in Gitea auf Lesezugriff beschränkbar. Liegt trotzdem im Klartext in `/config`. | +| **Passwort in der URL** | `--repo https://:@gitea…/audi-app.git` | Funktioniert mit Gitea genauso — aber es ist das **Kontopasswort**, im Klartext in `/config` und in jeder Sicherung. Bei aktivierter Zwei-Faktor-Anmeldung verweigert Gitea es ohnehin. | +| **Ohne hinterlegte Zugangsdaten** | `--update-repo aus` | Es wird nichts gespeichert. Aktualisiert wird dann weiterhin über `install.sh` — ein Aufruf statt eines Knopfdrucks. | +| **Anmeldung vorher im Terminal** | `git config --global credential.helper store` und einmal von Hand klonen, dann `install.sh` ohne Zugangsdaten | Reicht für die Installation, **nicht** für die Selbstaktualisierung (siehe oben). Sinnvoll in Kombination mit `--update-repo aus`. | +| **Repository öffentlich lesbar oder Spiegel** | — | Der einzige Weg ganz ohne Zugangsdaten auf der Platte. Kollidiert mit der Lizenzlage: die Audi-Schrift und die Typenschilder dürfen das Repository nicht verlassen. | + +Installations- und Updatequelle sind bewusst getrennt: `--repo` bestimmt, woher installiert wird, +`--update-repo` allein, was für später hinterlegt wird. So lässt sich mit vollen Zugangsdaten +installieren und trotzdem nichts davon ablegen. + +Enthält die hinterlegte URL Zugangsdaten, weist das Skript beim Lauf darauf hin und maskiert sie in +seiner Ausgabe. + +### Auch das Skript selbst liegt hinter der Anmeldung + +`install.sh` wird aus demselben privaten Repository geladen, `curl` braucht also ebenfalls Zugang: + +```bash +# mit Token +curl -fsSL -H "Authorization: token " \ + https://gitea.nothaft.cloud/paul/audi-app/raw/branch/main/homeassistant/install.sh -o install.sh + +# oder mit Nutzer und Passwort +curl -fsSL -u ':' \ + https://gitea.nothaft.cloud/paul/audi-app/raw/branch/main/homeassistant/install.sh -o install.sh + +bash install.sh --repo https://:@gitea.nothaft.cloud/paul/audi-app.git +``` + +### Nach der Umstellung auf die Integration + +Das Thema verkleinert sich, verschwindet aber nicht: Die `UpdateEntity` (§5) holt sich die neueste +Version über die Gitea-Schnittstelle und braucht dafür ebenfalls einen Zugang. Der Unterschied ist, +dass eine Integration ihn **selbst verwalten kann** — im Konfigurationsdialog abgefragt und über +Home Assistants eigene Ablage gespeichert, statt im Klartext in einer Python-Datei. Ein Token ist +dann klar die richtige Wahl, weil der Dialog es jederzeit ersetzen kann. + ## 2. Die Bausteine, die HA dafür mitbringt Alle in 2026.8.1 vorhanden und geprüft: diff --git a/homeassistant/INSTALL.md b/homeassistant/INSTALL.md index 96f1e5d..b9bf708 100644 --- a/homeassistant/INSTALL.md +++ b/homeassistant/INSTALL.md @@ -45,14 +45,22 @@ zusammen erledigt. Am einfachsten direkt auf der HA-Instanz im Add-on bash <(curl -fsSL https://gitea.nothaft.cloud/paul/audi-app/raw/branch/main/homeassistant/install.sh) ``` -Liegt das Repository privat (Standard), braucht der Aufruf ein Zugangstoken: +Liegt das Repository privat (Standard), braucht der Aufruf Zugangsdaten — mit +Token oder mit Nutzer und Passwort, beides funktioniert: ```bash -curl -fsSL -H "Authorization: token " \ +curl -fsSL -H "Authorization: token " \ https://gitea.nothaft.cloud/paul/audi-app/raw/branch/main/homeassistant/install.sh -o install.sh bash install.sh --repo https://:@gitea.nothaft.cloud/paul/audi-app.git ``` +**Eine Überlegung lohnt sich dabei:** Was in `--repo` steht, wird als Updatequelle +hinterlegt und landet im Klartext in `pyscript/modules/einstellungen.py`. Ein +Token ist dort besser aufgehoben als das Kontopasswort, weil er einzeln +widerrufbar und auf Lesezugriff beschränkbar ist. Wer gar nichts ablegen will, +hängt `--update-repo aus` an und aktualisiert weiter über dieses Skript. +Die Abwägung im Einzelnen steht in `ha_install.md`, Abschnitt 1b. + Alternativ von einem Rechner aus gegen ein eingebundenes config-Verzeichnis: ```bash diff --git a/homeassistant/install.sh b/homeassistant/install.sh index 1b117a4..badda99 100755 --- a/homeassistant/install.sh +++ b/homeassistant/install.sh @@ -26,6 +26,7 @@ ZIEL="/config" QUELLE="" TOKEN="" REPO="$REPO_STANDARD" +UPDATE_REPO="" # leer = wie --repo PYSCRIPT_INSTALLIEREN="ja" INTERAKTIV="ja" @@ -46,7 +47,12 @@ DataMetric360 — Installation in Home Assistant --ziel config-Verzeichnis von Home Assistant (Standard: /config) --von lokale Arbeitskopie benutzen statt zu klonen - --repo Repository zum Klonen und für die Selbstaktualisierung + --repo Repository zum Klonen (Standard: das Projekt-Repository) + --update-repo + Was als Updatequelle hinterlegt wird. Standard: wie --repo. + "aus" hinterlegt nichts - dann gibt es keine + Selbstaktualisierung, aber auch keine Zugangsdaten auf der + Platte. Siehe ha_install.md, Abschnitt 1b. --branch Branch (Standard: main) --token langlebiges Zugriffstoken für die Kilometerstand-Historie --ohne-pyscript pyscript nicht mitinstallieren (wenn schon vorhanden) @@ -57,6 +63,8 @@ Beispiele bash install.sh # auf der HA-Instanz, klont selbst bash install.sh --von ~/audi-app # aus einer lokalen Arbeitskopie bash install.sh --ziel /Volumes/config # gegen ein eingebundenes Laufwerk + bash install.sh --repo https://nutzer:token@gitea.example/paul/audi-app.git + bash install.sh --von . --update-repo aus # lokal einspielen, ohne Zugangsdaten abzulegen ENDE } @@ -65,6 +73,7 @@ while [ $# -gt 0 ]; do --ziel) ZIEL="${2:-}"; shift 2 ;; --von) QUELLE="${2:-}"; shift 2 ;; --repo) REPO="${2:-}"; shift 2 ;; + --update-repo) UPDATE_REPO="${2:-}"; shift 2 ;; --branch) BRANCH="${2:-}"; shift 2 ;; --token) TOKEN="${2:-}"; shift 2 ;; --ohne-pyscript) PYSCRIPT_INSTALLIEREN="nein"; shift ;; @@ -171,9 +180,17 @@ mkdir -p "$ZIEL/audi_dashboard/belege" schritt "Selbstaktualisierung verdrahten" -# UPDATE_REPO_URL im ausgelieferten einstellungen.py setzen, damit -# "Update suchen" in den Einstellungen der App funktioniert. -python3 - "$ZIEL/pyscript/modules/einstellungen.py" "$REPO" "$BRANCH" <<'PYENDE' +# Was hinterlegt wird, ist bewusst von der Installationsquelle getrennt: die +# Selbstaktualisierung laeuft spaeter im Home-Assistant-Prozess und klont +# allein anhand dieser URL - Zugangsdaten muessen also darin stehen und landen +# damit im Klartext in einstellungen.py. Wer das nicht will, gibt +# "--update-repo aus" an und aktualisiert weiterhin ueber dieses Skript. +QUELLE_FUER_UPDATE="${UPDATE_REPO:-$REPO}" +if [ "$QUELLE_FUER_UPDATE" = "aus" ]; then + QUELLE_FUER_UPDATE="" +fi + +python3 - "$ZIEL/pyscript/modules/einstellungen.py" "$QUELLE_FUER_UPDATE" "$BRANCH" <<'PYENDE' import re, sys pfad, repo, branch = sys.argv[1], sys.argv[2], sys.argv[3] with open(pfad, encoding="utf-8") as f: @@ -183,8 +200,16 @@ inhalt = re.sub(r'^UPDATE_BRANCH\s*=.*$', f'UPDATE_BRANCH = "{branch}"', inhalt, with open(pfad, "w", encoding="utf-8") as f: f.write(inhalt) PYENDE -grau " Updatequelle: $REPO ($BRANCH)" -grau " Danach in der App unter Einstellungen → Version → \"Update suchen\"" +if [ -n "$QUELLE_FUER_UPDATE" ]; then + grau " Updatequelle: $(printf '%s' "$QUELLE_FUER_UPDATE" | sed -E 's#://[^@/]+@#://***@#') ($BRANCH)" + grau " Danach in der App unter Einstellungen → Version → \"Update suchen\"" + case "$QUELLE_FUER_UPDATE" in + *://*:*@*) rot " Hinweis: Die URL enthaelt Zugangsdaten. Sie stehen im Klartext in" + rot " pyscript/modules/einstellungen.py und damit auch in jeder Sicherung." ;; + esac +else + grau " Keine Updatequelle hinterlegt - Aktualisieren laeuft weiter ueber dieses Skript." +fi # ---------------------------------------------------------- configuration.yaml