Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 38 additions & 18 deletions pkg/defaults/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -989,19 +989,7 @@ func runtimeStepConfigsForBuild(
if target != nil {
istTagRef := &target.InputImage.BaseImage
if root.FromRepository {
path := "." // By default, the path will be the working directory
if len(refs) > 1 { // If we are getting the build root image for a specific ref we must determine the absolute path
var matchingRefs []prowapi.Refs
for _, r := range refs {
if ref == fmt.Sprintf("%s.%s", r.Org, r.Repo) {
matchingRefs = append(matchingRefs, r)
}
}
if len(matchingRefs) == 0 { // If we didn't find anything, use the primary refs
matchingRefs = append(matchingRefs, *determinePrimaryRef(jobSpec, injectedTest))
}
path = decorate.DetermineWorkDir(codeMountPath, matchingRefs)
}
path := getPath(refs, ref, jobSpec, injectedTest)
var err error
istTagRef, err = buildRootImageStreamFromRepository(path, readFile)
if err != nil {
Expand Down Expand Up @@ -1039,13 +1027,44 @@ func runtimeStepConfigsForBuild(
buildSteps = append(buildSteps, getSourceStepsForJobSpec(jobSpec, injectedTest)...)

// Detect Dockerfile inputs for project images and add InputImageTagStepConfiguration entries
dockerfileInputSteps, images := detectDockerfileInputs(config.Images, config.BaseImages, readFile)
baseImagesWithRoot := config.BaseImages
if baseImagesWithRoot == nil {
baseImagesWithRoot = make(map[string]api.ImageStreamTagReference)
}

for _, imageConfig := range imageConfigs {
alias := string(imageConfig.InputImage.To)
baseImagesWithRoot[alias] = imageConfig.InputImage.BaseImage
}
path := getPath(refs, "", jobSpec, injectedTest)
dockerfileInputSteps, images := detectDockerfileInputs(config.Images, baseImagesWithRoot, path, readFile)
config.Images = images
buildSteps = append(buildSteps, dockerfileInputSteps...)

return buildSteps, nil
}

func getPath(refs []prowapi.Refs, ref string, jobSpec *api.JobSpec, injectedTest bool) string {
path := "." // By default, the path will be the working directory
if len(refs) > 1 { // If we are getting the build root image for a specific ref we must determine the absolute path
var matchingRefs []prowapi.Refs
for _, r := range refs {
if ref == fmt.Sprintf("%s.%s", r.Org, r.Repo) {
matchingRefs = append(matchingRefs, r)
}
}
if len(matchingRefs) == 0 { // If we didn't find anything, use the primary refs
primaryRef := determinePrimaryRef(jobSpec, injectedTest)
if primaryRef == nil {
return path
}
matchingRefs = append(matchingRefs, *primaryRef)
}
path = decorate.DetermineWorkDir(codeMountPath, matchingRefs)
}
return path
}

// dockerfileDetails holds the content and path of a Dockerfile
type dockerfileDetails struct {
content []byte
Expand All @@ -1055,10 +1074,10 @@ type dockerfileDetails struct {
// detectDockerfileInputs reads Dockerfiles for project images and detects registry.ci.openshift.org
// references that should be added as base images. It returns any required InputImageTagStepConfiguration steps to
// import the detected base images, as well as an updated list of image configurations with the detected inputs added
func detectDockerfileInputs(images []api.ProjectDirectoryImageBuildStepConfiguration, baseImages map[string]api.ImageStreamTagReference, readFile readFile) ([]api.StepConfiguration, []api.ProjectDirectoryImageBuildStepConfiguration) {
func detectDockerfileInputs(images []api.ProjectDirectoryImageBuildStepConfiguration, baseImages map[string]api.ImageStreamTagReference, path string, readFile readFile) ([]api.StepConfiguration, []api.ProjectDirectoryImageBuildStepConfiguration) {
var steps []api.StepConfiguration
for i, image := range images {
dockerfileDetails, err := readDockerfileForImage(image, readFile)
dockerfileDetails, err := readDockerfileForImage(image, path, readFile)
if err != nil {
logrus.WithError(err).WithField("image", image.To).Debug("Failed to read Dockerfile for input detection, skipping")
continue
Expand All @@ -1073,15 +1092,16 @@ func detectDockerfileInputs(images []api.ProjectDirectoryImageBuildStepConfigura

// readDockerfileForImage reads the Dockerfile content for a given image configuration
// Returns the dockerfileDetails and any error encountered
func readDockerfileForImage(image api.ProjectDirectoryImageBuildStepConfiguration, readFile readFile) (dockerfileDetails, error) {
func readDockerfileForImage(image api.ProjectDirectoryImageBuildStepConfiguration, path string, readFile readFile) (dockerfileDetails, error) {
if image.DockerfileLiteral != nil {
return dockerfileDetails{content: []byte(*image.DockerfileLiteral), path: "dockerfile_literal"}, nil
}
details := dockerfileDetails{path: "Dockerfile"}
if image.DockerfilePath != "" {
details.path = image.DockerfilePath
}
dockerfilePath := fmt.Sprintf("./%s", details.path)

dockerfilePath := fmt.Sprintf("%s/%s", path, details.path)
if image.ContextDir != "" {
dockerfilePath = fmt.Sprintf("%s/%s", image.ContextDir, details.path)
}
Expand Down
186 changes: 185 additions & 1 deletion pkg/defaults/defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1177,6 +1177,190 @@ func TestStepConfigsForBuild(t *testing.T) {
}},
injectedTest: true,
},
{
name: "test dockerfile inputs",
input: &api.ReleaseBuildConfiguration{
InputConfiguration: api.InputConfiguration{
BuildRootImage: &api.BuildRootImageConfiguration{
ImageStreamTagReference: &api.ImageStreamTagReference{
Namespace: "ocp",
Name: "builder",
Tag: "rhel-9-golang-1.25-openshift-4.21",
},
},
},
Images: []api.ProjectDirectoryImageBuildStepConfiguration{
{
From: "root",
To: "custom-dockerfile-image",
},
},
},
jobSpec: &api.JobSpec{
JobSpec: downwardapi.JobSpec{
Refs: &prowapi.Refs{
Org: "org",
Repo: "repo",
},
},
},
readFile: func(filename string) ([]byte, error) {
if filename != "./Dockerfile" {
return nil, fmt.Errorf("")
}
return []byte(`FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.25-openshift-4.21 AS builder
WORKDIR /go/src/github.com/openshift/cert-manager-operator

# build operator
COPY . .
RUN make build --warn-undefined-variables

FROM registry.ci.openshift.org/ocp/base:rhel-9-openshift-4.21
COPY --from=builder /go/src/github.com/openshift/cert-manager-operator/cert-manager-operator /usr/bin/

USER 65532:65532

ENTRYPOINT ["/usr/bin/cert-manager-operator"]`), nil
},
resolver: noopResolver,
output: []api.StepConfiguration{
{
InputImageTagStepConfiguration: &api.InputImageTagStepConfiguration{
InputImage: api.InputImage{
BaseImage: api.ImageStreamTagReference{
Namespace: "ocp",
Name: "builder",
Tag: "rhel-9-golang-1.25-openshift-4.21",
},
To: "root",
},
Sources: []api.ImageStreamSource{{SourceType: "root"}},
},
},
{
OutputImageTagStepConfiguration: &api.OutputImageTagStepConfiguration{
From: "custom-dockerfile-image",
To: api.ImageStreamTagReference{Name: "stable", Tag: "custom-dockerfile-image"},
},
},
{
ProjectDirectoryImageBuildStepConfiguration: &api.ProjectDirectoryImageBuildStepConfiguration{
From: "root",
To: "custom-dockerfile-image",
ProjectDirectoryImageBuildInputs: api.ProjectDirectoryImageBuildInputs{
Inputs: map[string]api.ImageBuildInputs{
"root": {
As: []string{"registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.25-openshift-4.21"},
},
},
},
},
},
{
SourceStepConfiguration: &api.SourceStepConfiguration{
From: "root",
To: "src",
ClonerefsPullSpec: "quay-proxy.ci.openshift.org/openshift/ci:ci_clonerefs_latest",
ClonerefsPath: "/ko-app/clonerefs",
},
},
},
},
{
name: "test dockerfile inputs, build_root from repository",
input: &api.ReleaseBuildConfiguration{
InputConfiguration: api.InputConfiguration{
BuildRootImage: &api.BuildRootImageConfiguration{
FromRepository: true,
},
},
Images: []api.ProjectDirectoryImageBuildStepConfiguration{
{
From: "root",
To: "custom-dockerfile-image",
ProjectDirectoryImageBuildInputs: api.ProjectDirectoryImageBuildInputs{
DockerfilePath: "custom/Dockerfile",
},
},
},
},
jobSpec: &api.JobSpec{
JobSpec: downwardapi.JobSpec{
Refs: &prowapi.Refs{
Org: "org",
Repo: "repo",
},
},
},
readFile: func(filename string) ([]byte, error) {
if filename == "./custom/Dockerfile" {
return []byte(`FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.25-openshift-4.21 AS builder
WORKDIR /go/src/github.com/openshift/cert-manager-operator

# build operator
COPY . .
RUN make build --warn-undefined-variables

FROM registry.ci.openshift.org/ocp/base:rhel-9-openshift-4.21
COPY --from=builder /go/src/github.com/openshift/cert-manager-operator/cert-manager-operator /usr/bin/

USER 65532:65532

ENTRYPOINT ["/usr/bin/cert-manager-operator"]`), nil
}
if filename == "./.ci-operator.yaml" {
return []byte(`build_root_image:
namespace: ocp
name: builder
tag: rhel-9-golang-1.25-openshift-4.21`), nil
}
return nil, fmt.Errorf("")
},
resolver: noopResolver,
output: []api.StepConfiguration{
{
InputImageTagStepConfiguration: &api.InputImageTagStepConfiguration{
InputImage: api.InputImage{
BaseImage: api.ImageStreamTagReference{
Namespace: "ocp",
Name: "builder",
Tag: "rhel-9-golang-1.25-openshift-4.21",
},
To: "root",
},
Sources: []api.ImageStreamSource{{SourceType: "root"}},
},
},
{
OutputImageTagStepConfiguration: &api.OutputImageTagStepConfiguration{
From: "custom-dockerfile-image",
To: api.ImageStreamTagReference{Name: "stable", Tag: "custom-dockerfile-image"},
},
},
{
ProjectDirectoryImageBuildStepConfiguration: &api.ProjectDirectoryImageBuildStepConfiguration{
From: "root",
To: "custom-dockerfile-image",
ProjectDirectoryImageBuildInputs: api.ProjectDirectoryImageBuildInputs{
DockerfilePath: "custom/Dockerfile",
Inputs: map[string]api.ImageBuildInputs{
"root": {
As: []string{"registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.25-openshift-4.21"},
},
},
},
},
},
{
SourceStepConfiguration: &api.SourceStepConfiguration{
From: "root",
To: "src",
ClonerefsPullSpec: "quay-proxy.ci.openshift.org/openshift/ci:ci_clonerefs_latest",
ClonerefsPath: "/ko-app/clonerefs",
},
},
},
},
}

for _, testCase := range testCases {
Expand Down Expand Up @@ -2344,7 +2528,7 @@ func TestReadDockerfileForImage(t *testing.T) {

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
details, err := readDockerfileForImage(tc.image, tc.readFile)
details, err := readDockerfileForImage(tc.image, ".", tc.readFile)

if tc.expectError {
if err == nil {
Expand Down