Skip to content
This repository was archived by the owner on Nov 1, 2023. It is now read-only.

Commit 4f8ab62

Browse files
committed
Revert removal of command.
1 parent 434a435 commit 4f8ab62

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

src/cli/onefuzz/api.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,81 @@ def _download_tasks(
528528
azcopy_sync(to_download[name], outdir)
529529

530530

531+
class Repro(Endpoint):
532+
"""Interact with repro files"""
533+
534+
endpoint = "repro_vms"
535+
536+
def get_files(
537+
self,
538+
report_container: primitives.Container,
539+
report_name: str,
540+
include_setup: bool = False,
541+
output_dir: primitives.Directory = primitives.Directory("."),
542+
) -> None:
543+
"""downloads the files necessary to locally repro the crash from a given report"""
544+
report_bytes = self.onefuzz.containers.files.get(report_container, report_name)
545+
report = json.loads(report_bytes)
546+
547+
crash_info = {
548+
"input_blob_container": primitives.Container(""),
549+
"input_blob_name": "",
550+
"job_id": "",
551+
}
552+
if "input_blob" in report:
553+
crash_info["input_blob_container"] = report["input_blob"]["container"]
554+
crash_info["input_blob_name"] = report["input_blob"]["name"]
555+
crash_info["job_id"] = report["job_id"]
556+
elif "crash_test_result" in report and "original_crash_test_result" in report:
557+
if report["original_crash_test_result"]["crash_report"] is None:
558+
self.logger.error(
559+
"No crash report found in the original crash test result, repro files cannot be retrieved"
560+
)
561+
return
562+
elif report["crash_test_result"]["crash_report"] is None:
563+
self.logger.info(
564+
"No crash report found in the new crash test result, falling back on the original crash test result for job_id"
565+
"Note: if using --include_setup, the downloaded fuzzer binaries may be out-of-date"
566+
)
567+
568+
original_report = report["original_crash_test_result"]["crash_report"]
569+
new_report = (
570+
report["crash_test_result"]["crash_report"] or original_report
571+
) # fallback on original_report
572+
573+
crash_info["input_blob_container"] = original_report["input_blob"][
574+
"container"
575+
]
576+
crash_info["input_blob_name"] = original_report["input_blob"]["name"]
577+
crash_info["job_id"] = new_report["job_id"]
578+
else:
579+
self.logger.error(
580+
"Encountered an unhandled report format, repro files cannot be retrieved"
581+
)
582+
return
583+
584+
self.logger.info(
585+
"downloading files necessary to locally repro crash %s",
586+
crash_info["input_blob_name"],
587+
)
588+
self.onefuzz.containers.files.download(
589+
primitives.Container(crash_info["input_blob_container"]),
590+
crash_info["input_blob_name"],
591+
os.path.join(output_dir, crash_info["input_blob_name"]),
592+
)
593+
594+
if include_setup:
595+
setup_container = list(
596+
self.onefuzz.jobs.containers.list(
597+
crash_info["job_id"], enums.ContainerType.setup
598+
)
599+
)[0]
600+
601+
self.onefuzz.containers.files.download_dir(
602+
primitives.Container(setup_container), output_dir
603+
)
604+
605+
531606
class Notifications(Endpoint):
532607
"""Interact with models.Notifications"""
533608

@@ -1588,6 +1663,7 @@ def __init__(
15881663
client_secret=client_secret,
15891664
)
15901665
self.containers = Containers(self)
1666+
self.repro = Repro(self)
15911667
self.notifications = Notifications(self)
15921668
self.tasks = Tasks(self)
15931669
self.jobs = Jobs(self)

0 commit comments

Comments
 (0)