func TestReplaceLastFrom(t *testing.T) { tests := []struct { original string image string want string }{ { original: `# no FROM instruction`, image: "centos", want: ``, }, { original: `FROM scratch # FROM busybox RUN echo "hello world" `, image: "centos", want: `FROM centos RUN echo "hello world" `, }, { original: `FROM scratch FROM busybox RUN echo "hello world" `, image: "centos", want: `FROM scratch FROM centos RUN echo "hello world" `, }, } for i, test := range tests { got, err := parser.Parse(strings.NewReader(test.original)) if err != nil { t.Errorf("test[%d]: %v", i, err) continue } want, err := parser.Parse(strings.NewReader(test.want)) if err != nil { t.Errorf("test[%d]: %v", i, err) continue } replaceLastFrom(got, test.image) if !bytes.Equal(dockerfile.ParseTreeToDockerfile(got), dockerfile.ParseTreeToDockerfile(want)) { t.Errorf("test[%d]: replaceLastFrom(node, %+v) = %+v; want %+v", i, test.image, got, want) t.Logf("resulting Dockerfile:\n%s", dockerfile.ParseTreeToDockerfile(got)) } } }
// addBuildParameters checks if a Image is set to replace the default base image. // If that's the case then change the Dockerfile to make the build with the given image. // Also append the environment variables and labels in the Dockerfile. func (d *DockerBuilder) addBuildParameters(dir string) error { dockerfilePath := filepath.Join(dir, "Dockerfile") if d.build.Spec.Strategy.DockerStrategy != nil && len(d.build.Spec.Source.ContextDir) > 0 { dockerfilePath = filepath.Join(dir, d.build.Spec.Source.ContextDir, "Dockerfile") } f, err := os.Open(dockerfilePath) if err != nil { return err } // Parse the Dockerfile. node, err := parser.Parse(f) if err != nil { return err } // Update base image if build strategy specifies the From field. if d.build.Spec.Strategy.DockerStrategy.From != nil && d.build.Spec.Strategy.DockerStrategy.From.Kind == "DockerImage" { // Reduce the name to a minimal canonical form for the daemon name := d.build.Spec.Strategy.DockerStrategy.From.Name if ref, err := imageapi.ParseDockerImageReference(name); err == nil { name = ref.DaemonMinimal().String() } err := replaceLastFrom(node, name) if err != nil { return err } } // Append build info as environment variables. err = appendEnv(node, d.buildInfo()) if err != nil { return err } // Append build labels. err = appendLabel(node, d.buildLabels(dir)) if err != nil { return err } // Insert environment variables defined in the build strategy. err = insertEnvAfterFrom(node, d.build.Spec.Strategy.DockerStrategy.Env) if err != nil { return err } instructions := dockerfile.ParseTreeToDockerfile(node) // Overwrite the Dockerfile. fi, err := f.Stat() if err != nil { return err } return ioutil.WriteFile(dockerfilePath, instructions, fi.Mode()) }
func TestInsertEnvAfterFrom(t *testing.T) { tests := map[string]struct { original string env []kapi.EnvVar want string }{ "no FROM instruction": { original: `RUN echo "invalid Dockerfile" `, env: []kapi.EnvVar{ {Name: "PATH", Value: "/bin"}, }, want: `RUN echo "invalid Dockerfile" `}, "empty env": { original: `FROM busybox `, env: []kapi.EnvVar{}, want: `FROM busybox `}, "single FROM instruction": { original: `FROM busybox RUN echo "hello world" `, env: []kapi.EnvVar{ {Name: "PATH", Value: "/bin"}, }, want: `FROM busybox ENV "PATH"="/bin" RUN echo "hello world" `}, "multiple FROM instructions": { original: `FROM scratch FROM busybox RUN echo "hello world" `, env: []kapi.EnvVar{ {Name: "PATH", Value: "/bin"}, {Name: "GOPATH", Value: "/go"}, {Name: "PATH", Value: "/go/bin:$PATH"}, }, want: `FROM scratch ENV "PATH"="/bin" "GOPATH"="/go" "PATH"="/go/bin:$PATH" FROM busybox ENV "PATH"="/bin" "GOPATH"="/go" "PATH"="/go/bin:$PATH" RUN echo "hello world" `}, } for name, test := range tests { got, err := parser.Parse(strings.NewReader(test.original)) if err != nil { t.Errorf("%s: %v", name, err) continue } want, err := parser.Parse(strings.NewReader(test.want)) if err != nil { t.Errorf("%s: %v", name, err) continue } insertEnvAfterFrom(got, test.env) if !reflect.DeepEqual(got, want) { t.Errorf("%s: insertEnvAfterFrom(node, %+v) = %+v; want %+v", name, test.env, got, want) t.Logf("resulting Dockerfile:\n%s", dockerfile.ParseTreeToDockerfile(got)) } } }