Skip to content

Commit

Permalink
bug: component detection with context
Browse files Browse the repository at this point in the history
Fixes RHTAPBUGS-418
  • Loading branch information
stuartwdouglas committed Jun 15, 2023
1 parent 4fa3f96 commit bebb2a0
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 15 deletions.
2 changes: 1 addition & 1 deletion controllers/componentdetectionquery_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ func (r *ComponentDetectionQueryReconciler) Reconcile(ctx context.Context, req c
if isMultiComponent {
log.Info(fmt.Sprintf("Since this is a multi-component, attempt will be made to read only level 1 dir for devfiles... %v", req.NamespacedName))

devfilesMap, devfilesURLMap, dockerfileContextMap, componentPortsMap, err = devfile.ScanRepo(log, r.AlizerClient, componentPath, r.DevfileRegistryURL, source)
devfilesMap, devfilesURLMap, dockerfileContextMap, componentPortsMap, err = devfile.ScanRepoWithContext(log, r.AlizerClient, source.Context, componentPath, r.DevfileRegistryURL, source)
if err != nil {
if _, ok := err.(*devfile.NoDevfileFound); !ok {
log.Error(err, fmt.Sprintf("Unable to find devfile(s) in repo %s due to an error %s, exiting reconcile loop %v", source.URL, err.Error(), req.NamespacedName))
Expand Down
27 changes: 14 additions & 13 deletions pkg/devfile/detect.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ type AlizerClient struct {
// Map 2 returns a context to the matched devfileURL from the github repository. If no devfile was present, then a link to a matching devfile in the devfile registry will be used instead.
// Map 3 returns a context to the Dockerfile uri or a matched DockerfileURL from the devfile registry if no Dockerfile is present in the context
// Map 4 returns a context to the list of ports that were detected by alizer in the source code, at that given context
func search(log logr.Logger, a Alizer, localpath string, devfileRegistryURL string, source appstudiov1alpha1.GitSource) (map[string][]byte, map[string]string, map[string]string, map[string][]int, error) {
func search(log logr.Logger, a Alizer, originalContext string, localpath string, devfileRegistryURL string, source appstudiov1alpha1.GitSource) (map[string][]byte, map[string]string, map[string]string, map[string][]int, error) {

devfileMapFromRepo := make(map[string][]byte)
devfilesURLMapFromRepo := make(map[string]string)
Expand All @@ -63,7 +63,8 @@ func search(log logr.Logger, a Alizer, localpath string, devfileRegistryURL stri
isDevfilePresent := false
isDockerfilePresent := false
curPath := path.Join(localpath, f.Name())
context := f.Name()
dirName := f.Name()
contextKey := originalContext + f.Name()
files, err := ioutil.ReadDir(curPath)
if err != nil {
return nil, nil, nil, nil, err
Expand All @@ -74,7 +75,7 @@ func search(log logr.Logger, a Alizer, localpath string, devfileRegistryURL stri
/* #nosec G304 -- false positive, filename is not based on user input*/
devfilePath := path.Join(curPath, f.Name())
// Set the proper devfile URL for the detected devfile
updatedLink, err := UpdateGitLink(source.URL, source.Revision, path.Join(source.Context, path.Join(context, f.Name())))
updatedLink, err := UpdateGitLink(source.URL, source.Revision, path.Join(source.Context, path.Join(dirName, f.Name())))
if err != nil {
return nil, nil, nil, nil, err
}
Expand All @@ -85,8 +86,8 @@ func search(log logr.Logger, a Alizer, localpath string, devfileRegistryURL stri
if shouldIgnoreDevfile {
isDevfilePresent = false
} else {
devfileMapFromRepo[context] = devfileBytes
devfilesURLMapFromRepo[context] = updatedLink
devfileMapFromRepo[contextKey] = devfileBytes
devfilesURLMapFromRepo[contextKey] = updatedLink
isDevfilePresent = true
}
} else if f.IsDir() && f.Name() == HiddenDevfileDir {
Expand All @@ -105,7 +106,7 @@ func search(log logr.Logger, a Alizer, localpath string, devfileRegistryURL stri
devfilePath := path.Join(hiddenDirPath, f.Name())

// Set the proper devfile URL for the detected devfile
updatedLink, err := UpdateGitLink(source.URL, source.Revision, path.Join(source.Context, path.Join(context, HiddenDevfileDir, f.Name())))
updatedLink, err := UpdateGitLink(source.URL, source.Revision, path.Join(source.Context, path.Join(dirName, HiddenDevfileDir, f.Name())))
if err != nil {
return nil, nil, nil, nil, err
}
Expand All @@ -117,8 +118,8 @@ func search(log logr.Logger, a Alizer, localpath string, devfileRegistryURL stri
if shouldIgnoreDevfile {
isDevfilePresent = false
} else {
devfileMapFromRepo[context] = devfileBytes
devfilesURLMapFromRepo[context] = updatedLink
devfileMapFromRepo[contextKey] = devfileBytes
devfilesURLMapFromRepo[contextKey] = updatedLink

isDevfilePresent = true
}
Expand All @@ -131,11 +132,11 @@ func search(log logr.Logger, a Alizer, localpath string, devfileRegistryURL stri
// we will read the devfile to ensure a Dockerfile has been referenced.
// However, if a Dockerfile is named differently and not referenced in the devfile
// it will go undetected
dockerfileContextMapFromRepo[context] = DockerfileName
dockerfileContextMapFromRepo[contextKey] = DockerfileName
isDockerfilePresent = true
} else if f.Name() == ContainerfileName {
// Check for Containerfile
dockerfileContextMapFromRepo[context] = ContainerfileName
dockerfileContextMapFromRepo[contextKey] = ContainerfileName
isDockerfilePresent = true
} else if f.IsDir() && (f.Name() == DockerDir || f.Name() == HiddenDockerDir || f.Name() == BuildDir) {
// Check for docker/Dockerfile, .docker/Dockerfile and build/Dockerfile
Expand All @@ -148,7 +149,7 @@ func search(log logr.Logger, a Alizer, localpath string, devfileRegistryURL stri
}
for _, f := range files {
if f.Name() == DockerfileName || f.Name() == ContainerfileName {
dockerfileContextMapFromRepo[context] = path.Join(dirName, f.Name())
dockerfileContextMapFromRepo[contextKey] = path.Join(dirName, f.Name())
isDockerfilePresent = true
}
}
Expand All @@ -158,12 +159,12 @@ func search(log logr.Logger, a Alizer, localpath string, devfileRegistryURL stri
// at this stage, we need to ensure the Dockerfile has been referenced
// in the devfile image component even if we detect both devfile and Dockerfile
if isDevfilePresent && isDockerfilePresent {
delete(dockerfileContextMapFromRepo, context)
delete(dockerfileContextMapFromRepo, contextKey)
isDockerfilePresent = false
}

if (!isDevfilePresent && !isDockerfilePresent) || (isDevfilePresent && !isDockerfilePresent) {
err := AnalyzePath(log, a, curPath, context, devfileRegistryURL, devfileMapFromRepo, devfilesURLMapFromRepo, dockerfileContextMapFromRepo, componentPortsMapFromRepo, isDevfilePresent, isDockerfilePresent)
err := AnalyzePath(log, a, curPath, contextKey, devfileRegistryURL, devfileMapFromRepo, devfilesURLMapFromRepo, dockerfileContextMapFromRepo, componentPortsMapFromRepo, isDevfilePresent, isDockerfilePresent)
if err != nil {
return nil, nil, nil, nil, err
}
Expand Down
23 changes: 22 additions & 1 deletion pkg/devfile/devfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,28 @@ func DownloadDevfileAndDockerfile(url string) ([]byte, string, []byte, string) {
// Map 3 returns a context to the Dockerfile uri or a matched DockerfileURL from the devfile registry if no Dockerfile/Containerfile is present in the context
// Map 4 returns a context to the list of ports that were detected by alizer in the source code, at that given context
func ScanRepo(log logr.Logger, a Alizer, localpath string, devfileRegistryURL string, source appstudiov1alpha1.GitSource) (map[string][]byte, map[string]string, map[string]string, map[string][]int, error) {
return search(log, a, localpath, devfileRegistryURL, source)
return search(log, a, "", localpath, devfileRegistryURL, source)
}

// ScanRepoWithContext attempts to read and return devfiles and Dockerfiles/Containerfiles from the local path upto the specified depth
// it also takes an originalContext parameter that represents the context path in the git repo
// this will be appended to the keys of all the returned maps
// Iterate through each sub-folder under first level, and scan for component. (devfile, Dockerfile/Containerfile, then Alizer)
// If no devfile(s) or Dockerfile(s)/Containerfile(s) are found in sub-folders of the root directory, then the Alizer tool is used to detect and match a devfile/Dockerfile from the devfile registry
// ScanRepo returns 3 maps and an error:
// Map 1 returns a context to the devfile bytes if present.
// Map 2 returns a context to the matched devfileURL from the devfile registry if no devfile is present in the context.
// Map 3 returns a context to the Dockerfile uri or a matched DockerfileURL from the devfile registry if no Dockerfile/Containerfile is present in the context
// Map 4 returns a context to the list of ports that were detected by alizer in the source code, at that given context
func ScanRepoWithContext(log logr.Logger, a Alizer, originalContext string, localpath string, devfileRegistryURL string, source appstudiov1alpha1.GitSource) (map[string][]byte, map[string]string, map[string]string, map[string][]int, error) {
if originalContext != "" {
if originalContext == "./" {
originalContext = ""
} else if !strings.HasSuffix(originalContext, "/") {
originalContext += "/"
}
}
return search(log, a, originalContext, localpath, devfileRegistryURL, source)
}

// UpdateLocalDockerfileURItoAbsolute takes in a Devfile, and a DockefileURL, and returns back a Devfile with any local URIs to the Dockerfile updates to be absolute
Expand Down

0 comments on commit bebb2a0

Please sign in to comment.