Skip to content

Commit 3b5ec5f

Browse files
Merge pull request buildpacks-community#1533 from buildpacks-community/relocated-run-image
Relocate the run image to the builder repo
2 parents 3ea5cba + 948eb18 commit 3b5ec5f

9 files changed

Lines changed: 483 additions & 86 deletions

File tree

pkg/cnb/builder_builder.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ func newBuilderBldr(kpackVersion string) *builderBlder {
6060
kpackVersion: kpackVersion,
6161
}
6262
}
63-
6463
func (bb *builderBlder) AddStack(baseImage v1.Image, clusterStack *buildapi.ClusterStack) error {
6564
file, err := baseImage.ConfigFile()
6665
if err != nil {
@@ -70,7 +69,6 @@ func (bb *builderBlder) AddStack(baseImage v1.Image, clusterStack *buildapi.Clus
7069
bb.os = file.OS
7170
bb.baseImage = baseImage
7271
bb.stackId = clusterStack.Status.Id
73-
bb.runImage = clusterStack.Status.RunImage.Image
7472
bb.mixins = clusterStack.Status.Mixins
7573
bb.cnbUserId = clusterStack.Status.UserID
7674
bb.cnbGroupId = clusterStack.Status.GroupID
@@ -183,6 +181,10 @@ func (bb *builderBlder) WriteableImage() (v1.Image, error) {
183181
})
184182
}
185183

184+
func (bb *builderBlder) AddRunImage(runImage string) {
185+
bb.runImage = runImage
186+
}
187+
186188
func (bb *builderBlder) validateBuilder(sortedBuildpacks []DescriptiveBuildpackInfo) error {
187189
platformApis := append(bb.LifecycleMetadata.APIs.Platform.Deprecated, bb.LifecycleMetadata.APIs.Platform.Supported...)
188190
err := validatePlatformApis(platformApis)

pkg/cnb/create_builder.go

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ package cnb
22

33
import (
44
"context"
5+
"fmt"
56

67
"github.com/google/go-containerregistry/pkg/authn"
78
ggcrv1 "github.com/google/go-containerregistry/pkg/v1"
8-
"github.com/pivotal/kpack/pkg/cosign"
99
corev1 "k8s.io/api/core/v1"
1010

1111
buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2"
1212
corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1"
13+
"github.com/pivotal/kpack/pkg/cosign"
1314
"github.com/pivotal/kpack/pkg/registry"
1415
)
1516

@@ -30,15 +31,34 @@ type RemoteBuilderCreator struct {
3031
ImageSigner cosign.BuilderSigner
3132
}
3233

33-
func (r *RemoteBuilderCreator) CreateBuilder(ctx context.Context, builderKeychain authn.Keychain, stackKeychain authn.Keychain, fetcher RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec, serviceAccountSecrets []*corev1.Secret) (buildapi.BuilderRecord, error) {
34-
buildImage, _, err := r.RegistryClient.Fetch(stackKeychain, clusterStack.Status.BuildImage.LatestImage)
34+
func (r *RemoteBuilderCreator) CreateBuilder(
35+
ctx context.Context,
36+
builderKeychain authn.Keychain,
37+
stackKeychain authn.Keychain,
38+
fetcher RemoteBuildpackFetcher,
39+
clusterStack *buildapi.ClusterStack,
40+
spec buildapi.BuilderSpec,
41+
serviceAccountSecrets []*corev1.Secret,
42+
resolvedBuilderRef string,
43+
) (buildapi.BuilderRecord, error) {
3544

45+
buildImage, _, err := r.RegistryClient.Fetch(stackKeychain, clusterStack.Status.BuildImage.LatestImage)
46+
if err != nil {
47+
return buildapi.BuilderRecord{}, err
48+
}
49+
runImage, _, err := r.RegistryClient.Fetch(stackKeychain, clusterStack.Status.RunImage.LatestImage)
3650
if err != nil {
3751
return buildapi.BuilderRecord{}, err
3852
}
3953

4054
builderBldr := newBuilderBldr(r.KpackVersion)
4155

56+
relocatedRunImage, err := r.RegistryClient.Save(builderKeychain, fmt.Sprintf("%s-run-image", resolvedBuilderRef), runImage)
57+
if err != nil {
58+
return buildapi.BuilderRecord{}, err
59+
}
60+
builderBldr.AddRunImage(relocatedRunImage)
61+
4262
err = builderBldr.AddStack(buildImage, clusterStack)
4363
if err != nil {
4464
return buildapi.BuilderRecord{}, err
@@ -72,7 +92,7 @@ func (r *RemoteBuilderCreator) CreateBuilder(ctx context.Context, builderKeychai
7292
return buildapi.BuilderRecord{}, err
7393
}
7494

75-
identifier, err := r.RegistryClient.Save(builderKeychain, spec.Tag, writeableImage)
95+
identifier, err := r.RegistryClient.Save(builderKeychain, resolvedBuilderRef, writeableImage)
7696
if err != nil {
7797
return buildapi.BuilderRecord{}, err
7898
}
@@ -96,7 +116,7 @@ func (r *RemoteBuilderCreator) CreateBuilder(ctx context.Context, builderKeychai
96116
builder := buildapi.BuilderRecord{
97117
Image: identifier,
98118
Stack: corev1alpha1.BuildStack{
99-
RunImage: clusterStack.Status.RunImage.LatestImage,
119+
RunImage: relocatedRunImage,
100120
ID: clusterStack.Status.Id,
101121
},
102122
Buildpacks: buildpackMetadata(builderBldr.buildpacks()),

pkg/cnb/create_builder_test.go

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
4141
const (
4242
stackID = "io.buildpacks.stacks.some-stack"
4343
mixin = "some-mixin"
44-
tag = "custom/example"
44+
builderTag = "custom/example:test-builder"
4545
buildImage = "index.docker.io/paketo-buildpacks/build@sha256:d19308ce0c1a9ec083432b2c850d615398f0c6a51095d589d58890a721925584"
46-
runImage = "index.docker.io/paketo-buildpacks/run@sha256:469f092c28ab64c6798d6f5e24feb4252ae5b36c2ed79cc667ded85ffb49d996"
46+
relocatedRunImageTag = "custom/example:test-builder-run-image"
4747
buildImageTag = "paketo-buildpacks/build:full-cnb"
4848
runImageTag = "paketo-buildpacks/run:full-cnb"
4949
buildImageLayers = 10
@@ -60,8 +60,10 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
6060
builderKeychain = authn.NewMultiKeychain(authn.DefaultKeychain)
6161
stackKeychain = authn.NewMultiKeychain(authn.DefaultKeychain)
6262
secretRef = registry.SecretRef{}
63-
64-
ctx = context.Background()
63+
runImage = createRunImage(os)
64+
runImageDigest = digest(runImage)
65+
runImageRef = fmt.Sprintf("%s@%s", runImageTag, runImageDigest)
66+
ctx = context.Background()
6567

6668
fetcher = &fakeFetcher{buildpacks: map[string][]buildpackLayer{}, observedGeneration: 10}
6769

@@ -117,7 +119,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
117119
Image: buildImageTag,
118120
},
119121
RunImage: buildapi.ClusterStackStatusImage{
120-
LatestImage: runImage,
122+
LatestImage: runImageRef,
121123
Image: runImageTag,
122124
},
123125
Mixins: []string{"some-unused-mixin", mixin, "common-mixin", "build:another-common-mixin", "run:another-common-mixin"},
@@ -128,7 +130,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
128130
}
129131

130132
clusterBuilderSpec = buildapi.BuilderSpec{
131-
Tag: "custom/example",
133+
Tag: builderTag,
132134
Stack: corev1.ObjectReference{
133135
Kind: "stack",
134136
Name: "some-stack",
@@ -309,7 +311,8 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
309311
fetcher.AddBuildpack(t, "io.buildpack.4", "v4", []buildpackLayer{buildpackWithDuplicatLayer})
310312
})
311313

312-
registryClient.AddSaveKeychain("custom/example", builderKeychain)
314+
registryClient.AddSaveKeychain(builderTag, builderKeychain)
315+
registryClient.AddImage(runImageRef, runImage, stackKeychain)
313316

314317
when("CreateBuilder", func() {
315318
var (
@@ -355,16 +358,16 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
355358
}
356359
})
357360

358-
it("creates a custom builder", func() {
359-
builderRecord, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{})
361+
it("creates a custom builder with a relocated run image", func() {
362+
builderRecord, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{}, builderTag)
360363
require.NoError(t, err)
361364

362365
assert.Len(t, builderRecord.Buildpacks, 4)
363366
assert.Contains(t, builderRecord.Buildpacks, corev1alpha1.BuildpackMetadata{Id: "io.buildpack.1", Version: "v1", Homepage: "buildpack.1.com"})
364367
assert.Contains(t, builderRecord.Buildpacks, corev1alpha1.BuildpackMetadata{Id: "io.buildpack.2", Version: "v2", Homepage: "buildpack.2.com"})
365368
assert.Contains(t, builderRecord.Buildpacks, corev1alpha1.BuildpackMetadata{Id: "io.buildpack.3", Version: "v3", Homepage: "buildpack.3.com"})
366369
assert.Contains(t, builderRecord.Buildpacks, corev1alpha1.BuildpackMetadata{Id: "io.buildpack.4", Version: "v4", Homepage: "buildpack.4.com"})
367-
assert.Equal(t, corev1alpha1.BuildStack{RunImage: runImage, ID: stackID}, builderRecord.Stack)
370+
assert.Equal(t, corev1alpha1.BuildStack{RunImage: fmt.Sprintf("%s@%s", relocatedRunImageTag, runImageDigest), ID: stackID}, builderRecord.Stack)
368371
assert.Equal(t, int64(10), builderRecord.ObservedStoreGeneration)
369372
assert.Equal(t, int64(11), builderRecord.ObservedStackGeneration)
370373
assert.Equal(t, os, builderRecord.OS)
@@ -388,16 +391,20 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
388391
},
389392
})
390393

391-
assert.Len(t, registryClient.SavedImages(), 1)
392-
savedImage := registryClient.SavedImages()[tag]
394+
assert.Len(t, registryClient.SavedImages(), 2)
395+
savedImage := registryClient.SavedImages()[builderTag]
396+
require.Contains(t, registryClient.SavedImages(), relocatedRunImageTag)
397+
digest, err := registryClient.SavedImages()[relocatedRunImageTag].Digest()
398+
require.NoError(t, err)
399+
require.Equal(t, digest.String(), runImageDigest)
393400

394401
workingDir, err := imagehelpers.GetWorkingDir(savedImage)
395402
require.NoError(t, err)
396403
assert.Equal(t, "/layers", workingDir)
397404

398405
hash, err := savedImage.Digest()
399406
require.NoError(t, err)
400-
assert.Equal(t, fmt.Sprintf("%s@%s", tag, hash), builderRecord.Image)
407+
assert.Equal(t, fmt.Sprintf("%s@%s", builderTag, hash), builderRecord.Image)
401408

402409
layers, err := savedImage.Layers()
403410
require.NoError(t, err)
@@ -487,9 +494,9 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
487494
typeflag: tar.TypeReg,
488495
mode: 0644,
489496
fileContent: //language=toml
490-
`[run-image]
491-
image = "paketo-buildpacks/run:full-cnb"
492-
`,
497+
fmt.Sprintf(`[run-image]
498+
image = "%s@%s"
499+
`, relocatedRunImageTag, runImageDigest),
493500
},
494501
})
495502
})
@@ -528,11 +535,11 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
528535
buildpackMetadata, err := imagehelpers.GetStringLabel(savedImage, buildpackMetadataLabel)
529536
assert.NoError(t, err)
530537
assert.JSONEq(t, //language=json
531-
`{
538+
fmt.Sprintf(`{
532539
"description": "Custom Builder built with kpack",
533540
"stack": {
534541
"runImage": {
535-
"image": "paketo-buildpacks/run:full-cnb",
542+
"image": "%s@%s",
536543
"mirrors": null
537544
}
538545
},
@@ -579,7 +586,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
579586
"homepage": "buildpack.1.com"
580587
}
581588
]
582-
}`, buildpackMetadata)
589+
}`, relocatedRunImageTag, runImageDigest), buildpackMetadata)
583590

