Merge pull request #1124 from samos123/travis-k8s-test

Travis k8s integration test
This commit is contained in:
Sam Stoelinga
2020-03-16 11:00:56 -07:00
committed by GitHub
11 changed files with 266 additions and 79 deletions
+34 -23
View File
@@ -185,23 +185,8 @@ func addServiceAccountFlags(flags []string, serviceAccount string) []string {
return flags
}
// BuildImage will build dockerfile (located at dockerfilesPath) using both kaniko and docker.
// 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.
func (d *DockerFileBuilder) BuildImage(config *integrationTestConfig, dockerfilesPath, dockerfile string) error {
_, ex, _, _ := runtime.Caller(0)
cwd := filepath.Dir(ex)
return d.BuildImageWithContext(config, dockerfilesPath, dockerfile, cwd)
}
func (d *DockerFileBuilder) BuildImageWithContext(config *integrationTestConfig, dockerfilesPath, dockerfile, contextDir string) error {
if _, present := d.filesBuilt[dockerfile]; present {
return nil
}
gcsBucket, serviceAccount, imageRepo := config.gcsBucket, config.serviceAccount, config.imageRepo
fmt.Printf("Building images for Dockerfile %s\n", dockerfile)
func (d *DockerFileBuilder) BuildDockerImage(imageRepo, dockerfilesPath, dockerfile, contextDir string) error {
fmt.Printf("Building image for Dockerfile %s\n", dockerfile)
var buildArgs []string
buildArgFlag := "--build-arg"
@@ -230,13 +215,39 @@ func (d *DockerFileBuilder) BuildImageWithContext(config *integrationTestConfig,
dockerCmd.Env = append(dockerCmd.Env, env...)
}
timer := timing.Start(dockerfile + "_docker")
out, err := RunCommandWithoutTest(dockerCmd)
timing.DefaultRun.Stop(timer)
if err != nil {
return fmt.Errorf("Failed to build image %s with docker command \"%s\": %s %s", dockerImage, dockerCmd.Args, err, string(out))
}
fmt.Printf("Build image for Dockerfile %s as %s. docker build output: %s \n", dockerfile, dockerImage, out)
return nil
}
// BuildImage will build dockerfile (located at dockerfilesPath) using both kaniko and docker.
// 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.
func (d *DockerFileBuilder) BuildImage(config *integrationTestConfig, dockerfilesPath, dockerfile string) error {
_, ex, _, _ := runtime.Caller(0)
cwd := filepath.Dir(ex)
return d.BuildImageWithContext(config, dockerfilesPath, dockerfile, cwd)
}
func (d *DockerFileBuilder) BuildImageWithContext(config *integrationTestConfig, dockerfilesPath, dockerfile, contextDir string) error {
if _, present := d.filesBuilt[dockerfile]; present {
return nil
}
gcsBucket, serviceAccount, imageRepo := config.gcsBucket, config.serviceAccount, config.imageRepo
var buildArgs []string
buildArgFlag := "--build-arg"
for _, arg := range argsMap[dockerfile] {
buildArgs = append(buildArgs, buildArgFlag, arg)
}
timer := timing.Start(dockerfile + "_docker")
d.BuildDockerImage(imageRepo, dockerfilesPath, dockerfile, contextDir)
timing.DefaultRun.Stop(timer)
contextFlag := "-c"
contextPath := buildContextPath
@@ -269,7 +280,7 @@ func (d *DockerFileBuilder) BuildImageWithContext(config *integrationTestConfig,
}
// build kaniko image
additionalFlags = append(buildArgs, additionalKanikoFlagsMap[dockerfile]...)
additionalFlags := append(buildArgs, additionalKanikoFlagsMap[dockerfile]...)
kanikoImage := GetKanikoImage(imageRepo, dockerfile)
fmt.Printf("Going to build image with kaniko: %s, flags: %s \n", kanikoImage, additionalFlags)
@@ -301,16 +312,16 @@ func (d *DockerFileBuilder) BuildImageWithContext(config *integrationTestConfig,
kanikoCmd := exec.Command("docker", dockerRunFlags...)
timer = timing.Start(dockerfile + "_kaniko")
out, err = RunCommandWithoutTest(kanikoCmd)
out, err := RunCommandWithoutTest(kanikoCmd)
timing.DefaultRun.Stop(timer)
if err != nil {
return fmt.Errorf("Failed to build image %s with kaniko command \"%s\": %s %s", dockerImage, kanikoCmd.Args, err, string(out))
return fmt.Errorf("Failed to build image %s with kaniko command \"%s\": %s %s", kanikoImage, kanikoCmd.Args, err, string(out))
}
if outputCheck := outputChecks[dockerfile]; outputCheck != nil {
if err := outputCheck(dockerfile, out); err != nil {
return fmt.Errorf("Output check failed for image %s with kaniko command \"%s\": %s %s", dockerImage, kanikoCmd.Args, err, string(out))
return fmt.Errorf("Output check failed for image %s with kaniko command \"%s\": %s %s", kanikoImage, kanikoCmd.Args, err, string(out))
}
}
+22
View File
@@ -0,0 +1,22 @@
apiVersion: batch/v1
kind: Job
metadata:
name: kaniko-test-{{.Name}}
spec:
template:
spec:
hostNetwork: true
containers:
- name: kaniko
image: localhost:5000/executor:debug
args: [ "--context=dir:///workspace",
"--destination={{.KanikoImage}}"]
volumeMounts:
- name: context
mountPath: /workspace
restartPolicy: Never
volumes:
- name: context
hostPath:
path: {{.Context}}
backoffLimit: 1
+106
View File
@@ -0,0 +1,106 @@
/*
Copyright 2018 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package integration
import (
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"testing"
"text/template"
)
type K8sConfig struct {
KanikoImage string
Context string
Name string
}
func TestK8s(t *testing.T) {
cwd, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
dir := filepath.Join(cwd, "dockerfiles-with-context")
testDirs, err := ioutil.ReadDir(dir)
if err != nil {
t.Fatal(err)
}
builder := NewDockerFileBuilder()
for _, tdInfo := range testDirs {
name := tdInfo.Name()
testDir := filepath.Join(dir, name)
t.Run("test_k8s_with_context_"+name, func(t *testing.T) {
t.Parallel()
if err := builder.BuildDockerImage(
config.imageRepo, "", name, testDir,
); err != nil {
t.Fatal(err)
}
dockerImage := GetDockerImage(config.imageRepo, name)
kanikoImage := GetKanikoImage(config.imageRepo, name)
tmpfile, err := ioutil.TempFile("", "k8s-job-*.yaml")
if err != nil {
log.Fatal(err)
}
defer os.Remove(tmpfile.Name()) // clean up
tmpl := template.Must(template.ParseFiles("k8s-job.yaml"))
job := K8sConfig{KanikoImage: kanikoImage, Context: testDir, Name: name}
if err := tmpl.Execute(tmpfile, job); err != nil {
t.Fatal(err)
}
fmt.Printf("Testing K8s based Kaniko building of dockerfile %s and push to %s \n",
testDir, kanikoImage)
content, err := ioutil.ReadFile(tmpfile.Name())
if err != nil {
log.Fatal(err)
}
fmt.Printf("K8s template %s:\n%s\n", tmpfile.Name(), content)
kubeCmd := exec.Command("kubectl", "apply", "-f", tmpfile.Name())
RunCommand(kubeCmd, t)
fmt.Printf("Waiting for K8s kaniko build job to finish: %s\n",
"job/kaniko-test-"+job.Name)
kubeWaitCmd := exec.Command("kubectl", "wait", "--for=condition=complete", "--timeout=60s",
"job/kaniko-test-"+job.Name)
RunCommand(kubeWaitCmd, t)
diff := containerDiff(t, daemonPrefix+dockerImage, kanikoImage, "--no-cache")
expected := fmt.Sprintf(emptyContainerDiff, dockerImage, kanikoImage, dockerImage, kanikoImage)
checkContainerDiffOutput(t, diff, expected)
})
}
if err := logBenchmarks("benchmark"); err != nil {
t.Logf("Failed to create benchmark file: %v", err)
}
}