Documentation
¶
Overview ¶
Package store provides MySQL-backed metadata storage for the Epoch control plane.
MySQL serves as an index/cache over the object-store-backed registry. Object storage remains the source of truth for blobs; MySQL provides queryable metadata.
Index ¶
- type Blob
- type DashboardStats
- type PlatformSize
- type PlatformSizes
- type Repository
- type Store
- func (s *Store) Close() error
- func (s *Store) CreateToken(ctx context.Context, name, createdBy string) (string, error)
- func (s *Store) DeleteTag(ctx context.Context, repoName, tagName string) error
- func (s *Store) DeleteToken(ctx context.Context, id int64) error
- func (s *Store) GetRepository(ctx context.Context, name string) (*Repository, error)
- func (s *Store) GetStats(ctx context.Context) (*DashboardStats, error)
- func (s *Store) GetTag(ctx context.Context, repoName, tagName string) (*Tag, error)
- func (s *Store) InvalidateTokenCache()
- func (s *Store) ListRepositories(ctx context.Context) ([]Repository, error)
- func (s *Store) ListTags(ctx context.Context, repoName string) ([]Tag, error)
- func (s *Store) ListTokens(ctx context.Context) ([]Token, error)
- func (s *Store) SyncFromCatalog(ctx context.Context, reg *registry.Registry) error
- func (s *Store) ValidateToken(ctx context.Context, plaintext string) bool
- type Tag
- type Token
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Blob ¶
type Blob struct {
Digest string `json:"digest"`
Size int64 `json:"size"`
MediaType string `json:"mediaType"`
RefCount int `json:"refCount"`
}
Blob is a DB blob record.
type DashboardStats ¶
type DashboardStats struct {
RepositoryCount int `json:"repositoryCount"`
TagCount int `json:"tagCount"`
BlobCount int `json:"blobCount"`
TotalSize int64 `json:"totalSize"`
}
DashboardStats holds aggregate stats for the UI dashboard.
type PlatformSize ¶ added in v0.1.7
type PlatformSize struct {
Digest string `json:"digest"`
Size int64 `json:"size"`
LayerCount int `json:"layerCount"`
}
PlatformSize is the standalone content size of one child manifest inside an OCI image index — i.e. config blob plus the sum of layer blobs as declared by that child, with no cross-platform deduplication. The natural answer to "if I only pulled this platform, how many bytes would I download".
type PlatformSizes ¶ added in v0.1.7
type PlatformSizes []PlatformSize
PlatformSizes is a slice of PlatformSize that round-trips through a MySQL JSON column transparently. Empty/nil persists as SQL NULL so non-index tags do not store a placeholder `[]`.
func (*PlatformSizes) Scan ¶ added in v0.1.7
func (p *PlatformSizes) Scan(src any) error
Scan implements sql.Scanner for reading back from a JSON column. NULL maps to a nil slice; the column is allowed to be string or []byte depending on driver flags.
type Repository ¶
type Repository struct {
ID int64 `json:"id"`
Name string `json:"name"`
TagCount int `json:"tagCount"`
TotalSize int64 `json:"totalSize"`
ArtifactType string `json:"artifactType,omitempty"`
Kind string `json:"kind,omitempty"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
Repository is a DB repository record. ArtifactType / Kind reflect the most recently pushed tag in the repo so the UI can show the artifact flavor (cloud-image / snapshot / container-image) without making a separate per-tag round-trip.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store wraps a MySQL connection for Epoch metadata.
func (*Store) CreateToken ¶
func (*Store) GetRepository ¶
func (*Store) InvalidateTokenCache ¶ added in v0.1.7
func (s *Store) InvalidateTokenCache()
InvalidateTokenCache clears all cached token validations.
func (*Store) ListRepositories ¶
func (s *Store) ListRepositories(ctx context.Context) ([]Repository, error)
func (*Store) SyncFromCatalog ¶
SyncFromCatalog walks the registry catalog and ingests every (repo, tag) into MySQL. Each tag's manifest is parsed as OCI and indexed by digest, artifactType, and aggregate size. Orphaned rows (repos / tags that no longer appear in the catalog) are deleted in a second pass.
Sync is split into two phases so the write transaction never holds while epoch is talking to remote object storage:
- prepareSync — read existing tag state from MySQL, fetch + parse + aggregate every catalog tag from the registry. No write TX is open, so the seconds spent on S3 round-trips do not block concurrent writers (token last_used updates, tag deletes, etc).
- commitSync — open one short write TX and upsert every prepared repo / tag / blob. The lock window stays in milliseconds even when phase 1 took seconds.
Per-tag failures stay non-fatal so one bad manifest does not abort the whole pass. Context cancellation during phase 1 aborts the pass before any writes are issued.
type Tag ¶
type Tag struct {
ID int64 `json:"id"`
RepositoryID int64 `json:"-"`
RepoName string `json:"repoName,omitempty"`
Name string `json:"name"`
Digest string `json:"digest"`
ArtifactType string `json:"artifactType,omitempty"`
Kind string `json:"kind,omitempty"`
ManifestJSON string `json:"-"`
TotalSize int64 `json:"totalSize"`
LayerCount int `json:"layerCount"`
PlatformSizes PlatformSizes `json:"platformSizes,omitempty"`
PushedAt time.Time `json:"pushedAt"`
SyncedAt time.Time `json:"syncedAt"`
}
Tag is a DB tag record. ArtifactType captures the OCI 1.1 manifest artifactType field (e.g. cocoonstack.snapshot.v1+json) so the UI can show whether a tag is a snapshot, cloud image, or container image without re-parsing the manifest JSON on every list call.
PlatformSizes is populated only for tags whose kind is image-index. Each entry is the standalone (config + sum(layers)) size of one child manifest, keyed by the child's content digest. Materialized at sync time so the tag detail API does not need to refetch every child manifest just to render per-platform sizes in the UI.
type Token ¶
type Token struct {
ID int64 `json:"id"`
Name string `json:"name"`
Token string `json:"token,omitempty"`
CreatedBy string `json:"createdBy"`
CreatedAt time.Time `json:"createdAt"`
LastUsed *time.Time `json:"lastUsed,omitempty"`
}
Token is a registry access token. The Token field is only populated on create (returned to caller); it is never read back from the DB.