1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-12 10:55:20 +02:00

feat(cnbBuild): write image digests to the CPE (#3602)

Co-authored-by: Johannes Dillmann <j.dillmann@sap.com>
This commit is contained in:
Pavel Busko 2022-03-02 16:26:45 +01:00 committed by GitHub
parent c1d2e6ad16
commit 0de06c6207
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 112 additions and 2 deletions

View File

@ -19,6 +19,7 @@ import (
piperhttp "github.com/SAP/jenkins-library/pkg/http"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/piperutils"
"github.com/SAP/jenkins-library/pkg/telemetry"
"github.com/imdario/mergo"
"github.com/mitchellh/mapstructure"
@ -554,6 +555,14 @@ func runCnbBuild(config *cnbBuildOptions, telemetryData *telemetry.CustomData, t
return errors.Wrapf(err, "execution of '%s' failed", creatorArgs)
}
digest, err := cnbutils.DigestFromReport(utils)
if err != nil {
log.SetErrorCategory(log.ErrorBuild)
return errors.Wrap(err, "failed to read image digest")
}
commonPipelineEnvironment.container.imageDigest = digest
commonPipelineEnvironment.container.imageDigests = append(commonPipelineEnvironment.container.imageDigests, digest)
if len(config.PreserveFiles) > 0 {
if pathType != pathEnumArchive {
err = cnbutils.CopyProject(target, source, ignore.CompileIgnoreLines(config.PreserveFiles...), nil, utils)

View File

@ -36,9 +36,11 @@ type cnbBuildOptions struct {
type cnbBuildCommonPipelineEnvironment struct {
container struct {
registryURL string
imageDigest string
imageNameTag string
imageNames []string
imageNameTags []string
imageDigests []string
}
}
@ -49,9 +51,11 @@ func (p *cnbBuildCommonPipelineEnvironment) persist(path, resourceName string) {
value interface{}
}{
{category: "container", name: "registryUrl", value: p.container.registryURL},
{category: "container", name: "imageDigest", value: p.container.imageDigest},
{category: "container", name: "imageNameTag", value: p.container.imageNameTag},
{category: "container", name: "imageNames", value: p.container.imageNames},
{category: "container", name: "imageNameTags", value: p.container.imageNameTags},
{category: "container", name: "imageDigests", value: p.container.imageDigests},
}
errCount := 0
@ -348,9 +352,11 @@ func cnbBuildMetadata() config.StepData {
Type: "piperEnvironment",
Parameters: []map[string]interface{}{
{"name": "container/registryUrl"},
{"name": "container/imageDigest"},
{"name": "container/imageNameTag"},
{"name": "container/imageNames", "type": "[]string"},
{"name": "container/imageNameTags", "type": "[]string"},
{"name": "container/imageDigests", "type": "[]string"},
},
},
},

View File

@ -23,6 +23,11 @@ func newCnbBuildTestsUtils() cnbutils.MockUtils {
ExecMockRunner: &mock.ExecMockRunner{},
FilesMock: &mock.FilesMock{},
}
utils.AddFile("/layers/report.toml", []byte(`[build]
[image]
tags = ["localhost:5000/not-found:0.0.1"]
digest = "sha256:52eac630560210e5ae13eb10797c4246d6f02d425f32b9430ca00bde697c79ec"
manifest-size = 2388`))
return utils
}
@ -101,6 +106,9 @@ func TestRunCnbBuild(t *testing.T) {
assert.Equal(t, config.ContainerRegistryURL, commonPipelineEnvironment.container.registryURL)
assert.Equal(t, "io-buildpacks-my-app:0.0.1", commonPipelineEnvironment.container.imageNameTag)
assert.Equal(t, "sha256:52eac630560210e5ae13eb10797c4246d6f02d425f32b9430ca00bde697c79ec", commonPipelineEnvironment.container.imageDigest)
assert.Contains(t, commonPipelineEnvironment.container.imageDigests, "sha256:52eac630560210e5ae13eb10797c4246d6f02d425f32b9430ca00bde697c79ec")
customDataAsString := telemetryData.Custom1
customData := cnbBuildTelemetry{}
err = json.Unmarshal([]byte(customDataAsString), &customData)
@ -539,6 +547,7 @@ uri = "some-buildpack"
customDataAsString := telemetryData.Custom1
customData := cnbBuildTelemetry{}
err = json.Unmarshal([]byte(customDataAsString), &customData)
assert.NoError(t, err)
require.Equal(t, expectedImageCount, len(customData.Data))
runner := utils.ExecMockRunner

View File

@ -44,8 +44,8 @@ func TestNpmProject(t *testing.T) {
Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()),
})
container.whenRunningPiperCommand("cnbBuild", "--customConfig", "TestCnbIntegration/config_env.yml", "--path", "TestMtaIntegration/npm", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL)
err := container.whenRunningPiperCommand("cnbBuild", "--customConfig", "TestCnbIntegration/config_env.yml", "--path", "TestMtaIntegration/npm", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL)
assert.NoError(t, err)
container.assertHasOutput(t, "running command: /cnb/lifecycle/creator")
container.assertHasOutput(t, "Selected Node Engine version (using BP_NODE_VERSION): 16")
container.assertHasOutput(t, "Paketo NPM Start Buildpack")

View File

@ -1,3 +1,5 @@
general:
verbose: true
steps:
cnbBuild:
buildEnvVars:

33
pkg/cnbutils/report.go Normal file
View File

@ -0,0 +1,33 @@
package cnbutils
import (
"fmt"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/buildpacks/lifecycle/platform"
"github.com/pelletier/go-toml"
)
const reportFile = "/layers/report.toml"
func DigestFromReport(utils BuildUtils) (string, error) {
report := platform.ExportReport{}
data, err := utils.FileRead(reportFile)
if err != nil {
return "", err
}
err = toml.Unmarshal(data, &report)
if err != nil {
return "", err
}
log.Entry().Debugf("Image report: %#v\n", report)
if report.Image.Digest == "" {
return "", fmt.Errorf("image digest is empty")
}
return report.Image.Digest, nil
}

View File

@ -0,0 +1,48 @@
package cnbutils_test
import (
"testing"
"github.com/SAP/jenkins-library/pkg/cnbutils"
"github.com/SAP/jenkins-library/pkg/mock"
"github.com/stretchr/testify/assert"
)
func TestDigestFromReport(t *testing.T) {
t.Run("return a digest from the report.toml", func(t *testing.T) {
mockUtils := &cnbutils.MockUtils{
FilesMock: &mock.FilesMock{},
}
mockUtils.AddFile("/layers/report.toml", []byte(`[build]
[image]
digest = "sha256:52eac630560210e5ae13eb10797c4246d6f02d425f32b9430ca00bde697c79ec"
`))
digest, err := cnbutils.DigestFromReport(mockUtils)
assert.NoError(t, err)
assert.Equal(t, "sha256:52eac630560210e5ae13eb10797c4246d6f02d425f32b9430ca00bde697c79ec", digest)
})
t.Run("fails if digest is empty", func(t *testing.T) {
mockUtils := &cnbutils.MockUtils{
ExecMockRunner: &mock.ExecMockRunner{},
FilesMock: &mock.FilesMock{},
}
mockUtils.AddFile("/layers/report.toml", []byte(``))
digest, err := cnbutils.DigestFromReport(mockUtils)
assert.Empty(t, digest)
assert.EqualError(t, err, "image digest is empty")
})
t.Run("fails to unmarshal corrupted file", func(t *testing.T) {
mockUtils := &cnbutils.MockUtils{
ExecMockRunner: &mock.ExecMockRunner{},
FilesMock: &mock.FilesMock{},
}
mockUtils.AddFile("/layers/report.toml", []byte(`{}`))
digest, err := cnbutils.DigestFromReport(mockUtils)
assert.Empty(t, digest)
assert.EqualError(t, err, "(1, 1): parsing error: keys cannot contain { character")
})
}

View File

@ -236,10 +236,13 @@ spec:
type: piperEnvironment
params:
- name: container/registryUrl
- name: container/imageDigest
- name: container/imageNameTag
- name: container/imageNames
type: "[]string"
- name: container/imageNameTags
type: "[]string"
- name: container/imageDigests
type: "[]string"
containers:
- image: "paketobuildpacks/builder:full"