Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/gunnar

crates/gunnar-monetize-guest/src/meters.rs

//! **gunnar's meter table, and the two tables gunnar itself keeps.**
//!
//! Transcribed from `products/gunnar/src/lib.rs` (the linked plugin, which monetize's T12
//! retires), which holds the reasoning for every row. A row that drifted would be a cap that
//! reads like a wall and is not, or a meter that prices to nothing.

use monetize_product_guest::{Backing, Enforcement, WireMeter};

/// gunnar's measured cost of one indexed object in an open store.
pub const RAM_BYTES_PER_OBJECT: u64 = 382;

/// The meters this guest declares. See the linked plugin's `METERS` for why
/// each row is what it is.
pub fn meters() -> Vec<WireMeter> {
    vec![
        WireMeter::new(
            "pack_bytes",
            "object bytes on disk that are not re-derivable (hot minus cache, plus cold); what is sold",
            Enforcement::Enforced,
        )
        .with_backing(Backing::DiskBytes),
        WireMeter::new(
            "cache_bytes",
            "the exploded read cache; re-derivable, becomes explode_budget_bytes",
            Enforcement::Enforced,
        ),
        WireMeter::new(
            "cold_bytes",
            "the cold (znippy) tier alone",
            Enforcement::Measured,
        ),
        WireMeter::new(
            "lfs_bytes",
            "LFS objects under the namespace's git dirs, committed and in flight",
            Enforcement::Enforced,
        )
        .with_backing(Backing::DiskBytes),
        WireMeter::new(
            "tombstoned_bytes",
            "soft-deleted repositories not yet purged; still charged",
            Enforcement::Measured,
        ),
        WireMeter::new(
            "repos",
            "live repositories in the namespace",
            Enforcement::Measured,
        ),
        WireMeter::new(
            "objects",
            "indexed objects across the namespace's OPEN stores; the count gunnar caps and reports",
            Enforcement::Measured,
        ),
        WireMeter::new(
            "open_store_ram_bytes",
            "RAM an open store costs: 382 B per indexed object (measured)",
            Enforcement::Measured,
        ),
        WireMeter::new(
            "bytes_in_today",
            "wire bytes accepted for this namespace today (UTC): receive-pack and every client half",
            Enforcement::Measured,
        ),
        WireMeter::new(
            "bytes_out_today",
            "wire bytes served for this namespace today (UTC): upload-pack, advertisements, archives",
            Enforcement::Measured,
        ),
        WireMeter::new(
            "pushes_today",
            "receive-pack sessions that finished today (UTC)",
            Enforcement::Measured,
        ),
        WireMeter::new(
            "fetches_today",
            "upload-pack sessions today (UTC), clones included; a bare ls-remote is not one",
            Enforcement::Measured,
        ),
        WireMeter::new(
            "refused_today",
            "transfers turned away today (UTC); Usage.Activity carries the reason breakdown",
            Enforcement::Measured,
        ),
        WireMeter::new(
            "last_push_unix_ms",
            "when this namespace was last pushed to, over the whole kept window; 0 is never",
            Enforcement::Measured,
        ),
        WireMeter::new(
            "last_fetch_unix_ms",
            "when this namespace was last fetched from, over the whole kept window; 0 is never",
            Enforcement::Measured,
        ),
        WireMeter::cap_only(
            "concurrent_transfers",
            "simultaneous pushes/clones; gunnar's Admission bounds this from an operator flag, box-wide, and reads no per-namespace cap",
            Enforcement::Measured,
        ),
        WireMeter::cap_only(
            "cpu_millicores",
            "CPU bought at the provider for the whole appliance (1000 = one core); gunnar polices no per-namespace CPU — the provider's invoice does",
            Enforcement::Provisioned,
        )
        .with_backing(Backing::CpuMillicores)
        .per_product(),
        WireMeter::cap_only(
            "ram_bytes",
            "RAM bought at the provider for the whole appliance; gunnar polices no per-namespace RAM (open_store_ram_bytes is what it can MEASURE)",
            Enforcement::Provisioned,
        )
        .with_backing(Backing::RamBytes)
        .per_product(),
    ]
}

/// **gunnar's own `METERS`**, transcribed: the cap keys `Entitlement.Set`
/// accepts and polices. A key in neither this nor [`PROVISIONED_ELSEWHERE`] is
/// refused by the appliance with `INVALID_ARGUMENT`, after the money moved.
pub const GUNNAR_METERS: &[(&str, Enforcement)] = &[
    ("pack_bytes", Enforcement::Enforced),
    ("cache_bytes", Enforcement::Enforced),
    ("cold_bytes", Enforcement::Measured),
    ("lfs_bytes", Enforcement::Enforced),
    ("tombstoned_bytes", Enforcement::Measured),
    ("repos", Enforcement::Measured),
    ("objects", Enforcement::Measured),
];

/// **gunnar's `PROVISIONED_ELSEWHERE`**: cap keys it accepts in a signed fact
/// and deliberately does not police, because they are iron bought at the cloud
/// provider.
pub const PROVISIONED_ELSEWHERE: &[&str] = &["cpu_millicores", "ram_bytes"];

/// Will gunnar's `Entitlement.Set` accept a fact carrying this cap key?
pub fn gunnar_honours(cap: &str) -> bool {
    GUNNAR_METERS.iter().any(|(name, _)| *name == cap) || PROVISIONED_ELSEWHERE.contains(&cap)
}

/// **The meters gunnar cannot grow at runtime at all.**
pub const IRON_CAPS: &[&str] = &["cpu_millicores", "ram_bytes"];