Skip to content

Commit c45c3cf

Browse files
authored
Merge pull request #2053 from buildpacks/bugfix/jjbustamante/issue-2050
Fixing an parsing error with the buildpacks to be flattened
2 parents 30dcc15 + 572f869 commit c45c3cf

3 files changed

Lines changed: 206 additions & 1 deletion

File tree

acceptance/acceptance_test.go

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2929,6 +2929,56 @@ include = [ "*.jar", "media/mountain.jpg", "/media/person.png", ]
29292929
})
29302930
})
29312931
})
2932+
2933+
when("builder create", func() {
2934+
when("--flatten=<buildpacks>", func() {
2935+
it("should flatten together all specified buildpacks", func() {
2936+
h.SkipIf(t, !createBuilderPack.SupportsFeature(invoke.FlattenBuilderCreationV2), "pack version <= 0.33.0 fails with this test")
2937+
h.SkipIf(t, imageManager.HostOS() == "windows", "These tests are not yet compatible with Windows-based containers")
2938+
2939+
// create a task, handled by a 'task manager' which executes our pack commands during tests.
2940+
// looks like this is used to de-dup tasks
2941+
key := taskKey(
2942+
"create-complex-flattened-builder",
2943+
append(
2944+
[]string{runImageMirror, createBuilderPackConfig.Path(), lifecycle.Identifier()},
2945+
createBuilderPackConfig.FixturePaths()...,
2946+
)...,
2947+
)
2948+
2949+
builderName, err := suiteManager.RunTaskOnceString(key, func() (string, error) {
2950+
return createFlattenBuilder(t,
2951+
assert,
2952+
buildpackManager,
2953+
lifecycle,
2954+
createBuilderPack,
2955+
runImageMirror)
2956+
})
2957+
assert.Nil(err)
2958+
2959+
// register task to be run to 'clean up' a task
2960+
suiteManager.RegisterCleanUp("clean-"+key, func() error {
2961+
imageManager.CleanupImages(builderName)
2962+
return nil
2963+
})
2964+
2965+
assertImage.ExistsLocally(builderName)
2966+
2967+
// 3 layers for runtime OS
2968+
// 1 layer setting cnb, platform, layers folders
2969+
// 1 layer for lifecycle binaries
2970+
// 1 layer for order.toml
2971+
// 1 layer for run.toml
2972+
// 1 layer for stack.toml
2973+
// 1 layer status file changed
2974+
// Base Layers = 9
2975+
2976+
// 1 layer for 3 flattened builpacks
2977+
// 3 layers for single buildpacks not flattened
2978+
assertImage.HasLengthLayers(builderName, 13)
2979+
})
2980+
})
2981+
})
29322982
})
29332983
}
29342984

@@ -3315,6 +3365,157 @@ func createStackImage(dockerCli client.CommonAPIClient, repoName string, dir str
33153365
}))
33163366
}
33173367

