mirror of
https://github.com/golang/go.git
synced 2025-05-28 10:51:22 +00:00
cmd/tip: move tip.golang.org from App Engine to Kubernetes on GKE
Change-Id: I52ca7eaca98de27bd920ae01086b3f7724819738 Reviewed-on: https://go-review.googlesource.com/37754 Reviewed-by: Chris Broadfoot <cbro@golang.org>
This commit is contained in:
parent
767744efe2
commit
03d3934baf
@ -1,13 +1,15 @@
|
||||
FROM golang:1.6
|
||||
FROM golang:1.8
|
||||
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y -q build-essential git
|
||||
|
||||
# golang puts its go install here (weird but true)
|
||||
ENV GOROOT_BOOTSTRAP /usr/local/go
|
||||
|
||||
RUN go get -d golang.org/x/crypto/acme/autocert
|
||||
|
||||
# golang sets GOPATH=/go
|
||||
ADD . /go/src/tip
|
||||
RUN go install tip
|
||||
ENTRYPOINT ["/go/bin/tip"]
|
||||
# Kubernetes expects us to listen on port 8080
|
||||
# App Engine expects us to listen on port 8080
|
||||
EXPOSE 8080
|
||||
|
15
cmd/tip/Makefile
Normal file
15
cmd/tip/Makefile
Normal file
@ -0,0 +1,15 @@
|
||||
# Copyright 2017 The Go Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
VERSION=v1
|
||||
|
||||
docker-prod: Dockerfile
|
||||
docker build -f Dockerfile --tag=gcr.io/symbolic-datum-552/tip:$(VERSION) .
|
||||
docker-dev: Dockerfile
|
||||
docker build -f Dockerfile --tag=gcr.io/go-dashboard-dev/tip:$(VERSION) .
|
||||
|
||||
push-prod: docker-prod
|
||||
gcloud docker push -- gcr.io/symbolic-datum-552/tip:$(VERSION)
|
||||
push-dev: docker-dev
|
||||
gcloud docker push -- gcr.io/go-dashboard-dev/tip:$(VERSION)
|
@ -1,7 +1,11 @@
|
||||
============================================================
|
||||
Old instructions, only valid for talks.golang.org:
|
||||
============================================================
|
||||
|
||||
1. Deploy the app.
|
||||
|
||||
To deploy tip.golang.org:
|
||||
$ gcloud --project golang-org app deploy --no-promote godoc.yaml
|
||||
(See Kubernetes instruction below.)
|
||||
|
||||
To deploy talks.golang.org:
|
||||
$ gcloud --project golang-org app deploy --no-promote talks.yaml
|
||||
@ -12,3 +16,18 @@
|
||||
https://console.developers.google.com/appengine/versions?project=golang-org&moduleId=tip
|
||||
|
||||
4. Clean up any old versions (they continue to use at least one instance).
|
||||
|
||||
============================================================
|
||||
New Kubernetes instructions, for tip.golang.org:
|
||||
============================================================
|
||||
|
||||
Kubernetes instructions:
|
||||
|
||||
* build & push images (see Makefile for helpers)
|
||||
* create/update resources:
|
||||
- kubectl create -f tip-rc.yaml
|
||||
- kubectl create -f tip-service.yaml
|
||||
|
||||
TODO(bradfitz): flesh out these instructions as I gain experience
|
||||
with updating this over time. Also: move talks.golang.org to GKE too?
|
||||
|
||||
|
@ -17,7 +17,7 @@ type godocBuilder struct {
|
||||
}
|
||||
|
||||
func (b godocBuilder) Signature(heads map[string]string) string {
|
||||
return heads["go"] + "-" + heads["tools"]
|
||||
return fmt.Sprintf("go=%v/tools=%v", heads["go"], heads["tools"])
|
||||
}
|
||||
|
||||
func (b godocBuilder) Init(dir, hostport string, heads map[string]string) (*exec.Cmd, error) {
|
||||
|
40
cmd/tip/tip-rc.yaml
Normal file
40
cmd/tip/tip-rc.yaml
Normal file
@ -0,0 +1,40 @@
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: tipgodoc-v1
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
app: tipgodoc
|
||||
template:
|
||||
metadata:
|
||||
name: tipgodoc
|
||||
labels:
|
||||
app: tipgodoc
|
||||
spec:
|
||||
volumes:
|
||||
- name: cache-volume
|
||||
emptyDir: {}
|
||||
containers:
|
||||
- name: gitmirror
|
||||
image: gcr.io/symbolic-datum-552/tip:v1
|
||||
imagePullPolicy: Always
|
||||
command: ["/go/bin/tip", "--autocert=tip.golang.org"]
|
||||
env:
|
||||
- name: TMPDIR
|
||||
value: /build
|
||||
- name: TIP_BUILDER
|
||||
value: godoc
|
||||
volumeMounts:
|
||||
- mountPath: /build
|
||||
name: cache-volume
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
- containerPort: 443
|
||||
resources:
|
||||
requests:
|
||||
cpu: "1"
|
||||
memory: "2Gi"
|
||||
limits:
|
||||
cpu: "2"
|
||||
memory: "4Gi"
|
16
cmd/tip/tip-service.yaml
Normal file
16
cmd/tip/tip-service.yaml
Normal file
@ -0,0 +1,16 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: tipgodoc
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 8080
|
||||
name: http
|
||||
- port: 443
|
||||
targetPort: 443
|
||||
name: https
|
||||
selector:
|
||||
app: tipgodoc
|
||||
type: LoadBalancer
|
||||
loadBalancerIP: 130.211.180.236
|
@ -8,8 +8,10 @@ package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@ -22,6 +24,8 @@ import (
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/acme/autocert"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -30,7 +34,15 @@ const (
|
||||
startTimeout = 10 * time.Minute
|
||||
)
|
||||
|
||||
var startTime = time.Now()
|
||||
|
||||
var (
|
||||
autoCertDomain = flag.String("autocert", "", "if non-empty, listen on port 443 and serve a LetsEncrypt cert for this hostname")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
const k = "TIP_BUILDER"
|
||||
var b Builder
|
||||
switch os.Getenv(k) {
|
||||
@ -47,9 +59,28 @@ func main() {
|
||||
http.Handle("/", httpsOnlyHandler{p})
|
||||
http.HandleFunc("/_ah/health", p.serveHealthCheck)
|
||||
|
||||
log.Print("Starting up")
|
||||
log.Printf("Starting up tip server for builder %q", os.Getenv(k))
|
||||
|
||||
if err := http.ListenAndServe(":8080", nil); err != nil {
|
||||
errc := make(chan error)
|
||||
|
||||
go func() {
|
||||
errc <- http.ListenAndServe(":8080", nil)
|
||||
}()
|
||||
if *autoCertDomain != "" {
|
||||
log.Printf("Listening on port 443 with LetsEncrypt support on domain %q", *autoCertDomain)
|
||||
m := autocert.Manager{
|
||||
Prompt: autocert.AcceptTOS,
|
||||
HostPolicy: autocert.HostWhitelist(*autoCertDomain),
|
||||
}
|
||||
s := &http.Server{
|
||||
Addr: ":https",
|
||||
TLSConfig: &tls.Config{GetCertificate: m.GetCertificate},
|
||||
}
|
||||
go func() {
|
||||
errc <- s.ListenAndServeTLS("", "")
|
||||
}()
|
||||
}
|
||||
if err := <-errc; err != nil {
|
||||
p.stop()
|
||||
log.Fatal(err)
|
||||
}
|
||||
@ -98,14 +129,17 @@ func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
func (p *Proxy) serveStatus(w http.ResponseWriter, r *http.Request) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
fmt.Fprintf(w, "side=%v\ncurrent=%v\nerror=%v\n", p.side, p.cur, p.err)
|
||||
fmt.Fprintf(w, "side=%v\ncurrent=%v\nerror=%v\nuptime=%v\n", p.side, p.cur, p.err, int(time.Since(startTime).Seconds()))
|
||||
}
|
||||
|
||||
func (p *Proxy) serveHealthCheck(w http.ResponseWriter, r *http.Request) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
// NOTE: Status 502, 503, 504 are the only status codes that signify an unhealthy app.
|
||||
// So long as this handler returns one of those codes, this instance will not be sent any requests.
|
||||
|
||||
// NOTE: (App Engine only; not GKE) Status 502, 503, 504 are
|
||||
// the only status codes that signify an unhealthy app. So
|
||||
// long as this handler returns one of those codes, this
|
||||
// instance will not be sent any requests.
|
||||
if p.proxy == nil {
|
||||
log.Printf("Health check: not ready")
|
||||
http.Error(w, "Not ready", http.StatusServiceUnavailable)
|
||||
@ -266,11 +300,13 @@ func checkout(repo, hash, path string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var timeoutClient = &http.Client{Timeout: 10 * time.Second}
|
||||
|
||||
// gerritMetaMap returns the map from repo name (e.g. "go") to its
|
||||
// latest master hash.
|
||||
// The returned map is nil on any transient error.
|
||||
func gerritMetaMap() map[string]string {
|
||||
res, err := http.Get(metaURL)
|
||||
res, err := timeoutClient.Get(metaURL)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
@ -309,7 +345,7 @@ func gerritMetaMap() map[string]string {
|
||||
}
|
||||
|
||||
func getOK(url string) (body []byte, err error) {
|
||||
res, err := http.Get(url)
|
||||
res, err := timeoutClient.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user