// LookupPath search for bin in paths. If found, it returns its absolute path, // if not, an error func LookupPath(bin string, paths string) (string, error) { pathsArr := filepath.SplitList(paths) for _, path := range pathsArr { binPath := filepath.Join(path, bin) binAbsPath, err := filepath.Abs(binPath) if err != nil { return "", fmt.Errorf("unable to find absolute path for %s", binPath) } if fileutil.IsExecutable(binAbsPath) { return binAbsPath, nil } } return "", fmt.Errorf("unable to find %q in %q", bin, paths) }
// lookupPathInsideApp returns the path (relative to the app rootfs) of the // given binary. It will look up on "paths" (also relative to the app rootfs) // and evaluate possible symlinks to check if the resulting path is actually // executable. func lookupPathInsideApp(bin string, paths string, appRootfs string, workDir string) (string, error) { pathsArr := filepath.SplitList(paths) var appPathsArr []string for _, p := range pathsArr { if !filepath.IsAbs(p) { p = filepath.Join(workDir, p) } appPathsArr = append(appPathsArr, filepath.Join(appRootfs, p)) } for _, path := range appPathsArr { binPath := filepath.Join(path, bin) stage2Path := strings.TrimPrefix(binPath, appRootfs) binRealPath, err := EvaluateSymlinksInsideApp(appRootfs, stage2Path) if err != nil { return "", errwrap.Wrap(fmt.Errorf("could not evaluate path %v", stage2Path), err) } binRealPath = filepath.Join(appRootfs, binRealPath) if fileutil.IsExecutable(binRealPath) { // The real path is executable, return the path relative to the app return stage2Path, nil } } return "", fmt.Errorf("unable to find %q in %q", bin, paths) }