From 70359e5d27b82e26da8ba7907dbae2dd86c37773 Mon Sep 17 00:00:00 2001 From: Antoine <13622487+skwair@users.noreply.github.com> Date: Wed, 15 Sep 2021 10:36:14 +0200 Subject: [PATCH] Replace go-bindata with Go embed Co-authored-by: nrwiersma --- .github/workflows/build.yaml | 5 +- .github/workflows/test-unit.yaml | 4 +- .github/workflows/validate.yaml | 9 +-- .gitignore | 3 +- .semaphore/semaphore.yml | 5 +- Makefile | 12 ++-- build.Dockerfile | 5 -- cmd/traefik/traefik.go | 6 -- docs/content/contributing/building-testing.md | 12 +--- exp.Dockerfile | 4 -- generate.go | 4 -- go.mod | 1 - go.sum | 2 - pkg/anonymize/anonymize.go | 4 +- pkg/anonymize/anonymize_config_test.go | 13 ---- pkg/api/dashboard.go | 59 ---------------- pkg/api/dashboard/dashboard.go | 68 +++++++++++++++++++ pkg/api/{ => dashboard}/dashboard_test.go | 52 ++++++-------- pkg/api/handler.go | 15 +--- pkg/config/static/static_config.go | 2 - pkg/server/service/managerfactory.go | 13 +++- script/binary | 5 -- script/crossbinary-default | 5 -- script/test-unit | 5 -- webui/dev/scripts/transfer.js | 4 +- webui/embed.go | 12 ++++ webui/readme.md | 18 ++--- 27 files changed, 142 insertions(+), 205 deletions(-) delete mode 100644 pkg/api/dashboard.go create mode 100644 pkg/api/dashboard/dashboard.go rename pkg/api/{ => dashboard}/dashboard_test.go (66%) create mode 100644 webui/embed.go diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index d0cde427c..49e945f2c 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -24,7 +24,7 @@ jobs: - name: Build webui run: | make generate-webui - tar czvf webui.tar.gz ./static/ + tar czvf webui.tar.gz ./webui/static/ - name: Artifact webui uses: actions/upload-artifact@v2 @@ -66,9 +66,6 @@ jobs: key: ${{ runner.os }}-build-go-${{ hashFiles('**/go.sum') }} restore-keys: ${{ runner.os }}-build-go- - - name: Installing dependencies - run: go install github.com/containous/go-bindata/go-bindata@v1.0.0 - - name: Artifact webui uses: actions/download-artifact@v2 with: diff --git a/.github/workflows/test-unit.yaml b/.github/workflows/test-unit.yaml index 9583a37da..a1d861a31 100644 --- a/.github/workflows/test-unit.yaml +++ b/.github/workflows/test-unit.yaml @@ -39,8 +39,8 @@ jobs: key: ${{ runner.os }}-test-unit-go-${{ hashFiles('**/go.sum') }} restore-keys: ${{ runner.os }}-test-unit-go- - - name: Installing dependencies - run: go install github.com/containous/go-bindata/go-bindata@v1.0.0 + - name: Avoid generating webui + run: mkdir -p webui/static && touch webui/static/index.html - name: Tests run: make test-unit diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index 4bf9abf12..80265b079 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -41,15 +41,15 @@ jobs: key: ${{ runner.os }}-validate-go-${{ hashFiles('**/go.sum') }} restore-keys: ${{ runner.os }}-validate-go- - - name: Installing dependencies - run: go install github.com/containous/go-bindata/go-bindata@v1.0.0 - - name: Install golangci-lint ${{ env.GOLANGCI_LINT_VERSION }} run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin ${GOLANGCI_LINT_VERSION} - name: Install missspell ${{ env.MISSSPELL_VERSION }} run: curl -sfL https://raw.githubusercontent.com/client9/misspell/master/install-misspell.sh | sh -s -- -b $(go env GOPATH)/bin ${MISSSPELL_VERSION} + - name: Avoid generating webui + run: mkdir -p webui/static && touch webui/static/index.html + - name: Validate run: make validate @@ -81,9 +81,6 @@ jobs: key: ${{ runner.os }}-validate-generate-go-${{ hashFiles('**/go.sum') }} restore-keys: ${{ runner.os }}-validate-generate-go- - - name: Installing dependencies - run: go install github.com/containous/go-bindata/go-bindata@v1.0.0 - - name: go generate run: | go generate diff --git a/.gitignore b/.gitignore index 5d3608c1f..de50e35db 100644 --- a/.gitignore +++ b/.gitignore @@ -5,10 +5,9 @@ .DS_Store /dist /webui/.tmp/ +/webui/static/ /site/ /docs/site/ -/static/ -/autogen/ /traefik /traefik.toml /traefik.yml diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index 0210c1ffa..138fbf9a7 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -27,7 +27,6 @@ global_job_config: - export GOPROXY=https://proxy.golang.org,direct - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "${GOPATH}/bin" v1.41.1 - curl -sfL https://install.goreleaser.com/github.com/goreleaser/goreleaser.sh | bash -s -- -b "${GOPATH}/bin" - - go install github.com/containous/go-bindata/go-bindata@v1.0.0 - checkout - cache restore traefik-$(checksum go.sum) @@ -41,7 +40,7 @@ blocks: - name: Test Integration Container commands: - make pull-images - - mkdir -p static # Avoid to generate webui + - mkdir -p webui/static && touch webui/static/index.html # Avoid generating webui - PRE_TARGET="" make binary - make test-integration-container - df -h @@ -61,7 +60,7 @@ blocks: jobs: - name: Test Integration Host commands: - - mkdir -p static # Avoid to generate webui + - mkdir -p webui/static && touch webui/static/index.html # Avoid generating webui - make test-integration-host epilogue: always: diff --git a/Makefile b/Makefile index f61335092..2de59c691 100644 --- a/Makefile +++ b/Makefile @@ -59,12 +59,12 @@ build-webui-image: ## Generate WebUI generate-webui: - if [ ! -d "static" ]; then \ + if [ ! -d "webui/static" ]; then \ $(MAKE) build-webui-image; \ - mkdir -p static; \ - docker run --rm -v "$$PWD/static":'/src/static' traefik-webui npm run build:nc; \ - docker run --rm -v "$$PWD/static":'/src/static' traefik-webui chown -R $(shell id -u):$(shell id -g) ../static; \ - echo 'For more information show `webui/readme.md`' > $$PWD/static/DONT-EDIT-FILES-IN-THIS-DIRECTORY.md; \ + mkdir -p webui/static; \ + docker run --rm -v "$$PWD/webui/static":'/src/webui/static' traefik-webui npm run build:nc; \ + docker run --rm -v "$$PWD/webui/static":'/src/webui/static' traefik-webui chown -R $(shell id -u):$(shell id -g) ./static; \ + echo 'For more information show `webui/readme.md`' > $$PWD/webui/static/DONT-EDIT-FILES-IN-THIS-DIRECTORY.md; \ fi ## Build the linux binary @@ -117,7 +117,7 @@ validate: $(PRE_TARGET) ## Clean up static directory and build a Docker Traefik image build-image: binary - rm -rf static + rm -rf webui/static docker build -t $(TRAEFIK_IMAGE) . ## Build a Docker Traefik image diff --git a/build.Dockerfile b/build.Dockerfile index cd9c84c98..cba57c98d 100644 --- a/build.Dockerfile +++ b/build.Dockerfile @@ -13,11 +13,6 @@ RUN mkdir -p /usr/local/bin \ && curl -fL https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz \ | tar -xzC /usr/local/bin --transform 's#^.+/##x' -# Download go-bindata binary to bin folder in $GOPATH -RUN mkdir -p /usr/local/bin \ - && curl -fsSL -o /usr/local/bin/go-bindata https://github.com/containous/go-bindata/releases/download/v1.0.0/go-bindata \ - && chmod +x /usr/local/bin/go-bindata - # Download golangci-lint binary to bin folder in $GOPATH RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.41.1 diff --git a/cmd/traefik/traefik.go b/cmd/traefik/traefik.go index 912f2b4dd..91a6d4d74 100644 --- a/cmd/traefik/traefik.go +++ b/cmd/traefik/traefik.go @@ -16,12 +16,10 @@ import ( "time" "github.com/coreos/go-systemd/daemon" - assetfs "github.com/elazarl/go-bindata-assetfs" "github.com/go-acme/lego/v4/challenge" gokitmetrics "github.com/go-kit/kit/metrics" "github.com/sirupsen/logrus" "github.com/traefik/paerser/cli" - "github.com/traefik/traefik/v2/autogen/genstatic" "github.com/traefik/traefik/v2/cmd" "github.com/traefik/traefik/v2/cmd/healthcheck" cmdVersion "github.com/traefik/traefik/v2/cmd/version" @@ -109,10 +107,6 @@ func runCmd(staticConfiguration *static.Configuration) error { log.WithoutContext().Debugf("Static configuration loaded %s", string(jsonConf)) } - if staticConfiguration.API != nil && staticConfiguration.API.Dashboard { - staticConfiguration.API.DashboardAssets = &assetfs.AssetFS{Asset: genstatic.Asset, AssetInfo: genstatic.AssetInfo, AssetDir: genstatic.AssetDir, Prefix: "static"} - } - if staticConfiguration.Global.CheckNewVersion { checkNewVersion() } diff --git a/docs/content/contributing/building-testing.md b/docs/content/contributing/building-testing.md index f2e7eea57..7572e2f6e 100644 --- a/docs/content/contributing/building-testing.md +++ b/docs/content/contributing/building-testing.md @@ -64,7 +64,6 @@ Requirements: - `go` v1.16+ - environment variable `GO111MODULE=on` -- [go-bindata](https://github.com/containous/go-bindata) `GO111MODULE=off go get -u github.com/containous/go-bindata/...` !!! tip "Source Directory" @@ -101,18 +100,9 @@ Requirements: Once you've set up your go environment and cloned the source repository, you can build Traefik. -Beforehand, you need to get [go-bindata](https://github.com/containous/go-bindata) (the first time) in order to be able to use the `go generate` command (which is part of the build process). - -```bash -cd ~/go/src/github.com/traefik/traefik - -# Get go-bindata. (Important: the ellipses are required.) -GO111MODULE=off go get github.com/containous/go-bindata/... -``` - ```bash # Generate UI static files -rm -rf static/ autogen/; make generate-webui +rm -rf ./webui/static/; make generate-webui # required to merge non-code components into the final binary, # such as the web dashboard/UI diff --git a/exp.Dockerfile b/exp.Dockerfile index 4d7bd5cca..45f8e5ffe 100644 --- a/exp.Dockerfile +++ b/exp.Dockerfile @@ -19,10 +19,6 @@ RUN apk --update upgrade \ && update-ca-certificates \ && rm -rf /var/cache/apk/* -RUN mkdir -p /usr/local/bin \ - && curl -fsSL -o /usr/local/bin/go-bindata https://github.com/containous/go-bindata/releases/download/v1.0.0/go-bindata \ - && chmod +x /usr/local/bin/go-bindata - WORKDIR /go/src/github.com/traefik/traefik # Download go modules diff --git a/generate.go b/generate.go index 720f4bd40..03f6de540 100644 --- a/generate.go +++ b/generate.go @@ -1,7 +1,3 @@ -//go:generate mkdir -p autogen -//go:generate rm -vf autogen/genstatic/gen.go -//go:generate mkdir -p static -//go:generate go-bindata -pkg genstatic -nocompress -o autogen/genstatic/gen.go ./static/... //go:generate go run ./internal/ package main diff --git a/go.mod b/go.mod index b6e105ebd..ef09d98af 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,6 @@ require ( github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect github.com/donovanhide/eventsource v0.0.0-20170630084216-b8f31a59085e // indirect github.com/eapache/channels v1.1.0 - github.com/elazarl/go-bindata-assetfs v1.0.0 github.com/fatih/structs v1.1.0 github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2 github.com/go-acme/lego/v4 v4.4.0 diff --git a/go.sum b/go.sum index fa3d5ffbd..a99b24304 100644 --- a/go.sum +++ b/go.sum @@ -311,8 +311,6 @@ github.com/elastic/go-sysinfo v1.1.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6 github.com/elastic/go-windows v1.0.0 h1:qLURgZFkkrYyTTkvYpsZIgf83AUsdIHfvlJaqaZ7aSY= github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU= github.com/elazarl/go-bindata-assetfs v0.0.0-20160803192304-e1a2a7ec64b0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= -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/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= diff --git a/pkg/anonymize/anonymize.go b/pkg/anonymize/anonymize.go index 4bbf61717..ca7b87d12 100644 --- a/pkg/anonymize/anonymize.go +++ b/pkg/anonymize/anonymize.go @@ -160,9 +160,7 @@ func reset(field reflect.Value, name string) error { } } case reflect.Interface: - if !field.IsNil() { - return reset(field.Elem(), "") - } + return fmt.Errorf("reset not supported for interface type (for %s field)", name) default: // Primitive type field.Set(reflect.Zero(field.Type())) diff --git a/pkg/anonymize/anonymize_config_test.go b/pkg/anonymize/anonymize_config_test.go index 831bdea65..a876cd7aa 100644 --- a/pkg/anonymize/anonymize_config_test.go +++ b/pkg/anonymize/anonymize_config_test.go @@ -7,7 +7,6 @@ import ( "testing" "time" - assetfs "github.com/elazarl/go-bindata-assetfs" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" @@ -778,18 +777,6 @@ func TestDo_staticConfiguration(t *testing.T) { Insecure: true, Dashboard: true, Debug: true, - DashboardAssets: &assetfs.AssetFS{ - Asset: func(path string) ([]byte, error) { - return nil, nil - }, - AssetDir: func(path string) ([]string, error) { - return nil, nil - }, - AssetInfo: func(path string) (os.FileInfo, error) { - return nil, nil - }, - Prefix: "fii", - }, } config.Metrics = &types.Metrics{ diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go deleted file mode 100644 index 54b0423c5..000000000 --- a/pkg/api/dashboard.go +++ /dev/null @@ -1,59 +0,0 @@ -package api - -import ( - "net/http" - "net/url" - - assetfs "github.com/elazarl/go-bindata-assetfs" - "github.com/gorilla/mux" - "github.com/traefik/traefik/v2/pkg/log" -) - -// DashboardHandler expose dashboard routes. -type DashboardHandler struct { - Assets *assetfs.AssetFS -} - -// Append add dashboard routes on a router. -func (g DashboardHandler) Append(router *mux.Router) { - if g.Assets == nil { - log.WithoutContext().Error("No assets for dashboard") - return - } - - // Expose dashboard - router.Methods(http.MethodGet). - Path("/"). - HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { - http.Redirect(resp, req, safePrefix(req)+"/dashboard/", http.StatusFound) - }) - - router.Methods(http.MethodGet). - PathPrefix("/dashboard/"). - Handler(http.StripPrefix("/dashboard/", http.FileServer(g.Assets))) -} - -func (g DashboardHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - // allow iframes from our domains only - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-src - w.Header().Set("Content-Security-Policy", "frame-src 'self' https://traefik.io https://*.traefik.io;") - http.FileServer(g.Assets).ServeHTTP(w, r) -} - -func safePrefix(req *http.Request) string { - prefix := req.Header.Get("X-Forwarded-Prefix") - if prefix == "" { - return "" - } - - parse, err := url.Parse(prefix) - if err != nil { - return "" - } - - if parse.Host != "" { - return "" - } - - return parse.Path -} diff --git a/pkg/api/dashboard/dashboard.go b/pkg/api/dashboard/dashboard.go new file mode 100644 index 000000000..ebcaf315e --- /dev/null +++ b/pkg/api/dashboard/dashboard.go @@ -0,0 +1,68 @@ +package dashboard + +import ( + "io/fs" + "net/http" + "net/url" + + "github.com/gorilla/mux" + "github.com/traefik/traefik/v2/webui" +) + +// Handler expose dashboard routes. +type Handler struct { + assets fs.FS // optional assets, to override the webui.FS default +} + +// Append adds dashboard routes on the given router, optionally using the given +// assets (or webui.FS otherwise). +func Append(router *mux.Router, customAssets fs.FS) { + assets := customAssets + if assets == nil { + assets = webui.FS + } + // Expose dashboard + router.Methods(http.MethodGet). + Path("/"). + HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + http.Redirect(resp, req, safePrefix(req)+"/dashboard/", http.StatusFound) + }) + + router.Methods(http.MethodGet). + PathPrefix("/dashboard/"). + HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // allow iframes from our domains only + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-src + w.Header().Set("Content-Security-Policy", "frame-src 'self' https://traefik.io https://*.traefik.io;") + http.StripPrefix("/dashboard/", http.FileServer(http.FS(assets))).ServeHTTP(w, r) + }) +} + +func (g Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + assets := g.assets + if assets == nil { + assets = webui.FS + } + // allow iframes from our domains only + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-src + w.Header().Set("Content-Security-Policy", "frame-src 'self' https://traefik.io https://*.traefik.io;") + http.FileServer(http.FS(assets)).ServeHTTP(w, r) +} + +func safePrefix(req *http.Request) string { + prefix := req.Header.Get("X-Forwarded-Prefix") + if prefix == "" { + return "" + } + + parse, err := url.Parse(prefix) + if err != nil { + return "" + } + + if parse.Host != "" { + return "" + } + + return parse.Path +} diff --git a/pkg/api/dashboard_test.go b/pkg/api/dashboard/dashboard_test.go similarity index 66% rename from pkg/api/dashboard_test.go rename to pkg/api/dashboard/dashboard_test.go index 384071dfe..d86cc0159 100644 --- a/pkg/api/dashboard_test.go +++ b/pkg/api/dashboard/dashboard_test.go @@ -1,12 +1,14 @@ -package api +package dashboard import ( - "fmt" + "errors" + "io/fs" "net/http" "net/http/httptest" "testing" + "testing/fstest" + "time" - assetfs "github.com/elazarl/go-bindata-assetfs" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -59,48 +61,30 @@ func Test_safePrefix(t *testing.T) { func Test_ContentSecurityPolicy(t *testing.T) { testCases := []struct { desc string - handler DashboardHandler + handler Handler expected int }{ { desc: "OK", - handler: DashboardHandler{ - Assets: &assetfs.AssetFS{ - Asset: func(path string) ([]byte, error) { - return []byte{}, nil - }, - AssetDir: func(path string) ([]string, error) { - return []string{}, nil - }, - }, + handler: Handler{ + assets: fstest.MapFS{"foobar.html": &fstest.MapFile{ + Mode: 0755, + ModTime: time.Now(), + }}, }, expected: http.StatusOK, }, { desc: "Not found", - handler: DashboardHandler{ - Assets: &assetfs.AssetFS{ - Asset: func(path string) ([]byte, error) { - return []byte{}, fmt.Errorf("not found") - }, - AssetDir: func(path string) ([]string, error) { - return []string{}, fmt.Errorf("not found") - }, - }, + handler: Handler{ + assets: fstest.MapFS{}, }, expected: http.StatusNotFound, }, { desc: "Internal server error", - handler: DashboardHandler{ - Assets: &assetfs.AssetFS{ - Asset: func(path string) ([]byte, error) { - return []byte{}, fmt.Errorf("oops") - }, - AssetDir: func(path string) ([]string, error) { - return []string{}, fmt.Errorf("oops") - }, - }, + handler: Handler{ + assets: errorFS{}, }, expected: http.StatusInternalServerError, }, @@ -122,3 +106,9 @@ func Test_ContentSecurityPolicy(t *testing.T) { }) } } + +type errorFS struct{} + +func (e errorFS) Open(name string) (fs.File, error) { + return nil, errors.New("oops") +} diff --git a/pkg/api/handler.go b/pkg/api/handler.go index ff2ae7e86..f0623d4cc 100644 --- a/pkg/api/handler.go +++ b/pkg/api/handler.go @@ -6,7 +6,6 @@ import ( "reflect" "strings" - assetfs "github.com/elazarl/go-bindata-assetfs" "github.com/gorilla/mux" "github.com/traefik/traefik/v2/pkg/config/dynamic" "github.com/traefik/traefik/v2/pkg/config/runtime" @@ -48,10 +47,7 @@ type RunTimeRepresentation struct { // Handler serves the configuration and status of Traefik on API endpoints. type Handler struct { - dashboard bool - debug bool - staticConfig static.Configuration - dashboardAssets *assetfs.AssetFS + staticConfig static.Configuration // runtimeConfiguration is the data set used to create all the data representations exposed by the API. runtimeConfiguration *runtime.Configuration @@ -73,11 +69,8 @@ func New(staticConfig static.Configuration, runtimeConfig *runtime.Configuration } return &Handler{ - dashboard: staticConfig.API.Dashboard, - dashboardAssets: staticConfig.API.DashboardAssets, runtimeConfiguration: rConfig, staticConfig: staticConfig, - debug: staticConfig.API.Debug, } } @@ -85,7 +78,7 @@ func New(staticConfig static.Configuration, runtimeConfig *runtime.Configuration func (h Handler) createRouter() *mux.Router { router := mux.NewRouter() - if h.debug { + if h.staticConfig.API.Debug { DebugHandler{}.Append(router) } @@ -118,10 +111,6 @@ func (h Handler) createRouter() *mux.Router { version.Handler{}.Append(router) - if h.dashboard { - DashboardHandler{Assets: h.dashboardAssets}.Append(router) - } - return router } diff --git a/pkg/config/static/static_config.go b/pkg/config/static/static_config.go index a3a8ba547..b55d6182a 100644 --- a/pkg/config/static/static_config.go +++ b/pkg/config/static/static_config.go @@ -6,7 +6,6 @@ import ( "strings" "time" - assetfs "github.com/elazarl/go-bindata-assetfs" legolog "github.com/go-acme/lego/v4/log" "github.com/sirupsen/logrus" ptypes "github.com/traefik/paerser/types" @@ -108,7 +107,6 @@ type API struct { Debug bool `description:"Enable additional endpoints for debugging and profiling." json:"debug,omitempty" toml:"debug,omitempty" yaml:"debug,omitempty" export:"true"` // TODO: Re-enable statistics // Statistics *types.Statistics `description:"Enable more detailed statistics." json:"statistics,omitempty" toml:"statistics,omitempty" yaml:"statistics,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` - DashboardAssets *assetfs.AssetFS `json:"-" toml:"-" yaml:"-" label:"-" file:"-"` } // SetDefaults sets the default values. diff --git a/pkg/server/service/managerfactory.go b/pkg/server/service/managerfactory.go index 172f956f9..5db06ef40 100644 --- a/pkg/server/service/managerfactory.go +++ b/pkg/server/service/managerfactory.go @@ -3,7 +3,9 @@ package service import ( "net/http" + "github.com/gorilla/mux" "github.com/traefik/traefik/v2/pkg/api" + "github.com/traefik/traefik/v2/pkg/api/dashboard" "github.com/traefik/traefik/v2/pkg/config/runtime" "github.com/traefik/traefik/v2/pkg/config/static" "github.com/traefik/traefik/v2/pkg/metrics" @@ -36,10 +38,17 @@ func NewManagerFactory(staticConfiguration static.Configuration, routinesPool *s } if staticConfiguration.API != nil { - factory.api = api.NewBuilder(staticConfiguration) + apiRouterBuilder := api.NewBuilder(staticConfiguration) if staticConfiguration.API.Dashboard { - factory.dashboardHandler = api.DashboardHandler{Assets: staticConfiguration.API.DashboardAssets} + factory.dashboardHandler = dashboard.Handler{} + factory.api = func(configuration *runtime.Configuration) http.Handler { + router := apiRouterBuilder(configuration).(*mux.Router) + dashboard.Append(router, nil) + return router + } + } else { + factory.api = apiRouterBuilder } } diff --git a/script/binary b/script/binary index 1297ef16c..0008a855c 100755 --- a/script/binary +++ b/script/binary @@ -1,11 +1,6 @@ #!/usr/bin/env bash set -e -if ! test -e autogen/genstatic/gen.go; then - echo >&2 'error: generate must be run before binary' - false -fi - rm -f dist/traefik FLAGS=() diff --git a/script/crossbinary-default b/script/crossbinary-default index 3a8d550f6..1567b1a9d 100755 --- a/script/crossbinary-default +++ b/script/crossbinary-default @@ -1,11 +1,6 @@ #!/usr/bin/env bash set -e -if ! test -e autogen/genstatic/gen.go; then - echo >&2 'error: generate must be run before crossbinary' - false -fi - if [ -z "$VERSION" ]; then VERSION=$(git rev-parse HEAD) fi diff --git a/script/test-unit b/script/test-unit index 08dab103d..2944bab6d 100755 --- a/script/test-unit +++ b/script/test-unit @@ -1,11 +1,6 @@ #!/usr/bin/env bash set -e -if ! test -e autogen/genstatic/gen.go; then - echo >&2 'error: generate must be run before test-unit' - false -fi - RED=$'\033[31m' GREEN=$'\033[32m' TEXTRESET=$'\033[0m' # reset the foreground colour diff --git a/webui/dev/scripts/transfer.js b/webui/dev/scripts/transfer.js index 37f28dfce..d6ec3c4fc 100644 --- a/webui/dev/scripts/transfer.js +++ b/webui/dev/scripts/transfer.js @@ -4,9 +4,9 @@ const folder = process.argv[2] async function execute () { try { - await fs.emptyDir('../static') + await fs.emptyDir('./static') console.log('Deleted static folder contents!') - await fs.copy(`./dist/${folder}`, '../static', { overwrite: true }) + await fs.copy(`./dist/${folder}`, './static', { overwrite: true }) console.log('Installed new files in static folder!') } catch (err) { console.error(err) diff --git a/webui/embed.go b/webui/embed.go new file mode 100644 index 000000000..155b0f9e6 --- /dev/null +++ b/webui/embed.go @@ -0,0 +1,12 @@ +package webui + +import ( + "embed" + "io/fs" +) + +//go:embed static +var assets embed.FS + +// FS contains the web UI assets. +var FS, _ = fs.Sub(assets, "static") diff --git a/webui/readme.md b/webui/readme.md index 4e58abf12..426698bbe 100644 --- a/webui/readme.md +++ b/webui/readme.md @@ -14,15 +14,15 @@ Traefik Web UI provide 2 types of information: Use the make file : ```shell -make build # Generate Docker image -make generate-webui # Generate static contents in `traefik/static/` folder. +make build-image # Generate Docker image +make generate-webui # Generate static contents in `traefik/webui/static/` folder. ``` ## How to build (only for frontend developer) - prerequisite: [Node 12.11+](https://nodejs.org) [Npm](https://www.npmjs.com/) -- Go to the directory `webui` +- Go to the `webui` directory - To install dependencies, execute the following commands: @@ -32,23 +32,23 @@ make generate-webui # Generate static contents in `traefik/static/` folder. - `npm run build` -- Static contents are build in the directory `static` +- Static contents are built in the `webui/static` directory -**Don't change manually the files in the directory `static`** +**Do not manually change the files in the `webui/static` directory** -- The build allow to: +- The build allows to: - optimize all JavaScript - optimize all CSS - add vendor prefixes to CSS (cross-bowser support) - add a hash in the file names to prevent browser cache problems - - all images will be optimized at build + - optimize all images at build time - bundle JavaScript in one file ## How to edit (only for frontend developer) -**Don't change manually the files in the directory `static`** +**Do not manually change the files in the `webui/static` directory** -- Go to the directory `webui` +- Go to the `webui` directory - Edit files in `webui/src` - Run in development mode : - `npm run dev`