Documentation
¶
Index ¶
- Constants
- Variables
- func CacheCmd() *cobra.Command
- func ProducerVersion() string
- func SetProducerVersion(v string)
- type OCIBlobMissingError
- type OCIClient
- func (c *OCIClient) GetBlob(ctx context.Context, digest string) ([]byte, error)
- func (c *OCIClient) GetManifest(ctx context.Context, ref string) (*OCIManifest, string, error)
- func (c *OCIClient) HeadBlob(ctx context.Context, digest string) (bool, error)
- func (c *OCIClient) PullBundle(ctx context.Context, ref string, parallelism int) (*OCIManifest, []byte, map[string][]byte, string, error)
- func (c *OCIClient) PushBundle(ctx context.Context, manifest *OCIManifest, configBytes []byte, ...) (string, error)
- func (c *OCIClient) PutBlob(ctx context.Context, digest string, data []byte) error
- func (c *OCIClient) PutManifest(ctx context.Context, ref string, manifest *OCIManifest) (string, error)
- func (c *OCIClient) SetHTTPClient(client *http.Client)
- func (c *OCIClient) SetToken(token string)
- type OCIDescriptor
- type OCIManifest
- type OCIManifestMissingError
Constants ¶
const CacheVersion = "0.1.0"
CacheVersion is the schema_version mache writes into the lockfile meta. Bumps require an LLO ADR-0021 schema change first.
const MacheProducerName = "mache"
MacheProducerName is the producer field per ADR-0020. Short-name convention for v1; reverse-DNS reserved for v2 if collisions.
Variables ¶
var ErrProjectionV6 = errors.New("the build cache cannot carry a projection-v6 _ast; " +
"consuming LLO's arena instead is mache-e64f36")
ErrProjectionV6 refuses a push from a projection-v6 .db (leyline v0.20.x).
A chunk carries _ast rows in projection-v4's shape, and pull writes them back. Teaching the cache v6's shape would mean mache writing more of LLO's tables, which is the data-plane work the LLO boundary marks for deletion: the cache is to consume LLO's own arena instead (mache-e64f36). Falling back to source-only chunks would restore a database without its AST and say nothing, so the push fails, naming why.
Functions ¶
func CacheCmd ¶
CacheCmd returns the cache command group for registration on the root command — registration hook #2 (mache-96c378); buildcache never imports cmd.
func ProducerVersion ¶
func ProducerVersion() string
ProducerVersion returns the identity stamped into lockfiles and cache metadata.
func SetProducerVersion ¶
func SetProducerVersion(v string)
SetProducerVersion overrides the recorded producer identity. Called once, from cmd wiring, with the ldflags-resolved build version.
Types ¶
type OCIBlobMissingError ¶
type OCIBlobMissingError struct {
Digest string
}
OCIBlobMissingError is returned by GetBlob on 404. Callers can errors.As() it to distinguish "blob not present" from other errors.
func (*OCIBlobMissingError) Error ¶
func (e *OCIBlobMissingError) Error() string
type OCIClient ¶
type OCIClient struct {
// contains filtered or unexported fields
}
OCIClient speaks the build-cache/v1 transport against a provider.
Construct via NewOCIClient(baseURL). Methods are safe to call concurrently on the same client; the underlying http.Client handles connection pooling.
func NewOCIClient ¶
NewOCIClient builds a client targeting <baseURL>/v2/<producer>/<scope>/. Empty baseURL is rejected up front; producer + scope can be empty only if the caller is using methods that don't need them (we don't have any such methods today, but the constructor doesn't enforce non-empty to keep test ergonomics simple).
func (*OCIClient) GetBlob ¶
GetBlob fetches the bytes under `digest` and verifies BLAKE3(body) matches the digest. Mismatch is a hard error — the consumer MUST refuse to vouch for tampered/corrupted blobs (per LLO BlobStore substrate contract).
func (*OCIClient) GetManifest ¶
GetManifest fetches and parses the manifest under <ref>. Verifies the body is well-formed OCI manifest with the expected mediaType + config.mediaType, and re-hashes the body to assert content-address integrity (if <ref> looks like a digest).
Returns the parsed manifest + the manifest's actual BLAKE3 digest (useful for tag-resolved pulls: pin the digest from the response).
func (*OCIClient) HeadBlob ¶
HeadBlob reports whether the registry has a blob at the given digest. Mapping: 200 → true, 404 → false, anything else → error.
Per push-protocol.md step 1: producers HEAD before uploading to honor the idempotency contract (no re-upload of existing chunks).
func (*OCIClient) PullBundle ¶
func (c *OCIClient) PullBundle(ctx context.Context, ref string, parallelism int) (*OCIManifest, []byte, map[string][]byte, string, error)
PullBundle is the inverse of PushBundle: GET manifest, GET config, GET every layer, verify-on-read at every step.
Returns (manifest, configBytes, chunks). chunks is a map digest → bytes.
Caller is responsible for asserting the lockfile's internal invariants (chunk-hash chain, root). This client just delivers the bytes faithfully.
func (*OCIClient) PushBundle ¶
func (c *OCIClient) PushBundle(ctx context.Context, manifest *OCIManifest, configBytes []byte, chunks map[string][]byte, tag string, parallelism int) (string, error)
PushBundle uploads a (config, chunks) bundle:
- PutBlob the config (idempotent)
- PutBlob every chunk in parallel (idempotent, bounded concurrency)
- PutManifest under both the manifest's content digest AND the human-readable tag (if non-empty)
Returns the manifest's content digest. Producers SHOULD pin to that digest for future pulls even when they also pushed a tag.
chunks is a map digest → bytes. The manifest references those digests in its layers; if a layer digest isn't in the map, that's a producer bug and PushBundle fails.
parallelism controls how many concurrent chunk uploads run. 0 → 4.
func (*OCIClient) PutBlob ¶
PutBlob uploads `data` under `digest`. Two-step per OCI:
POST /v2/<scope>/blobs/uploads/ → 202 Location: <upload-url> PUT <upload-url>?digest=<digest> → 201 Created
HEAD-check first: skip the upload if the registry already has it. Returns nil on success (idempotent — re-uploading an existing blob is a no-op from the producer's perspective).
func (*OCIClient) PutManifest ¶
func (c *OCIClient) PutManifest(ctx context.Context, ref string, manifest *OCIManifest) (string, error)
PutManifest uploads the manifest under <ref> (a digest like "sha256:abc..." or a tag like "latest").
Returns the manifest's own digest (BLAKE3 of the JSON body) so producers that pushed by tag can also pin the immutable form.
func (*OCIClient) SetHTTPClient ¶
SetHTTPClient swaps the underlying *http.Client — useful for tests (httptest) and for callers that need custom timeouts / TLS.
type OCIDescriptor ¶
type OCIDescriptor struct {
MediaType string `json:"mediaType"`
Digest string `json:"digest"`
Size int64 `json:"size"`
Annotations map[string]string `json:"annotations,omitempty"`
}
OCIDescriptor matches OCI Image Spec descriptor shape.
type OCIManifest ¶
type OCIManifest struct {
SchemaVersion int `json:"schemaVersion"`
MediaType string `json:"mediaType"`
Config OCIDescriptor `json:"config"`
Layers []OCIDescriptor `json:"layers"`
Annotations map[string]string `json:"annotations,omitempty"`
}
OCIManifest is the JSON shape per cloister-spec/build-cache/v1/wire/manifest-shape.md. Used for both push (we build + serialize) and pull (we parse + verify).
type OCIManifestMissingError ¶
type OCIManifestMissingError struct {
Ref string
}
OCIManifestMissingError is returned by GetManifest on 404.
func (*OCIManifestMissingError) Error ¶
func (e *OCIManifestMissingError) Error() string