Skip to content

Commit

Permalink
Merge pull request #2034 from buildpacks/enhancement/jjbustamante/iss…
Browse files Browse the repository at this point in the history
…ue-2033

Adding `--label` flag to `pack builder create` command
  • Loading branch information
jjbustamante authored Jan 26, 2024
2 parents c6dd3ce + bdc66d2 commit 1d3718b
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 0 deletions.
15 changes: 15 additions & 0 deletions internal/builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ type BuilderOption func(*options) error

type options struct {
toFlatten buildpack.FlattenModuleInfos
labels map[string]string
}

// FromImage constructs a builder from a builder image
Expand Down Expand Up @@ -139,6 +140,13 @@ func constructBuilder(img imgutil.Image, newName string, errOnMissingLabel bool,
return nil, err
}

for labelKey, labelValue := range opts.labels {
err = img.SetLabel(labelKey, labelValue)
if err != nil {
return nil, errors.Wrapf(err, "adding label %s=%s", labelKey, labelValue)
}
}

bldr := &Builder{
baseImageName: img.Name(),
image: img,
Expand Down Expand Up @@ -170,6 +178,13 @@ func WithFlattened(modules buildpack.FlattenModuleInfos) BuilderOption {
}
}

func WithLabels(labels map[string]string) BuilderOption {
return func(o *options) error {
o.labels = labels
return nil
}
}

func constructLifecycleDescriptor(metadata Metadata) LifecycleDescriptor {
return CompatDescriptor(LifecycleDescriptor{
Info: LifecycleInfo{
Expand Down
28 changes: 28 additions & 0 deletions internal/builder/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1939,6 +1939,34 @@ func testBuilder(t *testing.T, when spec.G, it spec.S) {
})
})
})

when("labels", func() {
var (
customLabels, imageLabels map[string]string
err error
)
it.Before(func() {
h.AssertNil(t, baseImage.SetEnv("CNB_USER_ID", "1234"))
h.AssertNil(t, baseImage.SetEnv("CNB_GROUP_ID", "4321"))
h.AssertNil(t, baseImage.SetLabel("io.buildpacks.stack.id", "some.stack.id"))
h.AssertNil(t, baseImage.SetLabel("io.buildpacks.stack.mixins", `["mixinX", "mixinY", "build:mixinA"]`))
})

it.After(func() {
h.AssertNilE(t, baseImage.Cleanup())
})

it("should set labels to the image", func() {
customLabels = map[string]string{"test.label.one": "1", "test.label.two": "2"}
subject, err = builder.New(baseImage, "some/builder", builder.WithLabels(customLabels))
h.AssertNil(t, err)

imageLabels, err = baseImage.Labels()
h.AssertNil(t, err)
h.AssertEq(t, imageLabels["test.label.one"], "1")
h.AssertEq(t, imageLabels["test.label.two"], "2")
})
})
}

func assertImageHasBPLayer(t *testing.T, image *fakes.Image, bp buildpack.BuildModule) {
Expand Down
3 changes: 3 additions & 0 deletions internal/commands/builder_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type BuilderCreateFlags struct {
Registry string
Policy string
Flatten []string
Label map[string]string
}

// CreateBuilder creates a builder image, based on a builder config
Expand Down Expand Up @@ -96,6 +97,7 @@ Creating a custom builder allows you to control what buildpacks are used and wha
Registry: flags.Registry,
PullPolicy: pullPolicy,
Flatten: toFlatten,
Labels: flags.Label,
}); err != nil {
return err
}
Expand All @@ -113,6 +115,7 @@ Creating a custom builder allows you to control what buildpacks are used and wha
cmd.Flags().BoolVar(&flags.Publish, "publish", false, "Publish the builder directly to the container registry specified in <image-name>, instead of the daemon.")
cmd.Flags().StringVar(&flags.Policy, "pull-policy", "", "Pull policy to use. Accepted values are always, never, and if-not-present. The default is always")
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>'")
cmd.Flags().StringToStringVarP(&flags.Label, "label", "l", nil, "Labels to add to the builder image, in the form of '<name>=<value>'")

AddHelpFlag(cmd, "create")
return cmd
Expand Down
17 changes: 17 additions & 0 deletions internal/commands/builder_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,5 +424,22 @@ func testCreateCommand(t *testing.T, when spec.G, it spec.S) {
})
})
})

when("--label", func() {
when("can not be parsed", func() {
it("errors with a descriptive message", func() {
cmd := packageCommand()
cmd.SetArgs([]string{
"some/builder",
"--config", builderConfigPath,
"--label", "name+value",
})

err := cmd.Execute()
h.AssertNotNil(t, err)
h.AssertError(t, err, "invalid argument \"name+value\" for \"-l, --label\" flag: name+value must be formatted as key=value")
})
})
})
})
}
7 changes: 7 additions & 0 deletions pkg/client/create_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ type CreateBuilderOptions struct {
// BuildConfigEnv for Builder
BuildConfigEnv map[string]string

// Map of labels to add to the Buildpack
Labels map[string]string

// Configuration that defines the functionality a builder provides.
Config pubbldr.Config

Expand Down Expand Up @@ -154,6 +157,10 @@ func (c *Client) createBaseBuilder(ctx context.Context, opts CreateBuilderOption
if opts.Flatten != nil && len(opts.Flatten.FlattenModules()) > 0 {
builderOpts = append(builderOpts, builder.WithFlattened(opts.Flatten))
}
if opts.Labels != nil && len(opts.Labels) > 0 {
builderOpts = append(builderOpts, builder.WithLabels(opts.Labels))
}

bldr, err := builder.New(baseImage, opts.BuilderName, builderOpts...)
if err != nil {
return nil, errors.Wrap(err, "invalid build-image")
Expand Down
14 changes: 14 additions & 0 deletions pkg/client/create_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,20 @@ func testCreateBuilder(t *testing.T, when spec.G, it spec.S) {
h.AssertNotContains(t, out.String(), "is using deprecated Buildpacks API version")
})

it("should set labels", func() {
opts.Labels = map[string]string{"test.label.one": "1", "test.label.two": "2"}
prepareFetcherWithBuildImage()
prepareFetcherWithRunImages()

err := subject.CreateBuilder(context.TODO(), opts)
h.AssertNil(t, err)

imageLabels, err := fakeBuildImage.Labels()
h.AssertNil(t, err)
h.AssertEq(t, imageLabels["test.label.one"], "1")
h.AssertEq(t, imageLabels["test.label.two"], "2")
})

when("Buildpack dependencies are provided", func() {
var (
bp1v1 buildpack.BuildModule
Expand Down

0 comments on commit 1d3718b

Please sign in to comment.