Skip to content

Commit

Permalink
Validate builder Lifecycle Platform API Version
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Meyer <[email protected]>
Signed-off-by: Javier Romero <[email protected]>
  • Loading branch information
jromero committed Sep 12, 2019
1 parent 059303c commit 65af576
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 18 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ all: clean verify test build
build:
@echo "> Building..."
mkdir -p ./out
$(GOENV) $(GOCMD) build -mod=vendor -ldflags "-X 'main.Version=${PACK_VERSION}'" -o ./out/$(PACK_BIN) -a ./cmd/pack
$(GOENV) $(GOCMD) build -mod=vendor -ldflags "-X 'github.com/buildpack/pack/cmd.Version=${PACK_VERSION}'" -o ./out/$(PACK_BIN) -a ./cmd/pack

package:
tar czf ./out/$(ARCHIVE_NAME).tgz -C out/ pack
Expand Down
32 changes: 29 additions & 3 deletions build.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ import (
"github.com/google/go-containerregistry/pkg/name"
"github.com/pkg/errors"

"github.com/buildpack/pack/api"
"github.com/buildpack/pack/build"
"github.com/buildpack/pack/builder"
"github.com/buildpack/pack/cmd"
"github.com/buildpack/pack/internal/archive"
"github.com/buildpack/pack/internal/paths"
"github.com/buildpack/pack/style"
Expand Down Expand Up @@ -69,14 +71,14 @@ func (c *Client) Build(ctx context.Context, opts BuildOptions) error {
return errors.Wrapf(err, "failed to fetch builder image '%s'", builderRef.Name())
}

builderImage, err := c.processBuilderImage(rawBuilderImage)
bldr, err := c.processBuilderImage(rawBuilderImage)
if err != nil {
return errors.Wrapf(err, "invalid builder '%s'", opts.Builder)
}

runImage := c.resolveRunImage(opts.RunImage, imageRef.Context().RegistryStr(), builderImage.GetStackInfo(), opts.AdditionalMirrors)
runImage := c.resolveRunImage(opts.RunImage, imageRef.Context().RegistryStr(), bldr.GetStackInfo(), opts.AdditionalMirrors)

if _, err := c.validateRunImage(ctx, runImage, opts.NoPull, opts.Publish, builderImage.StackID); err != nil {
if _, err := c.validateRunImage(ctx, runImage, opts.NoPull, opts.Publish, bldr.StackID); err != nil {
return errors.Wrapf(err, "invalid run-image '%s'", runImage)
}

Expand All @@ -91,6 +93,30 @@ func (c *Client) Build(ctx context.Context, opts BuildOptions) error {
}
defer c.docker.ImageRemove(context.Background(), ephemeralBuilder.Name(), types.ImageRemoveOptions{Force: true})

descriptor := ephemeralBuilder.GetLifecycleDescriptor()
lifecycleVersion := descriptor.Info.Version
if lifecycleVersion == nil {
c.logger.Warnf("lifecycle version unknown, assuming %s", style.Symbol(builder.AssumedLifecycleVersion))
lifecycleVersion = builder.VersionMustParse(builder.AssumedLifecycleVersion)
} else {
c.logger.Debugf("Executing lifecycle version %s", style.Symbol(lifecycleVersion.String()))
}

lcPlatformAPIVersion := api.MustParse(builder.AssumedPlatformAPIVersion)
if descriptor.API.PlatformVersion != nil {
lcPlatformAPIVersion = descriptor.API.PlatformVersion
}

if !api.MustParse(build.PlatformAPIVersion).SupportsVersion(lcPlatformAPIVersion) {
return errors.Errorf(
"pack %s (Platform API version %s) is incompatible with builder %s (Platform API version %s)",
cmd.Version,
build.PlatformAPIVersion,
style.Symbol(opts.Builder),
lcPlatformAPIVersion,
)
}

return c.lifecycle.Execute(ctx, build.LifecycleOptions{
AppPath: appPath,
Image: imageRef,
Expand Down
11 changes: 3 additions & 8 deletions build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import (
"github.com/buildpack/pack/style"
)

// PlatformAPIVersion is the current Platform API Version supported by this version of pack.
const PlatformAPIVersion = "0.1"

type Lifecycle struct {
builder *builder.Builder
logger logging.Logger
Expand Down Expand Up @@ -69,14 +72,6 @@ func (l *Lifecycle) Execute(ctx context.Context, opts LifecycleOptions) error {
l.logger.Debugf("Build cache %s cleared", style.Symbol(buildCache.Name()))
}

lifecycleVersion := l.builder.GetLifecycleDescriptor().Info.Version
if lifecycleVersion == nil {
l.logger.Warnf("lifecycle version unknown, assuming %s", style.Symbol(builder.AssumedLifecycleVersion))
lifecycleVersion = builder.VersionMustParse(builder.AssumedLifecycleVersion)
} else {
l.logger.Debugf("Executing lifecycle version %s", style.Symbol(lifecycleVersion.String()))
}

l.logger.Debug(style.Step("DETECTING"))
if err := l.Detect(ctx); err != nil {
return err
Expand Down
84 changes: 83 additions & 1 deletion build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@ import (

"github.com/buildpack/pack/api"
"github.com/buildpack/pack/blob"
"github.com/buildpack/pack/build"
"github.com/buildpack/pack/builder"
"github.com/buildpack/pack/cmd"
ifakes "github.com/buildpack/pack/internal/fakes"
"github.com/buildpack/pack/style"
h "github.com/buildpack/pack/testhelpers"
)

Expand Down Expand Up @@ -90,7 +93,7 @@ func testBuild(t *testing.T, when spec.G, it spec.S) {
},
API: builder.LifecycleAPI{
BuildpackVersion: api.MustParse("0.3"),
PlatformVersion: api.MustParse("0.2"),
PlatformVersion: api.MustParse(build.PlatformAPIVersion),
},
},
},
Expand Down Expand Up @@ -336,6 +339,11 @@ func testBuild(t *testing.T, when spec.G, it spec.S) {
Image: "some/run",
},
},
Lifecycle: builder.LifecycleMetadata{
API: builder.LifecycleAPI{
PlatformVersion: api.MustParse(build.PlatformAPIVersion),
},
},
})

fakeImageFetcher.LocalImages[customBuilderImage.Name()] = customBuilderImage
Expand Down Expand Up @@ -911,6 +919,80 @@ func testBuild(t *testing.T, when spec.G, it spec.S) {
})
})
})

