chore(backend): use Go 1.16 embed for static files

This commit is contained in:
Łukasz Mierzwa
2021-03-08 21:21:42 +00:00
committed by Łukasz Mierzwa
parent c0a54fb70e
commit 6f162d1a5a
22 changed files with 51 additions and 206 deletions
-1
View File
@@ -1,5 +1,4 @@
/coverage.txt
/cmd/karma/bindata_assetfs.go
/karma
/karma-*
/ui/build
-2
View File
@@ -1,4 +1,2 @@
run:
deadline: 5m
skip-files:
- bindata_assetfs.go
-18
View File
@@ -49,21 +49,3 @@ request.
To build and start `karma` from local branch see `Running` section of the
[README](README.md) file.
When working with assets (templates, stylesheets and javascript files) `DEBUG`
make variable can be set, which will recompile binary assets in debug mode,
meaning that files from disk will be read instead of compiled in assets.
See [go-bindata docs](https://github.com/jteeuwen/go-bindata#debug-vs-release-builds)
for details. Example:
make DEBUG=true run
make DEBUG=true run-docker
Note that this is not the same as enabling [debug mode](/README.md#debug) for
the [gin web framework](https://github.com/gin-gonic/gin) which is used
internally, but enabling `DEBUG` via this make variable will also enable gin
debug mode.
When running docker image via `make run-docker` with `DEBUG` make variable set
to `true` volume mapping will be added (in read-only mode), so that karma
instance running inside the docker can read asset files from the sources
directory.
+1 -2
View File
@@ -14,10 +14,9 @@ COPY make /src/make
COPY go.mod /src/go.mod
COPY go.sum /src/go.sum
RUN make -C /src download-deps-go
COPY tools/go-bindata /src/tools/go-bindata
RUN make -C /src install-deps-build-go
COPY --from=nodejs-builder /src/ui/src /src/ui/src
COPY --from=nodejs-builder /src/ui/build /src/ui/build
COPY --from=nodejs-builder /src/ui/embed.go /src/ui/embed.go
COPY cmd /src/cmd
COPY internal /src/internal
ARG VERSION
+1 -1
View File
@@ -15,7 +15,7 @@ test: lint
.PHONY: clean
clean:
rm -fr cmd/karma/bindata_assetfs.go $(NAME) $(NAME)-* ui/build ui/node_modules coverage.txt
rm -fr $(NAME) $(NAME)-* ui/build ui/node_modules coverage.txt
.PHONY: show-version
show-version:
+13 -56
View File
@@ -1,8 +1,6 @@
package main
import (
"errors"
"html/template"
"io"
"io/ioutil"
"mime"
@@ -11,58 +9,10 @@ import (
"strings"
"time"
assetfs "github.com/elazarl/go-bindata-assetfs"
"github.com/prymitive/karma/ui"
"github.com/rs/zerolog/log"
)
type binaryFileSystem struct {
fs http.FileSystem
}
func (b *binaryFileSystem) Open(name string) (http.File, error) {
return b.fs.Open(name)
}
func newBinaryFileSystem(root string) *binaryFileSystem {
fs := &assetfs.AssetFS{
Asset: Asset,
// Don't render directory index, return 404 for /static/ requests)
AssetDir: func(path string) ([]string, error) {
return nil, errors.New("not found")
},
Prefix: root,
}
return &binaryFileSystem{fs}
}
// load a template from binary asset resource
func loadTemplate(t *template.Template, path string) (*template.Template, error) {
templateContent, err := Asset(path)
if err != nil {
return nil, err
}
var tmpl *template.Template
if t == nil {
// if template wasn't yet initialized do it here
t = template.New(path)
}
if path == t.Name() {
tmpl = t
} else {
// if we already have an instance of template.Template then
// add a new file to it
tmpl = t.New(path)
}
_, err = tmpl.Parse(string(templateContent))
if err != nil {
return nil, err
}
return t, nil
}
func contentText(w http.ResponseWriter) {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
}
@@ -89,23 +39,30 @@ func serveFileOr404(path string, contentType string) http.HandlerFunc {
}
}
func serverStaticFiles(prefix string, fs *binaryFileSystem) func(next http.Handler) http.Handler {
func serverStaticFiles(prefix, root string) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fixedPath := strings.TrimPrefix(r.URL.Path, prefix)
filePath := strings.TrimSuffix(root, "/") + "/" + strings.TrimPrefix(fixedPath, "/")
log.Debug().Str("path", r.URL.Path).Str("root", root).Str("prefix", prefix).Str("filePath", filePath).Msg("Static file request")
if !strings.HasPrefix(r.URL.Path, prefix) {
log.Debug().Str("path", r.URL.Path).Str("prefix", prefix).Msg("Ignoring static file request")
next.ServeHTTP(w, r)
return
}
path := strings.TrimPrefix(r.URL.Path, prefix)
fl, err := fs.Open(path)
fl, err := ui.StaticFiles.Open(filePath)
if err != nil {
log.Debug().Str("path", r.URL.Path).Msg("Static file not found")
next.ServeHTTP(w, r)
return
}
defer fl.Close()
log.Debug().Str("path", r.URL.Path).Msg("Static file found")
ct := mime.TypeByExtension(filepath.Ext(path))
ct := mime.TypeByExtension(filepath.Ext(filePath))
if ct == "" {
ct = "application/octet-stream"
}
+13 -42
View File
@@ -2,7 +2,6 @@ package main
import (
"fmt"
"html/template"
"net/http/httptest"
"os"
"testing"
@@ -103,56 +102,18 @@ func TestStaticExpires404(t *testing.T) {
}
}
func TestLoadTemplateChained(t *testing.T) {
var tmpl *template.Template
tmpl, err := loadTemplate(tmpl, "ui/build/index.html")
if tmpl == nil {
t.Errorf("loadTemplate returned nil")
}
if err != nil {
t.Errorf("loadTemplate returned error: %s", err)
}
tmpl, err = loadTemplate(tmpl, "ui/build/manifest.json")
if tmpl == nil {
t.Errorf("loadTemplate returned nil")
}
if err != nil {
t.Errorf("loadTemplate returned error: %s", err)
}
if tmpl.Name() != "ui/build/index.html" {
t.Errorf("tmpl.Name() returned %q", tmpl.Name())
}
}
func TestLoadTemplateMissing(t *testing.T) {
_, err := loadTemplate(nil, "/this/file/does/not/exist")
if err == nil {
t.Error("loadTemplate() with invalid path didn't return any error")
}
}
func TestLoadTemplateUnparsable(t *testing.T) {
_, err := loadTemplate(nil, "cmd/karma/tests/bindata/go-test-invalid.html")
if err == nil {
t.Error("loadTemplate() with unparsable file didn't return any error")
}
}
func TestAssetFallbackMIME(t *testing.T) {
mockConfig()
r := testRouter()
r.Use(serverStaticFiles(getViewURL("/"), newBinaryFileSystem("cmd/karma/tests/bindata")))
setupRouter(r)
req := httptest.NewRequest("GET", "/bin.data", nil)
req := httptest.NewRequest("GET", "/static/js/App.tsx", nil)
resp := httptest.NewRecorder()
r.ServeHTTP(resp, req)
if resp.Code != 200 {
t.Errorf("Invalid status code for GET %s: %d", "/bin.data", resp.Code)
t.Errorf("Invalid status code for GET %s: %d", "/static/js/App.tsx", resp.Code)
}
if resp.Result().Header.Get("Content-Type") != "application/octet-stream" {
t.Errorf("Invalid Content-Type for GET /bin.data: %s, expected 'text/plain; charset=utf-8'", resp.Result().Header.Get("Content-Type"))
t.Errorf("Invalid Content-Type for GET /static/js/App.tsx: %s, expected 'text/plain; charset=utf-8'", resp.Result().Header.Get("Content-Type"))
}
}
@@ -189,6 +150,16 @@ func TestStaticFiles(t *testing.T) {
code: 404,
mime: "text/plain; charset=utf-8",
},
{
path: "/static/",
code: 404,
mime: "text/plain; charset=utf-8",
},
{
path: "/static/js/404.js",
code: 404,
mime: "text/plain; charset=utf-8",
},
}
mockConfig()
+5 -7
View File
@@ -24,6 +24,7 @@ import (
"github.com/prymitive/karma/internal/models"
"github.com/prymitive/karma/internal/transform"
"github.com/prymitive/karma/internal/uri"
"github.com/prymitive/karma/ui"
"github.com/getsentry/sentry-go"
sentryhttp "github.com/getsentry/sentry-go/http"
@@ -50,9 +51,6 @@ var (
// rather than do all the filtering every time
apiCache *cache.Cache
staticBuildFileSystem = newBinaryFileSystem("ui/build")
staticSrcFileSystem = newBinaryFileSystem("ui/src")
indexTemplate *template.Template
silenceACLs = []*silenceACL{}
@@ -96,13 +94,13 @@ func setupRouter(router *chi.Mux) {
compressor := middleware.NewCompressor(flate.DefaultCompression)
router.Use(compressor.Handler)
router.Use(serverStaticFiles(getViewURL("/"), staticBuildFileSystem))
router.Use(serverStaticFiles(getViewURL("/"), "build"))
// next 2 lines are to allow service raw sources so sentry can fetch source maps
router.Use(serverStaticFiles(getViewURL("/static/js/"), staticSrcFileSystem))
router.Use(serverStaticFiles(getViewURL("/static/js/"), "src"))
// FIXME
// compressed sources are under /static/js/main.js and reference ../static/js/main.js
// so we end up with /static/static/js
router.Use(serverStaticFiles(getViewURL("/static/static/js/"), staticSrcFileSystem))
router.Use(serverStaticFiles(getViewURL("/static/static/js/"), "src"))
router.Use(cors.Handler(cors.Options{
AllowOriginFunc: func(r *http.Request, origin string) bool {
return true
@@ -278,7 +276,7 @@ func setupLogger() error {
func loadTemplates() error {
var t *template.Template
t, err := loadTemplate(t, "ui/build/index.html")
t, err := template.ParseFS(ui.StaticFiles, "build/index.html")
if err != nil {
return fmt.Errorf("failed to load template: %s", err)
}
-1
View File
@@ -1 +0,0 @@
OK
@@ -1 +0,0 @@
hello{{range
+4 -5
View File
@@ -13,19 +13,18 @@ import (
"testing"
"time"
"github.com/go-chi/chi/v5"
"github.com/prymitive/karma/internal/alertmanager"
"github.com/prymitive/karma/internal/config"
"github.com/prymitive/karma/internal/mock"
"github.com/prymitive/karma/internal/models"
"github.com/prymitive/karma/internal/slices"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
cache "github.com/patrickmn/go-cache"
"github.com/go-chi/chi/v5"
"github.com/google/go-cmp/cmp"
"github.com/jarcoal/httpmock"
cache "github.com/patrickmn/go-cache"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/pflag"
)
+1 -2
View File
@@ -14,10 +14,9 @@ COPY make /src/make
COPY go.mod /src/go.mod
COPY go.sum /src/go.sum
RUN make -C /src download-deps-go
COPY tools/go-bindata /src/tools/go-bindata
RUN make -C /src install-deps-build-go
COPY --from=nodejs-builder /src/ui/src /src/ui/src
COPY --from=nodejs-builder /src/ui/build /src/ui/build
COPY --from=nodejs-builder /src/ui/embed.go /src/ui/embed.go
COPY cmd /src/cmd
COPY internal /src/internal
ARG VERSION
-1
View File
@@ -5,7 +5,6 @@ go 1.16
require (
github.com/Masterminds/semver/v3 v3.1.1
github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08
github.com/elazarl/go-bindata-assetfs v1.0.1
github.com/fvbommel/sortorder v1.0.2
github.com/getsentry/sentry-go v0.10.0
github.com/go-chi/chi/v5 v5.0.0
-2
View File
@@ -86,8 +86,6 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw=
github.com/elazarl/go-bindata-assetfs v1.0.1/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+1 -1
View File
@@ -1,7 +1,7 @@
include make/vars.mk
word-split = $(word $2,$(subst -, ,$1))
cc-%: go.mod go.sum cmd/karma/bindata_assetfs.go $(SOURCES_GO)
cc-%: go.mod go.sum $(SOURCES_GO) ui/build/index.html
$(eval GOOS := $(call word-split,$*,1))
$(eval GOARCH := $(call word-split,$*,2))
$(eval GOARM := $(call word-split,$*,3))
+4 -15
View File
@@ -8,15 +8,8 @@ endif
ui/build/index.html: $(call rwildcard, ui/src ui/package.json ui/package-lock.json, *)
@$(MAKE) -C ui build
$(GOBIN)/go-bindata: tools/go-bindata/go.mod tools/go-bindata/go.sum
go install -modfile=tools/go-bindata/go.mod github.com/go-bindata/go-bindata/...
$(GOBIN)/go-bindata-assetfs: $(GOBIN)/go-bindata tools/go-bindata/go.mod tools/go-bindata/go.sum
go install -modfile=tools/go-bindata/go.mod github.com/elazarl/go-bindata-assetfs/...
cmd/karma/bindata_assetfs.go: $(GOBIN)/go-bindata-assetfs $(SOURCES_JS) ui/build/index.html
env PATH="$(PATH):$(GOBIN)" $(GOBIN)/go-bindata-assetfs -o cmd/karma/bindata_assetfs.go ui/build/... ui/src/... cmd/karma/tests/bindata/...
.DEFAULT_GOAL := $(NAME)
$(NAME): go.mod go.sum cmd/karma/bindata_assetfs.go $(SOURCES_GO)
$(NAME): go.mod go.sum $(SOURCES_GO) ui/build/index.html
go build -ldflags "-X main.version=$(VERSION)" ./cmd/karma
.PHONY: test-go
@@ -63,21 +56,17 @@ download-deps-go:
@for f in $(wildcard tools/*/go.mod) ; do echo ">>> $$f" && cd $(CURDIR)/`dirname "$$f"` && go mod download && cd $(CURDIR) ; done
go mod download
.PHONY: install-deps-build-go
install-deps-build-go: $(GOBIN)/go-bindata-assetfs
.PHONY: openapi-client
openapi-client:
for f in $(wildcard internal/mapper/*/Dockerfile) ; do $(MAKE) -C `dirname "$$f"` ; done
# Creates mock bindata_assetfs.go with source assets
.PHONY: mock-assets
mock-assets: $(GOBIN)/go-bindata-assetfs
mock-assets:
rm -fr ui/build
mkdir ui/build
cp ui/public/* ui/build/
env PATH="$(PATH):$(GOBIN)" $(GOBIN)/go-bindata-assetfs -o cmd/karma/bindata_assetfs.go -nometadata ui/build/... cmd/karma/tests/bindata/...
rm -fr ui/build
mkdir ui/build/static
touch ui/build/static/main.js
.PHONY: tools-go-mod-tidy
tools-go-mod-tidy:
+1 -1
View File
@@ -7,4 +7,4 @@ VERSION ?= $(shell git describe --tags --always --dirty='-dev')
rwildcard = $(foreach d, $(wildcard $1*), $(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
SOURCES_GO = $(call rwildcard, cmd internal, *)
SOURCES_JS = $(call rwildcard, ui/build/index.html ui/src cmd/karma/test/bindata, *)
SOURCES_JS = $(call rwildcard, ui/build/index.html ui/src, *)
-1
View File
@@ -6,7 +6,6 @@ set -o pipefail
echo "mode: set" > coverage.txt
cat profile.* \
| grep -v mode: \
| grep -vE '^github.com/prymitive/karma/cmd/karma/bindata_assetfs.go:' \
| sort -r \
| awk '{if($1 != last) {print $0;last=$1}}' >> coverage.txt
rm -f profile.*
-9
View File
@@ -1,9 +0,0 @@
module _
go 1.14
require (
github.com/elazarl/go-bindata-assetfs v1.0.1
github.com/go-bindata/go-bindata/v3 v3.1.3
golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770 // indirect
)
-30
View File
@@ -1,30 +0,0 @@
github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw=
github.com/elazarl/go-bindata-assetfs v1.0.1/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
github.com/go-bindata/go-bindata/v3 v3.1.3 h1:F0nVttLC3ws0ojc7p60veTurcOm//D4QBODNM7EGrCI=
github.com/go-bindata/go-bindata/v3 v3.1.3/go.mod h1:1/zrpXsLD8YDIbhZRqXzm1Ghc7NhEvIN9+Z6R5/xH4I=
github.com/kisielk/errcheck v1.2.0 h1:reN85Pxc5larApoH1keMBiu2GWtPqXQ1nc9gx+jOU+E=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770 h1:M9Fif0OxNji8w+HvmhVQ8KJtiZOsjU9RgslJGhn95XE=
golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-8
View File
@@ -1,8 +0,0 @@
// +build tools
package tools
import (
_ "github.com/elazarl/go-bindata-assetfs"
_ "github.com/go-bindata/go-bindata/v3"
)
+7
View File
@@ -0,0 +1,7 @@
package ui
import "embed"
//go:embed build/* src/*
var StaticFiles embed.FS