# Preseed – Automatische Debian-Installation

**SnowTV Player Typ 1 – Unbeaufsichtigte Erstinstallation**

---

## Dateien

| Datei | Zweck |
|---|---|
| `preseed_sata.cfg` | fitlet2 / SATA SSD (`/dev/sda`) |
| `preseed_nvme.cfg` | fitlet3 / NVMe SSD (`/dev/nvme0n1`) |
| `grub_custom.cfg` | GRUB-Einträge für den Installer-USB |
| `installer_usb.md` | Anleitung USB erstellen + anpassen |

> `preseed_late.sh` wird nicht mehr benötigt – der Late Command ist vollständig
> inline in den Preseed-Dateien eingebettet.

---

## Ablauf

```
USB Boot (Debian 13 Trixie Netinstall, UEFI Partition 2)
    │
    ├─ GRUB-Menü → Gerät wählen (fitlet2 oder fitlet3)
    │    Netzwerk-Interface (eno1) via Kernel-Parameter gesetzt
    │
    ├─ Preseed beantwortet alle Installer-Fragen automatisch
    │    Partitionierung, User snowtv, Basispakete, GRUB
    │
    ├─ Late Command (inline, kein Download)
    │    → /etc/sudoers.d/snowtv mit NOPASSWD: ALL (temporär)
    │    → firstboot.sh auf Zielgerät ablegen
    │    → snowtv-install.service aktivieren
    │    → NetworkManager-wait-online aktivieren
    │
    └─ Reboot (~20 min nach USB-Boot)
         │
         ├─ snowtv-install.service startet (nur einmalig)
         │    → swinstall.sh downloaden + ausführen (~30 min)
         │    → /etc/sudoers.d/snowtv am Ende mit eingeschränkter
         │      Regel überschrieben (nur shutdown/reboot)
         │
         └─ Automatischer Reboot durch swinstall.sh
              │
              └─ set_mcid.sh (manuell) → Reboot → Player läuft
```

---

## Verwendung

### 1. Installer-USB vorbereiten
Siehe `installer_usb.md` – einmalige Einrichtung.

### 2. Dateien auf Deployment-Server hochladen
Aktueller Server: `172.105.95.252` – Webroot: `/home/snowtv/mc/`

Vor dem ersten Einsatz und nach jeder Änderung:
- [ ] `preseed_sata.cfg`, `preseed_nvme.cfg`, `swinstall.sh` + alle `bin_typ1/` Skripte → `/home/snowtv/mc/`
- [ ] Dateirechte setzen: `ssh root@172.105.95.252 'chmod -R o+r /home/snowtv/mc && find /home/snowtv/mc -type d -exec chmod o+x {} \;'`

> **Serverwechsel:** Alle URL-Referenzen in `swinstall.sh`, `swupgrade.sh`, `preseed_*.cfg`, `grub_custom.cfg` etc. anpassen. Siehe `CONTEXT.md` → Abschnitt «Deployment-Server» für die vollständige Liste.

### 3. Installation starten
USB einstecken. Im BIOS-Bootmenü **"UEFI: ... (Partition 2)"** wählen.
GRUB-Menü erscheint → Gerät auswählen → Enter. Läuft vollständig automatisch durch.

> Nicht den Legacy-Eintrag (ohne "UEFI") wählen – dort startet syslinux,
> das GRUB-Menü erscheint nicht.

### 4. Nach dem automatischen Reboot (manuell)
```bash
# ID und Domain setzen (gerätespezifisch):
bash ~/bin/set_mcid.sh
# → automatischer Reboot

# SSH Public Key eintragen:
echo "ssh-ed25519 AAAA..." >> ~/.ssh/authorized_keys

# Player serverseitig freischalten (infosnow.ch-Backend)
```

---

## Sudo-Mechanismus (Hintergrund)

Der Preseed legt `/etc/sudoers.d/snowtv` mit `NOPASSWD: ALL` an.
`swinstall.sh` läuft dadurch passwortlos durch (kein TTY im Service-Kontext).
Am Ende überschreibt `swinstall.sh` die Datei mit der eingeschränkten Regel
(nur `/sbin/shutdown` und `/sbin/reboot`) – in einem einzigen `sudo sh -c`-Aufruf
damit die Regel nicht sich selbst blockiert.

---

## Passwort ändern

