Skip to content

Commit

Permalink
Adds the ability to add additional labels to stacks at build time
Browse files Browse the repository at this point in the history
  • Loading branch information
ForestEckhardt committed Aug 17, 2023
1 parent a255494 commit 5010715
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 0 deletions.
4 changes: 4 additions & 0 deletions commands/create_stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type createStackFlags struct {
publish bool
buildReference string
runReference string
labels []string
}

func createStack() *cobra.Command {
Expand All @@ -43,6 +44,7 @@ func createStack() *cobra.Command {
cmd.Flags().BoolVar(&flags.publish, "publish", false, "publish to a registry")
cmd.Flags().StringVar(&flags.buildReference, "build-ref", "", "reference that specifies where to publish the build image (required)")
cmd.Flags().StringVar(&flags.runReference, "run-ref", "", "reference that specifies where to publish the run image (required)")
cmd.Flags().StringSliceVar(&flags.labels, "label", nil, "additional image label to be added to build and run image")

err := cmd.MarkFlagRequired("config")
if err != nil {
Expand Down Expand Up @@ -78,6 +80,8 @@ func createStackRun(flags createStackFlags) error {

_, definition.IncludeExperimentalSBOM = os.LookupEnv("EXPERIMENTAL_ATTACH_RUN_IMAGE_SBOM")

definition.Labels = flags.labels

scratch, err := os.MkdirTemp("", "")
if err != nil {
return err
Expand Down
7 changes: 7 additions & 0 deletions integration/create_stack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func testCreateStack(t *testing.T, _ spec.G, it spec.S) {
"--build-output", filepath.Join(tmpDir, "build.oci"),
"--run-output", filepath.Join(tmpDir, "run.oci"),
"--secret", "some-secret=my-secret-value",
"--label", "additional.label=label-value",
)
command.Env = append(os.Environ(), "EXPERIMENTAL_ATTACH_RUN_IMAGE_SBOM=true")
session, err := gexec.Start(command, buffer, buffer)
Expand Down Expand Up @@ -116,6 +117,7 @@ func testCreateStack(t *testing.T, _ spec.G, it spec.S) {
HaveKeyWithValue("io.buildpacks.stack.mixins", ContainSubstring(`"build:git"`)),
HaveKeyWithValue("io.paketo.stack.packages", ContainSubstring(`"openssl"`)),
HaveKeyWithValue("platform", "amd64"),
HaveKeyWithValue("additional.label", "label-value"),
))

Expect(file.Config.Labels).NotTo(HaveKeyWithValue("io.buildpacks.stack.mixins", ContainSubstring("run:")))
Expand Down Expand Up @@ -189,6 +191,7 @@ func testCreateStack(t *testing.T, _ spec.G, it spec.S) {
HaveKeyWithValue("io.buildpacks.stack.mixins", ContainSubstring(`"openssl"`)),
HaveKeyWithValue("io.paketo.stack.packages", ContainSubstring(`"openssl"`)),
HaveKeyWithValue("io.buildpacks.base.sbom", file.RootFS.DiffIDs[len(file.RootFS.DiffIDs)-1].String()),
HaveKeyWithValue("additional.label", "label-value"),
))

Expect(file.Config.Labels).NotTo(HaveKeyWithValue("io.buildpacks.stack.mixins", ContainSubstring("build:")))
Expand Down Expand Up @@ -241,11 +244,13 @@ func testCreateStack(t *testing.T, _ spec.G, it spec.S) {
" Adding io.buildpacks.stack.* labels",
" Adding io.buildpacks.stack.mixins label",
" Adding io.paketo.stack.packages label",
" Adding additional.label label",
" Creating cnb user",
" run: Decorating base image",
" Adding io.buildpacks.stack.* labels",
" Adding io.buildpacks.stack.mixins label",
" Adding io.paketo.stack.packages label",
" Adding additional.label label",
" Creating cnb user",
" Updating /etc/os-release",
" Attaching experimental SBOM",
Expand All @@ -260,11 +265,13 @@ func testCreateStack(t *testing.T, _ spec.G, it spec.S) {
" Adding io.buildpacks.stack.* labels",
" Adding io.buildpacks.stack.mixins label",
" Adding io.paketo.stack.packages label",
" Adding additional.label label",
" Creating cnb user",
" run: Decorating base image",
" Adding io.buildpacks.stack.* labels",
" Adding io.buildpacks.stack.mixins label",
" Adding io.paketo.stack.packages label",
" Adding additional.label label",
" Creating cnb user",
" Updating /etc/os-release",
" Attaching experimental SBOM",
Expand Down
12 changes: 12 additions & 0 deletions internal/ihop/creator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ihop
import (
"encoding/json"
"fmt"
"strings"
"time"

"github.com/paketo-buildpacks/packit/v2/scribe"
Expand Down Expand Up @@ -202,6 +203,17 @@ func (c Creator) mutate(image Image, def Definition, imageDef DefinitionImage, s
}
}

for _, label := range def.Labels {
kv := strings.Split(label, "=")
if len(kv) != 2 {
return Image{}, fmt.Errorf("label input %q malformed: should be in the form of <label-name>=<label-value>", label)
}

c.logger.Action("Adding %s label", kv[0])

image.Labels[kv[0]] = kv[1]
}

// create and attach a layer that creates a cnb user in the container image
// filesystem
c.logger.Action("Creating cnb user")
Expand Down
42 changes: 42 additions & 0 deletions internal/ihop/creator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,48 @@ func testCreator(t *testing.T, context spec.G, it spec.S) {
})
})

context("when additional labels are given", func() {
it("adds those labels to the build and run image", func() {
_, err := creator.Execute(ihop.Definition{
ID: "some-stack-id",
Homepage: "some-stack-homepage",
Maintainer: "some-stack-maintainer",
Platforms: []string{"some-platform"},
IncludeExperimentalSBOM: true,
Build: ihop.DefinitionImage{
Description: "some-stack-build-description",
Dockerfile: "test-base-build-dockerfile-path",
Args: map[string]any{
"sources": "test-sources",
"packages": "test-build-packages",
},
UID: 1234,
GID: 2345,
},
Run: ihop.DefinitionImage{
Description: "some-stack-run-description",
Dockerfile: "test-base-run-dockerfile-path",
Args: map[string]any{
"sources": "test-sources",
"packages": "test-run-packages",
},
UID: 3456,
GID: 4567,
},
Labels: []string{"additional.label=label-value"},
})
Expect(err).NotTo(HaveOccurred())

Expect(imageClient.UpdateCall.CallCount).To(Equal(2))

Expect(imageUpdateInvocations[0].Image.Digest).To(Equal("image-digest-1"))
Expect(imageUpdateInvocations[0].Image.Labels).To(HaveKeyWithValue("additional.label", "label-value"))

Expect(imageUpdateInvocations[1].Image.Digest).To(Equal("image-digest-2"))
Expect(imageUpdateInvocations[1].Image.Labels).To(HaveKeyWithValue("additional.label", "label-value"))
})
})

context("failure cases", func() {
context("when the build image promise errors", func() {
it.Before(func() {
Expand Down
3 changes: 3 additions & 0 deletions internal/ihop/definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ type Definition struct {
// IncludeExperimentalSBOM can be used to attach an experimental SBOM layer
// to the run image.
IncludeExperimentalSBOM bool `toml:"-"`

// Labels can be used to add custom labels to the build and run image.
Labels []string `toml:"-"`
}

type DefinitionImagePlatforms struct {
Expand Down

0 comments on commit 5010715

Please sign in to comment.