Refactor integration imaqge built

The aim of this change is to hide the complexity of image not being rebuilt. Image builder won't also have to know the list of dockerfiles
This commit is contained in:
Ben Einaudi 2020-02-13 18:51:47 +01:00
parent ae4e7d91aa
commit 0c1d05520f
2 changed files with 20 additions and 24 deletions

View File

@ -152,18 +152,15 @@ func FindDockerFiles(dockerfilesPath string) ([]string, error) {
// keeps track of which files have been built. // keeps track of which files have been built.
type DockerFileBuilder struct { type DockerFileBuilder struct {
// Holds all available docker files and whether or not they've been built // Holds all available docker files and whether or not they've been built
FilesBuilt map[string]bool filesBuilt map[string]struct{}
DockerfilesToIgnore map[string]struct{} DockerfilesToIgnore map[string]struct{}
TestCacheDockerfiles map[string]struct{} TestCacheDockerfiles map[string]struct{}
} }
// NewDockerFileBuilder will create a DockerFileBuilder initialized with dockerfiles, which // NewDockerFileBuilder will create a DockerFileBuilder initialized with dockerfiles, which
// it will assume are all as yet unbuilt. // it will assume are all as yet unbuilt.
func NewDockerFileBuilder(dockerfiles []string) *DockerFileBuilder { func NewDockerFileBuilder() *DockerFileBuilder {
d := DockerFileBuilder{FilesBuilt: map[string]bool{}} d := DockerFileBuilder{filesBuilt: map[string]struct{}{}}
for _, f := range dockerfiles {
d.FilesBuilt[f] = false
}
d.DockerfilesToIgnore = map[string]struct{}{ d.DockerfilesToIgnore = map[string]struct{}{
// TODO: remove test_user_run from this when https://github.com/GoogleContainerTools/container-diff/issues/237 is fixed // TODO: remove test_user_run from this when https://github.com/GoogleContainerTools/container-diff/issues/237 is fixed
"Dockerfile_test_user_run": {}, "Dockerfile_test_user_run": {},
@ -192,6 +189,9 @@ func addServiceAccountFlags(flags []string, serviceAccount string) []string {
// The resulting image will be tagged with imageRepo. If the dockerfile will be built with // The resulting image will be tagged with imageRepo. If the dockerfile will be built with
// context (i.e. it is in `buildContextTests`) the context will be pulled from gcsBucket. // context (i.e. it is in `buildContextTests`) the context will be pulled from gcsBucket.
func (d *DockerFileBuilder) BuildImage(config *integrationTestConfig, dockerfilesPath, dockerfile string) error { func (d *DockerFileBuilder) BuildImage(config *integrationTestConfig, dockerfilesPath, dockerfile string) error {
if _, present := d.filesBuilt[dockerfile]; present {
return nil
}
gcsBucket, serviceAccount, imageRepo := config.gcsBucket, config.serviceAccount, config.imageRepo gcsBucket, serviceAccount, imageRepo := config.gcsBucket, config.serviceAccount, config.imageRepo
_, ex, _, _ := runtime.Caller(0) _, ex, _, _ := runtime.Caller(0)
cwd := filepath.Dir(ex) cwd := filepath.Dir(ex)
@ -291,7 +291,7 @@ func (d *DockerFileBuilder) BuildImage(config *integrationTestConfig, dockerfile
} }
} }
d.FilesBuilt[dockerfile] = true d.filesBuilt[dockerfile] = struct{}{}
return nil return nil
} }

View File

@ -42,9 +42,11 @@ import (
var config *integrationTestConfig var config *integrationTestConfig
var imageBuilder *DockerFileBuilder var imageBuilder *DockerFileBuilder
var allDockerfiles []string
const ( const (
daemonPrefix = "daemon://" daemonPrefix = "daemon://"
integrationPath = "integration"
dockerfilesPath = "dockerfiles" dockerfilesPath = "dockerfiles"
emptyContainerDiff = `[ emptyContainerDiff = `[
{ {
@ -82,7 +84,7 @@ func getDockerMajorVersion() int {
} }
return ver return ver
} }
func launchTests(m *testing.M, dockerfiles []string) (int, error) { func launchTests(m *testing.M) (int, error) {
if config.isGcrRepository() { if config.isGcrRepository() {
contextFile, err := CreateIntegrationTarball() contextFile, err := CreateIntegrationTarball()
@ -104,7 +106,7 @@ func launchTests(m *testing.M, dockerfiles []string) (int, error) {
} else { } else {
var err error var err error
var migratedFiles []string var migratedFiles []string
if migratedFiles, err = MigrateGCRRegistry(dockerfilesPath, dockerfiles, config.imageRepo); err != nil { if migratedFiles, err = MigrateGCRRegistry(dockerfilesPath, allDockerfiles, config.imageRepo); err != nil {
RollbackMigratedFiles(dockerfilesPath, migratedFiles) RollbackMigratedFiles(dockerfilesPath, migratedFiles)
return 1, errors.Wrap(err, "Fail to migrate dockerfiles from gcs") return 1, errors.Wrap(err, "Fail to migrate dockerfiles from gcs")
} }
@ -115,23 +117,24 @@ func launchTests(m *testing.M, dockerfiles []string) (int, error) {
return 1, errors.Wrap(err, "Error while building images") return 1, errors.Wrap(err, "Error while building images")
} }
imageBuilder = NewDockerFileBuilder(dockerfiles) imageBuilder = NewDockerFileBuilder()
return m.Run(), nil return m.Run(), nil
} }
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
var err error
if !meetsRequirements() { if !meetsRequirements() {
fmt.Println("Missing required tools") fmt.Println("Missing required tools")
os.Exit(1) os.Exit(1)
} }
if dockerfiles, err := FindDockerFiles(dockerfilesPath); err != nil { if allDockerfiles, err = FindDockerFiles(dockerfilesPath); err != nil {
fmt.Println("Coudn't create map of dockerfiles", err) fmt.Println("Coudn't create map of dockerfiles", err)
os.Exit(1) os.Exit(1)
} else { } else {
config = initIntegrationTestConfig() config = initIntegrationTestConfig()
exitCode, err := launchTests(m, dockerfiles) exitCode, err := launchTests(m)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
@ -155,7 +158,7 @@ func buildRequiredImages() error {
}, },
{ {
name: "Building onbuild base image", name: "Building onbuild base image",
command: []string{"docker", "build", "-t", config.onbuildBaseImage, "-f", "dockerfiles/Dockerfile_onbuild_base", "."}, command: []string{"docker", "build", "-t", config.onbuildBaseImage, "-f", fmt.Sprintf("%s/Dockerfile_onbuild_base", dockerfilesPath), "."},
}, },
{ {
name: "Pushing onbuild base image", name: "Pushing onbuild base image",
@ -163,7 +166,7 @@ func buildRequiredImages() error {
}, },
{ {
name: "Building hardlink base image", name: "Building hardlink base image",
command: []string{"docker", "build", "-t", config.hardlinkBaseImage, "-f", "dockerfiles/Dockerfile_hardlink_base", "."}, command: []string{"docker", "build", "-t", config.hardlinkBaseImage, "-f", fmt.Sprintf("%s/Dockerfile_hardlink_base", dockerfilesPath), "."},
}, },
{ {
name: "Pushing hardlink base image", name: "Pushing hardlink base image",
@ -182,7 +185,7 @@ func buildRequiredImages() error {
} }
func TestRun(t *testing.T) { func TestRun(t *testing.T) {
for dockerfile := range imageBuilder.FilesBuilt { for _, dockerfile := range allDockerfiles {
t.Run("test_"+dockerfile, func(t *testing.T) { t.Run("test_"+dockerfile, func(t *testing.T) {
dockerfile := dockerfile dockerfile := dockerfile
t.Parallel() t.Parallel()
@ -194,7 +197,6 @@ func TestRun(t *testing.T) {
} }
buildImage(t, dockerfile, imageBuilder) buildImage(t, dockerfile, imageBuilder)
imageBuilder.FilesBuilt[dockerfile] = true
dockerImage := GetDockerImage(config.imageRepo, dockerfile) dockerImage := GetDockerImage(config.imageRepo, dockerfile)
kanikoImage := GetKanikoImage(config.imageRepo, dockerfile) kanikoImage := GetKanikoImage(config.imageRepo, dockerfile)
@ -238,7 +240,7 @@ func getGitRepo() string {
func TestGitBuildcontext(t *testing.T) { func TestGitBuildcontext(t *testing.T) {
repo := getGitRepo() repo := getGitRepo()
dockerfile := "integration/dockerfiles/Dockerfile_test_run_2" dockerfile := fmt.Sprintf("%s/%s/Dockerfile_test_run_2", integrationPath, dockerfilesPath)
// Build with docker // Build with docker
dockerImage := GetDockerImage(config.imageRepo, "Dockerfile_test_git") dockerImage := GetDockerImage(config.imageRepo, "Dockerfile_test_git")
@ -285,7 +287,7 @@ func TestLayers(t *testing.T) {
"Dockerfile_test_add": 12, "Dockerfile_test_add": 12,
"Dockerfile_test_scratch": 3, "Dockerfile_test_scratch": 3,
} }
for dockerfile := range imageBuilder.FilesBuilt { for _, dockerfile := range allDockerfiles {
t.Run("test_layer_"+dockerfile, func(t *testing.T) { t.Run("test_layer_"+dockerfile, func(t *testing.T) {
dockerfile := dockerfile dockerfile := dockerfile
@ -295,7 +297,6 @@ func TestLayers(t *testing.T) {
} }
buildImage(t, dockerfile, imageBuilder) buildImage(t, dockerfile, imageBuilder)
imageBuilder.FilesBuilt[dockerfile] = true
// Pull the kaniko image // Pull the kaniko image
dockerImage := GetDockerImage(config.imageRepo, dockerfile) dockerImage := GetDockerImage(config.imageRepo, dockerfile)
@ -313,15 +314,10 @@ func TestLayers(t *testing.T) {
} }
func buildImage(t *testing.T, dockerfile string, imageBuilder *DockerFileBuilder) { func buildImage(t *testing.T, dockerfile string, imageBuilder *DockerFileBuilder) {
if imageBuilder.FilesBuilt[dockerfile] {
return
}
if err := imageBuilder.BuildImage(config, dockerfilesPath, dockerfile); err != nil { if err := imageBuilder.BuildImage(config, dockerfilesPath, dockerfile); err != nil {
t.Errorf("Error building image: %s", err) t.Errorf("Error building image: %s", err)
t.FailNow() t.FailNow()
} }
return return
} }