Advanced Usage
For most users, github.com/meigma/blob provides everything needed. This guide covers advanced patterns that require internal packages.
When to Use Internal Packages
Use internal packages when you need:
- Local-only archives: Create archives without pushing to a registry
- Custom data sources: Use archives from HTTP, S3, or custom sources
- Custom cache implementations: Implement your own caching strategy
- Direct registry operations: Bypass the high-level client
- Lower-level control: Fine-grained control over archive creation
For standard push/pull workflows, prefer the unified API:
import "github.com/meigma/blob"
c, _ := blob.NewClient(blob.WithDockerConfig())
c.Push(ctx, ref, srcDir)
archive, _ := c.Pull(ctx, ref)
Local-Only Archives (No Registry)
Create archives directly to disk without pushing to a registry:
import blobcore "github.com/meigma/blob/core"
// Create archive files in destDir
blobFile, err := blobcore.CreateBlob(ctx, srcDir, destDir,
blobcore.CreateBlobWithCompression(blobcore.CompressionZstd),
blobcore.CreateBlobWithChangeDetection(blobcore.ChangeDetectionStrict),
)
if err != nil {
return err
}
defer blobFile.Close()
// Use the archive immediately
content, _ := blobFile.ReadFile("config.json")
// Files created:
// - destDir/index.blob
// - destDir/data.blob
Custom Filenames
blobFile, err := blobcore.CreateBlob(ctx, srcDir, destDir,
blobcore.CreateBlobWithIndexName("my-archive.idx"),
blobcore.CreateBlobWithDataName("my-archive.dat"),
)
Opening Existing Local Archives
blobFile, err := blobcore.OpenFile("/path/to/index.blob", "/path/to/data.blob")
if err != nil {
return err
}
defer blobFile.Close()
content, _ := blobFile.ReadFile("lib/utils.go")
Custom HTTP Sources
Fetch archives from any HTTP endpoint with range request support:
import (
blobcore "github.com/meigma/blob/core"
blobhttp "github.com/meigma/blob/core/http"
)
// Create HTTP source with authentication
source, err := blobhttp.NewSource(dataURL,
blobhttp.WithHeader("Authorization", "Bearer "+token),
)
if err != nil {
return err
}
// Read index blob separately (e.g., from another URL or embedded)
indexData, _ := fetchIndexBlob(indexURL)
// Create archive from HTTP source
archive, err := blobcore.New(indexData, source)
if err != nil {
return err
}
// File reads use HTTP range requests
content, _ := archive.ReadFile("config.json")
Custom Source ID
For block caching, provide a stable source identifier:
source, err := blobhttp.NewSource(dataURL,
blobhttp.WithSourceID("myapp:archive:v1.2.3"),
)
Custom Cache Implementations
Implement the cache.Cache interface for custom caching strategies:
import "io/fs"
type Cache interface {
// Get returns an fs.File for reading cached content.
// Returns nil, false if content is not cached.
Get(hash []byte) (fs.File, bool)
// Put stores content by reading from the provided fs.File.
Put(hash []byte, f fs.File) error
// Delete removes cached content for the given hash.
Delete(hash []byte) error
// MaxBytes returns the configured cache size limit (0 = unlimited).
MaxBytes() int64
// SizeBytes returns the current cache size in bytes.
SizeBytes() int64
// Prune removes entries until the cache is at or below targetBytes.
Prune(targetBytes int64) (int64, error)
}
Example: Redis Cache
type RedisCache struct {
client *redis.Client
maxBytes int64
}
func (c *RedisCache) Get(hash []byte) (fs.File, bool) {
key := hex.EncodeToString(hash)
data, err := c.client.Get(ctx, key).Bytes()
if err != nil {
return nil, false
}
return &bytesFile{data: data}, true
}
func (c *RedisCache) Put(hash []byte, f fs.File) error {
data, err := io.ReadAll(f)
if err != nil {
return err
}
key := hex.EncodeToString(hash)
return c.client.Set(ctx, key, data, 0).Err()
}
// ... implement remaining methods
Using Custom Cache
import blobcore "github.com/meigma/blob/core"
archive, err := blobcore.New(indexData, source,
blobcore.WithCache(myRedisCache),
)
Block Cache for HTTP Sources
Add block-level caching to reduce HTTP range requests:
import (
blobcore "github.com/meigma/blob/core"
blobhttp "github.com/meigma/blob/core/http"
"github.com/meigma/blob/core/cache"
"github.com/meigma/blob/core/cache/disk"
)
// Create HTTP source
source, err := blobhttp.NewSource(dataURL)
if err != nil {
return err
}
// Create block cache
blockCache, err := disk.NewBlockCache("/var/cache/blob-blocks",
disk.WithBlockMaxBytes(256 << 20), // 256 MB limit
)
if err != nil {
return err
}
// Wrap source with caching
cachedSource, err := blockCache.Wrap(source,
cache.WithBlockSize(64 << 10), // 64 KB blocks
cache.WithMaxBlocksPerRead(4), // Bypass large sequential reads
)
if err != nil {
return err
}
// Use cached source
archive, err := blobcore.New(indexData, cachedSource)
Direct Registry Operations
Use the registry package for lower-level OCI operations:
import "github.com/meigma/blob/registry"
// Create registry client
reg := registry.New(
registry.WithDockerConfig(),
)
// Fetch manifest metadata
manifest, err := reg.Fetch(ctx, "ghcr.io/myorg/myarchive:v1")
if err != nil {
return err
}
// Access manifest details
digest := manifest.Digest()
indexDesc := manifest.IndexDescriptor()
dataDesc := manifest.DataDescriptor()
fmt.Printf("Digest: %s\n", digest)
fmt.Printf("Index size: %d bytes\n", indexDesc.Size)
fmt.Printf("Data size: %d bytes\n", dataDesc.Size)
// Pull full archive with options
archive, err := reg.Pull(ctx, ref,
registry.PullWithMaxFileSize(512 << 20),
)
// Tag an existing manifest with a new tag
err = reg.Tag(ctx, "ghcr.io/myorg/myarchive:latest", manifest.Digest())
Lower-Level Create API
For streaming archive creation to arbitrary writers:
import blobcore "github.com/meigma/blob/core"
// Create to arbitrary io.Writers
indexFile, _ := os.Create("index.blob")
dataFile, _ := os.Create("data.blob")
defer indexFile.Close()
defer dataFile.Close()
err := blobcore.Create(ctx, srcDir, indexFile, dataFile,
blobcore.CreateWithCompression(blobcore.CompressionZstd),
blobcore.CreateWithSkipCompression(blobcore.DefaultSkipCompression(1024)),
blobcore.CreateWithChangeDetection(blobcore.ChangeDetectionStrict),
blobcore.CreateWithMaxFiles(100000),
)
Package Reference
| Package | Purpose |
|---|---|
github.com/meigma/blob | Primary API - client, push, pull |
github.com/meigma/blob/core | Archive creation and reading |
github.com/meigma/blob/core/cache | Cache interfaces |
github.com/meigma/blob/core/cache/disk | Disk cache implementations |
github.com/meigma/blob/core/http | HTTP byte source |
github.com/meigma/blob/registry | OCI registry operations |
github.com/meigma/blob/registry/cache | Registry cache implementations |
github.com/meigma/blob/policy | Policy composition (RequireAll, RequireAny) |
github.com/meigma/blob/policy/sigstore | Sigstore signature verification (GitHubActionsPolicy) |
github.com/meigma/blob/policy/slsa | SLSA provenance validation (GitHubActionsWorkflow) |
github.com/meigma/blob/policy/opa | Custom OPA/Rego policy evaluation |
See Also
- OCI Client - High-level client API
- Caching - Standard cache configuration
- Creating Archives - Archive options
- API Reference - Complete API documentation