From 7377d63619a3005b35ce75d7fbf078f1132f9b75 Mon Sep 17 00:00:00 2001 From: Yevgeny Pats Date: Thu, 5 Sep 2019 15:24:12 +0300 Subject: [PATCH] Change bashscript to Golang based agent --- client/agent.go | 391 +++++++++++++++++++++++++++++++++++++++++++++ client/client.go | 16 ++ client/commands.go | 105 +++++------- client/storage.go | 60 +++++++ client/utils.go | 63 +++----- cmd/job.go | 1 + cmd/root.go | 2 +- cmd/run.go | 82 ++++++++++ go.mod | 7 +- go.sum | 10 +- main.go | 4 +- 11 files changed, 622 insertions(+), 119 deletions(-) create mode 100644 client/agent.go create mode 100644 cmd/run.go diff --git a/client/agent.go b/client/agent.go new file mode 100644 index 0000000..817911f --- /dev/null +++ b/client/agent.go @@ -0,0 +1,391 @@ +package client + +import ( + "cloud.google.com/go/firestore" + "context" + "fmt" + "log" + "os" + "os/exec" + "strings" + "syscall" + "time" +) + +const ( + libFuzzerTimeoutExitCode = 77 + libFuzzerLeakExitCode = 76 + libFuzzerCrashExitCode = 1 + libFuzzerOOMExitCode = -9 + + fuzzingInterval = 3600 +) + +var libFuzzerArgs = []string{ + "-print_final_stats=1", + "-exact_artifact_path=./artifact", +} + +func libFuzzerExitCodeToStatus(exitCode int) string { + artifactExist := false + if _, err := os.Stat("artifact"); err == nil { + artifactExist = true + } + status := "pass" + switch exitCode { + case libFuzzerTimeoutExitCode: + status = "timeout" + case libFuzzerCrashExitCode: + status = "crash" + case libFuzzerLeakExitCode: + status = "crash" + case libFuzzerOOMExitCode: + status = "oom" + } + + if status == "crash" && !artifactExist { + status = "failed" + } + + return status +} + +func (c *FuzzitClient) runlibFuzzerMerge() error { + if err := os.Mkdir("merge", 0644); err != nil { + return err + } + if _, err := os.Stat("/tmp/merge_control.txt"); err == nil { + if err = os.Remove("/tmp/merge_control.txt"); err != nil { + return err + } + } + args := append([]string{ + "-print_final_stats=1", + "-exact_artifact_path=./artifact", + fmt.Sprintf("-error_exitcode=%d", libFuzzerTimeoutExitCode), + "-merge_control_file=/tmp/merge_control.txt", + "-merge=1", + "merge", + "corpus", + }) + + log.Println("Running merge with: ./fuzzer " + strings.Join(args, " ")) + cmd := exec.Command("./fuzzer", + args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err := cmd.Run() + if err != nil { + return err + } + + if err = c.archiveAndUpload("merge", + fmt.Sprintf("orgs/%s/targets/%s/corpus.tar.gz", c.Org, c.targetId), + "corpus.tar.gz"); err != nil { + return err + } + + if err = os.RemoveAll("corpus"); err != nil { + return err + } + + if err = os.Rename("merge", "corpus"); err != nil { + return err + } + + return nil +} + +func (c *FuzzitClient) uploadCrash(exitCode int) error { + ctx := context.Background() + + if !c.updateDB { + return nil + } + + if _, err := os.Stat("artifact"); err == nil { + log.Printf("uploading crash...") + if err = c.uploadFile("artifact", + fmt.Sprintf("orgs/%s/targets/%s/crashes/%s-%s", c.Org, c.targetId, c.jobId, os.Getenv("POD_ID")), + "crash"); err != nil { + return err + } + colRef := c.firestoreClient.Collection(fmt.Sprintf("orgs/%s/targets/%s/crashes", c.Org, c.targetId)) + _, _, err = colRef.Add(ctx, crash{ + TargetName: c.targetId, + PodId: os.Getenv("POD_ID"), + JobId: c.jobId, + TargetId: c.targetId, + OrgId: c.Org, + ExitCode: uint32(exitCode), + Type: "CRASH", + }) + if err != nil { + return err + } + } + + return nil +} + +func (c *FuzzitClient) runLibFuzzerFuzzing() error { + ctx := context.Background() + + args := append([]string{ + "-print_final_stats=1", + "-exact_artifact_path=./artifact", + "-error_exitcode=76", + "-max_total_time=3600", + "corpus", + "seed", + }) + + var err error + err = nil + var exitCode int + for err == nil { + log.Println("Running fuzzing with: ./fuzzer " + strings.Join(args, " ")) + cmd := exec.Command("./fuzzer", + args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err = cmd.Start() + // Use a channel to signal completion so we can use a select statement + done := make(chan error) + go func() { done <- cmd.Wait() }() + timeout := time.After(60 * time.Second) + stopSession := false + for stopSession == false { + select { + case <-timeout: + var fuzzingJob job + docRef := c.firestoreClient.Doc(fmt.Sprintf("orgs/%s/targets/%s/jobs/%s", c.Org, c.targetId, c.jobId)) + if docRef == nil { + return fmt.Errorf("invalid resource") + } + docsnap, err := docRef.Get(ctx) + if err != nil { + return err + } + err = docsnap.DataTo(&fuzzingJob) + if err != nil { + return err + } + if fuzzingJob.Status == "in progress" { + timeout = time.After(60 * time.Second) + } else { + log.Println("job was cancel by user. exiting...") + cmd.Process.Kill() + return nil + } + case err = <-done: + stopSession = true + if err != nil { + log.Printf("process finished with error = %v\n", err) + if exiterr, ok := err.(*exec.ExitError); ok { + // The program has exited with an exit code != 0 + + // This works on both Unix and Windows. Although package + // syscall is generally platform dependent, WaitStatus is + // defined for both Unix and Windows and in both cases has + // an ExitStatus() method with the same signature. + if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { + exitCode = status.ExitStatus() + log.Printf("Exit Status: %d", status.ExitStatus()) + } + } else { + return err + } + } else { + if err = c.runlibFuzzerMerge(); err != nil { + return err + } + log.Print("process finished successfully") + } + } + } + } + + err = c.uploadCrash(exitCode) + if err != nil { + return err + } + + err = c.transitionStatus(libFuzzerExitCodeToStatus(exitCode)) + if err != nil { + return err + } + + return nil +} + +func (c *FuzzitClient) runLibFuzzerRegression() error { + var corpusFiles []string + var seedFiles []string + + corpusFiles, err := listFiles("corpus") + if err != nil { + return err + } + seedFiles, err = listFiles("seed") + if err != nil { + return err + } + + regressionFiles := append(corpusFiles, seedFiles...) + if len(regressionFiles) == 0 { + log.Println("no files in corpus and seed. skipping run") + return nil + } + + args := append([]string{ + "-print_final_stats=1", + "-exact_artifact_path=./artifact", + "-error_exitcode=76", + }, regressionFiles...) + log.Println("Running regression...") + cmd := exec.Command("./fuzzer", + args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + exitCode := 0 + if err := cmd.Run(); err != nil { + if !c.updateDB { + // if this is local regression we want to exit with error code so the ci can fail + return err + } + if exiterr, ok := err.(*exec.ExitError); ok { + // The program has exited with an exit code != 0 + + // This works on both Unix and Windows. Although package + // syscall is generally platform dependent, WaitStatus is + // defined for both Unix and Windows and in both cases has + // an ExitStatus() method with the same signature. + if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { + exitCode = status.ExitStatus() + log.Printf("Exit Status: %d", exitCode) + } + } else { + return err + } + } + + if err := c.uploadCrash(exitCode); err != nil { + return err + } + + err = c.transitionStatus(libFuzzerExitCodeToStatus(exitCode)) + if err != nil { + return err + } + + return nil +} + +func (c *FuzzitClient) transitionToInProgress() error { + ctx := context.Background() + + if c.updateDB { + // transaction doesnt work for now at go client with oauth token + jobRef := c.firestoreClient.Doc(fmt.Sprintf("orgs/%s/targets/%s/jobs/%s", c.Org, c.targetId, c.jobId)) + docsnap, err := jobRef.Get(ctx) + if err != nil { + return err + } + err = docsnap.DataTo(&c.currentJob) + if err != nil { + return err + } + if c.currentJob.Status == "queued" { + _, err := jobRef.Update(ctx, []firestore.Update{{Path: "status", Value: "in progress"}}) + if err != nil { + return err + } + } + } + return nil +} + +func (c *FuzzitClient) transitionStatus(status string) error { + ctx := context.Background() + + if !c.updateDB { + return nil + } + + // transaction doesnt work for now at go client with oauth token + jobRef := c.firestoreClient.Doc(fmt.Sprintf("orgs/%s/targets/%s/jobs/%s", c.Org, c.targetId, c.jobId)) + _, err := jobRef.Update(ctx, []firestore.Update{{Path: "status", Value: status}}) + if err != nil { + return err + } + + return nil +} + +func (c *FuzzitClient) RunJob(targetId string, jobId string, updateDB bool, fuzzingType string) error { + err := c.refreshToken() + c.targetId = targetId + c.jobId = jobId + c.updateDB = updateDB + + log.SetPrefix("AGENT: ") + + if err = c.transitionToInProgress(); err != nil { + return err + } + + if err = os.Mkdir("corpus", 0644); err != nil { + return err + } + if err = os.Mkdir("seed", 0644); err != nil { + return err + } + + if jobId != "" { + log.Println("downloading fuzzer") + if err := c.DownloadAndExtractFuzzer(".", targetId, jobId); err != nil { + return err + } + } + + if _, err := os.Stat("fuzzer"); os.IsNotExist(err) { + c.transitionStatus("failed") + return fmt.Errorf("fuzzer executable doesnt exist") + } + + if err := os.Chmod("./fuzzer", 0770); err != nil { + return err + } + + log.Println("downloading corpus") + if err := c.DownloadAndExtractCorpus("./corpus", targetId); err != nil { + if err.Error() == "404 Not Found" { + log.Println("no generating corpus yet. continue...") + } else { + return err + } + } + + log.Println("downloading seed") + if err := c.DownloadAndExtractSeed("./seed", targetId); err != nil { + if err.Error() == "404 Not Found" { + log.Println("no seed corpus. continue...") + } else { + return err + } + } + + if fuzzingType == "regression" { + err = c.runLibFuzzerRegression() + } else { + err = c.runLibFuzzerFuzzing() + } + + if err != nil { + return err + } + + return nil +} diff --git a/client/client.go b/client/client.go index ba36c82..e01aa6d 100644 --- a/client/client.go +++ b/client/client.go @@ -20,6 +20,7 @@ type Job struct { TargetId string `firestore:"target_id"` Args string `firestore:"args"` Type string `firestore:"type"` + Engine string `firestore:"engine"` Host string `firestore:"host"` Revision string `firestore:"revision"` Branch string `firestore:"branch"` @@ -38,6 +39,17 @@ type job struct { Job } +type crash struct { + TargetName string `firestore:"target_name"` + PodId string `firestore:"pod_id"` + JobId string `firestore:"job_id"` + TargetId string `firestore:"target_id"` + OrgId string `firestore:"org_id"` + ExitCode uint32 `firestore:"exit_code"` + Type string `firestore:"type"` + Time time.Time `firestore:"time,serverTimestamp"` +} + type FuzzitClient struct { Org string Namespace string @@ -50,6 +62,10 @@ type FuzzitClient struct { LastRefresh int64 firestoreClient *firestore.Client httpClient *http.Client + currentJob job // this is mainly used by the agent + targetId string // this is mainly used by the agent + jobId string // this is mainly used by the agent + updateDB bool // this is mainly used by the agent } func NewFuzzitClient(apiKey string) (*FuzzitClient, error) { diff --git a/client/commands.go b/client/commands.go index b389bc6..accc31b 100644 --- a/client/commands.go +++ b/client/commands.go @@ -1,7 +1,6 @@ package client import ( - "archive/tar" "context" "encoding/json" "fmt" @@ -67,6 +66,33 @@ func (c *FuzzitClient) archiveFiles(files []string) (string, error) { return fuzzerPath, nil } +func (c *FuzzitClient) DownloadAndExtractCorpus(dst string, target string) error { + storagePath := fmt.Sprintf("orgs/%s/targets/%s/corpus.tar.gz", c.Org, target) + err := c.downloadAndExtract(dst, storagePath) + if err != nil { + return err + } + return nil +} + +func (c *FuzzitClient) DownloadAndExtractSeed(dst string, target string) error { + storagePath := fmt.Sprintf("orgs/%s/targets/%s/seed", c.Org, target) + err := c.downloadAndExtract(dst, storagePath) + if err != nil { + return err + } + return nil +} + +func (c *FuzzitClient) DownloadAndExtractFuzzer(dst string, target string, job string) error { + storagePath := fmt.Sprintf("orgs/%s/targets/%s/jobs/%s/fuzzer", c.Org, target, job) + err := c.downloadAndExtract(dst, storagePath) + if err != nil { + return err + } + return nil +} + func (c *FuzzitClient) DownloadSeed(dst string, target string) error { storagePath := fmt.Sprintf("orgs/%s/targets/%s/seed", c.Org, target) err := c.downloadFile(dst, storagePath) @@ -189,41 +215,6 @@ func (c *FuzzitClient) CreateTarget(target Target, seedPath string, skipIsExists return docRef, nil } -func (c *FuzzitClient) getRunShTar() (*os.File, error) { - tmpfile, err := ioutil.TempFile("", "run.*.tar") - if err != nil { - log.Fatal(err) - } - tw := tar.NewWriter(tmpfile) - hdr := &tar.Header{ - Name: "run.sh", - Mode: 0777, - Size: int64(len(runSh)), - } - if err := tw.WriteHeader(hdr); err != nil { - return nil, err - } - if _, err := tw.Write([]byte(runSh)); err != nil { - return nil, err - } - if err := tw.Flush(); err != nil { - return nil, err - } - if err := tw.Close(); err != nil { - return nil, err - } - if err := tmpfile.Close(); err != nil { - return nil, err - } - - runShTar, err := os.Open(tmpfile.Name()) - if err != nil { - return nil, err - } - - return runShTar, nil -} - func (c *FuzzitClient) CreateLocalJob(jobConfig Job, files []string) error { ctx := context.Background() cli, err := client.NewClientWithOpts(client.FromEnv) @@ -242,19 +233,6 @@ func (c *FuzzitClient) CreateLocalJob(jobConfig Job, files []string) error { return err } - corpusPath := fmt.Sprintf("orgs/%s/targets/%s/corpus.tar.gz", c.Org, jobConfig.TargetId) - log.Print(corpusPath) - corpusLink, err := c.getStorageLink(corpusPath, "read") - if err != nil { - return err - } - - seedPath := fmt.Sprintf("orgs/%s/targets/%s/seed", c.Org, jobConfig.TargetId) - seedLink, err := c.getStorageLink(seedPath, "read") - if err != nil { - return err - } - log.Println("Pulling container") reader, err := cli.ImagePull(ctx, HostToDocker[jobConfig.Host], types.ImagePullOptions{}) if err != nil { @@ -269,14 +247,23 @@ func (c *FuzzitClient) CreateLocalJob(jobConfig Job, files []string) error { &container.Config{ Env: append( []string{ - "CORPUS_LINK=" + corpusLink, - "SEED_LINK=" + seedLink, "ARGS=" + jobConfig.Args, "LD_LIBRARY_PATH=/app", + "FUZZIT_API_KEY=" + c.ApiKey, + "ORG_ID=" + c.Org, + "TARGET_ID=" + jobConfig.TargetId, }, jobConfig.EnvironmentVariables...), - Image: HostToDocker[jobConfig.Host], - Cmd: []string{"/bin/sh", "/app/run.sh"}, + Image: HostToDocker[jobConfig.Host], + Cmd: []string{ + "/bin/sh", + "-c", + `cd /app +echo "Downloading fuzzit cli/agent..." +wget -q -O fuzzit https://github.com/fuzzitdev/fuzzit/releases/download/v2.4.36/fuzzit_Linux_x86_64 +chmod a+x fuzzit +./fuzzit run --type regression`, + }, AttachStdin: true, }, &container.HostConfig{ @@ -294,18 +281,6 @@ func (c *FuzzitClient) CreateLocalJob(jobConfig Job, files []string) error { return err } - runShTar, err := c.getRunShTar() - if err != nil { - return err - } - log.Println("Uploading run.sh to container") - err = cli.CopyToContainer(ctx, createdContainer.ID, "/app/", runShTar, types.CopyToContainerOptions{ - AllowOverwriteDirWithFile: true, - }) - if err != nil { - return err - } - log.Println("Starting the container") err = cli.ContainerStart(ctx, createdContainer.ID, types.ContainerStartOptions{}) if err != nil { diff --git a/client/storage.go b/client/storage.go index b410d69..89bfb80 100755 --- a/client/storage.go +++ b/client/storage.go @@ -4,12 +4,15 @@ import ( "encoding/json" "errors" "fmt" + "github.com/h2non/filetype" + "github.com/mholt/archiver" "io" "io/ioutil" "log" "net/http" "net/url" "os" + "path/filepath" "time" ) @@ -74,6 +77,27 @@ func (c *FuzzitClient) uploadFile(filePath string, storagePath string, filename return nil } +func (c *FuzzitClient) archiveAndUpload(dirPath string, storagePath string, filename string) error { + dir, err := ioutil.TempDir("", "archiveAndUpload") + if err != nil { + log.Fatal(err) + } + defer os.RemoveAll(dir) // clean up + + tmpArchiveFileName := filepath.Join(dir, "archive.tar.gz") + + dirArchiver := archiver.NewTarGz() + if err = dirArchiver.Archive([]string{dirPath}, tmpArchiveFileName); err != nil { + return err + } + + if err = c.uploadFile(tmpArchiveFileName, storagePath, filename); err != nil { + return err + } + + return nil +} + func (c *FuzzitClient) downloadFile(filePath string, storagePath string) error { storageLink, err := c.getStorageLink(storagePath, "read") if err != nil { @@ -102,3 +126,39 @@ func (c *FuzzitClient) downloadFile(filePath string, storagePath string) error { return nil } + +func (c *FuzzitClient) downloadAndExtract(dirPath string, storagePath string) error { + tmpArchiveFile, err := ioutil.TempFile("", "archive") + if err != nil { + return err + } + defer tmpArchiveFile.Close() + + if err := c.downloadFile(tmpArchiveFile.Name(), storagePath); err != nil { + return err + } + buf, _ := ioutil.ReadFile(tmpArchiveFile.Name()) + kind, _ := filetype.Match(buf) + var unarchiver archiver.Unarchiver + switch kind.MIME.Value { + case "application/gzip": + unarchiver = archiver.NewTarGz() + break + case "application/zip": + unarchiver = archiver.NewZip() + break + default: + // assume executable + if _, err := copyFile(filepath.Join(dirPath, "fuzzer"), tmpArchiveFile.Name()); err != nil { + return err + } + return nil + } + + err = unarchiver.Unarchive(tmpArchiveFile.Name(), dirPath) + if err != nil { + return err + } + + return nil +} diff --git a/client/utils.go b/client/utils.go index dcdbd49..4b99edb 100644 --- a/client/utils.go +++ b/client/utils.go @@ -6,6 +6,7 @@ import ( "os" "os/user" "path" + "path/filepath" ) func getCacheFile() (string, error) { @@ -64,48 +65,20 @@ func copyFile(dst, src string) (int64, error) { return nBytes, nil } -const runSh = ` -#!/bin/sh - -mkdir corpus_dir -mkdir seed_dir -touch corpus_dir/empty # This to avoid fuzzer stuck -touch seed_dir/empty # This is to avoid fuzzer stuck - -echo "Downloading main corpus from Fuzzit servers..." -wget -O corpus.tar.gz $CORPUS_LINK || rm -f corpus.tar.gz # remove empty file if corpus doesn't exist -if test -f "corpus.tar.gz"; then - tar -xzf corpus.tar.gz -C corpus_dir -else - echo "corpus is still empty. continuing without..." -fi - -echo "Downloading seed corpus from Fuzzit servers..." -wget -O seed $SEED_LINK || rm -f seed -if test -f "seed"; then - case $(file --mime-type -b seed) in - application/gzip|application/x-gzip) - tar -xzf seed -C seed_dir - ;; - application/zip) - unzip seed -d seed_dir - ;; - *) - echo "seed in unknown format. Please upload seed in tar.gz or zip format. If you did and you believe it's - a bug, please contact support@fuzzit.dev" - exit 1 - ;; - esac -else - echo "seed corpus is empty. continuing without..." -fi - -if test -f "fuzzer"; then - chmod a+x fuzzer - echo "running regression..." - ./fuzzer -exact_artifact_path=./artifact -print_final_stats=1 $(find seed_dir -type f) ./corpus_dir/* $ARGS || exit 1 -else - echo "failed to locate fuzzer. does 'fuzzer' executable exist in the archive?" - exit 1 -fi -` +func listFiles(dst string) ([]string, error) { + var fileList []string + err := filepath.Walk(dst, func(path string, info os.FileInfo, err error) error { + if err != nil { + fmt.Printf("prevent panic by handling failure accessing a path %q: %v\n", path, err) + return err + } + if !info.IsDir() { + fileList = append(fileList, path) + } + return nil + }) + if err != nil { + return nil, err + } + return fileList, nil +} diff --git a/cmd/job.go b/cmd/job.go index 0068ffc..68d0926 100644 --- a/cmd/job.go +++ b/cmd/job.go @@ -91,6 +91,7 @@ func init() { branch := client.GetValueFromEnv("TRAVIS_BRANCH", "CIRCLE_BRANCH") jobCmd.Flags().StringVar(&newJob.Type, "type", "fuzzing", "fuzzing/regression/local-regression") + jobCmd.Flags().StringVar(&newJob.Engine, "engine", "libfuzzer", "libfuzzer/jqf") jobCmd.Flags().Uint16Var(&newJob.Parallelism, "cpus", 1, "number of cpus to use (only relevant for fuzzing job)") jobCmd.Flags().StringVar(&newJob.Revision, "revision", revision, "Revision tag of fuzzer (populates automatically from git,travis,circleci)") jobCmd.Flags().StringVar(&newJob.Branch, "branch", branch, "Branch of the fuzzer (populates automatically from git,travis,circleci)") diff --git a/cmd/root.go b/cmd/root.go index 5740251..077aefa 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -31,7 +31,7 @@ var gFuzzitClient *client.FuzzitClient var rootCmd = &cobra.Command{ Use: "fuzzit", Short: "Continuous fuzzing made simple CLI", - Version: "2.4.35", + Version: "2.4.36", } func Execute() { diff --git a/cmd/run.go b/cmd/run.go new file mode 100644 index 0000000..3717f2e --- /dev/null +++ b/cmd/run.go @@ -0,0 +1,82 @@ +/* +Copyright © 2019 fuzzit.dev, inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cmd + +import ( + "fmt" + "github.com/fuzzitdev/fuzzit/client" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "log" + "os" +) + +// authCmd represents the auth command +var runCmd = &cobra.Command{ + Use: "run", + Short: "Run job locally (used by the agent)", + Args: cobra.ExactArgs(0), + Run: func(cmd *cobra.Command, args []string) { + apiKey := viper.GetString("api-key") + gFuzzitClient, err := client.NewFuzzitClient(apiKey) + if err != nil { + log.Fatalln(err) + } + + fuzzingType, err := cmd.Flags().GetString("type") + if err != nil { + log.Fatalln(err) + } + + updateDB, err := cmd.Flags().GetBool("update-db") + if err != nil { + log.Fatal(err) + } + + orgId := os.Getenv("ORG_ID") + if orgId == "" { + log.Fatalln(fmt.Errorf("ORG_ID environment variable should be provided")) + } + + targetId := os.Getenv("TARGET_ID") + if orgId == "" { + log.Fatalln(fmt.Errorf("TARGET_ID environment variable should be provided")) + } + + jobId := "" + if updateDB { + jobId = os.Getenv("JOB_ID") + if orgId == "" { + log.Fatalln(fmt.Errorf("JOB_ID environment variable should be provided")) + } + } + + gFuzzitClient.Org = orgId + err = gFuzzitClient.RunJob(targetId, jobId, updateDB, fuzzingType) + + if err != nil { + log.Fatalln(err) + } + }, + Hidden: true, +} + +func init() { + rootCmd.AddCommand(runCmd) + runCmd.Flags().Bool("update-db", false, "if this runs on fuzzit then update db") + runCmd.Flags().String("type", "fuzzing", "fuzzing/regression") +} diff --git a/go.mod b/go.mod index ad83e1e..c6a9dae 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.12 require ( cloud.google.com/go v0.43.0 + github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect github.com/Microsoft/go-winio v0.4.13 // indirect github.com/containerd/containerd v1.2.7 // indirect github.com/docker/distribution v2.7.1+incompatible // indirect @@ -11,10 +12,13 @@ require ( github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.4.0 // indirect github.com/dsnet/compress v0.0.1 // indirect + github.com/frankban/quicktest v1.4.2 // indirect github.com/golang/snappy v0.0.1 // indirect github.com/google/uuid v1.1.1 + github.com/gorilla/mux v1.7.3 // indirect + github.com/h2non/filetype v1.0.10 github.com/mholt/archiver v3.1.1+incompatible - github.com/mitchellh/go-homedir v1.1.0 + github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c // indirect github.com/nwaples/rardecode v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0-rc1 // indirect github.com/opencontainers/image-spec v1.0.1 // indirect @@ -26,4 +30,5 @@ require ( google.golang.org/api v0.7.0 google.golang.org/grpc v1.21.1 gopkg.in/src-d/go-git.v4 v4.13.1 + gotest.tools v2.2.0+incompatible // indirect ) diff --git a/go.sum b/go.sum index 125dbdc..8791937 100644 --- a/go.sum +++ b/go.sum @@ -41,12 +41,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v0.0.0-20170601211448-f5ec1e2936dc h1:S8H7eaOGNNOZ83UGSgpgv4FlCtoBTJxG6GzFNkwJr5Q= -github.com/docker/docker v0.0.0-20170601211448-f5ec1e2936dc/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v0.7.3-0.20190802030316-4e83c90ae836 h1:+CrvVfB8NpGBPgGHd1wti3jk6lxPOBl64py2db9bHFE= github.com/docker/docker v0.7.3-0.20190802030316-4e83c90ae836/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo= -github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= @@ -58,8 +54,8 @@ github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/frankban/quicktest v1.4.1 h1:Wv2VwvNn73pAdFIVUQRXYDFp31lXKbqblIXo/Q5GPSg= -github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ= +github.com/frankban/quicktest v1.4.2 h1:eV8n2LQHuA97qKj0t6+7UrHRU0Smz9G+yh87F3Z+3Uk= +github.com/frankban/quicktest v1.4.2/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -103,6 +99,8 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/h2non/filetype v1.0.10 h1:z+SJfnL6thYJ9kAST+6nPRXp1lMxnOVbMZHNYHMar0s= +github.com/h2non/filetype v1.0.10/go.mod h1:isekKqOuhMj+s/7r3rIeTErIRy4Rub5uBWHfvMusLMU= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= diff --git a/main.go b/main.go index 38583db..4f570fa 100644 --- a/main.go +++ b/main.go @@ -16,7 +16,9 @@ limitations under the License. package main -import "github.com/fuzzitdev/fuzzit/cmd" +import ( + "github.com/fuzzitdev/fuzzit/cmd" +) func main() { cmd.Execute()