From 621cb43076d7edfaeb8be90a48af6d9278758ab2 Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Wed, 4 Jul 2018 14:23:23 +1000 Subject: [PATCH] helper: Better support for building from local source (#1589). (#1595) Parse WORKDIR from the Dockerfile and use that to mount in the local source. --- infra/helper.py | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/infra/helper.py b/infra/helper.py index 021bd6080..e4042e184 100755 --- a/infra/helper.py +++ b/infra/helper.py @@ -186,7 +186,7 @@ def _is_base_image(image_name): def _check_project_exists(project_name): """Checks if a project exists.""" - if not os.path.exists(os.path.join(OSSFUZZ_DIR, 'projects', project_name)): + if not os.path.exists(_get_project_dir(project_name)): print(project_name, 'does not exist', file=sys.stderr) return False @@ -222,6 +222,16 @@ def _get_command_string(command): return ' '.join(pipes.quote(part) for part in command) +def _get_project_dir(project_name): + """Returns path to the project.""" + return os.path.join(OSSFUZZ_DIR, 'projects', project_name) + + +def _get_dockerfile_path(project_name): + """Returns path to the project Dockerfile.""" + return os.path.join(_get_project_dir(project_name), 'Dockerfile') + + def _get_corpus_dir(project_name=''): """Returns path to /corpus directory for the given project (if specified).""" return os.path.join(BUILD_DIR, 'corpus', project_name) @@ -283,6 +293,27 @@ def _env_to_docker_args(env_list): return sum([['-e', v] for v in env_list], []) +def _workdir_from_dockerfile(dockerfile_path): + """Parse WORKDIR from the Dockerfile.""" + WORKDIR_REGEX = re.compile(r'\s*WORKDIR\s*([^\s]+)') + + with open(dockerfile_path) as f: + lines = f.readlines() + + for line in reversed(lines): # reversed to get last WORKDIR. + match = re.match(WORKDIR_REGEX, line) + if match: + workdir = match.group(1) + workdir = workdir.replace('$SRC', '/src') + + if not os.path.isabs(workdir): + workdir = os.path.join('/src', workdir) + + return workdir + + return os.path.join('/src', project_name) + + def docker_run(run_args, print_output=True): """Call `docker run`.""" command = ['docker', 'run', '--rm', '-i', '--privileged'] @@ -401,7 +432,9 @@ def build_fuzzers(args): if args.source_path: command += [ '-v', - '%s:/src/%s' % (_get_absolute_path(args.source_path), args.project_name) + '%s:%s' % (_get_absolute_path(args.source_path), + _workdir_from_dockerfile( + _get_dockerfile_path(args.project_name))), ] command += [ '-v', '%s:/out' % project_out_dir,