Go Library¶
s3lo exposes its core packages for use in other Go programs.
Packages¶
| Package | Description |
|---|---|
github.com/OuFinx/s3lo/pkg/image |
High-level operations: push, pull, copy, list, inspect, delete, GC, stats, scan |
github.com/OuFinx/s3lo/pkg/ref |
Parse s3://, gs://, az://, local:// references |
github.com/OuFinx/s3lo/pkg/storage |
Storage backend interface + AWS S3, GCS, Azure Blob, and local filesystem implementations |
github.com/OuFinx/s3lo/pkg/oci |
OCI manifest and config types |
All functions accept context.Context as the first argument.
Push¶
import "github.com/OuFinx/s3lo/pkg/image"
err := image.Push(ctx, "myapp:v1.0", "s3://my-bucket/myapp:v1.0", image.PushOptions{})
With progress callback:
err := image.Push(ctx, "myapp:v1.0", "s3://my-bucket/myapp:v1.0", image.PushOptions{
OnBlob: func(digest string, size int64, skipped bool) {
if skipped {
fmt.Printf("skip %s\n", digest[:12])
} else {
fmt.Printf("upload %s (%d bytes)\n", digest[:12], size)
}
},
})
Pull¶
Pull a specific platform from a multi-arch image:
err := image.Pull(ctx, "s3://my-bucket/alpine:latest", "", image.PullOptions{
Platform: "linux/amd64",
})
Copy¶
result, err := image.Copy(ctx, "alpine:latest", "s3://my-bucket/alpine:latest", image.CopyOptions{})
fmt.Printf("copied %d blobs, skipped %d\n", result.BlobsCopied, result.BlobsSkipped)
Copy a specific platform:
result, err := image.Copy(ctx, "alpine:latest", "s3://my-bucket/alpine:latest", image.CopyOptions{
Platform: "linux/amd64",
})
List¶
images, err := image.List(ctx, "s3://my-bucket/")
for _, img := range images {
fmt.Println(img) // "myapp:v1.0"
}
Inspect¶
info, err := image.Inspect(ctx, "s3://my-bucket/myapp:v1.0")
fmt.Printf("layers: %d, size: %d bytes\n", len(info.Layers), info.TotalSize)
if info.IsIndex {
for _, p := range info.Platforms {
fmt.Printf("platform: %s, layers: %d\n", p.Platform, len(p.Layers))
}
}
Delete¶
Garbage collect¶
// Dry run
result, err := image.GC(ctx, "s3://my-bucket/", true)
fmt.Printf("would delete %d blobs (%d bytes)\n", result.Candidates, result.FreedBytes)
// Apply
result, err = image.GC(ctx, "s3://my-bucket/", false)
fmt.Printf("deleted %d blobs (%d bytes freed)\n", result.Deleted, result.FreedBytes)
Stats¶
stats, err := image.Stats(ctx, "s3://my-bucket/")
fmt.Printf("images: %d, tags: %d, size: %d bytes\n", stats.Images, stats.Tags, stats.ActualBytes)
fmt.Printf("dedup savings: %d bytes\n", stats.LogicalBytes-stats.ActualBytes)
Scan¶
import "github.com/OuFinx/s3lo/pkg/image"
// Scan an image — Trivy must be installed.
exitCode, err := image.Scan(ctx, "s3://my-bucket/myapp:v1.0", image.ScanOptions{
TrivyPath: "/usr/local/bin/trivy",
Severity: "HIGH,CRITICAL",
})
if exitCode != 0 {
fmt.Println("vulnerabilities found")
}
With progress callback and platform selection:
exitCode, err := image.Scan(ctx, "s3://my-bucket/alpine:latest", image.ScanOptions{
TrivyPath: trivyPath,
Platform: "linux/amd64",
Severity: "HIGH,CRITICAL",
Format: "json",
OnBlob: func(digest string, size int64) {
fmt.Printf("downloaded %s (%d bytes)\n", digest[:12], size)
},
})
Parse a reference¶
import "github.com/OuFinx/s3lo/pkg/ref"
r, err := ref.Parse("s3://my-bucket/myapp:v1.0")
fmt.Println(r.Scheme) // "s3"
fmt.Println(r.Bucket) // "my-bucket"
fmt.Println(r.Image) // "myapp"
fmt.Println(r.Tag) // "v1.0"
fmt.Println(r.ManifestsPrefix()) // "manifests/myapp/v1.0/"
All schemes are supported:
ref.Parse("gs://my-gcs-bucket/myapp:v1.0") // GCS
ref.Parse("az://my-container/myapp:v1.0") // Azure Blob
ref.Parse("local://./store/myapp:v1.0") // local filesystem
S3-compatible endpoints¶
To use MinIO, Cloudflare R2, or Ceph, pass the endpoint via context: