0
Fork 0
mirror of https://github.com/project-zot/zot.git synced 2024-12-16 21:56:37 -05:00

feat(ui): package zui within zot binary (#1161)

(cherry picked from commit d557da0baba819b7cd7e6b5941528776e125ac6d)

build(ui): fix stacker builds


(cherry picked from commit ba25daf02b4a9bc7ee1cb6f84b7a6b096ca7d61f)

build(ui): various fixes

- Fix metrics endpoint
- Fix unit tests unit tests
- Make the ui build optional in the makefile
before the linter lint runs in the golangci-lint workflow
- Do not attempt to include UI routes if search is enabled
- Fix authorization for search endpoint



fix: use zot tag in ui make target


(cherry picked from commit 2a6882fa23f06b2d68c6c299773a6ff50bf90e78)

Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>
Signed-off-by: Catalin Hofnar <catalin.hofnar@gmail.com>
Signed-off-by: Andrei Aaron <aaaron@luxoft.com>
Co-authored-by: Ramkumar Chinchani <rchincha@cisco.com>
This commit is contained in:
Andrei Aaron 2023-02-11 00:52:54 +02:00 committed by GitHub
parent d12836e69c
commit c0aaca8ed1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 189 additions and 37 deletions

View file

@ -41,6 +41,19 @@ jobs:
go-version: 1.19.x
- name: Check out source code
uses: actions/checkout@v3
- name: Push release tag to zui
if: github.event_name == 'release' && github.event.action == 'published' && matrix.os == 'linux' && matrix.arch == 'amd64'
uses: ncipollo/release-action@v1
with:
token: ${{ secrets.ZUI_TOKEN }}
repo: zui
owner: project-zot
tag: ${{ github.event.release.tag_name }}
name: ${{ github.event.release.name }}
body: ${{ github.event.release.body }}
commit: main
- name: Cache go dependencies
id: cache-go-dependencies
uses: actions/cache@v3
@ -105,7 +118,7 @@ jobs:
make OS=$OS ARCH=$ARCH
sudo env "PATH=$PATH" make privileged-test
else
make OS=$OS ARCH=$ARCH binary binary-minimal binary-debug cli bench exporter-minimal
make OS=$OS ARCH=$ARCH binary binary-minimal binary-debug binary-ui cli bench exporter-minimal
fi
env:
S3MOCK_ENDPOINT: localhost:4566

3
.gitignore vendored
View file

@ -11,6 +11,9 @@
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Output of the UI build
pkg/extensions/build/
# Tooling used for blackbox testing
hack/
.stacker/

View file

@ -32,7 +32,7 @@ hyphen:= -
extended-name:=
.PHONY: all
all: modcheck swagger binary binary-minimal binary-debug cli bench exporter-minimal verify-config test covhtml check check-gh-actions
all: modcheck swagger binary binary-minimal binary-debug binary-ui cli bench exporter-minimal verify-config test covhtml check check-gh-actions
.PHONY: modcheck
modcheck:
@ -45,7 +45,7 @@ ifdef EXTENSIONS
endif
.PHONY: build-metadata
build-metadata:
build-metadata: $(if $(findstring ui,$(EXTENSIONS)), ui)
echo "Imports: \n"
go list -tags $(EXTENSIONS) -f '{{ join .Imports "\n" }}' ./... | sort -u
echo "\n Files: \n"
@ -57,13 +57,19 @@ binary-minimal: modcheck build-metadata
env CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) go build -o bin/zot-$(OS)-$(ARCH)-minimal -buildmode=pie -tags containers_image_openpgp -v -trimpath -ldflags "-X zotregistry.io/zot/pkg/api/config.ReleaseTag=${RELEASE_TAG} -X zotregistry.io/zot/pkg/api/config.Commit=${COMMIT} -X zotregistry.io/zot/pkg/api/config.BinaryType=minimal -X zotregistry.io/zot/pkg/api/config.GoVersion=${GO_VERSION} -s -w" ./cmd/zot
.PHONY: binary
binary: $(if $(findstring ui,$(EXTENSIONS)), ui)
binary: modcheck create-name build-metadata
env CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) go build -o bin/zot-$(OS)-$(ARCH) -buildmode=pie -tags $(EXTENSIONS),containers_image_openpgp -v -trimpath -ldflags "-X zotregistry.io/zot/pkg/api/config.ReleaseTag=${RELEASE_TAG} -X zotregistry.io/zot/pkg/api/config.Commit=${COMMIT} -X zotregistry.io/zot/pkg/api/config.BinaryType=$(extended-name) -X zotregistry.io/zot/pkg/api/config.GoVersion=${GO_VERSION} -s -w" ./cmd/zot
.PHONY: binary-debug
binary-debug: $(if $(findstring ui,$(EXTENSIONS)), ui)
binary-debug: modcheck swagger create-name build-metadata
env CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) go build -o bin/zot-$(OS)-$(ARCH)-debug -buildmode=pie -tags $(EXTENSIONS),debug,containers_image_openpgp -v -gcflags all='-N -l' -ldflags "-X zotregistry.io/zot/pkg/api/config.ReleaseTag=${RELEASE_TAG} -X zotregistry.io/zot/pkg/api/config.Commit=${COMMIT} -X zotregistry.io/zot/pkg/api/config.BinaryType=$(extended-name) -X zotregistry.io/zot/pkg/api/config.GoVersion=${GO_VERSION}" ./cmd/zot
.PHONY: binary-ui
binary-ui: modcheck create-name build-metadata ui
env CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) go build -o bin/zot-$(OS)-$(ARCH)-ui -buildmode=pie -tags $(EXTENSIONS),ui,containers_image_openpgp -v -trimpath -ldflags "-X zotregistry.io/zot/pkg/api/config.Commit=${COMMIT} -X zotregistry.io/zot/pkg/api/config.BinaryType=$(extended-name) -X zotregistry.io/zot/pkg/api/config.GoVersion=${GO_VERSION} -s -w" ./cmd/zot
.PHONY: cli
cli: modcheck create-name build-metadata
env CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) go build -o bin/zli-$(OS)-$(ARCH) -buildmode=pie -tags $(EXTENSIONS),search,containers_image_openpgp -v -trimpath -ldflags "-X zotregistry.io/zot/pkg/api/config.Commit=${COMMIT} -X zotregistry.io/zot/pkg/api/config.BinaryType=$(extended-name) -X zotregistry.io/zot/pkg/api/config.GoVersion=${GO_VERSION} -s -w" ./cmd/zli
@ -78,6 +84,7 @@ exporter-minimal: modcheck build-metadata
env CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) go build -o bin/zxp-$(OS)-$(ARCH) -buildmode=pie -tags containers_image_openpgp -v -trimpath ./cmd/zxp
.PHONY: test
test: $(if $(findstring ui,$(EXTENSIONS)), ui)
test: check-skopeo $(TESTDATA) $(NOTATION) $(ORAS)
go test -failfast -tags $(EXTENSIONS),containers_image_openpgp -v -trimpath -race -timeout 15m -cover -coverpkg ./... -coverprofile=coverage-extended.txt -covermode=atomic ./...
go test -failfast -tags containers_image_openpgp -v -trimpath -race -cover -coverpkg ./... -coverprofile=coverage-minimal.txt -covermode=atomic ./...
@ -87,6 +94,7 @@ test: check-skopeo $(TESTDATA) $(NOTATION) $(ORAS)
go test -failfast -tags stress,$(EXTENSIONS),containers_image_openpgp -v -trimpath -race -timeout 15m ./pkg/cli/stress_test.go
.PHONY: privileged-test
privileged-test: $(if $(findstring ui,$(EXTENSIONS)), ui)
privileged-test: check-skopeo $(TESTDATA) $(NOTATION)
go test -failfast -tags needprivileges,$(EXTENSIONS),containers_image_openpgp -v -trimpath -race -timeout 15m -cover -coverpkg ./... -coverprofile=coverage-dev-needprivileges.txt -covermode=atomic ./pkg/storage/... ./pkg/cli/... -run ^TestElevatedPrivileges
@ -151,12 +159,16 @@ $(GOLINTER):
$(GOLINTER) version
.PHONY: check
check: $(if $(findstring ui,$(EXTENSIONS)), ui)
check: ./golangcilint.yaml $(GOLINTER)
mkdir -p pkg/extensions/build; touch pkg/extensions/build/.empty
$(GOLINTER) --config ./golangcilint.yaml run --enable-all --out-format=colored-line-number --build-tags containers_image_openpgp ./...
$(GOLINTER) --config ./golangcilint.yaml run --enable-all --out-format=colored-line-number --build-tags $(EXTENSIONS),containers_image_openpgp ./...
$(GOLINTER) --config ./golangcilint.yaml run --enable-all --out-format=colored-line-number --build-tags $(EXTENSIONS),containers_image_openpgp,ui,debug ./...
$(GOLINTER) --config ./golangcilint.yaml run --enable-all --out-format=colored-line-number --build-tags dev,containers_image_openpgp ./...
$(GOLINTER) --config ./golangcilint.yaml run --enable-all --out-format=colored-line-number --build-tags dev,$(EXTENSIONS),containers_image_openpgp ./...
$(GOLINTER) --config ./golangcilint.yaml run --enable-all --out-format=colored-line-number --build-tags stress,$(EXTENSIONS),containers_image_openpgp ./...
rm pkg/extensions/build/.empty
swagger/docs.go:
swag -v || go install github.com/swaggo/swag/cmd/swag@1.6.3
@ -204,6 +216,7 @@ clean:
rm -rf hack
rm -rf test/data/zot-test
rm -rf test/data/zot-cve-test
rm -rf pkg/extensions/build
.PHONY: run
run: binary test
@ -262,12 +275,12 @@ run-container:
.PHONY: binary-stacker
binary-stacker:
${STACKER} build \
${STACKER} --debug build \
-f build/stacker.yaml \
--substitute COMMIT=$(PWD) \
--substitute OS=$(OS) \
--substitute ARCH=$(ARCH) \
--substitute PWD=$(PWD)
--substitute PWD=$$PWD \
--substitute COMMIT=$$COMMIT \
--substitute ARCH=$$ARCH \
--substitute OS=$$OS
.PHONY: image
image:
@ -369,3 +382,20 @@ $(COSIGN):
mkdir -p $(TOOLSDIR)/bin
curl -fsSL https://github.com/sigstore/cosign/releases/download/v1.13.0/cosign-linux-amd64 -o $@; \
chmod +x $@
.PHONY: ui
ui:
pwd=$$(pwd);\
tdir=$$(mktemp -d);\
cd $$tdir;\
if [ -z $(RELEASE_UI) ]; then\
git clone https://github.com/project-zot/zui.git;\
else\
git clone --depth 1 --branch $(RELEASE_TAG) https://github.com/project-zot/zui.git;\
fi;\
cd zui;\
npm install;\
npm run build;\
cd $$pwd;\
rm -rf ./pkg/extensions/build;\
cp -R $$tdir/zui/build ./pkg/extensions/;

