Skip to content

VirtDeck v3.0.4

Choose a tag to compare

@github-actions github-actions released this 14 Oct 06:53
· 13 commits to main since this release

VirtDeck v3.0.4

What changed

v3.0.4 — connection identity and safe cache restore (external audit stage 5.1)

Bug fixes

  • Connection identity: every connection now carries a stable conn_id, independent of its display name. Connection names must be unique up to normalization (NFC + outer-space strip + case-insensitive comparison). Legacy databases that already contain colliding names (Web/web, trailing spaces, different Unicode compositions of the same text) load untouched — the entries are not merged, renamed or removed; they stay visible with a distinct warning and are excluded from hard/soft refresh, cache restore, token operations, the PBS panel and fleet collection until the user resolves the conflict in the new repair dialog (pick the connection to keep — the loser is removed through the regular delete flow with its own confirmation and token revoke). Creating new conflicts is rejected at the add dialog, at the add flow and centrally at config save
  • Startup cache restore is identity-keyed: cached rows are matched by the producing connection's conn_id, never by the display name. A connection deleted and re-created under the same name restores nothing, rows written by previous versions (no conn_id) and rows of unknown connections are never attached — the data is re-fetched from the server instead of showing resources of a foreign infrastructure. Resource-cache writes are skipped entirely while a conn_id migration has not been persisted (e.g. a read-only config directory), and rows without an identity are never stored
  • Worker results are identity-gated: a refresh result of an unknown, deleted or re-created connection (or of an ambiguous one) is dropped before it can touch the repositories, the update epochs, the UI or the cache; the owner's name is taken from the current configuration, not from the stale result. The existing generation/epoch checks are preserved — a late answer of a deleted connection cannot resurrect its data
  • Config import: entries are matched by (type, host, user) instead of (host, user) — a PBS entry at the same address as a PVE entry no longer silently replaces it. A matched connection keeps its local name and identity; only credential/option fields are imported, and the token is written to the keyring only when it actually changed. Identifiers from the bundle are never accepted as local identity: new entries get fresh local ids, and a full-restore import (merge=False) assigns fresh ids to every entry — a restored backup can never attach the local cache of another installation. Conflicting names, invalid entries and ambiguous matches are skipped with explicit reasons collected into the import summary instead of aborting the whole import or silently overwriting; re-importing the same bundle is idempotent and no longer leaves orphaned keyring entries
  • Token refresh (reconnect) no longer rebuilds the connection from the dialog's short field list — skip, group, port/proxy/cluster settings and the conn_id survive a token rotation (previously skip and group were silently dropped)

Internal

  • The conn_id migration runs at config load and persists in a single SQLite transaction touching only the changed rows; on failure the app keeps working with in-memory ids while resource-cache writes stay blocked until a successful config save anchors them. Tokens and other secrets are never touched by the migration
  • Name normalization, ambiguity detection and uniqueness checks are centralized in the config layer (normalize_name, name_key, mark_ambiguous, save_config); the shrink-only guarantee for legacy conflict groups is enforced inside save_config itself, against the stored database — no caller can widen the tolerance (a group may stay verbatim, shrink or disappear, never grow, and no new group may appear)
  • 50 new regression tests (config-level and UI-level) covering the audit 5.1/5.1.1 matrices and the 5.1.3 review: id migration and the pending state (including failed saves keeping the flag), ambiguity handling and the shrink-only save rule, import rules, the three data-ingestion gates, the legacy name-fallback boundaries and cache-write blocking
  • Release engineering: the CI matrix covers Python 3.10–3.14 and PySide6 is capped to >=6.5,<6.12 per the project policy (the floating CI resolution pulled the buggy 6.12.0 and was red); a new scripts/check_release.py runs as a CI job and verifies install-command versions, CI-matrix-vs-declared-support, i18n key parity and fingerprint formatting; the README install command, the PEP 668 note (venv-first), the fingerprint spacing (+ machine verification snippet) and the Language switching section were corrected to match the actual implementation
  • python3-pyside6 debs (revision -3) declare Provides: libpyside6-py3, libshiboken6-py3 and Conflicts: against the distro split-PySide6 packages: Ubuntu 26.04's python3-pyqtgraph hard-depends on libpyside6-py3, which previously made apt install virtdeck unsolvable there (file clash with our wheel). The virtual provides satisfy pyqtgraph, the conflicts remove the distro pieces gracefully instead of a dpkg error

Install

Website: https://virtdeck.mclure.ru · Repository: https://repo.mclure.ru

Download: .deb (Debian/Ubuntu), .rpm (Fedora), .zip/.exe (Windows); .tar.gz / .whl — from source.

Debian 12 / 13, Ubuntu 24.04 / 26.04 — from the package repository (PySide6 comes from there too, no pip needed):

curl -fsSL https://repo.mclure.ru/KEY.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/virtdeck.gpg
echo "deb [signed-by=/etc/apt/keyrings/virtdeck.gpg] https://repo.mclure.ru/apt bookworm main" | sudo tee /etc/apt/sources.list.d/virtdeck.list
sudo apt update && sudo apt install virtdeck

(Ubuntu 24.04 — replace bookworm with noble; Ubuntu 26.04 — resolute; Debian 13 — trixie)

Fedora 43 / 44:

sudo tee /etc/yum.repos.d/virtdeck.repo <<'EOF'
[virtdeck]
name=VirtDeck
baseurl=https://repo.mclure.ru/rpm/fedora/$releasever
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://repo.mclure.ru/KEY.gpg
EOF
sudo dnf install virtdeck

Verify the repository key fingerprint after downloading it
(the key and the packages share one domain; the fingerprint is also
published on the website and at repo.mclure.ru):

117D EABD 3EA4 8810 B219 BA6B 401F 700F B97D E8B8

For the VM console install virt-viewer (sudo apt install virt-viewer / sudo dnf install virt-viewer).