syz-repro-automation: logfile and dir flags

Add logfile and dir flags to specify whether or not argument is a log
file or directory. Also refactored accordingly.

BUG=b:193906330
TEST=go run repro.go

Change-Id: I74150286c5121b291c9fba15ac4f3e5e3e677de1
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/dev-util/+/3057632
Commit-Queue: Grant Hugh <ghugh@chromium.org>
Tested-by: Grant Hugh <ghugh@chromium.org>
Reviewed-by: Zubin Mithra <zsm@chromium.org>
diff --git a/contrib/syz-repro-automation/README.md b/contrib/syz-repro-automation/README.md
index fed3f23..e2010b0 100644
--- a/contrib/syz-repro-automation/README.md
+++ b/contrib/syz-repro-automation/README.md
@@ -20,3 +20,9 @@
 - `-model`: specify what model device to lease (default: garg)
 - `-minutes`: specify how many minutes to lease the device for (default: 60)
 - `-imageid`: specify the kernel image id to flash onto the DUT (default: lookup the latest image for the DUT board)
+
+To run syz-repro on a directory, the user can run
+
+	$ ./syz-repro-automation -logdir PATH/TO/LOGDIR
+
+*Information about logopts.yaml will be added in next commit*
diff --git a/contrib/syz-repro-automation/repro.go b/contrib/syz-repro-automation/repro.go
index 2e503fd..678a02f 100644
--- a/contrib/syz-repro-automation/repro.go
+++ b/contrib/syz-repro-automation/repro.go
@@ -99,21 +99,43 @@
 func checkPaths(paths []string) error {
 	for _, path := range paths {
 		if _, err := os.Stat(path); os.IsNotExist(err) {
-			return fmt.Errorf("path for %v is invalid: %v", err)
+			return fmt.Errorf("filepath %v is invalid: %v", err)
 		}
 	}
 	return nil
 }
 
+func run(model string, minutes int, imageID string, paths map[string]string) {
+	hostname, err := dut.Lease(model, minutes)
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer dut.Abandon(hostname)
+
+	if err = dut.FlashKernel(hostname, imageID); err != nil {
+		log.Panic(err)
+	}
+
+	if err = runSyzRepro(paths, hostname, flag.Arg(0)); err != nil {
+		log.Panic(err)
+	}
+}
+
 func main() {
 	model := flag.String("model", "garg", "Model for leased DUT")
 	minutes := flag.Int("minutes", 60, "Number of minutes to lease DUT")
 	imageID := flag.String("imageid", "", "Kernel image id to flash onto DUT")
+	logFile := flag.Bool("logfile", false, "Argument supplied is a log file")
+	logDir := flag.Bool("logdir", false, "Argument supplied is a directory")
 
 	flag.Parse()
 
+	if *logFile == *logDir {
+		log.Fatal("please use exactly one of the flags -logfile or -dir")
+	}
+
 	if flag.Arg(0) == "" {
-		log.Fatal("must provide a log file to run syz-repro on")
+		log.Fatal("must provide a file or directory to run syz-repro on")
 	}
 
 	syzkallerDir := os.Getenv("SYZKALLER")
@@ -124,7 +146,7 @@
 	sshKey := filepath.Join(syzkallerDir, "testing_rsa")
 	startupScript := filepath.Join(syzkallerDir, "startup_script.sh")
 
-	if err := checkPaths([]string{syzkallerDir, syzrepro, sshKey, startupScript}); err != nil {
+	if err := checkPaths([]string{flag.Arg(0), syzkallerDir, syzrepro, sshKey, startupScript}); err != nil {
 		log.Fatal(err)
 	}
 
@@ -135,17 +157,7 @@
 		"startupScript": startupScript,
 	}
 
-	hostname, err := dut.Lease(*model, *minutes)
-	if err != nil {
-		log.Fatal(err)
-	}
-	defer dut.Abandon(hostname)
-
-	if err = dut.FlashKernel(hostname, *imageID); err != nil {
-		log.Panic(err)
-	}
-
-	if err = runSyzRepro(paths, hostname, flag.Arg(0)); err != nil {
-		log.Panic(err)
+	if *logFile {
+		run(*model, *minutes, *imageID, paths)
 	}
 }