Das Default-Passwort `snowtv123` bei Bedarf anpassen:
```bash
openssl passwd -6 "NeuesPasswort"
```
Hash in `preseed_sata.cfg` und `preseed_nvme.cfg` bei `passwd/user-password-crypted`
ersetzen und neu hochladen.

---

## Troubleshooting

**Installer fragt trotzdem nach Netzwerk-Interface:**
Sicherstellen dass `grub_custom.cfg` den Parameter `netcfg/choose_interface=eno1`
in der Kernel-Zeile enthält (nicht nur in der Preseed-Datei).

**Late Command schlägt fehl:**
Installer-Log prüfen: `Alt+F4` während Installation.
Manuell nachholen nach dem Boot:
```bash
wget --no-check-certificate https://172.105.95.252/swinstall.sh
bash swinstall.sh
```

**snowtv-install.service fehlgeschlagen:**
```bash
sudo journalctl -u snowtv-install.service
cat ~/stv-install.log
# Dann manuell:
bash ~/firstboot.sh
```

**Autologin funktioniert nicht:**
```bash
cat /etc/systemd/system/getty@tty1.service.d/override.conf
# Darf NUR die zwei ExecStart-Zeilen enthalten, kein Shell-Code
sudo systemctl daemon-reload && sudo systemctl restart getty@tty1
```

**BIOS-System (kein UEFI):**
In der Preseed-Datei und `grub_custom.cfg` entsprechend anpassen
(siehe Kommentare in den jeweiligen Dateien).

---

## Remote Reinstall (bestehende Player via SSH)

Zwei Methoden stehen zur Verfügung:

| | kexec (`remote_reinstall.sh`) | debootstrap (`remote_reinstall_debootstrap.sh`) |
|---|---|---|
| **Netzabbruch während Install** | ❌ Brick | ✅ Retry via SSH möglich |
| **Stromausfall nach Disk-Format** | ❌ Brick | ❌ Brick |
| **Komplexität** | gering | höher |
| **Dauer** | ~50 Min | ~40 Min |
| **Empfehlung** | Stabile Verbindung | Unsichere/LTE-Verbindung |

---

### Methode A – kexec (schnell, einfach)

Für Player mit Debian 9–12 die remote auf Debian 13 + aktuelle
Skripte gebracht werden sollen – ohne USB-Stick, vollständig via SSH.

### Voraussetzungen
- SSH-Zugang zum Player (direkt oder via Jumpserver: `ssh -p 10{ID} snowtv@139.162.165.199`)
- `remote_reinstall.sh`, `preseed_sata.cfg`, `preseed_nvme.cfg` aktuell auf 172.105.95.252
- Player-ID bekannt (Geräte-Etikett oder infosnow.ch-Backend) – wird automatisch erkannt,
  bei sehr alten Systemen als Fallback manuell eingegeben

### Ablauf

```
ssh -p 10{ID} snowtv@139.162.165.199
bash /home/snowtv/bin/remote_reinstall.sh
```

Das Skript erledigt alles automatisch:

```
remote_reinstall.sh
  ├─ ID ermitteln (mehrstufig):
  │    mcid.cfg → mc.cfg → manuelle Eingabe
  ├─ Domain ermitteln (mehrstufig):
  │    mcdomain.cfg → mc.cfg → Auswahl-Menü (infosnow/zbag/andere)
  ├─ erkennt Disk: /dev/nvme0n1 → preseed_nvme.cfg
  │                /dev/sda     → preseed_sata.cfg
  ├─ Bestätigungsabfrage (Eingabe "ja" erforderlich)
  ├─ installiert kexec-tools via apt
  ├─ lädt Debian 13 Netboot-Kernel + initrd (~40 MB)
  └─ kexec -e → Installer bootet, SSH-Verbindung bricht ab (normal)

Debian 13 Installer (unbeaufsichtigt, ~20 Min)
  └─ Late Command:
       ├─ liest mcid=134 + mcdomain=... aus Kernel-Cmdline
       ├─ schreibt mcid.cfg + mcdomain.cfg ins Zielsystem
       └─ legt firstboot.sh + snowtv-install.service an

First Boot → swinstall.sh (~30 Min)
  ├─ sichert mcid.cfg + mcdomain.cfg
  ├─ deployed alle Skripte, SSH-Keys, Crontab
  ├─ stellt mcid.cfg + mcdomain.cfg wieder her
  ├─ Token wird geleert → Server stellt neues tokenID aus
  └─ sshcon.sh baut Reverse-Tunnel auf → Player erreichbar
```

### Player nach Reinstall erreichen

```bash
# ca. 50 Min nach Skriptstart:
ssh -p 10134 snowtv@139.162.165.199
```

Der Player meldet sich mit der gleichen ID beim Server, erhält
automatisch ein neues Token und lädt mc.cfg herunter.
**Kein manueller Eingriff nötig** (set_mcid.sh entfällt, ID bleibt erhalten).

### Kompatibilität nach Debian-Version

| Debian-Version | mcid.cfg | mcdomain.cfg | Verhalten |
|---|---|---|---|
| 13 (aktuell) | ✅ vorhanden | ✅ vorhanden | Vollautomatisch |
| 11–12 | meist vorhanden | meist vorhanden | Vollautomatisch |
| 9–10 (alt) | ggf. fehlend | ggf. fehlend | Fallback: mc.cfg oder manuelle Eingabe |

Bei manueller Eingabe: ID steht auf dem Geräte-Etikett oder im infosnow.ch-Backend.

### ⚠️ Risiko Methode A

Bei Netzwerkabbruch während der Installation (~50 Min) ist das
Gerät nicht mehr remote erreichbar → physischer Zugriff nötig.
Stabile Netzwerkverbindung vor dem Start sicherstellen.

---

### Methode B – debootstrap (robust bei instabilem Netz)

```
ssh -p 10{ID} snowtv@139.162.165.199
bash /home/snowtv/bin/remote_reinstall_debootstrap.sh
```

```
remote_reinstall_debootstrap.sh
  ├─ ID + Domain ermitteln (gleiche Fallback-Logik wie Methode A)
  ├─ UEFI/BIOS + SATA/NVMe erkennen
  ├─ Bestätigungsabfrage (Eingabe "ja" erforderlich)
  ├─ debootstrap + parted installieren
  │
  ├─ Disk partitionieren + formatieren  ← POINT OF NO RETURN
  │    UEFI: GPT → EFI (512MB) + Root
  │    BIOS: MBR → Root
  │
  ├─ debootstrap Debian 13 → /mnt/newroot
  │    Bei Netzabbruch: Retry-Dialog, altes System läuft noch im RAM
  │
  ├─ chroot-Konfiguration:
  │    apt sources, locale (de_CH), timezone (Zurich), fstab
  │    Kernel (linux-image-amd64) + GRUB installieren
  │    User snowtv anlegen, sudoers (temporär NOPASSWD: ALL)
  │    mcid.cfg + mcdomain.cfg schreiben
  │    firstboot.sh + snowtv-install.service anlegen
  │
  └─ Reboot → Debian 13 bootet

First Boot → swinstall.sh (~30 Min)
  ├─ sichert mcid.cfg + mcdomain.cfg
  ├─ deployed alle Skripte, SSH-Keys, Crontab
  ├─ stellt mcid.cfg + mcdomain.cfg wieder her
  ├─ Token wird geleert → Server stellt neues tokenID aus
  └─ sshcon.sh baut Reverse-Tunnel auf → Player erreichbar
```

### Player nach Reinstall erreichen (beide Methoden)

```bash
# Methode A: ca. 50 Min nach Skriptstart
# Methode B: ca. 40 Min nach Skriptstart
ssh -p 10{ID} snowtv@139.162.165.199
```

### Kompatibilität nach Debian-Version (beide Methoden)

| Debian-Version | mcid.cfg | mcdomain.cfg | Verhalten |
|---|---|---|---|
| 13 (aktuell) | ✅ vorhanden | ✅ vorhanden | Vollautomatisch |
| 11–12 | meist vorhanden | meist vorhanden | Vollautomatisch |
| 9–10 (alt) | ggf. fehlend | ggf. fehlend | Fallback: mc.cfg oder manuelle Eingabe |

Bei manueller Eingabe: ID steht auf dem Geräte-Etikett oder im infosnow.ch-Backend.

---

## Rollout-Checkliste

- [ ] `preseed_sata.cfg` auf 172.105.95.252 hochgeladen
- [ ] `preseed_nvme.cfg` auf 172.105.95.252 hochgeladen
- [ ] `bin_typ1/` Skripte aktuell auf 172.105.95.252
- [ ] `grub_custom.cfg` auf USB-Stick aktuell
- [ ] Passwort-Hash aktuell (bei Bedarf)
