Skip to content

Commit a85eebb

Browse files
infra: enable building projects using cached images (google#12597)
Signed-off-by: David Korczynski <[email protected]> Co-authored-by: Oliver Chang <[email protected]>
1 parent a181f3f commit a85eebb

File tree

2 files changed

+39
-12
lines changed

2 files changed

+39
-12
lines changed

Diff for: infra/build/functions/build_project.py

+28-9
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@
6161
LOCAL_BUILD_LOG_PATH = '/workspace/build.log'
6262
BUILD_SUCCESS_MARKER = '/workspace/build.succeeded'
6363

64+
_CACHED_IMAGE = ('us-central1-docker.pkg.dev/oss-fuzz/oss-fuzz-gen/'
65+
'{name}-ofg-cached-{sanitizer}')
66+
_CACHED_SANITIZERS = ('address', 'coverage')
67+
6468

6569
@dataclass
6670
class Config:
@@ -163,6 +167,8 @@ def __init__(self, name, project_yaml, dockerfile):
163167
else:
164168
self.main_repo = ''
165169

170+
self.cached_sanitizer = None
171+
166172
@property
167173
def sanitizers(self):
168174
"""Returns processed sanitizers."""
@@ -172,8 +178,14 @@ def sanitizers(self):
172178
@property
173179
def image(self):
174180
"""Returns the docker image for the project."""
181+
if self.cached_sanitizer:
182+
return self.cached_image(self.cached_sanitizer)
183+
175184
return f'gcr.io/{build_lib.IMAGE_PROJECT}/{self.name}'
176185

186+
def cached_image(self, sanitizer):
187+
return _CACHED_IMAGE.format(name=self.name, sanitizer=sanitizer)
188+
177189

178190
def get_last_step_id(steps):
179191
"""Returns the id of the last step in |steps|."""
@@ -313,30 +325,37 @@ def get_build_steps( # pylint: disable=too-many-locals, too-many-statements, to
313325
project_yaml,
314326
dockerfile,
315327
config,
316-
additional_env=None):
328+
additional_env=None,
329+
use_caching=False):
317330
"""Returns build steps for project."""
318331

319332
project = Project(project_name, project_yaml, dockerfile)
320-
321333
if project.disabled:
322334
logging.info('Project "%s" is disabled.', project.name)
323335
return []
324336

325337
timestamp = get_datetime_now().strftime('%Y%m%d%H%M')
326-
build_steps = build_lib.get_project_image_steps(
327-
project.name,
328-
project.image,
329-
project.fuzzing_language,
330-
config=config,
331-
architectures=project.architectures,
332-
experiment=config.experiment)
338+
if use_caching:
339+
# Use cached built image.
340+
build_steps = []
341+
else:
342+
build_steps = build_lib.get_project_image_steps(
343+
project.name,
344+
project.image,
345+
project.fuzzing_language,
346+
config=config,
347+
architectures=project.architectures,
348+
experiment=config.experiment)
333349

334350
# Sort engines to make AFL first to test if libFuzzer has an advantage in
335351
# finding bugs first since it is generally built first.
336352
for fuzzing_engine in sorted(project.fuzzing_engines):
337353
# Sort sanitizers and architectures so order is determinisitic (good for
338354
# tests).
339355
for sanitizer in sorted(project.sanitizers):
356+
if use_caching and sanitizer in _CACHED_SANITIZERS:
357+
project.cached_sanitizer = sanitizer
358+
340359
# Build x86_64 before i386.
341360
for architecture in reversed(sorted(project.architectures)):
342361
build = Build(fuzzing_engine, sanitizer, architecture)

Diff for: infra/build/functions/target_experiment.py

+11-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030

3131
def run_experiment(project_name, target_name, args, output_path, errlog_path,
3232
build_output_path, upload_corpus_path, upload_coverage_path,
33-
experiment_name, upload_reproducer_path, tags):
33+
experiment_name, upload_reproducer_path, tags,
34+
use_cached_image):
3435
config = build_project.Config(testing=True,
3536
test_image_suffix='',
3637
repo=build_project.DEFAULT_OSS_FUZZ_REPO,
@@ -68,7 +69,8 @@ def run_experiment(project_name, target_name, args, output_path, errlog_path,
6869
project_yaml,
6970
dockerfile_contents,
7071
config,
71-
additional_env=jcc_env)
72+
additional_env=jcc_env,
73+
use_caching=use_cached_image)
7274

7375
build = build_project.Build('libfuzzer', 'address', 'x86_64')
7476
local_output_path = '/workspace/output.log'
@@ -209,6 +211,9 @@ def run_experiment(project_name, target_name, args, output_path, errlog_path,
209211
env = build_project.get_env(project_yaml['language'], build)
210212
env.extend(jcc_env)
211213

214+
if use_cached_image:
215+
project.cached_sanitizer = 'coverage'
216+
212217
steps.append(
213218
build_project.get_compile_step(project, build, env, config.parallel))
214219

@@ -330,12 +335,15 @@ def main():
330335
nargs='*',
331336
help='Tags for cloud build.',
332337
default=[])
338+
parser.add_argument('--use_cached_image',
339+
action='store_true',
340+
help='Use cached images post build.')
333341
args = parser.parse_args()
334342

335343
run_experiment(args.project, args.target, args.args, args.upload_output_log,
336344
args.upload_err_log, args.upload_build_log, args.upload_corpus,
337345
args.upload_coverage, args.experiment_name,
338-
args.upload_reproducer, args.tags)
346+
args.upload_reproducer, args.tags, args.use_cached_image)
339347

340348

341349
if __name__ == '__main__':

0 commit comments

Comments
 (0)