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:
parent
c1d2e6ad16
commit
0de06c6207
@ -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)
|
||||
|
@ -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"},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -1,3 +1,5 @@
|
||||
general:
|
||||
verbose: true
|
||||
steps:
|
||||
cnbBuild:
|
||||
buildEnvVars:
|
||||
|
33
pkg/cnbutils/report.go
Normal file
33
pkg/cnbutils/report.go
Normal 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
|
||||
}
|
48
pkg/cnbutils/report_test.go
Normal file
48
pkg/cnbutils/report_test.go
Normal 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")
|
||||
})
|
||||
}
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user