cmd/tip: fix the build
https://golang.org/cl/52390 was submitted too early with failing trybots.
This fixes it, hiding the cloud.google.com stuff behind a build tag,
used by the Dockerfile but not the Go build system.
Change-Id: I66c6b40d4b06bf6c763f3ab221c7997856bfc910
Reviewed-on: https://go-review.googlesource.com/52470
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jessie Frazelle <me@jessfraz.com>
diff --git a/cmd/tip/Dockerfile b/cmd/tip/Dockerfile
index 3604d52..86dfe36 100644
--- a/cmd/tip/Dockerfile
+++ b/cmd/tip/Dockerfile
@@ -126,7 +126,7 @@
# golang sets GOPATH=/go
ADD . /go/src/tip
-RUN go install tip
+RUN go install --tags=autocert tip
ENTRYPOINT ["/go/bin/tip"]
# App Engine expects us to listen on port 8080
EXPOSE 8080
diff --git a/cmd/tip/cert.go b/cmd/tip/cert.go
new file mode 100644
index 0000000..e00777b
--- /dev/null
+++ b/cmd/tip/cert.go
@@ -0,0 +1,50 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+// +build autocert
+
+// This file contains autocert and cloud.google.com/go/storage
+// dependencies we want to hide by default from the Go build system,
+// which currently doesn't know how to fetch non-golang.org/x/*
+// dependencies. The Dockerfile builds the production binary
+// with this code using --tags=autocert.
+
+package main
+
+import (
+ "context"
+ "crypto/tls"
+ "log"
+ "net/http"
+
+ "cloud.google.com/go/storage"
+ "golang.org/x/build/autocertcache"
+ "golang.org/x/crypto/acme/autocert"
+)
+
+func init() {
+ runHTTPS = runHTTPSAutocert
+}
+
+func runHTTPSAutocert(h http.Handler) error {
+ var cache autocert.Cache
+ if b := *autoCertCacheBucket; b != "" {
+ sc, err := storage.NewClient(context.Background())
+ if err != nil {
+ log.Fatalf("storage.NewClient: %v", err)
+ }
+ cache = autocertcache.NewGoogleCloudStorageCache(sc, b)
+ }
+ m := autocert.Manager{
+ Prompt: autocert.AcceptTOS,
+ HostPolicy: autocert.HostWhitelist(*autoCertDomain),
+ Cache: cache,
+ }
+ s := &http.Server{
+ Addr: ":https",
+ Handler: h,
+ TLSConfig: &tls.Config{GetCertificate: m.GetCertificate},
+ }
+ return s.ListenAndServeTLS("", "")
+}
diff --git a/cmd/tip/tip.go b/cmd/tip/tip.go
index 30f1864..6e0fd47 100644
--- a/cmd/tip/tip.go
+++ b/cmd/tip/tip.go
@@ -8,8 +8,6 @@
import (
"bufio"
- "context"
- "crypto/tls"
"encoding/json"
"errors"
"flag"
@@ -25,10 +23,6 @@
"path/filepath"
"sync"
"time"
-
- "cloud.google.com/go/storage"
- "golang.org/x/build/autocertcache"
- "golang.org/x/crypto/acme/autocert"
)
const (
@@ -44,6 +38,10 @@
autoCertCacheBucket = flag.String("autocert-bucket", "", "if non-empty, the Google Cloud Storage bucket in which to store the LetsEncrypt cache")
)
+// runHTTPS, if non-nil, specifies the function to serve HTTPS.
+// It is set non-nil in cert.go with the "autocert" build tag.
+var runHTTPS func(http.Handler) error
+
func main() {
flag.Parse()
@@ -64,34 +62,20 @@
log.Printf("Starting up tip server for builder %q", os.Getenv(k))
- errc := make(chan error)
+ errc := make(chan error, 1)
go func() {
errc <- http.ListenAndServe(":8080", mux)
}()
if *autoCertDomain != "" {
+ if runHTTPS == nil {
+ errc <- errors.New("can't use --autocert without building binary with the autocert build tag")
+ } else {
+ go func() {
+ errc <- runHTTPS(mux)
+ }()
+ }
log.Printf("Listening on port 443 with LetsEncrypt support on domain %q", *autoCertDomain)
- var cache autocert.Cache
- if b := *autoCertCacheBucket; b != "" {
- sc, err := storage.NewClient(context.Background())
- if err != nil {
- log.Fatalf("storage.NewClient: %v", err)
- }
- cache = autocertcache.NewGoogleCloudStorageCache(sc, b)
- }
- m := autocert.Manager{
- Prompt: autocert.AcceptTOS,
- HostPolicy: autocert.HostWhitelist(*autoCertDomain),
- Cache: cache,
- }
- s := &http.Server{
- Addr: ":https",
- Handler: mux,
- TLSConfig: &tls.Config{GetCertificate: m.GetCertificate},
- }
- go func() {
- errc <- s.ListenAndServeTLS("", "")
- }()
}
if err := <-errc; err != nil {
p.stop()