From 3fd990c6be325a4f9f9a82b6b4951b1393e90fff Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Tue, 1 Aug 2017 17:22:09 +0000 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Jessie Frazelle --- cmd/tip/Dockerfile | 2 +- cmd/tip/cert.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++ cmd/tip/tip.go | 40 +++++++++++-------------------------- 3 files changed, 63 insertions(+), 29 deletions(-) create mode 100644 cmd/tip/cert.go diff --git a/cmd/tip/Dockerfile b/cmd/tip/Dockerfile index 3604d521..86dfe364 100644 --- a/cmd/tip/Dockerfile +++ b/cmd/tip/Dockerfile @@ -126,7 +126,7 @@ RUN go install cloud.google.com/go/compute/metadata \ # 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 00000000..e00777b2 --- /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 30f18642..6e0fd47a 100644 --- a/cmd/tip/tip.go +++ b/cmd/tip/tip.go @@ -8,8 +8,6 @@ package main import ( "bufio" - "context" - "crypto/tls" "encoding/json" "errors" "flag" @@ -25,10 +23,6 @@ import ( "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 @@ var ( 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 @@ func main() { 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()