Skip to content
Snippets Groups Projects
Commit 0638fa69 authored by Cameron Swords's avatar Cameron Swords :ghost:
Browse files

Fix failing loads OCI step test

Also refactor the cache load method into a separate method
parent 407dbf21
No related branches found
No related tags found
1 merge request!178OCI steps can be downloaded and run using an OCI step reference
......@@ -55,32 +55,9 @@ func NewWithOptions(options ...func(*cache)) runner.Cache {
func (c *cache) Get(ctx context.Context, parentDir string, stepResource runner.StepResource) (*proto.SpecDefinition, error) {
stepRef := stepResource.ToProtoStepRef()
load := func(dir string) (*proto.SpecDefinition, error) {
path := filepath.Join(stepRef.Path...)
filename := filepath.Join(dir, path, stepRef.Filename)
spec, step, err := schema.LoadSteps(filename)
if err != nil {
return nil, fmt.Errorf("loading file %q: %w", filename, err)
}
protoSpec, err := spec.Compile()
if err != nil {
return nil, fmt.Errorf("compiling file %q: %w", dir, err)
}
protoDef, err := step.Compile()
if err != nil {
return nil, fmt.Errorf("compiling file %q: %w", dir, err)
}
protoStepDef := &proto.SpecDefinition{
Spec: protoSpec,
Definition: protoDef,
}
protoStepDef.Dir = filepath.Join(dir, path)
return protoStepDef, nil
}
switch {
case stepRef.Protocol == proto.StepReferenceProtocol_local:
return load(parentDir)
return c.load(stepRef, parentDir)
case stepRef.Protocol == proto.StepReferenceProtocol_git:
dir, err := c.gitFetcher.Get(ctx, stepRef.Url, stepRef.Version)
......@@ -88,9 +65,44 @@ func (c *cache) Get(ctx context.Context, parentDir string, stepResource runner.S
return nil, fmt.Errorf("fetching step %q: %w", stepRef, err)
}
return load(dir)
return c.load(stepRef, dir)
case stepRef.Protocol == proto.StepReferenceProtocol_oci:
dir, err := c.ociFetcher.Fetch(ctx, stepRef.Url, stepRef.Version)
if err != nil {
return nil, fmt.Errorf("fetching step %q: %w", stepRef, err)
}
return c.load(stepRef, dir)
default:
return nil, fmt.Errorf("invalid step reference: %v", stepRef)
}
}
func (c *cache) load(stepRef *proto.Step_Reference, stepDir string) (*proto.SpecDefinition, error) {
path := filepath.Join(stepRef.Path...)
filename := filepath.Join(stepDir, path, stepRef.Filename)
spec, step, err := schema.LoadSteps(filename)
if err != nil {
return nil, fmt.Errorf("loading file %q: %w", filename, err)
}
protoSpec, err := spec.Compile()
if err != nil {
return nil, fmt.Errorf("compiling file %q: %w", stepDir, err)
}
protoDef, err := step.Compile()
if err != nil {
return nil, fmt.Errorf("compiling file %q: %w", stepDir, err)
}
protoStepDef := &proto.SpecDefinition{
Spec: protoSpec,
Definition: protoDef,
Dir: filepath.Join(stepDir, path),
}
return protoStepDef, nil
}
......@@ -69,10 +69,11 @@ func TestCache(t *testing.T) {
layer := bldr.OCIImageLayer(t).WithFile("/step.yml", []byte("spec:\n---\nexec: {command: [bash]}")).Build()
img := bldr.OCIImage(t).WithLayer(layer).Build()
registry.Push(remoteImgRef, img)
imgIndex := bldr.OCIImageIndex(t).WithImageForThisPlatform(img).Build()
registry.PushImageIndex(remoteImgRef, imgIndex)
res := bldr.OCIStepResource().WithImgRef(remoteImgRef).Build()
ociFetcher := oci.NewOCIFetcher()
ociFetcher := oci.NewOCIFetcher(t.TempDir())
stepCache := cache.NewWithOptions(cache.WithOCIFetcher(ociFetcher))
specDef, err := stepCache.Get(context.Background(), t.TempDir(), res)
......
package oci
import (
"context"
"fmt"
"github.com/google/go-containerregistry/pkg/name"
"gitlab.com/gitlab-org/step-runner/pkg/cache/oci/internal"
)
type OCIFetcher struct {
client *internal.Client
}
func NewOCIFetcher() *OCIFetcher {
return &OCIFetcher{}
func NewOCIFetcher(downloadDir string) *OCIFetcher {
return &OCIFetcher{
client: internal.NewClient(downloadDir),
}
}
func (f *OCIFetcher) Fetch(ctx context.Context, url, tag string) (string, error) {
urlAndTag := fmt.Sprintf("%s:%s", url, tag)
imgRef, err := name.ParseReference(urlAndTag)
if err != nil {
return "", fmt.Errorf("OCI image: %w", err)
}
dir, err := f.client.Pull(ctx, imgRef)
if err != nil {
return "", err
}
return dir, nil
}
package oci_test
import (
"context"
"testing"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/step-runner/pkg/cache/oci"
)
func TestOCIFetcher_Fetch(t *testing.T) {
t.Run("invalid image url", func(t *testing.T) {
fetcher := oci.NewOCIFetcher(t.TempDir())
_, err := fetcher.Fetch(context.Background(), "registry.gitlab.com/!", "latest")
require.Error(t, err)
require.Contains(t, err.Error(), "OCI image: could not parse reference: registry.gitlab.com/!:latest")
})
t.Run("invalid tag", func(t *testing.T) {
fetcher := oci.NewOCIFetcher(t.TempDir())
_, err := fetcher.Fetch(context.Background(), "registry.gitlab.com/step-runner", "!err!")
require.Error(t, err)
require.Contains(t, err.Error(), "OCI image: could not parse reference: registry.gitlab.com/step-runner:!err!")
})
}
......@@ -3,6 +3,7 @@ package bldr
import (
"testing"
"github.com/containerd/platforms"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/empty"
"github.com/google/go-containerregistry/pkg/v1/mutate"
......@@ -33,6 +34,20 @@ func (b *OCIImageIndexBuilder) WithPlatformImage(platform *v1.Platform, image v1
return b
}
func (b *OCIImageIndexBuilder) WithImageForThisPlatform(img v1.Image) *OCIImageIndexBuilder {
thisPlatform := platforms.DefaultSpec()
v1Platform := &v1.Platform{
OS: thisPlatform.OS,
Architecture: thisPlatform.Architecture,
Variant: thisPlatform.Variant,
OSVersion: thisPlatform.OSVersion,
OSFeatures: thisPlatform.OSFeatures,
Features: nil,
}
return b.WithPlatformImage(v1Platform, img)
}
func (b *OCIImageIndexBuilder) Build() v1.ImageIndex {
return b.index
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment