Skip to content

Commit 1d3718b

Browse files
authored
Merge pull request #2034 from buildpacks/enhancement/jjbustamante/issue-2033
Adding `--label` flag to `pack builder create` command
2 parents c6dd3ce + bdc66d2 commit 1d3718b

6 files changed

Lines changed: 84 additions & 0 deletions

File tree

internal/builder/builder.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ type BuilderOption func(*options) error
103103

104104
type options struct {
105105
toFlatten buildpack.FlattenModuleInfos
106+
labels map[string]string
106107
}
107108

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

143+
for labelKey, labelValue := range opts.labels {
144+
err = img.SetLabel(labelKey, labelValue)
145+
if err != nil {
146+
return nil, errors.Wrapf(err, "adding label %s=%s", labelKey, labelValue)
147+
}
148+
}
149+
142150
bldr := &Builder{
143151
baseImageName: img.Name(),
144152
image: img,
@@ -170,6 +178,13 @@ func WithFlattened(modules buildpack.FlattenModuleInfos) BuilderOption {
170178
}
171179
}
172180

181+
func WithLabels(labels map[string]string) BuilderOption {
182+
return func(o *options) error {
183+
o.labels = labels
184+
return nil
185+
}
186+
}
187+
173188
func constructLifecycleDescriptor(metadata Metadata) LifecycleDescriptor {
174189
return CompatDescriptor(LifecycleDescriptor{
175190
Info: LifecycleInfo{

internal/builder/builder_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1939,6 +1939,34 @@ func testBuilder(t *testing.T, when spec.G, it spec.S) {
19391939
})
19401940
})
19411941
})
1942+
1943+
when("labels", func() {
1944+
var (
1945+
customLabels, imageLabels map[string]string
1946+
err error
1947+
)
1948+
it.Before(func() {
1949+
h.AssertNil(t, baseImage.SetEnv("CNB_USER_ID", "1234"))
1950+
h.AssertNil(t, baseImage.SetEnv("CNB_GROUP_ID", "4321"))
1951+
h.AssertNil(t, baseImage.SetLabel("io.buildpacks.stack.id", "some.stack.id"))
1952+
h.AssertNil(t, baseImage.SetLabel("io.buildpacks.stack.mixins", `["mixinX", "mixinY", "build:mixinA"]`))
1953+
})
1954+
1955+
it.After(func() {
1956+
h.AssertNilE(t, baseImage.Cleanup())
1957+
})
1958+
1959+
it("should set labels to the image", func() {
1960+
customLabels = map[string]string{"test.label.one": "1", "test.label.two": "2"}
1961+
subject, err = builder.New(baseImage, "some/builder", builder.WithLabels(customLabels))
1962+
h.AssertNil(t, err)
1963+
1964+
imageLabels, err = baseImage.Labels()
1965+
h.AssertNil(t, err)
1966+
h.AssertEq(t, imageLabels["test.label.one"], "1")
1967+
h.AssertEq(t, imageLabels["test.label.two"], "2")
1968+
})
1969+
})
19421970
}
19431971

19441972
func assertImageHasBPLayer(t *testing.T, image *fakes.Image, bp buildpack.BuildModule) {

internal/commands/builder_create.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ type BuilderCreateFlags struct {
2323
Registry string
2424
Policy string
2525
Flatten []string
26+
Label map[string]string
2627
}
2728

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

117120
AddHelpFlag(cmd, "create")
118121
return cmd

internal/commands/builder_create_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,5 +424,22 @@ func testCreateCommand(t *testing.T, when spec.G, it spec.S) {
424424
})
425425
})
426426
})
427+
428+
when("--label", func() {
429+
when("can not be parsed", func() {
430+
it("errors with a descriptive message", func() {
431+
cmd := packageCommand()
432+
cmd.SetArgs([]string{
433+
"some/builder",
434+
"--config", builderConfigPath,
435+
"--label", "name+value",
436+
})
437+
438+
err := cmd.Execute()
439+
h.AssertNotNil(t, err)
440+
h.AssertError(t, err, "invalid argument \"name+value\" for \"-l, --label\" flag: name+value must be formatted as key=value")
441+
})
442+
})
443+
})
427444
})
428445
}

pkg/client/create_builder.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ type CreateBuilderOptions struct {
3232
// BuildConfigEnv for Builder
3333
BuildConfigEnv map[string]string
3434

35+
// Map of labels to add to the Buildpack
36+
Labels map[string]string
37+
3538
// Configuration that defines the functionality a builder provides.
3639
Config pubbldr.Config
3740

@@ -154,6 +157,10 @@ func (c *Client) createBaseBuilder(ctx context.Context, opts CreateBuilderOption
154157
if opts.Flatten != nil && len(opts.Flatten.FlattenModules()) > 0 {
155158
builderOpts = append(builderOpts, builder.WithFlattened(opts.Flatten))
156159
}
160+
if opts.Labels != nil && len(opts.Labels) > 0 {
161+
builderOpts = append(builderOpts, builder.WithLabels(opts.Labels))
162+
}
163+
157164
bldr, err := builder.New(baseImage, opts.BuilderName, builderOpts...)
158165
if err != nil {
159166
return nil, errors.Wrap(err, "invalid build-image")

pkg/client/create_builder_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,20 @@ func testCreateBuilder(t *testing.T, when spec.G, it spec.S) {
791791
h.AssertNotContains(t, out.String(), "is using deprecated Buildpacks API version")
792792
})
793793

794+
it("should set labels", func() {
795+
opts.Labels = map[string]string{"test.label.one": "1", "test.label.two": "2"}
796+
prepareFetcherWithBuildImage()
797+
prepareFetcherWithRunImages()
798+
799+
err := subject.CreateBuilder(context.TODO(), opts)
800+
h.AssertNil(t, err)
801+
802+
imageLabels, err := fakeBuildImage.Labels()
803+
h.AssertNil(t, err)
804+
h.AssertEq(t, imageLabels["test.label.one"], "1")
805+
h.AssertEq(t, imageLabels["test.label.two"], "2")
806+
})
807+
794808
when("Buildpack dependencies are provided", func() {
795809
var (
796810
bp1v1 buildpack.BuildModule

0 commit comments

Comments
 (0)