Releases: mrInvincible29/Qguardarr
Releases · mrInvincible29/Qguardarr
Release list
v0.3.7
v0.3.7 – Test stability fixes
Tests
- fix: stabilize CI by fixing event-loop usage in
tests/unit/test_rollback_apply.pyand avoiding mixing@pytest.mark.asynciowithTestClientintests/unit/test_managed_endpoint.py. - Note: Test-only changes; no runtime behavior change.
Links
- Full Changelog: v0.3.6...v0.3.7
v0.3.6
v0.3.6 – Auto‑unlimit inactive torrents
Added
- feat(config):
global.auto_unlimit_on_inactive(default false). When enabled, Qguardarr sets per‑torrent upload limits to unlimited (‑1) as soon as a torrent is not active in the current allocation cycle.
Changed
- feat(allocation): After applying differential updates, auto‑unlimit torrents that are currently inactive. Records rollback entries with reason
auto_unlimit_inactive. In dry‑run, persists changes to the dry‑run store only (no qBittorrent calls).
Tests
- Add unit tests covering real mode and dry‑run behavior.
Links
- Full Changelog: v0.3.5...v0.3.6
v0.3.5
What's Changed
Added
- config:
global.cache_ttl_secondsto control TorrentCache cleanup TTL (default 1800s).
Changed
- allocation: Only include active torrents; drop cache backfill-by-hashes API calls.
- allocation: Use configured TTL for cache cleanup to avoid stale entries.
- qbit: Add DEBUG logs for tracker URL selection and fallbacks.
Documentation
- README: Simplify Docker Quick Start, clarify config essentials, and document cache TTL.
Tests
- Update active-torrents unit to assert no backfill; add TTL cleanup test.
No breaking changes.
v0.3.4
Changed
- chore(config): Default
global.rollout_percentageis now 100 when omitted (previous default was 10). If you don’t specify it in config, Qguardarr manages 100% of eligible torrents. - chore(matching): Normalize shorthand tracker patterns like
.example\..*(e.g.,.example\.com.) into.*example\.com.*unless anchored with^/$.
Added
- feat(logging): DEBUG logs now include the selected tracker URL per torrent and the matched tracker with current upload speed (e.g.,
up=2.95 MiB/s). - feat(api):
/match/test?url=...&detailed=trueendpoint to test a tracker URL against configured patterns.
Tests
- Add unit tests for pattern normalization and the new match-test endpoint.
Full Changelog
v0.3.3
Added
- feat(api):
GET /stats/managedreturns managed torrents grouped by tracker withhash,current_limit,added_at,last_seen, andage_seconds.
Fixed
- fix(stats): For unlimited trackers (configured
max_upload_speed <= 0), reportconfigured_limit_mbps: nullinstead of-0.
Notes
- Application logs are written to the configured file (e.g.,
logs/qguardarr.log), while Uvicorn writes console logs. Tail the file for allocator activity.
Full Changelog
v0.3.2
Changed
- perf(qbit): Eliminate full-list queries. Use
filter=active+ upspeed threshold and backfill only a bounded subset of cached hashes viaGET /torrents/info?hashes=...(cap 1000). Trackers are fetched only for the filtered subsets. - chore(tests): Update unit tests to validate backfill-by-hashes behavior.
- chore(runner): Quick Docker test runner now waits for Qguardarr and executes the config hot-reload test in quick mode.
Added
- feat(config): Automatic config hot-reload via background watcher (mtime-based). Manual
POST /config/reloadendpoint for ops. - test(integration): Hot-reload integration test that edits host
config/qguardarr.yamland asserts rollout change.
Security
- No changes since 0.3.1; single-password auth and log redaction remain enforced.
Full Changelog
v0.3.1
Highlights
- Performance: query torrents with
filter=activeand fetch trackers only for torrents with real upload activity. This massively reduces qBittorrent API calls on large libraries. - Config: example config now reads
global.portfromAPP_PORTto align with Compose.
Images
- GHCR:
ghcr.io/mrinvincible29/qguardarr:latest - GHCR (pinned):
ghcr.io/mrinvincible29/qguardarr:v0.3.1 - Edge (latest commit):
ghcr.io/mrinvincible29/qguardarr:edge
Changed
- perf(qbit): Use
/api/v2/torrents/info?filter=active(instead ofuploading) and then keep only torrents withupspeed >= active_torrent_threshold_kb * 1024. Fetch/api/v2/torrents/trackersonly for this filtered subset. Greatly reduces per-cycle API load.
Tests
- Add unit test verifying the
activefilter is used and tracker lookups occur only for the active subset. - Docker quick integration tests: green.
Documentation
- Example config reads
global.portfromAPP_PORTfor consistency with Compose.
Upgrade Notes
- No breaking changes. Behavior is more selective by default and should lower API traffic.
- If you rely on very low-activity torrents, adjust
global.active_torrent_threshold_kb(default example is 10 KB/s). In large environments, 10–50 KB/s is typical; use higher values to be more selective.
Quick Pull
docker pull ghcr.io/mrinvincible29/qguardarr:v0.3.1- To pin in Compose:
image: ghcr.io/mrinvincible29/qguardarr:v0.3.1
Full Changelog
v0.3.0
Highlights
- Soft per-tracker limits with borrowing + smoothing (Phase 3).
- New admin endpoints: preview next cycle, reset smoothing, reset limits.
- Security: single-password qBittorrent auth, no password logs.
- Docker: use GHCR image by default; simpler Compose with
APP_PORT, noversion:key.
Images
- GHCR:
ghcr.io/mrinvincible29/qguardarr:latest - GHCR (pinned):
ghcr.io/mrinvincible29/qguardarr:v0.3.0 - Edge (latest commit):
ghcr.io/mrinvincible29/qguardarr:edge
Added
- Phase 3 “soft” strategy with priority-weighted borrowing and EMA smoothing.
- API:
GET /preview/next-cyclefor proposed tracker caps and per‑torrent changes. - API:
POST /smoothing/resetto clear Phase 3 smoothing state. - API:
POST /limits/resetto set touched torrents back to unlimited (supports dry‑run). - Stats: expose current
strategy; addeffective_cap_mbps,borrowed_mbpsper tracker.
Security
- Authenticate to qBittorrent using only configured credentials.
- Remove fallback/default password attempts; redact secrets in logs.
Changed
- Compose: pull from GHCR by default; drop obsolete
version:key; exposeAPP_PORTfor container port/health alignment. - Compose: remove
mem_limit; rely on host/container constraints or user-provided limits. - Logging: centralized setup; ensure log directory exists; avoid file handler permission errors.
Documentation
- Quick Start: run directly from GHCR, download compose and config from repo (no git clone).
- Webhooks: optional but recommended; periodic cycles still manage updates without them. Benefits and examples documented.
.env.example: addAPP_PORT=8089.
Tests
- Unit test: enforce single-password auth and log redaction.
- Docker quick integration tests: passing with Phase 3 and new endpoints.
Upgrade Notes
- Config compatibility: 0.3.0 is backward-compatible; Phase 3 is opt-in via
global.allocation_strategy: soft. - Docker:
- Compose now expects
APP_PORT(defaults 8089). If yourconfig.global.portdiffers, setAPP_PORTin.envto match (e.g.,APP_PORT=8189). version:key removed to silence Compose v2 warnings.mem_limitremoved; if you previously saw OOM kills (exit 137), consider adding your own limits or ensure adequate host memory.
- Compose now expects
- Cross-seed:
- Set
cross_seed.enabled: truein config to enable forwarding; environment variables alone do not enable it.
- Set
Quick Pull
docker pull ghcr.io/mrinvincible29/qguardarr:v0.3.0- In compose, set
image: ghcr.io/mrinvincible29/qguardarr:v0.3.0to pin.
Full Changelog
Qguardarr 0.2.0 — Phase 2: Weighted Allocation + Scoring
Qguardarr 0.2.0 — Phase 2: Weighted Allocation + Scoring
Highlights
- Weighted within-tracker allocation with smart torrent scoring (optional).
- Activity-based selection limits active set to top-N torrents for performance.
- Strategy switch keeps Phase 1 equal-split as default; opt-in to weighted.
- /stats now surfaces managed_torrent_count and score_distribution.
Added
- ActivityScorer: scores torrents by current upload, recent activity, and peers.
- Selection: manages only top global set (global.max_managed_torrents, default 1000).
- Weighted allocator: proportional per-tracker distribution with bounds (min 10 KB/s, max 60% of tracker cap).
- Config keys:
- global.allocation_strategy: equal (default) or weighted
- global.max_managed_torrents: integer (default 1000)
- /config and README document new settings; /stats documents new fields.
Migration
- No breaking changes; defaults remain Phase 1 equal-split.
- To enable Phase 2, add under global:
- allocation_strategy: weighted
- max_managed_torrents: 1000
- Verify via /config and observe /stats for managed_torrent_count and score_distribution.
Notes
- Per-torrent bounds: min 10 KB/s, max 60% of tracker cap.
- Differential updates and batching preserved to keep API calls low.
- Borrowing across trackers remains out-of-scope for 0.2.0 (planned for Phase 3).
Links
Qguardarr 0.1.0 — Phase 1 MVP
Qguardarr 0.1.0 — Phase 1 MVP
Highlights
- Hard per-tracker upload limits with equal distribution.
- Fast webhook handler (<10ms) using a queue pattern.
- Gradual rollout and differential updates to reduce API churn.
- Full rollback capability with SQLite-backed change tracking.
Added
- Per-tracker upload speed limits (equal split within trackers).
- Webhook handler for qBittorrent events with background processing.
- Allocation engine with rollout percentage and differential updates.
- SQLite rollback system with REST
/rollbackendpoint. - Docker deployment, Docker-based integration tests, and CI setup.
- Multi-arch Docker images (linux/amd64, linux/arm64).
- Unlimited semantics: set
max_upload_speed: -1for no cap (catch-all supported).
Notes
- Catch-all tracker should be last (pattern:
.*). - Matching precedence: specific tracker patterns take priority over catch-all.
- Multi-tracker handling (Phase 1): we use a single primary tracker per torrent (first working URL, else first non-error).
- Endpoints:
/health,/stats,/stats/trackers,POST /webhook,POST /cycle/force,POST /rollback,POST /rollout.
Links