when("Lifecycle option", func() {
when("Platform API", func() {
when("lifecycle platform API is compatible", func() {
it("should succeed", func() {
err := subject.Build(context.TODO(), BuildOptions{
Image: "some/app",
Builder: builderName,
})

h.AssertNil(t, err)
})
})

when("lifecycle platform API is not compatible", func() {
var incompatibleBuilderImage *fakes.Image
it.Before(func() {
incompatibleBuilderImage = ifakes.NewFakeBuilderImage(t,
"incompatible-"+builderName,
defaultBuilderStackID,
"1234",
"5678",
builder.Metadata{
Stack: builder.StackMetadata{
RunImage: builder.RunImageMetadata{
Image: "default/run",
Mirrors: []string{
"registry1.example.com/run/mirror",
"registry2.example.com/run/mirror",
},
},
},
Lifecycle: builder.LifecycleMetadata{
LifecycleInfo: builder.LifecycleInfo{
Version: &builder.Version{
Version: *semver.MustParse("0.3.0"),
},
},
API: builder.LifecycleAPI{
BuildpackVersion: api.MustParse("0.3"),
PlatformVersion: api.MustParse("0.9"),
},
},
},
)

fakeImageFetcher.LocalImages[incompatibleBuilderImage.Name()] = incompatibleBuilderImage
})

it.After(func() {
incompatibleBuilderImage.Cleanup()
})

it("should error", func() {
builderName := incompatibleBuilderImage.Name()

err := subject.Build(context.TODO(), BuildOptions{
Image: "some/app",
Builder: builderName,
})

h.AssertError(t,
err,
fmt.Sprintf(
"pack %s (Platform API version %s) is incompatible with builder %s (Platform API version %s)",
cmd.Version,
build.PlatformAPIVersion,
style.Symbol(builderName),
"0.9",
))
})
})
})
})
})
}

Expand Down
6 changes: 6 additions & 0 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package cmd

var (
// Version is the version of `pack`. It is injected at compile time.
Version = "0.0.0"
)
8 changes: 3 additions & 5 deletions cmd/pack/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,14 @@ import (
"github.com/spf13/cobra"

"github.com/buildpack/pack"
"github.com/buildpack/pack/cmd"
"github.com/buildpack/pack/commands"
"github.com/buildpack/pack/config"
clilogger "github.com/buildpack/pack/internal/logging"
"github.com/buildpack/pack/logging"
)

var (
Version = "0.0.0"
packClient pack.Client
)
var packClient pack.Client

func main() {
// create logger with defaults
Expand Down Expand Up @@ -64,7 +62,7 @@ func main() {
rootCmd.AddCommand(commands.SuggestBuilders(logger, &packClient))

rootCmd.AddCommand(commands.SuggestStacks(logger))
rootCmd.AddCommand(commands.Version(logger, Version))
rootCmd.AddCommand(commands.Version(logger, cmd.Version))

rootCmd.AddCommand(commands.CompletionCommand(logger))

Expand Down

0 comments on commit 65af576

Please sign in to comment.