mirror of
https://github.com/project-zot/zot.git
synced 2026-06-16 20:38:08 +08:00
Manage builds with different combinations of extensions
Files were added to be built whether an extension is on or off. New build tags were added for each extension, while minimal and extended disappeared. added custom binary naming depending on extensions used and changed references from binary to binary-extended added automated blackbox tests for sync, search, scrub, metrics added contributor guidelines Signed-off-by: Alex Stan <alexandrustan96@yahoo.ro>
This commit is contained in:
committed by
Ramkumar Chinchani
parent
616d5f8a6d
commit
ada21ed842
@@ -353,21 +353,23 @@ func (c *Controller) Shutdown() {
|
||||
func (c *Controller) StartBackgroundTasks(reloadCtx context.Context) {
|
||||
// Enable extensions if extension config is provided for DefaultStore
|
||||
if c.Config != nil && c.Config.Extensions != nil {
|
||||
ext.EnableExtensions(c.Config, c.Log, c.Config.Storage.RootDirectory)
|
||||
ext.EnableMetricsExtension(c.Config, c.Log, c.Config.Storage.RootDirectory)
|
||||
ext.EnableSearchExtension(c.Config, c.Log, c.Config.Storage.RootDirectory)
|
||||
}
|
||||
|
||||
if c.Config.Storage.SubPaths != nil {
|
||||
for _, storageConfig := range c.Config.Storage.SubPaths {
|
||||
// Enable extensions if extension config is provided for subImageStore
|
||||
if c.Config != nil && c.Config.Extensions != nil {
|
||||
ext.EnableExtensions(c.Config, c.Log, storageConfig.RootDirectory)
|
||||
ext.EnableMetricsExtension(c.Config, c.Log, storageConfig.RootDirectory)
|
||||
ext.EnableSearchExtension(c.Config, c.Log, storageConfig.RootDirectory)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Enable extensions if extension config is provided for storeController
|
||||
if c.Config.Extensions != nil {
|
||||
if c.Config.Extensions.Sync != nil && *c.Config.Extensions.Sync.Enable {
|
||||
if c.Config.Extensions.Sync != nil {
|
||||
ext.EnableSyncExtension(reloadCtx, c.Config, c.wgShutDown, c.StoreController, c.Log)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build sync && scrub && metrics && search && ui_base
|
||||
// +build sync,scrub,metrics,search,ui_base
|
||||
|
||||
package api_test
|
||||
|
||||
|
||||
+2
-1
@@ -121,7 +121,8 @@ func (rh *RouteHandler) SetupRoutes() {
|
||||
prefixedRouter.HandleFunc("/metrics", rh.GetMetrics).Methods("GET")
|
||||
} else {
|
||||
// extended build
|
||||
ext.SetupRoutes(rh.c.Config, rh.c.Router, rh.c.StoreController, rh.c.Log)
|
||||
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.Log)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build sync && scrub && metrics && search && ui_base
|
||||
// +build sync,scrub,metrics,search,ui_base
|
||||
|
||||
package api_test
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build ui_base || search
|
||||
// +build ui_base search
|
||||
|
||||
package cli
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build search || ui_base
|
||||
// +build search ui_base
|
||||
|
||||
package cli
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended && needprivileges
|
||||
// +build extended,needprivileges
|
||||
//go:build ui_base && needprivileges
|
||||
// +build ui_base,needprivileges
|
||||
|
||||
package cli //nolint:testpackage
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build ui_base
|
||||
// +build ui_base
|
||||
|
||||
package cli //nolint:testpackage
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build search || ui_base
|
||||
// +build search ui_base
|
||||
|
||||
package cli
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build ui_base
|
||||
// +build ui_base
|
||||
|
||||
package cli //nolint:testpackage
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build search || ui_base
|
||||
// +build search ui_base
|
||||
|
||||
package cli
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build ui_base
|
||||
// +build ui_base
|
||||
|
||||
package cli //nolint:testpackage
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build sync && scrub && metrics && search && ui_base
|
||||
// +build sync,scrub,metrics,search,ui_base
|
||||
|
||||
package cli_test
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build search || ui_base
|
||||
// +build search ui_base
|
||||
|
||||
package cli
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build ui_base
|
||||
// +build ui_base
|
||||
|
||||
package cli //nolint:testpackage
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
//go:build minimal
|
||||
// +build minimal
|
||||
//go:build !search && !ui_base
|
||||
// +build !search,!ui_base
|
||||
|
||||
package cli
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build search || ui_base
|
||||
// +build search ui_base
|
||||
|
||||
package cli
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build search || ui_base
|
||||
// +build search ui_base
|
||||
|
||||
package cli
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build ui_base || search
|
||||
// +build ui_base search
|
||||
|
||||
package cli
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build minimal
|
||||
// +build minimal
|
||||
//go:build !metrics
|
||||
// +build !metrics
|
||||
|
||||
package api
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build minimal
|
||||
// +build minimal
|
||||
//go:build !metrics
|
||||
// +build !metrics
|
||||
|
||||
package api
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build minimal
|
||||
// +build minimal
|
||||
//go:build !metrics
|
||||
// +build !metrics
|
||||
|
||||
package api_test
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build minimal
|
||||
// +build minimal
|
||||
//go:build !metrics
|
||||
// +build !metrics
|
||||
|
||||
// nolint: varnamelen
|
||||
package api
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build minimal
|
||||
// +build minimal
|
||||
//go:build !metrics
|
||||
// +build !metrics
|
||||
|
||||
package cli
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
## Adding new extensions
|
||||
|
||||
As new requirements come and build time extensions need to be added, there are a few things that you have to make sure are present before commiting :
|
||||
|
||||
- files that should be included in the binary only with a specific extension must contain the following syntax at the beginning of the file :
|
||||
|
||||
//go:build sync will be added automatically by the linter, so only the second line is mandatory .
|
||||
|
||||
NOTE: the third line in the example should be blank, otherwise the build tag would be just another comment.
|
||||
|
||||
```
|
||||
//go:build sync
|
||||
// +build sync
|
||||
|
||||
package extensions
|
||||
...................
|
||||
```
|
||||
|
||||
- when adding a new tag, specify the new order in which multiple tags should be used (bottom of this page)
|
||||
|
||||
- for each and every new file that contains functions (functionalities) specific to an extension, one should create a corresponding file that <b>must contain the exact same functions, but no functionalities included</b>. This file must begin with an "anti-tag" (e.g. // +build !sync) which will include this file in binaries that don't include this extension ( in this example, the file won't be used in binaries that include sync extension ). See [extension-sync-disabled.go](extension-sync-disabled.go) for an example.
|
||||
|
||||
- when a new extension comes out, the developer should also write some blackbox tests, where a binary that contains the new extension should be tested in a real usage scenario. See [test/blackbox](test/blackbox/sync.bats) folder for multiple extensions examples.
|
||||
|
||||
- newly added blackbox tests should have targets in Makefile. You should also add them as Github Workflows, in [.github/workflows/ecosystem-tools.yaml](.github/workflows/ecosystem-tools.yaml)
|
||||
|
||||
- with every new extension, you should modify the EXTENSIONS variable in Makefile by adding the new extension. The EXTENSIONS variable represents all extensions and is used in Make targets that require them all (e.g make test).
|
||||
|
||||
- the available extensions that can be used at the moment are: <b>sync, scrub, metrics, search, ui_base </b>.
|
||||
NOTE: When multiple extensions are used, they should be enlisted in the above presented order.
|
||||
@@ -0,0 +1,25 @@
|
||||
//go:build !metrics
|
||||
// +build !metrics
|
||||
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"github.com/gorilla/mux"
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
)
|
||||
|
||||
// EnableMetricsExtension ...
|
||||
func EnableMetricsExtension(config *config.Config, log log.Logger, rootDir string) {
|
||||
log.Warn().Msg("skipping enabling metrics extension because given zot binary doesn't include this feature," +
|
||||
"please build a binary that does so")
|
||||
}
|
||||
|
||||
// SetupMetricsRoutes ...
|
||||
func SetupMetricsRoutes(conf *config.Config, router *mux.Router,
|
||||
storeController storage.StoreController, 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")
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//go:build metrics
|
||||
// +build metrics
|
||||
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
)
|
||||
|
||||
func EnableMetricsExtension(config *config.Config, log log.Logger, rootDir string) {
|
||||
if config.Extensions.Metrics != nil &&
|
||||
*config.Extensions.Metrics.Enable &&
|
||||
config.Extensions.Metrics.Prometheus != nil {
|
||||
if config.Extensions.Metrics.Prometheus.Path == "" {
|
||||
config.Extensions.Metrics.Prometheus.Path = "/metrics"
|
||||
|
||||
log.Warn().Msg("Prometheus instrumentation Path not set, changing to '/metrics'.")
|
||||
}
|
||||
} else {
|
||||
log.Info().Msg("Metrics config not provided, skipping Metrics config update")
|
||||
}
|
||||
}
|
||||
|
||||
func SetupMetricsRoutes(config *config.Config, router *mux.Router, storeController storage.StoreController,
|
||||
l log.Logger,
|
||||
) {
|
||||
// fork a new zerolog child to avoid data race
|
||||
log := log.Logger{Logger: l.With().Caller().Timestamp().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())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//go:build !scrub
|
||||
// +build !scrub
|
||||
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
)
|
||||
|
||||
// EnableScrubExtension ...
|
||||
func EnableScrubExtension(config *config.Config,
|
||||
log log.Logger, run bool,
|
||||
imgStore storage.ImageStore, repo string,
|
||||
) {
|
||||
log.Warn().Msg("skipping enabling scrub extension because given zot binary doesn't include this feature," +
|
||||
"please build a binary that does so")
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
//go:build scrub
|
||||
// +build scrub
|
||||
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
"zotregistry.io/zot/pkg/extensions/scrub"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
)
|
||||
|
||||
// EnableScrubExtension enables scrub extension.
|
||||
func EnableScrubExtension(config *config.Config, log log.Logger, run bool, imgStore storage.ImageStore, repo string) {
|
||||
if !run {
|
||||
if config.Extensions.Scrub != nil &&
|
||||
config.Extensions.Scrub.Interval != 0 {
|
||||
minScrubInterval, _ := time.ParseDuration("2h")
|
||||
|
||||
if config.Extensions.Scrub.Interval < minScrubInterval {
|
||||
config.Extensions.Scrub.Interval = minScrubInterval
|
||||
|
||||
log.Warn().Msg("Scrub interval set to too-short interval < 2h, changing scrub duration to 2 hours and continuing.") //nolint:lll // gofumpt conflicts with lll
|
||||
}
|
||||
} else {
|
||||
log.Info().Msg("Scrub config not provided, skipping scrub")
|
||||
}
|
||||
} else {
|
||||
scrub.RunScrubRepo(imgStore, repo, log)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
//go:build !search && !ui_base
|
||||
// +build !search,!ui_base
|
||||
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"github.com/gorilla/mux"
|
||||
distext "github.com/opencontainers/distribution-spec/specs-go/v1/extensions"
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
)
|
||||
|
||||
// EnableSearchExtension ...
|
||||
func EnableSearchExtension(config *config.Config, log log.Logger, rootDir string) {
|
||||
log.Warn().Msg("skipping enabling search extension because given zot binary doesn't include this feature," +
|
||||
"please build a binary that does so")
|
||||
}
|
||||
|
||||
// SetupSearchRoutes ...
|
||||
func SetupSearchRoutes(conf *config.Config, router *mux.Router,
|
||||
storeController storage.StoreController, log log.Logger,
|
||||
) {
|
||||
log.Warn().Msg("skipping setting up search routes because given zot binary doesn't include this feature," +
|
||||
"please build a binary that does so")
|
||||
}
|
||||
|
||||
// GetExtensions...
|
||||
func GetExtensions(config *config.Config) distext.ExtensionList {
|
||||
return distext.ExtensionList{}
|
||||
}
|
||||
@@ -1,45 +1,23 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build search || ui_base
|
||||
// +build search ui_base
|
||||
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
goSync "sync"
|
||||
"time"
|
||||
|
||||
gqlHandler "github.com/99designs/gqlgen/graphql/handler"
|
||||
"github.com/gorilla/mux"
|
||||
distext "github.com/opencontainers/distribution-spec/specs-go/v1/extensions"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
"zotregistry.io/zot/pkg/api/constants"
|
||||
"zotregistry.io/zot/pkg/extensions/scrub"
|
||||
"zotregistry.io/zot/pkg/extensions/search"
|
||||
cveinfo "zotregistry.io/zot/pkg/extensions/search/cve"
|
||||
"zotregistry.io/zot/pkg/extensions/sync"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
)
|
||||
|
||||
// DownloadTrivyDB ...
|
||||
func downloadTrivyDB(dbDir string, log log.Logger, updateInterval time.Duration) error {
|
||||
for {
|
||||
log.Info().Msg("updating the CVE database")
|
||||
|
||||
err := cveinfo.UpdateCVEDb(dbDir, log)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Info().Str("DB update completed, next update scheduled after", updateInterval.String()).Msg("")
|
||||
|
||||
time.Sleep(updateInterval)
|
||||
}
|
||||
}
|
||||
|
||||
func EnableExtensions(config *config.Config, log log.Logger, rootDir string) {
|
||||
func EnableSearchExtension(config *config.Config, log log.Logger, rootDir string) {
|
||||
if config.Extensions.Search != nil && *config.Extensions.Search.Enable && config.Extensions.Search.CVE != nil {
|
||||
defaultUpdateInterval, _ := time.ParseDuration("2h")
|
||||
|
||||
@@ -59,51 +37,41 @@ func EnableExtensions(config *config.Config, log log.Logger, rootDir string) {
|
||||
} else {
|
||||
log.Info().Msg("CVE config not provided, skipping CVE update")
|
||||
}
|
||||
}
|
||||
|
||||
if config.Extensions.Metrics != nil &&
|
||||
*config.Extensions.Metrics.Enable &&
|
||||
config.Extensions.Metrics.Prometheus != nil {
|
||||
if config.Extensions.Metrics.Prometheus.Path == "" {
|
||||
config.Extensions.Metrics.Prometheus.Path = constants.DefaultMetricsExtensionRoute
|
||||
func downloadTrivyDB(dbDir string, log log.Logger, updateInterval time.Duration) error {
|
||||
for {
|
||||
log.Info().Msg("updating the CVE database")
|
||||
|
||||
log.Warn().Msg(fmt.Sprintf("Prometheus instrumentation Path not set, changing to %s.",
|
||||
constants.DefaultMetricsExtensionRoute))
|
||||
err := cveinfo.UpdateCVEDb(dbDir, log)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
log.Info().Msg("Metrics config not provided, skipping Metrics config update")
|
||||
|
||||
log.Info().Str("DB update completed, next update scheduled after", updateInterval.String()).Msg("")
|
||||
|
||||
time.Sleep(updateInterval)
|
||||
}
|
||||
}
|
||||
|
||||
// EnableSyncExtension enables sync extension.
|
||||
func EnableSyncExtension(ctx context.Context, config *config.Config, wg *goSync.WaitGroup,
|
||||
storeController storage.StoreController, log log.Logger,
|
||||
func SetupSearchRoutes(config *config.Config, router *mux.Router, storeController storage.StoreController,
|
||||
l log.Logger,
|
||||
) {
|
||||
if config.Extensions.Sync != nil && *config.Extensions.Sync.Enable {
|
||||
if err := sync.Run(ctx, *config.Extensions.Sync, storeController, wg, log); err != nil {
|
||||
log.Error().Err(err).Msg("Error encountered while setting up syncing")
|
||||
}
|
||||
} else {
|
||||
log.Info().Msg("Sync registries config not provided or disabled, skipping sync")
|
||||
}
|
||||
}
|
||||
// fork a new zerolog child to avoid data race
|
||||
log := log.Logger{Logger: l.With().Caller().Timestamp().Logger()}
|
||||
log.Info().Msg("setting up search routes")
|
||||
|
||||
// EnableScrubExtension enables scrub extension.
|
||||
func EnableScrubExtension(config *config.Config, log log.Logger, run bool, imgStore storage.ImageStore, repo string) {
|
||||
if !run {
|
||||
if config.Extensions.Scrub != nil &&
|
||||
config.Extensions.Scrub.Interval != 0 {
|
||||
minScrubInterval, _ := time.ParseDuration("2h")
|
||||
if config.Extensions.Search != nil && *config.Extensions.Search.Enable {
|
||||
var resConfig search.Config
|
||||
|
||||
if config.Extensions.Scrub.Interval < minScrubInterval {
|
||||
config.Extensions.Scrub.Interval = minScrubInterval
|
||||
|
||||
log.Warn().Msg("Scrub interval set to too-short interval < 2h, changing scrub duration to 2 hours and continuing.") //nolint:lll // gofumpt conflicts with lll
|
||||
}
|
||||
if config.Extensions.Search.CVE != nil {
|
||||
resConfig = search.GetResolverConfig(log, storeController, true)
|
||||
} else {
|
||||
log.Info().Msg("Scrub config not provided, skipping scrub")
|
||||
resConfig = search.GetResolverConfig(log, storeController, false)
|
||||
}
|
||||
} else {
|
||||
scrub.RunScrubRepo(imgStore, repo, log)
|
||||
|
||||
router.PathPrefix(constants.ExtSearchPrefix).Methods("OPTIONS", "GET", "POST").
|
||||
Handler(gqlHandler.NewDefaultServer(search.NewExecutableSchema(resConfig)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,40 +103,3 @@ func GetExtensions(config *config.Config) distext.ExtensionList {
|
||||
|
||||
return extensionList
|
||||
}
|
||||
|
||||
// SetupRoutes ...
|
||||
func SetupRoutes(config *config.Config, router *mux.Router, storeController storage.StoreController, l log.Logger,
|
||||
) {
|
||||
// fork a new zerolog child to avoid data race
|
||||
log := log.Logger{Logger: l.With().Caller().Timestamp().Logger()}
|
||||
log.Info().Msg("setting up extensions routes")
|
||||
|
||||
if config.Extensions.Search != nil && *config.Extensions.Search.Enable {
|
||||
var resConfig search.Config
|
||||
|
||||
if config.Extensions.Search.CVE != nil {
|
||||
resConfig = search.GetResolverConfig(log, storeController, true)
|
||||
} else {
|
||||
resConfig = search.GetResolverConfig(log, storeController, false)
|
||||
}
|
||||
|
||||
router.PathPrefix(constants.ExtSearchPrefix).Methods("OPTIONS", "GET", "POST").
|
||||
Handler(gqlHandler.NewDefaultServer(search.NewExecutableSchema(resConfig)))
|
||||
}
|
||||
|
||||
if config.Extensions.Metrics != nil && *config.Extensions.Metrics.Enable {
|
||||
router.PathPrefix(config.Extensions.Metrics.Prometheus.Path).
|
||||
Handler(promhttp.Handler())
|
||||
}
|
||||
}
|
||||
|
||||
// SyncOneImage syncs one image.
|
||||
func SyncOneImage(config *config.Config, storeController storage.StoreController,
|
||||
repoName, reference string, isArtifact bool, log log.Logger,
|
||||
) error {
|
||||
log.Info().Msgf("syncing image %s:%s", repoName, reference)
|
||||
|
||||
err := sync.OneImage(*config.Extensions.Sync, storeController, repoName, reference, isArtifact, log)
|
||||
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
//go:build !sync
|
||||
// +build !sync
|
||||
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"context"
|
||||
goSync "sync"
|
||||
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
)
|
||||
|
||||
// EnableSyncExtension ...
|
||||
func EnableSyncExtension(ctx context.Context,
|
||||
config *config.Config, wg *goSync.WaitGroup,
|
||||
storeController storage.StoreController, log log.Logger,
|
||||
) {
|
||||
log.Warn().Msg("skipping enabling sync extension because given zot binary doesn't include this feature," +
|
||||
"please build a binary that does so")
|
||||
}
|
||||
|
||||
// SyncOneImage ...
|
||||
func SyncOneImage(config *config.Config, storeController storage.StoreController,
|
||||
repoName, reference string, isArtifact bool, log log.Logger,
|
||||
) error {
|
||||
log.Warn().Msg("skipping syncing on demand because given zot binary doesn't include this feature," +
|
||||
"please build a binary that does so")
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
//go:build sync
|
||||
// +build sync
|
||||
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"context"
|
||||
goSync "sync"
|
||||
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
"zotregistry.io/zot/pkg/extensions/sync"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
)
|
||||
|
||||
func EnableSyncExtension(ctx context.Context, config *config.Config, wg *goSync.WaitGroup,
|
||||
storeController storage.StoreController, log log.Logger,
|
||||
) {
|
||||
if config.Extensions.Sync != nil && *config.Extensions.Sync.Enable {
|
||||
if err := sync.Run(ctx, *config.Extensions.Sync, storeController, wg, log); err != nil {
|
||||
log.Error().Err(err).Msg("Error encountered while setting up syncing")
|
||||
}
|
||||
} else {
|
||||
log.Info().Msg("Sync registries config not provided or disabled, skipping sync")
|
||||
}
|
||||
}
|
||||
|
||||
func SyncOneImage(config *config.Config, storeController storage.StoreController,
|
||||
repoName, reference string, isArtifact bool, log log.Logger,
|
||||
) error {
|
||||
log.Info().Msgf("syncing image %s:%s", repoName, reference)
|
||||
|
||||
err := sync.OneImage(*config.Extensions.Sync, storeController, repoName, reference, isArtifact, log)
|
||||
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
//go:build sync || metrics
|
||||
// +build sync metrics
|
||||
|
||||
package extensions_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
"zotregistry.io/zot/pkg/api"
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
extconf "zotregistry.io/zot/pkg/extensions/config"
|
||||
"zotregistry.io/zot/pkg/extensions/sync"
|
||||
"zotregistry.io/zot/pkg/test"
|
||||
)
|
||||
|
||||
func TestEnableExtension(t *testing.T) {
|
||||
Convey("Verify log if sync disabled in config", t, func() {
|
||||
globalDir := t.TempDir()
|
||||
port := test.GetFreePort()
|
||||
baseURL := test.GetBaseURL(port)
|
||||
conf := config.New()
|
||||
falseValue := false
|
||||
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &falseValue,
|
||||
Registries: []sync.RegistryConfig{},
|
||||
}
|
||||
|
||||
// conf.Extensions.Sync.Enable = &falseValue
|
||||
conf.Extensions = &extconf.ExtensionConfig{}
|
||||
conf.Extensions.Sync = syncConfig
|
||||
conf.HTTP.Port = port
|
||||
|
||||
logFile, err := ioutil.TempFile(globalDir, "zot-log*.txt")
|
||||
So(err, ShouldBeNil)
|
||||
conf.Log.Level = "info"
|
||||
conf.Log.Output = logFile.Name()
|
||||
defer os.Remove(logFile.Name()) // cleanup
|
||||
|
||||
ctlr := api.NewController(conf)
|
||||
|
||||
defer func() {
|
||||
ctx := context.Background()
|
||||
_ = ctlr.Server.Shutdown(ctx)
|
||||
}()
|
||||
|
||||
ctlr.Config.Storage.RootDirectory = globalDir
|
||||
|
||||
go func() {
|
||||
if err := ctlr.Run(context.Background()); err != nil {
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
test.WaitTillServerReady(baseURL)
|
||||
|
||||
data, err := os.ReadFile(logFile.Name())
|
||||
So(err, ShouldBeNil)
|
||||
So(string(data), ShouldContainSubstring,
|
||||
"Sync registries config not provided or disabled, skipping sync")
|
||||
})
|
||||
}
|
||||
|
||||
func TestMetricsExtension(t *testing.T) {
|
||||
Convey("Verify Metrics enabled for storage subpaths", t, func() {
|
||||
globalDir := t.TempDir()
|
||||
conf := config.New()
|
||||
port := test.GetFreePort()
|
||||
conf.HTTP.Port = port
|
||||
baseURL := test.GetBaseURL(port)
|
||||
|
||||
logFile, err := ioutil.TempFile(globalDir, "zot-log*.txt")
|
||||
So(err, ShouldBeNil)
|
||||
defaultValue := true
|
||||
|
||||
conf.Extensions = &extconf.ExtensionConfig{}
|
||||
conf.Extensions.Metrics = &extconf.MetricsConfig{
|
||||
Enable: &defaultValue,
|
||||
Prometheus: &extconf.PrometheusConfig{},
|
||||
}
|
||||
conf.Log.Level = "info"
|
||||
conf.Log.Output = logFile.Name()
|
||||
defer os.Remove(logFile.Name()) // cleanup
|
||||
|
||||
ctlr := api.NewController(conf)
|
||||
|
||||
subPaths := make(map[string]config.StorageConfig)
|
||||
subPaths["/a"] = config.StorageConfig{}
|
||||
|
||||
ctlr.Config.Storage.RootDirectory = globalDir
|
||||
ctlr.Config.Storage.SubPaths = subPaths
|
||||
|
||||
go func() {
|
||||
if err := ctlr.Run(context.Background()); err != nil {
|
||||
return
|
||||
}
|
||||
}()
|
||||
test.WaitTillServerReady(baseURL)
|
||||
|
||||
data, _ := os.ReadFile(logFile.Name())
|
||||
|
||||
So(string(data), ShouldContainSubstring,
|
||||
"Prometheus instrumentation Path not set, changing to '/metrics'.")
|
||||
})
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
//go:build minimal
|
||||
// +build minimal
|
||||
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"context"
|
||||
goSync "sync"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
distext "github.com/opencontainers/distribution-spec/specs-go/v1/extensions"
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
)
|
||||
|
||||
// nolint: deadcode,unused
|
||||
func downloadTrivyDB(dbDir string, log log.Logger, updateInterval time.Duration) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnableExtensions ...
|
||||
func EnableExtensions(config *config.Config, log log.Logger, rootDir string) {
|
||||
log.Warn().Msg("skipping enabling extensions because given zot binary doesn't support " +
|
||||
"any extensions, please build zot full binary for this feature")
|
||||
}
|
||||
|
||||
// GetExtensions...
|
||||
func GetExtensions(config *config.Config) distext.ExtensionList {
|
||||
return distext.ExtensionList{}
|
||||
}
|
||||
|
||||
// EnableSyncExtension ...
|
||||
func EnableSyncExtension(ctx context.Context, config *config.Config, wg *goSync.WaitGroup,
|
||||
storeController storage.StoreController, log log.Logger,
|
||||
) {
|
||||
log.Warn().Msg("skipping enabling sync extension because given zot binary doesn't support any extensions," +
|
||||
"please build zot full binary for this feature")
|
||||
}
|
||||
|
||||
// EnableScrubExtension ...
|
||||
func EnableScrubExtension(config *config.Config, log log.Logger, run bool, imgStore storage.ImageStore, repo string) {
|
||||
log.Warn().Msg("skipping enabling scrub extension because given zot binary doesn't support any extensions," +
|
||||
"please build zot full binary for this feature")
|
||||
}
|
||||
|
||||
// SetupRoutes ...
|
||||
func SetupRoutes(conf *config.Config, router *mux.Router, storeController storage.StoreController, log log.Logger,
|
||||
) {
|
||||
log.Warn().Msg("skipping setting up extensions routes because given zot binary doesn't support " +
|
||||
"any extensions, please build zot full binary for this feature")
|
||||
}
|
||||
|
||||
// SyncOneImage ...
|
||||
func SyncOneImage(config *config.Config, storeController storage.StoreController,
|
||||
repoName, reference string, isArtifact bool, log log.Logger,
|
||||
) error {
|
||||
log.Warn().Msg("skipping syncing on demand because given zot binary doesn't support any extensions," +
|
||||
"please build zot full binary for this feature")
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build metrics
|
||||
// +build metrics
|
||||
|
||||
package monitoring
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build minimal
|
||||
// +build minimal
|
||||
//go:build !metrics
|
||||
// +build !metrics
|
||||
|
||||
// nolint: varnamelen,forcetypeassert
|
||||
package monitoring
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build minimal
|
||||
// +build minimal
|
||||
//go:build !metrics
|
||||
// +build !metrics
|
||||
|
||||
package monitoring
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build metrics
|
||||
// +build metrics
|
||||
|
||||
package monitoring_test
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build scrub
|
||||
// +build scrub
|
||||
|
||||
package scrub
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build scrub
|
||||
// +build scrub
|
||||
|
||||
package scrub_test
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build search
|
||||
// +build search
|
||||
|
||||
package common_test
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build search
|
||||
// +build search
|
||||
|
||||
// nolint:lll,gosimple
|
||||
package cveinfo_test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build search
|
||||
// +build search
|
||||
|
||||
// nolint: gochecknoinits
|
||||
package digestinfo_test
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
//go:build !sync
|
||||
// +build !sync
|
||||
|
||||
package sync_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
"gopkg.in/resty.v1"
|
||||
"zotregistry.io/zot/pkg/api"
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
extconf "zotregistry.io/zot/pkg/extensions/config"
|
||||
"zotregistry.io/zot/pkg/extensions/sync"
|
||||
"zotregistry.io/zot/pkg/test"
|
||||
)
|
||||
|
||||
func TestSyncExtension(t *testing.T) {
|
||||
Convey("Make a new controller", t, func() {
|
||||
conf := config.New()
|
||||
port := test.GetFreePort()
|
||||
|
||||
baseURL := test.GetBaseURL(port)
|
||||
globalDir := t.TempDir()
|
||||
defaultValue := true
|
||||
|
||||
logFile, err := ioutil.TempFile(globalDir, "zot-log*.txt")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(logFile.Name())
|
||||
|
||||
conf.HTTP.Port = port
|
||||
conf.Storage.RootDirectory = globalDir
|
||||
conf.Storage.Commit = true
|
||||
conf.Extensions = &extconf.ExtensionConfig{}
|
||||
conf.Extensions.Sync = &sync.Config{
|
||||
Enable: &defaultValue,
|
||||
}
|
||||
conf.Log.Level = "warn"
|
||||
conf.Log.Output = logFile.Name()
|
||||
|
||||
ctlr := api.NewController(conf)
|
||||
|
||||
go func() {
|
||||
if err := ctlr.Run(context.Background()); err != nil {
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
defer func() {
|
||||
_ = ctlr.Server.Shutdown(context.Background())
|
||||
}()
|
||||
test.WaitTillServerReady(baseURL)
|
||||
|
||||
Convey("verify sync is skipped when binary doesn't include it", func() {
|
||||
resp, err := resty.R().
|
||||
Head(baseURL + "/v2/" + "invalid" + "/manifests/invalid:0.0.2")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp, ShouldNotBeNil)
|
||||
|
||||
data, err := os.ReadFile(logFile.Name())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(string(data), ShouldContainSubstring,
|
||||
"skipping syncing on demand because given zot binary doesn't include "+
|
||||
"this feature,please build a binary that does so")
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build sync
|
||||
// +build sync
|
||||
|
||||
package sync_test
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build sync && scrub && metrics && search && ui_base
|
||||
// +build sync,scrub,metrics,search,ui_base
|
||||
|
||||
package log_test
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build extended
|
||||
// +build extended
|
||||
//go:build sync && scrub && metrics && search && ui_base
|
||||
// +build sync,scrub,metrics,search,ui_base
|
||||
|
||||
package test_test
|
||||
|
||||
|
||||
Reference in New Issue
Block a user