Skip to content

Commit

Permalink
UI: Use native go:embed instead of go-bindata (#6900)
Browse files Browse the repository at this point in the history
* UI: Use native go:embed instead of go-bindata

With this commit we migrate from the no longer actively maintained
go-bindata project, to go:embed, for embedding the UI app into the go
binary.

Signed-off-by: Jacob Baungard Hansen <[email protected]>

* UI: Remove static react app from .dockerignore

Otherwise we cannot build in e2e tests for example.

Signed-off-by: Jacob Baungard Hansen <[email protected]>

---------

Signed-off-by: Jacob Baungard Hansen <[email protected]>
  • Loading branch information
jacobbaungard authored Nov 18, 2023
1 parent d0198f7 commit 7895e27
Show file tree
Hide file tree
Showing 22 changed files with 174 additions and 531 deletions.
6 changes: 0 additions & 6 deletions .bingo/Variables.mk
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,6 @@ $(FAILLINT): $(BINGO_DIR)/faillint.mod
@echo "(re)installing $(GOBIN)/faillint-v1.11.0"
@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=faillint.mod -o=$(GOBIN)/faillint-v1.11.0 "github.com/fatih/faillint"

GO_BINDATA := $(GOBIN)/go-bindata-v3.1.1+incompatible
$(GO_BINDATA): $(BINGO_DIR)/go-bindata.mod
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
@echo "(re)installing $(GOBIN)/go-bindata-v3.1.1+incompatible"
@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=go-bindata.mod -o=$(GOBIN)/go-bindata-v3.1.1+incompatible "github.com/go-bindata/go-bindata/go-bindata"

GOIMPORTS := $(GOBIN)/goimports-v0.12.0
$(GOIMPORTS): $(BINGO_DIR)/goimports.mod
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
Expand Down
5 changes: 0 additions & 5 deletions .bingo/go-bindata.mod

This file was deleted.

2 changes: 0 additions & 2 deletions .bingo/go-bindata.sum

This file was deleted.

2 changes: 0 additions & 2 deletions .bingo/variables.env
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ BINGO="${GOBIN}/bingo-v0.8.1-0.20230820182247-0568407746a2"

FAILLINT="${GOBIN}/faillint-v1.11.0"

GO_BINDATA="${GOBIN}/go-bindata-v3.1.1+incompatible"

GOIMPORTS="${GOBIN}/goimports-v0.12.0"

GOJSONTOYAML="${GOBIN}/gojsontoyaml-v0.1.0"
Expand Down
3 changes: 0 additions & 3 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,4 @@ website/public/
website/docs-pre-processed/
!website/data

# React build assets
pkg/ui/static/react

tmp/
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ website/public/
website/docs-pre-processed/
!website/data

# React build assets
pkg/ui/static/react

tmp/bin
examples/tmp/

Expand Down
10 changes: 2 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,8 @@ $(REACT_APP_OUTPUT_DIR): $(REACT_APP_NODE_MODULES_PATH) $(REACT_APP_SOURCE_FILES
@echo ">> building React app"
@scripts/build-react-app.sh

.PHONY: assets
assets: # Repacks all static assets into go file for easier deploy.
assets: $(GO_BINDATA) $(REACT_APP_OUTPUT_DIR)
@echo ">> deleting asset file"
@rm pkg/ui/bindata.go || true
@echo ">> writing assets"
@$(GO_BINDATA) $(bindata_flags) -pkg ui -o pkg/ui/bindata.go pkg/ui/static/...
@$(MAKE) format
.PHONY: react-app
react-app: $(REACT_APP_OUTPUT_DIR)

.PHONY: react-app-lint
react-app-lint: $(REACT_APP_NODE_MODULES_PATH)
Expand Down
7 changes: 3 additions & 4 deletions pkg/ui/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
The `ui` package contains static files and templates used in the web UI. For
easier distribution they are statically compiled into the Thanos binary
using the go-bindata tool (c.f. Makefile).
easier distribution they are included in the Thanos binary using go:embed.

During development it is more convenient to always use the files on disk to
directly see changes without recompiling.
Set the environment variable `DEBUG=1` and compile Thanos for this to work.
This is for development purposes only.

After making changes to any file, run `make assets` before committing to update
the generated inline version of the file.
After making changes to any file, run `make react-app` before committing to update
the generated static files and templates.
492 changes: 0 additions & 492 deletions pkg/ui/bindata.go

This file was deleted.

2 changes: 1 addition & 1 deletion pkg/ui/react-app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,4 @@ To build a Thanos binary that includes a compiled-in version of the production b

This compiles in all web assets into the Thanos binary.

Note that `make build` only compiles static assets using `bindata.go`, if you are working on React UI, make sure you run `make assets` to update `pkg/ui/bindata.go`
Note that `make build` only compiles static assets in `pkg/ui/static/`, if you are working on React UI, make sure you run `make react-app` to update `pkg/ui/static/`.
15 changes: 15 additions & 0 deletions pkg/ui/static/react/asset-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"files": {
"main.css": "./static/css/main.5a4981c4.css",
"main.js": "./static/js/main.a00a7e6c.js",
"static/media/codicon.ttf": "./static/media/codicon.b3726f0165bf67ac6849.ttf",
"index.html": "./index.html",
"static/media/index.cjs": "./static/media/index.cd351d7c31d0d3fccf96.cjs",
"main.5a4981c4.css.map": "./static/css/main.5a4981c4.css.map",
"main.a00a7e6c.js.map": "./static/js/main.a00a7e6c.js.map"
},
"entrypoints": [
"static/css/main.5a4981c4.css",
"static/js/main.a00a7e6c.js"
]
}
Binary file added pkg/ui/static/react/favicon.ico
Binary file not shown.
1 change: 1 addition & 0 deletions pkg/ui/static/react/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="shortcut icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><meta name="theme-color" content="#000000"/><script>const GLOBAL_PATH_PREFIX="{{ pathPrefix }}"</script><script>const THANOS_COMPONENT="{{ .Component }}",THANOS_QUERY_URL="{{ .queryURL }}"</script><link rel="manifest" href="./manifest.json"/><title>Thanos | Highly available Prometheus setup</title><script defer="defer" src="./static/js/main.a00a7e6c.js"></script><link href="./static/css/main.5a4981c4.css" rel="stylesheet"></head><body class="bootstrap"><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
15 changes: 15 additions & 0 deletions pkg/ui/static/react/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"short_name": "Thanos",
"name": "Thanos web interface",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
6 changes: 6 additions & 0 deletions pkg/ui/static/react/static/css/main.5a4981c4.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pkg/ui/static/react/static/css/main.5a4981c4.css.map

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions pkg/ui/static/react/static/js/main.a00a7e6c.js

Large diffs are not rendered by default.

111 changes: 111 additions & 0 deletions pkg/ui/static/react/static/js/main.a00a7e6c.js.LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
object-assign
(c) Sindre Sorhus
@license MIT
*/

/*!
* Sizzle CSS Selector Engine v2.3.6
* https://sizzlejs.com/
*
* Copyright JS Foundation and other contributors
* Released under the MIT license
* https://js.foundation/
*
* Date: 2021-02-16
*/

/*!
Copyright (c) 2018 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/

/*!
* Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/

/*!
* is-plain-object <https://github.com/jonschlinkert/is-plain-object>
*
* Copyright (c) 2014-2017, Jon Schlinkert.
* Released under the MIT License.
*/

/*!
* jQuery JavaScript Library v3.6.0
* https://jquery.com/
*
* Includes Sizzle.js
* https://sizzlejs.com/
*
* Copyright OpenJS Foundation and other contributors
* Released under the MIT license
* https://jquery.org/license
*
* Date: 2021-03-02T17:08Z
*/

/*!@preserve
* Tempus Dominus Bootstrap4 v5.39.0 (https://tempusdominus.github.io/bootstrap-4/)
* Copyright 2016-2020 Jonathan Peterson and contributors
* Licensed under MIT (https://github.com/tempusdominus/bootstrap-3/blob/master/LICENSE)
*/

/** @license React v0.19.1
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/** @license React v16.13.1
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/** @license React v16.14.0
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/** @license React v16.14.0
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/** @license React v16.14.0
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

//! Copyright (c) JS Foundation and other contributors

//! github.com/moment/moment-timezone

//! license : MIT

//! moment-timezone.js

//! moment.js

//! version : 0.5.34
1 change: 1 addition & 0 deletions pkg/ui/static/react/static/js/main.a00a7e6c.js.map

Large diffs are not rendered by default.

Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let urlAlphabet="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict",customAlphabet=(t,e=21)=>(a=e)=>{let l="",o=a;for(;o--;)l+=t[Math.random()*t.length|0];return l},nanoid=(t=21)=>{let e="",a=t;for(;a--;)e+=urlAlphabet[64*Math.random()|0];return e};module.exports={nanoid:nanoid,customAlphabet:customAlphabet};
19 changes: 14 additions & 5 deletions pkg/ui/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ package ui

import (
"bytes"
"embed"
"html/template"
"io/fs"
"net/http"
"net/url"
"os"
Expand Down Expand Up @@ -39,6 +41,9 @@ var reactRouterPaths = []string{
"/tsdb-status",
}

//go:embed static/react
var reactUI embed.FS

type BaseUI struct {
logger log.Logger
tmplFuncs template.FuncMap
Expand All @@ -55,7 +60,7 @@ func NewBaseUI(logger log.Logger, funcMap template.FuncMap, tmplVariables map[st
}

func (bu *BaseUI) serveReactUI(w http.ResponseWriter, req *http.Request) {
bu.serveReactIndex("pkg/ui/static/react/index.html", w, req)
bu.serveReactIndex("static/react/index.html", w, req)
}

func (bu *BaseUI) serveReactIndex(index string, w http.ResponseWriter, req *http.Request) {
Expand All @@ -81,14 +86,18 @@ func (bu *BaseUI) serveReactIndex(index string, w http.ResponseWriter, req *http
}

func (bu *BaseUI) getAssetFile(filename string) (os.FileInfo, []byte, error) {
info, err := AssetInfo(filename)
filesys := fs.FS(reactUI)

info, err := fs.Stat(filesys, filename)
if err != nil {
return nil, nil, err
}
file, err := Asset(filename)

file, err := fs.ReadFile(filesys, filename)
if err != nil {
return nil, nil, err
}

return info, file, nil
}

Expand Down Expand Up @@ -142,7 +151,7 @@ func registerReactApp(r *route.Router, ins extpromhttp.InstrumentationMiddleware
// The favicon and manifest are bundled as part of the React app, but we want to serve
// them on the root.
for _, p := range []string{"/favicon.ico", "/manifest.json"} {
assetPath := "pkg/ui/static/react" + p
assetPath := "static/react" + p
r.Get(p, func(w http.ResponseWriter, r *http.Request) {
if err := bu.serveAsset(assetPath, w, r); err != nil {
level.Warn(bu.logger).Log("msg", "Could not get file", "err", err, "file", assetPath)
Expand All @@ -154,7 +163,7 @@ func registerReactApp(r *route.Router, ins extpromhttp.InstrumentationMiddleware
// Static files required by the React app.
r.Get("/static/*filepath", func(w http.ResponseWriter, r *http.Request) {
fp := route.Param(r.Context(), "filepath")
fp = filepath.Join("pkg/ui/static/react/static", fp)
fp = filepath.Join("static/react/static", fp)
if err := bu.serveAsset(fp, w, r); err != nil {
level.Warn(bu.logger).Log("msg", "Could not get file", "err", err, "file", fp)
w.WriteHeader(http.StatusNotFound)
Expand Down

0 comments on commit 7895e27

Please sign in to comment.