You've already forked sap-jenkins-library
mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-11-06 09:09:19 +02:00
feat(cnbBuild): remove docker config after parsing (#3417)
Co-authored-by: Philipp Stehle <philipp.stehle@sap.com>
This commit is contained in:
@@ -2,7 +2,6 @@ package cmd
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
@@ -21,7 +20,6 @@ import (
|
||||
"github.com/SAP/jenkins-library/pkg/log"
|
||||
"github.com/SAP/jenkins-library/pkg/piperutils"
|
||||
"github.com/SAP/jenkins-library/pkg/telemetry"
|
||||
"github.com/docker/cli/cli/config/configfile"
|
||||
"github.com/pkg/errors"
|
||||
ignore "github.com/sabhiram/go-gitignore"
|
||||
)
|
||||
@@ -295,36 +293,12 @@ func runCnbBuild(config *cnbBuildOptions, telemetryData *telemetry.CustomData, u
|
||||
}
|
||||
|
||||
dockerConfigFile := ""
|
||||
dockerConfig := &configfile.ConfigFile{}
|
||||
dockerConfigJSON := []byte(`{"auths":{}}`)
|
||||
if len(config.DockerConfigJSON) > 0 {
|
||||
dockerConfigFile, err = prepareDockerConfig(config.DockerConfigJSON, utils)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorConfiguration)
|
||||
return errors.Wrapf(err, "failed to rename DockerConfigJSON file '%v'", config.DockerConfigJSON)
|
||||
}
|
||||
dockerConfigJSON, err = utils.FileRead(dockerConfigFile)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorConfiguration)
|
||||
return errors.Wrapf(err, "failed to read DockerConfigJSON file '%v'", config.DockerConfigJSON)
|
||||
}
|
||||
}
|
||||
|
||||
err = json.Unmarshal(dockerConfigJSON, dockerConfig)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorConfiguration)
|
||||
return errors.Wrapf(err, "failed to parse DockerConfigJSON file '%v'", config.DockerConfigJSON)
|
||||
}
|
||||
|
||||
auth := map[string]string{}
|
||||
for registry, value := range dockerConfig.AuthConfigs {
|
||||
auth[registry] = fmt.Sprintf("Basic %s", value.Auth)
|
||||
}
|
||||
|
||||
cnbRegistryAuth, err := json.Marshal(auth)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorConfiguration)
|
||||
return errors.Wrap(err, "failed to marshal DockerConfigJSON")
|
||||
}
|
||||
|
||||
target := "/workspace"
|
||||
@@ -374,6 +348,20 @@ func runCnbBuild(config *cnbBuildOptions, telemetryData *telemetry.CustomData, u
|
||||
}
|
||||
}
|
||||
|
||||
cnbRegistryAuth, err := cnbutils.GenerateCnbAuth(dockerConfigFile, utils)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorConfiguration)
|
||||
return errors.Wrap(err, "failed to generate CNB_REGISTRY_AUTH")
|
||||
}
|
||||
|
||||
if dockerConfigFile != "" {
|
||||
err = utils.FileRemove(dockerConfigFile)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorBuild)
|
||||
return errors.Wrap(err, "failed to remove docker config.json file")
|
||||
}
|
||||
}
|
||||
|
||||
if len(config.ContainerRegistryURL) == 0 || len(config.ContainerImageName) == 0 || len(config.ContainerImageTag) == 0 {
|
||||
log.SetErrorCategory(log.ErrorConfiguration)
|
||||
return errors.New("containerRegistryUrl, containerImageName and containerImageTag must be present")
|
||||
@@ -411,7 +399,7 @@ func runCnbBuild(config *cnbBuildOptions, telemetryData *telemetry.CustomData, u
|
||||
log.Entry().Info("skipping certificates update")
|
||||
}
|
||||
|
||||
utils.AppendEnv([]string{fmt.Sprintf("CNB_REGISTRY_AUTH=%s", string(cnbRegistryAuth))})
|
||||
utils.AppendEnv([]string{fmt.Sprintf("CNB_REGISTRY_AUTH=%s", cnbRegistryAuth)})
|
||||
utils.AppendEnv([]string{"CNB_PLATFORM_API=0.8"})
|
||||
|
||||
creatorArgs := []string{
|
||||
|
||||
@@ -17,7 +17,6 @@ func newCnbBuildTestsUtils() cnbutils.MockUtils {
|
||||
utils := cnbutils.MockUtils{
|
||||
ExecMockRunner: &mock.ExecMockRunner{},
|
||||
FilesMock: &mock.FilesMock{},
|
||||
DockerMock: &cnbutils.DockerMock{},
|
||||
}
|
||||
return utils
|
||||
}
|
||||
@@ -118,6 +117,12 @@ func TestRunCnbBuild(t *testing.T) {
|
||||
assert.Contains(t, runner.Calls[0].Params, "/tmp/buildpacks/order.toml")
|
||||
assert.Contains(t, runner.Calls[0].Params, fmt.Sprintf("%s/%s:%s", registry, config.ContainerImageName, config.ContainerImageTag))
|
||||
assert.Contains(t, runner.Calls[0].Params, fmt.Sprintf("%s/%s:latest", registry, config.ContainerImageName))
|
||||
|
||||
initialFileExists, _ := utils.FileExists("/path/to/test.json")
|
||||
renamedFileExists, _ := utils.FileExists("/path/to/config.json")
|
||||
|
||||
assert.False(t, initialFileExists)
|
||||
assert.False(t, renamedFileExists)
|
||||
})
|
||||
|
||||
t.Run("success case (customTlsCertificates)", func(t *testing.T) {
|
||||
@@ -200,7 +205,7 @@ func TestRunCnbBuild(t *testing.T) {
|
||||
addBuilderFiles(&utils)
|
||||
|
||||
err := runCnbBuild(&config, nil, &utils, &commonPipelineEnvironment, &piperhttp.Client{})
|
||||
assert.EqualError(t, err, "failed to parse DockerConfigJSON file '/path/to/config.json': json: cannot unmarshal string into Go struct field ConfigFile.auths of type types.AuthConfig")
|
||||
assert.EqualError(t, err, "failed to generate CNB_REGISTRY_AUTH: json: cannot unmarshal string into Go struct field ConfigFile.auths of type types.AuthConfig")
|
||||
})
|
||||
|
||||
t.Run("error case: DockerConfigJSON file not there (config.json)", func(t *testing.T) {
|
||||
@@ -215,7 +220,7 @@ func TestRunCnbBuild(t *testing.T) {
|
||||
addBuilderFiles(&utils)
|
||||
|
||||
err := runCnbBuild(&config, nil, &utils, &commonPipelineEnvironment, &piperhttp.Client{})
|
||||
assert.EqualError(t, err, "failed to read DockerConfigJSON file 'not-there/config.json': could not read 'not-there/config.json'")
|
||||
assert.EqualError(t, err, "failed to generate CNB_REGISTRY_AUTH: could not read 'not-there/config.json'")
|
||||
})
|
||||
|
||||
t.Run("error case: DockerConfigJSON file not there (not config.json)", func(t *testing.T) {
|
||||
|
||||
37
pkg/cnbutils/auth.go
Normal file
37
pkg/cnbutils/auth.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package cnbutils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/cli/cli/config/configfile"
|
||||
)
|
||||
|
||||
func GenerateCnbAuth(config string, utils BuildUtils) (string, error) {
|
||||
var err error
|
||||
dockerConfig := &configfile.ConfigFile{}
|
||||
|
||||
if config != "" {
|
||||
dockerConfigJSON, err := utils.FileRead(config)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(dockerConfigJSON, dockerConfig)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
auth := map[string]string{}
|
||||
for registry, value := range dockerConfig.AuthConfigs {
|
||||
auth[registry] = fmt.Sprintf("Basic %s", value.Auth)
|
||||
}
|
||||
|
||||
cnbRegistryAuth, err := json.Marshal(auth)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(cnbRegistryAuth), nil
|
||||
}
|
||||
42
pkg/cnbutils/auth_test.go
Normal file
42
pkg/cnbutils/auth_test.go
Normal file
@@ -0,0 +1,42 @@
|
||||
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 TestGenerateCnbAuth(t *testing.T) {
|
||||
var mockUtils = &cnbutils.MockUtils{
|
||||
ExecMockRunner: &mock.ExecMockRunner{},
|
||||
FilesMock: &mock.FilesMock{},
|
||||
}
|
||||
|
||||
t.Run("successfully generates cnb auth env variable", func(t *testing.T) {
|
||||
mockUtils.AddFile("/test/valid_config.json", []byte("{\"auths\":{\"example.com\":{\"username\":\"username\",\"password\":\"password\",\"auth\":\"dXNlcm5hbWU6cGFzc3dvcmQ=\"}}}"))
|
||||
auth, err := cnbutils.GenerateCnbAuth("/test/valid_config.json", mockUtils)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "{\"example.com\":\"Basic dXNlcm5hbWU6cGFzc3dvcmQ=\"}", auth)
|
||||
})
|
||||
|
||||
t.Run("successfully generates cnb auth env variable if docker config is not present", func(t *testing.T) {
|
||||
auth, err := cnbutils.GenerateCnbAuth("", mockUtils)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "{}", auth)
|
||||
})
|
||||
|
||||
t.Run("fails if file not found", func(t *testing.T) {
|
||||
_, err := cnbutils.GenerateCnbAuth("/not/found", mockUtils)
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "could not read '/not/found'", err.Error())
|
||||
})
|
||||
|
||||
t.Run("fails if file is invalid json", func(t *testing.T) {
|
||||
mockUtils.AddFile("/test/invalid_config.json", []byte("not a json"))
|
||||
_, err := cnbutils.GenerateCnbAuth("/test/invalid_config.json", mockUtils)
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "invalid character 'o' in literal null (expecting 'u')", err.Error())
|
||||
})
|
||||
}
|
||||
@@ -13,8 +13,8 @@ import (
|
||||
)
|
||||
|
||||
func TestProcessBindings(t *testing.T) {
|
||||
var mockUtils = func() cnbutils.MockUtils {
|
||||
var utils = cnbutils.MockUtils{
|
||||
var mockUtils = func() *cnbutils.MockUtils {
|
||||
var utils = &cnbutils.MockUtils{
|
||||
FilesMock: &mock.FilesMock{},
|
||||
}
|
||||
utils.AddFile("/tmp/somefile.yaml", []byte("some file content"))
|
||||
|
||||
@@ -1,35 +1,24 @@
|
||||
package cnbutils
|
||||
package cnbutils_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/SAP/jenkins-library/pkg/cnbutils"
|
||||
"github.com/SAP/jenkins-library/pkg/mock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var mockUtils = MockUtils{
|
||||
ExecMockRunner: &mock.ExecMockRunner{},
|
||||
FilesMock: &mock.FilesMock{},
|
||||
DockerMock: &DockerMock{},
|
||||
}
|
||||
|
||||
func TestBuildpackDownload(t *testing.T) {
|
||||
var mockUtils = &cnbutils.MockUtils{
|
||||
ExecMockRunner: &mock.ExecMockRunner{},
|
||||
FilesMock: &mock.FilesMock{},
|
||||
}
|
||||
|
||||
t.Run("successfully downloads a buildpack", func(t *testing.T) {
|
||||
mockUtils.AddDir("/tmp/testtest")
|
||||
_, err := DownloadBuildpacks("/test", []string{"test"}, "/test/config.json", mockUtils)
|
||||
_, err := cnbutils.DownloadBuildpacks("/test", []string{"test"}, "/test/config.json", mockUtils)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, mockUtils.HasRemovedFile("/tmp/testtest"))
|
||||
})
|
||||
}
|
||||
|
||||
func TestBuildpackCopy(t *testing.T) {
|
||||
t.Run("successfully downloads a buildpack", func(t *testing.T) {
|
||||
|
||||
mockUtils.AddDir("/src/buildpack/0.0.1")
|
||||
mockUtils.AddDir("/dst")
|
||||
err := copyBuildPack("/src", "/dst", mockUtils)
|
||||
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
package cnbutils
|
||||
package cnbutils_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/SAP/jenkins-library/pkg/cnbutils"
|
||||
"github.com/SAP/jenkins-library/pkg/mock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCreateEnvFiles(t *testing.T) {
|
||||
t.Run("successfully writes environment files", func(t *testing.T) {
|
||||
mockUtils := MockUtils{
|
||||
mockUtils := &cnbutils.MockUtils{
|
||||
FilesMock: &mock.FilesMock{},
|
||||
}
|
||||
|
||||
@@ -20,7 +21,7 @@ func TestCreateEnvFiles(t *testing.T) {
|
||||
"COMPLEX": "{\"foo\": \"bar=3\"}",
|
||||
}
|
||||
|
||||
err := CreateEnvFiles(mockUtils, "/tmp/platform", envVars)
|
||||
err := cnbutils.CreateEnvFiles(mockUtils, "/tmp/platform", envVars)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, mockUtils.HasWrittenFile("/tmp/platform/env/FOO"))
|
||||
@@ -41,7 +42,7 @@ func TestCreateEnvFiles(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("raises an error if unable to write to a file", func(t *testing.T) {
|
||||
mockUtils := MockUtils{
|
||||
mockUtils := &cnbutils.MockUtils{
|
||||
FilesMock: &mock.FilesMock{
|
||||
FileWriteErrors: map[string]error{
|
||||
"/tmp/platform/env/FOO": fmt.Errorf("unable to create dir"),
|
||||
@@ -49,7 +50,7 @@ func TestCreateEnvFiles(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := CreateEnvFiles(mockUtils, "/tmp/platform", map[string]interface{}{"FOO": "BAR"})
|
||||
err := cnbutils.CreateEnvFiles(mockUtils, "/tmp/platform", map[string]interface{}{"FOO": "BAR"})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, err.Error(), "unable to create dir")
|
||||
})
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
//go:build !release
|
||||
// +build !release
|
||||
|
||||
package cnbutils
|
||||
|
||||
import (
|
||||
"io"
|
||||
"path/filepath"
|
||||
|
||||
pkgutil "github.com/GoogleContainerTools/container-diff/pkg/util"
|
||||
"github.com/SAP/jenkins-library/pkg/docker"
|
||||
"github.com/SAP/jenkins-library/pkg/mock"
|
||||
"github.com/SAP/jenkins-library/pkg/piperutils"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
@@ -16,21 +17,13 @@ import (
|
||||
type MockUtils struct {
|
||||
*mock.ExecMockRunner
|
||||
*mock.FilesMock
|
||||
*DockerMock
|
||||
}
|
||||
|
||||
func (c *MockUtils) GetDockerClient() docker.Download {
|
||||
return c.DockerMock
|
||||
}
|
||||
|
||||
func (c *MockUtils) GetFileUtils() piperutils.FileUtils {
|
||||
return c.FilesMock
|
||||
}
|
||||
|
||||
type DockerMock struct{}
|
||||
|
||||
func (d *DockerMock) DownloadImageToPath(_, filePath string) (pkgutil.Image, error) {
|
||||
|
||||
func (c *MockUtils) DownloadImageToPath(bpack, filePath string) (pkgutil.Image, error) {
|
||||
fakeImage := fakeImage.FakeImage{}
|
||||
fakeImage.ConfigFileReturns(&v1.ConfigFile{
|
||||
Config: v1.Config{
|
||||
@@ -39,16 +32,19 @@ func (d *DockerMock) DownloadImageToPath(_, filePath string) (pkgutil.Image, err
|
||||
},
|
||||
},
|
||||
}, nil)
|
||||
|
||||
c.AddDir(filepath.Join(filePath, "cnb/buildpacks", bpack))
|
||||
c.AddDir(filepath.Join(filePath, "cnb/buildpacks", bpack, "0.0.1"))
|
||||
img := pkgutil.Image{
|
||||
Image: &fakeImage,
|
||||
}
|
||||
return img, nil
|
||||
}
|
||||
|
||||
func (d *DockerMock) GetImageSource() (string, error) {
|
||||
func (c *MockUtils) GetImageSource() (string, error) {
|
||||
return "imageSource", nil
|
||||
}
|
||||
|
||||
func (d *DockerMock) TarImage(writer io.Writer, image pkgutil.Image) error {
|
||||
func (c *MockUtils) TarImage(writer io.Writer, image pkgutil.Image) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
package cnbutils
|
||||
package cnbutils_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/SAP/jenkins-library/pkg/cnbutils"
|
||||
"github.com/SAP/jenkins-library/pkg/mock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestOrderSave(t *testing.T) {
|
||||
t.Run("successfully Encode struct to toml format (multiple buildpacks)", func(t *testing.T) {
|
||||
mockUtils := MockUtils{
|
||||
mockUtils := &cnbutils.MockUtils{
|
||||
ExecMockRunner: &mock.ExecMockRunner{},
|
||||
FilesMock: &mock.FilesMock{},
|
||||
DockerMock: &DockerMock{},
|
||||
}
|
||||
|
||||
testBuildpacks := []BuildPackMetadata{
|
||||
testBuildpacks := []cnbutils.BuildPackMetadata{
|
||||
{
|
||||
ID: "paketo-buildpacks/sap-machine",
|
||||
Version: "1.1.1",
|
||||
@@ -26,13 +26,13 @@ func TestOrderSave(t *testing.T) {
|
||||
Version: "2.2.2",
|
||||
},
|
||||
}
|
||||
testOrder := Order{
|
||||
testOrder := cnbutils.Order{
|
||||
Utils: mockUtils,
|
||||
}
|
||||
|
||||
var testEntry OrderEntry
|
||||
var testEntry cnbutils.OrderEntry
|
||||
testEntry.Group = append(testEntry.Group, testBuildpacks...)
|
||||
testOrder.Order = []OrderEntry{testEntry}
|
||||
testOrder.Order = []cnbutils.OrderEntry{testEntry}
|
||||
|
||||
err := testOrder.Save("/tmp/order.toml")
|
||||
|
||||
@@ -44,15 +44,14 @@ func TestOrderSave(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("raises an error if unable to write the file", func(t *testing.T) {
|
||||
mockUtils := MockUtils{
|
||||
mockUtils := &cnbutils.MockUtils{
|
||||
ExecMockRunner: &mock.ExecMockRunner{},
|
||||
FilesMock: &mock.FilesMock{},
|
||||
DockerMock: &DockerMock{},
|
||||
}
|
||||
mockUtils.FileWriteErrors = map[string]error{
|
||||
"/tmp/order.toml": fmt.Errorf("unable to write to file"),
|
||||
}
|
||||
testOrder := Order{
|
||||
testOrder := cnbutils.Order{
|
||||
Utils: mockUtils,
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ version = "5.9.1"
|
||||
[[build.buildpacks]]
|
||||
id = "paketo-buildpacks/nodejs"
|
||||
`
|
||||
utils := cnbutils.MockUtils{
|
||||
utils := &cnbutils.MockUtils{
|
||||
FilesMock: &mock.FilesMock{},
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ id = "test/inline"
|
||||
shell = "/bin/bash"
|
||||
inline = "date"
|
||||
`
|
||||
utils := cnbutils.MockUtils{
|
||||
utils := &cnbutils.MockUtils{
|
||||
FilesMock: &mock.FilesMock{},
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ exclude = [
|
||||
]
|
||||
`
|
||||
|
||||
utils := cnbutils.MockUtils{
|
||||
utils := &cnbutils.MockUtils{
|
||||
FilesMock: &mock.FilesMock{},
|
||||
}
|
||||
utils.AddFile("project.toml", []byte(projectToml))
|
||||
@@ -131,7 +131,7 @@ exclude = [
|
||||
})
|
||||
|
||||
t.Run("fails with file not found", func(t *testing.T) {
|
||||
utils := cnbutils.MockUtils{
|
||||
utils := &cnbutils.MockUtils{
|
||||
FilesMock: &mock.FilesMock{},
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ exclude = [
|
||||
|
||||
t.Run("fails to parse corrupted project.toml", func(t *testing.T) {
|
||||
projectToml := "test123"
|
||||
utils := cnbutils.MockUtils{
|
||||
utils := &cnbutils.MockUtils{
|
||||
FilesMock: &mock.FilesMock{},
|
||||
}
|
||||
utils.AddFile("project.toml", []byte(projectToml))
|
||||
|
||||
@@ -24,7 +24,7 @@ func TestWriteProjectMetadata(t *testing.T) {
|
||||
commit = "012548"
|
||||
describe = "test-commit"
|
||||
`
|
||||
mockUtils := cnbutils.MockUtils{
|
||||
mockUtils := &cnbutils.MockUtils{
|
||||
ExecMockRunner: &mock.ExecMockRunner{},
|
||||
FilesMock: &mock.FilesMock{},
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ type FileUtils interface {
|
||||
Copy(src, dest string) (int64, error)
|
||||
FileRead(path string) ([]byte, error)
|
||||
FileWrite(path string, content []byte, perm os.FileMode) error
|
||||
FileRemove(path string) error
|
||||
MkdirAll(path string, perm os.FileMode) error
|
||||
Chmod(path string, mode os.FileMode) error
|
||||
Glob(pattern string) (matches []string, err error)
|
||||
|
||||
Reference in New Issue
Block a user