View file

@ -45,7 +45,7 @@ build:
arch: ${{ARCH}}
from:
type: docker
url: docker://gcr.io/distroless/base:latest-${{ARCH}}
url: docker://zothub.io/c3/base:jammy
overlay_dirs:
- source: ../.build/${{REPO_NAME}}/binary
dest: /usr/local/bin

23
examples/config-ui.json Normal file
View file

@ -0,0 +1,23 @@
{
"distSpecVersion": "1.1.0-dev",
"storage": {
"rootDirectory": "/tmp/zot"
},
"http": {
"address": "0.0.0.0",
"port": "8080"
},
"log": {
"level": "debug"
},
"extensions": {
"search": {
"cve": {
"updateInterval": "2h"
}
},
"ui": {
"enable": true
}
}
}

View file

@ -58,7 +58,8 @@ func allowedMethods(method string) []string {
}
func (rh *RouteHandler) SetupRoutes() {
rh.c.Router.Use(AuthHandler(rh.c))
prefixedRouter := rh.c.Router.PathPrefix(constants.RoutePrefix).Subrouter()
prefixedRouter.Use(AuthHandler(rh.c))
// authz is being enabled if AccessControl is specified
// if Authn is not present AccessControl will have only default policies
if rh.c.Config.AccessControl != nil && !isBearerAuthEnabled(rh.c.Config) {
@ -68,11 +69,10 @@ func (rh *RouteHandler) SetupRoutes() {
rh.c.Log.Info().Msg("default policy only access control is being enabled")
}
rh.c.Router.Use(AuthzHandler(rh.c))
prefixedRouter.Use(AuthzHandler(rh.c))
}
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#endpoints
prefixedRouter := rh.c.Router.PathPrefix(constants.RoutePrefix).Subrouter()
{
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/tags/list", zreg.NameRegexp.String()),
rh.ListTags).Methods(allowedMethods("GET")...)
@ -116,7 +116,7 @@ func (rh *RouteHandler) SetupRoutes() {
constants.ArtifactSpecRoutePrefix, zreg.NameRegexp.String()), rh.GetOrasReferrers).Methods("GET")
// swagger
debug.SetupSwaggerRoutes(rh.c.Config, rh.c.Router, rh.c.Log)
debug.SetupSwaggerRoutes(rh.c.Config, rh.c.Router, AuthHandler(rh.c), rh.c.Log)
// Setup Extensions Routes
if rh.c.Config != nil {
@ -125,9 +125,10 @@ func (rh *RouteHandler) SetupRoutes() {
prefixedRouter.HandleFunc("/metrics", rh.GetMetrics).Methods("GET")
} else {
// extended build
ext.SetupMetricsRoutes(rh.c.Config, rh.c.Router, rh.c.StoreController, rh.c.Log)
ext.SetupSearchRoutes(rh.c.Config, rh.c.Router, rh.c.StoreController, rh.c.RepoDB, rh.c.CveInfo, rh.c.Log)
gqlPlayground.SetupGQLPlaygroundRoutes(rh.c.Config, rh.c.Router, rh.c.StoreController, rh.c.Log)
ext.SetupMetricsRoutes(rh.c.Config, rh.c.Router, rh.c.StoreController, AuthHandler(rh.c), rh.c.Log)
ext.SetupSearchRoutes(rh.c.Config, prefixedRouter, rh.c.StoreController, rh.c.RepoDB, rh.c.CveInfo, rh.c.Log)
ext.SetupUIRoutes(rh.c.Config, rh.c.Router, rh.c.StoreController, rh.c.Log)
gqlPlayground.SetupGQLPlaygroundRoutes(rh.c.Config, prefixedRouter, rh.c.StoreController, rh.c.Log)
}
}
}

