Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6e07f672a | ||
|
|
d32e7e59c3 | ||
|
|
4f8e65b76b | ||
|
|
a2605a2802 | ||
|
|
0588a8d9b3 |
@@ -4,6 +4,12 @@
|
||||
FROM python:3.11-slim-bullseye
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
# PyInstaller braucht objdump aus binutils (im slim-Image nicht enthalten).
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends binutils \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN pip install --no-cache-dir pyinstaller
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# Baut die Windows-.exe des Host-Agents AUF LINUX — via Wine + Windows-Python +
|
||||
# PyInstaller. tobix/pywine bringt Wine + Windows-Python 3.11 mit (PyInstaller
|
||||
# kann NICHT cross-compilen, deshalb der Wine-Umweg).
|
||||
#
|
||||
# Zusaetzlich baut NSIS ein setup.exe, das die Agent-.exe installiert, eine .env
|
||||
# in C:\ProgramData\ARIA-Host-Agent anlegt (falls keine da ist) und den Agent als
|
||||
# automatisch startenden Windows-Dienst (via nssm) einrichtet.
|
||||
FROM tobix/pywine:3.11
|
||||
|
||||
ARG VERSION=0.0.0
|
||||
|
||||
# NSIS (Installer-Compiler, laeuft nativ auf Linux) + Tools fuer nssm.
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends nsis curl unzip ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /work
|
||||
|
||||
# nssm — Non-Sucking Service Manager (public domain): macht aus der Konsolen-.exe
|
||||
# einen sauberen Windows-Dienst (die .exe selbst spricht das SCM nicht).
|
||||
RUN curl -fsSL https://nssm.cc/release/nssm-2.24.zip -o /tmp/nssm.zip \
|
||||
&& unzip -q /tmp/nssm.zip -d /tmp \
|
||||
&& cp /tmp/nssm-2.24/win64/nssm.exe ./nssm.exe \
|
||||
&& rm -rf /tmp/nssm*
|
||||
|
||||
COPY requirements.txt host_agent.py ./
|
||||
COPY windows/installer.nsi ./
|
||||
|
||||
# Windows-Python-Deps + PyInstaller, dann die Onefile-.exe bauen.
|
||||
RUN wine pip install --no-cache-dir -r requirements.txt pyinstaller
|
||||
RUN wine pyinstaller --onefile --name aria-host-agent --collect-all psutil host_agent.py \
|
||||
&& cp dist/aria-host-agent.exe ./aria-host-agent.exe \
|
||||
&& makensis -DVERSION=${VERSION} installer.nsi
|
||||
|
||||
# Beide Artefakte rausreichen (dist/ wird vom build-win.sh als Volume gemountet).
|
||||
CMD ["bash","-lc","cp dist/aria-host-agent.exe /out/ && cp aria-host-agent-setup.exe /out/ && echo 'OK -> /out/aria-host-agent.exe + /out/aria-host-agent-setup.exe'"]
|
||||
+43
-1
@@ -46,11 +46,23 @@ PyInstaller kann **nicht cross-kompilieren** — jede Binary wird auf ihrem OS g
|
||||
./build-native.sh # -> dist/aria-host-agent
|
||||
```
|
||||
|
||||
**Windows** — PyInstaller (Python 3 im PATH nötig):
|
||||
**Windows — nativ** (auf einem Windows-Rechner, Python 3 im PATH nötig):
|
||||
```bat
|
||||
build-native.bat REM -> dist\aria-host-agent.exe
|
||||
```
|
||||
|
||||
**Windows — aus Docker heraus (auf Linux!), inkl. Installer** — Wine baut die
|
||||
`.exe`, NSIS packt ein `setup.exe`, das den Agent als Windows-Dienst einrichtet:
|
||||
```bash
|
||||
./build-win.sh [version]
|
||||
# -> dist/aria-host-agent.exe (Konsolen-Binary)
|
||||
# -> dist/aria-host-agent-setup.exe (Installer: Dienst + .env in ProgramData)
|
||||
```
|
||||
Der erste Lauf zieht das `tobix/pywine`-Image (~1–2 GB) und richtet die Wine-
|
||||
Python-Umgebung ein — das dauert; Folge-Builds sind schnell. PyInstaller kann
|
||||
nicht cross-compilen, deshalb der Wine-Umweg. **macOS geht so NICHT** (Apple
|
||||
lässt sich nicht legal aus Docker bauen) — dort `./build-native.sh` auf einem Mac.
|
||||
|
||||
### Docker scheitert? (Live-ISO / overlayfs-Root)
|
||||
|
||||
Wenn `build.sh` mit `failed to mount … overlayfs … invalid argument` abbricht,
|
||||
@@ -96,6 +108,36 @@ Danach: `systemctl status aria-host-agent` · `journalctl -u aria-host-agent -f`
|
||||
Die Binary sucht er unter `dist/aria-host-agent` bzw. `./aria-host-agent` (oder
|
||||
2. Argument). Braucht `dialog` für den Dateibrowser (bietet die Installation an).
|
||||
|
||||
### Windows-Dienst (setup.exe)
|
||||
|
||||
`aria-host-agent-setup.exe` (aus `build-win.sh` oder dem Gitea-Release) als
|
||||
Administrator ausführen. Der Installer:
|
||||
- kopiert die `.exe` nach `%ProgramFiles%\ARIA Host-Agent`,
|
||||
- legt `%ProgramData%\ARIA-Host-Agent\.env` an (nur falls noch keine da ist),
|
||||
- richtet über **nssm** den Dienst **ARIA Host-Agent** ein (Autostart) und startet ihn.
|
||||
|
||||
Danach die `.env` unter `%ProgramData%\ARIA-Host-Agent\` mit RVS-Zugang +
|
||||
`CONTROL_ENABLED=true` füllen und den Dienst neu starten (`services.msc` →
|
||||
*ARIA Host-Agent*, oder `nssm restart ARIAHostAgent`). Deinstallation über
|
||||
*Apps & Features* → *ARIA Host-Agent* (die `.env` in ProgramData bleibt erhalten).
|
||||
|
||||
## Release (Binaries als Gitea-Assets)
|
||||
|
||||
`release_agent.sh <version>` baut alles Docker-Baubare und hängt es als
|
||||
**Release-Asset** an den Tag `agent-v<version>` — nichts landet im Git-Tree:
|
||||
|
||||
```bash
|
||||
./release_agent.sh 0.2.0 # Linux + Android + Windows (Wine)
|
||||
SKIP_WINDOWS=1 ./release_agent.sh 0.2.0 # ohne Windows (schneller)
|
||||
```
|
||||
|
||||
Assets: `aria-host-agent-linux-x64`, `aria-host-agent-android-agent-v<v>.apk`,
|
||||
`aria-host-agent-windows.exe`, `aria-host-agent-windows-setup.exe`. **macOS** ist
|
||||
nicht Docker-baubar — auf einem Mac `./build-native.sh` laufen lassen und das
|
||||
Ergebnis vor dem Release nach `dist/aria-host-agent-macos` legen, dann nimmt das
|
||||
Skript es automatisch mit. Gitea-Zugang via `.env`/Umgebung (`GITEA_URL`,
|
||||
`GITEA_REPO`, `GITEA_USER`), Kennwort wird abgefragt.
|
||||
|
||||
## TLS / SNI — Agent im selben Netz wie der RVS
|
||||
|
||||
Steht der Rechner im **selben Netz wie der RVS** (z.B. Rechenzentrum) und soll
|
||||
|
||||
@@ -116,16 +116,79 @@ identisch, nur der Wecker ändert sich.
|
||||
4. **Feinschliff** — `info`/`app_list`/`notify`, Build-Härtung, `release.sh`
|
||||
(Version-Param → Gitea-Release-Asset, wie die App).
|
||||
|
||||
## Build & Release (geplant)
|
||||
## Bauen
|
||||
|
||||
APK-Builds laufen **nur unter Linux** — deshalb im Docker-Container. Du brauchst
|
||||
nichts Android-spezifisches installiert, **nur Docker**. Android-SDK, Gradle und
|
||||
Build-Tools zieht der Container selbst (`Dockerfile.build`).
|
||||
|
||||
```bash
|
||||
cd host-agent/android
|
||||
./build.sh # Docker (Android-SDK+Gradle) -> aria-android-agent.apk
|
||||
./release.sh 0.1.0 # baut, taggt, laedt APK als Gitea-Release-Asset hoch
|
||||
./build.sh
|
||||
```
|
||||
|
||||
APK wird manuell aufs Zielgerät kopiert + installiert (unbekannte Quellen
|
||||
erlauben). Gitea-Release macht den Download einfach (wie die Haupt-App).
|
||||
`build.sh` baut das Image `aria-android-agent-build` und lässt darin
|
||||
`gradle assembleDebug` laufen. Ergebnis:
|
||||
|
||||
> Status: **M1 + M2 fertig** (verbinden, `info`, `screenshot`, `ui_dump`).
|
||||
> Als Nächstes Meilenstein 3 (Steuern).
|
||||
```
|
||||
host-agent/android/dist/aria-android-agent.apk
|
||||
```
|
||||
|
||||
Das ist ein **Debug-APK**: auto-signiert mit dem Android-Debug-Key, also direkt
|
||||
installierbar — ohne eigenen Keystore, ohne Play Store.
|
||||
|
||||
### Auf dem Handy installieren
|
||||
|
||||
1. `dist/aria-android-agent.apk` aufs Zielgerät kopieren (USB, Cloud, `adb install
|
||||
dist/aria-android-agent.apk`, …).
|
||||
2. Antippen → Android fragt nach **„Unbekannte Quellen / Aus dieser Quelle
|
||||
installieren erlauben"** → erlauben.
|
||||
3. App öffnen → verbinden (QR/manuell), „Steuerung erlauben" an, für M2 zusätzlich
|
||||
„Bildschirm-Zugriff erlauben" + „Bedienungshilfe öffnen".
|
||||
|
||||
### Was der erste Build kostet
|
||||
|
||||
Der **erste** Lauf lädt viel (JDK-Image, Gradle, Android-SDK, Dependencies) und
|
||||
dauert entsprechend — mehrere Minuten. Folge-Builds sind schnell (Docker-Layer +
|
||||
Gradle-Cache im Image). Häufige Stolperer:
|
||||
|
||||
- **Docker fehlt / kein Zugriff** → `docker`-Rechte prüfen (`docker ps`).
|
||||
- **Overlay-on-Overlay auf einem Live-ISO** („invalid argument" beim Image-Bau) —
|
||||
gleiches Problem wie beim Desktop-Agent auf dem Mint-Live-System; von einer
|
||||
installierten Linux-Kiste bauen.
|
||||
- **Kotlin-/Manifest-Fehler** beim allerersten Bau eines neuen Meilensteins: den
|
||||
Gradle-Fehler posten, das glätten wir schnell.
|
||||
|
||||
### Version setzen
|
||||
|
||||
Bis es `release.sh` gibt, wird die Version in `app/build.gradle` gepflegt
|
||||
(`versionCode` / `versionName`). Aktuell `1` / `0.2.0` (M1+M2).
|
||||
|
||||
## Release
|
||||
|
||||
Das APK ist **kein** Teil des Git-Trees (blaeht sonst die History dauerhaft auf) —
|
||||
es wird als **Release-Asset** an einen Tag gehaengt. Das macht `release_agent.sh`
|
||||
(liegt eine Ebene hoeher, in `host-agent/`):
|
||||
|
||||
```bash
|
||||
cd host-agent
|
||||
./release_agent.sh 0.2.0
|
||||
```
|
||||
|
||||
Das Skript (wie die `release.sh` der Haupt-App, Version als Parameter):
|
||||
|
||||
- setzt die Version (`host_agent.py` → `AGENT_VERSION`, `app/build.gradle` →
|
||||
`versionName`/`versionCode`),
|
||||
- baut **Linux-Binary + Android-APK** per Docker,
|
||||
- committet den Version-Bump, taggt **`agent-v<version>`** (eigener Namespace,
|
||||
kollidiert nicht mit den App-Tags `v<version>`) und pusht,
|
||||
- legt ein Gitea-Release an und laedt die Assets hoch:
|
||||
`aria-host-agent-linux-x64`, `aria-host-agent-android-agent-v<version>.apk`,
|
||||
optional `-macos` / `-windows.exe` (falls in `host-agent/dist/` vorgebaut).
|
||||
|
||||
Gitea-Zugang (`GITEA_URL`, `GITEA_REPO`, `GITEA_USER`) kommt aus der Umgebung oder
|
||||
einer `.env`; das Kennwort wird interaktiv abgefragt. **Binaries landen unter
|
||||
„Releases", nie im Tree.**
|
||||
|
||||
> Status: **M1 + M2 fertig** (verbinden, `info`, `screenshot`, `ui_dump`),
|
||||
> `release_agent.sh` vorhanden. Als Nächstes Meilenstein 3 (Steuern).
|
||||
|
||||
@@ -12,7 +12,7 @@ android {
|
||||
minSdk 26
|
||||
targetSdk 33 // 33 vermeidet die Foreground-Service-Typ-Pflicht von 34
|
||||
versionCode 1
|
||||
versionName '0.1.0'
|
||||
versionName '0.0.0.1'
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
# Baut die Windows-.exe + setup.exe des Host-Agents AUF LINUX (Wine im Docker).
|
||||
# ./build-win.sh [version]
|
||||
# Ergebnis:
|
||||
# dist/aria-host-agent.exe (Konsolen-Binary)
|
||||
# dist/aria-host-agent-setup.exe (Installer: richtet Windows-Dienst ein)
|
||||
#
|
||||
# Hinweis: Der erste Lauf zieht das tobix/pywine-Image (~1-2 GB) + baut die
|
||||
# Wine-Umgebung — das dauert. Folge-Builds sind schnell.
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")"
|
||||
VERSION="${1:-0.0.0}"
|
||||
mkdir -p dist
|
||||
docker build -f Dockerfile.win --build-arg VERSION="$VERSION" -t aria-host-agent-win .
|
||||
docker run --rm -v "$(pwd)/dist:/out" aria-host-agent-win
|
||||
echo
|
||||
echo "Fertig: dist/aria-host-agent.exe + dist/aria-host-agent-setup.exe"
|
||||
@@ -64,7 +64,13 @@ def _load_dotenv() -> None:
|
||||
"""Laedt eine .env neben der Binary/dem Script (oder im CWD) in os.environ.
|
||||
Bereits gesetzte Werte gewinnen. Kein python-dotenv noetig."""
|
||||
here = os.path.dirname(os.path.abspath(__file__))
|
||||
for path in (os.path.join(here, ".env"), os.path.join(os.getcwd(), ".env")):
|
||||
# PyInstaller-onefile: __file__ liegt im Temp-Extract-Dir, NICHT beim .exe/
|
||||
# Binary — deshalb zusaetzlich sys.executable-Ordner (echter Binary-Ort) und
|
||||
# das CWD (z.B. der ProgramData-Ordner, den der Windows-Dienst als AppDir nutzt).
|
||||
exe_dir = os.path.dirname(os.path.abspath(sys.executable))
|
||||
seen = set()
|
||||
candidates = [os.path.join(d, ".env") for d in (exe_dir, here, os.getcwd())]
|
||||
for path in [p for p in candidates if not (p in seen or seen.add(p))]:
|
||||
if not os.path.isfile(path):
|
||||
continue
|
||||
try:
|
||||
@@ -155,6 +161,9 @@ OUT_MAX_CHARS_HARD = int(os.environ.get("OUT_MAX_CHARS_HARD", "200000") or "2000
|
||||
# Datei-Transfer-Limit (Base64 durchs RVS).
|
||||
FILE_MAX_BYTES = int(os.environ.get("FILE_MAX_BYTES", str(10 * 1024 * 1024)) or str(10 * 1024 * 1024))
|
||||
|
||||
# Version (wird von release_agent.sh beim Release gesetzt).
|
||||
AGENT_VERSION = "0.0.0.1"
|
||||
|
||||
HEARTBEAT_SEC = 25
|
||||
CAPS = ["exec", "read", "write", "info", "screenshot"]
|
||||
|
||||
@@ -291,6 +300,7 @@ def _do_write(params: dict) -> dict:
|
||||
def _do_info(params: dict) -> dict:
|
||||
info = {
|
||||
"host": HOST_NAME, "hostname": socket.gethostname(),
|
||||
"agent_version": AGENT_VERSION,
|
||||
"os": platform.platform(), "kernel": platform.release(),
|
||||
"arch": platform.machine(), "python": platform.python_version(),
|
||||
"user": os.environ.get("USER") or os.environ.get("USERNAME") or "",
|
||||
@@ -414,7 +424,7 @@ class HostAgent:
|
||||
HOST_ID, HOST_NAME, ",".join(CAPS), CONTROL_ENABLED)
|
||||
await self._send({"type": "host_hello", "payload": {
|
||||
"hostId": HOST_ID, "name": HOST_NAME, "os": platform.platform(),
|
||||
"caps": CAPS, "control": CONTROL_ENABLED,
|
||||
"version": AGENT_VERSION, "caps": CAPS, "control": CONTROL_ENABLED,
|
||||
}, "timestamp": int(time.time() * 1000)})
|
||||
|
||||
async def _heartbeat(self) -> None:
|
||||
|
||||
Executable
+150
@@ -0,0 +1,150 @@
|
||||
#!/bin/bash
|
||||
# ════════════════════════════════════════════════════════════════════
|
||||
# ARIA Host-Agent — Release Script
|
||||
# Baut die auf Linux+Docker moeglichen Artefakte und haengt sie als
|
||||
# Gitea-Release-Assets an einen Tag. NICHTS wandert in den Git-Tree —
|
||||
# Binaries leben nur unter "Releases" (blaeht clone/History nicht auf).
|
||||
#
|
||||
# Verwendung: ./release_agent.sh <version> (z.B. ./release_agent.sh 0.2.0)
|
||||
#
|
||||
# Artefakte:
|
||||
# - Linux-x64-Binary (Docker, PyInstaller) -> immer
|
||||
# - Android-APK (Docker, Gradle) -> immer
|
||||
# - macOS / Windows (falls in dist/ vorgebaut) -> optional
|
||||
# (mac/win koennen auf Linux nicht cross-gebaut werden -> build-native.*
|
||||
# auf dem jeweiligen OS laufen lassen, Ergebnis nach host-agent/dist/ legen)
|
||||
#
|
||||
# Eigener Tag-Namespace agent-v<version> (kollidiert NICHT mit den
|
||||
# App-Tags v<version>).
|
||||
#
|
||||
# Gitea-Zugang (GITEA_URL, GITEA_REPO, GITEA_USER) wird aus der Umgebung
|
||||
# oder aus host-agent/.env bzw. der Repo-Wurzel-.env gelesen; das Kennwort
|
||||
# wird interaktiv abgefragt.
|
||||
# ════════════════════════════════════════════════════════════════════
|
||||
|
||||
set -e
|
||||
cd "$(dirname "$0")" # host-agent/
|
||||
SCRIPT_DIR="$(pwd)"
|
||||
ROOT_DIR="$(cd .. && pwd)"
|
||||
|
||||
# ── Farben ───────────────────────────────────────────────────────────
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
|
||||
|
||||
# ── Parameter ────────────────────────────────────────────────────────
|
||||
VERSION=${1:?"Usage: ./release_agent.sh <version> (z.B. 0.2.0)"}
|
||||
TAG="agent-v$VERSION"
|
||||
|
||||
# ── Gitea-Konfiguration (env > host-agent/.env > Repo-Wurzel-.env) ────
|
||||
[ -f "$SCRIPT_DIR/.env" ] && source "$SCRIPT_DIR/.env"
|
||||
[ -f "$ROOT_DIR/.env" ] && source "$ROOT_DIR/.env"
|
||||
|
||||
GITEA_URL="${GITEA_URL:?"GITEA_URL nicht gesetzt (in .env oder als Umgebungsvariable)"}"
|
||||
GITEA_REPO="${GITEA_REPO:?"GITEA_REPO nicht gesetzt (z.B. stefan/aria-agent)"}"
|
||||
GITEA_USER="${GITEA_USER:-$(echo "$GITEA_REPO" | cut -d'/' -f1)}"
|
||||
|
||||
echo -e "${CYAN}╔═══════════════════════════════════════════╗${NC}"
|
||||
echo -e "${CYAN}║ ARIA Host-Agent Release — ${TAG}$(printf '%*s' $((14 - ${#TAG})) '')║${NC}"
|
||||
echo -e "${CYAN}╚═══════════════════════════════════════════╝${NC}\n"
|
||||
|
||||
# ── Kennwort ─────────────────────────────────────────────────────────
|
||||
echo -e "${YELLOW}Gitea-Login: ${GITEA_USER}${NC}"
|
||||
read -s -p "Gitea-Kennwort: " GITEA_PASS; echo ""
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -u "${GITEA_USER}:${GITEA_PASS}" "$GITEA_URL/api/v1/user")
|
||||
if [ "$HTTP_CODE" != "200" ]; then
|
||||
echo -e "${RED}Login fehlgeschlagen (HTTP $HTTP_CODE). Kennwort korrekt?${NC}"; exit 1
|
||||
fi
|
||||
echo -e " ${GREEN}✓${NC} Login erfolgreich\n"
|
||||
|
||||
# ── Versionsnummern setzen ───────────────────────────────────────────
|
||||
echo -e "${GREEN}[1/5] Version auf $VERSION setzen...${NC}"
|
||||
# Desktop-Agent
|
||||
sed -i "s/^AGENT_VERSION = \"[^\"]*\"/AGENT_VERSION = \"$VERSION\"/" host_agent.py
|
||||
echo -e " ${GREEN}✓${NC} host_agent.py → AGENT_VERSION $VERSION"
|
||||
# Android: versionName + versionCode (aus Version berechnen; 3- oder 4-stellig)
|
||||
IFS='.' read -ra VP <<< "$VERSION"
|
||||
V1=${VP[0]:-0}; V2=${VP[1]:-0}; V3=${VP[2]:-0}; V4=${VP[3]:-0}
|
||||
VERSION_CODE=$((V1 * 1000000 + V2 * 10000 + V3 * 100 + V4)); [ "$VERSION_CODE" -lt 1 ] && VERSION_CODE=1
|
||||
sed -i "s/versionName '[^']*'/versionName '$VERSION'/" android/app/build.gradle
|
||||
sed -i "s/versionCode [0-9]*/versionCode $VERSION_CODE/" android/app/build.gradle
|
||||
echo -e " ${GREEN}✓${NC} android/app/build.gradle → versionName $VERSION, versionCode $VERSION_CODE\n"
|
||||
|
||||
# ── Bauen (Docker) ───────────────────────────────────────────────────
|
||||
echo -e "${GREEN}[2/5] Linux-Binary + Android-APK bauen (Docker)...${NC}"
|
||||
./build.sh >/dev/null
|
||||
LINUX_BIN="$SCRIPT_DIR/dist/aria-host-agent"
|
||||
[ -f "$LINUX_BIN" ] || { echo -e "${RED}Linux-Binary fehlt: $LINUX_BIN${NC}"; exit 1; }
|
||||
echo -e " ${GREEN}✓${NC} Linux-Binary ($(du -h "$LINUX_BIN" | cut -f1))"
|
||||
|
||||
( cd android && ./build.sh >/dev/null )
|
||||
APK="$SCRIPT_DIR/android/dist/aria-android-agent.apk"
|
||||
[ -f "$APK" ] || { echo -e "${RED}APK fehlt: $APK${NC}"; exit 1; }
|
||||
echo -e " ${GREEN}✓${NC} Android-APK ($(du -h "$APK" | cut -f1))"
|
||||
|
||||
# Windows (.exe + setup.exe) via Wine im Docker. Dauert (pywine-Image ~1-2 GB) —
|
||||
# mit SKIP_WINDOWS=1 ./release_agent.sh <v> ueberspringbar.
|
||||
if [ "${SKIP_WINDOWS:-0}" = "1" ]; then
|
||||
echo -e " ${YELLOW}Windows-Build uebersprungen (SKIP_WINDOWS=1)${NC}"
|
||||
else
|
||||
echo -e " ${CYAN}…${NC} Windows-.exe + setup.exe bauen (Wine, kann dauern)"
|
||||
if ./build-win.sh "$VERSION" >/dev/null 2>&1; then
|
||||
echo -e " ${GREEN}✓${NC} Windows-.exe + setup.exe"
|
||||
else
|
||||
echo -e " ${YELLOW}Windows-Build fehlgeschlagen — Release laeuft ohne Windows weiter.${NC}"
|
||||
echo -e " ${YELLOW}(Einzeln testen: ./build-win.sh $VERSION)${NC}"
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Asset-Liste aufbauen: "lokaler_pfad::asset-name"
|
||||
ASSETS=(
|
||||
"$LINUX_BIN::aria-host-agent-linux-x64"
|
||||
"$APK::aria-host-agent-android-$TAG.apk"
|
||||
)
|
||||
# Native Artefakte (nur wenn vorhanden): Windows aus build-win.sh, macOS
|
||||
# vorgebaut (build-native.sh auf einem Mac -> dist/aria-host-agent-macos legen).
|
||||
[ -f "$SCRIPT_DIR/dist/aria-host-agent-macos" ] && ASSETS+=("$SCRIPT_DIR/dist/aria-host-agent-macos::aria-host-agent-macos")
|
||||
[ -f "$SCRIPT_DIR/dist/aria-host-agent.exe" ] && ASSETS+=("$SCRIPT_DIR/dist/aria-host-agent.exe::aria-host-agent-windows.exe")
|
||||
[ -f "$SCRIPT_DIR/dist/aria-host-agent-setup.exe" ] && ASSETS+=("$SCRIPT_DIR/dist/aria-host-agent-setup.exe::aria-host-agent-windows-setup.exe")
|
||||
|
||||
# ── Git-Tag ──────────────────────────────────────────────────────────
|
||||
echo -e "${GREEN}[3/5] Git-Tag $TAG...${NC}"
|
||||
git add host_agent.py android/app/build.gradle
|
||||
git commit -m "release(agent): bump to $VERSION" 2>/dev/null || echo -e " ${YELLOW}Keine Aenderungen zum Committen${NC}"
|
||||
if git rev-parse "$TAG" &>/dev/null; then
|
||||
echo -e " ${YELLOW}Tag $TAG existiert bereits — überspringe${NC}"
|
||||
else
|
||||
git tag "$TAG"; echo -e " ${GREEN}✓${NC} Tag $TAG erstellt"
|
||||
fi
|
||||
git push origin main "$TAG"
|
||||
echo -e " ${GREEN}✓${NC} Tag gepusht\n"
|
||||
|
||||
# ── Gitea-Release ────────────────────────────────────────────────────
|
||||
echo -e "${GREEN}[4/5] Gitea-Release anlegen...${NC}"
|
||||
BODY="ARIA Host-Agent $TAG\n\nDesktop (Linux) + Android-APK. Auf das Zielgeraet kopieren, siehe README."
|
||||
BODY_JSON=$(printf '%s' "$BODY" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))' 2>/dev/null || printf '"%s"' "$BODY")
|
||||
RESP=$(curl -s -X POST "$GITEA_URL/api/v1/repos/$GITEA_REPO/releases" \
|
||||
-u "${GITEA_USER}:${GITEA_PASS}" -H "Content-Type: application/json" \
|
||||
-d "{\"tag_name\":\"$TAG\",\"name\":\"Host-Agent $TAG\",\"body\":$BODY_JSON,\"draft\":false,\"prerelease\":false}")
|
||||
RELEASE_ID=$(echo "$RESP" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
|
||||
if [ -z "$RELEASE_ID" ]; then echo -e "${RED}Release fehlgeschlagen:${NC}\n$RESP"; exit 1; fi
|
||||
echo -e " ${GREEN}✓${NC} Release #$RELEASE_ID erstellt\n"
|
||||
|
||||
# ── Assets hochladen ─────────────────────────────────────────────────
|
||||
echo -e "${GREEN}[5/5] Assets hochladen (${#ASSETS[@]})...${NC}"
|
||||
for entry in "${ASSETS[@]}"; do
|
||||
path="${entry%%::*}"; name="${entry##*::}"
|
||||
UP=$(curl -s -X POST \
|
||||
"$GITEA_URL/api/v1/repos/$GITEA_REPO/releases/$RELEASE_ID/assets?name=$name" \
|
||||
-u "${GITEA_USER}:${GITEA_PASS}" -F "attachment=@${path}")
|
||||
if echo "$UP" | grep -q '"name"'; then
|
||||
echo -e " ${GREEN}✓${NC} $name"
|
||||
else
|
||||
echo -e " ${RED}✗ $name fehlgeschlagen:${NC} $UP"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}╔═══════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${GREEN}║ Host-Agent $TAG ist live!${NC}"
|
||||
echo -e "${GREEN}║${NC} $GITEA_URL/$GITEA_REPO/releases/tag/$TAG"
|
||||
echo -e "${GREEN}╚═══════════════════════════════════════════════════╝${NC}"
|
||||
@@ -0,0 +1,83 @@
|
||||
; ARIA Host-Agent — Windows-Installer (NSIS, auf Linux mit makensis gebaut).
|
||||
;
|
||||
; Installiert die Agent-.exe nach %ProgramFiles%\ARIA Host-Agent, legt eine .env
|
||||
; in %ProgramData%\ARIA-Host-Agent an (nur falls noch keine da ist — User-Config
|
||||
; bleibt erhalten) und richtet einen automatisch startenden Windows-Dienst via
|
||||
; nssm ein. Der Dienst laeuft mit AppDirectory = ProgramData-Ordner, damit der
|
||||
; Agent die .env von dort (aus dem CWD) liest.
|
||||
|
||||
!ifndef VERSION
|
||||
!define VERSION "0.0.0"
|
||||
!endif
|
||||
!define SVC "ARIAHostAgent"
|
||||
|
||||
Name "ARIA Host-Agent ${VERSION}"
|
||||
OutFile "aria-host-agent-setup.exe"
|
||||
InstallDir "$PROGRAMFILES64\ARIA Host-Agent"
|
||||
RequestExecutionLevel admin
|
||||
Unicode true
|
||||
ShowInstDetails show
|
||||
ShowUninstDetails show
|
||||
|
||||
Var DataDir
|
||||
|
||||
Page directory
|
||||
Page instfiles
|
||||
UninstPage uninstConfirm
|
||||
UninstPage instfiles
|
||||
|
||||
Section "Install"
|
||||
SetOutPath "$INSTDIR"
|
||||
File "aria-host-agent.exe"
|
||||
File "nssm.exe"
|
||||
|
||||
; ProgramData-Ordner fuer die .env bestimmen
|
||||
ReadEnvStr $0 "ProgramData"
|
||||
StrCmp $0 "" 0 +2
|
||||
StrCpy $0 "$PROFILE" ; Fallback, falls %ProgramData% fehlt
|
||||
StrCpy $DataDir "$0\ARIA-Host-Agent"
|
||||
CreateDirectory "$DataDir"
|
||||
|
||||
; .env nur schreiben, wenn noch keine existiert (User-Config nicht ueberschreiben)
|
||||
IfFileExists "$DataDir\.env" env_done 0
|
||||
FileOpen $1 "$DataDir\.env" w
|
||||
FileWrite $1 "# ARIA Host-Agent — Konfiguration (dieser Windows-Dienst liest diese Datei).$\r$\n"
|
||||
FileWrite $1 "# Nach dem Aendern den Dienst neu starten: services.msc -> ARIA Host-Agent.$\r$\n"
|
||||
FileWrite $1 "RVS_HOST=rvs.example.de$\r$\n"
|
||||
FileWrite $1 "RVS_PORT=443$\r$\n"
|
||||
FileWrite $1 "RVS_TLS=true$\r$\n"
|
||||
FileWrite $1 "RVS_TLS_FALLBACK=true$\r$\n"
|
||||
FileWrite $1 "RVS_TOKEN=$\r$\n"
|
||||
FileWrite $1 "RVS_SNI=$\r$\n"
|
||||
FileWrite $1 "HOST_NAME=$\r$\n"
|
||||
FileWrite $1 "CONTROL_ENABLED=true$\r$\n"
|
||||
FileClose $1
|
||||
env_done:
|
||||
|
||||
; Dienst (neu) einrichten — evtl. alten sauber entfernen, dann installieren
|
||||
nsExec::ExecToLog '"$INSTDIR\nssm.exe" stop ${SVC}'
|
||||
nsExec::ExecToLog '"$INSTDIR\nssm.exe" remove ${SVC} confirm'
|
||||
nsExec::ExecToLog '"$INSTDIR\nssm.exe" install ${SVC} "$INSTDIR\aria-host-agent.exe"'
|
||||
nsExec::ExecToLog '"$INSTDIR\nssm.exe" set ${SVC} AppDirectory "$DataDir"'
|
||||
nsExec::ExecToLog '"$INSTDIR\nssm.exe" set ${SVC} DisplayName "ARIA Host-Agent"'
|
||||
nsExec::ExecToLog '"$INSTDIR\nssm.exe" set ${SVC} Description "ARIA-Fernsteuerung dieses Rechners (RVS-Agent)."'
|
||||
nsExec::ExecToLog '"$INSTDIR\nssm.exe" set ${SVC} Start SERVICE_AUTO_START'
|
||||
nsExec::ExecToLog '"$INSTDIR\nssm.exe" start ${SVC}'
|
||||
|
||||
; Uninstaller + Eintrag unter "Apps & Features"
|
||||
WriteUninstaller "$INSTDIR\uninstall.exe"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ARIAHostAgent" "DisplayName" "ARIA Host-Agent"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ARIAHostAgent" "DisplayVersion" "${VERSION}"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ARIAHostAgent" "UninstallString" '"$INSTDIR\uninstall.exe"'
|
||||
SectionEnd
|
||||
|
||||
Section "Uninstall"
|
||||
nsExec::ExecToLog '"$INSTDIR\nssm.exe" stop ${SVC}'
|
||||
nsExec::ExecToLog '"$INSTDIR\nssm.exe" remove ${SVC} confirm'
|
||||
Delete "$INSTDIR\aria-host-agent.exe"
|
||||
Delete "$INSTDIR\nssm.exe"
|
||||
Delete "$INSTDIR\uninstall.exe"
|
||||
RMDir "$INSTDIR"
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ARIAHostAgent"
|
||||
; Die .env in %ProgramData%\ARIA-Host-Agent bleibt bewusst erhalten (User-Config).
|
||||
SectionEnd
|
||||
Reference in New Issue
Block a user