584591
buildpackLayers, err := imagehelpers.GetStringLabel(savedImage, buildpackLayersLabel)
585592
assert.NoError(t, err)
@@ -653,11 +660,11 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
653660
})
654661

655662
it("creates images deterministically ", func() {
656-
original, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{})
663+
original, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{}, builderTag)
657664
require.NoError(t, err)
658665

659666
for i := 1; i <= 50; i++ {
660-
other, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{})
667+
other, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{}, builderTag)
661668

662669
require.NoError(t, err)
663670

@@ -688,7 +695,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
688695
},
689696
}
690697

691-
_, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{})
698+
_, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{}, builderTag)
692699
require.EqualError(t, err, "validating buildpack io.buildpack.unsupported.stack@v4: stack io.buildpacks.stacks.some-stack is not supported")
693700
})
694701

@@ -712,7 +719,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
712719
}},
713720
}}
714721

715-
_, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{})
722+
_, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{}, builderTag)
716723
require.EqualError(t, err, "validating buildpack io.buildpack.unsupported.mixin@v4: stack missing mixin(s): something-missing-mixin, something-missing-mixin2")
717724
})
718725

@@ -757,7 +764,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
757764
}},
758765
}}
759766

760-
_, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{})
767+
_, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{}, builderTag)
761768
require.Nil(t, err)
762769
})
763770

