diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2016-11-16 17:03:13 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2016-11-16 17:03:13 +0100 |
| commit | aa9fbfb94b8efc6f3fdc236545a5f34e8f2e3540 (patch) | |
| tree | 84a00f0dd3a1ac629e1105a70877fe3a71817799 | |
| parent | 1d5ba315b46a39cdc053ad178a33e57542fa4f6e (diff) | |
syz-gce: proxy manager http requests
Firewall may restrict access to manager, proxy traffic manager requests.
Also choose manager port automatically.
| -rw-r--r-- | syz-gce/http.go | 40 | ||||
| -rw-r--r-- | syz-gce/syz-gce.go | 53 |
2 files changed, 69 insertions, 24 deletions
diff --git a/syz-gce/http.go b/syz-gce/http.go index b6e86b381..9ce0a4990 100644 --- a/syz-gce/http.go +++ b/syz-gce/http.go @@ -6,15 +6,19 @@ package main import ( "fmt" "html/template" + "io" "net" "net/http" "strings" + "sync/atomic" . "github.com/google/syzkaller/log" ) func initHttp(addr string) { - http.HandleFunc("/", httpSummary) + http.HandleFunc("/", httpManager) + http.HandleFunc("/syz-gce", httpSummary) + ln, err := net.Listen("tcp4", addr) if err != nil { Fatalf("failed to listen on %v: %v", addr, err) @@ -28,8 +32,9 @@ func initHttp(addr string) { func httpSummary(w http.ResponseWriter, r *http.Request) { data := &UISummaryData{ - Name: cfg.Name, - Log: CachedLogOutput(), + Name: cfg.Name, + Manager: atomic.LoadUint32(&managerHttpPort) != 0, + Log: CachedLogOutput(), } if err := summaryTemplate.Execute(w, data); err != nil { http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError) @@ -37,13 +42,28 @@ func httpSummary(w http.ResponseWriter, r *http.Request) { } } +func httpManager(w http.ResponseWriter, r *http.Request) { + port := atomic.LoadUint32(&managerHttpPort) + if port == 0 { + http.Error(w, "manager is not running", http.StatusInternalServerError) + return + } + resp, err := http.Get(fmt.Sprintf("http://localhost:%v/%v", port, r.RequestURI)) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + io.Copy(w, resp.Body) +} + func compileTemplate(html string) *template.Template { return template.Must(template.New("").Parse(strings.Replace(html, "{{STYLE}}", htmlStyle, -1))) } type UISummaryData struct { - Name string - Log string + Name string + Manager bool + Log string } var summaryTemplate = compileTemplate(` @@ -55,8 +75,14 @@ var summaryTemplate = compileTemplate(` </head> <body> <b>{{.Name}} syz-gce</b> -<br> -<br> +<br><br> + +{{if .Manager}} +<a href="/">manager</a> +{{else}} +manager is not running +{{end}} +<br><br> Log: <br> diff --git a/syz-gce/syz-gce.go b/syz-gce/syz-gce.go index 77b2723ea..8b6da1f42 100644 --- a/syz-gce/syz-gce.go +++ b/syz-gce/syz-gce.go @@ -15,11 +15,13 @@ import ( "fmt" "io" "io/ioutil" + "net" "os" "os/exec" "os/signal" "path/filepath" "strings" + "sync/atomic" "syscall" "time" @@ -35,23 +37,23 @@ var ( flagNoImageCreate = flag.Bool("noimagecreate", false, "don't download/create image (for testing)") flagNoRebuild = flag.Bool("norebuild", false, "don't update/rebuild syzkaller (for testing)") - cfg *Config - ctx context.Context - storageClient *storage.Client - GCE *gce.Context + cfg *Config + ctx context.Context + storageClient *storage.Client + GCE *gce.Context + managerHttpPort uint32 ) type Config struct { - Name string - Image_Archive string - Image_Path string - Image_Name string - Http_Port int - Manager_Http_Port int - Machine_Type string - Machine_Count int - Sandbox string - Procs int + Name string + Image_Archive string + Image_Path string + Image_Name string + Http_Port int + Machine_Type string + Machine_Count int + Sandbox string + Procs int } func main() { @@ -98,6 +100,7 @@ func main() { } Logf(0, "syz-manager exited with %v", err) managerCmd = nil + atomic.StoreUint32(&managerHttpPort, 0) case s := <-sigC: switch s { case syscall.SIGUSR1: @@ -194,7 +197,12 @@ func main() { *flagNoRebuild = false lastSyzkallerHash = syzkallerHash - if err := writeManagerConfig("manager.cfg"); err != nil { + port, err := chooseUnusedPort() + if err != nil { + Logf(0, "failed to choose an unused port: %v", err) + continue + } + if err := writeManagerConfig(port, "manager.cfg"); err != nil { Logf(0, "failed to write manager config: %v", err) continue } @@ -207,6 +215,7 @@ func main() { continue } stoppingManager = false + atomic.StoreUint32(&managerHttpPort, uint32(port)) go func() { managerStopped <- managerCmd.Wait() }() @@ -229,7 +238,7 @@ func readConfig(filename string) *Config { return cfg } -func writeManagerConfig(file string) error { +func writeManagerConfig(httpPort int, file string) error { tag, err := ioutil.ReadFile("image/tag") if err != nil { return fmt.Errorf("failed to read tag file: %v", err) @@ -239,7 +248,7 @@ func writeManagerConfig(file string) error { } managerCfg := &config.Config{ Name: cfg.Name, - Http: fmt.Sprintf(":%v", cfg.Manager_Http_Port), + Http: fmt.Sprintf(":%v", httpPort), Rpc: ":0", Workdir: "workdir", Vmlinux: "image/obj/vmlinux", @@ -264,6 +273,16 @@ func writeManagerConfig(file string) error { return nil } +func chooseUnusedPort() (int, error) { + ln, err := net.Listen("tcp4", ":") + if err != nil { + return 0, err + } + port := ln.Addr().(*net.TCPAddr).Port + ln.Close() + return port, nil +} + func openFile(file string) (*storage.ObjectHandle, time.Time, error) { pos := strings.IndexByte(file, '/') if pos == -1 { |
