Replace GraphQL Unraid MCP with MUA
This commit is contained in:
+1
-1
@@ -747,7 +747,7 @@ services:
|
|||||||
# Seed native MCP connections on a fresh Open WebUI database. Secrets
|
# Seed native MCP connections on a fresh Open WebUI database. Secrets
|
||||||
# stay inside the tool containers, so these internal URLs need no keys.
|
# stay inside the tool containers, so these internal URLs need no keys.
|
||||||
TOOL_SERVER_CONNECTIONS: >-
|
TOOL_SERVER_CONNECTIONS: >-
|
||||||
[{"url":"http://mike-ai-mcp-platform-context:8000/mcp","path":"","type":"mcp","auth_type":"none","headers":null,"key":"","config":{"enable":true,"access_grants":[]},"info":{"id":"athena-platform","name":"Athena Plattformwissen","description":"Zuerst aktivieren und verwenden, wenn an Athena/MikeAI, Modellen, Profilen, Router, OpenWebUI, MCPs, TTS/STT, Vision, Netzwerk oder Recovery gearbeitet wird. Liefert versionierte Dokumentation und einen begrenzten aktuellen Systemstand. Dokumentationspflege nur über Vorschau und ausdrückliche Freigabe; keine Container-, Shell-, Netzwerk-, Git- oder Secretrechte."}},{"url":"http://mike-ai-mcp-web:8000/mcp","path":"","type":"mcp","auth_type":"none","headers":null,"key":"","config":{"enable":true,"access_grants":[]},"info":{"id":"web-local","name":"Web (öffentlich, read-only)","description":"Für aktuelle öffentliche Internetdaten, Quellenprüfung, Hugging Face und Produktsuche. Für GitHub-Quellcode den offiziellen GitHub-MCP verwenden; nicht für Home Assistant, Medienverwaltung oder NAS-Diagnose."}},{"url":"http://mike-ai-mcp-github:8000/mcp","path":"","type":"mcp","auth_type":"none","headers":null,"key":"","config":{"enable":true,"access_grants":[]},"info":{"id":"github-local","name":"GitHub (offiziell, read-only)","description":"Für GitHub-Repositories, Quellcode, README-Dateien, Verzeichnisbäume und Code-Suche. Strikt read-only mit genau vier Werkzeugen; nicht für allgemeine Webrecherche oder Änderungen an Repositories."}},{"url":"http://mike-ai-mcp-homeassistant:8000/mcp","path":"","type":"mcp","auth_type":"none","headers":null,"key":"","config":{"enable":true,"access_grants":[]},"info":{"id":"homeassistant-local","name":"Home Assistant (lokal)","description":"Für Home-Assistant-Entitäten, Zustände, Historie, Automationen, Dashboards, HA-Diagnose und freigegebene YAML-Dateien. YAML-Lesen ist begrenzt; Änderungen benötigen serverseitige Vorschau, explizite Freigabe, Sicherung und Validierung. Nicht für Unraid, Sonarr/Radarr oder allgemeine Websuche."}},{"url":"http://mike-ai-mcp-arr:8000/mcp","path":"","type":"mcp","auth_type":"none","headers":null,"key":"","config":{"enable":true,"access_grants":[]},"info":{"id":"arr-local","name":"Sonarr und Radarr (lokal)","description":"Nur für verwaltete Serien/Filme, fehlende Episoden, Queue und Suche über konfigurierte Indexer. Keine allgemeine Websuche; Schreibaktionen benötigen Vorschau und Freigabe."}},{"url":"http://mike-ai-mcp-navidrome:3000/mcp","path":"","type":"mcp","auth_type":"none","headers":null,"key":"","config":{"enable":true,"access_grants":[]},"info":{"id":"navidrome-local","name":"Navidrome (Musikbibliothek)","description":"Nur für die persönliche Navidrome-Musikbibliothek: Titel, Alben, Künstler, Playlists, Favoriten und Hörverlauf. Nicht für Sonarr/Radarr, allgemeine Websuche oder Audioausgabe auf dem KI-Host. Wegen des großen Werkzeugkatalogs nur bei Musikaufgaben aktivieren."}},{"url":"http://mike-ai-mcp-unraid-official:8000/mcp","path":"","type":"mcp","auth_type":"none","headers":null,"key":"","config":{"enable":true,"access_grants":[]},"info":{"id":"unraid-readonly-local","name":"Unraid (Systemdiagnose)","description":"Nur für Unraid-Host, Array, Datenträger, Docker-Container, Shares, Netzwerk, UPS und Systemlogs. Nicht für Home Assistant oder Medieninhalte; Standardzugriff read-only."}}]
|
[{"url":"http://mike-ai-mcp-platform-context:8000/mcp","path":"","type":"mcp","auth_type":"none","headers":null,"key":"","config":{"enable":true,"access_grants":[]},"info":{"id":"athena-platform","name":"Athena Plattformwissen","description":"Zuerst aktivieren und verwenden, wenn an Athena/MikeAI, Modellen, Profilen, Router, OpenWebUI, MCPs, TTS/STT, Vision, Netzwerk oder Recovery gearbeitet wird. Liefert versionierte Dokumentation und einen begrenzten aktuellen Systemstand. Dokumentationspflege nur über Vorschau und ausdrückliche Freigabe; keine Container-, Shell-, Netzwerk-, Git- oder Secretrechte."}},{"url":"http://mike-ai-mcp-web:8000/mcp","path":"","type":"mcp","auth_type":"none","headers":null,"key":"","config":{"enable":true,"access_grants":[]},"info":{"id":"web-local","name":"Web (öffentlich, read-only)","description":"Für aktuelle öffentliche Internetdaten, Quellenprüfung, Hugging Face und Produktsuche. Für GitHub-Quellcode den offiziellen GitHub-MCP verwenden; nicht für Home Assistant, Medienverwaltung oder NAS-Diagnose."}},{"url":"http://mike-ai-mcp-github:8000/mcp","path":"","type":"mcp","auth_type":"none","headers":null,"key":"","config":{"enable":true,"access_grants":[]},"info":{"id":"github-local","name":"GitHub (offiziell, read-only)","description":"Für GitHub-Repositories, Quellcode, README-Dateien, Verzeichnisbäume und Code-Suche. Strikt read-only mit genau vier Werkzeugen; nicht für allgemeine Webrecherche oder Änderungen an Repositories."}},{"url":"http://mike-ai-mcp-homeassistant:8000/mcp","path":"","type":"mcp","auth_type":"none","headers":null,"key":"","config":{"enable":true,"access_grants":[]},"info":{"id":"homeassistant-local","name":"Home Assistant (lokal)","description":"Für Home-Assistant-Entitäten, Zustände, Historie, Automationen, Dashboards, HA-Diagnose und freigegebene YAML-Dateien. YAML-Lesen ist begrenzt; Änderungen benötigen serverseitige Vorschau, explizite Freigabe, Sicherung und Validierung. Nicht für Unraid, Sonarr/Radarr oder allgemeine Websuche."}},{"url":"http://mike-ai-mcp-arr:8000/mcp","path":"","type":"mcp","auth_type":"none","headers":null,"key":"","config":{"enable":true,"access_grants":[]},"info":{"id":"arr-local","name":"Sonarr und Radarr (lokal)","description":"Nur für verwaltete Serien/Filme, fehlende Episoden, Queue und Suche über konfigurierte Indexer. Keine allgemeine Websuche; Schreibaktionen benötigen Vorschau und Freigabe."}},{"url":"http://mike-ai-mcp-navidrome:3000/mcp","path":"","type":"mcp","auth_type":"none","headers":null,"key":"","config":{"enable":true,"access_grants":[]},"info":{"id":"navidrome-local","name":"Navidrome (Musikbibliothek)","description":"Nur für die persönliche Navidrome-Musikbibliothek: Titel, Alben, Künstler, Playlists, Favoriten und Hörverlauf. Nicht für Sonarr/Radarr, allgemeine Websuche oder Audioausgabe auf dem KI-Host. Wegen des großen Werkzeugkatalogs nur bei Musikaufgaben aktivieren."}}]
|
||||||
DO_NOT_TRACK: "true"
|
DO_NOT_TRACK: "true"
|
||||||
SCARF_NO_ANALYTICS: "true"
|
SCARF_NO_ANALYTICS: "true"
|
||||||
dns: ["${AI_DNS:-1.1.1.1}"]
|
dns: ["${AI_DNS:-1.1.1.1}"]
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Root-only auf Athena unter /etc/mike-ai/mua-mcp.env ablegen (Modus 0600).
|
||||||
|
# Der echte Bearer-Token gehört niemals ins Git-Repository.
|
||||||
|
MUA_MCP_URL=http://192.168.1.2:3002/mcp
|
||||||
|
MUA_MCP_BEARER_TOKEN=REPLACE_WITH_MUA_BEARER_TOKEN
|
||||||
@@ -51,7 +51,6 @@ Das Skript nimmt ausschließlich auf:
|
|||||||
|
|
||||||
- `/etc/mike-ai` einschließlich aller Fach-MCP-Secrets,
|
- `/etc/mike-ai` einschließlich aller Fach-MCP-Secrets,
|
||||||
- `/root/mike-ai-install.env`,
|
- `/root/mike-ai-install.env`,
|
||||||
- das lokale `runraid`-Binary, falls vorhanden,
|
|
||||||
- das produktive Dokumentations-Overlay unter `/opt/mike-ai/stack/docs`,
|
- das produktive Dokumentations-Overlay unter `/opt/mike-ai/stack/docs`,
|
||||||
- Vorschläge, Sicherungen und Auditstatus des Platform Context MCP unter
|
- Vorschläge, Sicherungen und Auditstatus des Platform Context MCP unter
|
||||||
`/data/mike-ai-platform-context`,
|
`/data/mike-ai-platform-context`,
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@
|
|||||||
| Platform Context MCP | Athena-/MikeAI-Wissen, begrenzter Laufzeitsnapshot und kontrollierte Dokumentationspflege | eigener Container ohne Docker-Socket, Shell, Egress oder Secrets | Kern |
|
| Platform Context MCP | Athena-/MikeAI-Wissen, begrenzter Laufzeitsnapshot und kontrollierte Dokumentationspflege | eigener Container ohne Docker-Socket, Shell, Egress oder Secrets | Kern |
|
||||||
| Athena Operator MCP | Entwicklung und vollständiger Betrieb der KI-Plattform mit gebundenen Freigaben | unprivilegierte MCP-Fassade plus rootseitiger strukturierter Executor; keine freie Shell | Kern |
|
| Athena Operator MCP | Entwicklung und vollständiger Betrieb der KI-Plattform mit gebundenen Freigaben | unprivilegierte MCP-Fassade plus rootseitiger strukturierter Executor; keine freie Shell | Kern |
|
||||||
| Operator-Kontext | `docs/QWEN_OPERATOR_CONTEXT.md` plus `config/operator-system-prompt.txt` | versionierte Selbstbeschreibung und Sicherheitsregeln für Qwen | Kern |
|
| Operator-Kontext | `docs/QWEN_OPERATOR_CONTEXT.md` plus `config/operator-system-prompt.txt` | versionierte Selbstbeschreibung und Sicherheitsregeln für Qwen | Kern |
|
||||||
| Unraid-MCP | lokales `runraid`-Binary | eigener optionaler Container | optional |
|
| Unraid/MUA | MUA-Plugin auf dem HomeServer, direkter MCP-Endpunkt | read-only Automatik plus bewusst aktivierte Verwaltung in Open WebUI | Kern |
|
||||||
| Whisper | ggml-org/whisper.cpp | Service im Router-Deploy | optional |
|
| Whisper | ggml-org/whisper.cpp | Service im Router-Deploy | optional |
|
||||||
| XTTS-v2 | Coqui, offizielles CUDA-12.1-Image per Digest | RTX-3060-Container, Stimme `Annmarie Nele`, CPML | Kern |
|
| XTTS-v2 | Coqui, offizielles CUDA-12.1-Image per Digest | RTX-3060-Container, Stimme `Annmarie Nele`, CPML | Kern |
|
||||||
| TTS-Gateway | `platform/docker/tts-gateway/` | interne Queue, stabile deutsche Satzblöcke, automatische Erkennung rein englischer Texte und Piper-Fallback | Kern |
|
| TTS-Gateway | `platform/docker/tts-gateway/` | interne Queue, stabile deutsche Satzblöcke, automatische Erkennung rein englischer Texte und Piper-Fallback | Kern |
|
||||||
|
|||||||
@@ -175,6 +175,11 @@ mit erweiterten Verwaltungsrechten bleibt von der Automatik ausgeschlossen;
|
|||||||
eine automatisch bereitgestellte Verbindung erteilt niemals Schreibrechte
|
eine automatisch bereitgestellte Verbindung erteilt niemals Schreibrechte
|
||||||
oder eine Änderungsfreigabe.
|
oder eine Änderungsfreigabe.
|
||||||
|
|
||||||
|
Unraid ist ausschließlich über das MUA-Plugin angebunden. Die automatische
|
||||||
|
Verbindung `mua-readonly-local` und die bewusst aktivierte Verbindung `mua`
|
||||||
|
nutzen denselben MUA-Endpunkt. Der frühere GraphQL-basierte Unraid-MCP wurde
|
||||||
|
entfernt und gehört weder zum Start noch zum Recovery.
|
||||||
|
|
||||||
Der GitHub-Container läuft produktiv. Token-Datei, interner
|
Der GitHub-Container läuft produktiv. Token-Datei, interner
|
||||||
Streamable-HTTP-Handshake, fehlende Host-Portfreigabe und exakt vier
|
Streamable-HTTP-Handshake, fehlende Host-Portfreigabe und exakt vier
|
||||||
read-only Werkzeuge wurden am 23. August 2026 verifiziert.
|
read-only Werkzeuge wurden am 23. August 2026 verifiziert.
|
||||||
|
|||||||
@@ -162,10 +162,14 @@ vorhanden ist:
|
|||||||
/etc/mike-ai/homeassistant-admin-mcp.env
|
/etc/mike-ai/homeassistant-admin-mcp.env
|
||||||
/etc/mike-ai/arr-mcp.env
|
/etc/mike-ai/arr-mcp.env
|
||||||
/etc/mike-ai/navidrome-mcp.env
|
/etc/mike-ai/navidrome-mcp.env
|
||||||
/etc/mike-ai/runraid/.env
|
/etc/mike-ai/mua-mcp.env
|
||||||
/usr/local/bin/runraid Version 0.4.2
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Die MUA-Datei wird nach `config/mua-mcp.env.example` angelegt und mit Modus
|
||||||
|
`0600` geschützt. Sie verbindet Open WebUI direkt mit dem MUA-Plugin auf dem
|
||||||
|
Unraid-HomeServer. Unraids GraphQL-API wird nicht benötigt und soll deaktiviert
|
||||||
|
bleiben.
|
||||||
|
|
||||||
Nach dem Nachreichen einer Datei genügt:
|
Nach dem Nachreichen einer Datei genügt:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
+1
-2
@@ -53,8 +53,7 @@ Das Skript prüft zuerst die Archiv-Hashes und übernimmt ausschließlich:
|
|||||||
- die persistente OpenWebUI-Datenbank samt Einstellungen und Uploads,
|
- die persistente OpenWebUI-Datenbank samt Einstellungen und Uploads,
|
||||||
- das zur Datenbank passende, gesicherte OpenWebUI-Container-Image,
|
- das zur Datenbank passende, gesicherte OpenWebUI-Container-Image,
|
||||||
- den dazugehörigen WebUI- und Router-Schlüssel,
|
- den dazugehörigen WebUI- und Router-Schlüssel,
|
||||||
- die freigegebenen HA-, ARR- und Unraid-Secrets,
|
- die freigegebenen HA-, ARR- und MUA-/Unraid-Secrets.
|
||||||
- `runraid`, dessen privaten Schlüssel, Zertifikat und Known-Hosts-Datei.
|
|
||||||
|
|
||||||
Es übernimmt bewusst **keine** alten Compose-Dateien, Routerprofile,
|
Es übernimmt bewusst **keine** alten Compose-Dateien, Routerprofile,
|
||||||
Experimentdienste oder `.before-*`-Altstände. Vor dem Ersetzen des frischen
|
Experimentdienste oder `.before-*`-Altstände. Vor dem Ersetzen des frischen
|
||||||
|
|||||||
@@ -71,6 +71,9 @@ erzeugt nicht ungefragt eine zweite Deemix-Instanz.
|
|||||||
Automatische Unraid-Abfragen verwenden einen eigenen MUA-Read-only-Zugang, der
|
Automatische Unraid-Abfragen verwenden einen eigenen MUA-Read-only-Zugang, der
|
||||||
in Open WebUI ausschließlich Diagnosewerkzeuge sichtbar macht. Der vollständige
|
in Open WebUI ausschließlich Diagnosewerkzeuge sichtbar macht. Der vollständige
|
||||||
MUA-Verwaltungszugang bleibt davon getrennt und muss bewusst gewählt werden.
|
MUA-Verwaltungszugang bleibt davon getrennt und muss bewusst gewählt werden.
|
||||||
|
Beide Verbindungen sprechen denselben MCP-Endpunkt des MUA-Plugins auf dem
|
||||||
|
HomeServer an. Athena betreibt keinen zusätzlichen Unraid-GraphQL-MCP; die
|
||||||
|
GraphQL-API von Unraid darf deaktiviert bleiben.
|
||||||
|
|
||||||
Open WebUI und Router veröffentlichen keinen normalen Host-Port. Der
|
Open WebUI und Router veröffentlichen keinen normalen Host-Port. Der
|
||||||
WireGuard-Gateway-Container stellt nur die vorgesehenen VPN-Endpunkte bereit.
|
WireGuard-Gateway-Container stellt nur die vorgesehenen VPN-Endpunkte bereit.
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ Netzzugriff. Kein MCP-Port wird am Host veröffentlicht.
|
|||||||
| Home Assistant | Zustände, Historie, Diagnose, begrenzte YAML-Abläufe | Lesen; Schreiben nur Preview/Approval |
|
| Home Assistant | Zustände, Historie, Diagnose, begrenzte YAML-Abläufe | Lesen; Schreiben nur Preview/Approval |
|
||||||
| ARR | Sonarr/Radarr, Indexersuche, kontrollierte Grabs | Lesen; Schreiben nur Preview/Approval |
|
| ARR | Sonarr/Radarr, Indexersuche, kontrollierte Grabs | Lesen; Schreiben nur Preview/Approval |
|
||||||
| Navidrome | Bibliothek, Empfehlungen, Playlists/Favoriten | eigener Benutzer; gezielt aktivieren |
|
| Navidrome | Bibliothek, Empfehlungen, Playlists/Favoriten | eigener Benutzer; gezielt aktivieren |
|
||||||
| Unraid | Host-, Docker-, Array-, Netzwerk- und Logdiagnose | read-only Standard |
|
| MUA read-only | Host-, Docker-, Array-, Netzwerk- und Logdiagnose | automatischer Standard |
|
||||||
| MUA/Admin | eng definierte Unraid-Verwaltung | bewusst aktivieren |
|
| MUA/Admin | eng definierte Unraid-Verwaltung | bewusst aktivieren |
|
||||||
|
|
||||||
Für automatische Unraid-Diagnose existiert in Open WebUI zusätzlich
|
Für automatische Unraid-Diagnose existiert in Open WebUI zusätzlich
|
||||||
@@ -247,6 +247,8 @@ Für automatische Unraid-Diagnose existiert in Open WebUI zusätzlich
|
|||||||
blendet aber Start/Stop, Installation, Änderungen und die freie Root-Shell
|
blendet aber Start/Stop, Installation, Änderungen und die freie Root-Shell
|
||||||
serverseitig in Open WebUI aus. Die vollständige Verbindung `mua` wird niemals
|
serverseitig in Open WebUI aus. Die vollständige Verbindung `mua` wird niemals
|
||||||
automatisch bereitgestellt.
|
automatisch bereitgestellt.
|
||||||
|
Es gibt keinen zweiten GraphQL-basierten Unraid-MCP. Schlägt MUA fehl, darf
|
||||||
|
nicht auf GraphQL ausgewichen oder dessen API eigenmächtig aktiviert werden.
|
||||||
|
|
||||||
Der vorhandene Deemix-Dienst läuft auf Unraid und ist als externe Abhängigkeit
|
Der vorhandene Deemix-Dienst läuft auf Unraid und ist als externe Abhängigkeit
|
||||||
im Diensteverzeichnis eingetragen. Für ein Deemix-MCP wird standardmäßig nur
|
im Diensteverzeichnis eingetragen. Für ein Deemix-MCP wird standardmäßig nur
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ Im Repository gesichert sind inzwischen:
|
|||||||
Noch extern zu beschaffen und exakt festzuhalten sind:
|
Noch extern zu beschaffen und exakt festzuhalten sind:
|
||||||
|
|
||||||
- Home-Assistant-MCP
|
- Home-Assistant-MCP
|
||||||
- `runraid` 0.4.2 für den read-only Unraid-MCP
|
- MUA-Plugin auf dem Unraid-HomeServer sowie die root-only gesicherte
|
||||||
- gegebenenfalls eigener Unraid-Administrations-MCP
|
`/etc/mike-ai/mua-mcp.env`
|
||||||
- LLama-GUI, falls sie erhalten bleibt
|
- LLama-GUI, falls sie erhalten bleibt
|
||||||
|
|
||||||
Jede noch externe Komponente bekommt zusätzlich:
|
Jede noch externe Komponente bekommt zusätzlich:
|
||||||
|
|||||||
@@ -64,8 +64,7 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
for optional in mike-ai-mcp-web mike-ai-mcp-homeassistant mike-ai-mcp-arr \
|
for optional in mike-ai-mcp-web mike-ai-mcp-homeassistant mike-ai-mcp-arr \
|
||||||
mike-ai-mcp-github mike-ai-mcp-platform-context mike-ai-mcp-athena-operator \
|
mike-ai-mcp-github mike-ai-mcp-platform-context mike-ai-mcp-athena-operator; do
|
||||||
mike-ai-mcp-unraid-official; do
|
|
||||||
if container_healthy "$optional"; then
|
if container_healthy "$optional"; then
|
||||||
pass "$optional aktiv"
|
pass "$optional aktiv"
|
||||||
else
|
else
|
||||||
@@ -73,6 +72,12 @@ for optional in mike-ai-mcp-web mike-ai-mcp-homeassistant mike-ai-mcp-arr \
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if docker ps -a --format '{{.Names}}' | grep -qx 'mike-ai-mcp-unraid-official'; then
|
||||||
|
fail "veralteter GraphQL-basierter Unraid-MCP ist noch vorhanden"
|
||||||
|
else
|
||||||
|
pass "kein GraphQL-basierter Unraid-MCP vorhanden"
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ -s /var/lib/mike-ai-platform-context/runtime.json ]]; then
|
if [[ -s /var/lib/mike-ai-platform-context/runtime.json ]]; then
|
||||||
snapshot_age=$(( $(date +%s) - $(stat -c %Y /var/lib/mike-ai-platform-context/runtime.json) ))
|
snapshot_age=$(( $(date +%s) - $(stat -c %Y /var/lib/mike-ai-platform-context/runtime.json) ))
|
||||||
if (( snapshot_age <= 180 )); then
|
if (( snapshot_age <= 180 )); then
|
||||||
|
|||||||
@@ -60,10 +60,8 @@ case "${1:-}" in
|
|||||||
start_proxy mike-ai-emergency-mcp-web mike-ai-tools 18090 mike-ai-mcp-web
|
start_proxy mike-ai-emergency-mcp-web mike-ai-tools 18090 mike-ai-mcp-web
|
||||||
start_proxy mike-ai-emergency-mcp-homeassistant mike-ai-tools 18091 mike-ai-mcp-homeassistant
|
start_proxy mike-ai-emergency-mcp-homeassistant mike-ai-tools 18091 mike-ai-mcp-homeassistant
|
||||||
start_proxy mike-ai-emergency-mcp-arr mike-ai-tools 18092 mike-ai-mcp-arr
|
start_proxy mike-ai-emergency-mcp-arr mike-ai-tools 18092 mike-ai-mcp-arr
|
||||||
start_proxy mike-ai-emergency-mcp-unraid mike-ai-tools 18093 mike-ai-mcp-unraid-official
|
|
||||||
|
|
||||||
echo 'Notfall-Proxys laufen ausschließlich auf 127.0.0.1.'
|
echo 'Notfall-Proxys laufen ausschließlich auf 127.0.0.1.'
|
||||||
echo 'Jetzt vom Client einen SSH-Tunnel auf die Ports 18080 und 18090-18093 öffnen.'
|
echo 'Jetzt vom Client einen SSH-Tunnel auf die Ports 18080 und 18090-18092 öffnen.'
|
||||||
;;
|
;;
|
||||||
stop)
|
stop)
|
||||||
remove_proxies
|
remove_proxies
|
||||||
|
|||||||
+13
-3
@@ -17,9 +17,14 @@ Prompts heraus, verhindert den früher beobachteten Kontextverbrauch von über
|
|||||||
| `mcp-arr` | `http://mike-ai-mcp-arr:8000/mcp` | Sonarr/Radarr/Prowlarr mit serverseitiger Policy | Profil `arr` |
|
| `mcp-arr` | `http://mike-ai-mcp-arr:8000/mcp` | Sonarr/Radarr/Prowlarr mit serverseitiger Policy | Profil `arr` |
|
||||||
| `mcp-navidrome` | `http://mike-ai-mcp-navidrome:3000/mcp` | Navidrome-Bibliothek, Suche, Playlists, Favoriten und Hörverlauf | Profil `navidrome` |
|
| `mcp-navidrome` | `http://mike-ai-mcp-navidrome:3000/mcp` | Navidrome-Bibliothek, Suche, Playlists, Favoriten und Hörverlauf | Profil `navidrome` |
|
||||||
| `mcp-github` | `http://mike-ai-mcp-github:8000/mcp` | offizieller GitHub-MCP, auf vier reine Repository-Lesewerkzeuge begrenzt | Profil `github` |
|
| `mcp-github` | `http://mike-ai-mcp-github:8000/mcp` | offizieller GitHub-MCP, auf vier reine Repository-Lesewerkzeuge begrenzt | Profil `github` |
|
||||||
| `mcp-unraid-official` | `http://mike-ai-mcp-unraid-official:8000/mcp` | offizieller, read-only begrenzter Unraid-Zugang | Profil `unraid` |
|
|
||||||
| `mcp-unraid-ssh` | `http://mike-ai-mcp-unraid-ssh:8000/mcp` | erweiterte Diagnose über einen erzwungenen SSH-Befehl | optional (`extended`) |
|
| `mcp-unraid-ssh` | `http://mike-ai-mcp-unraid-ssh:8000/mcp` | erweiterte Diagnose über einen erzwungenen SSH-Befehl | optional (`extended`) |
|
||||||
|
|
||||||
|
Unraid wird produktiv ausschließlich über das auf dem HomeServer laufende
|
||||||
|
MUA-Plugin (`http://192.168.1.2:3002/mcp`) angebunden. Open WebUI führt davon
|
||||||
|
zwei Ansichten: `mua-readonly-local` für automatische Diagnose und `mua` für
|
||||||
|
bewusst aktivierte Verwaltungsaktionen. Ein GraphQL-basierter Unraid-MCP ist
|
||||||
|
nicht Bestandteil des Stacks.
|
||||||
|
|
||||||
Die drei Websuch-Container verwenden `AI_DNS` aus
|
Die drei Websuch-Container verwenden `AI_DNS` aus
|
||||||
`/etc/mike-ai/stack.env`. Der Web-MCP hängt zusätzlich am getrennten
|
`/etc/mike-ai/stack.env`. Der Web-MCP hängt zusätzlich am getrennten
|
||||||
`mike-ai-tools-egress`-Netz, weil er gefundene öffentliche Seiten nach der
|
`mike-ai-tools-egress`-Netz, weil er gefundene öffentliche Seiten nach der
|
||||||
@@ -88,7 +93,7 @@ passenden Server wählen:
|
|||||||
| Entitäten, Zustände, Historie, Automationen und Dashboards | Home Assistant | Web, Unraid |
|
| Entitäten, Zustände, Historie, Automationen und Dashboards | Home Assistant | Web, Unraid |
|
||||||
| Serien, Filme, fehlende Episoden und Indexer-Releases | Sonarr und Radarr | Web |
|
| Serien, Filme, fehlende Episoden und Indexer-Releases | Sonarr und Radarr | Web |
|
||||||
| Persönliche Musikbibliothek, Titel, Alben, Künstler und Playlists | Navidrome | Web, ARR |
|
| Persönliche Musikbibliothek, Titel, Alben, Künstler und Playlists | Navidrome | Web, ARR |
|
||||||
| Lesende NAS-, Docker-, Array-, Netzwerk- und Logdiagnose | Unraid (Systemdiagnose) | MUA |
|
| Lesende NAS-, Docker-, Array-, Netzwerk- und Logdiagnose | MUA · Unraid-Diagnose (read-only) | MUA-Verwaltung |
|
||||||
| Athena-KI-Plattform entwickeln, testen, deployen, Modelle/Git/Recovery pflegen | Athena Operator | Platform Context für reine Architekturauskunft |
|
| Athena-KI-Plattform entwickeln, testen, deployen, Modelle/Git/Recovery pflegen | Athena Operator | Platform Context für reine Architekturauskunft |
|
||||||
| Ausdrücklich benötigte MUA-Verwaltungsaktion | MUA | Unraid-Diagnose nicht parallel |
|
| Ausdrücklich benötigte MUA-Verwaltungsaktion | MUA | Unraid-Diagnose nicht parallel |
|
||||||
|
|
||||||
@@ -132,9 +137,14 @@ Die lokale Installation benötigt die vorhandenen Secret-Dateien:
|
|||||||
/etc/mike-ai/arr-mcp.env
|
/etc/mike-ai/arr-mcp.env
|
||||||
/etc/mike-ai/navidrome-mcp.env
|
/etc/mike-ai/navidrome-mcp.env
|
||||||
/etc/mike-ai/github-mcp.env
|
/etc/mike-ai/github-mcp.env
|
||||||
/etc/mike-ai/runraid/.env
|
/etc/mike-ai/mua-mcp.env
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`mua-mcp.env` enthält ausschließlich MUA-Endpunkt und Bearer-Token. Der
|
||||||
|
Installer legt daraus die vollständige MUA-Verbindung und eine strikt auf
|
||||||
|
Lesewerkzeuge begrenzte automatische Ansicht an. Die Datei ist root-only
|
||||||
|
(Modus `0600`) und wird nur verschlüsselt im Recovery-Bundle gesichert.
|
||||||
|
|
||||||
Die erweiterte Unraid-Diagnose benötigt zusätzlich die Konfigurationsdatei,
|
Die erweiterte Unraid-Diagnose benötigt zusätzlich die Konfigurationsdatei,
|
||||||
den eingeschränkten Schlüssel und die bekannte Hostsignatur. Sie wird nur mit
|
den eingeschränkten Schlüssel und die bekannte Hostsignatur. Sie wird nur mit
|
||||||
`--profile extended` gestartet.
|
`--profile extended` gestartet.
|
||||||
|
|||||||
@@ -213,29 +213,6 @@ services:
|
|||||||
retries: 5
|
retries: 5
|
||||||
start_period: 15s
|
start_period: 15s
|
||||||
|
|
||||||
mcp-unraid-official:
|
|
||||||
<<: *tool-common
|
|
||||||
image: debian:13-slim
|
|
||||||
container_name: mike-ai-mcp-unraid-official
|
|
||||||
profiles: [unraid]
|
|
||||||
env_file:
|
|
||||||
- ${RUNRAID_ENV_FILE:-/etc/mike-ai/runraid/.env}
|
|
||||||
environment:
|
|
||||||
UNRAID_RMCP_HOST: 0.0.0.0
|
|
||||||
UNRAID_RMCP_PORT: "8000"
|
|
||||||
UNRAID_RMCP_DISABLE_HTTP_AUTH: "true"
|
|
||||||
UNRAID_NOAUTH: "true"
|
|
||||||
UNRAID_RMCP_ALLOWED_HOSTS: "mike-ai-mcp-unraid-official:8000,mike-ai-mcp-unraid-official,localhost:8000,127.0.0.1:8000"
|
|
||||||
# Public DNS cannot resolve the Fritzbox-only name. Preserve the hostname
|
|
||||||
# used by the TLS endpoint while binding it to the verified home-LAN IP.
|
|
||||||
extra_hosts:
|
|
||||||
- "homeserver.fritz.box:192.168.1.2"
|
|
||||||
volumes:
|
|
||||||
- ${RUNRAID_BINARY:-/usr/local/bin/runraid}:/usr/local/bin/unraid:ro
|
|
||||||
entrypoint: ["/usr/local/bin/unraid"]
|
|
||||||
command: ["serve"]
|
|
||||||
networks: [tools, egress]
|
|
||||||
|
|
||||||
mcp-unraid-ssh:
|
mcp-unraid-ssh:
|
||||||
<<: *tool-common
|
<<: *tool-common
|
||||||
profiles: [extended]
|
profiles: [extended]
|
||||||
|
|||||||
@@ -61,12 +61,6 @@ if [[ -s /etc/mike-ai/github-mcp.env ]] && \
|
|||||||
else
|
else
|
||||||
echo "GitHub bleibt aus: dedizierter Read-only-Token fehlt."
|
echo "GitHub bleibt aus: dedizierter Read-only-Token fehlt."
|
||||||
fi
|
fi
|
||||||
if [[ -s /etc/mike-ai/runraid/.env && -x /usr/local/bin/runraid ]]; then
|
|
||||||
profiles+=(--profile unraid)
|
|
||||||
else
|
|
||||||
echo "Unraid bleibt aus: runraid 0.4.2 oder Secret-Datei fehlt."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# TinySearch keeps the embedding bundle outside the container. Download it
|
# TinySearch keeps the embedding bundle outside the container. Download it
|
||||||
# once on a fresh host; subsequent rebuilds reuse the named volume.
|
# once on a fresh host; subsequent rebuilds reuse the named volume.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -107,11 +107,8 @@ tar -xzf "$mcp_archive" -C "$stage/approved" \
|
|||||||
etc/mike-ai/router-api-key \
|
etc/mike-ai/router-api-key \
|
||||||
etc/mike-ai/homeassistant-admin-mcp.env \
|
etc/mike-ai/homeassistant-admin-mcp.env \
|
||||||
etc/mike-ai/arr-mcp.env \
|
etc/mike-ai/arr-mcp.env \
|
||||||
etc/mike-ai/runraid/.env \
|
|
||||||
etc/mike-ai/runraid/homeserver-cert.pem \
|
|
||||||
etc/mike-ai/keys/unraid_root \
|
etc/mike-ai/keys/unraid_root \
|
||||||
etc/mike-ai/ssh/known_hosts_unraid_ai \
|
etc/mike-ai/ssh/known_hosts_unraid_ai
|
||||||
usr/local/bin/runraid
|
|
||||||
|
|
||||||
old_router_key=$(<"$stage/approved/etc/mike-ai/router-api-key")
|
old_router_key=$(<"$stage/approved/etc/mike-ai/router-api-key")
|
||||||
[[ -n $old_router_key ]] || die "Router-Key in der Sicherung ist leer."
|
[[ -n $old_router_key ]] || die "Router-Key in der Sicherung ist leer."
|
||||||
@@ -151,21 +148,15 @@ if [[ -f $INSTALL_CONFIG ]]; then
|
|||||||
set_env_value "$INSTALL_CONFIG" OPENWEBUI_IMAGE "$REFERENCE_OPENWEBUI_TAG"
|
set_env_value "$INSTALL_CONFIG" OPENWEBUI_IMAGE "$REFERENCE_OPENWEBUI_TAG"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
install -d -m 0700 "$SECRETS_DIR/runraid" "$SECRETS_DIR/keys" "$SECRETS_DIR/ssh"
|
install -d -m 0700 "$SECRETS_DIR/keys" "$SECRETS_DIR/ssh"
|
||||||
install -m 0600 "$stage/approved/etc/mike-ai/homeassistant-admin-mcp.env" \
|
install -m 0600 "$stage/approved/etc/mike-ai/homeassistant-admin-mcp.env" \
|
||||||
"$SECRETS_DIR/homeassistant-admin-mcp.env"
|
"$SECRETS_DIR/homeassistant-admin-mcp.env"
|
||||||
install -m 0600 "$stage/approved/etc/mike-ai/arr-mcp.env" \
|
install -m 0600 "$stage/approved/etc/mike-ai/arr-mcp.env" \
|
||||||
"$SECRETS_DIR/arr-mcp.env"
|
"$SECRETS_DIR/arr-mcp.env"
|
||||||
install -m 0600 "$stage/approved/etc/mike-ai/runraid/.env" \
|
|
||||||
"$SECRETS_DIR/runraid/.env"
|
|
||||||
install -m 0600 "$stage/approved/etc/mike-ai/runraid/homeserver-cert.pem" \
|
|
||||||
"$SECRETS_DIR/runraid/homeserver-cert.pem"
|
|
||||||
install -m 0600 "$stage/approved/etc/mike-ai/keys/unraid_root" \
|
install -m 0600 "$stage/approved/etc/mike-ai/keys/unraid_root" \
|
||||||
"$SECRETS_DIR/keys/unraid_root"
|
"$SECRETS_DIR/keys/unraid_root"
|
||||||
install -m 0600 "$stage/approved/etc/mike-ai/ssh/known_hosts_unraid_ai" \
|
install -m 0600 "$stage/approved/etc/mike-ai/ssh/known_hosts_unraid_ai" \
|
||||||
"$SECRETS_DIR/ssh/known_hosts_unraid_ai"
|
"$SECRETS_DIR/ssh/known_hosts_unraid_ai"
|
||||||
install -m 0755 "$stage/approved/usr/local/bin/runraid" /usr/local/bin/runraid
|
|
||||||
|
|
||||||
log "Tool-Container mit der neuen Stackdefinition aktivieren"
|
log "Tool-Container mit der neuen Stackdefinition aktivieren"
|
||||||
"$STACK_DIR/platform/mcp/install-tools.sh"
|
"$STACK_DIR/platform/mcp/install-tools.sh"
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ CONTAINER=${OPENWEBUI_CONTAINER:-mike-ai-open-webui}
|
|||||||
VOLUME=${OPENWEBUI_VOLUME:-mike-ai_open-webui-data}
|
VOLUME=${OPENWEBUI_VOLUME:-mike-ai_open-webui-data}
|
||||||
FILTER_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/filters" && pwd)
|
FILTER_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/filters" && pwd)
|
||||||
ACTION_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/actions" && pwd)
|
ACTION_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/actions" && pwd)
|
||||||
|
MUA_MCP_ENV_FILE=${MUA_MCP_ENV_FILE:-/etc/mike-ai/mua-mcp.env}
|
||||||
|
|
||||||
die() { printf 'FEHLER: %s\n' "$*" >&2; exit 1; }
|
die() { printf 'FEHLER: %s\n' "$*" >&2; exit 1; }
|
||||||
[[ $EUID -eq 0 ]] || die "Bitte als root ausführen."
|
[[ $EUID -eq 0 ]] || die "Bitte als root ausführen."
|
||||||
@@ -42,7 +43,7 @@ if [[ -s /etc/mike-ai/github-mcp.env ]] && \
|
|||||||
grep -Eq '^GITHUB_PERSONAL_ACCESS_TOKEN=.+$' /etc/mike-ai/github-mcp.env; then
|
grep -Eq '^GITHUB_PERSONAL_ACCESS_TOKEN=.+$' /etc/mike-ai/github-mcp.env; then
|
||||||
github_enabled=true
|
github_enabled=true
|
||||||
fi
|
fi
|
||||||
python3 - "$db" "$FILTER_DIR" "$ACTION_DIR" "${OPENWEBUI_FILTER_OWNER_ID:-}" "$navidrome_enabled" "$github_enabled" <<'PY'
|
python3 - "$db" "$FILTER_DIR" "$ACTION_DIR" "${OPENWEBUI_FILTER_OWNER_ID:-}" "$navidrome_enabled" "$github_enabled" "$MUA_MCP_ENV_FILE" <<'PY'
|
||||||
import json
|
import json
|
||||||
import copy
|
import copy
|
||||||
import pathlib
|
import pathlib
|
||||||
@@ -50,7 +51,10 @@ import sqlite3
|
|||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
db, filter_dir, action_dir, requested_owner, navidrome_enabled_raw, github_enabled_raw = sys.argv[1:]
|
(
|
||||||
|
db, filter_dir, action_dir, requested_owner, navidrome_enabled_raw,
|
||||||
|
github_enabled_raw, mua_mcp_env_file,
|
||||||
|
) = sys.argv[1:]
|
||||||
navidrome_enabled = navidrome_enabled_raw.lower() == "true"
|
navidrome_enabled = navidrome_enabled_raw.lower() == "true"
|
||||||
github_enabled = github_enabled_raw.lower() == "true"
|
github_enabled = github_enabled_raw.lower() == "true"
|
||||||
con = sqlite3.connect(db)
|
con = sqlite3.connect(db)
|
||||||
@@ -173,8 +177,9 @@ with con:
|
|||||||
isinstance(connection, dict)
|
isinstance(connection, dict)
|
||||||
and (
|
and (
|
||||||
str((connection.get("info") or {}).get("id", "")).lower()
|
str((connection.get("info") or {}).get("id", "")).lower()
|
||||||
== "athena-terminal-local"
|
in {"athena-terminal-local", "unraid-readonly-local"}
|
||||||
or "mike-ai-mcp-athena-terminal" in str(connection.get("url", "")).lower()
|
or "mike-ai-mcp-athena-terminal" in str(connection.get("url", "")).lower()
|
||||||
|
or "mike-ai-mcp-unraid-official" in str(connection.get("url", "")).lower()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@@ -199,14 +204,8 @@ with con:
|
|||||||
"konfigurierte Indexer. Keine allgemeine Websuche; Schreibaktionen benötigen "
|
"konfigurierte Indexer. Keine allgemeine Websuche; Schreibaktionen benötigen "
|
||||||
"Vorschau und Freigabe.",
|
"Vorschau und Freigabe.",
|
||||||
),
|
),
|
||||||
"unraid-readonly-local": (
|
|
||||||
"Unraid (Systemdiagnose)",
|
|
||||||
"Bevorzugtes Werkzeug für lesende Unraid-Diagnose: Host, Array, Datenträger, "
|
|
||||||
"Docker, Shares, Netzwerk, UPS und Logs. Für dieselbe Anfrage nicht zusätzlich "
|
|
||||||
"MUA aufrufen; MUA nur für dessen spezielle oder freigegebene Verwaltungsaktionen.",
|
|
||||||
),
|
|
||||||
"mua-readonly-local": (
|
"mua-readonly-local": (
|
||||||
"Unraid-Diagnose (MUA read-only)",
|
"MUA · Unraid-Diagnose (read-only)",
|
||||||
"Automatisch verwendbarer, serverseitig in Open WebUI auf reine Lese- und "
|
"Automatisch verwendbarer, serverseitig in Open WebUI auf reine Lese- und "
|
||||||
"Diagnosewerkzeuge begrenzter MUA-Zugang. Für Containerbestand, Logs, System, "
|
"Diagnosewerkzeuge begrenzter MUA-Zugang. Für Containerbestand, Logs, System, "
|
||||||
"Storage, Shares und Netzwerkstatus. Keine Start/Stop-, Installations-, "
|
"Storage, Shares und Netzwerkstatus. Keine Start/Stop-, Installations-, "
|
||||||
@@ -215,8 +214,8 @@ with con:
|
|||||||
"mua": (
|
"mua": (
|
||||||
"MUA (Unraid-Verwaltung)",
|
"MUA (Unraid-Verwaltung)",
|
||||||
"Nur für ausdrücklich benötigte MUA-spezifische oder freigegebene Unraid-"
|
"Nur für ausdrücklich benötigte MUA-spezifische oder freigegebene Unraid-"
|
||||||
"Verwaltungsaktionen. Für reine Statusabfragen und Diagnosen stattdessen "
|
"Verwaltungsaktionen. Für reine Statusabfragen und Diagnosen die read-only-"
|
||||||
"Unraid (Systemdiagnose) verwenden; niemals beide parallel ausprobieren.",
|
"MUA-Verbindung verwenden; niemals beide parallel ausprobieren.",
|
||||||
),
|
),
|
||||||
"navidrome-local": (
|
"navidrome-local": (
|
||||||
"Navidrome (Musikbibliothek)",
|
"Navidrome (Musikbibliothek)",
|
||||||
@@ -267,8 +266,6 @@ with con:
|
|||||||
match = "github-local"
|
match = "github-local"
|
||||||
elif "mike-ai-mcp-athena-operator" in url:
|
elif "mike-ai-mcp-athena-operator" in url:
|
||||||
match = "athena-operator-local"
|
match = "athena-operator-local"
|
||||||
elif "mike-ai-mcp-unraid-official" in url:
|
|
||||||
match = "unraid-readonly-local"
|
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
name, description = descriptions[match]
|
name, description = descriptions[match]
|
||||||
@@ -289,6 +286,30 @@ with con:
|
|||||||
),
|
),
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
if mua_source is None and pathlib.Path(mua_mcp_env_file).is_file():
|
||||||
|
mua_env = {}
|
||||||
|
for raw_line in pathlib.Path(mua_mcp_env_file).read_text().splitlines():
|
||||||
|
line = raw_line.strip()
|
||||||
|
if not line or line.startswith("#") or "=" not in line:
|
||||||
|
continue
|
||||||
|
key, value = line.split("=", 1)
|
||||||
|
mua_env[key.strip()] = value.strip().strip('"').strip("'")
|
||||||
|
mua_url = mua_env.get("MUA_MCP_URL", "")
|
||||||
|
mua_token = mua_env.get("MUA_MCP_BEARER_TOKEN", "")
|
||||||
|
if mua_url and mua_token:
|
||||||
|
name, description = descriptions["mua"]
|
||||||
|
mua_source = {
|
||||||
|
"url": mua_url,
|
||||||
|
"path": "",
|
||||||
|
"type": "mcp",
|
||||||
|
"auth_type": "bearer",
|
||||||
|
"headers": None,
|
||||||
|
"key": mua_token,
|
||||||
|
"config": {"enable": True, "access_grants": []},
|
||||||
|
"info": {"id": "mua", "name": name, "description": description},
|
||||||
|
}
|
||||||
|
connections.append(mua_source)
|
||||||
|
changed = True
|
||||||
if mua_source is not None:
|
if mua_source is not None:
|
||||||
readonly_functions = ",".join((
|
readonly_functions = ",".join((
|
||||||
"unraid_docker_list", "unraid_docker_inspect", "unraid_docker_logs",
|
"unraid_docker_list", "unraid_docker_inspect", "unraid_docker_logs",
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ mkdir -p "$stage/rootfs" "$stage/payload"
|
|||||||
for source in \
|
for source in \
|
||||||
/etc/mike-ai \
|
/etc/mike-ai \
|
||||||
/root/mike-ai-install.env \
|
/root/mike-ai-install.env \
|
||||||
/usr/local/bin/runraid \
|
|
||||||
/opt/mike-ai/stack/docs \
|
/opt/mike-ai/stack/docs \
|
||||||
/data/mike-ai-platform-context; do
|
/data/mike-ai-platform-context; do
|
||||||
[[ -e $source ]] || continue
|
[[ -e $source ]] || continue
|
||||||
|
|||||||
@@ -44,9 +44,6 @@ tar -C "$stage/rootfs" -xzf "$stage/host-config.tar.gz"
|
|||||||
install -d -m 0700 /etc/mike-ai
|
install -d -m 0700 /etc/mike-ai
|
||||||
rsync -a "$stage/rootfs/etc/mike-ai/" /etc/mike-ai/
|
rsync -a "$stage/rootfs/etc/mike-ai/" /etc/mike-ai/
|
||||||
install -m 0600 "$stage/rootfs/root/mike-ai-install.env" /root/mike-ai-install.env
|
install -m 0600 "$stage/rootfs/root/mike-ai-install.env" /root/mike-ai-install.env
|
||||||
if [[ -x $stage/rootfs/usr/local/bin/runraid ]]; then
|
|
||||||
install -m 0755 "$stage/rootfs/usr/local/bin/runraid" /usr/local/bin/runraid
|
|
||||||
fi
|
|
||||||
|
|
||||||
log "Reproduzierbaren Host-Installer ausführen"
|
log "Reproduzierbaren Host-Installer ausführen"
|
||||||
set +e
|
set +e
|
||||||
|
|||||||
Reference in New Issue
Block a user