From aaa7a347b22a522c6ac8877bd82b1fdfb6849b6c Mon Sep 17 00:00:00 2001 From: Tim-Oliver Husser Date: Wed, 26 Aug 2026 13:25:25 +0200 Subject: [PATCH 1/4] Remove specs/design/ links from README User-facing docs shouldn't point at internal design docs; inline the relevant facts instead. --- README.md | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index be24e3f..d5ff6c4 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ filter their logs, and view and edit their configuration files — all from a br - Responsive: on small screens the table collapses to status dot + name + log counts + actions - **Module detail** — per-module view with four tabs: - *Overview* — current status, PID, uptime, CPU and memory usage, running `pyobs-*` package versions (flagged when they lag the installed set), per-level log message counts (last 24 h), XMPP connection state (if enabled), start/restart/stop/activate/deactivate control - - *Logs* — live log tail with text filter, time-range filter (set a start date to load all logs since that instant, or click a line to set it), colour-coded by severity, auto-refresh; scrolling to the top auto-loads older entries (journald-backed modules, or file-backed modules once a start date is set, see [journald-logs.md](specs/design/journald-logs.md)) + - *Logs* — live log tail with text filter, time-range filter (set a start date to load all logs since that instant, or click a line to set it), colour-coded by severity, auto-refresh; scrolling to the top auto-loads older entries (journald-backed modules, or file-backed modules once a start date is set) - *Config* — YAML editor with syntax highlighting and colour-coded `{include}` lines; included shared configs are shown as clickable links - *ACL* — point-and-click editor for the module's `acl:` block: click to allow/deny known modules, add other callers, toggle enforce/log mode - **New module** — a "+" next to the sidebar's Modules section creates a brand-new `.yaml` config (a minimal starter with just a `class:` key) and takes you straight to its Config tab to fill in the rest @@ -26,7 +26,7 @@ filter their logs, and view and edit their configuration files — all from a br - **Packages** (`/packages/`) — every installed `pyobs-*` package (plus anything else listed in `PYOBS_MANAGED_PACKAGES`) with its installed and latest-PyPI version, and a one-click Update button; git/URL-installed packages get a Reinstall action instead (see [Package management](#package-management)) - **Overview** (`/overview/`) — fleet-wide summary, one row per configured host: reachable or not, running/stopped/total counts, aggregate CPU/RAM, linking into that host's own Dashboard, plus a package-version matrix (one row per `pyobs-*` package, one column per host) so version drift across the fleet is visible at a glance. Deliberately no bulk or per-module actions — those stay on the per-host Dashboard, since a fleet-wide "Stop All" from one button is a real footgun - **All Logs** (`/logs/`) — fleet-wide live log tail across every module on every configured host, same filtering and scroll-to-load-older behaviour as a module's own Logs tab -- **ACL Matrix** (`/acl/`) — fleet-wide read-only matrix of which module can call which, merged across every configured host (see [acl-matrix.md](specs/design/acl-matrix.md)) +- **ACL Matrix** (`/acl/`) — fleet-wide read-only matrix of which module can call which, merged across every configured host - **Hub mode** — control multiple remote pyobs hosts from a single browser tab; remote hosts are listed in the sidebar and all actions are proxied transparently - **ejabberd / XMPP status** (optional) — dashboard summary tile and per-module connected/not-connected indicator, plus a session/last-seen/registered-account block on each module's own page, for modules with a `comm.user` in their config — closes the gap between "the process is running" and "the module is actually reachable over XMPP" (see [ejabberd integration](#ejabberd-integration)) - **ejabberd / XMPP user management** (optional, builds on the above) — register, reset password, ban/unban, unregister, and kick XMPP accounts, either from a module's own Overview tab or from a fleet-wide **Users** page (`/xmpp-users/`) listing every registered account across every host, cross-referenced against which module(s) use it and which one is actually running. Safe by design for an identity shared across more than one module's `comm.user` — a password reset writes back to every module sharing it, and destructive actions name which other modules are affected before you confirm (see [ejabberd user management](#ejabberd-user-management)) @@ -193,13 +193,12 @@ PYOBS_LOG_DIR = "/opt/pyobs/log" # directory containing *.log files PYOBS_RUN_DIR = "/opt/pyobs/run" # directory for PID files PYOBS_LOG_LEVEL = "info" # log level passed to pyobs on start PYOBS_LOG_BACKEND = None # None (default): auto-detect from pyobsd's own - # config; "file" or "journald" to override -- - # see specs/design/journald-logs.md. If "journald": - # the account running pyobs-web-admin needs journal - # read access — `usermod -aG systemd-journal - # ` (preferred over `adm`, see the doc's - # "Which group to grant") — otherwise logs come - # back silently empty, no error. + # config; "file" or "journald" to override. If + # "journald": the account running pyobs-web-admin + # needs journal read access — `usermod -aG + # systemd-journal ` (preferred over `adm`, + # which grants broader log access than needed) — + # otherwise logs come back silently empty, no error. # Packages page (optional — see Package management section) PYOBS_MANAGED_PACKAGES = [] # e.g. ["pyobs-core[full]", "my-custom-driver", @@ -389,7 +388,7 @@ it as-is; `mod_http_api` can also expose account-management commands trusted, no password or token is involved. This blocks the network (a request from outside the host is rejected), but **not** other processes on the same machine, which get the same access pyobs-web-admin does. That's an accepted tradeoff for a dedicated, single-purpose -observatory control host — see `specs/design/ejabberd-integration.md` if your threat model is different. +observatory control host, not a shared one — reassess if that's not your deployment. --- @@ -539,12 +538,12 @@ end up as a literal `pip install` command-line argument, visible to any other lo - **Discovery** — all `*.yaml` files in `PYOBS_CONFIG_DIR` (excluding `*.shared.yaml`) are treated as modules. `*.shared.yaml` files are listed separately as shared configs. - **Creating a module** — the "New module" button writes a fresh `.yaml` with a minimal starter (`class:` key only); `PYOBS_CONFIG_DIR` is created automatically if it doesn't exist yet. - **Activate / Deactivate** — deactivating a module renames its config from `name.yaml` to `_name.yaml` (stopping it first if running); activating renames it back. Deactivated modules are excluded from *Start All* and *Restart All*. -- **Start** — runs `pyobs --pid-file /.pid --log-file /.log --log-level `. pyobs daemonises itself via `python-daemon`. If the effective log backend is `"journald"` (see below), `--syslog` is passed instead of `--log-file` — pyobs then logs directly to the systemd journal, tagged `SYSLOG_IDENTIFIER=pyobs` and `PYOBS_MODULE=` (see [journald-logs.md](specs/design/journald-logs.md)). +- **Start** — runs `pyobs --pid-file /.pid --log-file /.log --log-level `. pyobs daemonises itself via `python-daemon`. If the effective log backend is `"journald"` (see below), `--syslog` is passed instead of `--log-file` — pyobs then logs directly to the systemd journal, tagged `SYSLOG_IDENTIFIER=pyobs` and `PYOBS_MODULE=`. - **Stop** — sends `SIGTERM` to the PID in the PID file; falls back to `SIGKILL` after 5 s. - **Restart** — stop followed by start. - **Status** — checks whether the process with the stored PID is alive (`os.kill(pid, 0)`). - **Resource usage** — uptime, CPU %, and RSS memory read via `psutil` on every status poll. -- **Logs** — read from `PYOBS_LOG_DIR`'s flat files by default, or from the systemd journal via `journalctl` if the effective log backend is `"journald"`; the log viewer and per-level counts work identically either way. The effective backend is `PYOBS_LOG_BACKEND` if set explicitly, otherwise auto-detected from `pyobsd`'s own config file (`~/.config/pyobs.yaml`, `/etc/pyobs.yaml`, or `/opt/pyobs/storage/pyobs.yaml`, first found wins) — the same file `pyobsd` (`pyobs-core`'s daemon manager) reads to decide whether *it* starts modules with `--syslog`, so this can't silently drift out of sync with it. Scrolling a log window to the top auto-loads older entries via journalctl's `--until`, for journald-backed modules only — the file backend's plain `tail -n` has no seek/offset to page further back with, so it reports nothing older available instead (see [journald-logs.md](specs/design/journald-logs.md)). +- **Logs** — read from `PYOBS_LOG_DIR`'s flat files by default, or from the systemd journal via `journalctl` if the effective log backend is `"journald"`; the log viewer and per-level counts work identically either way. The effective backend is `PYOBS_LOG_BACKEND` if set explicitly, otherwise auto-detected from `pyobsd`'s own config file (`~/.config/pyobs.yaml`, `/etc/pyobs.yaml`, or `/opt/pyobs/storage/pyobs.yaml`, first found wins) — the same file `pyobsd` (`pyobs-core`'s daemon manager) reads to decide whether *it* starts modules with `--syslog`, so this can't silently drift out of sync with it. Scrolling a log window to the top auto-loads older entries via journalctl's `--until`, for journald-backed modules only — the file backend's plain `tail -n` has no seek/offset to page further back with, so it reports nothing older available instead. - **Log counts** — per-level message counts (DEBUG / INFO / WARNING / ERROR / CRITICAL) for the last 24 h, using binary search on the log file to avoid reading the whole file. --- From 89f62a5af5e9b7ae27d5e4ba834030042e4423ed Mon Sep 17 00:00:00 2001 From: Tim-Oliver Husser Date: Wed, 26 Aug 2026 13:37:24 +0200 Subject: [PATCH 2/4] Add UI screenshots to docs and README Captures the module dashboard and the per-module YAML config editor. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01RKRey9bBbX8BRXaHtgdJA4 --- README.md | 2 ++ .../_static/screenshots/config-editor.jpg | Bin 0 -> 34660 bytes docs/source/_static/screenshots/dashboard.jpg | Bin 0 -> 55681 bytes docs/source/features/dashboard.rst | 10 ++++++++++ 4 files changed, 12 insertions(+) create mode 100644 docs/source/_static/screenshots/config-editor.jpg create mode 100644 docs/source/_static/screenshots/dashboard.jpg diff --git a/README.md b/README.md index d5ff6c4..334c10d 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ A web-based administration interface for [pyobs](https://github.com/pyobs/pyobs- the robotic telescope framework. It lets you start, stop, and restart modules, tail and filter their logs, and view and edit their configuration files — all from a browser. +![Dashboard showing modules grouped under Stopped and Deactivated headings, with summary tiles and per-row quick-action buttons](docs/source/_static/screenshots/dashboard.jpg) + ## Features - **Dashboard** — sortable list view of all modules with: diff --git a/docs/source/_static/screenshots/config-editor.jpg b/docs/source/_static/screenshots/config-editor.jpg new file mode 100644 index 0000000000000000000000000000000000000000..411da7d6951cfb805b3e5163bbad07ad0f596fbb GIT binary patch literal 34660 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 Uzws@6b{*4S`*vJh$A4h`KUY`sC;$Ke literal 0 HcmV?d00001 diff --git a/docs/source/_static/screenshots/dashboard.jpg b/docs/source/_static/screenshots/dashboard.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6e7616bf0f27cb9e01e38cded70e221287ad6ca3 GIT binary patch literal 55681 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 literal 0 HcmV?d00001 diff --git a/docs/source/features/dashboard.rst b/docs/source/features/dashboard.rst index 5cc0060..62a9d63 100644 --- a/docs/source/features/dashboard.rst +++ b/docs/source/features/dashboard.rst @@ -1,6 +1,16 @@ Dashboard and module detail ############################ +.. image:: ../_static/screenshots/dashboard.jpg + :alt: Dashboard showing six modules grouped under Stopped and Deactivated headings, with + Total/Running/Stopped/RAM/CPU summary tiles and per-row quick-action buttons. + :width: 100% + +.. image:: ../_static/screenshots/config-editor.jpg + :alt: Module detail Config tab showing a syntax-highlighted YAML editor for a module's + config file. + :width: 100% + Dashboard ********* From 0b03ceeba917894bb511618ddebee02b247673f3 Mon Sep 17 00:00:00 2001 From: Tim-Oliver Husser Date: Wed, 26 Aug 2026 13:57:31 +0200 Subject: [PATCH 3/4] Require stable pyobs-auth>=2.0.0 --- pyproject.toml | 2 +- uv.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 99faf48..b4b6391 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ dependencies = [ "gunicorn>=26.0.0", "packaging>=24.0", "psutil>=6.0", - "pyobs-auth>=2.0.0.dev9", + "pyobs-auth>=2.0.0", "pyyaml>=6.0", "requests>=2.32", "ruamel.yaml>=0.18", diff --git a/uv.lock b/uv.lock index 355920c..b43e4da 100644 --- a/uv.lock +++ b/uv.lock @@ -325,7 +325,7 @@ crypto = [ [[package]] name = "pyobs-auth" -version = "2.0.0.dev9" +version = "2.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "django" }, @@ -333,9 +333,9 @@ dependencies = [ { name = "pyjwt", extra = ["crypto"] }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7d/ff/a64a7994969277066c095497a70751fbef8111ce732123744cf4fc7880bf/pyobs_auth-2.0.0.dev9.tar.gz", hash = "sha256:1c6b9cc5bb46598cf5b11f070aaaa8975b5133b52c2960588b3b5a5c42041288", size = 10731, upload-time = "2026-08-23T11:09:30.172Z" } +sdist = { url = "https://files.pythonhosted.org/packages/03/d8/e48c678696cd9fe01107b447b34121c8353fac79750eae3c0cd7717fe948/pyobs_auth-2.0.0.tar.gz", hash = "sha256:09111ea0c40834230fb07f77a257c88843d9058da8ca2d49ed8f6823129ce18d", size = 10734, upload-time = "2026-08-26T11:48:35.842Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ad/ea/c292cb6eb57247a64747b186cb0f0ff0b8190235d190d74bab9e9499d426/pyobs_auth-2.0.0.dev9-py3-none-any.whl", hash = "sha256:7122ac35d604d1d3f251c5c9f0d7180696ecdfefd7860a09585fd88e06dfdf72", size = 12827, upload-time = "2026-08-23T11:09:29.062Z" }, + { url = "https://files.pythonhosted.org/packages/05/56/38a65add71f41b80b6d3105b85083e785855f6159228880b710a6eddc163/pyobs_auth-2.0.0-py3-none-any.whl", hash = "sha256:22831044a997ec7ec5ea58ac233f12adda14683ab7f18b3685b272cf8026d743", size = 12770, upload-time = "2026-08-26T11:48:34.908Z" }, ] [[package]] @@ -366,7 +366,7 @@ requires-dist = [ { name = "gunicorn", specifier = ">=26.0.0" }, { name = "packaging", specifier = ">=24.0" }, { name = "psutil", specifier = ">=6.0" }, - { name = "pyobs-auth", specifier = ">=2.0.0.dev9" }, + { name = "pyobs-auth", specifier = ">=2.0.0" }, { name = "pyyaml", specifier = ">=6.0" }, { name = "requests", specifier = ">=2.32" }, { name = "ruamel-yaml", specifier = ">=0.18" }, From e6e5ad9a7a997b1aedeeea8b1ae8763a383c4efa Mon Sep 17 00:00:00 2001 From: Tim-Oliver Husser Date: Wed, 26 Aug 2026 13:57:35 +0200 Subject: [PATCH 4/4] v2.0.0 --- pyproject.toml | 2 +- uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b4b6391..fd92ae6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "pyobs-web-admin" -version = "2.0.0.dev14" +version = "2.0.0" description = "Web-based administration interface for pyobs robotic telescope modules" authors = [ { name = "Tim-Oliver Husser", email = "thusser@uni-goettingen.de" }, diff --git a/uv.lock b/uv.lock index b43e4da..2f5fa0c 100644 --- a/uv.lock +++ b/uv.lock @@ -340,7 +340,7 @@ wheels = [ [[package]] name = "pyobs-web-admin" -version = "2.0.0.dev14" +version = "2.0.0" source = { virtual = "." } dependencies = [ { name = "django" },