mirror of
https://github.com/hauler-dev/hauler.git
synced 2026-03-06 03:31:13 +00:00
* represent all content as artifact.OCI interface and manipulate/add all content using oci layouts * initial brew taps and macos universal binary * change mediaType to string for better compatibility with other libraries * ensure config is minimally viable for file/charts * add transparent layer caching (filesystem) to artifact operations, clean up layer interface used by file/chart * add store list and store copy commands Signed-off-by: Josh Wolf <josh@joshwolf.dev>
103 lines
1.8 KiB
Go
103 lines
1.8 KiB
Go
package cache
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
|
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
|
"github.com/google/go-containerregistry/pkg/v1/types"
|
|
|
|
"github.com/rancherfederal/hauler/pkg/artifact"
|
|
)
|
|
|
|
type Cache interface {
|
|
Put(v1.Layer) (v1.Layer, error)
|
|
|
|
Get(v1.Hash) (v1.Layer, error)
|
|
}
|
|
|
|
var ErrLayerNotFound = errors.New("layer not found")
|
|
|
|
type oci struct {
|
|
artifact.OCI
|
|
|
|
c Cache
|
|
}
|
|
|
|
func Oci(o artifact.OCI, c Cache) artifact.OCI {
|
|
return &oci{
|
|
OCI: o,
|
|
c: c,
|
|
}
|
|
}
|
|
|
|
func (o *oci) Layers() ([]v1.Layer, error) {
|
|
ls, err := o.OCI.Layers()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var out []v1.Layer
|
|
for _, l := range ls {
|
|
out = append(out, &lazyLayer{inner: l, c: o.c})
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
type lazyLayer struct {
|
|
inner v1.Layer
|
|
c Cache
|
|
}
|
|
|
|
func (l *lazyLayer) Compressed() (io.ReadCloser, error) {
|
|
digest, err := l.inner.Digest()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
layer, err := l.getOrPut(digest)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return layer.Compressed()
|
|
}
|
|
|
|
func (l *lazyLayer) Uncompressed() (io.ReadCloser, error) {
|
|
diffID, err := l.inner.DiffID()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
layer, err := l.getOrPut(diffID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return layer.Uncompressed()
|
|
}
|
|
|
|
func (l *lazyLayer) getOrPut(h v1.Hash) (v1.Layer, error) {
|
|
var layer v1.Layer
|
|
if cl, err := l.c.Get(h); err == nil {
|
|
layer = cl
|
|
|
|
} else if err == ErrLayerNotFound {
|
|
rl, err := l.c.Put(l.inner)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
layer = rl
|
|
|
|
} else {
|
|
return nil, err
|
|
}
|
|
|
|
return layer, nil
|
|
}
|
|
|
|
func (l *lazyLayer) Size() (int64, error) { return l.inner.Size() }
|
|
func (l *lazyLayer) DiffID() (v1.Hash, error) { return l.inner.Digest() }
|
|
func (l *lazyLayer) Digest() (v1.Hash, error) { return l.inner.Digest() }
|
|
func (l *lazyLayer) MediaType() (types.MediaType, error) { return l.inner.MediaType() }
|