Sammelcommit fuer den ueber mehrere Sitzungen gewachsenen, bisher nicht
eingecheckten Stand. Getrennte Commits waeren ehrlicher gewesen, sind es
nachtraeglich aber nicht mehr: BugRepo, changelog.json und die Doku tragen
Aenderungen aus allen Straengen gleichzeitig, und keine Zwischenstufe waere
lauffaehig.
ROADMAP IM DEPLOYMENTCENTER (2.7.0)
Planungsstand, Reihenfolge und Zustaendigkeit lagen in handgepflegten
Markdown-Dateien neben einem Bugtracker, der genau diese drei Dinge bereits
fuehrt. Zwei Pfleger fuer dasselbe Feld - Drift war eine Frage der Zeit.
Ab jetzt: Zustand im DC, Begruendung in der Datei. Kein Feld hat zwei Pfleger.
- Migration 016: epic, roadmap_rank, target_build, defer_trigger,
doc_anchor, Status "deferred", Tabelle roadmap_epics.
KEINE Roadmap-Tabelle - ein Eintrag ist ein bugtracker_item.
- Zugehoerigkeit ist ein Feld: Ein Item steht auf der Roadmap, wenn es ein
epic hat. Ein zweites Kennzeichen daneben koennte auseinanderlaufen.
- Kennung ist die Item-ID. Handvergebene Kuerzel ("A12") erzeugen die
schlimmste Fehlerart: Beide Seiten stimmig, Verschiedenes gemeint, weil
die Kennung nach einer Loeschung neu vergeben wurde.
- Zurueckstellen verlangt defer_trigger. Ohne benannten Anlass ist ein
Vorhaben nicht zurueckgestellt, sondern vergessen. Die Regel sitzt im
Repository, damit sie auf allen drei Schreibwegen gleich greift.
- Modules/Bugtracker/Roadmap.php, /api/bugtracker/v1/roadmap.php,
WebUI-Modul mit Filtern, cli/roadmap.php --write/--check,
dc_roadmap und dc_roadmap_set im MCP-Adapter.
- cli/roadmap.php --write ERZEUGT den Zustandsteil der Markdown-Datei;
--check prueft nur die Prosa. Was erzeugt wird, kann nicht driften.
- docs/ROADMAP_MIGRATION.md: Uebernahme fuer die anderen Projekte.
TESTINSTANZ UND TESTTOR
- dc-dev.mhdf.de: zweite Installation, eigene DB, eigene Schluessel,
Basic-Auth davor, Rocket.Chat aus.
- 124 Testfaelle in tests/e2e gegen API, Rechte, Migrationen, Sperre.
- scripts/deploy.py bringt vor jedem Upload erst den anstehenden Stand auf
die Testinstanz und laesst dann den Testlauf laufen. Erst bei
Rueckgabewert 0 geht etwas auf die Produktion (--ohne-test als Notausgang).
Andersherum prueft der Lauf aelteren Code als den, der gleich hochgeht.
- tests/ ist aus dem Produktiv-Deploy ausgeschlossen; testctl.php kann
nicht versehentlich auf dc.mhdf.de landen.
- Ein Lauf mit mehr uebersprungenen als geprueften Faellen endet mit
Rueckgabewert 2 statt 0. Nichts ist kaputt, geprueft wurde es aber auch
nicht - der Unterschied darf nicht am Rueckgabewert verschwinden.
SUPERVISOR, PROJEKTLANDSCHAFT, NACHPRUEFUNG (2.6.0/2.6.1)
- Migration 013: projektuebergreifend melden (dev_agent, evidence,
triage_external, affects).
- Migration 014: supervisor_findings, Katalog, fuenf serverseitige
Detektoren im Tick.
- Migration 015: Nachpruefung als Arbeitsschlange statt Benachrichtigung.
- DEV-Lizenzschluessel zur Selbstbedienung, dc-testkit fuer die Test-VM.
- MCP-Adapter: 15 Werkzeuge, ohne Fremdabhaengigkeiten, mit Abgrenzung
von Fremddaten gegen Prompt-Injektion.
BEHOBEN
- observe und status im Supervisor legten den Zustand des Befundes als
"status" in die Antwort. Http::ok() merged ['status' => 'success']
darunter, also gewann der Befundzustand - eine angenommene Meldung kam
als status="open" an. Heisst jetzt finding_status. War Item #59.
Migrationen 013-016 sind auf dem Produktivserver noch NICHT ausgefuehrt.
Ohne sie bricht das WebUI, weil die Roadmap-Ansicht bei jedem Seitenaufruf
gegen bugtracker_items.epic abfragt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
834 lines
36 KiB
Markdown
834 lines
36 KiB
Markdown
# Linux-Testumgebung — Anleitung für Agenten
|
|
|
|
**Stand: 28.08.2026** · Gilt projektübergreifend für alle Agenten und Entwickler, die auf der
|
|
geteilten Test-VM arbeiten.
|
|
|
|
> **Diese Datei ist die maßgebliche Fassung.** Sie liegt im Deploymentcenter-Repo unter
|
|
> `docs/TESTUMGEBUNG.md`. Die Kopie auf der Maschine (`~/TESTUMGEBUNG.md`) und die Verweise in
|
|
> den Projektrepos zeigen hierher. Wer etwas an der Umgebung ändert, ändert es **hier** und
|
|
> kopiert danach auf die VM — nicht umgekehrt.
|
|
>
|
|
> **Bewusst nicht unter `public/`:** Diese Datei nennt eine interne Adresse, einen Benutzernamen
|
|
> und den Weg, `sudo` zeitweise freizuschalten. `/docs/` auf dem Deploymentcenter ist öffentlich
|
|
> erreichbar; dort gehört das nicht hin. Das Testkit-Skript dagegen schon — es enthält nichts
|
|
> davon.
|
|
|
|
---
|
|
|
|
## 1. Was diese Maschine ist
|
|
|
|
Eine Ubuntu-Desktop-VM zum **Testen** — nicht für Produktivbetrieb, nicht für echte Zugangsdaten,
|
|
nicht für Geld bewegende Läufe.
|
|
|
|
| | |
|
|
|---|---|
|
|
| System | Ubuntu 26.04 LTS, Kernel 7.0, x86_64 |
|
|
| Ausstattung | 31 GB RAM, 5 CPUs, ~33 GB freier Plattenplatz |
|
|
| Erreichbar | `192.168.40.48` über einen WireGuard-Tunnel |
|
|
| Benutzer | `richard` |
|
|
| Besonderheit | **Desktop-Umgebung vorhanden** — grafische Anwendungen sind testbar, nicht nur Dienste |
|
|
|
|
**Warum eine Desktop-VM?** Weil sich damit beides prüfen lässt: der kopflose Serverbetrieb
|
|
(systemd) *und* die grafische Oberfläche auf der Zielplattform.
|
|
|
|
---
|
|
|
|
## 2. Zugang einrichten
|
|
|
|
Der Zugang läuft über **SSH-Schlüssel**. Passwort-Anmeldung wird nicht verwendet — Agenten geben
|
|
grundsätzlich keine Passwörter ein. Diese Regel gilt auch dort, wo es bequemer wäre: Der
|
|
`update-agent` fragt bei `--action install` nach Zugangsdaten; genau deshalb nimmt das Testkit
|
|
diesen Weg nicht (siehe §4.7).
|
|
|
|
### 2.1 Schlüssel erzeugen (auf dem eigenen Rechner)
|
|
|
|
```bash
|
|
ssh-keygen -t ed25519 -f ~/.ssh/testvm_<projekt> -N "" -C "<projekt>@testvm"
|
|
```
|
|
|
|
Ein **eigener Schlüssel je Projekt** — dann lässt sich einzelnen Projekten der Zugang entziehen,
|
|
ohne alle anderen auszusperren.
|
|
|
|
### 2.2 Öffentlichen Schlüssel hinterlegen
|
|
|
|
Der Inhalt von `~/.ssh/testvm_<projekt>.pub` wird auf der VM in `~/.ssh/authorized_keys`
|
|
eingetragen. **Das muss ein Mensch tun** (einmalig, mit Passwort). Direkt auf der VM:
|
|
|
|
```bash
|
|
mkdir -p ~/.ssh && chmod 700 ~/.ssh && echo '<INHALT DER .pub-DATEI>' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys
|
|
```
|
|
|
|
### 2.3 SSH-Konfiguration (auf dem eigenen Rechner)
|
|
|
|
```
|
|
Host testvm
|
|
HostName 192.168.40.48
|
|
User richard
|
|
IdentityFile ~/.ssh/testvm_<projekt>
|
|
IdentitiesOnly yes
|
|
ServerAliveInterval 30
|
|
ServerAliveCountMax 4
|
|
```
|
|
|
|
⚠️ **Kein `ControlMaster`/`ControlPath` eintragen, wenn der Client unter Windows läuft** —
|
|
Windows-OpenSSH unterstützt Verbindungs-Multiplexing nicht und scheitert mit
|
|
„Failed to connect to new control master". Stattdessen mehrere Prüfschritte pro Aufruf bündeln.
|
|
|
|
Test: `ssh testvm "hostname"`
|
|
|
|
---
|
|
|
|
## 3. Was installiert ist
|
|
|
|
| Werkzeug | Version | Anmerkung |
|
|
|---|---|---|
|
|
| .NET SDK | 10.0.111 (Runtime 10.0.11) | SDK, nicht nur Runtime — auf der VM kann gebaut werden |
|
|
| MariaDB | 11.8.6 | Dienst `mariadb`, lauscht auf `localhost:3306` |
|
|
| Git | 2.53.0 | |
|
|
| curl, python3 | vorhanden | Voraussetzung für das Testkit (§4) |
|
|
| Xvfb | vorhanden | Virtueller Framebuffer für GUI-Tests ohne Bildschirm (siehe 5.7) |
|
|
| xdotool | vorhanden | Klicks und Tastatureingaben skripten |
|
|
| ImageMagick | vorhanden | `import` für Bildschirmaufnahmen, `convert` zum Zuschneiden |
|
|
| JetBrains Rider | vorhanden | |
|
|
| Docker | **nicht** installiert | |
|
|
| Node.js | **nicht** installiert | |
|
|
| jq | **nicht** installiert | Wird auch nicht gebraucht — das Testkit liest JSON mit `python3` |
|
|
|
|
**Nicht vorhandene Werkzeuge dürfen installiert werden** — aber bitte in der Belegungsliste
|
|
(Abschnitt 7) vermerken, damit andere wissen, was sich geändert hat.
|
|
|
|
---
|
|
|
|
## 4. Das Testkit — vorhandene Infrastruktur statt Eigenbau
|
|
|
|
Alles, was ein Testlauf braucht, gibt es im Deploymentcenter schon: Lizenzschlüssel,
|
|
Release-Ablage, Update-Agent, Bugtracker. Was fehlte, war der Weg dorthin ohne einen Menschen,
|
|
der im WebUI etwas anklickt.
|
|
|
|
**`dc-testkit` ist dieser Weg.** Ein Skript, ein Aufruf je Schritt, für alle Projekte dasselbe.
|
|
|
|
> **Warum überhaupt ein Skript und nicht „der Agent ruft die API direkt auf"?** Weil sonst jeder
|
|
> Agent seine eigene Fassung der immer gleichen fünf `curl`-Aufrufe baut — jede mit anderen
|
|
> Vorgaben, anderer Fehlerbehandlung und anderem Umgang mit dem Token. Die Unterschiede fallen
|
|
> niemandem auf, solange nichts schiefgeht. Und wenn etwas schiefgeht, ist unklar, ob die
|
|
> Anwendung oder der Aufruf schuld war. Ein Weg, den alle nehmen, ist der einzige, dessen Fehler
|
|
> man findet.
|
|
|
|
### 4.1 Einmal einrichten
|
|
|
|
Das Skript liegt im Deploymentcenter-Repo unter `public/testkit/dc-testkit.sh` und wird mit
|
|
`deploy.py` ins Webroot ausgeliefert. Auf der VM:
|
|
|
|
```bash
|
|
mkdir -p ~/bin
|
|
curl -fsSL https://dc.mhdf.de/testkit/dc-testkit.sh -o ~/bin/dc-testkit
|
|
chmod +x ~/bin/dc-testkit
|
|
```
|
|
|
|
> ⚠️ **Beides — dieser Download und `dc-testkit license` — setzt Deploymentcenter 2.6.1 voraus.**
|
|
> Solange die Fassung auf dem Server älter ist, gibt es die Datei unter `/testkit/` nicht, und der
|
|
> Endpunkt `/api/license/v1/dev-key` fehlt. Der fehlende Endpunkt fällt dabei **nicht** mit 404
|
|
> auf: Die Lizenz-API antwortet bei unbekannten Pfadsegmenten mit ihrer Verfügbarkeitsprüfung, also
|
|
> mit HTTP 200. Das Testkit erkennt das und sagt es; wer von Hand `curl`t, sucht sonst lange.
|
|
>
|
|
> Bis dahin geht es auch per `scp` aus dem Repo:
|
|
> `scp public/testkit/dc-testkit.sh testvm:~/bin/dc-testkit`
|
|
|
|
Dann je Projekt eine Konfiguration — **das Token gehört in die Datei, nicht in die Befehlszeile**,
|
|
sonst steht es in der Shell-History:
|
|
|
|
```bash
|
|
mkdir -p ~/.config/dc-testkit
|
|
cat > ~/.config/dc-testkit/config <<'EOF'
|
|
DC_URL=https://dc.mhdf.de
|
|
DC_TOKEN=<Werkbank-Token des Projekts>
|
|
DC_PROJECT=<slug>
|
|
DC_CHANNEL=prod
|
|
EOF
|
|
chmod 600 ~/.config/dc-testkit/config
|
|
```
|
|
|
|
Arbeitet ein Agent an mehreren Projekten, hält er je Projekt eine eigene Datei und wählt sie über
|
|
`DC_TESTKIT_CONFIG=~/.config/dc-testkit/polytrader dc-testkit …`.
|
|
|
|
Prüfen, ob alles steht:
|
|
|
|
```bash
|
|
dc-testkit doctor
|
|
```
|
|
|
|
### 4.2 Das Werkbank-Token
|
|
|
|
Ein Mensch legt es **einmal je Projekt** an — im WebUI unter *System → Tokens*:
|
|
|
|
| Feld | Wert |
|
|
|---|---|
|
|
| Typ | Master |
|
|
| Besitzerart | `dev_agent` |
|
|
| Projekt | der Slug des Projekts |
|
|
| Rechte | `bugtracker:manage`, `license:dev`, `updateservice:read` |
|
|
|
|
Mehr braucht es nicht, und mehr sollte es nicht sein. `bugtracker:manage` schließt Lesen und
|
|
Melden ein, `license:dev` schließt `updateservice:read` ein — zwei Häkchen genügen also.
|
|
|
|
**Nicht `*` vergeben.** Ein Token mit allen Rechten auf einer geteilten Testmaschine darf auch
|
|
Releases veröffentlichen und Lizenzen fremder Projekte anfassen.
|
|
|
|
### 4.3 DEV-Lizenzschlüssel selbst holen
|
|
|
|
```bash
|
|
dc-testkit license
|
|
```
|
|
|
|
Das ist der Aufruf, der bisher fehlte. Er stellt für **diese Maschine und dieses Projekt** einen
|
|
befristeten Lizenzschlüssel aus und legt ihn mit Rechten 600 ab. Ausgegeben wird er nicht — wer
|
|
ihn wirklich sehen muss, hängt `--print` an.
|
|
|
|
Was dabei passiert und warum:
|
|
|
|
| | |
|
|
|---|---|
|
|
| **Befristet** | 30 Tage (einstellbar über `license.dev_ttl_days`, höchstens 90). Ein Schlüssel, den beim Anlegen niemand befristet hat, läuft nie ab und liegt in drei Monaten noch in einem Chatverlauf. |
|
|
| **Erkennbar** | Trägt `dev-agent@testumgebung.invalid` als Kundenadresse und `DEV <maschine>` als Namen. In der Aktivierungsliste ist Testhardware damit von echten Installationen zu unterscheiden. |
|
|
| **Wiederholbar** | Derselbe Aufruf liefert denselben Schlüssel zurück und verlängert die Frist. Er darf deshalb am Anfang **jedes** Laufs stehen. |
|
|
| **Öffnet die Release-Ablage** | `/releases/<slug>/` liegt seit 2.4 hinter Basic-Auth, die am Lizenzschlüssel hängt. Der neue Schlüssel wird beim Ausstellen sofort in die `.htpasswd` des Produkts nachgezogen. |
|
|
| **Begrenzt** | Höchstens 12 gleichzeitig je Projekt. Eine Schleife in einem fehlerhaften Testskript legt sonst über Nacht tausende an. |
|
|
|
|
Zurückgeben, wenn die Maschine das Projekt nicht mehr testet:
|
|
|
|
```bash
|
|
dc-testkit license --revoke
|
|
```
|
|
|
|
Nötig ist das nicht — abgelaufene Schlüssel verschwinden von selbst. Es macht nur sofort Platz.
|
|
|
|
> **Ein DEV-Schlüssel ist kein Sonderfall im Lizenzsystem.** Er durchläuft dieselbe Prüfung,
|
|
> dieselbe Aktivierungsgrenze, denselben Release-Zugang wie ein Kundenschlüssel. Das ist Absicht:
|
|
> Wäre er ein Sonderweg, prüfte der Test hinterher etwas anderes als den Betrieb.
|
|
|
|
### 4.4 Installations- und Updateroutinen prüfen
|
|
|
|
```bash
|
|
dc-testkit agent # update-agent holen, Prüfsumme gegen installer.json abgleichen
|
|
dc-testkit install # Erstauslieferung in einen leeren Sandkasten
|
|
dc-testkit verify # Was liegt jetzt da, und passt es zu dem, was der Server führt?
|
|
dc-testkit update # Update auf latest
|
|
dc-testkit verify
|
|
```
|
|
|
|
Oder alles auf einmal, mit automatischer Meldung dessen, was scheitert:
|
|
|
|
```bash
|
|
dc-testkit run
|
|
```
|
|
|
|
Der Sandkasten liegt unter `~/.local/state/dc-testkit/<projekt>/sandbox` — bewusst **nicht** in
|
|
`/opt`. Ein Testlauf, der die echte Installation überschreibt, ist kein Test, sondern ein
|
|
Deployment.
|
|
|
|
**Was geprüft wird:** Download aus der Release-Ablage mit dem eigenen Lizenzschlüssel,
|
|
SHA256-Abgleich, Signaturprüfung, Staging und Rollback, das geschriebene `manifest.json`, und der
|
|
Abgleich der installierten Fassung gegen die, die der Server als neueste führt.
|
|
|
|
Ein Rückfall auf eine ältere Fassung — der Weg, der im Ernstfall gebraucht wird und deshalb
|
|
geprüft gehört:
|
|
|
|
```bash
|
|
dc-testkit update --version 1.3.2
|
|
dc-testkit verify
|
|
```
|
|
|
|
Der Lizenzschlüssel geht dabei über die Umgebungsvariable `DC_LICENSE_KEY` an den Agenten, nicht
|
|
über `--license-key`. **Auf einer geteilten Maschine sieht jeder andere Benutzer die
|
|
Befehlszeilen fremder Prozesse** in `ps aux`; die Umgebung eines Prozesses liest nur, wem er
|
|
gehört.
|
|
|
|
### 4.5 Gefundenes melden
|
|
|
|
Ein Befund, von dem nur das Terminal weiß, ist kein Befund gewesen.
|
|
|
|
```bash
|
|
dc-testkit report --type bug --severity high \
|
|
--title "Update bricht bei fehlender manifest.json ab" \
|
|
--desc "Nach der Erstauslieferung fehlt manifest.json; der naechste Lauf haelt jede Version fuer neuer." \
|
|
--file "client-dotnet/Deploymentcenter.UpdateAgent/Program.cs" --line 412
|
|
```
|
|
|
|
Auch ein Wunsch statt eines Fehlers:
|
|
|
|
```bash
|
|
dc-testkit report --type feature --severity wishlist \
|
|
--title "update-agent: kopfloser Installationsmodus" --desc-file /tmp/begruendung.txt
|
|
```
|
|
|
|
Die Beschreibung darf über die Standardeingabe kommen — Fehlertexte entstehen meist als Ausgabe
|
|
eines anderen Befehls:
|
|
|
|
```bash
|
|
./meinprogramm 2>&1 | dc-testkit report --title "Absturz beim Start" --severity critical
|
|
```
|
|
|
|
**`client_ref` wird abgeleitet, nicht gewürfelt** — aus Projekt, Titel und Fundstelle. Derselbe
|
|
Befund aus zehn Testläufen legt damit ein Item an und nicht zehn. Wer bewusst ein zweites will,
|
|
gibt `--ref` selbst an.
|
|
|
|
### Der Tracker antwortet — melde nicht blind
|
|
|
|
Bevor du etwas meldest, ist die Frage nicht „ist das ein Fehler?", sondern **„ist das hier schon
|
|
bekannt, und in welcher Fassung wurde es behoben?"** Diese Antwort steht bereits in der Datenbank:
|
|
Jedes erledigte Item trägt seine Zielfassung in `resolved_in_build`.
|
|
|
|
Das Testkit schickt deshalb bei jeder Meldung die geprüfte Fassung mit — automatisch, gelesen aus
|
|
der `manifest.json` im Sandkasten. **Ohne diese Angabe kann der Server nicht unterscheiden, worum
|
|
es sich handelt**, und legt im Zweifel ein Regressionsitem an. Sie zu vergessen ist der häufigste
|
|
Weg, den Tracker unbrauchbar zu machen.
|
|
|
|
Daraus fallen zwei verschiedene Antworten:
|
|
|
|
**Behoben in einer späteren Fassung als deiner** — der Regelfall auf einem Prüfstand, der nicht
|
|
immer die neueste Fassung fährt:
|
|
|
|
```
|
|
ok Nicht gemeldet - schon behoben.
|
|
Item #128, behoben in 1.4.3; geprüft wurde 1.4.2.
|
|
Es wurde nichts angelegt und nichts hochgezählt.
|
|
Aktualisiere und prüfe erneut. Tritt es dann immer noch auf,
|
|
ist es eine Regression und gehört gemeldet.
|
|
```
|
|
|
|
Es entsteht **kein** Item, kein Kommentar, kein hochgezählter Zähler. Der Befund sagt nichts über
|
|
die Software aus, sondern nur über die Fassung, die du geprüft hast.
|
|
|
|
**Behoben in einer Fassung, die du bereits hast** — dann ist es ernst:
|
|
|
|
```
|
|
warn REGRESSION: Item #144 ist ein Wiederauftreten von #128.
|
|
warn Der Fehler galt als behoben und ist in 1.4.7 wieder da.
|
|
```
|
|
|
|
Hier entsteht ein neues Item mit Verweis auf das alte, und am alten wird vermerkt, in welcher
|
|
Fassung es wieder auftrat. Das ist der Fall, für den die Kennzeichnung da ist.
|
|
|
|
> **Warum das vorher nicht ging.** Der Server verglich die Fassungen nicht. Jede Meldung gegen ein
|
|
> bereits erledigtes Item wurde zur Regression erklärt — auch die von einem Prüfstand, der den Fix
|
|
> schlicht noch nicht hatte. Bei einer Testumgebung, die absichtlich auch ältere Fassungen prüft,
|
|
> wäre bald jede zweite Meldung eine „Regression" gewesen, und die echten wären darin
|
|
> untergegangen.
|
|
|
|
### Der Prüfauftrag — Arbeit, die von selbst zu dir kommt
|
|
|
|
Ein Fix ist eine Behauptung, bis jemand ihn gegen ein ausgeliefertes Paket geprüft hat. Genau
|
|
dafür gibt es seit 2.6.1 einen Platz in der Arbeitsschlange — und deshalb braucht der Rückkanal
|
|
keine Zustellung: **`dc-testkit next` gibt dir Prüfaufträge wie jede andere Arbeit.**
|
|
|
|
```
|
|
==> Naechstes Item
|
|
|
|
NACHPRUEFUNG, keine neue Fehlersuche:
|
|
Item #128 Update bricht bei fehlender manifest.json ab
|
|
Behoben laut Tracker in: 1.4.3
|
|
Projekt: deploymentcenter
|
|
|
|
Gegen diesen Build testen. Dann eines von beidem:
|
|
traegt -> dc-testkit confirm 128 "kurz was geprueft wurde"
|
|
traegt nicht-> den Fehler erneut melden (dc-testkit report ...);
|
|
das Item wechselt dann selbst auf fix_insufficient.
|
|
```
|
|
|
|
**Lies den Hinweis.** Ein Prüfauftrag sieht im JSON aus wie jede andere Arbeit, stellt aber eine
|
|
andere Frage: nicht „behebe das", sondern „trägt der Fix?". Wer das übersieht, fängt an, einen
|
|
bereits behobenen Fehler ein zweites Mal zu beheben.
|
|
|
|
### Der Lebenslauf
|
|
|
|
| Status | Bedeutung |
|
|
|---|---|
|
|
| `open` → `in_progress` | Gewöhnliche Arbeit. Übernehmen befördert |
|
|
| `resolved` | Ein Agent sagt: behoben in Build X. Noch nichts ausgeliefert |
|
|
| `awaiting_verification` | Build X **ist veröffentlicht** — jetzt lässt sich nachsehen |
|
|
| `in_verification` | Jemand sieht gerade nach. Entsteht durch denselben Claim |
|
|
| `fix_insufficient` | Gegen den Build geprüft, Fehler immer noch da |
|
|
| `closed` | Bestätigt weg |
|
|
|
|
Der Übergang nach `awaiting_verification` passiert **beim Veröffentlichen**, nicht beim Beheben.
|
|
Vorher gibt es kein Paket, gegen das man prüfen könnte — eine Prüfaufgabe zu diesem Zeitpunkt
|
|
wäre eine, die niemand erledigen kann.
|
|
|
|
**`confirm` ist nicht `resolve`.** `resolve` behauptet „ich habe es behoben, in Build X" und setzt
|
|
`resolved_in_build`. `confirm` behauptet nichts, sondern bestätigt den Fix eines anderen. Beides in
|
|
einen Befehl zu legen hieße, den Unterschied zwischen Fixen und Prüfen einzuebnen.
|
|
|
|
### Was passiert, wenn du nicht fertig wirst
|
|
|
|
Nichts Schlimmes — aber es bleibt nicht liegen:
|
|
|
|
- **Lease läuft ab** → das Item geht zurück auf `awaiting_verification` und liegt wieder in der
|
|
Schlange. (Dasselbe gilt seit 2.6.1 für gewöhnliche Arbeit: `in_progress` → `open`. Vorher blieb
|
|
ein liegengelassenes Item auf `in_progress` stehen und wurde nie wieder ausgegeben — es war weg.)
|
|
- **Dreimal begonnen, nie beendet** → ein Vermerk am Item holt einen Menschen. Still weiter
|
|
einzureihen hieße, eine Schlange zu führen, in die niemand sieht.
|
|
- **30 Tage niemand angenommen** → wird ungeprüft geschlossen, mit einem Kommentar, der genau das
|
|
sagt. Ein ehrliches Ende ist besser als eine Aufgabe, die niemand annimmt. Die Zahl
|
|
„geschlossen" bedeutet dann eben nicht „bestätigt", und das steht am Item.
|
|
|
|
### Auch für Befunde in fremden Projekten
|
|
|
|
Hast du einen Fehler im Deploymentcenter gemeldet (§4.6), bekommst **du** den Prüfauftrag, wenn
|
|
er behoben ist — obwohl das Item dem Deploymentcenter gehört. Du bist als betroffen vermerkt, und
|
|
oft bist du der Einzige, der bestätigen kann, dass der Fix bei dir wirkt.
|
|
|
|
Das ist die eine, eng gefasste Ausnahme von der Regel „ein Agent arbeitet nur im eigenen Projekt":
|
|
nur Items, die auf Nachprüfung warten, nur wenn dein Projekt in `affects` steht. Du darfst sie
|
|
kommentieren, im Status setzen und zurückgeben — aber nicht `resolve`. Was in einem fremden Projekt
|
|
als „behoben in Build X" gilt, entscheidet dieses Projekt.
|
|
|
|
Den Kreis schließen, wenn daran gearbeitet wird:
|
|
|
|
```bash
|
|
dc-testkit next # naechstes Item uebernehmen (exklusiv)
|
|
dc-testkit comment 42 "Ursache gefunden: Pfadtrenner unter Linux." fix_proposed
|
|
dc-testkit resolve 42 v1.4.3 "Behoben in Installer.cs." # ich habe es behoben
|
|
dc-testkit confirm 42 "Gegen 1.4.3 geprueft, Paket sauber." # der Fix eines anderen traegt
|
|
dc-testkit unclaim 42 "Komme nicht weiter, brauche Zugriff auf die Kundendaten."
|
|
```
|
|
|
|
**Übernehmen ist keine Formsache.** Wer es überspringt, arbeitet irgendwann parallel zu jemandem
|
|
am selben Problem. Antwortet der Server mit `409 already_claimed`, nimm das nächste Item.
|
|
|
|
### 4.6 Befunde, die ein anderes Projekt betreffen
|
|
|
|
**Das ist der wichtigste Abschnitt dieser Datei.** Ein Agent auf der Test-VM stolpert
|
|
zwangsläufig über Dinge, die nicht seinem Projekt gehören: Der PolyTrader-Agent findet einen
|
|
Fehler im `update-agent`. Ihm fällt auf, dass diese Anleitung an einer Stelle lügt. Er hätte
|
|
einen Vorschlag, wie das Testkit besser wäre.
|
|
|
|
Landet das im eigenen Projekt, ist es verloren — dort liest es niemand, der es beheben könnte.
|
|
Landet es gar nirgends, wiederholt sich derselbe Stolperstein bei jedem, der nach ihm kommt.
|
|
|
|
```bash
|
|
dc-testkit projects # welche Slugs gibt es überhaupt?
|
|
|
|
dc-testkit report --project deploymentcenter --type bug --severity medium --title "update-agent schreibt bei --action update kein manifest.json" --desc-file /tmp/befund.txt --evidence "Nach dc-testkit install liegt kein manifest.json im Zielverzeichnis. Der naechste Lauf meldet deshalb 'Unbekannt' als installierte Fassung und haelt jede Version fuer neuer. Reproduziert mit polytrader und deploymentcenter, also nicht projektspezifisch."
|
|
```
|
|
|
|
### Wohin gehört was
|
|
|
|
| Befund | Slug |
|
|
|---|---|
|
|
| Fehler im `update-agent`, im SDK, in der Lizenzprüfung, im Bugtracker | `deploymentcenter` |
|
|
| Fehler oder Lücke in **dieser Anleitung** oder in `dc-testkit` | `deploymentcenter` — beide liegen in dessen Repo |
|
|
| Die Test-VM selbst: fehlendes Werkzeug, belegtes Display, kaputte Konvention | `deploymentcenter`, `--type feature` |
|
|
| Alles am eigenen Programm | das eigene Projekt, ohne `--project` |
|
|
|
|
**Die Testumgebung ist kein eigenes Projekt.** Sie hat keinen Slug. Wer sie verbessern will,
|
|
meldet an `deploymentcenter` — dort liegen Skript und Anleitung, und dort wird beides gepflegt.
|
|
|
|
### Drei Dinge, die dabei anders sind
|
|
|
|
**1. Eine Begründung ist Pflicht** — `--evidence`, mindestens 40 Zeichen. Nicht als Schikane:
|
|
Ein Agent in Projekt X kann selten sicher unterscheiden, ob das fremde Projekt kaputt ist oder ob
|
|
X es falsch benutzt. Die Voreinstellung eines hilfsbereiten Modells ist im Zweifel „melde es".
|
|
Etwas ausformulieren zu müssen kostet diesen Reflex fast immer den Kopf. Beantworte darin: *Was
|
|
wurde beobachtet, und warum liegt die Ursache dort und nicht bei mir?*
|
|
|
|
**2. Der Schweregrad wird auf `medium` gedeckelt.** `high` und `critical` vergibt die empfangende
|
|
Seite — nur sie weiß, wer sonst noch betroffen ist. Das Testkit warnt, wenn du höher einstufst.
|
|
Was dringlich ist, gehört in die Begründung, nicht in das Feld.
|
|
|
|
**3. Die Meldung landet in `triage_external`, nicht in `open`.** Das ist ein Eingang, kein
|
|
Ablagefach: Fremdmeldungen zählen erst nach Bestätigung in die Statistik des Zielprojekts —
|
|
sonst verdürben Fehlmeldungen die Zahlen, auf denen die Supervisor-Detektoren kalibrieren.
|
|
**Such dein Item also nicht in der offenen Liste des fremden Projekts.**
|
|
|
|
### Die Herkunft ist bezeugt, nicht behauptet
|
|
|
|
`reported_from` wird aus der Bindung deines Tokens abgeleitet und **nie** aus dem Body übernommen.
|
|
Du kannst dich nicht als jemand anderes ausgeben. Genau das macht das Signal erst wertvoll: Melden
|
|
drei Projekte dasselbe, ist das eine Aussage über die Sache und nicht über die Meldefreudigkeit
|
|
eines Agenten. Meldet ein zweites Projekt einen bereits erfassten Befund, entsteht kein neues Item
|
|
— es wird als weiterer Betroffener geführt (`affects`).
|
|
|
|
**Voraussetzung ist ein Werkbank-Token** (Besitzerart `dev_agent`, §4.2). Nur solche Token dürfen
|
|
projektübergreifend melden. Ein Laufzeit-Token darf es nicht: Es steckt in der ausgelieferten
|
|
Anwendung und ist extrahierbar.
|
|
|
|
### Wenn ein Fremdbefund dich betrifft
|
|
|
|
**Du musst nicht benachrichtigt werden — du kannst fragen.** Meldest du denselben Befund erneut,
|
|
antwortet der Tracker mit `known_fixed_in` (siehe §4.5): behoben in Fassung X, du hast Y. Das
|
|
beantwortet die Frage „ist mein Workaround noch nötig?" ohne Rückkanal, und zwar für Fremdmeldungen
|
|
genauso wie für eigene.
|
|
|
|
Was **nicht** von selbst passiert: Niemand stößt dich an. Wird ein Item behoben, das du gemeldet
|
|
hast, erfährst du es erst, wenn du das nächste Mal fragst — beim Melden oder über den Changelog:
|
|
|
|
```bash
|
|
curl -s "https://dc.mhdf.de/api/updateservice/v1/changelog?since=<deine Fassung>"
|
|
```
|
|
|
|
Für einen Testlauf, der ohnehin regelmäßig läuft, genügt das: Er fragt bei jedem Durchgang. Wer
|
|
einen Workaround gebaut hat und ihn zurückbauen möchte, ohne darauf zu warten, braucht den aktiven
|
|
Rückkanal (Roadmap C3).
|
|
|
|
### 4.7 Was das Testkit nicht kann — und warum
|
|
|
|
**Den interaktiven Installationsdialog.** `update-agent --action install` ist ein Dialog mit
|
|
Auswahllisten und Passwortabfrage. Er lässt sich nicht kopflos treiben, und ein Agent darf ohnehin
|
|
kein Passwort eingeben (§2).
|
|
|
|
Was `dc-testkit install` stattdessen tut, ist die Erstauslieferung in ein **leeres** Verzeichnis
|
|
über den Update-Weg. Das ist keine Notlösung: Der Installer holt die Dateien laut
|
|
[SETUP_INTEGRATION_GUIDE](./SETUP_INTEGRATION_GUIDE.md) über genau denselben Pfad — Download,
|
|
SHA256, Signaturprüfung, Staging, Rollback. Was der Dialog zusätzlich tut, ist fragen und eine
|
|
Konfiguration schreiben.
|
|
|
|
**Geprüft wird also die Auslieferung, nicht die Gesprächsführung.** Die Auflösung von `setup.json`
|
|
und das Schreiben der Konfiguration bleiben ungeprüft. Ein kopfloser Installationsmodus
|
|
(`--action install --answers antworten.json`) würde diese Lücke schließen; er steht in der
|
|
[Roadmap](./ROADMAP.md) unter G1.
|
|
|
|
---
|
|
|
|
## 5. Konventionen für mehrere Projekte
|
|
|
|
Die Maschine wird von mehreren Projekten geteilt. Diese Regeln verhindern, dass sich Tests
|
|
gegenseitig zerstören.
|
|
|
|
### 5.1 Datenbanken — je Projekt eine eigene
|
|
|
|
**Niemals** eine fremde Datenbank mitbenutzen und **niemals** eine Produktivdatenbank verbinden.
|
|
|
|
```bash
|
|
# Passwort erzeugen und ablegen (nur für den Besitzer lesbar)
|
|
PW=$(openssl rand -base64 18 | tr -d "/+=" | head -c 20)
|
|
echo "$PW" > ~/.<projekt>_test_dbpw && chmod 600 ~/.<projekt>_test_dbpw
|
|
|
|
sudo mariadb -e "CREATE DATABASE IF NOT EXISTS <projekt>_test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
CREATE USER IF NOT EXISTS '<projekt>_test'@'localhost' IDENTIFIED BY '$PW';
|
|
GRANT ALL PRIVILEGES ON <projekt>_test.* TO '<projekt>_test'@'localhost';
|
|
FLUSH PRIVILEGES;"
|
|
```
|
|
|
|
| Was | Schema | Beispiel |
|
|
|---|---|---|
|
|
| Datenbank | `<projekt>_test` | `polytrader_test` |
|
|
| Benutzer | `<projekt>_test`@`localhost` | `polytrader_test` |
|
|
| Passwortdatei | `~/.<projekt>_test_dbpw` (Rechte 600) | |
|
|
|
|
Die Rechte enden **an der eigenen Datenbank** — `GRANT ALL ON <projekt>_test.*`, nie global.
|
|
|
|
### 5.2 Verzeichnisse
|
|
|
|
| Zweck | Ort |
|
|
|---|---|
|
|
| Quellcode | `~/RiderProjects/<projekt>` |
|
|
| Sandkasten des Testkits | `~/.local/state/dc-testkit/<projekt>/sandbox` |
|
|
| Publish/Testlauf von Hand | `~/<projekt>-test` (voller Projektname, keine Kürzel) |
|
|
| Installation als Dienst | `/opt/<projekt>` |
|
|
|
|
### 5.3 systemd-Dienste
|
|
|
|
Unit-Name = Projektname: `<projekt>.service`. Eigenes Dienstkonto je Projekt:
|
|
|
|
```bash
|
|
sudo useradd --system --home-dir /opt/<projekt> --shell /usr/sbin/nologin <projekt>
|
|
```
|
|
|
|
Nach dem Test **abschalten** (Abschnitt 8) — sonst laufen irgendwann fünf Dienste, die niemand
|
|
mehr zuordnen kann, und der nächste Test misst gegen fremde Last.
|
|
|
|
> **Im Dienst ohne Heimatverzeichnis** (systemd `User=` ohne `$HOME`) fällt der Lizenz-Cache auf
|
|
> `/var/lib/<slug>/license` zurück. Ist auch das nicht beschreibbar, gibt es keinen Offline-Cache
|
|
> — dann muss `DEPLOYMENTCENTER_STORAGE_DIR` auf ein beschreibbares Verzeichnis zeigen. Das ist
|
|
> ein Fehlerbild, das nur im Dienstbetrieb auftritt und deshalb hier gehört.
|
|
|
|
### 5.4 Ports
|
|
|
|
Vor dem Belegen prüfen: `ss -tlnp`. Belegte Ports stehen in Abschnitt 7. Wer einen Port dauerhaft
|
|
belegt, trägt ihn dort ein.
|
|
|
|
### 5.5 X-Displays — feste Nummer je Projekt
|
|
|
|
Damit **mehrere Agenten gleichzeitig** Oberflächen testen können, bekommt jedes Projekt ein
|
|
eigenes virtuelles Display. Zwei Prozesse auf demselben Display sehen die Fenster des jeweils
|
|
anderen — Klicks landen im falschen Programm, Aufnahmen zeigen fremde Anwendungen.
|
|
|
|
| Display | Projekt |
|
|
|---|---|
|
|
| `:99` | **PolyTrader** |
|
|
| `:98` | **Predictalytics** |
|
|
| `:97` | **ClawdDotNet** |
|
|
| `:96` | **IBKRTrader** |
|
|
| `:95` und **absteigend** | künftige Projekte (nächstes freies von oben nach unten) |
|
|
|
|
Wer ein neues Projekt aufnimmt, trägt seine Nummer in die Belegungsliste (Abschnitt 7) ein.
|
|
|
|
**Belegte Displays prüfen:**
|
|
|
|
```bash
|
|
ls /tmp/.X11-unix/ # X0 = der echte Desktop, X99 = PolyTrader usw.
|
|
pgrep -a Xvfb # zeigt, welcher Xvfb auf welchem Display läuft
|
|
```
|
|
|
|
**Verwaiste Sockets** — beide Befehle gemeinsam lesen: Steht in `/tmp/.X11-unix/` ein `X98`, zu
|
|
dem `pgrep` keinen Prozess zeigt, ist das ein Überbleibsel eines abgestürzten oder hart beendeten
|
|
Xvfb. Die Nummer wirkt dann belegt, obwohl sie frei ist. Aufräumen:
|
|
|
|
```bash
|
|
sudo rm -f /tmp/.X11-unix/X98
|
|
```
|
|
|
|
*(Genau so entstanden: ein `xvfb-run -a`, das sich :98 nahm, weil :99 gerade lief — siehe die
|
|
Warnung in 5.7.)*
|
|
|
|
⚠️ **Drei Regeln, damit der Parallelbetrieb wirklich trägt:**
|
|
|
|
1. **`DISPLAY` in jedem Skript setzen** (`export DISPLAY=:98`). Fehlt die Variable, landet man auf
|
|
`:0` — dem echten Desktop — und stört den Menschen, der dort gerade arbeitet.
|
|
2. **Nie `pkill Xvfb` ohne Displaynummer.** Das erschlägt die Sitzungen aller anderen Projekte.
|
|
Immer `pkill -f "Xvfb :98"`. Dasselbe gilt für die eigene Anwendung: `pkill -f` mit einem zu
|
|
allgemeinen Muster trifft fremde Prozesse — besser die gemerkte PID beenden.
|
|
3. **Dateien in `/tmp` mit Projektpräfix.** `/tmp/v_1.png` überschreibt sich gegenseitig; nimm
|
|
`/tmp/<projekt>_v_1.png`. Gleiches gilt für Logdateien und Skripte.
|
|
|
|
### 5.6 Erhöhte Rechte
|
|
|
|
`sudo` verlangt normalerweise ein Passwort. Für Testläufe kann es befristet freigeschaltet werden
|
|
(**ein Mensch, einmalig**):
|
|
|
|
```bash
|
|
echo "richard ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/99-testing && sudo chmod 440 /etc/sudoers.d/99-testing
|
|
```
|
|
|
|
**Nach Abschluss wieder entfernen:**
|
|
|
|
```bash
|
|
sudo rm /etc/sudoers.d/99-testing
|
|
```
|
|
|
|
Das hebt den Schutz für das Konto vollständig auf — vertretbar auf einer Test-VM hinter VPN, aber
|
|
nicht dauerhaft und niemals auf einer Produktivmaschine.
|
|
|
|
**Für das Testkit wird das nicht gebraucht.** Es arbeitet vollständig im Benutzerkontext.
|
|
|
|
### 5.7 GUI-Anwendungen ohne Bildschirm testen
|
|
|
|
Braucht eine Anwendung X11, scheitert sie über SSH mit `XOpenDisplay failed`. Für einen einzelnen
|
|
Durchlauf genügt:
|
|
|
|
```bash
|
|
xvfb-run -n <deine-nummer> ./MeineAnwendung --irgendein-schalter
|
|
```
|
|
|
|
⚠️ **Nicht `xvfb-run -a` verwenden.** Das `-a` sucht sich selbst ein freies Display und **beginnt
|
|
dabei bei :99** — also ausgerechnet auf PolyTraders Nummer. Läuft dort gerade nichts, belegt es
|
|
diese Nummer; startet PolyTrader kurz darauf, kollidieren beide. Mit `-n 98` (bzw. der eigenen
|
|
Nummer aus 5.5) bleibt die Zuordnung eindeutig.
|
|
|
|
### 5.8 Oberflächen selbst begutachten — ohne Bildschirm, ohne fremde Hilfe
|
|
|
|
**Ein Agent kann die Oberfläche eigenständig prüfen.** Kein Mensch muss am Bildschirm sitzen und
|
|
Bildschirmfotos schicken. Das Verfahren hat sich am 26.08.2026 bewährt und **sieben Befunde
|
|
zutage gefördert**, darunter einen, der sämtliche Tabellen der Anwendung unsichtbar machte.
|
|
|
|
Drei Werkzeuge, alle installiert: **Xvfb** (virtuelles Display), **xdotool** (Klicken und Tippen),
|
|
**ImageMagick** (`import` für Aufnahmen, `convert` zum Zuschneiden).
|
|
|
|
Anders als `xvfb-run` wird das Display hier **dauerhaft** gestartet, damit sich zwischen den
|
|
Aufnahmen navigieren lässt:
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# Kopf anpassen - das ist alles, was sich je Projekt unterscheidet:
|
|
PROJEKT="polytrader"
|
|
DISP=":99" # eigene Nummer aus Abschnitt 5.5!
|
|
FENSTER="^PolyTrader$"
|
|
|
|
cd ~/$PROJEKT-test
|
|
export DISPLAY=$DISP
|
|
|
|
pkill -f "Xvfb $DISP" 2>/dev/null; sleep 1
|
|
Xvfb $DISP -screen 0 1600x1000x24 >/dev/null 2>&1 &
|
|
sleep 3
|
|
|
|
nohup ./MeineAnwendung > /tmp/${PROJEKT}_gui.log 2>&1 &
|
|
APP=$!
|
|
sleep 25 # Startzeit großzügig bemessen
|
|
|
|
# Fenster-ID ermitteln (bestaetigt, dass die Oberflaeche ueberhaupt erscheint)
|
|
xdotool search --name "$FENSTER" | head -1
|
|
|
|
# navigieren und aufnehmen - Dateinamen mit Projektpraefix, sonst
|
|
# ueberschreiben sich parallel laufende Projekte gegenseitig
|
|
shoot() { sleep 5; import -window root /tmp/${PROJEKT}_$1.png; echo " $1"; }
|
|
shoot 1_start
|
|
xdotool mousemove 127 205 click 1; shoot 2_zweite_ansicht
|
|
xdotool mousemove 127 237 click 1; shoot 3_dritte_ansicht
|
|
|
|
kill $APP 2>/dev/null; sleep 2; pkill -f "Xvfb $DISP" 2>/dev/null
|
|
```
|
|
|
|
Danach die Bilder abholen und ansehen:
|
|
|
|
```bash
|
|
scp testvm:'/tmp/polytrader_*.png' .
|
|
```
|
|
|
|
**Was sich dabei bewährt hat:**
|
|
|
|
- **Großzügige Wartezeiten.** 25 Sekunden nach dem Start, 5 Sekunden nach jedem Klick. Wird zu
|
|
früh aufgenommen, entsteht ein halb gezeichnetes Fenster, und man sucht Fehler, die keine sind.
|
|
- **Klickpunkte aus dem ersten Bild ablesen.** Erst eine Aufnahme machen, dort die Koordinaten der
|
|
Menüpunkte bestimmen, dann das Skript damit bestücken.
|
|
- **Details vergrößern statt raten.** Bei einem Verdacht den Ausschnitt herausschneiden:
|
|
```bash
|
|
convert v_1_start.png -crop 560x130+265+540 +repage -resize 200% /tmp/detail.png
|
|
```
|
|
- **Kontraste nachmessen statt schätzen.** Ob Text lesbar ist, lässt sich ausrechnen — Pixelfarben
|
|
auslesen und das WCAG-Verhältnis bestimmen (4,5:1 für normalen Text). So wird aus „wirkt blass"
|
|
ein belegter Befund.
|
|
- **Nur eine Instanz des eigenen Projekts gleichzeitig.** Läuft der systemd-Dienst noch, schreiben
|
|
zwei Prozesse in dieselbe Datenbank und es entstehen Fehler, die nichts mit der Oberfläche zu tun
|
|
haben. Vorher `sudo systemctl stop <projekt>`. (Ein **anderes** Projekt auf seinem eigenen
|
|
Display stört dagegen nicht — dafür ist die Trennung aus 5.5 da.)
|
|
- **Auf Zeichen achten, die falsch aussehen.** Fehlt eine Icon-Schriftart, ersetzt Fontconfig sie
|
|
stillschweigend durch etwas anderes — ein Kalendersymbol wird dann zu einer sinnlosen Zahl. Das
|
|
fällt nur im Bild auf, nie im Log.
|
|
|
|
Was dabei auffällt, gehört in den Bugtracker — nicht in eine Notizdatei. Siehe §4.5.
|
|
|
|
Für einen Test **mit echtem Bildschirm** kann trotzdem jemand am Desktop der VM sitzen (oder RDP
|
|
nutzen, Port 3389 ist offen) — nötig ist es für die Sichtprüfung nicht.
|
|
|
|
---
|
|
|
|
## 6. Was hier nicht passieren darf
|
|
|
|
1. **Keine Produktivdatenbank verbinden.** Hintergrunddienste schreiben oft ungefragt — bei
|
|
PolyTrader etwa synchronisiert der `MarketSyncService` selbständig Marktdaten.
|
|
2. **Keine echten Handels- oder Zugangsdaten hinterlegen.** Keine privaten Schlüssel, keine
|
|
Live-API-Zugänge. **Lizenzschlüssel nur als DEV-Schlüssel aus `dc-testkit license`** — ein
|
|
Kundenschlüssel auf einer geteilten Maschine verbraucht dessen Aktivierungsplätze und ist
|
|
hinterher nicht mehr sauber freizubekommen.
|
|
3. **Kein Token mit `*`.** Für Testläufe genügen zwei Rechte, siehe §4.2.
|
|
4. **Keine fremden Projektverzeichnisse oder Datenbanken anfassen.**
|
|
5. **Nichts veröffentlichen.** `updateservice:publish` gehört in die CI, nicht auf die Test-VM.
|
|
Ein Release aus einem Testlauf heraus wäre für Kunden sofort sichtbar.
|
|
6. **Nichts Dauerhaftes hinterlassen**, was nicht in Abschnitt 7 steht.
|
|
|
|
---
|
|
|
|
## 7. Belegung (bei Änderungen fortschreiben)
|
|
|
|
**Datenbanken**
|
|
|
|
| Datenbank | Benutzer | Projekt | seit |
|
|
|---|---|---|---|
|
|
| `polytrader_test` | `polytrader_test`@localhost | PolyTrader | 26.08.2026 |
|
|
|
|
**Dienste**
|
|
|
|
| Unit | Konto | Verzeichnis | Projekt | seit |
|
|
|---|---|---|---|---|
|
|
| `polytrader.service` | `polytrader` | `/opt/polytrader` | PolyTrader | 26.08.2026 |
|
|
|
|
**Verzeichnisse**
|
|
|
|
| Projekt | Publish-Verzeichnis | Dienst |
|
|
|---|---|---|
|
|
| PolyTrader | `~/polytrader-test` | `/opt/polytrader` |
|
|
|
|
**Werkbank-Token** (Vergabe siehe 4.2)
|
|
|
|
| Projekt | Token angelegt | Rechte |
|
|
|---|---|---|
|
|
| *noch keins* | | |
|
|
|
|
**X-Displays** (Vergabe siehe 5.5)
|
|
|
|
| Display | Projekt | Stand |
|
|
|---|---|---|
|
|
| `:0` | echter Desktop — **nie belegen** | |
|
|
| `:99` | PolyTrader | 26.08.2026 |
|
|
| `:98` | Predictalytics | reserviert |
|
|
| `:97` | ClawdDotNet | reserviert |
|
|
| `:96` | IBKRTrader | reserviert |
|
|
| `:95` abwärts | frei für künftige Projekte | |
|
|
|
|
**Ports** (Stand 26.08.2026)
|
|
|
|
| Port | Belegt durch |
|
|
|---|---|
|
|
| 22 | SSH |
|
|
| 3306 | MariaDB (nur localhost) |
|
|
| 3389 | RDP |
|
|
| 5000 | vorhandener Dienst (nur IPv6-localhost) |
|
|
| 631 | CUPS |
|
|
|
|
**Nachträglich installiert:** MariaDB 11.8.6, Xvfb, xdotool, ImageMagick, x11-utils
|
|
(alle am 26.08.2026 für PolyTrader).
|
|
|
|
---
|
|
|
|
## 8. Aufräumen nach dem Test
|
|
|
|
Das Testkit räumt sein eigenes auf:
|
|
|
|
```bash
|
|
dc-testkit cleanup # Sandkasten weg, DEV-Schlüssel zurückgegeben, Agent gelöscht
|
|
dc-testkit cleanup --sandbox # nur der Sandkasten, Schlüssel behalten
|
|
```
|
|
|
|
Alles Übrige von Hand:
|
|
|
|
```bash
|
|
# Virtuelles Display beenden (falls noch offen) - NUR das eigene!
|
|
pkill -f "Xvfb :<deine-nummer>"
|
|
rm -f /tmp/<projekt>_*.png /tmp/<projekt>_gui.log
|
|
|
|
# Dienst abschalten und entfernen
|
|
sudo systemctl disable --now <projekt>
|
|
sudo rm -f /etc/systemd/system/<projekt>.service /etc/logrotate.d/<projekt>
|
|
sudo systemctl daemon-reload
|
|
|
|
# Dateien
|
|
sudo rm -rf /opt/<projekt> ~/<projekt>-test
|
|
sudo userdel <projekt>
|
|
|
|
# Datenbank (nur wenn nicht mehr gebraucht)
|
|
sudo mariadb -e "DROP DATABASE <projekt>_test; DROP USER '<projekt>_test'@'localhost';"
|
|
rm -f ~/.<projekt>_test_dbpw
|
|
|
|
# sudo-Freigabe zurücknehmen
|
|
sudo rm -f /etc/sudoers.d/99-testing
|
|
```
|
|
|
|
Danach Abschnitt 7 nachziehen.
|
|
|
|
---
|
|
|
|
## 9. Bekannte Einschränkungen
|
|
|
|
- **Claude Code lässt sich auf dieser VM nicht betreiben.** Es blockiert die Maschine bis zum
|
|
Neustart; mehrere Reparaturversuche waren erfolglos, es wird auf ein Update gewartet. Agenten
|
|
arbeiten deshalb **über SSH von außen**. (Speichermangel ist **nicht** die Ursache — die
|
|
Maschine hat 31 GB, davon 25 GB frei.)
|
|
- **Verbindungs-Multiplexing funktioniert nicht mit Windows-OpenSSH** (siehe 2.3).
|
|
- **Der Installationsdialog ist nicht kopflos prüfbar** (siehe 4.7). Damit bleiben die Auflösung
|
|
von `setup.json` und das Schreiben der Konfiguration ungeprüft.
|
|
- **Die Systemzeitzone ist Testgegenstand.** Für realistische Servertests wird sie zeitweise auf
|
|
UTC gestellt (`sudo timedatectl set-timezone UTC`). Wer sie ändert, stellt sie danach zurück —
|
|
Standard hier ist `Europe/Berlin`.
|
|
|
|
---
|
|
|
|
## Weiterführend
|
|
|
|
| | |
|
|
|---|---|
|
|
| [LICENSE_INTEGRATION_GUIDE.md](./LICENSE_INTEGRATION_GUIDE.md) | Wie die Lizenzprüfung in der Anwendung selbst funktioniert |
|
|
| [UPDATESERVICE_INTEGRATION_GUIDE.md](./UPDATESERVICE_INTEGRATION_GUIDE.md) | Release-Verteilung, Kanäle, Signatur, Zugangsschutz der Ablage |
|
|
| [SETUP_INTEGRATION_GUIDE.md](./SETUP_INTEGRATION_GUIDE.md) | Erstinstallation und `setup.json` |
|
|
| [Agenten-Handbuch](../public/docs/bugtracker.md) | Vollständige Beschreibung des Bugtracker-Workflows |
|
|
| `GET /api/openapi.json` | Die Schnittstelle maschinenlesbar |
|