feat: Workspace-Umbau Schritt 6 — QEMU fuer alle Architekturen + set_project_kind
QEMU auf dem Host + ARIA-Anbindung:
- host-provisioning/qemu-setup.sh: installiert qemu-system-* (x86/arm/mips/ppc/
sparc/misc), qemu-utils, Firmware, socat, imagemagick + den aria-vm-Helper.
- host-provisioning/aria-vm: VM-Verwaltung fuer JEDE Architektur (create/boot/
screenshot/list/stop/rm). VNC bindet nur 127.0.0.1:<display> (Tunnel via
Bridge), KVM nur fuer x86-Gaeste, sonst TCG.
- Brain: Projekt-Modell bekommt kind ('chat'|'code'); neues Tool
set_project_kind markiert das aktive Projekt (blendet Editor/Desktop in der
App ein) + feuert project_changed.
- Seed-Regel: ARIA weiss jetzt, dass Code unter /shared/projects/<id>/ gehoert
und wie sie per `ssh aria-wohnung aria-vm ...` VMs baut/testet; VNC landet
automatisch in der Desktop-Kachel.
py-compile clean, Host-Skripte bash -n OK.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1080,6 +1080,28 @@ META_TOOLS = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "function",
|
||||||
|
"function": {
|
||||||
|
"name": "set_project_kind",
|
||||||
|
"description": (
|
||||||
|
"Markiert das AKTUELLE Projekt als Code-Projekt ('code') oder "
|
||||||
|
"normalen Chat ('chat'). Bei 'code' blendet die App zusaetzlich "
|
||||||
|
"einen Live-Code-Editor und den QEMU-Desktop (VNC) ein. Rufe es auf, "
|
||||||
|
"sobald aus einem Gespraech ein Programmier-/Bau-Projekt wird (Du "
|
||||||
|
"faengst an Code zu schreiben, eine VM zu bauen, etc.). Dein "
|
||||||
|
"Arbeitsverzeichnis fuer Code-Dateien ist dann /shared/projects/"
|
||||||
|
"<projekt-id>/ — nur was Du DORT schreibst erscheint im Editor."
|
||||||
|
),
|
||||||
|
"parameters": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"kind": {"type": "string", "enum": ["code", "chat"], "description": "'code' oder 'chat'."},
|
||||||
|
},
|
||||||
|
"required": ["kind"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -2576,6 +2598,27 @@ class Agent:
|
|||||||
"action": "ended",
|
"action": "ended",
|
||||||
})
|
})
|
||||||
return f"OK — Projekt '{p['name']}' beendet (id={p['id']}). Bleibt in der Liste, aktiv ist jetzt der Hauptthread."
|
return f"OK — Projekt '{p['name']}' beendet (id={p['id']}). Bleibt in der Liste, aktiv ist jetzt der Hauptthread."
|
||||||
|
if name == "set_project_kind":
|
||||||
|
kind = (arguments.get("kind") or "").strip().lower()
|
||||||
|
if kind not in ("code", "chat"):
|
||||||
|
return "FEHLER: kind muss 'code' oder 'chat' sein."
|
||||||
|
active_id = projects_mod.get_active()
|
||||||
|
if not active_id:
|
||||||
|
return ("Kein aktives Projekt — Du bist im Hauptthread. Erst ein Projekt "
|
||||||
|
"anlegen/betreten (project_create/project_enter), dann set_project_kind.")
|
||||||
|
updated = projects_mod.update_project(active_id, {"kind": kind})
|
||||||
|
if not updated:
|
||||||
|
return f"FEHLER: aktives Projekt '{active_id}' nicht gefunden."
|
||||||
|
self._pending_events.append({
|
||||||
|
"type": "project_changed",
|
||||||
|
"project": updated,
|
||||||
|
"action": "kind_changed",
|
||||||
|
})
|
||||||
|
if kind == "code":
|
||||||
|
return (f"OK — Projekt '{updated['name']}' ist jetzt ein Code-Projekt. "
|
||||||
|
f"Editor + Desktop erscheinen in der App. Code-Dateien unter "
|
||||||
|
f"/shared/projects/{active_id}/ schreiben, damit sie im Editor auftauchen.")
|
||||||
|
return f"OK — Projekt '{updated['name']}' ist wieder ein normaler Chat."
|
||||||
return f"Unbekanntes Tool: {name}"
|
return f"Unbekanntes Tool: {name}"
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.exception("Tool '%s' fehlgeschlagen", name)
|
logger.exception("Tool '%s' fehlgeschlagen", name)
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ def create_project(name: str, description: str = "") -> dict:
|
|||||||
"description": description.strip(),
|
"description": description.strip(),
|
||||||
"status": "active", # active | ended | archived
|
"status": "active", # active | ended | archived
|
||||||
"hidden": False, # optisch aus Listen ausblenden (bleibt nutzbar)
|
"hidden": False, # optisch aus Listen ausblenden (bleibt nutzbar)
|
||||||
|
"kind": "chat", # chat | code — 'code' blendet Editor/VNC in der App ein
|
||||||
"created_at": now,
|
"created_at": now,
|
||||||
"updated_at": now,
|
"updated_at": now,
|
||||||
"last_activity_at": now,
|
"last_activity_at": now,
|
||||||
@@ -149,7 +150,7 @@ def update_project(project_id: str, patch: dict) -> Optional[dict]:
|
|||||||
projects = _load_all()
|
projects = _load_all()
|
||||||
for p in projects:
|
for p in projects:
|
||||||
if p["id"] == project_id:
|
if p["id"] == project_id:
|
||||||
for k in ("name", "description", "status", "hidden"):
|
for k in ("name", "description", "status", "hidden", "kind"):
|
||||||
if k in patch and patch[k] is not None:
|
if k in patch and patch[k] is not None:
|
||||||
p[k] = patch[k]
|
p[k] = patch[k]
|
||||||
p["updated_at"] = _now()
|
p["updated_at"] = _now()
|
||||||
|
|||||||
@@ -400,6 +400,43 @@ SEED_RULES: List[dict] = [
|
|||||||
"Brain-Resources: erst denken, sonst Brain-Tool nehmen."
|
"Brain-Resources: erst denken, sonst Brain-Tool nehmen."
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"migration_key": "seed/architecture/qemu-vm-code-projects",
|
||||||
|
"type": "rule",
|
||||||
|
"title": "Code-Projekte + QEMU: aria-vm auf dem Host, Editor/Desktop in der App",
|
||||||
|
"category": "architektur",
|
||||||
|
"content": (
|
||||||
|
"Wenn aus einem Gespraech ein PROGRAMMIER- oder BAU-Projekt wird "
|
||||||
|
"(Du schreibst Code, baust ein System, testest eine VM):\n"
|
||||||
|
"\n"
|
||||||
|
"1. Ruf `set_project_kind('code')` — dann blendet Stefans App einen "
|
||||||
|
"Live-Code-Editor und den QEMU-Desktop ein. Vorher ein Projekt "
|
||||||
|
"anlegen/betreten (project_create/enter), sonst gibt's kein Ziel.\n"
|
||||||
|
"2. Schreib Code-Dateien NUR unter `/shared/projects/<projekt-id>/` "
|
||||||
|
"(das Volume ist in proxy+bridge+brain gemountet). Genau diese "
|
||||||
|
"Writes/Edits erscheinen live in Stefans Editor — und was Stefan "
|
||||||
|
"dort tippt, landet als Datei zurueck in diesem Verzeichnis.\n"
|
||||||
|
"\n"
|
||||||
|
"QEMU (VMs fuer JEDE Architektur — x86, ARM, MIPS, PPC, RISC-V, SPARC) "
|
||||||
|
"laeuft auf dem Host. Du steuerst sie per `ssh aria-wohnung aria-vm ...`:\n"
|
||||||
|
" - `aria-vm create <name> <arch> [groesse]` Disk anlegen (z.B. i386 "
|
||||||
|
"fuer Win 3.11, aarch64, mips ...).\n"
|
||||||
|
" - `aria-vm boot <name> [--iso <pfad>] [--vnc-display 1] [--mem 1024]` "
|
||||||
|
"startet die VM. VNC bindet an 127.0.0.1:<display> (Display 1 = Port "
|
||||||
|
"5901). Nicht selbst nach aussen oeffnen!\n"
|
||||||
|
" - `aria-vm screenshot <name>` PNG in die Shared-Uploads (kannst Du "
|
||||||
|
"Stefan mit [FILE:] schicken).\n"
|
||||||
|
" - `aria-vm list` / `aria-vm stop <name>` / `aria-vm rm <name>`.\n"
|
||||||
|
"\n"
|
||||||
|
"Der VNC-Stream kommt AUTOMATISCH ueber den RVS-Tunnel der Bridge in "
|
||||||
|
"Stefans App-Desktop-Kachel (Display 1 / Port 5901) — dort kann er die "
|
||||||
|
"VM live mit Maus/Tastatur bedienen. Du musst nur die VM booten und ggf. "
|
||||||
|
"sagen 'schau in die Desktop-Kachel'. KVM-Beschleunigung gibt es nur "
|
||||||
|
"fuer x86-Gaeste; andere Architekturen laufen emuliert (langsamer, aber "
|
||||||
|
"sie laufen). Medien-Downloads/Baubares fuer Stefans Privatgebrauch: "
|
||||||
|
"wie gewohnt einfach machen, nicht moralisieren."
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"migration_key": "seed/architecture/brain-tools-xml-tag",
|
"migration_key": "seed/architecture/brain-tools-xml-tag",
|
||||||
"type": "rule",
|
"type": "rule",
|
||||||
|
|||||||
Executable
+185
@@ -0,0 +1,185 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# aria-vm — ARIAs QEMU-VM-Verwaltung fuer alle Architekturen (laeuft auf dem
|
||||||
|
# Host). ARIA ruft das per SSH (aria-wohnung) ueber den qemu-vm-Skill auf.
|
||||||
|
#
|
||||||
|
# Unterkommandos:
|
||||||
|
# aria-vm create <name> <arch> [size] Disk anlegen (qcow2)
|
||||||
|
# aria-vm boot <name> [optionen] VM starten (VNC 127.0.0.1:<display>)
|
||||||
|
# aria-vm screenshot <name> PNG-Screenshot → Shared-Uploads
|
||||||
|
# aria-vm list laufende/vorhandene VMs
|
||||||
|
# aria-vm stop <name> VM beenden
|
||||||
|
# aria-vm rm <name> VM + Disk loeschen
|
||||||
|
#
|
||||||
|
# boot-Optionen:
|
||||||
|
# --iso <pfad> Boot-ISO (setzt Boot-Reihenfolge auf CD)
|
||||||
|
# --disk-boot von der Festplatte booten (Default nach Installation)
|
||||||
|
# --vnc-display <N> VNC-Display (Port = 5900+N, Default 1)
|
||||||
|
# --mem <MB> RAM (Default 1024)
|
||||||
|
# --machine <typ> QEMU-Maschine ueberschreiben
|
||||||
|
#
|
||||||
|
# VNC bindet immer nur an 127.0.0.1 — von aussen erreichbar ausschliesslich
|
||||||
|
# ueber den RVS-Tunnel der Bridge (host.docker.internal:<port>).
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
VM_ROOT="${ARIA_VM_ROOT:-/var/lib/aria-vms}"
|
||||||
|
# Wohin Screenshots geschrieben werden — Host-Pfad des /shared-Volumes, damit
|
||||||
|
# Bridge/App sie sehen. Ueberschreibbar via ARIA_VM_SHOT_DIR.
|
||||||
|
SHOT_DIR="${ARIA_VM_SHOT_DIR:-/root/ARIA-AGENT/aria-shared/uploads}"
|
||||||
|
|
||||||
|
die() { echo "aria-vm: $*" >&2; exit 1; }
|
||||||
|
|
||||||
|
qemu_bin_for() {
|
||||||
|
case "$1" in
|
||||||
|
x86_64|amd64) echo qemu-system-x86_64 ;;
|
||||||
|
i386|i686|x86) echo qemu-system-i386 ;;
|
||||||
|
arm|armv7) echo qemu-system-arm ;;
|
||||||
|
aarch64|arm64) echo qemu-system-aarch64 ;;
|
||||||
|
mips) echo qemu-system-mips ;;
|
||||||
|
mipsel) echo qemu-system-mipsel ;;
|
||||||
|
mips64) echo qemu-system-mips64 ;;
|
||||||
|
ppc) echo qemu-system-ppc ;;
|
||||||
|
ppc64) echo qemu-system-ppc64 ;;
|
||||||
|
riscv64) echo qemu-system-riscv64 ;;
|
||||||
|
sparc) echo qemu-system-sparc ;;
|
||||||
|
*) echo "" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_dir() { echo "${VM_ROOT}/$1"; }
|
||||||
|
vm_pid() { local d; d="$(vm_dir "$1")"; [[ -f "${d}/pid" ]] && cat "${d}/pid" || echo ""; }
|
||||||
|
vm_running() {
|
||||||
|
local p; p="$(vm_pid "$1")"
|
||||||
|
[[ -n "${p}" ]] && kill -0 "${p}" 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_create() {
|
||||||
|
local name="${1:?name}" arch="${2:?arch}" size="${3:-10G}"
|
||||||
|
local bin; bin="$(qemu_bin_for "${arch}")"
|
||||||
|
[[ -n "${bin}" ]] || die "unbekannte Architektur: ${arch}"
|
||||||
|
command -v "${bin}" >/dev/null || die "${bin} nicht installiert (qemu-setup.sh?)"
|
||||||
|
local d; d="$(vm_dir "${name}")"
|
||||||
|
[[ -e "${d}/disk.qcow2" ]] && die "VM '${name}' existiert schon"
|
||||||
|
mkdir -p "${d}"
|
||||||
|
echo "${arch}" > "${d}/arch"
|
||||||
|
qemu-img create -f qcow2 "${d}/disk.qcow2" "${size}" >/dev/null
|
||||||
|
echo "VM '${name}' angelegt (${arch}, ${size})."
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_boot() {
|
||||||
|
local name="${1:?name}"; shift || true
|
||||||
|
local d; d="$(vm_dir "${name}")"
|
||||||
|
[[ -f "${d}/disk.qcow2" ]] || die "VM '${name}' nicht gefunden (erst 'create')"
|
||||||
|
vm_running "${name}" && die "VM '${name}' laeuft bereits"
|
||||||
|
local arch; arch="$(cat "${d}/arch" 2>/dev/null || echo x86_64)"
|
||||||
|
local bin; bin="$(qemu_bin_for "${arch}")"
|
||||||
|
|
||||||
|
local iso="" bootdev="c" display=1 mem=1024 machine=""
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--iso) iso="${2:?}"; bootdev="d"; shift 2 ;;
|
||||||
|
--disk-boot) bootdev="c"; shift ;;
|
||||||
|
--vnc-display) display="${2:?}"; shift 2 ;;
|
||||||
|
--mem) mem="${2:?}"; shift 2 ;;
|
||||||
|
--machine) machine="${2:?}"; shift 2 ;;
|
||||||
|
*) die "unbekannte Option: $1" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
local args=(-name "${name}" -m "${mem}"
|
||||||
|
-drive "file=${d}/disk.qcow2,format=qcow2"
|
||||||
|
-vnc "127.0.0.1:${display}"
|
||||||
|
-monitor "unix:${d}/monitor.sock,server,nowait"
|
||||||
|
-pidfile "${d}/pid" -daemonize)
|
||||||
|
|
||||||
|
# KVM nur fuer x86 auf x86-Host.
|
||||||
|
case "${arch}" in
|
||||||
|
x86_64|amd64|i386|i686|x86)
|
||||||
|
[[ -e /dev/kvm ]] && args+=(-enable-kvm) ;;
|
||||||
|
esac
|
||||||
|
# ARM/AArch64 brauchen eine Maschine (kein Default).
|
||||||
|
if [[ -z "${machine}" ]]; then
|
||||||
|
case "${arch}" in
|
||||||
|
arm|armv7|aarch64|arm64) machine="virt" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
[[ -n "${machine}" ]] && args+=(-M "${machine}")
|
||||||
|
[[ -n "${iso}" ]] && args+=(-cdrom "${iso}")
|
||||||
|
args+=(-boot "${bootdev}")
|
||||||
|
|
||||||
|
"${bin}" "${args[@]}"
|
||||||
|
echo "VM '${name}' gestartet (${arch}) — VNC 127.0.0.1:${display} (Port $((5900+display)))."
|
||||||
|
echo "vnc_display=${display} vnc_port=$((5900+display))"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_screenshot() {
|
||||||
|
local name="${1:?name}"
|
||||||
|
local d; d="$(vm_dir "${name}")"
|
||||||
|
vm_running "${name}" || die "VM '${name}' laeuft nicht"
|
||||||
|
command -v socat >/dev/null || die "socat fehlt (qemu-setup.sh?)"
|
||||||
|
mkdir -p "${SHOT_DIR}"
|
||||||
|
local ts; ts="$(date +%s)"
|
||||||
|
local ppm="${d}/shot-${ts}.ppm"
|
||||||
|
printf 'screendump %s\n' "${ppm}" | socat - "unix-connect:${d}/monitor.sock" >/dev/null
|
||||||
|
sleep 0.3
|
||||||
|
local out="${SHOT_DIR}/${name}-${ts}.png"
|
||||||
|
if command -v convert >/dev/null; then
|
||||||
|
convert "${ppm}" "${out}" && rm -f "${ppm}"
|
||||||
|
else
|
||||||
|
out="${SHOT_DIR}/${name}-${ts}.ppm"; mv "${ppm}" "${out}"
|
||||||
|
fi
|
||||||
|
echo "screenshot=${out}"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_list() {
|
||||||
|
[[ -d "${VM_ROOT}" ]] || { echo "(keine VMs)"; return; }
|
||||||
|
local any=0
|
||||||
|
for d in "${VM_ROOT}"/*/; do
|
||||||
|
[[ -d "${d}" ]] || continue
|
||||||
|
any=1
|
||||||
|
local name arch state
|
||||||
|
name="$(basename "${d}")"
|
||||||
|
arch="$(cat "${d}/arch" 2>/dev/null || echo '?')"
|
||||||
|
if vm_running "${name}"; then state="laeuft (pid $(vm_pid "${name}"))"; else state="gestoppt"; fi
|
||||||
|
echo "${name} [${arch}] ${state}"
|
||||||
|
done
|
||||||
|
[[ "${any}" -eq 1 ]] || echo "(keine VMs)"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_stop() {
|
||||||
|
local name="${1:?name}"
|
||||||
|
local d; d="$(vm_dir "${name}")"
|
||||||
|
if vm_running "${name}"; then
|
||||||
|
printf 'quit\n' | socat - "unix-connect:${d}/monitor.sock" >/dev/null 2>&1 || true
|
||||||
|
sleep 0.5
|
||||||
|
vm_running "${name}" && kill "$(vm_pid "${name}")" 2>/dev/null || true
|
||||||
|
echo "VM '${name}' gestoppt."
|
||||||
|
else
|
||||||
|
echo "VM '${name}' lief nicht."
|
||||||
|
fi
|
||||||
|
rm -f "${d}/pid" "${d}/monitor.sock"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_rm() {
|
||||||
|
local name="${1:?name}"
|
||||||
|
vm_running "${name}" && cmd_stop "${name}"
|
||||||
|
rm -rf "$(vm_dir "${name}")"
|
||||||
|
echo "VM '${name}' geloescht."
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local sub="${1:-}"; shift || true
|
||||||
|
case "${sub}" in
|
||||||
|
create) cmd_create "$@" ;;
|
||||||
|
boot) cmd_boot "$@" ;;
|
||||||
|
screenshot) cmd_screenshot "$@" ;;
|
||||||
|
list) cmd_list "$@" ;;
|
||||||
|
stop) cmd_stop "$@" ;;
|
||||||
|
rm) cmd_rm "$@" ;;
|
||||||
|
""|-h|--help)
|
||||||
|
sed -n '2,40p' "$0" | sed 's/^# \{0,1\}//' ;;
|
||||||
|
*) die "unbekanntes Kommando: ${sub} (siehe --help)" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
Executable
+53
@@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# qemu-setup.sh — installiert QEMU fuer ALLE Architekturen auf dem ARIA-Host
|
||||||
|
# (172.0.2.33) plus den aria-vm-Helper. Einmalig als root ausfuehren.
|
||||||
|
#
|
||||||
|
# sudo bash host-provisioning/qemu-setup.sh
|
||||||
|
#
|
||||||
|
# KVM-Beschleunigung gibt es nur fuer x86-Gaeste auf einem x86-Host; ARM/MIPS/
|
||||||
|
# PPC/RISC-V laufen unter TCG (voll emuliert, langsamer, aber alle Architekturen
|
||||||
|
# baubar). websockify/noVNC werden NICHT installiert — der VNC-Stream wird als
|
||||||
|
# RFB-Bytes durch die Bridge/RVS getunnelt (siehe aria_bridge.py VNC-Bruecke).
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [[ "${EUID}" -ne 0 ]]; then
|
||||||
|
echo "Bitte als root ausfuehren (sudo)." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[qemu-setup] apt update ..."
|
||||||
|
apt-get update -qq
|
||||||
|
|
||||||
|
echo "[qemu-setup] Installiere QEMU (alle Architekturen) + Werkzeuge ..."
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
qemu-system \
|
||||||
|
qemu-system-x86 \
|
||||||
|
qemu-system-arm \
|
||||||
|
qemu-system-mips \
|
||||||
|
qemu-system-ppc \
|
||||||
|
qemu-system-sparc \
|
||||||
|
qemu-system-misc \
|
||||||
|
qemu-utils \
|
||||||
|
seabios \
|
||||||
|
ovmf \
|
||||||
|
ipxe-qemu \
|
||||||
|
socat \
|
||||||
|
imagemagick
|
||||||
|
|
||||||
|
echo "[qemu-setup] KVM-Status:"
|
||||||
|
if [[ -e /dev/kvm ]]; then
|
||||||
|
echo " /dev/kvm vorhanden → x86-Gaeste mit KVM-Beschleunigung."
|
||||||
|
else
|
||||||
|
echo " /dev/kvm FEHLT → alle Gaeste laufen unter TCG (emuliert, langsamer)."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# aria-vm-Helper installieren (liegt neben diesem Skript).
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
install -m 0755 "${SCRIPT_DIR}/aria-vm" /usr/local/bin/aria-vm
|
||||||
|
echo "[qemu-setup] /usr/local/bin/aria-vm installiert."
|
||||||
|
|
||||||
|
mkdir -p /var/lib/aria-vms
|
||||||
|
echo "[qemu-setup] VM-Verzeichnis: /var/lib/aria-vms"
|
||||||
|
|
||||||
|
echo "[qemu-setup] Fertig. Test: aria-vm list"
|
||||||
Reference in New Issue
Block a user