Auto-start collectors when saving machines

This commit is contained in:
2026-05-07 21:09:05 +02:00
parent 02f6617f71
commit 3934893099
4 changed files with 19 additions and 6 deletions
+3 -2
View File
@@ -126,8 +126,9 @@ docker compose up --build
2. After the API is running, open the app, go to **Settings**, and add machine entries:
- **Local**: monitors the API host itself without SSH.
- **SSH**: monitors another machine using a host, username, and a private key pasted directly into the machine settings, with an optional passphrase.
- The machine editor groups Connection, Monitoring / Files, Jellyfin, and Jellyseerr settings under separate headings so each service area is easier to scan.
- Saving an SSH machine now validates the banner/auth flow and records the first trusted host key into the backend-managed `known_hosts` file, surfacing any errors if the host cannot be reached or authenticated.
- The machine editor groups Connection, Monitoring / Files, Jellyfin, Jellyseerr, and Notes under separate headings so each service area is easier to scan.
- Saving a monitoring machine now validates the banner/auth flow, records the first trusted host key into the backend-managed `known_hosts` file, and starts the collector so charts populate without a separate manual step.
- If the host cannot be reached or authenticated, the save flow surfaces the SSH error directly in the dialog.
- Use **Validate SSH + trust host** in the machine editor before saving if you want to test the banner/auth flow explicitly.
- The first successful SSH connection uses trust-on-first-use: the backend records that machine's host key into its managed `known_hosts` file automatically, then continues verifying it strictly on later connects.
@@ -12,6 +12,7 @@ from pydantic import BaseModel, Field
from media_library_viewer_api.clients.ssh import RemoteSSHClient
from media_library_viewer_api.config import get_settings
from media_library_viewer_api.dependencies import get_monitoring_poller, get_settings_store
from media_library_viewer_api.services.monitoring_actions import start_collector
from media_library_viewer_api.services.db_maintenance import remove_sqlite_database
from media_library_viewer_api.services.known_hosts import has_known_host
from media_library_viewer_api.services.media_index import MediaIndex
@@ -124,6 +125,12 @@ def _validate_saved_machine_ssh(machine: MonitoringMachineInput, store: Settings
client.close()
def _start_machine_collector(machine: MonitoringMachineInput, store: SettingsStore) -> None:
if "monitoring" not in {str(service).strip().lower() for service in machine.services}:
return
start_collector(machine.model_dump(exclude_none=True), store)
@router.post("/machines/test-ssh")
def test_machine_ssh(
machine: MonitoringMachineInput,
@@ -183,7 +190,9 @@ def post_machine(
saved = store.upsert_machine(machine.model_dump(exclude_none=True), machine.id)
poller = get_monitoring_poller()
try:
_validate_saved_machine_ssh(MonitoringMachineInput.model_validate(saved), store)
saved_machine = MonitoringMachineInput.model_validate(saved)
_validate_saved_machine_ssh(saved_machine, store)
_start_machine_collector(saved_machine, store)
finally:
poller.start()
poller.kick()
@@ -201,7 +210,9 @@ def put_machine(
saved = store.upsert_machine(machine.model_dump(exclude_none=True), machine_id)
poller = get_monitoring_poller()
try:
_validate_saved_machine_ssh(MonitoringMachineInput.model_validate(saved), store)
saved_machine = MonitoringMachineInput.model_validate(saved)
_validate_saved_machine_ssh(saved_machine, store)
_start_machine_collector(saved_machine, store)
finally:
poller.start()
poller.kick()