aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-06-01 12:03:48 +0200
committerGitHub <noreply@github.com>2017-06-01 12:03:48 +0200
commit7ac42b0295b4e88960fe9e81fc9bb630521923a9 (patch)
treef322defe838dfe5047e774658c1f53ccc03bc03a
parent4c777a22999258c9f0edb7cb3ca1914f64f6d082 (diff)
parent4d6cb372add889a16f38d09803d0643d961b8dc0 (diff)
Merge pull request #213 from google/dvyukov-git
pkg/git: add new package
-rw-r--r--pkg/git/git.go86
-rw-r--r--syz-gce/syz-gce.go49
2 files changed, 90 insertions, 45 deletions
diff --git a/pkg/git/git.go b/pkg/git/git.go
new file mode 100644
index 000000000..773535cb7
--- /dev/null
+++ b/pkg/git/git.go
@@ -0,0 +1,86 @@
+// Copyright 2017 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+// Package git provides helper functions for working with git repositories.
+package git
+
+import (
+ "bytes"
+ "fmt"
+ "os"
+ "os/exec"
+ "time"
+)
+
+// Poll checkouts the specified repository/branch in dir.
+// This involves fetching/resetting/cloning as necessary to recover from all possible problems.
+// Returns hash of the HEAD commit in the specified branch.
+func Poll(dir, repo, branch string) (string, error) {
+ runCmd(dir, "git", "reset", "--hard")
+ if _, err := runCmd(dir, "git", "fetch", "--no-tags", "--depth=", "1"); err != nil {
+ if err := os.RemoveAll(dir); err != nil {
+ return "", fmt.Errorf("failed to remove repo dir: %v", err)
+ }
+ if err := os.MkdirAll(dir, 0700); err != nil {
+ return "", fmt.Errorf("failed to create repo dir: %v", err)
+ }
+ args := []string{
+ "clone",
+ repo,
+ "--no-tags",
+ "--depth", "1",
+ "--single-branch",
+ "--branch", branch,
+ dir,
+ }
+ if _, err := runCmd("", "git", args...); err != nil {
+ return "", err
+ }
+ }
+ if _, err := runCmd(dir, "git", "checkout", branch); err != nil {
+ return "", err
+ }
+ return HeadCommit(dir)
+}
+
+// HeadCommit returns hash of the HEAD commit of the current branch of git repository in dir.
+func HeadCommit(dir string) (string, error) {
+ output, err := runCmd(dir, "git", "log", "--pretty=format:'%H'", "-n", "1")
+ if err != nil {
+ return "", err
+ }
+ if len(output) != 0 && output[len(output)-1] == '\n' {
+ output = output[:len(output)-1]
+ }
+ if len(output) != 0 && output[0] == '\'' && output[len(output)-1] == '\'' {
+ output = output[1 : len(output)-1]
+ }
+ if len(output) != 40 {
+ return "", fmt.Errorf("unexpected git log output, want commit hash: %q", output)
+ }
+ return string(output), nil
+}
+
+func runCmd(dir, bin string, args ...string) ([]byte, error) {
+ output := new(bytes.Buffer)
+ cmd := exec.Command(bin, args...)
+ cmd.Dir = dir
+ cmd.Stdout = output
+ cmd.Stderr = output
+ if err := cmd.Start(); err != nil {
+ return nil, fmt.Errorf("failed to start %v %+v: %v", bin, args, err)
+ }
+ done := make(chan bool)
+ go func() {
+ select {
+ case <-time.After(time.Hour):
+ cmd.Process.Kill()
+ case <-done:
+ }
+ }()
+ defer close(done)
+ if err := cmd.Wait(); err != nil {
+ return nil, fmt.Errorf("failed to run %v %+v: %v\n%v", bin, args, err, output.String())
+ }
+ return output.Bytes(), nil
+}
diff --git a/syz-gce/syz-gce.go b/syz-gce/syz-gce.go
index 9bdedbe5b..ddc410536 100644
--- a/syz-gce/syz-gce.go
+++ b/syz-gce/syz-gce.go
@@ -42,6 +42,7 @@ import (
"github.com/google/syzkaller/gce"
. "github.com/google/syzkaller/log"
pkgconfig "github.com/google/syzkaller/pkg/config"
+ "github.com/google/syzkaller/pkg/git"
"github.com/google/syzkaller/syz-manager/config"
"golang.org/x/net/context"
)
@@ -302,7 +303,7 @@ func (a *SyzkallerAction) Poll() (string, error) {
if _, err := runCmd("", "go", "get", "-u", "-d", "github.com/google/syzkaller/syz-manager"); err != nil {
return "", err
}
- return gitRevision("gopath/src/github.com/google/syzkaller")
+ return git.HeadCommit("gopath/src/github.com/google/syzkaller")
}
func (a *SyzkallerAction) Build() error {
@@ -346,32 +347,7 @@ func (a *LocalBuildAction) Name() string {
func (a *LocalBuildAction) Poll() (string, error) {
dir := filepath.Join(a.Dir, "linux")
- runCmd(dir, "git", "reset", "--hard")
- if _, err := runCmd(dir, "git", "pull"); err != nil {
- if err := os.RemoveAll(dir); err != nil {
- return "", fmt.Errorf("failed to remove repo dir: %v", err)
- }
- if err := os.MkdirAll(dir, 0700); err != nil {
- return "", fmt.Errorf("failed to create repo dir: %v", err)
- }
- cloneArgs := []string{"clone", a.Repo, "--single-branch", "--depth", "1"}
- if a.Branch != "" {
- cloneArgs = append(cloneArgs, "--branch", a.Branch)
- }
- cloneArgs = append(cloneArgs, dir)
- if _, err := runCmd("", "git", cloneArgs...); err != nil {
- return "", err
- }
- if _, err := runCmd(dir, "git", "pull"); err != nil {
- return "", err
- }
- }
- if a.Branch != "" {
- if _, err := runCmd(dir, "git", "checkout", a.Branch); err != nil {
- return "", err
- }
- }
- rev, err := gitRevision(dir)
+ rev, err := git.Poll(dir, a.Repo, a.Branch)
if err != nil {
return "", err
}
@@ -383,7 +359,7 @@ func (a *LocalBuildAction) Poll() (string, error) {
func (a *LocalBuildAction) Build() error {
dir := filepath.Join(a.Dir, "linux")
- hash, err := gitRevision(dir)
+ hash, err := git.HeadCommit(dir)
if err != nil {
return err
}
@@ -633,23 +609,6 @@ func uploadFile(localFile, gcsFile string) error {
return nil
}
-func gitRevision(dir string) (string, error) {
- output, err := runCmd(dir, "git", "log", "--pretty=format:'%H'", "-n", "1")
- if err != nil {
- return "", err
- }
- if len(output) != 0 && output[len(output)-1] == '\n' {
- output = output[:len(output)-1]
- }
- if len(output) != 0 && output[0] == '\'' && output[len(output)-1] == '\'' {
- output = output[1 : len(output)-1]
- }
- if len(output) != 40 {
- return "", fmt.Errorf("unexpected git log output, want commit hash: %q", output)
- }
- return string(output), nil
-}
-
func buildKernel(dir, ccompiler string) error {
os.Remove(filepath.Join(dir, ".config"))
if _, err := runCmd(dir, "make", "defconfig"); err != nil {