View file

@ -107,7 +107,8 @@ func TestServeExtensions(t *testing.T) {
WaitTillServerReady(baseURL)
data, err := os.ReadFile(logFile.Name())
So(err, ShouldBeNil)
So(string(data), ShouldContainSubstring, "\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":null,\"Scrub\":null,\"Lint\":null") //nolint:lll // gofumpt conflicts with lll
So(string(data), ShouldContainSubstring,
"\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":null,\"Scrub\":null,\"Lint\":null,\"UI\":null") //nolint:lll // gofumpt conflicts with lll
})
}
@ -148,7 +149,7 @@ func testWithMetricsEnabled(cfgContentFormat string) {
data, err := os.ReadFile(logFile.Name())
So(err, ShouldBeNil)
So(string(data), ShouldContainSubstring,
"\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":{\"Enable\":true,\"Prometheus\":{\"Path\":\"/metrics\"}},\"Scrub\":null,\"Lint\":null}") //nolint:lll // gofumpt conflicts with lll
"\"Metrics\":{\"Enable\":true,\"Prometheus\":{\"Path\":\"/metrics\"}}")
}
func TestServeMetricsExtension(t *testing.T) {
@ -272,7 +273,7 @@ func TestServeMetricsExtension(t *testing.T) {
data, err := os.ReadFile(logFile.Name())
So(err, ShouldBeNil)
So(string(data), ShouldContainSubstring,
"\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":{\"Enable\":false,\"Prometheus\":{\"Path\":\"/metrics\"}},\"Scrub\":null,\"Lint\":null}}") //nolint:lll // gofumpt conflicts with lll
"\"Metrics\":{\"Enable\":false,\"Prometheus\":{\"Path\":\"/metrics\"}}") //nolint:lll // gofumpt conflicts with lll
})
}
@ -472,8 +473,7 @@ func TestServeScrubExtension(t *testing.T) {
defer os.Remove(logPath) // clean up
// Even if in config we specified scrub interval=1h, the minimum interval is 2h
dataStr := string(data)
So(dataStr, ShouldContainSubstring,
"\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":null,\"Scrub\":{\"Enable\":true,\"Interval\":3600000000000},\"Lint\":null") //nolint:lll // gofumpt conflicts with lll
So(dataStr, ShouldContainSubstring, "\"Scrub\":{\"Enable\":true,\"Interval\":3600000000000}")
So(dataStr, ShouldContainSubstring,
"Scrub interval set to too-short interval < 2h, changing scrub duration to 2 hours and continuing.")
})
@ -536,8 +536,7 @@ func TestServeScrubExtension(t *testing.T) {
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
dataStr := string(data)
So(dataStr, ShouldContainSubstring,
"\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":null,\"Scrub\":{\"Enable\":false,\"Interval\":86400000000000},\"Lint\":null}") //nolint:lll // gofumpt conflicts with lll
So(dataStr, ShouldContainSubstring, "\"Scrub\":{\"Enable\":false,\"Interval\":86400000000000}")
So(dataStr, ShouldContainSubstring, "Scrub config not provided, skipping scrub")
So(dataStr, ShouldNotContainSubstring,
"Scrub interval set to too-short interval < 2h, changing scrub duration to 2 hours and continuing.")
@ -639,7 +638,8 @@ func TestServeSearchEnabled(t *testing.T) {
// to avoid data race when multiple go routines write to trivy DB instance.
defer os.Remove(logPath) // clean up
substring := "\"Extensions\":{\"Search\":{\"Enable\":true,\"CVE\":null},\"Sync\":null,\"Metrics\":null,\"Scrub\":null,\"Lint\":null}" //nolint:lll // gofumpt conflicts with lll
substring := `"Extensions":{"Search":{"Enable":true,"CVE":null}`
found, err := readLogFileAndSearchString(logPath, substring, readLogFileTimeout)
So(found, ShouldBeTrue)
So(err, ShouldBeNil)
@ -680,7 +680,8 @@ func TestServeSearchEnabledCVE(t *testing.T) {
// to avoid data race when multiple go routines write to trivy DB instance.
WaitTillTrivyDBDownloadStarted(tempDir)
substring := "\"Extensions\":{\"Search\":{\"Enable\":true,\"CVE\":{\"UpdateInterval\":3600000000000,\"Trivy\":null}},\"Sync\":null,\"Metrics\":null,\"Scrub\":null,\"Lint\":null}" //nolint:lll // gofumpt conflicts with lll
substring := "\"Search\":{\"Enable\":true,\"CVE\":{\"UpdateInterval\":3600000000000,\"Trivy\":null}}"
found, err := readLogFileAndSearchString(logPath, substring, readLogFileTimeout)
So(found, ShouldBeTrue)
So(err, ShouldBeNil)
@ -726,7 +727,7 @@ func TestServeSearchEnabledNoCVE(t *testing.T) {
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
substring := "\"Extensions\":{\"Search\":{\"Enable\":true,\"CVE\":null},\"Sync\":null,\"Metrics\":null,\"Scrub\":null,\"Lint\":null}" //nolint:lll // gofumpt conflicts with lll
substring := `"Extensions":{"Search":{"Enable":true,"CVE":null}` //nolint:lll // gofumpt conflicts with lll
found, err := readLogFileAndSearchString(logPath, substring, readLogFileTimeout)
So(found, ShouldBeTrue)
So(err, ShouldBeNil)
@ -768,7 +769,7 @@ func TestServeSearchDisabled(t *testing.T) {
defer os.Remove(logPath) // clean up
dataStr := string(data)
So(dataStr, ShouldContainSubstring,
"\"Extensions\":{\"Search\":{\"Enable\":false,\"CVE\":{\"UpdateInterval\":10800000000000,\"Trivy\":null}},\"Sync\":null,\"Metrics\":null,\"Scrub\":null,\"Lint\":null}") //nolint:lll // gofumpt conflicts with lll
"\"Search\":{\"Enable\":false,\"CVE\":{\"UpdateInterval\":10800000000000,\"Trivy\":null}")
So(dataStr, ShouldContainSubstring, "CVE config not provided, skipping CVE update")
So(dataStr, ShouldNotContainSubstring,
"CVE update interval set to too-short interval < 2h, changing update duration to 2 hours and continuing.")

View file

@ -33,7 +33,7 @@ func SetupGQLPlaygroundRoutes(conf *config.Config, router *mux.Router,
}
//nolint:lll
router.PathPrefix(constants.RoutePrefix + debugCst.GQLPlaygroundEndpoint).HandlerFunc(func(writer http.ResponseWriter, req *http.Request) {
router.PathPrefix(debugCst.GQLPlaygroundEndpoint).HandlerFunc(func(writer http.ResponseWriter, req *http.Request) {
writer.Header().Add("Content-Type", "text/html")
proto := ""

View file

@ -17,9 +17,12 @@ import (
_ "zotregistry.io/zot/swagger"
)
func SetupSwaggerRoutes(conf *config.Config, router *mux.Router, log log.Logger,
func SetupSwaggerRoutes(conf *config.Config, router *mux.Router, authFunc mux.MiddlewareFunc,
log log.Logger,
) {
log.Info().Msg("setting up swagger route")
// swagger swagger "/swagger/v2/index.html"
router.PathPrefix("/swagger/v2/").Methods("GET").Handler(httpSwagger.WrapHandler)
swgRouter := router.PathPrefix("/swagger/v2/").Subrouter()
swgRouter.Use(authFunc)
swgRouter.Methods("GET").Handler(httpSwagger.WrapHandler)
}

View file

@ -16,7 +16,8 @@ import (
_ "zotregistry.io/zot/swagger"
)
func SetupSwaggerRoutes(conf *config.Config, router *mux.Router, log log.Logger,
func SetupSwaggerRoutes(conf *config.Config, router *mux.Router, authFunc mux.MiddlewareFunc,
log log.Logger,
) {
// swagger swagger "/swagger/v2/index.html"
log.Warn().Msg("skipping enabling swagger because given zot binary " +

View file

@ -17,6 +17,7 @@ type ExtensionConfig struct {
Metrics *MetricsConfig
Scrub *ScrubConfig
Lint *LintConfig
UI *UIConfig
}
type LintConfig struct {
@ -52,3 +53,7 @@ type ScrubConfig struct {
BaseConfig `mapstructure:",squash"`
Interval time.Duration
}
type UIConfig struct {
BaseConfig `mapstructure:",squash"`
}

View file

@ -0,0 +1,19 @@
//go:build !search || !ui
// +build !search !ui
package extensions
import (
"github.com/gorilla/mux"
"zotregistry.io/zot/pkg/api/config"
"zotregistry.io/zot/pkg/log"
"zotregistry.io/zot/pkg/storage"
)
func SetupUIRoutes(config *config.Config, router *mux.Router, storeController storage.StoreController,
log log.Logger,
) {
log.Warn().Msg("skipping setting up ui routes because given zot binary doesn't include this feature," +
"please build a binary that does so")
}

View file

@ -0,0 +1,51 @@
//go:build search && ui
// +build search,ui
package extensions
import (
"embed"
"io/fs"
"net/http"
"github.com/gorilla/mux"
"zotregistry.io/zot/pkg/api/config"
"zotregistry.io/zot/pkg/log"
"zotregistry.io/zot/pkg/storage"
)
// content is our static web server content.
//
//go:embed build/*
var content embed.FS
type uiHandler struct {
log log.Logger
}
func (uih uiHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
buf, _ := content.ReadFile("build/index.html")
_, err := w.Write(buf)
if err != nil {
uih.log.Error().Err(err).Msg("unable to serve index.html")
}
}
func SetupUIRoutes(config *config.Config, router *mux.Router, storeController storage.StoreController,
log log.Logger,
) {
if config.Extensions.UI != nil {
fsub, _ := fs.Sub(content, "build")
uih := uiHandler{log: log}
router.PathPrefix("/login").Handler(uih)
router.PathPrefix("/home").Handler(uih)
router.PathPrefix("/explore").Handler(uih)
router.PathPrefix("/image").Handler(uih)
router.PathPrefix("/").Handler(http.FileServer(http.FS(fsub)))
log.Info().Msg("setting up ui routes")
}
}

View file

@ -27,12 +27,13 @@ func EnableMetricsExtension(config *config.Config, log log.Logger, rootDir strin
}
func SetupMetricsRoutes(config *config.Config, router *mux.Router, storeController storage.StoreController,
log log.Logger,
authFunc mux.MiddlewareFunc, log log.Logger,
) {
log.Info().Msg("setting up metrics routes")
if config.Extensions.Metrics != nil && *config.Extensions.Metrics.Enable {
router.PathPrefix(config.Extensions.Metrics.Prometheus.Path).
Handler(promhttp.Handler())
extRouter := router.PathPrefix(config.Extensions.Metrics.Prometheus.Path).Subrouter()
extRouter.Use(authFunc)
extRouter.Methods("GET").Handler(promhttp.Handler())
}
}

View file

@ -19,7 +19,7 @@ func EnableMetricsExtension(config *config.Config, log log.Logger, rootDir strin
// SetupMetricsRoutes ...
func SetupMetricsRoutes(conf *config.Config, router *mux.Router,
storeController storage.StoreController, log log.Logger,
storeController storage.StoreController, authFunc mux.MiddlewareFunc, log log.Logger,
) {
log.Warn().Msg("skipping setting up metrics routes because given zot binary doesn't include this feature," +
"please build a binary that does so")

View file

@ -84,8 +84,9 @@ func SetupSearchRoutes(config *config.Config, router *mux.Router, storeControlle
if config.Extensions.Search != nil && *config.Extensions.Search.Enable {
resConfig := search.GetResolverConfig(log, storeController, repoDB, cveInfo)
graphqlPrefix := router.PathPrefix(constants.FullSearchPrefix).Methods("OPTIONS", "GET", "POST")
graphqlPrefix.Handler(gqlHandler.NewDefaultServer(gql_generated.NewExecutableSchema(resConfig)))
extRouter := router.PathPrefix(constants.ExtSearchPrefix).Subrouter()
extRouter.Methods("GET", "POST", "OPTIONS").
Handler(gqlHandler.NewDefaultServer(gql_generated.NewExecutableSchema(resConfig)))
}
}