mirror of
https://github.com/hauler-dev/hauler.git
synced 2026-08-19 04:16:27 +00:00
cleanup pkg/artifacts and fix inconsistencies (#728)
Signed-off-by: Adam Martin <adam.martin@ranchergovernment.com>
This commit is contained in:
@@ -28,10 +28,10 @@ import (
|
||||
|
||||
"hauler.dev/go/hauler/v2/internal/flags"
|
||||
v1 "hauler.dev/go/hauler/v2/pkg/apis/hauler.cattle.io/v1"
|
||||
"hauler.dev/go/hauler/v2/pkg/artifacts/chart"
|
||||
"hauler.dev/go/hauler/v2/pkg/artifacts/file"
|
||||
"hauler.dev/go/hauler/v2/pkg/audit"
|
||||
"hauler.dev/go/hauler/v2/pkg/consts"
|
||||
"hauler.dev/go/hauler/v2/pkg/content/chart"
|
||||
"hauler.dev/go/hauler/v2/pkg/cosign"
|
||||
"hauler.dev/go/hauler/v2/pkg/getter"
|
||||
"hauler.dev/go/hauler/v2/pkg/log"
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"helm.sh/helm/v4/pkg/action"
|
||||
|
||||
"hauler.dev/go/hauler/v2/pkg/artifacts/chart"
|
||||
"hauler.dev/go/hauler/v2/pkg/consts"
|
||||
"hauler.dev/go/hauler/v2/pkg/content/chart"
|
||||
)
|
||||
|
||||
func TestNewChart(t *testing.T) {
|
||||
@@ -1,80 +0,0 @@
|
||||
package image
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/google/go-containerregistry/pkg/authn"
|
||||
gname "github.com/google/go-containerregistry/pkg/name"
|
||||
gv1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
|
||||
"hauler.dev/go/hauler/v2/pkg/artifacts"
|
||||
)
|
||||
|
||||
var _ artifacts.OCI = (*Image)(nil)
|
||||
|
||||
func (i *Image) MediaType() string {
|
||||
mt, err := i.Image.MediaType()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(mt)
|
||||
}
|
||||
|
||||
func (i *Image) RawConfig() ([]byte, error) {
|
||||
return i.RawConfigFile()
|
||||
}
|
||||
|
||||
// Image implements the OCI interface for Image API objects. API spec information
|
||||
// is stored into the Name field.
|
||||
type Image struct {
|
||||
Name string
|
||||
gv1.Image
|
||||
}
|
||||
|
||||
func NewImage(name string, opts ...remote.Option) (*Image, error) {
|
||||
r, err := gname.ParseReference(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defaultOpts := []remote.Option{
|
||||
remote.WithAuthFromKeychain(authn.DefaultKeychain),
|
||||
}
|
||||
opts = append(opts, defaultOpts...)
|
||||
|
||||
img, err := remote.Image(r, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Image{
|
||||
Name: name,
|
||||
Image: img,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func IsMultiArchImage(name string, opts ...remote.Option) (bool, error) {
|
||||
ref, err := gname.ParseReference(name)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("parsing reference %q: %v", name, err)
|
||||
}
|
||||
|
||||
defaultOpts := []remote.Option{
|
||||
remote.WithAuthFromKeychain(authn.DefaultKeychain),
|
||||
}
|
||||
opts = append(opts, defaultOpts...)
|
||||
|
||||
desc, err := remote.Get(ref, opts...)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("getting image %q: %v", name, err)
|
||||
}
|
||||
|
||||
_, err = desc.ImageIndex()
|
||||
if err != nil {
|
||||
// if the descriptor could not be converted to an image index... it's not a multi-arch image
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// if the descriptor could be converted to an image index... it's a multi-arch image
|
||||
return true, nil
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
package image_test
|
||||
@@ -1,78 +0,0 @@
|
||||
package memory
|
||||
|
||||
import (
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/google/go-containerregistry/pkg/v1/partial"
|
||||
"github.com/google/go-containerregistry/pkg/v1/static"
|
||||
"github.com/google/go-containerregistry/pkg/v1/types"
|
||||
|
||||
"hauler.dev/go/hauler/v2/pkg/artifacts"
|
||||
"hauler.dev/go/hauler/v2/pkg/consts"
|
||||
)
|
||||
|
||||
var _ artifacts.OCI = (*Memory)(nil)
|
||||
|
||||
// Memory implements the OCI interface for a generic set of bytes stored in memory.
|
||||
type Memory struct {
|
||||
blob v1.Layer
|
||||
annotations map[string]string
|
||||
config artifacts.Config
|
||||
}
|
||||
|
||||
type defaultConfig struct {
|
||||
MediaType string `json:"mediaType,omitempty"`
|
||||
}
|
||||
|
||||
func NewMemory(data []byte, mt string, opts ...Option) *Memory {
|
||||
blob := static.NewLayer(data, types.MediaType(mt))
|
||||
|
||||
cfg := defaultConfig{MediaType: consts.MemoryConfigMediaType}
|
||||
m := &Memory{
|
||||
blob: blob,
|
||||
config: artifacts.ToConfig(cfg),
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(m)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *Memory) MediaType() string {
|
||||
return consts.OCIManifestSchema1
|
||||
}
|
||||
|
||||
func (m *Memory) Manifest() (*v1.Manifest, error) {
|
||||
layer, err := partial.Descriptor(m.blob)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfgDesc, err := partial.Descriptor(m.config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
manifest := &v1.Manifest{
|
||||
SchemaVersion: 2,
|
||||
MediaType: types.MediaType(m.MediaType()),
|
||||
Config: *cfgDesc,
|
||||
Layers: []v1.Descriptor{*layer},
|
||||
Annotations: m.annotations,
|
||||
}
|
||||
|
||||
return manifest, nil
|
||||
}
|
||||
|
||||
func (m *Memory) RawConfig() ([]byte, error) {
|
||||
if m.config == nil {
|
||||
return []byte(`{}`), nil
|
||||
}
|
||||
return m.config.Raw()
|
||||
}
|
||||
|
||||
func (m *Memory) Layers() ([]v1.Layer, error) {
|
||||
var layers []v1.Layer
|
||||
layers = append(layers, m.blob)
|
||||
return layers, nil
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package memory_test
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/opencontainers/go-digest"
|
||||
|
||||
"hauler.dev/go/hauler/v2/pkg/artifacts/memory"
|
||||
)
|
||||
|
||||
func TestMemory_Layers(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
want *v1.Manifest
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "should preserve content",
|
||||
want: nil,
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
data, m := setup(t)
|
||||
|
||||
layers, err := m.Layers()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(layers) != 1 {
|
||||
t.Fatalf("Expected 1 layer, got %d", len(layers))
|
||||
}
|
||||
|
||||
h, err := layers[0].Digest()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
d := digest.FromBytes(data)
|
||||
|
||||
if d.String() != h.String() {
|
||||
t.Fatalf("bytes do not match, got %s, expected %s", h.String(), d.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func setup(t *testing.T) ([]byte, *memory.Memory) {
|
||||
block := make([]byte, 2048)
|
||||
_, err := rand.Read(block)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
mem := memory.NewMemory(block, "random")
|
||||
return block, mem
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package memory
|
||||
|
||||
import "hauler.dev/go/hauler/v2/pkg/artifacts"
|
||||
|
||||
type Option func(*Memory)
|
||||
|
||||
func WithConfig(obj interface{}, mediaType string) Option {
|
||||
return func(m *Memory) {
|
||||
m.config = artifacts.ToConfig(obj, artifacts.WithConfigMediaType(mediaType))
|
||||
}
|
||||
}
|
||||
|
||||
func WithAnnotations(annotations map[string]string) Option {
|
||||
return func(m *Memory) {
|
||||
m.annotations = annotations
|
||||
}
|
||||
}
|
||||
@@ -26,9 +26,6 @@ const (
|
||||
FileDirectoryConfigMediaType = "application/vnd.content.hauler.file.directory.config.v1+json"
|
||||
FileHttpConfigMediaType = "application/vnd.content.hauler.file.http.config.v1+json"
|
||||
|
||||
// memory media types
|
||||
MemoryConfigMediaType = "application/vnd.content.hauler.memory.config.v1+json"
|
||||
|
||||
// wasm media types
|
||||
WasmArtifactLayerMediaType = "application/vnd.wasm.content.layer.v1+wasm"
|
||||
WasmConfigMediaType = "application/vnd.wasm.config.v1+json"
|
||||
|
||||
Reference in New Issue
Block a user