feat(setup): Erstinstallation ueber den Update-Agent, Installationskonto, Downloads
Bisher gab es nur den Update-Weg: eine Anwendung musste bereits installiert und eingerichtet sein, damit sich etwas aktualisieren liess. Die Erstinstallation auf einem neuen System war Handarbeit - Paket kopieren, Konfiguration abtippen, Token besorgen. Setup-API (neu) - POST /api/setup/v1/login tauscht Benutzername und Passwort gegen ein Token mit 30 Minuten Gueltigkeit und ausschliesslich setup:install. Es wird nicht mitgeschrieben und lebt im Installer nur im Speicher. - GET /api/setup/v1/catalog zeigt nur, was zur Laufzeitkennung des anfragenden Systems passt. Ein Projekt mit ausschliesslich Windows-Paket taucht auf einem Linux-Rechner gar nicht erst auf. - POST /api/setup/v1/token stellt das Dauertoken der Anwendung aus. Welche Rechte vergeben werden, entscheidet der Server; die Anfrage kann nur einschraenken. Sonst waere der Umweg ueber ein kurzlebiges Token wirkungslos. Rollentrennung (Migration 012) - dc_users bekommt role, disabled und last_login_at. Die Rolle "installer" darf sich ueber den Setup-Weg anmelden und nicht am WebUI. Die Zugangsdaten werden auf jedem Zielsystem eingetippt; mit einem Administratorkonto verteilte man damit den Zugang zu Tokens, Lizenzen und Monitoren auf jeden Rechner, auf dem je etwas installiert wurde. - Auth::verifyCredentials() prueft sessionfrei, damit Setup- und WebUI-Login nicht zwei verschiedene Haertungsgrade haben (Drosselung, Timing-Angleichung, Rehash gelten fuer beide). - Konten mit hinterlegtem TOTP-Geheimnis werden am Setup-Weg mit 501 abgewiesen. Eine TOTP-Pruefung gibt es im Deploymentcenter noch nicht; sie stillschweigend zu uebergehen waere ein Rueckschritt. - Benutzerverwaltung im WebUI - es gab bisher gar keine, nur den einen von install_db.php angelegten Admin. Das letzte aktive Administratorkonto laesst sich weder deaktivieren noch loeschen. Installer - update-agent --action install fuehrt durch Anmeldung, Auswahl, Zielverzeichnis, Installation und Einrichtung. Die Dateien kommen ueber denselben Pfad wie ein Update - mit Pruefsumme, Signatur, Staging und Rollback. Ein zweiter Download-Weg waere ein zweiter Ort fuer dieselben Fehler. - --action configure holt die Einrichtung nachtraeglich. - setup.json im Paket beschreibt die benoetigten Werte. Bewusst im Paket und nicht zentral: so ist sie mit der Anwendung versioniert. - Gefragt wird nur, was uebrig bleibt: bereits gesetzt -> detect:... -> provision -> fragen. Platzhalter wie changeme oder <dein-wert> gelten dabei nicht als eingerichtet, sonst liefe die Anwendung mit der Vorlage los. - SetupWriter erhaelt vorhandene Inhalte. Eine appsettings.json fuehrt neben den abgefragten Werten meist Logging und anderes; sie neu zu erzeugen waere bequemer und verloere das - bei einer Neuinstallation ohne Backup. int und bool landen als JSON-Typ, nicht als Zeichenkette. Downloads - scripts/build_installer.ps1 baut selbstenthaltende Einzeldateien fuer win-x64, linux-x64 und linux-arm64 (rund 34 MB, .NET-Laufzeit inbegriffen). Ohne NativeAOT und ohne Trimming: Spectre.Console loest ueber Reflexion auf und braeche sonst erst beim Anwender. - scripts/upload_installer.py laedt sie nach /installer/. Getrennt von deploy.py, das client-dotnet bewusst ausklammert. - Bereich "Installer" auf der UpdateService-Seite mit Groessen, Pruefsummen und den wget-Befehlen; die Angaben stammen aus installer.json statt aus fest eingetragenem Text. - install.sh und install.ps1 laden, pruefen die Pruefsumme und legen ab - sie richten bewusst nichts selbst ein. Das Manifest wird BOM-frei geschrieben, sonst scheitert json_decode() daran. Enthaelt ausserdem die bislang nicht committete Arbeit an den RocketChat-Benachrichtigungen (Migrationen 010 und 011) sowie die Loesch- und Editierfunktion des UpdateService; die betroffenen Dateien liessen sich nicht getrennt stagen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
2388b5abe1
commit
c8f3e78635
@@ -18,6 +18,7 @@ Monitoring und einen Bugtracker, den Coding-Agenten selbständig bedienen.
|
||||
- **[Lizenzsystem (Hardware-ID v2)](./LICENSE_INTEGRATION_GUIDE.md)** — Hardware-Anbindung, Schlüsselvalidierung, Offline-Cache, CLI, Windows und Linux/Docker
|
||||
- **[Watchdog (Heartbeat & Telemetrie)](./WATCHDOG_INTEGRATION_GUIDE.md)** — Überwachung von Anwendungen, Diensten und Infrastruktur
|
||||
- **[UpdateService](./UPDATESERVICE_INTEGRATION_GUIDE.md)** — Release-Verteilung und Update-Prüfung
|
||||
- **[Erstinstallation](./SETUP_INTEGRATION_GUIDE.md)** — `setup.json`, Installationskonto, `update-agent --action install`
|
||||
- **[Bugtracker](./BUGTRACKER_INTEGRATION_GUIDE.md)** — Anbindung aus Anwendungen heraus
|
||||
|
||||
---
|
||||
@@ -31,6 +32,7 @@ Monitoring und einen Bugtracker, den Coding-Agenten selbständig bedienen.
|
||||
| **Watchdog** | Heartbeat-Monitoring, Zustandsbewertung, Alarmierung | `/api/watchdog/v1/ping`<br>`/api/watchdog/v1/evaluate` | Token mit `watchdog:ping` |
|
||||
| **Lizenzen** | Lizenzprüfung, Hardware-ID v2, Offline-Cache | `/api/license/v1/validate`<br>`/api/license/v1/deactivate` | Validierung offen, Deaktivierung authentifiziert |
|
||||
| **Tokens** | Selbst-Provisionierung von Sub-Tokens | `/api/tokens/v1/provision` | Master-Token |
|
||||
| **Setup** | Erstinstallation: Anmeldung, Katalog, Anwendungstoken | `/api/setup/v1/login`<br>`/api/setup/v1/catalog`<br>`/api/setup/v1/token` | Login offen, Rest `setup:*` |
|
||||
| **System** | Verfügbarkeit, Schema-Status, Schnittstellenbeschreibung | `/api/health`<br>`/api/openapi.json` | Health optional, OpenAPI offen |
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
# Deploymentcenter — Erstinstallation von Anwendungen
|
||||
|
||||
> **Neu in Version 2.3.** Bis dahin gab es nur den Update-Weg: eine Anwendung
|
||||
> musste bereits installiert und eingerichtet sein, damit sich etwas
|
||||
> aktualisieren ließ. Die Erstinstallation auf einem neuen System war
|
||||
> Handarbeit — Paket kopieren, Konfiguration abtippen, Token besorgen,
|
||||
> Monitoring nachtragen.
|
||||
|
||||
Die Erstinstallation läuft jetzt über denselben `update-agent`, der auch
|
||||
Updates einspielt. Kein eigener Installer je Anwendung, kein MSI, kein
|
||||
Setup-Assistent im Anwendungscode.
|
||||
|
||||
```bash
|
||||
update-agent --action install
|
||||
```
|
||||
|
||||
Mehr braucht es nicht. Der Rest ist ein Dialog.
|
||||
|
||||
---
|
||||
|
||||
## 0. Den Installer besorgen
|
||||
|
||||
Im WebUI unter **UpdateService → ⬇️ Installer**, oder direkt vom Server.
|
||||
|
||||
**Linux** — lädt das zur Architektur passende Binary, prüft die Prüfsumme und legt es ab:
|
||||
|
||||
```bash
|
||||
wget -qO- https://dc.mhdf.de/installer/install.sh | sh
|
||||
```
|
||||
|
||||
Ohne Skript geht es genauso:
|
||||
|
||||
```bash
|
||||
wget https://dc.mhdf.de/installer/update-agent-linux-x64 -O update-agent
|
||||
```
|
||||
|
||||
**Windows** (PowerShell):
|
||||
|
||||
```powershell
|
||||
irm https://dc.mhdf.de/installer/install.ps1 | iex
|
||||
```
|
||||
|
||||
| Datei | Plattform |
|
||||
|---|---|
|
||||
| `/installer/update-agent-win-x64.exe` | Windows x64 |
|
||||
| `/installer/update-agent-linux-x64` | Linux x64 |
|
||||
| `/installer/update-agent-linux-arm64` | Linux ARM64 |
|
||||
| `/installer/installer.json` | Version, Größen und Prüfsummen aller Binaries |
|
||||
|
||||
Zu jedem Binary liegt eine `.sha256` daneben. **Die Prüfsumme vergleichen** —
|
||||
„Programm herunterladen und Zugangsdaten eingeben" ist genau das Muster, das
|
||||
Phishing nachahmt; die Prüfsumme ist der Grund, warum man es hier trotzdem tun
|
||||
kann. Die Bootstrap-Skripte tun das automatisch und brechen bei Abweichung ab.
|
||||
|
||||
Die Skripte richten **nichts** von selbst ein. Sie laden, prüfen, legen ab und
|
||||
sagen, wie es weitergeht — ein Skript aus dem Netz, das ungefragt eine
|
||||
Anwendung aufsetzt und dabei nach Zugangsdaten fragt, wäre genau das, wovor man
|
||||
Nutzer sonst warnt.
|
||||
|
||||
Rund 34 MB je Plattform: Das Binary bringt die .NET-Laufzeit mit, damit auf
|
||||
einem frisch aufgesetzten System nichts vorinstalliert sein muss. Bewusst ohne
|
||||
NativeAOT und ohne Trimming — Spectre.Console löst seine Eingabeaufforderungen
|
||||
über Reflexion auf; getrimmt baut das zwar, bricht aber erst beim Anwender.
|
||||
|
||||
### Neu bauen und hochladen
|
||||
|
||||
```bash
|
||||
pwsh scripts/build_installer.ps1
|
||||
python scripts/upload_installer.py ./artifacts/installer
|
||||
```
|
||||
|
||||
`deploy.py` klammert `client-dotnet` bewusst aus — der Quelltext des Agenten
|
||||
gehört nicht auf den Webserver, die übersetzten Binaries schon. Deshalb der
|
||||
eigene Upload-Weg.
|
||||
|
||||
---
|
||||
|
||||
## 1. Der Ablauf
|
||||
|
||||
```
|
||||
update-agent --action install
|
||||
├ Deploymentcenter? https://dc.mhdf.de
|
||||
├ Benutzer / Passwort → kurzlebiges Token (30 Minuten)
|
||||
├ Auswahl aus dem Katalog → nur, was auf dieser Plattform läuft
|
||||
├ Kanal (prod / beta / dev)
|
||||
├ Zielverzeichnis → vorbelegt mit /opt/<slug> bzw. Programme\<slug>
|
||||
├ Paket laden, Prüfsumme, Signatur, Entpacken ← der reguläre Update-Weg
|
||||
├ setup.json auflösen → fragt nur, was übrig bleibt
|
||||
└ Konfiguration schreiben
|
||||
```
|
||||
|
||||
Die Dateien kommen über **denselben Pfad wie ein Update** ins Zielverzeichnis:
|
||||
mit SHA256-Prüfung, Signaturprüfung, Staging und Rollback. Ein zweiter
|
||||
Download-Weg wäre ein zweiter Ort, an dem dieselben Fehler wieder entstehen.
|
||||
|
||||
---
|
||||
|
||||
## 2. Das Installationskonto
|
||||
|
||||
Für Zielsysteme gibt es die Rolle **`installer`**. Im WebUI unter
|
||||
**System → 👤 Benutzer** anzulegen.
|
||||
|
||||
Ein solches Konto kann genau zwei Dinge: sich über `/api/setup/v1/login`
|
||||
anmelden und Anwendungen einrichten. **Am WebUI kann es sich nicht anmelden** —
|
||||
der Versuch wird abgewiesen und protokolliert.
|
||||
|
||||
Das ist der Kern der Sache: Die Zugangsdaten werden auf jedem Zielsystem
|
||||
eingetippt, auf dem je etwas installiert wird. Mit einem Administratorkonto
|
||||
verteilte man damit den Zugang zu Tokens, Lizenzen, Monitoren und dem
|
||||
Bugtracker auf all diese Rechner.
|
||||
|
||||
| | admin | installer |
|
||||
|---|---|---|
|
||||
| WebUI | ja | **nein** |
|
||||
| `/api/setup/v1/*` | ja | ja |
|
||||
| Token ausstellen | alle Rechte | nur `watchdog:ping`, `watchdog:read`, `bugtracker:report`, `updateservice:read` |
|
||||
|
||||
> **Noch offen: der zweite Faktor.** `dc_users.totp_secret` existiert als
|
||||
> Spalte, wird aber von keinem Anmeldeweg ausgewertet — es gibt bislang keine
|
||||
> TOTP-Prüfung im Deploymentcenter. Ein Konto mit hinterlegtem Geheimnis wird
|
||||
> von der Setup-Anmeldung deshalb ausdrücklich **abgelehnt** (`501
|
||||
> totp_not_supported`), statt den zweiten Faktor stillschweigend zu übergehen.
|
||||
> Bis das nachgezogen ist, tragen ein langes Passwort und die enge
|
||||
> Rechtevergabe die Sicherheit.
|
||||
|
||||
---
|
||||
|
||||
## 3. `setup.json`
|
||||
|
||||
Die Datei beschreibt, was eine Anwendung zum Laufen braucht. Sie gehört in das
|
||||
Publish-Verzeichnis und landet damit im Paket, neben der `manifest.json`.
|
||||
|
||||
**Bewusst im Paket und nicht zentral im Deploymentcenter.** So ist die
|
||||
Beschreibung mit der Anwendung versioniert: Braucht Version 2.0 ein Feld mehr
|
||||
als 1.9, stimmt es automatisch. Eine zweite Pflegestelle liefe früher oder
|
||||
später auseinander.
|
||||
|
||||
Vollständige Vorlage: **[setup.example.json](./setup.example.json)**
|
||||
|
||||
```json
|
||||
{
|
||||
"schema": 1,
|
||||
"displayName": "Beispielanwendung",
|
||||
"targets": [
|
||||
{ "id": "app", "file": "appsettings.json", "format": "json" }
|
||||
],
|
||||
"fields": [
|
||||
{ "key": "ConnectionStrings:Main", "label": "Datenbank", "type": "secret" },
|
||||
{ "key": "Deploymentcenter:BaseUrl", "source": "detect:baseurl", "type": "url" },
|
||||
{ "key": "Deploymentcenter:Token", "source": "provision",
|
||||
"scopes": ["watchdog:ping"] }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Fehlt die Datei, lässt sich die Anwendung trotzdem installieren — der Installer
|
||||
entpackt sie dann nur und fragt nichts ab.
|
||||
|
||||
### Felder
|
||||
|
||||
| Eigenschaft | Bedeutung |
|
||||
|---|---|
|
||||
| `key` | Schlüssel im Ziel. Doppelpunkte trennen Ebenen (`ConnectionStrings:Main`) — die Schreibweise von `Microsoft.Extensions.Configuration` |
|
||||
| `label` | Beschriftung der Frage |
|
||||
| `help` | Erläuterung, die darüber steht |
|
||||
| `type` | `string`, `secret`, `url`, `int`, `bool`, `enum` |
|
||||
| `required` | Vorgabe `true` |
|
||||
| `default` | Vorbelegung der Eingabe |
|
||||
| `source` | `ask` (Vorgabe), `detect:…`, `provision` |
|
||||
| `scopes` | Rechte, wenn `source: "provision"` |
|
||||
| `options` | Auswahl bei `type: "enum"` |
|
||||
| `validate` | Regulärer Ausdruck |
|
||||
| `target` | `id` des Ziels, wenn es mehrere gibt |
|
||||
|
||||
`type` bestimmt auch, **wie** geschrieben wird: `int` und `bool` landen als
|
||||
JSON-Zahl beziehungsweise -Wahrheitswert, nicht als Zeichenkette. Sonst
|
||||
scheitert die Bindung in der Anwendung.
|
||||
|
||||
### Nur die wirklich fehlenden Informationen
|
||||
|
||||
Je Feld gilt die erste zutreffende Regel:
|
||||
|
||||
| Regel | fragt |
|
||||
|---|---|
|
||||
| Wert steht schon in der Zieldatei und ist kein Platzhalter | nein |
|
||||
| `source: "detect:…"` | nein |
|
||||
| `source: "provision"` | nein |
|
||||
| sonst | **ja**, mit `default` vorbelegt |
|
||||
|
||||
Erkannte Platzhalter (`changeme`, `TODO`, `your-…`, `<…>`, `example.com` und
|
||||
ähnliche) gelten **nicht** als eingerichteter Wert — sonst liefe die Anwendung
|
||||
mit der ausgelieferten Vorlage los.
|
||||
|
||||
Ableitbare Werte: `detect:hostname`, `detect:platform`, `detect:installdir`,
|
||||
`detect:project`, `detect:baseurl`, `detect:username`.
|
||||
|
||||
### Das Token der Anwendung
|
||||
|
||||
`source: "provision"` lässt den Server ein Dauertoken ausstellen, das an das
|
||||
Projekt und den Rechnernamen gebunden ist. Der Installer schreibt es in das
|
||||
angegebene Feld; niemand muss es sehen oder kopieren.
|
||||
|
||||
Welche Rechte vergeben werden, entscheidet **der Server**, nicht die Anfrage.
|
||||
Die `scopes` aus der `setup.json` können nur einschränken. Andernfalls wäre der
|
||||
Umweg über ein kurzlebiges Setup-Token wirkungslos — wer einmal installieren
|
||||
darf, stellte sich sonst ein Token mit allen Rechten aus und behielte es.
|
||||
|
||||
---
|
||||
|
||||
## 4. Konfiguration schreiben
|
||||
|
||||
**Vorhandene Inhalte bleiben erhalten.** Eine `appsettings.json` enthält neben
|
||||
den abgefragten Werten fast immer Logging-Einstellungen, Feature-Schalter und
|
||||
anderes. Die Datei neu zu erzeugen wäre der bequemere Weg und verlöre all das —
|
||||
und zwar bei einer Neuinstallation, bei der niemand ein Backup hat.
|
||||
|
||||
- **JSON**: Ebenen werden aus dem Schlüssel gebildet, bestehende Zweige bleiben
|
||||
stehen. Kommentare und nachgestellte Kommata werden beim Lesen toleriert.
|
||||
- **env**: bestehende Zeilen werden ersetzt, unbekannte Schlüssel angehängt.
|
||||
Kommentare und Reihenfolge bleiben erhalten. `A:B` wird zu `A__B`.
|
||||
|
||||
Ist eine vorhandene Datei kein gültiges JSON, wird sie als
|
||||
`<name>.unlesbar-<zeitstempel>` zur Seite gelegt statt überschrieben.
|
||||
|
||||
Zusammenspiel mit `preservePatterns` des Packagers: Die Vorlage wird
|
||||
ausgeliefert (Erstinstallation bekommt sie), ein Update ersetzt sie nicht, und
|
||||
der Installer schreibt die abgefragten Werte hinein. Siehe
|
||||
**[UPDATESERVICE_INTEGRATION_GUIDE §3A](./UPDATESERVICE_INTEGRATION_GUIDE.md#3a-ausschließen-oder-schützen)**.
|
||||
|
||||
---
|
||||
|
||||
## 5. Nachträglich einrichten
|
||||
|
||||
```bash
|
||||
update-agent --action configure --target-dir /opt/myapp --project myapp
|
||||
```
|
||||
|
||||
Liest die `setup.json` der bestehenden Installation und fragt nur, was noch
|
||||
fehlt. Nach Zugangsdaten wird dabei nur gefragt, wenn ein Feld mit
|
||||
`source: "provision"` vorkommt — sonst braucht es den Server gar nicht.
|
||||
|
||||
---
|
||||
|
||||
## 6. Schnittstelle
|
||||
|
||||
| Aufruf | Zweck | Authentifizierung |
|
||||
|---|---|---|
|
||||
| `POST /api/setup/v1/login` | Benutzername + Passwort → Setup-Token | keine |
|
||||
| `GET /api/setup/v1/catalog` | Was ist hier installierbar? | `setup:catalog` |
|
||||
| `POST /api/setup/v1/token` | Dauertoken der Anwendung | `setup:install` |
|
||||
|
||||
```bash
|
||||
curl -X POST https://dc.mhdf.de/api/setup/v1/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"installer","password":"…","hostname":"srv-07"}'
|
||||
```
|
||||
|
||||
```json
|
||||
{ "status": "success", "setup_token": "dc_setup_…", "expires_in": 1800,
|
||||
"scopes": ["setup:install"], "role": "installer" }
|
||||
```
|
||||
|
||||
Das Setup-Token lebt **nur im Speicher** des Installers, wird nirgends abgelegt
|
||||
und läuft nach 30 Minuten ab. Was auf dem System zurückbleibt, ist das
|
||||
Dauertoken der Anwendung mit genau den Rechten, die sie braucht.
|
||||
|
||||
Der Katalog zeigt ausschließlich, was zur Laufzeitkennung des anfragenden
|
||||
Systems passt. Ein Projekt, von dem es nur ein Windows-Paket gibt, taucht auf
|
||||
einem Linux-Rechner gar nicht erst auf — alles andere wäre eine Auswahl, die
|
||||
beim Anklicken fehlschlägt.
|
||||
|
||||
---
|
||||
|
||||
## 7. Was noch fehlt
|
||||
|
||||
Diese Fassung ist Stufe 1. Bewusst noch nicht enthalten:
|
||||
|
||||
| Fehlt | Bedeutet |
|
||||
|---|---|
|
||||
| **Zentrale Geheimnisse** | Datenbankzugang und API-Schlüssel werden je Installation eingetippt. Stufe 2 hinterlegt sie verschlüsselt je *(Projekt, Umgebung)* im Deploymentcenter, sodass `source: "bundle:…"` sie automatisch zieht |
|
||||
| **Übernahme früherer Antworten** | Die zweite Installation derselben Anwendung fragt dasselbe noch einmal |
|
||||
| **Verbindungstests** | Ob die eingegebene Datenbankverbindung wirklich trägt, zeigt sich erst beim ersten Start |
|
||||
| **TOTP** | Siehe [§2](#2-das-installationskonto) |
|
||||
| **Dienstregistrierung** | systemd-Unit beziehungsweise Windows-Dienst legt der Installer nicht an |
|
||||
| **Watchdog-Eintrag** | Der Monitor entsteht beim ersten Heartbeat, nicht schon bei der Installation |
|
||||
@@ -634,3 +634,47 @@ auf. War der Wechsel beabsichtigt, die Datei löschen.
|
||||
|
||||
Ohne hinterlegten Schlüssel bleibt also alles funktionsfähig — es fehlt nur die
|
||||
Vertrauenskette, und darauf wird bei jedem Update hingewiesen.
|
||||
|
||||
---
|
||||
|
||||
## 7. Release-Verwaltung (Bearbeiten & Löschen)
|
||||
|
||||
Veröffentlichte Releases können sowohl über das Web-Interface als auch über die API nachträglich bearbeitet oder gelöscht werden.
|
||||
|
||||
### Web-Interface (`public/index.php`)
|
||||
- Im Tab **UpdateService** → **📦 Veröffentlichte Software Releases** enthält jede Zeile die Aktionen `✏️ Bearbeiten` und `🗑️ Löschen`.
|
||||
- **Bearbeiten**: Öffnet einen Modal-Dialog, in dem Release-Notes, Download-URL, SHA256-Hash, Git Commit, Plattform, Kanal, Version und IsCritical angepasst werden können. Beim Speichern wird die kanonische Signatur serverseitig neu berechnet.
|
||||
- **Löschen**: Entfernt nach Bestätigung den Release-Datensatz aus der Datenbank.
|
||||
|
||||
### API-Endpunkte
|
||||
|
||||
#### Release Bearbeiten
|
||||
- **POST** `/api/updateservice/v1/update` (oder `action=update` / `action=edit`)
|
||||
- Scope: `updateservice:publish`
|
||||
- Parameter: `release_id` (oder `id`), optional updated `product_slug`, `version`, `channel`, `platform`, `download_url`, `sha256_hash`, `git_commit`, `release_notes`, `size_bytes`, `is_critical`.
|
||||
- Antwort (200 OK):
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"release_id": 42,
|
||||
"updated": true,
|
||||
"platform": "win-x64",
|
||||
"signed": true,
|
||||
"message": "Release 1.2.0 (prod, win-x64) fuer \"myapp\" erfolgreich aktualisiert."
|
||||
}
|
||||
```
|
||||
|
||||
#### Release Löschen
|
||||
- **POST / DELETE** `/api/updateservice/v1/delete` (oder `action=delete`)
|
||||
- Scope: `updateservice:publish`
|
||||
- Parameter: `release_id` (oder `id`) ODER die Kombination aus `product_slug`, `version`, `channel`, `platform`.
|
||||
- Antwort (200 OK):
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"release_id": 42,
|
||||
"deleted": true,
|
||||
"message": "Release v1.2.0 (prod, win-x64) fuer \"myapp\" geloescht."
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"_comment": "Vorlage fuer setup.json. Gehoert ins Wurzelverzeichnis des Publish-Ordners, damit sie im Paket neben der manifest.json landet. Der Installer liest sie nach dem Entpacken und fragt genau die Werte ab, die er nicht selbst ermitteln kann.",
|
||||
|
||||
"schema": 1,
|
||||
"displayName": "Beispielanwendung",
|
||||
"description": "Fuer den Betrieb werden eine Datenbank und ein Zugang zum Kursdatenanbieter benoetigt.",
|
||||
|
||||
"_targets_comment": "Wohin geschrieben wird. Pfade sind relativ zum Installationsverzeichnis. format ist 'json' oder 'env'. Ueber 'id' lassen sich einzelne Felder gezielt einer Datei zuordnen; ohne Angabe schreibt ein Feld in das erste Ziel.",
|
||||
"targets": [
|
||||
{ "id": "app", "file": "appsettings.json", "format": "json" },
|
||||
{ "id": "env", "file": ".env", "format": "env" }
|
||||
],
|
||||
|
||||
"_fields_comment": "source steuert, ob gefragt wird: 'ask' (Vorgabe) fragt nach, 'detect:...' leitet ab, 'provision' laesst ein Token ausstellen. Ist der Wert in der Zieldatei bereits gesetzt und kein Platzhalter, wird er uebernommen und nicht erneut erfragt.",
|
||||
"fields": [
|
||||
{
|
||||
"key": "ConnectionStrings:Main",
|
||||
"label": "Datenbankverbindung",
|
||||
"help": "Beispiel: Server=localhost;Database=beispiel;User Id=app;Password=...;",
|
||||
"type": "secret",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"key": "Marktdaten:ApiKey",
|
||||
"label": "API-Schluessel des Kursdatenanbieters",
|
||||
"type": "secret",
|
||||
"required": true,
|
||||
"validate": "^[A-Za-z0-9_-]{20,}$",
|
||||
"validationMessage": "Der Schluessel besteht aus mindestens 20 Zeichen ohne Leerzeichen."
|
||||
},
|
||||
{
|
||||
"key": "Deploymentcenter:BaseUrl",
|
||||
"label": "Deploymentcenter",
|
||||
"type": "url",
|
||||
"source": "detect:baseurl"
|
||||
},
|
||||
{
|
||||
"key": "Deploymentcenter:Token",
|
||||
"label": "Token dieser Installation",
|
||||
"source": "provision",
|
||||
"scopes": ["watchdog:ping", "bugtracker:report"]
|
||||
},
|
||||
{
|
||||
"key": "Watchdog:Source",
|
||||
"label": "Name im Monitoring",
|
||||
"source": "detect:hostname"
|
||||
},
|
||||
{
|
||||
"key": "Watchdog:IntervalSeconds",
|
||||
"label": "Heartbeat-Intervall in Sekunden",
|
||||
"type": "int",
|
||||
"default": "60",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"key": "Features:BetaAktiv",
|
||||
"label": "Beta-Funktionen einschalten",
|
||||
"type": "bool",
|
||||
"default": "false",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"key": "LOGLEVEL",
|
||||
"label": "Protokollierungsstufe",
|
||||
"target": "env",
|
||||
"type": "enum",
|
||||
"options": ["Debug", "Information", "Warning", "Error"],
|
||||
"default": "Information",
|
||||
"required": false
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user