diff --git a/build.go b/build.go index 8890864..17ff652 100644 --- a/build.go +++ b/build.go @@ -179,9 +179,8 @@ func Build(builder Builder, options ...Option) { logger.Debug(PlatformFormatter(ctx.Platform)) } - file = filepath.Join(ctx.Platform.Path, "bindings") - if ctx.Platform.Bindings, err = NewBindingsFromEnvOrPath(file); err != nil { - config.exitHandler.Error(fmt.Errorf("unable to read platform bindings %s\n%w", file, err)) + if ctx.Platform.Bindings, err = NewBindingsForBuild(ctx.Platform.Path); err != nil { + config.exitHandler.Error(fmt.Errorf("unable to read platform bindings %s\n%w", ctx.Platform.Path, err)) return } logger.Debugf("Platform Bindings: %+v", ctx.Platform.Bindings) diff --git a/platform.go b/platform.go index 7acf494..2a732a6 100644 --- a/platform.go +++ b/platform.go @@ -35,6 +35,18 @@ const ( // BindingType is the key for a binding's type. BindingType = "type" + + // EnvServiceBindings is the name of the environment variable that contains the path to service bindings directory. + // + // See the Service Binding Specification for Kubernetes for more details - https://k8s-service-bindings.github.io/spec/ + EnvServiceBindings = "SERVICE_BINDING_ROOT" + + // EnvCNBBindings is the name of the environment variable that contains the path to the CNB bindings directory. The CNB + // bindings spec will eventually by deprecated in favor of the Service Binding Specification for Kubernetes - + // https://github.com/buildpacks/rfcs/blob/main/text/0055-deprecate-service-bindings.md. + // + // See the CNB bindings extension spec for more details - https://github.com/buildpacks/spec/blob/main/extensions/bindings.md + EnvCNBBindings = "CNB_BINDINGS" ) // Binding is a projection of metadata about an external entity to be bound to. @@ -134,13 +146,20 @@ type Bindings []Binding // NewBindingsFromEnvironment creates a new bindings from all the bindings at the path defined by $SERVICE_BINDING_ROOT // or $CNB_BINDINGS if it does not exist. If neither is defined, returns an empty collection of Bindings. +// Note - This API is deprecated. Please use NewBindingsForLaunch instead. func NewBindingsFromEnvironment() (Bindings, error) { - if path, ok := os.LookupEnv("SERVICE_BINDING_ROOT"); ok { + return NewBindingsForLaunch() +} + +// NewBindingsForLaunch creates a new bindings from all the bindings at the path defined by $SERVICE_BINDING_ROOT +// or $CNB_BINDINGS if it does not exist. If neither is defined, returns an empty collection of Bindings. +func NewBindingsForLaunch() (Bindings, error) { + if path, ok := os.LookupEnv(EnvServiceBindings); ok { return NewBindingsFromPath(path) } // TODO: Remove as CNB_BINDINGS ages out - if path, ok := os.LookupEnv("CNB_BINDINGS"); ok { + if path, ok := os.LookupEnv(EnvCNBBindings); ok { return NewBindingsFromPath(path) } @@ -167,19 +186,18 @@ func NewBindingsFromPath(path string) (Bindings, error) { return bindings, nil } -// NewBindingsFromEnvOrPath creates a new bindings from all the bindings at the path defined by $SERVICE_BINDING_ROOT -// or $CNB_BINDINGS if it does not exist. If neither is defined, it defaults to using the given path. -func NewBindingsFromEnvOrPath(path string) (Bindings, error) { - if path, ok := os.LookupEnv("SERVICE_BINDING_ROOT"); ok { +// NewBindingsForBuild creates a new bindings from all the bindings at the path defined by $SERVICE_BINDING_ROOT +// or $CNB_BINDINGS if it does not exist. If neither is defined, bindings are read from /bindings, the default +// path defined in the CNB Binding extension specification. +func NewBindingsForBuild(platformDir string) (Bindings, error) { + if path, ok := os.LookupEnv(EnvServiceBindings); ok { return NewBindingsFromPath(path) } - // TODO: Remove as CNB_BINDINGS ages out - if path, ok := os.LookupEnv("CNB_BINDINGS"); ok { + if path, ok := os.LookupEnv(EnvCNBBindings); ok { return NewBindingsFromPath(path) } - - return NewBindingsFromPath(path) + return NewBindingsFromPath(filepath.Join(platformDir, "bindings")) } // Platform is the contents of the platform directory. diff --git a/platform_test.go b/platform_test.go index cbbcb36..b2f3ce3 100644 --- a/platform_test.go +++ b/platform_test.go @@ -33,12 +33,13 @@ func testPlatform(t *testing.T, context spec.G, it spec.S) { var ( Expect = NewWithT(t).Expect - path string + path, platformPath string ) it.Before(func() { var err error - path, err = ioutil.TempDir("", "bindings") + platformPath, err = ioutil.TempDir("", "platform") + path = filepath.Join(platformPath, "bindings") Expect(err).NotTo(HaveOccurred()) }) @@ -155,11 +156,11 @@ func testPlatform(t *testing.T, context spec.G, it spec.S) { context("from environment", func() { it.Before(func() { - Expect(os.Setenv("CNB_BINDINGS", path)) + Expect(os.Setenv(libcnb.EnvCNBBindings, path)) }) it.After(func() { - Expect(os.Unsetenv("CNB_BINDINGS")) + Expect(os.Unsetenv(libcnb.EnvCNBBindings)) }) it("creates bindings from path in $CNB_BINDINGS", func() { @@ -278,11 +279,11 @@ func testPlatform(t *testing.T, context spec.G, it spec.S) { context("from environment", func() { it.Before(func() { - Expect(os.Setenv("SERVICE_BINDING_ROOT", path)) + Expect(os.Setenv(libcnb.EnvServiceBindings, path)) }) it.After(func() { - Expect(os.Unsetenv("SERVICE_BINDING_ROOT")) + Expect(os.Unsetenv(libcnb.EnvServiceBindings)) }) it("creates bindings from path in SERVICE_BINDING_ROOT", func() { @@ -308,17 +309,17 @@ func testPlatform(t *testing.T, context spec.G, it spec.S) { context("from environment or path", func() { context("when SERVICE_BINDING_ROOT is defined but CNB_BINDINGS or the passed path does not exist", func() { it.Before(func() { - Expect(os.Setenv("SERVICE_BINDING_ROOT", path)) - Expect(os.Setenv("CNB_BINDINGS", "does not exist")) + Expect(os.Setenv(libcnb.EnvServiceBindings, path)) + Expect(os.Setenv(libcnb.EnvCNBBindings, "does not exist")) }) it.After(func() { - Expect(os.Unsetenv("SERVICE_BINDING_ROOT")) - Expect(os.Unsetenv("CNB_BINDINGS")) + Expect(os.Unsetenv(libcnb.EnvServiceBindings)) + Expect(os.Unsetenv(libcnb.EnvCNBBindings)) }) it("creates bindings from path in SERVICE_BINDING_ROOT", func() { - Expect(libcnb.NewBindingsFromEnvOrPath("random-path-that-does-not-exist")).To(Equal(libcnb.Bindings{ + Expect(libcnb.NewBindingsForBuild("random-path-that-does-not-exist")).To(Equal(libcnb.Bindings{ libcnb.Binding{ Name: "alpha", Path: filepath.Join(path, "alpha"), @@ -339,15 +340,15 @@ func testPlatform(t *testing.T, context spec.G, it spec.S) { context("when CNB_BINDINGS is defined but the path does not exist", func() { it.Before(func() { - Expect(os.Setenv("CNB_BINDINGS", path)) + Expect(os.Setenv(libcnb.EnvCNBBindings, path)) }) it.After(func() { - Expect(os.Unsetenv("CNB_BINDINGS")) + Expect(os.Unsetenv(libcnb.EnvCNBBindings)) }) it("creates bindings from path in CNB_BINDINGS", func() { - Expect(libcnb.NewBindingsFromEnvOrPath("random-path-that-does-not-exist")).To(Equal(libcnb.Bindings{ + Expect(libcnb.NewBindingsForBuild("random-path-that-does-not-exist")).To(Equal(libcnb.Bindings{ libcnb.Binding{ Name: "alpha", Path: filepath.Join(path, "alpha"), @@ -368,7 +369,7 @@ func testPlatform(t *testing.T, context spec.G, it spec.S) { context("when SERVICE_BINDING_ROOT and CNB_BINDINGS is not defined but the path exists", func() { it("creates bindings from the given path", func() { - Expect(libcnb.NewBindingsFromEnvOrPath(path)).To(Equal(libcnb.Bindings{ + Expect(libcnb.NewBindingsForBuild(platformPath)).To(Equal(libcnb.Bindings{ libcnb.Binding{ Name: "alpha", Path: filepath.Join(path, "alpha"), @@ -389,7 +390,7 @@ func testPlatform(t *testing.T, context spec.G, it spec.S) { context("when no valid binding variable is set", func() { it("returns an an empty binding", func() { - Expect(libcnb.NewBindingsFromEnvOrPath("does-not-exist")).To(Equal(libcnb.Bindings{})) + Expect(libcnb.NewBindingsForBuild("does-not-exist")).To(Equal(libcnb.Bindings{})) }) })