• v0.5.6 631f2b414e

    brian released this 2026-09-26 14:23:18 +00:00 | 20 commits to main since this release

    Overview

    A UI-focused release with a reliability fix. The dashboard is rebuilt as a responsive grid of
    compact cards, the instance cards on the system detail page were redesigned, and the
    intermittent "system/instance disappears" flapping was traced to a connection leak and fixed.
    Plus a full dependency CVE audit and patch pass across the backend, frontend, and shipped Docker
    image. No functional API changes — every item below is presentation, reliability, or
    dependency hygiene.

    UI Improvements

    Dashboard rebuilt as a responsive card grid

    The whole dashboard was redesigned to match a new compact card layout. The antd
    Row/Col/Card/Statistic scaffolding was replaced with a plain CSS grid.

    • Responsive grid, one scrollable page: 1 column on small screens, 2 at ≥768px, 3 at
      ≥1024px, and 4 at ≥1280px where the Systems card spans two columns.
    • Accent icon chip on each summary card (Systems, Total Users, Tenants, Backups, Snapshots),
      each with its own theme token — new --accent-systems/users/tenants/backups/snapshots variables
      defined for both light and dark mode (darker shades use lighter variants for contrast).
    • Systems card: shows the top 3 systems by CPU as nested panels, each with stacked
      CPU/RAM bars and a Connected: X / Y indicator that turns amber when any host is down.
    • My Instances / Total Instances: show the top 5 running instances by CPU or RAM with an
      in-card CPU | RAM toggle. Rows are name-first (long names ellipsize with a tooltip on hover),
      followed by a bar and the metric value. Each card keeps an independent toggle and its own
      footer pill — Total Running X / Y for My Instances, Running / Stopped X / Y for Total.
      Running instances only (a stopped instance always reports 0% CPU, so it would never rank).
      CPU bars are absolute 0–100%; RAM bars are scaled relative to the heaviest instance shown.
      "Mine" is derived on the frontend from the per-instance owner tag, so no new API call.
    • Total Users shows the role split as pills (Admin: N, User: N) instead of tags.
    • Tenants, Backups, and Snapshots move their detail lines into compact info panels
      under the headline number.
    • All colors are theme-aware (light + dark) via the app's CSS variables; no hardcoded hex values
      in the view.

    Instance cards redesigned (system detail page)

    • Redesigned the cards on /systems/:id/instances for a cleaner, scannable layout:
      • Instance name on its own line with a tinted type badge (container/virtual-machine)
        beside it — labels no longer cover the name.
      • Status row beneath: colored status dot (Running/Stopped) and @owner.
      • Metrics restyled: CPU, RAM Usage, and Disk Storage each show label + monospace
        value on one line with a slim rounded bar below (purple/green/blue).
      • Network Throughput row with ▼ RX / ▲ TX live rates replaces the mini sparkline
        (the sparkline remains in the expanded detail view).
      • CPU now shows live utilization % (delta-based, like the dashboard system graphs) —
        e.g. 38% with the bar scaled 0–100 — instead of cumulative "CPU Time" in seconds. The
        label includes the allocation when set (CPU (2 cores)); percentage is computed against
        limits.cpu, falling back to the host's total core count. The Instances table shows the
        same %.
      • Disk Storage now shows used / total (e.g. 4.2 GiB / 9.3 GiB). The total comes from
        the instance's live Incus state (size/filesystems.space_total per disk device), falling
        back to the configured root-device size, instead of previously showing bare usage whenever
        no explicit size limit was configured. The global Instances table and detail panel use the
        same totals.
      • Interfaces (N) footer lists IP chips with a Hide/Show IPs toggle; collapsed by
        click, and toggling never triggers card expansion.
    • All colors are theme-aware (light + dark) via the app's CSS variables.
    • Card click-to-expand (detail tabs) is unchanged.

    Bug Fixes

    Systems and instances intermittently disappeared from the dashboard

    • Symptom: cards for a given host would periodically vanish and the "connected" count would
      flap between e.g. 5/5 → 4/5 → 5/5. The frontend keeps stale data on failed fetches, so cards
      only disappeared when the backend answered successfully with empty/false — meaning transient
      Incus request failures were being silently swallowed.
    • Root cause 1 — connection leak: every polling path created a fresh httpx.AsyncClient per
      system per cycle and never closed it (dashboard summary, systems/host-info, instances-state,
      and the 30s background instance sync). A steady socket/TLS-session leak in a long-running
      container is a prime cause of intermittent Incus connection failures.
    • Root cause 2 — no retry: a single timeout or connection reset marked a system as
      connected: false, which with 10s pollers reads as a card disappearing.
    • Fix:
      • Added IncusConnector.aclose() (closes the pooled client and clears the handle; idempotent)
        and wired finally: await connector.aclose() into every polling path listed above, plus the
        scheduled-backup worker.
      • IncusConnector.get() now retries twice (3 attempts total, 0.5s pause) on
        httpx.RequestError. GETs are idempotent, so this absorbs transient daemon hiccups without
        hiding persistent failure.
      • Added logger.warning on every previously-silent failure path (dashboard get_server_info,
        both instance-listing builders, and the host-info probe) so docker logs now shows the real
        exception at the moment a system drops, instead of the card just going quiet.
    • Note: if flapping persists on a specific host, re-register that system with its static-IP
      endpoint — a hostname-registered endpoint can intermittently fail DNS resolution from inside
      the container (EAI_AGAIN via the router/mDNS resolver).

    Security Fixes

    Python dependencies

    • Removed: python-jose[cryptography] — the package is unused by the application (auth is
      built on PyJWT) and dragged in ecdsa, which carries the Minerva timing-attack advisory
      (CVE-2024-23342 / PYSEC-2026-1325) with no upstream fix available. Dropping the dead
      dependency eliminates it from the image entirely.
    • Added: cryptography pinned explicitly (it was only present transitively via python-jose;
      required for RS256 delegation tokens and hub key handling).
    • All packages resolved to latest (fastapi 0.141.1, starlette 1.6.0, pydantic 2.13.5,
      cryptography 50.0.1, PyJWT 2.14.x, httpx 0.28.1, ...). pip-audit on the full dependency tree:
      0 known vulnerabilities.

    Frontend (npm) dependencies

    • axios 1.x → 1.20.0 — fixes axios form-data recursion DoS (GHSA-42h9-826w-cgv3) and the
      form-serializer maxDepth bypass (GHSA-hcpx-6fm6-wx23).
    • form-data → 4.0.6 — fixes CRLF injection in multipart field names/filenames
      (GHSA-hmw2-7cc7-3qxx).
    • postcss → 8.5.28 (build-time) — fixes source-map path traversal / arbitrary .map
      disclosure (GHSA-fxqj-rqcc-2cmp, GHSA-r28c-9q8g-f849).
    • nanoid → 3.3.19 (build-time) — fixes generator loops with negative/zero size
      (GHSA-28wg-ghj8-5hjv, GHSA-2v37-7h3g-55p8).
    • npm audit (prod and dev trees): 0 vulnerabilities.

    Docker base image

    • Rebuilt from the latest python:3.12-slim (Debian 13.7) via docker build --pull; apt reports
      no further upgrades available.
    • Known residual (unpatchable): 44 Debian 13 HIGH advisories flagged "affected, no fix in the
      stable repos yet" — util-linux mount helpers (4 CVEs across its packages), ncurses,
      libsystemd/libudev, libacl1, and perl-base (fix deferred upstream). None of these are on the
      application's attack surface (the container runs uvicorn + nginx only; it invokes no mount,
      terminal, or perl tooling). Re-evaluate when Debian ships point releases.
    • Trivy scan of the shipped image: 0 HIGH/CRIT in python-pkg and npm layers.

    Test Results

    • Backend pytest 743/743 against the exact shipped dependency resolution; vitest 215/215;
      Playwright E2E 71/71; vite build clean; in-container verification (app import, RS256
      roundtrip, static asset serving) and a live smoke test against a Postgres sidecar
      (/api/health 200, container health healthy).

    Upgrade Notes

    • Pull bmcgonag/incus-commander:0.5.6 (or latest) and restart; hard-refresh the browser.
    • Image digest: sha256:6617b10490cb351a738b07f36d397de547f05427e34cc2e398adb003d6ef4f83
    • The dashboard redesign is presentation-only — no schema migrations, no API changes, no config
      changes. Existing sessions and settings carry over untouched.
    Downloads
  • v0.5.5 da62538e36

    brian released this 2026-09-21 12:19:48 +00:00 | 24 commits to main since this release

    Overview

    Storage management across the board — a new Storage Pools page (pool inventory, available
    disks, pool creation) plus custom volume create/attach from both the Storage Volumes page and
    the instance menu — a round of static-IP fixes that simplified instance networking, and reliable
    System deletion with a new type-to-confirm safety gate. This release includes everything
    previously shipped piecemeal as the 0.5.4-beta and 0.5.5-beta images since v0.5.2.

    New Features

    Storage Pools Page

    • New top-level Storage Pools page: pick a system to see its configured pools (driver,
      usage bars) alongside the physical disks that are free for new pools (Available Disks).
    • New: POST /api/systems/{id}/storage-pools — admins can create a storage pool from an
      available source (403 for non-admins). Backed by GET /{id}/storage-pools (configured) and
      GET /{id}/storage-pools/available (unconfigured disks from host resources).

    Create Custom Storage Volumes

    • New: POST /api/systems/{id}/storage-pools/{pool}/volumes creates a filesystem custom volume
      (name + size, e.g. 10GiB). Gated to admin/tenant_admin, validates the name and size format, and
      checks pool free space before creating (400 on insufficient capacity, 502 on Incus errors).
    • UI: A Create Volume button on the Storage Volumes page (admin/tenant_admin) opens a modal
      to pick system, pool, name, and size.

    Attach Existing / New Volumes to Instances

    • New: POST /api/systems/{id}/instances/{name}/storage/attach attaches an existing custom
      volume as a disk device on a container or VM (admin, tenant admin, or instance owner).
    • UI: The instance Attach Storage modal now has modes: Storage Template (as before),
      Existing Volume (pool → volume → mount point), and New Volume for admins (creates the
      volume then attaches it in one action). With no templates available the modal opens in
      Existing Volume mode.

    Bug Fixes

    Static IP during instance creation failed with "Unsupported device type"

    • Fixed: Creating a container with a static IP (modal Network Configuration) against a profile
      whose NIC uses nictype: bridged/parent: (or network:) failed with:
      Invalid devices: Device validation failed for "eth0": Failed loading device "eth0": Unsupported device type.
    • Root cause: The static-IP NIC override submitted to Incus only carried type, name, and
      the IP keys. Incus validates the submitted device before applying profile overrides, so a NIC
      without a parent/network reference has no determinable device type and is rejected.
    • Fix: The override now inherits the profile NIC's base keys (nictype/parent or network)
      before the IP keys are applied.
    • Fixed (follow-up): Containers with a static IP then failed to start with
      Failed to start device "eth0": "ipv4.gateway" is only supported on OCI containers. Incus only
      accepts ipv4.gateway on a NIC for OCI app containers — system containers/VMs must get the
      gateway from the managed network's DHCP or configure it inside the guest. The API now never
      submits ipv4.gateway (the deprecated ipv4_gateway field is accepted but ignored).
    • Removed: The Network Configuration section (static IP / gateway inputs) is gone from the
      Create Instance modal. Containers now simply boot with DHCP from their network (managed = Incus
      DHCP, unmanaged bridge = LAN router DHCP); pin addresses with a router DHCP reservation or
      guest-side netplan. The network_config API field remains for managed-network use.

    "Failed to delete system" when removing a registered host

    • Fixed: Deleting a system from the Systems page failed with a generic error whenever the
      system had any activity history. delete_system only cleaned up four tables, while six others
      hold non-cascade foreign keys to it (audit_logs, background_tasks, storage_templates,
      local_images, federated_instances, console_tokens), so the database rejected the delete.
    • Fix: The endpoint now runs in a single transaction: audit log and background task history
      are preserved (detached from the deleted system; the activity log keeps its system name),
      and all system-scoped artifacts (templates, attachments, local image records, federated
      instances, console tokens) are removed. This makes it possible to cleanly delete a system whose
      Incus host no longer exists.
    • UI: The delete error toast now shows the server's error detail instead of only a generic
      message.

    System deletion now requires confirmation by name

    • Safety: Deleting a system now requires typing the system name to confirm (same pattern as
      instance Destroy) — the Delete button stays disabled until the name matches exactly, preventing
      accidental removal of the wrong host.

    Technical Changes

    • backend/app/api/systems.py: added create_storage_pool, create_storage_pool_volume and
      attach_existing_volume endpoints; delete_system now performs transactional cleanup of all FK
      dependents (history preserved); create_system_instance static-IP handling now merges profile
      NIC base keys and never submits ipv4.gateway.
    • backend/app/services/incus.py: added create_storage_pool() connector method.
    • backend/app/utils/human.py: added parse_size_to_bytes() size-string parser.
    • frontend/src/views/StoragePoolsView.vue: new pools + available-disks page with admin pool
      creation.
    • frontend/src/components/CreateStorageVolumeModal.vue: new shared create-volume modal.
    • frontend/src/views/StorageVolumesView.vue: Create Volume button (role-gated).
    • frontend/src/views/InstancesView.vue, SystemInstancesView.vue: multi-mode Attach Storage modal.
    • frontend/src/views/SystemsView.vue: type-to-confirm delete modal (replaces the plain confirm).
    • frontend/src/components/CreateInstanceModal.vue: Network Configuration section removed
      (~200 lines of NIC/IP/gateway inputs, validation, and conflict checks).

    Breaking Changes

    • None at the database or authentication level. The instance-create UI no longer offers static
      IP entry (the network_config API field and check-ip endpoint remain, API-only); the
      deprecated ipv4_gateway field in network_config is now accepted but ignored.

    Upgrade Notes

    • No migration required. Pull the new Docker image (bmcgonag/incus-commander:0.5.5 or
      latest) and restart the container.
    • Hard-refresh the browser (Ctrl+Shift+R) after upgrading to pick up the new frontend build.
    Downloads
  • v0.5.2 c5276693df

    brian released this 2026-09-10 11:41:40 +00:00 | 27 commits to main since this release

    This release focuses on addressing stub features and small bugs.

    • Console navigation fix - the root console opened, but showed the side navigation which took up space and was not necessary.
    • Publish to Image for running containers - Publish to image failed if the container was running. This has been fixed so that it will first stop the container, create the image, and restart the container.
    • IP address display with endpoint fallback - Just felt it was useful to see the IP address of the host machines.
      • this includes back-end tests for config handling and IP extraction
    • Storage volume size formatting - Storage volumes showed, but couldn't be adjusted.
    • Edit modal storage attachment - Couldn't add storage when editing an existing container.
    • Auto Boot/Security Nesting toggle fixes - The Auto Boot and Security Nesting toggles didn't show the proper state, and were not able to be toggled in the Edit modal.

    To get this version you can get the docker image:

    • bmcgonag/incus-commander:0.5.2
    • bmcgonag/incus-commander:latest
    Downloads
  • v0.5.0 4d88e2b0b1

    brian released this 2026-08-27 15:26:30 +00:00 | 30 commits to main since this release

    New Features:

    • Image type indicators (C for containers, VM for virtual machines) in dropdowns
    • Template auto-start support

    Bug Fixes:

    • Image pull now waits for completion (600s timeout) with proper error messages
    • Instance type validation prevents mismatched image/instance combinations
    • Disk display NaN issue resolved
    • Template image display improvements
    Downloads
  • v0.4.0 3d03838292

    brian released this 2026-07-15 17:49:44 +00:00 | 41 commits to main since this release

    New Features

    ###Local Images Management

    • Upload images from your local machine to any Incus system
    • Download images from Incus systems to your local machine
    • Delete images with confirmation
    • View image details (aliases, size, properties, creation date)
    • Remote image server management (create, list, delete remotes)

    Native VGA Console (SPICE)

    • Open a full graphical console for virtual machines directly in the browser
    • Uses the SPICE protocol via spice-client for near-native display performance
    • Keyboard and mouse input forwarded in real-time
    • Fullscreen mode and Ctrl+Alt+Del toolbar
    • Containers are greyed out with tooltip (VGA only available for VMs)
    • Short-lived JWT tokens (60s expiry) for secure WebSocket connections
    • Per-channel WebSocket proxy with essential channel filtering (rejects playback, record, port, webdav channels)

    Instance Templates

    • Auto-system selection when creating instances from templates

    Backend Changes

    • Image upload/download streaming with progress tracking
    • VGA console token endpoint (POST /api/console/vga-token)
    • Per-channel SPICE WebSocket proxy (WS /api/console/vga/{systemId}/{name})
    • Image remote management endpoints
    • Certificate helpers for system connections
    • Settings defaults for image management

    Frontend Changes

    • LocalImagesView — full CRUD UI for images with upload modal, detail drawer
    • VgaConsoleView — SPICE client rendering with fullscreen and toolbar
    • VGA console launch from instance menus (admin and non-admin)
    • Router: /console/vga/:systemId/:name route
    • Updated profiles and instances views

    Infrastructure

    • Upgraded Docker base images: node:22-alpine, python:3.13-slim, nginx:alpine
    • Added spice-client npm dependency

    Test Coverage

    • 15 new backend console API tests (token creation, validation, expiry, role gating)
    • New backend image management API tests
    • Frontend VGA console unit tests
    • E2E tests for image management and VGA console navigation

    Docker Image

    docker pull bmcgonag/incus-commander:0.4.0
    docker pull bmcgonag/incus-commander:latest

    Downloads
  • 0.3.13 a48e0eeb16

    brian released this 2026-06-28 18:51:39 +00:00 | 42 commits to main since this release

    v0.3.13 — Local Images Filters & Full Actions

    Features

    • Added filter bar to Local Images view: filter by alias text, type (container/VM), system, and created by — all client-side computed with matching pagination
    • Incus-native images (those existing on hosts, not published through the app) now have full action support: Info modal (OS, release, arch, aliases, etc.), Refresh, Add Alias, Delete
    • New backend endpoints for Incus-native image management: GET/DELETE /images/by-system/{id}/{fingerprint}, alias CRUD, and refresh

    v0.3.12 — Incus-Native Image Management

    Features

    • Changed GET /images to aggregate from all Incus systems, not just the local_images DB table — images already on your hosts now appear in the list
    • Actions dropdown for Incus-native images: Info, Refresh, Add Alias, Delete
    • Info modal shows full Incus image metadata (fingerprint, type, size, architecture, OS, release, serial, auto-update, aliases with removable tags)

    v0.3.11 — Template & Destroy Confirmation Fixes

    Fixes

    • Template images now properly populate in instance creation dropdown (was blocked by a prop mismatch visible→open and Promise.all rejection on system API failure)
    • Instance creation from template no longer fails with "Image not provided" — backend resolves fingerprint/alias from the template record unconditionally
    • Destroy confirmation dialog added to SystemInstancesView (requires typing the instance name, matching the InstancesView pattern)

    v0.3.10–v0.3.4 — (Build iteration releases)

    v0.3.3 — Production Build Cache Fix

    Fixes

    • Resolved "stale frontend build" issue where lazy-loaded chunks returned 404 with wrong MIME type — rebuilt Docker image with --no-cache to ensure fresh vite build output
    Downloads