@@ -782,7 +789,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
782789
}},
783790
}}
784791

785-
_, err := subject.CreateBuilder(ctx, builderKeychain, nil, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{})
792+
_, err := subject.CreateBuilder(ctx, builderKeychain, nil, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{}, builderTag)
786793
require.Error(t, err, "validating buildpack io.buildpack.relaxed.old.mixin@v4: stack missing mixin(s): build:common-mixin, run:common-mixin, another-common-mixin")
787794
})
788795

@@ -805,7 +812,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
805812
}},
806813
}}
807814

808-
_, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{})
815+
_, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{}, builderTag)
809816
require.EqualError(t, err, "validating buildpack io.buildpack.unsupported.buildpack.api@v4: unsupported buildpack api: 0.1, expecting: 0.2, 0.3")
810817
})
811818

@@ -848,7 +855,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
848855
}},
849856
}}
850857

851-
_, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{})
858+
_, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{}, builderTag)
852859
require.NoError(t, err)
853860
})
854861
})
@@ -875,14 +882,14 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
875882
},
876883
}
877884

878-
_, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{})
885+
_, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{}, builderTag)
879886
require.EqualError(t, err, "unsupported platform apis in kpack lifecycle: 0.1, 0.2, 0.999, expecting one of: 0.3, 0.4, 0.5, 0.6, 0.7, 0.8")
880887
})
881888
})
882889

