devapp: further preparation for running on GKE
+ Remove superfluous check for PORT env var since only the flag
will be used.
+ Remove HTML being written to the page before escaping step,
causing jank.
+ Grab the GitHub token from GCE metadata if it’s available.
Updates golang/go#20691
Change-Id: I10fbc163ee91907ef0b843c823f40fd87a62f476
Reviewed-on: https://go-review.googlesource.com/46210
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/devapp/devapp.go b/devapp/devapp.go
index f55d784..552506e 100644
--- a/devapp/devapp.go
+++ b/devapp/devapp.go
@@ -141,7 +141,6 @@
if cls {
data.PrintCLs(&output)
} else {
- fmt.Fprintf(&output, fmt.Sprintf(`<a href="/stats/release?cycle=%d">Go 1.%d Issue Stats Dashboard</a>`, data.GoReleaseCycle, data.GoReleaseCycle))
data.PrintIssues(&output)
}
var html bytes.Buffer
diff --git a/devapp/devappserver/Dockerfile.0 b/devapp/devappserver/Dockerfile.0
index e857b72..fce55a2 100644
--- a/devapp/devappserver/Dockerfile.0
+++ b/devapp/devappserver/Dockerfile.0
@@ -28,6 +28,9 @@
RUN go get -d golang.org/x/sync/errgroup && \
cd /go/src/golang.org/x/sync && git reset --hard f52d1811a62927559de87708c8913c1650ce4f26
+RUN go get -d cloud.google.com/go/compute/metadata && \
+ cd /go/src/cloud.google.com/go && git reset --hard 23179f286bc31e07fba2eddaa540fb999b1b1fd9
+
# Optimization to speed COPY+go install steps later. This go install
# isn't required for correctness.
RUN go install github.com/aclements/go-gg/generic/slice \
@@ -39,7 +42,8 @@
github.com/kylelemons/godebug/pretty \
golang.org/x/net/context \
golang.org/x/oauth2 \
- golang.org/x/sync/errgroup
+ golang.org/x/sync/errgroup \
+ cloud.google.com/go/compute/metadata
COPY . /go/src/golang.org/x/build/
diff --git a/devapp/devappserver/main.go b/devapp/devappserver/main.go
index e623bcf..cd9657c 100644
--- a/devapp/devappserver/main.go
+++ b/devapp/devappserver/main.go
@@ -7,10 +7,9 @@
//
// Usage:
//
-// devappserver --port=8081
+// devappserver --http=:8081
//
-// By default devapp listens on port 8081. You can also configure the port by
-// setting the PORT environment variable (but not both).
+// By default devappserver listens on port 80.
//
// For the moment, Github issues and Gerrit CL's are stored in memory
// in the running process. To trigger an initial download, visit
@@ -32,35 +31,21 @@
func init() {
flag.Usage = func() {
- os.Stderr.WriteString(`usage: devapp [-port=port]
+ os.Stderr.WriteString(`usage: devappserver [-http=addr]
-Devapp generates the dashboard that powers dev.golang.org.
+devappserver generates the dashboard that powers dev.golang.org.
`)
}
}
-const defaultPort = "8081"
-
func main() {
- portFlag := flag.String("port", "", "Port to listen on")
+ httpAddr := flag.String("http", ":80", "HTTP service address (e.g., ':8080')")
flag.Parse()
- if *portFlag != "" && os.Getenv("PORT") != "" {
- os.Stderr.WriteString("cannot set both $PORT and --port flags\n")
- os.Exit(2)
- }
- var port string
- if p := os.Getenv("PORT"); p != "" {
- port = p
- } else if *portFlag != "" {
- port = *portFlag
- } else {
- port = defaultPort
- }
- ln, err := net.Listen("tcp", ":"+port)
+ ln, err := net.Listen("tcp", *httpAddr)
if err != nil {
- fmt.Fprintf(os.Stderr, "Error listening on %s: %v\n", port, err)
+ fmt.Fprintf(os.Stderr, "Error listening on %s: %v\n", *httpAddr, err)
os.Exit(2)
}
- fmt.Fprintf(os.Stderr, "Listening on port %s\n", port)
+ fmt.Fprintf(os.Stderr, "Serving at %s\n", ln.Addr().String())
log.Fatal(http.Serve(ln, nil))
}
diff --git a/devapp/noappengine.go b/devapp/noappengine.go
index 759b12d..6b42161 100644
--- a/devapp/noappengine.go
+++ b/devapp/noappengine.go
@@ -8,7 +8,6 @@
package devapp
import (
- "errors"
"flag"
"fmt"
"io/ioutil"
@@ -20,6 +19,7 @@
"sync"
"time"
+ "cloud.google.com/go/compute/metadata"
"golang.org/x/net/context"
)
@@ -130,11 +130,13 @@
return nil
}
-var githubToken string
-var githubOnceErr error
-var githubOnce sync.Once
+var (
+ githubToken string
+ githubOnceErr error
+ githubOnce sync.Once
+)
-func getToken(ctx context.Context) (string, error) {
+func getTokenFromFile(ctx context.Context) (string, error) {
githubOnce.Do(func() {
const short = ".github-issue-token"
filename := filepath.Clean(os.Getenv("HOME") + "/" + short)
@@ -145,14 +147,16 @@
}
data, err := ioutil.ReadFile(filename)
if err != nil {
- msg := fmt.Sprintln("reading token: ", err, "\n\n"+
- "Please create a personal access token at https://github.com/settings/tokens/new\n"+
- "and write it to ", shortFilename, " to use this program.\n"+
- "The token only needs the repo scope, or private_repo if you want to\n"+
- "view or edit issues for private repositories.\n"+
- "The benefit of using a personal access token over using your GitHub\n"+
- "password directly is that you can limit its use and revoke it at any time.\n\n")
- githubOnceErr = errors.New(msg)
+ const fmtStr = `reading token: %v
+
+Please create a personal access token at https://github.com/settings/tokens/new
+and write it to %s or store it in GCE metadata using the
+key 'maintner-github-token' to use this program.
+The token only needs the repo scope, or private_repo if you want to view or edit
+issues for private repositories. The benefit of using a personal access token
+over using your GitHub password directly is that you can limit its use and revoke
+it at any time.`
+ githubOnceErr = fmt.Errorf(fmtStr, err, shortFilename)
return
}
fi, err := os.Stat(filename)
@@ -169,6 +173,17 @@
return githubToken, githubOnceErr
}
+func getToken(ctx context.Context) (string, error) {
+ if metadata.OnGCE() {
+ // Re-use maintner-github-token until this is migrated to using the maintner API.
+ token, err := metadata.ProjectAttributeValue("maintner-github-token")
+ if len(token) > 0 && err == nil {
+ return token, nil
+ }
+ }
+ return getTokenFromFile(ctx)
+}
+
func getContext(r *http.Request) context.Context {
return r.Context()
}