Replace go-bindata with Go embed

Co-authored-by: nrwiersma <nick@wiersma.co.za>
This commit is contained in:
Antoine 2021-09-15 10:36:14 +02:00 committed by GitHub
parent 7ff13c3e3e
commit 70359e5d27
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 142 additions and 205 deletions

View file

@ -24,7 +24,7 @@ jobs:
- name: Build webui - name: Build webui
run: | run: |
make generate-webui make generate-webui
tar czvf webui.tar.gz ./static/ tar czvf webui.tar.gz ./webui/static/
- name: Artifact webui - name: Artifact webui
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
@ -66,9 +66,6 @@ jobs:
key: ${{ runner.os }}-build-go-${{ hashFiles('**/go.sum') }} key: ${{ runner.os }}-build-go-${{ hashFiles('**/go.sum') }}
restore-keys: ${{ runner.os }}-build-go- 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 - name: Artifact webui
uses: actions/download-artifact@v2 uses: actions/download-artifact@v2
with: with:

View file

@ -39,8 +39,8 @@ jobs:
key: ${{ runner.os }}-test-unit-go-${{ hashFiles('**/go.sum') }} key: ${{ runner.os }}-test-unit-go-${{ hashFiles('**/go.sum') }}
restore-keys: ${{ runner.os }}-test-unit-go- restore-keys: ${{ runner.os }}-test-unit-go-
- name: Installing dependencies - name: Avoid generating webui
run: go install github.com/containous/go-bindata/go-bindata@v1.0.0 run: mkdir -p webui/static && touch webui/static/index.html
- name: Tests - name: Tests
run: make test-unit run: make test-unit

View file

@ -41,15 +41,15 @@ jobs:
key: ${{ runner.os }}-validate-go-${{ hashFiles('**/go.sum') }} key: ${{ runner.os }}-validate-go-${{ hashFiles('**/go.sum') }}
restore-keys: ${{ runner.os }}-validate-go- 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 }} - 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} 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 }} - 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} 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 - name: Validate
run: make validate run: make validate
@ -81,9 +81,6 @@ jobs:
key: ${{ runner.os }}-validate-generate-go-${{ hashFiles('**/go.sum') }} key: ${{ runner.os }}-validate-generate-go-${{ hashFiles('**/go.sum') }}
restore-keys: ${{ runner.os }}-validate-generate-go- 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 - name: go generate
run: | run: |
go generate go generate

3
.gitignore vendored
View file

@ -5,10 +5,9 @@
.DS_Store .DS_Store
/dist /dist
/webui/.tmp/ /webui/.tmp/
/webui/static/
/site/ /site/
/docs/site/ /docs/site/
/static/
/autogen/
/traefik /traefik
/traefik.toml /traefik.toml
/traefik.yml /traefik.yml

View file

@ -27,7 +27,6 @@ global_job_config:
- export GOPROXY=https://proxy.golang.org,direct - 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 -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" - 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 - checkout
- cache restore traefik-$(checksum go.sum) - cache restore traefik-$(checksum go.sum)
@ -41,7 +40,7 @@ blocks:
- name: Test Integration Container - name: Test Integration Container
commands: commands:
- make pull-images - 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 - PRE_TARGET="" make binary
- make test-integration-container - make test-integration-container
- df -h - df -h
@ -61,7 +60,7 @@ blocks:
jobs: jobs:
- name: Test Integration Host - name: Test Integration Host
commands: commands:
- mkdir -p static # Avoid to generate webui - mkdir -p webui/static && touch webui/static/index.html # Avoid generating webui
- make test-integration-host - make test-integration-host
epilogue: epilogue:
always: always:

View file

