Skip to content

Commit

Permalink
replace go-bindata with vfsgen (#521)
Browse files Browse the repository at this point in the history
Signed-off-by: niedhui <niedhui@gmail.com>
  • Loading branch information
niedhui authored May 28, 2020
1 parent 9026010 commit be659b1
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 121 deletions.
4 changes: 2 additions & 2 deletions cmd/tidb-dashboard/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ func main() {
log.Fatal("Dashboard server listen failed", zap.String("addr", listenAddr), zap.Error(err))
}

uiserver.InitAssetFS(cliConfig.CoreConfig.PathPrefix)
uiserver.RewriteAssetsPublicPath(cliConfig.CoreConfig.PathPrefix)
s := apiserver.NewService(
cliConfig.CoreConfig,
apiserver.StoppedHandler,
Expand All @@ -204,7 +204,7 @@ func main() {
defer s.Stop(context.Background()) //nolint:errcheck

mux := http.DefaultServeMux
mux.Handle("/dashboard/", http.StripPrefix("/dashboard", uiserver.Handler()))
mux.Handle("/dashboard/", http.StripPrefix("/dashboard", uiserver.Handler(uiserver.AssetFS())))
mux.Handle("/dashboard/api/", apiserver.Handler(s))
mux.Handle("/dashboard/api/swagger/", swaggerserver.Handler())

Expand Down
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ require (
github.com/appleboy/gin-jwt/v2 v2.6.3
github.com/cenkalti/backoff/v4 v4.0.2
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/elazarl/go-bindata-assetfs v1.0.0
github.com/gin-contrib/gzip v0.0.1
github.com/gin-gonic/gin v1.5.0
github.com/go-bindata/go-bindata/v3 v3.1.3
github.com/go-sql-driver/mysql v1.5.0
github.com/goccy/go-graphviz v0.0.5
github.com/google/pprof v0.0.0-20200407044318-7d83b28da2e9
Expand All @@ -27,6 +25,9 @@ require (
github.com/pingcap/sysutil v0.0.0-20200206130906-2bfa6dc40bcd
github.com/pkg/errors v0.9.1
github.com/rs/cors v1.7.0
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect
github.com/shurcooL/httpgzip v0.0.0-20190720172056-320755c1c1b0
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
github.com/spf13/pflag v1.0.1
github.com/stretchr/testify v1.4.0
github.com/swaggo/http-swagger v0.0.0-20200103000832-0e9263c4b516
Expand All @@ -35,6 +36,8 @@ require (
go.uber.org/atomic v1.5.0
go.uber.org/fx v1.10.0
go.uber.org/zap v1.13.0
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f // indirect
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2 // indirect
google.golang.org/grpc v1.25.1
)

Expand Down
14 changes: 10 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumC
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4 h1:qk/FSDDxo05wdJH28W+p5yivv7LuLYLRXPPD8KQCtZs=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
Expand All @@ -76,8 +74,6 @@ github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
github.com/gin-gonic/gin v1.5.0 h1:fi+bqFAx/oLK54somfCtEZs9HeH1LHVoEPUgARpTqyc=
github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
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/go-chi/chi v4.0.2+incompatible h1:maB6vn6FqCxrpz4FqWdh4+lwpyZIQS7YEAUcHlgXVRs=
github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
Expand Down Expand Up @@ -275,8 +271,14 @@ github.com/shirou/gopsutil v2.19.10+incompatible h1:lA4Pi29JEVIQIgATSeftHSY0rMGI
github.com/shirou/gopsutil v2.19.10+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/httpgzip v0.0.0-20190720172056-320755c1c1b0 h1:mj/nMDAwTBiaCqMEs4cYCqF7pO6Np7vhy1D1wcQGz+E=
github.com/shurcooL/httpgzip v0.0.0-20190720172056-320755c1c1b0/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0=
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
Expand Down Expand Up @@ -388,6 +390,8 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0 h1:2mqDk8w/o6UmeUCu5Qiq2y7iMf6anbx+YA8d1JFoFrs=
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2 h1:eDrdRpKgkcCqKZQwyZRyeFZgfqt37SL7Kv3tok06cKE=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand All @@ -410,6 +414,8 @@ golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 h1:ng0gs1AKnRRuEMZoTLLlbOd+C
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e h1:9vRrk9YW2BTzLP0VCB9ZDjU4cPqkg+IDWL7XgxA1yxQ=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
Expand Down
7 changes: 3 additions & 4 deletions pkg/apiserver/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"net/http"
"sync"

assetfs "github.com/elazarl/go-bindata-assetfs"
"github.com/gin-contrib/gzip"
"github.com/gin-gonic/gin"
"github.com/joho/godotenv"
Expand Down Expand Up @@ -68,12 +67,12 @@ type Service struct {
config *config.Config
newPDDataProvider PDDataProviderConstructor
stoppedHandler http.Handler
uiAssetFS *assetfs.AssetFS
uiAssetFS http.FileSystem

apiHandlerEngine *gin.Engine
}

func NewService(cfg *config.Config, stoppedHandler http.Handler, uiAssetFS *assetfs.AssetFS, newPDDataProvider PDDataProviderConstructor) *Service {
func NewService(cfg *config.Config, stoppedHandler http.Handler, uiAssetFS http.FileSystem, newPDDataProvider PDDataProviderConstructor) *Service {
once.Do(func() {
// These global modification will be effective only for the first invoke.
_ = godotenv.Load()
Expand Down Expand Up @@ -176,7 +175,7 @@ func (s *Service) handler(w http.ResponseWriter, r *http.Request) {
s.apiHandlerEngine.ServeHTTP(w, r)
}

func (s *Service) provideLocals() (*config.Config, *assetfs.AssetFS) {
func (s *Service) provideLocals() (*config.Config, http.FileSystem) {
return s.config, s.uiAssetFS
}

Expand Down
26 changes: 10 additions & 16 deletions pkg/apiserver/diagnose/diagnose.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ import (
"net/http"
"time"

assetfs "github.com/elazarl/go-bindata-assetfs"
"github.com/gin-gonic/gin"
"github.com/pingcap/log"
"go.uber.org/zap"

"github.com/pingcap-incubator/tidb-dashboard/pkg/uiserver"

"github.com/pingcap-incubator/tidb-dashboard/pkg/apiserver/user"
apiutils "github.com/pingcap-incubator/tidb-dashboard/pkg/apiserver/utils"
"github.com/pingcap-incubator/tidb-dashboard/pkg/config"
Expand All @@ -38,10 +39,10 @@ type Service struct {
config *config.Config
db *dbstore.DB
tidbForwarder *tidb.Forwarder
uiAssetFS *assetfs.AssetFS
fileServer http.Handler
}

func NewService(config *config.Config, tidbForwarder *tidb.Forwarder, db *dbstore.DB, uiAssetFS *assetfs.AssetFS) *Service {
func NewService(config *config.Config, tidbForwarder *tidb.Forwarder, db *dbstore.DB, uiAssetFS http.FileSystem) *Service {
err := autoMigrate(db)
if err != nil {
log.Fatal("Failed to initialize database", zap.Error(err))
Expand All @@ -51,7 +52,7 @@ func NewService(config *config.Config, tidbForwarder *tidb.Forwarder, db *dbstor
config: config,
db: db,
tidbForwarder: tidbForwarder,
uiAssetFS: uiAssetFS,
fileServer: uiserver.Handler(uiAssetFS),
}
}

Expand Down Expand Up @@ -175,19 +176,12 @@ func (s *Service) reportStatusHandler(c *gin.Context) {
// @Success 200 {string} string
// @Router /diagnose/reports/{id}/detail [get]
func (s *Service) reportHTMLHandler(c *gin.Context) {
if s.uiAssetFS == nil {
c.Data(http.StatusNotFound, "text/plain", []byte("UI is not built"))
return
}

// Serve report html directly from assets
d, err := s.uiAssetFS.Asset("build/diagnoseReport.html")
if err != nil {
c.Status(http.StatusNotFound)
return
}
defer func(old string) {
c.Request.URL.Path = old
}(c.Request.URL.Path)

c.Data(http.StatusOK, "text/html; charset=utf-8", d)
c.Request.URL.Path = "diagnoseReport.html"
s.fileServer.ServeHTTP(c.Writer, c.Request)
}

// @Summary SQL diagnosis report data
Expand Down
53 changes: 23 additions & 30 deletions pkg/uiserver/embedded_assets_rewriter.go
Original file line number Diff line number Diff line change
@@ -1,40 +1,33 @@
// Copyright 2020 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
// +build ui_server

package uiserver

import (
"html"
"net/http"
"os"
"strings"
)

type modifiedFileInfo struct {
os.FileInfo
size int64
}

func (f modifiedFileInfo) Size() int64 {
return f.size
}

func (f modifiedFileInfo) Sys() interface{} {
return nil
}

func InitAssetFS(prefix string) {
rewrite := func(assetPath string) {
a, err := _bindata[assetPath]()
if err != nil {
panic("Asset " + assetPath + " not found.")
}
tmplText := string(a.bytes)
updated := strings.ReplaceAll(tmplText, "__PUBLIC_PATH_PREFIX__", html.EscapeString(prefix))
a.bytes = []byte(updated)
a.info = modifiedFileInfo{a.info, int64(len(a.bytes))}
_bindata[assetPath] = func() (*asset, error) {
return a, nil
func RewriteAssetsPublicPath(publicPath string) {
RewriteAssets(publicPath, AssetFS(), func(fs http.FileSystem, f http.File, path, newContent string, bs []byte) {
m := fs.(vfsgen۰FS)
fi := f.(os.FileInfo)
m[path] = &vfsgen۰CompressedFileInfo{
name: fi.Name(),
modTime: fi.ModTime(),
uncompressedSize: int64(len(newContent)),
compressedContent: bs,
}
}
rewrite("build/index.html")
rewrite("build/diagnoseReport.html")
})
}
9 changes: 4 additions & 5 deletions pkg/uiserver/empty_assets_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@
package uiserver

import (
assetfs "github.com/elazarl/go-bindata-assetfs"
"net/http"
)

func InitAssetFS(prefix string) {}
var assets http.FileSystem

func RewriteAssetsPublicPath(_ string) {}

func assetFS() *assetfs.AssetFS {
return nil
}
85 changes: 32 additions & 53 deletions pkg/uiserver/uiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,79 +14,58 @@
package uiserver

import (
"bytes"
"compress/gzip"
"html"
"io"
"io/ioutil"
"net/http"
"strings"
"sync"

assetfs "github.com/elazarl/go-bindata-assetfs"
"github.com/shurcooL/httpgzip"
)

var (
fs = assetFS()
)
func AssetFS() http.FileSystem {
return assets
}

func Handler() http.Handler {
if fs != nil {
return NewGzipHandler(fs)
func Handler(root http.FileSystem) http.Handler {
if root != nil {
return httpgzip.FileServer(root, httpgzip.FileServerOptions{IndexHTML: true})
}

return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = io.WriteString(w, "Dashboard UI is not built. Use `UI=1 make`.\n")
})
}

func AssetFS() *assetfs.AssetFS {
return fs
}

type gzipHandler struct {
raw http.Handler // The original FileServer
pool sync.Pool
}

func NewGzipHandler(fs http.FileSystem) http.Handler {
var pool sync.Pool
pool.New = func() interface{} {
gz, err := gzip.NewWriterLevel(ioutil.Discard, gzip.BestSpeed)
if err != nil {
panic(err)
}
return gz
}
return &gzipHandler{raw: http.FileServer(fs), pool: pool}
}
type UpdateContentFunc func(fs http.FileSystem, oldFile http.File, path, newContent string, zippedBytes []byte)

func (g *gzipHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if g.shouldCompress(r) {
gz := g.pool.Get().(*gzip.Writer)
defer func() {
gz.Close()
gz.Reset(ioutil.Discard)
g.pool.Put(gz)
}()
gz.Reset(w)
w.Header().Set("Content-Encoding", "gzip")
g.raw.ServeHTTP(&gzipWriter{
ResponseWriter: w,
writer: gz,
}, r)
func RewriteAssets(publicPath string, fs http.FileSystem, updater UpdateContentFunc) {
if fs == nil {
return
}
g.raw.ServeHTTP(w, r)
}

func (g *gzipHandler) shouldCompress(r *http.Request) bool {
return strings.Contains(r.Header.Get("Accept-Encoding"), "gzip")
}
rewrite := func(assetPath string) {
f, err := fs.Open(assetPath)
if err != nil {
panic("Asset " + assetPath + " not found.")
}
defer f.Close()
bs, err := ioutil.ReadAll(f)
if err != nil {
panic("Read Asset " + assetPath + " fail.")
}
tmplText := string(bs)
updated := strings.ReplaceAll(tmplText, "__PUBLIC_PATH_PREFIX__", html.EscapeString(publicPath))

type gzipWriter struct {
http.ResponseWriter
writer *gzip.Writer
}
var b bytes.Buffer
w := gzip.NewWriter(&b)
w.Write([]byte(updated))
w.Close()

func (g *gzipWriter) Write(data []byte) (int, error) {
return g.writer.Write(data)
updater(fs, f, assetPath, updated, b.Bytes())
}
rewrite("/index.html")
rewrite("/diagnoseReport.html")
}
Loading

0 comments on commit be659b1

Please sign in to comment.