diff --git a/pkg/builders/builders_int_test.go b/pkg/builders/builders_int_test.go index cc222684..b64db9c8 100644 --- a/pkg/builders/builders_int_test.go +++ b/pkg/builders/builders_int_test.go @@ -1,3 +1,5 @@ +//go:build integration + package builders_test import ( @@ -35,7 +37,6 @@ import ( ) func TestPrivateGitRepository(t *testing.T) { - t.Skip("tested functionality not implemented yet") ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -65,6 +66,21 @@ func TestPrivateGitRepository(t *testing.T) { t.Fatal(ctx.Err()) } + gitCredsDir := t.TempDir() + err := os.WriteFile(filepath.Join(gitCredsDir, "type"), []byte(`git-credentials`), 0600) + if err != nil { + t.Fatal(err) + } + + gitCred := `url=https://git-private.127.0.0.1.sslip.io +username=developer +password=nbusr123 +` + err = os.WriteFile(filepath.Join(gitCredsDir, "credentials"), []byte(gitCred), 0600) + if err != nil { + t.Fatal(err) + } + builder := buildpacks.NewBuilder(buildpacks.WithVerbose(true)) f, err := fn.NewFunction(filepath.Join("testdata", "go-fn-with-private-deps")) if err != nil { @@ -73,6 +89,14 @@ func TestPrivateGitRepository(t *testing.T) { f.Build.Image = "localhost:50000/go-app:test" f.Build.Builder = "pack" f.Build.BuilderImages = map[string]string{"pack": builderImage} + f.Build.BuildEnvs = []fn.Env{{ + Name: ptr("SERVICE_BINDING_ROOT"), + Value: ptr("/bindings"), + }} + f.Build.Mounts = []fn.MountSpec{{ + Source: gitCredsDir, + Destination: "/bindings/git-binding", + }} err = builder.Build(ctx, f, nil) if err != nil { t.Fatal(err) diff --git a/pkg/builders/buildpacks/builder.go b/pkg/builders/buildpacks/builder.go index 83c6ba85..ab6f24cb 100644 --- a/pkg/builders/buildpacks/builder.go +++ b/pkg/builders/buildpacks/builder.go @@ -179,6 +179,12 @@ func (b *Builder) Build(ctx context.Context, f fn.Function, platforms []fn.Platf opts.ContainerConfig.Network = "host" } + var bindings = make([]string, 0, len(f.Build.Mounts)) + for _, m := range f.Build.Mounts { + bindings = append(bindings, fmt.Sprintf("%s:%s", m.Source, m.Destination)) + } + opts.ContainerConfig.Volumes = bindings + // only trust our known builders opts.TrustBuilder = TrustBuilder diff --git a/pkg/functions/function.go b/pkg/functions/function.go index 4c0ce310..af70f8b2 100644 --- a/pkg/functions/function.go +++ b/pkg/functions/function.go @@ -148,6 +148,14 @@ type BuildSpec struct { // Image stores last built image name NOT in func.yaml, but instead // in .func/built-image Image string `yaml:"-"` + + // Mounts used in build phase. This is useful in particular for paketo bindings. + Mounts []MountSpec `yaml:"mounts,omitempty"` +} + +type MountSpec struct { + Source string `yaml:"source"` + Destination string `yaml:"destination"` } // RunSpec diff --git a/schema/func_yaml-schema.json b/schema/func_yaml-schema.json index 633336d9..74504ec3 100644 --- a/schema/func_yaml-schema.json +++ b/schema/func_yaml-schema.json @@ -48,6 +48,14 @@ "remoteStorageClass": { "type": "string", "description": "RemoteStorageClass specifies the storage class to use for the volume used\non-cluster during when built remotely." + }, + "mounts": { + "items": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/MountSpec" + }, + "type": "array", + "description": "Mounts used in build phase. This is useful in particular for paketo bindings." } }, "additionalProperties": false, @@ -269,6 +277,22 @@ "additionalProperties": false, "type": "object" }, + "MountSpec": { + "required": [ + "source", + "destination" + ], + "properties": { + "source": { + "type": "string" + }, + "destination": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object" + }, "Options": { "properties": { "scale": {