model

package
v1.0.32 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 16, 2026 License: GPL-2.0, GPL-3.0 Imports: 4 Imported by: 0

Documentation

Overview

Package model holds the pure data types that describe a registry-stats snapshot. Types here carry no behavior beyond JSON struct tags; the tags define the on-disk /data/YYYY-MM-DD.json contract and the HTTP API response shapes, so they MUST stay identical across refactors.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type GhcrStats

type GhcrStats struct {
	Package       string `json:"package"`
	DownloadCount int64  `json:"download_count"`
}

GhcrStats is a GHCR package's scraped download count.

type ImageInfo

type ImageInfo struct {
	Architecture string `json:"architecture"`
	OS           string `json:"os"`
	Digest       string `json:"digest"`
	Size         int64  `json:"size"`
}

ImageInfo is a single per-architecture manifest inside a multi-arch tag.

type PullEntry

type PullEntry struct {
	Date      string
	Repo      string
	PullCount int64
	Source    RegistrySource
}

PullEntry is a single (date, source, repo, pullCount) record in the pre-computed pull index. Handlers consume these directly instead of iterating every snapshot file per request.

type RegistryEntry

type RegistryEntry struct {
	Name          string
	LastUpdated   string
	Tags          []TagInfo
	PullCount     int64
	DownloadCount int64
}

RegistryEntry is the registry-agnostic Collect() result used by api.RegistrySource implementations. Later steps map it into the per-registry on-disk arrays (docker_hub / ghcr). Zero-value fields are ignored for the registry that doesn't populate them (Tags/PullCount are Docker Hub-only, DownloadCount is GHCR-only).

type RegistryFilter

type RegistryFilter struct {
	Only RegistrySource
	Set  bool
}

RegistryFilter is the typed view of the registry= query parameter. Zero value means "include every registry" (the Grafana default and the behaviour of an unset / $__all / {$__all} / multi-value brace input). When Set is true the filter restricts to Only.

The filter is populated via ParseRegistryFilter so the three handler call sites share one parse of the raw query string (previously each handler re-implemented the brace-stripping dance).

func ParseRegistryFilter

func ParseRegistryFilter(raw string) RegistryFilter

ParseRegistryFilter turns a registry= query value into a typed filter. Accepts the full vocabulary that the pre-refactor stripGrafanaBraces + registryIncludes pair handled:

  • "" and "$__all" → include every source (zero value).
  • "{$__all}" → include every source (Grafana brace-wrapping).
  • "dockerhub", "ghcr" → restrict to that source.
  • "{dockerhub}", "{ghcr}" → restrict (brace-wrapped single).
  • "{a,b}" (comma inside braces) → include every source. Multi- value braces come from Grafana when the template variable is set to multiple values; the pre-refactor registryIncludes treated any unknown stripped value as "include both", and because {a,b} → "a,b" (unknown as a source name) it fell into the "include both" branch. We preserve that semantics.
  • unknown single values → include every source (same fallback).

func (RegistryFilter) Includes

func (f RegistryFilter) Includes(r RegistrySource) bool

Includes reports whether the filter allows entries from r. A zero-value filter (Set == false) includes every source.

type RegistrySource

type RegistrySource uint8

RegistrySource is the typed identity of a container registry that registry-stats scrapes. The zero value (SourceUnknown) represents "registry not classified"; handlers that build carry-forward maps key by RegistrySource + name so a misplaced empty string can never silently collide with a real source. The String() method produces the lowercase on-wire name used in the JSON summary row's `registry` field and in WARN/ERROR log k/v pairs, preserving byte-identical output for Grafana dashboards and Loki alerts.

const (
	SourceUnknown RegistrySource = iota
	SourceDockerHub
	SourceGHCR
)

RegistrySource values. SourceUnknown exists only to catch unset / defaulted values in filter plumbing; production code paths should always hold one of the concrete sources.

func ParseRegistrySource

func ParseRegistrySource(s string) RegistrySource

ParseRegistrySource maps the lowercase on-wire name back to its typed value. Unknown input returns SourceUnknown; callers decide whether that is an error or (for the registry= query param) a "include everything" signal.

func (RegistrySource) MarshalJSON

func (r RegistrySource) MarshalJSON() ([]byte, error)

MarshalJSON renders a RegistrySource as its lowercase name. Today SummaryEntry.Registry stays a plain string on the wire (see the handler rows' `registry` field), so this method is defensive future-proofing for any struct that may embed RegistrySource directly: it keeps the JSON vocabulary consistent.

func (RegistrySource) String

func (r RegistrySource) String() string

String returns the lowercase on-wire name of a RegistrySource. It MUST match the registry= query-parameter vocabulary and the SummaryEntry.Registry JSON field (inviolate: HTTP API surface). SourceUnknown returns "" so callers that write it into a response without checking first surface the mis-classification as an empty field rather than a bogus label.

type RepoPull

type RepoPull struct {
	Repo      string
	PullCount int64
}

RepoPull is a repo name + pull count extracted from a snapshot.

type RepoRef

type RepoRef struct {
	Owner string
	Repo  string
}

RepoRef is an owner/repo pair parsed from env var input. Repo is "*" for wildcard refs that expand at collection time.

type RepoStats

type RepoStats struct {
	Repo        string    `json:"repo"`
	LastUpdated string    `json:"last_updated"`
	Tags        []TagInfo `json:"tags"`
	PullCount   int64     `json:"pull_count"`
}

RepoStats is a Docker Hub repo's pull count plus tag metadata.

type Snapshot

type Snapshot struct {
	Timestamp time.Time   `json:"timestamp"`
	DockerHub []RepoStats `json:"docker_hub,omitempty"`
	GHCR      []GhcrStats `json:"ghcr,omitempty"`
}

Snapshot is the root on-disk object written once per collection cycle.

func (*Snapshot) Entries

func (s *Snapshot) Entries() iter.Seq2[RegistrySource, SummaryEntry]

Entries yields a flattened stream of (RegistrySource, SummaryEntry) pairs across all registry slices in the snapshot. Zero-download GHCR packages are skipped (a zero scrape is treated as "not applicable"). This centralises the source→slice routing so consumers iterate a uniform stream without knowing the per-registry storage layout.

func (*Snapshot) PullEntries

func (s *Snapshot) PullEntries(date string) []PullEntry

PullEntries returns PullEntry records for all repos in the snapshot, skipping zero-download GHCR packages. The date parameter is stamped onto each entry (it comes from the caller's storage key, not the snapshot's Timestamp).

type SummaryEntry

type SummaryEntry struct {
	Registry  string
	Name      string
	PullCount int64
	TagCount  int
}

SummaryEntry carries the per-registry view that handleSummary needs. filteredPulls also builds on it (summing across registries for the same name).

type TagInfo

type TagInfo struct {
	Name        string      `json:"name"`
	LastUpdated string      `json:"last_updated"`
	Digest      string      `json:"digest"`
	Images      []ImageInfo `json:"images,omitempty"`
	FullSize    int64       `json:"full_size"`
}

TagInfo is a single tag as returned by the Docker Hub /tags/ endpoint.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL