From fc16580b4ce3354a30b290b714a07f1ebd678ef6 Mon Sep 17 00:00:00 2001 From: Johannes 'fish' Ziemke Date: Mon, 18 Mar 2013 17:48:50 +0100 Subject: [PATCH] Ship assets in compiled binary. - utility/embed-static.sh, get called in Makefile to create go map from files - web/blob/blob.go implements http Handle for serving the files from the map - web/status.go uses blog.GetFile() to get the template file The assets are gzipped and decompressed on demand. --- .gitignore | 1 + Makefile | 2 ++ utility/embed-static.sh | 38 ++++++++++++++++++++++++++++++++++++ web/blob/blob.go | 43 +++++++++++++++++++++++++++++++++++++++++ web/status.go | 9 ++++++++- web/web.go | 3 ++- 6 files changed, 94 insertions(+), 2 deletions(-) create mode 100755 utility/embed-static.sh create mode 100644 web/blob/blob.go diff --git a/.gitignore b/.gitignore index 93fe42cb5..281b2bb72 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ [568a].out _cgo_* core +web/blob/files.go diff --git a/Makefile b/Makefile index 9dc694f15..6c2367b5c 100644 --- a/Makefile +++ b/Makefile @@ -19,11 +19,13 @@ test: build go test ./... build: + ./utility/embed-static.sh web/static web/templates > web/blob/files.go $(MAKE) -C model go build ./... go build -o prometheus.build clean: + rm -rf web/static/blob/files.go rm -rf $(TEST_ARTIFACTS) $(MAKE) -C model clean -find . -type f -iname '*~' -exec rm '{}' ';' diff --git a/utility/embed-static.sh b/utility/embed-static.sh new file mode 100755 index 000000000..0cf0fcb86 --- /dev/null +++ b/utility/embed-static.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +cat < $type_file +var types = map [string] map [string] string { +EOF + + +for dir in $@ +do + pushd "$dir" > /dev/null + echo -e "\t\"`basename $dir`\": {" + echo -e "\t\"`basename $dir`\": {" >> $type_file + + find -type f | while read file + do + mime=`mimetype -b "$file"` + name=`echo "$file"|sed 's|\.\/||'` + echo -e "\t\t\"$name\": \"$mime\"," >> $type_file + + echo -e "\t\t\"$name\": {" + gzip -9 -c "$file" | xxd -p |sed 's/\(..\)/0x\1, /g' + echo -e "\t\t}," + echo + done + echo -e "\t}," >> $type_file + echo -e "\t}," + popd > /dev/null +done +echo '}' +cat $type_file +echo '}' +rm $type_file diff --git a/web/blob/blob.go b/web/blob/blob.go new file mode 100644 index 000000000..479cba5bb --- /dev/null +++ b/web/blob/blob.go @@ -0,0 +1,43 @@ +package blob + +import ( + "bytes" + "compress/gzip" + "io" + "log" + "net/http" +) + +func GetFile(bucket string, name string) ([]byte, error) { + reader := bytes.NewReader(files[bucket][name]) + gz, err := gzip.NewReader(reader) + if err != nil { + return nil, err + } + + var b bytes.Buffer + io.Copy(&b, gz) + gz.Close() + + return b.Bytes(), nil +} + +type Handler struct{} + +func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + name := r.URL.String() + if name == "" { + name = "index.html" + } + + file, err := GetFile("static", name) + if err != nil { + if err != io.EOF { + log.Printf("Could not get file: %s", err) + } + w.WriteHeader(http.StatusNotFound) + return + } + w.Header().Set("Content-Type", types["static"][name]) + w.Write(file) +} diff --git a/web/status.go b/web/status.go index f8a7ed0ae..c30cd4268 100644 --- a/web/status.go +++ b/web/status.go @@ -16,7 +16,9 @@ package web import ( "github.com/prometheus/prometheus/appstate" "github.com/prometheus/prometheus/retrieval" + "github.com/prometheus/prometheus/web/blob" "html/template" + "log" "net/http" ) @@ -38,6 +40,11 @@ func (h *StatusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { Status: "TODO: add status information here", TargetPools: h.appState.TargetManager.Pools(), } - t, _ := template.ParseFiles("web/templates/status.html") + template_file, err := blob.GetFile("templates", "status.html") + if err != nil { + log.Fatalf("Could not read template: %s", err) + } + + t, _ := template.New("status").Parse(string(template_file)) t.Execute(w, status) } diff --git a/web/web.go b/web/web.go index 827d3bad8..b7a9f4350 100644 --- a/web/web.go +++ b/web/web.go @@ -19,6 +19,7 @@ import ( "github.com/prometheus/client_golang" "github.com/prometheus/prometheus/appstate" "github.com/prometheus/prometheus/web/api" + "github.com/prometheus/prometheus/web/blob" "net/http" _ "net/http/pprof" ) @@ -35,7 +36,7 @@ func StartServing(appState *appstate.ApplicationState) { http.Handle("/status", &StatusHandler{appState: appState}) http.Handle("/api/", gorest.Handle()) http.Handle("/metrics.json", exporter) - http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("web/static")))) + http.Handle("/static/", http.StripPrefix("/static/", new(blob.Handler))) go http.ListenAndServe(*listenAddress, nil) }