# How OpenLogi's Asset Mirror System Works and Fetches Device Renders

> Discover how OpenLogi's asset mirror system finds the fastest source, downloads catalogs, and fetches device renders with SHA-256 verification. Learn about its efficient, secure process.

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: internals
- Published: 2026-09-05

---

**OpenLogi's asset mirror system probes multiple redundant mirrors concurrently to locate the fastest source, downloads a versioned catalog, and resolves device-specific renders through priority-based file selection with SHA-256 verification.**

The **asset mirror system** in the [AprilNEA/OpenLogi](https://github.com/AprilNEA/OpenLogi) repository manages the distribution of device metadata and renders across three redundant sources. At runtime, the system automatically selects the optimal mirror, retrieves a centralized catalog, and fetches specific device assets like hero renders and button images with cryptographic verification.

## Mirror Discovery and Selection

OpenLogi distributes **device assets** (metadata, hero renders, button renders) across three distinct mirrors to ensure high availability and fast global access. The discovery logic resides in [`crates/openlogi-assets/src/source.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-assets/src/source.rs).

The system recognizes three built-in mirrors:

- **Production**: `https://assets.openlogi.org` — A mutable custom domain for rapid updates
- **Cloudflare Pages**: `https://v0-1-0.openlogi-assets.pages.dev` — Versioned releases matching npm package versions
- **jsDelivr**: `https://cdn.jsdelivr.net/npm/@logi-assets/catalog@0.1.0` — npm-based distribution requiring a routing table ([`npm-routes.json`](https://github.com/AprilNEA/OpenLogi/blob/main/npm-routes.json))

When `AssetRegistry::load` initiates a sync, the system executes the following priority logic:

1. **Environment override**: If `--base` is passed via CLI or `OPENLOGI_ASSETS` is set in the environment, the system uses that URL directly
2. **Concurrent probing**: Otherwise, `probe_default_sources` spawns three threads executing `probe_uniform` (for Production and Pages) and `probe_jsdelivr` (for jsDelivr) simultaneously
3. **First-success caching**: The first mirror returning a valid [`index.json`](https://github.com/AprilNEA/OpenLogi/blob/main/index.json) wins and is cached in `AssetRegistry::source` for the registry's lifetime

If all probes fail, the system returns `AssetError::SourcesUnavailable`.

## Loading the Asset Catalog

Each mirror hosts an **[`index.json`](https://github.com/AprilNEA/OpenLogi/blob/main/index.json)** file that serves as the master catalog for all supported devices. The `AssetClient::fetch_index_raw` function in [`crates/openlogi-assets/src/http.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-assets/src/http.rs) performs a GET request to `<base>/index.json`, deserializing the response into the `Index` struct defined in [`crates/openlogi-assets/src/index.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-assets/src/index.rs).

The `Index` structure contains:

- `devices: HashMap<String, DeviceEntry>` — A map keyed by depot ID
- `DeviceEntry` fields: `model_id`, optional `model_ids`, `asset_path`, and `files: Vec<FileEntry>` where each `FileEntry` specifies `name`, `sha256`, and `bytes`

This catalog enables the system to locate any supported Logi device without hardcoding device-specific URLs.

## Resolving Device Render Files

OpenLogi uses a **priority-based file selection** system to handle varying asset availability across device generations. The system defines fallback chains as constants in [`crates/openlogi-assets/src/index.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-assets/src/index.rs):

```rust
pub const METADATA_FILES: [&str; 3] = ["core_metadata.json", "metadata_full.json", "metadata.json"];
pub const FRONT_RENDER_FILES: [&str; 2] = ["front_core.png", "front.png"];
pub const BUTTONS_RENDER_FILES: [&str; 2] = ["side_core.png", "side.png"];

```

The `DeviceEntry::baseline_files` method iterates these arrays and selects the **first filename present** in the device's `files` list via `preferred_file`. This yields a consistent set of:

- One metadata file (priority: core → full → legacy)
- One hero render (priority: front_core.png → front.png)
- One button render if available (priority: side_core.png → side.png)

This approach ensures backward compatibility while prioritizing modern asset formats.

## Building Mirror URLs

URL construction differs based on the selected mirror type. The `AssetClient::asset_url` method handles both schemes:

**For Production and Cloudflare Pages**, the URL follows a direct pattern:

```

<base>/<asset_path>/<file_name>

```

**For jsDelivr**, the system consults [`npm-routes.json`](https://github.com/AprilNEA/OpenLogi/blob/main/npm-routes.json) to map `asset_path` values to npm package names. The `build_jsdelivr_client` function validates the routing table's schema version and constructs a lookup map `package_by_asset_path`. Final URLs expand to:

```

https://cdn.jsdelivr.net/npm/<package>@<version>/<asset_path>/<file_name>

```

This sharding strategy ensures jsDelivr requests hit the correct npm package while preserving the Cloudflare Pages directory structure internally.

## Cache-Aware Fetching and Verification

The `AssetClient::fetch_entry_if_stale` method in [`crates/openlogi-assets/src/http.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-assets/src/http.rs) implements **content-addressed caching** with the following flow:

1. **Safe path construction**: Generates a sanitized destination path via `safe_component_path`
2. **Cache validation**: Checks `cached_matches` to compare the local file's SHA-256 against the catalog entry
3. **Conditional download**: On cache miss, executes `fetch_file` → `get_bytes` to download from the mirror
4. **Atomic verification**: Validates the SHA-256 hash before calling `write_replace` to store the file atomically

This ensures that partial downloads or corruption never contaminate the local cache, and subsequent runs skip unnecessary network requests when hashes match.

## End-to-End Device Render Retrieval

To fetch a specific device render, OpenLogi executes this coordinated sequence:

1. **Initialize registry**: Call `AssetRegistry::load(None, cache_dir)` to probe mirrors and load [`index.json`](https://github.com/AprilNEA/OpenLogi/blob/main/index.json)
2. **Locate device**: Use `Index::find_by_model_id` or `find_by_model_id_suffix` to retrieve the `DeviceEntry` for a specific model ID (e.g., "2b043" for MX Master 3S)
3. **Select render file**: Invoke `DeviceEntry::preferred_file` with `FRONT_RENDER_FILES` to determine which hero image exists for this device
4. **Construct URL**: Call `AssetClient::asset_url` with the entry's `asset_path` and selected filename
5. **Fetch with verification**: Execute `fetch_entry_if_stale` to download or retrieve from cache after SHA-256 validation

If the file exists in the local cache and the hash matches the catalog, the system returns the cached path immediately without network overhead.

## Rust Implementation Example

```rust
use openlogi_assets::{AssetRegistry, AssetSource};
use std::path::Path;

/// Load the asset registry (probing the three mirrors) into a local cache folder.
let cache_dir = Path::new("/tmp/openlogi-assets");
let registry = AssetRegistry::load(None, cache_dir).expect("asset registry");

// Suppose we have a device model ID from HID++.
let model_id = "2b043";   // MX Master 3S primary PID

// Locate the depot that matches this model ID.
let (depot, entry) = registry
    .index()
    .find_by_model_id(model_id)
    .expect("device not found in index");

// Determine which render file the depot provides.
let render_name = entry
    .preferred_file(&openlogi_assets::FRONT_RENDER_FILES)
    .expect("no front render defined");

// Build the full URL for that render.
let url = registry
    .client()
    .asset_url(&entry.asset_path, render_name)
    .expect("failed to construct URL");

// Download the render (cached if already present).
let outcome = registry
    .client()
    .fetch_entry_if_stale(&entry.asset_path, cache_dir, &openlogi_assets::FileEntry {
        name: render_name.to_string(),
        sha256: /* SHA‑256 from entry.files */ String::new(),
        bytes: 0,
    })
    .expect("fetch failed");

println!("Render URL: {url}");
println!("Fetch outcome: {outcome:?}");

```

## Summary

- OpenLogi employs **three redundant mirrors** (Production, Cloudflare Pages, jsDelivr) with concurrent probing to ensure asset availability
- The **[`index.json`](https://github.com/AprilNEA/OpenLogi/blob/main/index.json)** catalog maps device model IDs to specific asset paths and cryptographic hashes
- **Priority arrays** (`FRONT_RENDER_FILES`, `METADATA_FILES`) handle backward compatibility by selecting the best available asset variant
- **jsDelivr integration** requires [`npm-routes.json`](https://github.com/AprilNEA/OpenLogi/blob/main/npm-routes.json) to shard assets across multiple npm packages while preserving path structures
- All downloads use **SHA-256 verification** and atomic writes to maintain cache integrity
- The `AssetRegistry` caches the selected mirror for the process lifetime, minimizing redundant probes

## Frequently Asked Questions

### How does OpenLogi handle mirror failures?

If the primary mirror fails, the `probe_default_sources` function in [`crates/openlogi-assets/src/source.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-assets/src/source.rs) automatically fails over to the next available mirror. The system spawns concurrent threads to probe all three mirrors simultaneously, selecting the first successful response. If all mirrors fail, it returns `AssetError::SourcesUnavailable`.

### What determines which render file is downloaded for a device?

The `DeviceEntry::baseline_files` method in [`crates/openlogi-assets/src/index.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-assets/src/index.rs) checks the device's available files against priority arrays like `FRONT_RENDER_FILES`. It selects the first match in the priority list, preferring modern assets (e.g., `front_core.png`) over legacy formats (e.g., `front.png`).

### Can I force OpenLogi to use a specific asset mirror?

Yes. Set the `OPENLOGI_ASSETS` environment variable or pass the `--base` CLI flag with your desired URL. When provided, `AssetRegistry::load` skips the concurrent probing logic and uses your specified mirror directly.

### How does the system verify downloaded renders are not corrupted?

Every file entry in [`index.json`](https://github.com/AprilNEA/OpenLogi/blob/main/index.json) includes a SHA-256 hash. The `fetch_entry_if_stale` method in [`crates/openlogi-assets/src/http.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-assets/src/http.rs) computes the hash of downloaded bytes before writing them to disk. If the hash mismatch, the operation fails. Valid files are written atomically using `write_replace` to prevent partial writes.