@ -59,12 +59,12 @@ build-webui-image:
## Generate WebUI ## Generate WebUI
generate-webui: generate-webui:
if [ ! -d "static" ]; then \ if [ ! -d "webui/static" ]; then \
$(MAKE) build-webui-image; \ $(MAKE) build-webui-image; \
mkdir -p static; \ mkdir -p webui/static; \
docker run --rm -v "$$PWD/static":'/src/static' traefik-webui npm run build:nc; \ docker run --rm -v "$$PWD/webui/static":'/src/webui/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; \ 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/static/DONT-EDIT-FILES-IN-THIS-DIRECTORY.md; \ echo 'For more information show `webui/readme.md`' > $$PWD/webui/static/DONT-EDIT-FILES-IN-THIS-DIRECTORY.md; \
fi fi
## Build the linux binary ## Build the linux binary
@ -117,7 +117,7 @@ validate: $(PRE_TARGET)
## Clean up static directory and build a Docker Traefik image ## Clean up static directory and build a Docker Traefik image
build-image: binary build-image: binary
rm -rf static rm -rf webui/static
docker build -t $(TRAEFIK_IMAGE) . docker build -t $(TRAEFIK_IMAGE) .
## Build a Docker Traefik image ## Build a Docker Traefik image

View file

@ -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 \ && curl -fL https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz \
| tar -xzC /usr/local/bin --transform 's#^.+/##x' | 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 # 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 RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.41.1

View file

@ -16,12 +16,10 @@ import (
"time" "time"
"github.com/coreos/go-systemd/daemon" "github.com/coreos/go-systemd/daemon"
assetfs "github.com/elazarl/go-bindata-assetfs"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
gokitmetrics "github.com/go-kit/kit/metrics" gokitmetrics "github.com/go-kit/kit/metrics"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/traefik/paerser/cli" "github.com/traefik/paerser/cli"
"github.com/traefik/traefik/v2/autogen/genstatic"
"github.com/traefik/traefik/v2/cmd" "github.com/traefik/traefik/v2/cmd"
"github.com/traefik/traefik/v2/cmd/healthcheck" "github.com/traefik/traefik/v2/cmd/healthcheck"
cmdVersion "github.com/traefik/traefik/v2/cmd/version" 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)) 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 { if staticConfiguration.Global.CheckNewVersion {
checkNewVersion() checkNewVersion()
} }

View file

@ -64,7 +64,6 @@ Requirements:
- `go` v1.16+ - `go` v1.16+
- environment variable `GO111MODULE=on` - 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" !!! 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. 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 ```bash
# Generate UI static files # 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, # required to merge non-code components into the final binary,
# such as the web dashboard/UI # such as the web dashboard/UI

View file