3368+
func createFlattenBuilder(
3369+
t *testing.T,
3370+
assert h.AssertionManager,
3371+
buildpackManager buildpacks.BuildModuleManager,
3372+
lifecycle config.LifecycleAsset,
3373+
pack *invoke.PackInvoker,
3374+
runImageMirror string,
3375+
) (string, error) {
3376+
t.Helper()
3377+
t.Log("creating flattened builder image...")
3378+
3379+
// CREATE TEMP WORKING DIR
3380+
tmpDir, err := os.MkdirTemp("", "create-complex-test-flattened-builder")
3381+
if err != nil {
3382+
return "", err
3383+
}
3384+
defer os.RemoveAll(tmpDir)
3385+
3386+
// ARCHIVE BUILDPACKS
3387+
builderBuildpacks := []buildpacks.TestBuildModule{
3388+
buildpacks.BpNoop,
3389+
buildpacks.BpNoop2,
3390+
buildpacks.BpOtherStack,
3391+
buildpacks.BpReadEnv,
3392+
}
3393+
3394+
templateMapping := map[string]interface{}{
3395+
"run_image_mirror": runImageMirror,
3396+
}
3397+
3398+
packageImageName := registryConfig.RepoName("nested-level-1-buildpack-" + h.RandString(8))
3399+
nestedLevelTwoBuildpackName := registryConfig.RepoName("nested-level-2-buildpack-" + h.RandString(8))
3400+
simpleLayersBuildpackName := registryConfig.RepoName("simple-layers-buildpack-" + h.RandString(8))
3401+
simpleLayersBuildpackDifferentShaName := registryConfig.RepoName("simple-layers-buildpack-different-name-" + h.RandString(8))
3402+
3403+
templateMapping["package_id"] = "simple/nested-level-1"
3404+
templateMapping["package_image_name"] = packageImageName
3405+
templateMapping["nested_level_1_buildpack"] = packageImageName
3406+
templateMapping["nested_level_2_buildpack"] = nestedLevelTwoBuildpackName
3407+
templateMapping["simple_layers_buildpack"] = simpleLayersBuildpackName
3408+
templateMapping["simple_layers_buildpack_different_sha"] = simpleLayersBuildpackDifferentShaName
3409+
3410+
fixtureManager := pack.FixtureManager()
3411+
3412+
nestedLevelOneConfigFile, err := os.CreateTemp(tmpDir, "nested-level-1-package.toml")
3413+
assert.Nil(err)
3414+
fixtureManager.TemplateFixtureToFile(
3415+
"nested-level-1-buildpack_package.toml",
3416+
nestedLevelOneConfigFile,
3417+
templateMapping,
3418+
)
3419+
err = nestedLevelOneConfigFile.Close()
3420+
assert.Nil(err)
3421+
3422+
nestedLevelTwoConfigFile, err := os.CreateTemp(tmpDir, "nested-level-2-package.toml")
3423+
assert.Nil(err)
3424+
fixtureManager.TemplateFixtureToFile(
3425+
"nested-level-2-buildpack_package.toml",
3426+
nestedLevelTwoConfigFile,
3427+
templateMapping,
3428+
)
3429+
3430+
err = nestedLevelTwoConfigFile.Close()
3431+
assert.Nil(err)
3432+
3433+
packageImageBuildpack := buildpacks.NewPackageImage(
3434+
t,
3435+
pack,
3436+
packageImageName,
3437+
nestedLevelOneConfigFile.Name(),
3438+
buildpacks.WithRequiredBuildpacks(
3439+
buildpacks.BpNestedLevelOne,
3440+
buildpacks.NewPackageImage(
3441+
t,
3442+
pack,
3443+
nestedLevelTwoBuildpackName,
3444+
nestedLevelTwoConfigFile.Name(),
3445+
buildpacks.WithRequiredBuildpacks(
3446+
buildpacks.BpNestedLevelTwo,
3447+
buildpacks.NewPackageImage(
3448+
t,
3449+
pack,
3450+
simpleLayersBuildpackName,
3451+
fixtureManager.FixtureLocation("simple-layers-buildpack_package.toml"),
3452+
buildpacks.WithRequiredBuildpacks(buildpacks.BpSimpleLayers),
3453+
),
3454+
),
3455+
),
3456+
),
3457+
)
3458+
3459+
simpleLayersDifferentShaBuildpack := buildpacks.NewPackageImage(
3460+
t,
3461+
pack,
3462+
simpleLayersBuildpackDifferentShaName,
3463+
fixtureManager.FixtureLocation("simple-layers-buildpack-different-sha_package.toml"),
3464+
buildpacks.WithRequiredBuildpacks(buildpacks.BpSimpleLayersDifferentSha),
3465+
)
3466+
3467+
defer imageManager.CleanupImages(packageImageName, nestedLevelTwoBuildpackName, simpleLayersBuildpackName, simpleLayersBuildpackDifferentShaName)
3468+
3469+
builderBuildpacks = append(
3470+
builderBuildpacks,
3471+
packageImageBuildpack,
3472+
simpleLayersDifferentShaBuildpack,
3473+
)
3474+
3475+
buildpackManager.PrepareBuildModules(tmpDir, builderBuildpacks...)
3476+
3477+
// ADD lifecycle
3478+
if lifecycle.HasLocation() {
3479+
lifecycleURI := lifecycle.EscapedPath()
3480+
t.Logf("adding lifecycle path '%s' to builder config", lifecycleURI)
3481+
templateMapping["lifecycle_uri"] = lifecycleURI
3482+
} else {
3483+
lifecycleVersion := lifecycle.Version()
3484+
t.Logf("adding lifecycle version '%s' to builder config", lifecycleVersion)
3485+
templateMapping["lifecycle_version"] = lifecycleVersion
3486+
}
3487+
3488+
// RENDER builder.toml
3489+
builderConfigFile, err := os.CreateTemp(tmpDir, "nested_builder.toml")
3490+
if err != nil {
3491+
return "", err
3492+
}
3493+
3494+
pack.FixtureManager().TemplateFixtureToFile("nested_builder.toml", builderConfigFile, templateMapping)
3495+
3496+
err = builderConfigFile.Close()
3497+
if err != nil {
3498+
return "", err
3499+
}
3500+
3501+
// NAME BUILDER
3502+
bldr := registryConfig.RepoName("test/flatten-builder-" + h.RandString(10))
3503+
3504+
// CREATE BUILDER
3505+
output := pack.RunSuccessfully(
3506+
"builder", "create", bldr,
3507+
"-c", builderConfigFile.Name(),
3508+
"--no-color",
3509+
"--verbose",
3510+
"--flatten", "read/env@read-env-version,noop.buildpack@noop.buildpack.version,noop.buildpack@noop.buildpack.later-version",
3511+
)
3512+
3513+
assert.Contains(output, fmt.Sprintf("Successfully created builder image '%s'", bldr))
3514+
assert.Succeeds(h.PushImage(dockerCli, bldr, registryConfig))
3515+
3516+
return bldr, nil
3517+
}
3518+
33183519
// taskKey creates a key from the prefix and all arguments to be unique
33193520
func taskKey(prefix string, args ...string) string {
33203521
hash := sha256.New()

acceptance/invoke/pack.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ const (
236236
BuildpackFlatten
237237
MetaBuildpackFolder
238238
PlatformRetries
239+
FlattenBuilderCreationV2
239240
)
240241

241242
var featureTests = map[Feature]func(i *PackInvoker) bool{
@@ -266,6 +267,9 @@ var featureTests = map[Feature]func(i *PackInvoker) bool{
266267
PlatformRetries: func(i *PackInvoker) bool {
267268
return i.atLeast("v0.32.1")
268269
},
270+
FlattenBuilderCreationV2: func(i *PackInvoker) bool {
271+
return i.atLeast("v0.33.1")
272+
},
269273
}
270274

271275
func (i *PackInvoker) SupportsFeature(f Feature) bool {

internal/commands/builder_create.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ Creating a custom builder allows you to control what buildpacks are used and wha
114114
cmd.Flags().StringVarP(&flags.BuilderTomlPath, "config", "c", "", "Path to builder TOML file (required)")
115115
cmd.Flags().BoolVar(&flags.Publish, "publish", false, "Publish the builder directly to the container registry specified in <image-name>, instead of the daemon.")
116116
cmd.Flags().StringVar(&flags.Policy, "pull-policy", "", "Pull policy to use. Accepted values are always, never, and if-not-present. The default is always")
117-
cmd.Flags().StringSliceVar(&flags.Flatten, "flatten", nil, "List of buildpacks to flatten together into a single layer (format: '<buildpack-id>@<buildpack-version>,<buildpack-id>@<buildpack-version>'")
117+
cmd.Flags().StringArrayVar(&flags.Flatten, "flatten", nil, "List of buildpacks to flatten together into a single layer (format: '<buildpack-id>@<buildpack-version>,<buildpack-id>@<buildpack-version>'")
118118
cmd.Flags().StringToStringVarP(&flags.Label, "label", "l", nil, "Labels to add to the builder image, in the form of '<name>=<value>'")
119119

120120
AddHelpFlag(cmd, "create")

0 commit comments

Comments
 (0)