883890
when("signing a builder image", func() {
884891
it("does not populate the signature paths when no secrets were present", func() {
885-
builderRecord, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{})
892+
builderRecord, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{}, builderTag)
886893
require.NoError(t, err)
887894
require.NotNil(t, builderRecord)
888895
require.Empty(t, builderRecord.SignaturePaths)
@@ -902,7 +909,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
902909
},
903910
}
904911

905-
_, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{&fakeSecret})
912+
_, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{&fakeSecret}, builderTag)
906913
require.Error(t, err)
907914
})
908915

@@ -925,7 +932,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) {
925932
},
926933
}
927934

928-
builderRecord, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{&fakeSecret})
935+
builderRecord, err := subject.CreateBuilder(ctx, builderKeychain, stackKeychain, fetcher, stack, clusterBuilderSpec, []*corev1.Secret{&fakeSecret}, builderTag)
929936
require.NoError(t, err)
930937
require.NotNil(t, builderRecord)
931938
require.NotEmpty(t, builderRecord.SignaturePaths)
@@ -1073,3 +1080,19 @@ func layerToRemoteBuildpack(bpLayer buildpackLayer, layer *fakeLayer, secretRef
10731080
SecretRef: secretRef,
10741081
}
10751082
}
1083+
1084+
func createRunImage(os string) v1.Image {
1085+
runImg, _ := random.Image(1, int64(5))
1086+
1087+
config, _ := runImg.ConfigFile()
1088+
1089+
config.OS = os
1090+
runImg, _ = mutate.ConfigFile(runImg, config)
1091+
1092+
return runImg
1093+
}
1094+
1095+
func digest(image v1.Image) string {
1096+
d, _ := image.Digest()
1097+
return d.String()
1098+
}

0 commit comments

Comments
 (0)