@ -19,10 +19,6 @@ RUN apk --update upgrade \
&& update-ca-certificates \ && update-ca-certificates \
&& rm -rf /var/cache/apk/* && 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 WORKDIR /go/src/github.com/traefik/traefik
# Download go modules # Download go modules

View file

@ -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/ //go:generate go run ./internal/
package main package main

1
go.mod
View file

@ -27,7 +27,6 @@ require (
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect
github.com/donovanhide/eventsource v0.0.0-20170630084216-b8f31a59085e // indirect github.com/donovanhide/eventsource v0.0.0-20170630084216-b8f31a59085e // indirect
github.com/eapache/channels v1.1.0 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/fatih/structs v1.1.0
github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2 github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2
github.com/go-acme/lego/v4 v4.4.0 github.com/go-acme/lego/v4 v4.4.0

2
go.sum
View file

@ -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 h1:qLURgZFkkrYyTTkvYpsZIgf83AUsdIHfvlJaqaZ7aSY=
github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU= 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 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-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/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= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=

View file

@ -160,9 +160,7 @@ func reset(field reflect.Value, name string) error {
} }
} }
case reflect.Interface: case reflect.Interface:
if !field.IsNil() { return fmt.Errorf("reset not supported for interface type (for %s field)", name)
return reset(field.Elem(), "")
}
default: default:
// Primitive type // Primitive type
field.Set(reflect.Zero(field.Type())) field.Set(reflect.Zero(field.Type()))

View file

@ -7,7 +7,6 @@ import (
"testing" "testing"
"time" "time"
assetfs "github.com/elazarl/go-bindata-assetfs"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
ptypes "github.com/traefik/paerser/types" ptypes "github.com/traefik/paerser/types"
@ -778,18 +777,6 @@ func TestDo_staticConfiguration(t *testing.T) {
Insecure: true, Insecure: true,
Dashboard: true, Dashboard: true,
Debug: 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{ config.Metrics = &types.Metrics{

View file

@ -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
}

View file

@ -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
}

View file

@ -1,12 +1,14 @@
package api package dashboard
import ( import (
"fmt" "errors"
"io/fs"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"testing" "testing"
"testing/fstest"
"time"
assetfs "github.com/elazarl/go-bindata-assetfs"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -59,48 +61,30 @@ func Test_safePrefix(t *testing.T) {
func Test_ContentSecurityPolicy(t *testing.T) { func Test_ContentSecurityPolicy(t *testing.T) {
testCases := []struct { testCases := []struct {
desc string desc string
handler DashboardHandler handler Handler
expected int expected int
}{ }{
{ {
desc: "OK", desc: "OK",
handler: DashboardHandler{ handler: Handler{
Assets: &assetfs.AssetFS{ assets: fstest.MapFS{"foobar.html": &fstest.MapFile{
Asset: func(path string) ([]byte, error) { Mode: 0755,
return []byte{}, nil ModTime: time.Now(),
}, }},
AssetDir: func(path string) ([]string, error) {
return []string{}, nil
},
},
}, },
expected: http.StatusOK, expected: http.StatusOK,
}, },
{ {
desc: "Not found", desc: "Not found",
handler: DashboardHandler{ handler: Handler{
Assets: &assetfs.AssetFS{ assets: fstest.MapFS{},
Asset: func(path string) ([]byte, error) {
return []byte{}, fmt.Errorf("not found")
},
AssetDir: func(path string) ([]string, error) {
return []string{}, fmt.Errorf("not found")
},
},
}, },
expected: http.StatusNotFound, expected: http.StatusNotFound,
}, },
{ {
desc: "Internal server error", desc: "Internal server error",
handler: DashboardHandler{ handler: Handler{
Assets: &assetfs.AssetFS{ assets: errorFS{},
Asset: func(path string) ([]byte, error) {
return []byte{}, fmt.Errorf("oops")
},
AssetDir: func(path string) ([]string, error) {
return []string{}, fmt.Errorf("oops")
},
},
}, },
expected: http.StatusInternalServerError, 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")
}

View file

@ -6,7 +6,6 @@ import (
"reflect" "reflect"
"strings" "strings"
assetfs "github.com/elazarl/go-bindata-assetfs"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/traefik/traefik/v2/pkg/config/dynamic" "github.com/traefik/traefik/v2/pkg/config/dynamic"
"github.com/traefik/traefik/v2/pkg/config/runtime" "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. // Handler serves the configuration and status of Traefik on API endpoints.
type Handler struct { type Handler struct {
dashboard bool staticConfig static.Configuration
debug bool
staticConfig static.Configuration
dashboardAssets *assetfs.AssetFS
// runtimeConfiguration is the data set used to create all the data representations exposed by the API. // runtimeConfiguration is the data set used to create all the data representations exposed by the API.
runtimeConfiguration *runtime.Configuration runtimeConfiguration *runtime.Configuration
@ -73,11 +69,8 @@ func New(staticConfig static.Configuration, runtimeConfig *runtime.Configuration
} }
return &Handler{ return &Handler{
dashboard: staticConfig.API.Dashboard,
dashboardAssets: staticConfig.API.DashboardAssets,
runtimeConfiguration: rConfig, runtimeConfiguration: rConfig,
staticConfig: staticConfig, staticConfig: staticConfig,
debug: staticConfig.API.Debug,
} }
} }
@ -85,7 +78,7 @@ func New(staticConfig static.Configuration, runtimeConfig *runtime.Configuration
func (h Handler) createRouter() *mux.Router { func (h Handler) createRouter() *mux.Router {
router := mux.NewRouter() router := mux.NewRouter()
if h.debug { if h.staticConfig.API.Debug {
DebugHandler{}.Append(router) DebugHandler{}.Append(router)
} }
@ -118,10 +111,6 @@ func (h Handler) createRouter() *mux.Router {
version.Handler{}.Append(router) version.Handler{}.Append(router)
if h.dashboard {
DashboardHandler{Assets: h.dashboardAssets}.Append(router)
}
return router return router
} }

View file

@ -6,7 +6,6 @@ import (
"strings" "strings"
"time" "time"
assetfs "github.com/elazarl/go-bindata-assetfs"
legolog "github.com/go-acme/lego/v4/log" legolog "github.com/go-acme/lego/v4/log"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
ptypes "github.com/traefik/paerser/types" 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"` 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 // 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"` // 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. // SetDefaults sets the default values.

View file

@ -3,7 +3,9 @@ package service
import ( import (
"net/http" "net/http"
"github.com/gorilla/mux"
"github.com/traefik/traefik/v2/pkg/api" "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/runtime"
"github.com/traefik/traefik/v2/pkg/config/static" "github.com/traefik/traefik/v2/pkg/config/static"
"github.com/traefik/traefik/v2/pkg/metrics" "github.com/traefik/traefik/v2/pkg/metrics"
@ -36,10 +38,17 @@ func NewManagerFactory(staticConfiguration static.Configuration, routinesPool *s
} }
if staticConfiguration.API != nil { if staticConfiguration.API != nil {
factory.api = api.NewBuilder(staticConfiguration) apiRouterBuilder := api.NewBuilder(staticConfiguration)
if staticConfiguration.API.Dashboard { 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
} }
} }

View file

@ -1,11 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e 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 rm -f dist/traefik
FLAGS=() FLAGS=()

View file

@ -1,11 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e 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 if [ -z "$VERSION" ]; then
VERSION=$(git rev-parse HEAD) VERSION=$(git rev-parse HEAD)
fi fi

View file

@ -1,11 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e 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' RED=$'\033[31m'
GREEN=$'\033[32m' GREEN=$'\033[32m'
TEXTRESET=$'\033[0m' # reset the foreground colour TEXTRESET=$'\033[0m' # reset the foreground colour

View file

@ -4,9 +4,9 @@ const folder = process.argv[2]
async function execute () { async function execute () {
try { try {
await fs.emptyDir('../static') await fs.emptyDir('./static')
console.log('Deleted static folder contents!') 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!') console.log('Installed new files in static folder!')
} catch (err) { } catch (err) {
console.error(err) console.error(err)

12
webui/embed.go Normal file
View file

@ -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")

View file

@ -14,15 +14,15 @@ Traefik Web UI provide 2 types of information:
Use the make file : Use the make file :
```shell ```shell
make build # Generate Docker image make build-image # Generate Docker image
make generate-webui # Generate static contents in `traefik/static/` folder. make generate-webui # Generate static contents in `traefik/webui/static/` folder.
``` ```
## How to build (only for frontend developer) ## How to build (only for frontend developer)
- prerequisite: [Node 12.11+](https://nodejs.org) [Npm](https://www.npmjs.com/) - 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: - To install dependencies, execute the following commands:
@ -32,23 +32,23 @@ make generate-webui # Generate static contents in `traefik/static/` folder.
- `npm run build` - `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 JavaScript
- optimize all CSS - optimize all CSS
- add vendor prefixes to CSS (cross-bowser support) - add vendor prefixes to CSS (cross-bowser support)
- add a hash in the file names to prevent browser cache problems - 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 - bundle JavaScript in one file
## How to edit (only for frontend developer) ## 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` - Edit files in `webui/src`
- Run in development mode : - Run in development mode :
- `npm run dev` - `npm run dev`