From 725dcd26e86b0fd798272aa04861b5304f9c9983 Mon Sep 17 00:00:00 2001 From: Mechiel Lukkien Date: Wed, 22 May 2019 13:39:20 +0200 Subject: [PATCH] add /info endpoint with build information clear out release.sh --- Makefile | 21 +--- fabricate/fabricate.go | 1 + go.mod | 1 + go.sum | 2 + httpserve.go | 11 ++ main.go | 6 +- release.sh | 20 ---- vendor/github.com/mjl-/httpinfo/LICENSE | 7 ++ vendor/github.com/mjl-/httpinfo/README.txt | 5 + vendor/github.com/mjl-/httpinfo/go.mod | 3 + vendor/github.com/mjl-/httpinfo/httpinfo.go | 114 ++++++++++++++++++++ vendor/modules.txt | 2 + 12 files changed, 153 insertions(+), 40 deletions(-) delete mode 100755 release.sh create mode 100644 vendor/github.com/mjl-/httpinfo/LICENSE create mode 100644 vendor/github.com/mjl-/httpinfo/README.txt create mode 100644 vendor/github.com/mjl-/httpinfo/go.mod create mode 100644 vendor/github.com/mjl-/httpinfo/httpinfo.go diff --git a/Makefile b/Makefile index b7cce4f..1940b6b 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,6 @@ run: build run-root: build sudo ./ding serve local/local-root.conf - build: go build go vet @@ -16,24 +15,8 @@ frontend: test: golint - go test -cover . -- local/local-test.conf - -coverage: - go test -coverprofile=coverage.out -test.outputdir . -- local/local-test.conf - go tool cover -html=coverage.out - -fmt: - go fmt . - -release: - -mkdir local 2>/dev/null - (cd assets && zip -qr0 ../assets.zip .) - env GOOS=linux GOARCH=amd64 ./release.sh - env GOOS=linux GOARCH=386 ./release.sh - env GOOS=linux GOARCH=arm GOARM=6 ./release.sh - env GOOS=linux GOARCH=arm64 ./release.sh - env GOOS=darwin GOARCH=amd64 ./release.sh - env GOOS=openbsd GOARCH=amd64 ./release.sh + go test -race -coverprofile cover.out -- local/local-test.conf + go tool cover -html=cover.out -o cover.html clean: go clean diff --git a/fabricate/fabricate.go b/fabricate/fabricate.go index 88f7e7b..4f2f54a 100644 --- a/fabricate/fabricate.go +++ b/fabricate/fabricate.go @@ -157,6 +157,7 @@ func build(dest string) { []string{"www-src/licenses/angularjs-1.5.7"}}, {"UI Bootstrap 1.3.3", []string{"www-src/licenses/ui-bootstrap-1.3.3"}}, + {"", []string{"vendor/github.com/mjl-/httpinfo/LICENSE"}}, {"", []string{"vendor/github.com/mjl-/sherpa/LICENSE"}}, {"", []string{"vendor/bitbucket.org/mjl/httpasset/LICENSE"}}, {"", []string{"vendor/github.com/mjl-/sconf/LICENSE"}}, diff --git a/go.mod b/go.mod index b45d545..58e18be 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.12 require ( bitbucket.org/mjl/httpasset v0.0.4 github.com/lib/pq v1.1.1 + github.com/mjl-/httpinfo v0.0.2 github.com/mjl-/sconf v0.0.0-20190512072357-ca074d2407b2 github.com/mjl-/sherpa v0.6.0 github.com/mjl-/sherpadoc v0.0.0-20190505200843-c0a7f43f5f1d diff --git a/go.sum b/go.sum index 3e2f0f1..76fc039 100644 --- a/go.sum +++ b/go.sum @@ -22,6 +22,8 @@ github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4= github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mjl-/httpinfo v0.0.2 h1:6lSs4JowAuZeqx3OlTsBaYQjmlPo/5pqQdbFBhMjt/o= +github.com/mjl-/httpinfo v0.0.2/go.mod h1:o/nQc5HN+F0rwF5dFOcU11wqsLUePZuXOMAIsL/HglU= github.com/mjl-/sconf v0.0.0-20190512072357-ca074d2407b2 h1:gJIMFIUb3dMd/pWgeoNGled+wRcqkK0Q3IHwJYqN4Io= github.com/mjl-/sconf v0.0.0-20190512072357-ca074d2407b2/go.mod h1:DX63hxdqGErxyNhsm5guT7SXiP2GfoD/W+Yk7KOKWws= github.com/mjl-/sherpa v0.6.0 h1:lNu86b3htqJVhftOOxAxJwfIZ5Xuo6lz1ifiZZ096Do= diff --git a/httpserve.go b/httpserve.go index 8436add..4832db4 100644 --- a/httpserve.go +++ b/httpserve.go @@ -16,6 +16,7 @@ import ( "strconv" "strings" + "github.com/mjl-/httpinfo" "github.com/mjl-/sherpa" "github.com/mjl-/sherpadoc" "github.com/mjl-/sherpaprom" @@ -102,6 +103,16 @@ func servehttp(args []string) { handler, err := sherpa.NewHandler("/ding/", version, Ding{}, &doc, opts) check(err, "making sherpa handler") + // Since we set the version variables with ldflags -X, we cannot read them in the vars section. + // So we combine them into a CodeVersion during init, and add the handler while we're at it. + info := httpinfo.CodeVersion{ + CommitHash: vcsCommitHash, + Tag: vcsTag, + Branch: vcsBranch, + Full: version, + } + http.Handle("/info", httpinfo.NewHandler(info, nil)) + http.HandleFunc("/", serveAsset) http.Handle("/ding/", handler) http.Handle("/metrics", promhttp.Handler()) diff --git a/main.go b/main.go index 55854b0..ec57266 100644 --- a/main.go +++ b/main.go @@ -23,8 +23,12 @@ const ( var ( httpFS http.FileSystem - version = "dev" database *sql.DB + + version = "dev" + vcsCommitHash = "" + vcsTag = "" + vcsBranch = "" ) var config struct { diff --git a/release.sh b/release.sh deleted file mode 100755 index 1467fca..0000000 --- a/release.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh -set -e - -exec env GOOS=$GOOS GOARCH=$GOARCH \ -NAME=$(basename $PWD) \ -VERSION=$(git describe --tags | sed 's/^v//') \ -GOVERSION=$(go version | cut -f3 -d' ') \ -sh -c ' - set -e - export CGO_ENABLED=0 - SUFFIX="" - if test $GOOS = windows; then - SUFFIX=.exe - fi - DEST=local/${NAME}-${VERSION:-x}-${GOOS:-x}-${GOARCH:-x}-${GOVERSION:-x}-${BUILDID:-0}${SUFFIX} - go build -ldflags "-X main.version=${VERSION:-x}" - mv $NAME${SUFFIX} $DEST - sh -c "cat assets.zip >>$DEST" - echo release: $NAME $VERSION $GOOS $GOARCH $GOVERSION $DEST -' diff --git a/vendor/github.com/mjl-/httpinfo/LICENSE b/vendor/github.com/mjl-/httpinfo/LICENSE new file mode 100644 index 0000000..b90262c --- /dev/null +++ b/vendor/github.com/mjl-/httpinfo/LICENSE @@ -0,0 +1,7 @@ +Copyright (c) 2019 Mechiel Lukkien + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/mjl-/httpinfo/README.txt b/vendor/github.com/mjl-/httpinfo/README.txt new file mode 100644 index 0000000..98f3066 --- /dev/null +++ b/vendor/github.com/mjl-/httpinfo/README.txt @@ -0,0 +1,5 @@ +httpinfo - Go HTTP handler returning build information (dependencies, runtime, versions). + +Documentation at https://godoc.org/github.com/mjl-/httpinfo. + +MIT-licensed. diff --git a/vendor/github.com/mjl-/httpinfo/go.mod b/vendor/github.com/mjl-/httpinfo/go.mod new file mode 100644 index 0000000..789c0aa --- /dev/null +++ b/vendor/github.com/mjl-/httpinfo/go.mod @@ -0,0 +1,3 @@ +module github.com/mjl-/httpinfo + +go 1.12 diff --git a/vendor/github.com/mjl-/httpinfo/httpinfo.go b/vendor/github.com/mjl-/httpinfo/httpinfo.go new file mode 100644 index 0000000..c7a0a15 --- /dev/null +++ b/vendor/github.com/mjl-/httpinfo/httpinfo.go @@ -0,0 +1,114 @@ +/* +Package httpinfo provides an HTTP handler serving build information (compiler used, modules included, VCS versions) about a running service. + +Example usage: + + // Variables with versions for your service. Set them at compile time like so: + // go build -ldflags "-X main.vcsCommitHash=${COMMITHASH} -X main.vcsTag=${TAG} -X main.vcsBranch=${BRANCH} -X main.version=${VERSION}" + var ( + version = "dev" + vcsCommitHash = "" + vcsTag = "" + vcsBranch = "" + ) + + func init() { + // Since we set the version variables with ldflags -X, we cannot read them in the vars section. + // So we combine them into a CodeVersion during init, and add the handler while we're at it. + info := httpinfo.CodeVersion{ + CommitHash: vcsCommitHash, + Tag: vcsTag, + Branch: vcsBranch, + Full: version, + } + http.Handle("/info", httpinfo.NewHandler(info, nil)) + } +*/ +package httpinfo + +import ( + "encoding/json" + "log" + "net/http" + "os" + "runtime" + "runtime/debug" + "time" +) + +// Info is returned by the handler encoded as JSON. +type Info struct { + BuildInfo *debug.BuildInfo // Modules used in the service. + Time time.Time // Current time at server. + Go GoVersion // Go compiler information. + Hostname string // Hostname currently running on. + Version CodeVersion // VCS version information for service. + More interface{} // Other information you want to store. +} + +// CodeVersion specifies the exact version of a VCS code repository. +type CodeVersion struct { + CommitHash string // E.g. "d6d03be3edea736a79d925c736c1dfc0185a3bb9" + Tag string // E.g. "v0.1.2". Should be empty when the commit isn't tagged. + Branch string // E.g. "master". + Full string // Full description of version, may included tags and commits after tag. E.g. "0.1.2" for a cleanly tagged version. Or "0.2.0-15-gf247de4" for a tagged version plus changes and a short git commit hash. +} + +// GoVersion specifies the Go compiler and runtime this application is running under. +type GoVersion struct { + Compiler string // From runtime.Compiler. + Arch string // One of the GOARCH values. + Os string // One of the GOOS values. + Version string // E.g. "1.12.2". +} + +type infoHandler struct { + BuildInfo *debug.BuildInfo + GoVersion GoVersion + CodeVersion CodeVersion + more func() interface{} +} + +// NewHandler returns a http handler serving service information for each GET request it receives. +// Buildinfo and Go version information is collected immediately. +// More should return a JSON-encodable value that will also be included. More can be nil. If set it is called for each request. +func NewHandler(version CodeVersion, more func() interface{}) http.Handler { + bi, ok := debug.ReadBuildInfo() + if !ok { + log.Println("no buildinfo available for /info") + } + gov := GoVersion{ + Compiler: runtime.Compiler, + Arch: runtime.GOARCH, + Os: runtime.GOOS, + Version: runtime.Version(), + } + return infoHandler{bi, gov, version, more} +} + +// ServeHTTP serves GET requests with a JSON-encoded Info. +func (h infoHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, "method not allowed", http.StatusMethodNotAllowed) + return + } + + var more interface{} + if h.more != nil { + more = h.more() + } + hostname, _ := os.Hostname() + var info = Info{ + BuildInfo: h.BuildInfo, + Time: time.Now(), + Go: h.GoVersion, + Hostname: hostname, + Version: h.CodeVersion, + More: more, + } + w.Header().Set("Content-Type", "application/json; charset=utf-8") + err := json.NewEncoder(w).Encode(info) + if err != nil { + log.Printf("writing info: %s\n", err) + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index ae81826..a825cc5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -10,6 +10,8 @@ github.com/lib/pq/oid github.com/lib/pq/scram # github.com/matttproud/golang_protobuf_extensions v1.0.1 github.com/matttproud/golang_protobuf_extensions/pbutil +# github.com/mjl-/httpinfo v0.0.2 +github.com/mjl-/httpinfo # github.com/mjl-/sconf v0.0.0-20190512072357-ca074d2407b2 github.com/mjl-/sconf # github.com/mjl-/sherpa v0.6.0