2019-06-20 18:36:40 -05:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
2021-12-02 12:45:26 -05:00
|
|
|
"context"
|
2019-06-20 18:36:40 -05:00
|
|
|
"crypto/tls"
|
|
|
|
"crypto/x509"
|
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
"net/http"
|
2022-09-02 07:56:02 -05:00
|
|
|
"os"
|
2022-01-21 15:30:09 -05:00
|
|
|
"runtime"
|
2022-09-09 00:41:13 -05:00
|
|
|
"strconv"
|
2022-01-21 15:30:09 -05:00
|
|
|
"strings"
|
|
|
|
"syscall"
|
2021-04-22 14:18:33 -05:00
|
|
|
"time"
|
2019-06-20 18:36:40 -05:00
|
|
|
|
2019-11-25 17:33:58 -05:00
|
|
|
"github.com/gorilla/handlers"
|
2019-07-10 00:23:59 -05:00
|
|
|
"github.com/gorilla/mux"
|
2023-07-07 11:27:10 -05:00
|
|
|
"github.com/zitadel/oidc/pkg/client/rp"
|
2022-10-20 11:39:20 -05:00
|
|
|
|
2021-12-03 22:50:58 -05:00
|
|
|
"zotregistry.io/zot/errors"
|
|
|
|
"zotregistry.io/zot/pkg/api/config"
|
|
|
|
ext "zotregistry.io/zot/pkg/extensions"
|
2023-09-14 04:34:18 -05:00
|
|
|
extconf "zotregistry.io/zot/pkg/extensions/config"
|
2021-12-03 22:50:58 -05:00
|
|
|
"zotregistry.io/zot/pkg/extensions/monitoring"
|
|
|
|
"zotregistry.io/zot/pkg/log"
|
2023-07-18 12:27:26 -05:00
|
|
|
"zotregistry.io/zot/pkg/meta"
|
|
|
|
mTypes "zotregistry.io/zot/pkg/meta/types"
|
2022-09-23 00:27:56 -05:00
|
|
|
"zotregistry.io/zot/pkg/scheduler"
|
2021-12-03 22:50:58 -05:00
|
|
|
"zotregistry.io/zot/pkg/storage"
|
2023-09-22 13:51:20 -05:00
|
|
|
"zotregistry.io/zot/pkg/storage/gc"
|
2019-06-20 18:36:40 -05:00
|
|
|
)
|
|
|
|
|
2021-04-22 14:18:33 -05:00
|
|
|
const (
|
2022-10-05 05:21:14 -05:00
|
|
|
idleTimeout = 120 * time.Second
|
|
|
|
readHeaderTimeout = 5 * time.Second
|
2021-04-22 14:18:33 -05:00
|
|
|
)
|
|
|
|
|
2019-06-20 18:36:40 -05:00
|
|
|
type Controller struct {
|
2022-03-24 07:49:51 -05:00
|
|
|
Config *config.Config
|
|
|
|
Router *mux.Router
|
2023-07-18 12:27:26 -05:00
|
|
|
MetaDB mTypes.MetaDB
|
2022-03-24 07:49:51 -05:00
|
|
|
StoreController storage.StoreController
|
|
|
|
Log log.Logger
|
|
|
|
Audit *log.Logger
|
|
|
|
Server *http.Server
|
|
|
|
Metrics monitoring.MetricServer
|
2023-09-22 13:49:17 -05:00
|
|
|
CveScanner ext.CveScanner
|
2023-05-31 12:26:23 -05:00
|
|
|
SyncOnDemand SyncOnDemand
|
2023-07-07 11:27:10 -05:00
|
|
|
RelyingParties map[string]rp.RelyingParty
|
2023-10-16 22:03:42 -05:00
|
|
|
CookieStore *CookieStore
|
2022-09-09 00:41:13 -05:00
|
|
|
// runtime params
|
|
|
|
chosenPort int // kernel-chosen port
|
2019-06-20 18:36:40 -05:00
|
|
|
}
|
|
|
|
|
2021-06-08 15:11:18 -05:00
|
|
|
func NewController(config *config.Config) *Controller {
|
2021-05-25 03:38:21 -05:00
|
|
|
var controller Controller
|
|
|
|
|
|
|
|
logger := log.NewLogger(config.Log.Level, config.Log.Output)
|
|
|
|
controller.Config = config
|
|
|
|
controller.Log = logger
|
|
|
|
|
|
|
|
if config.Log.Audit != "" {
|
|
|
|
audit := log.NewAuditLogger(config.Log.Level, config.Log.Audit)
|
|
|
|
controller.Audit = audit
|
|
|
|
}
|
|
|
|
|
|
|
|
return &controller
|
2019-06-20 18:36:40 -05:00
|
|
|
}
|
|
|
|
|
2022-01-21 15:30:09 -05:00
|
|
|
func DumpRuntimeParams(log log.Logger) {
|
|
|
|
var rLimit syscall.Rlimit
|
|
|
|
|
2023-10-20 09:27:04 -05:00
|
|
|
evt := log.Info().Int("cpus", runtime.NumCPU()) //nolint: zerologlint
|
2022-01-21 15:30:09 -05:00
|
|
|
|
|
|
|
err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit)
|
|
|
|
if err == nil {
|
2023-07-29 12:41:25 -05:00
|
|
|
evt = evt.Uint64("max. open files", uint64(rLimit.Cur)) //nolint: unconvert // required for *BSD
|
2022-01-21 15:30:09 -05:00
|
|
|
}
|
|
|
|
|
2022-09-02 07:56:02 -05:00
|
|
|
if content, err := os.ReadFile("/proc/sys/net/core/somaxconn"); err == nil {
|
2022-01-21 15:30:09 -05:00
|
|
|
evt = evt.Str("listen backlog", strings.TrimSuffix(string(content), "\n"))
|
|
|
|
}
|
|
|
|
|
2022-09-02 07:56:02 -05:00
|
|
|
if content, err := os.ReadFile("/proc/sys/user/max_inotify_watches"); err == nil {
|
2022-01-21 15:30:09 -05:00
|
|
|
evt = evt.Str("max. inotify watches", strings.TrimSuffix(string(content), "\n"))
|
|
|
|
}
|
|
|
|
|
|
|
|
evt.Msg("runtime params")
|
|
|
|
}
|
|
|
|
|
2022-09-09 00:41:13 -05:00
|
|
|
func (c *Controller) GetPort() int {
|
|
|
|
return c.chosenPort
|
|
|
|
}
|
|
|
|
|
2022-03-24 07:49:51 -05:00
|
|
|
func (c *Controller) Run(reloadCtx context.Context) error {
|
2023-10-16 22:03:42 -05:00
|
|
|
if err := c.initCookieStore(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-02-10 00:04:52 -05:00
|
|
|
c.StartBackgroundTasks(reloadCtx)
|
2022-01-21 15:30:09 -05:00
|
|
|
|
|
|
|
// setup HTTP API router
|
2019-07-10 00:23:59 -05:00
|
|
|
engine := mux.NewRouter()
|
2022-01-21 15:30:09 -05:00
|
|
|
|
|
|
|
// rate-limit HTTP requests if enabled
|
|
|
|
if c.Config.HTTP.Ratelimit != nil {
|
|
|
|
if c.Config.HTTP.Ratelimit.Rate != nil {
|
|
|
|
engine.Use(RateLimiter(c, *c.Config.HTTP.Ratelimit.Rate))
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, mrlim := range c.Config.HTTP.Ratelimit.Methods {
|
|
|
|
engine.Use(MethodRateLimiter(c, mrlim.Method, mrlim.Rate))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
engine.Use(
|
2021-10-15 10:05:00 -05:00
|
|
|
SessionLogger(c),
|
2021-05-05 17:31:56 -05:00
|
|
|
handlers.RecoveryHandler(handlers.RecoveryLogger(c.Log),
|
|
|
|
handlers.PrintRecoveryStack(false)))
|
2019-12-13 00:53:18 -05:00
|
|
|
|
2021-05-25 03:38:21 -05:00
|
|
|
if c.Audit != nil {
|
2021-10-15 10:05:00 -05:00
|
|
|
engine.Use(SessionAuditLogger(c.Audit))
|
2021-05-25 03:38:21 -05:00
|
|
|
}
|
|
|
|
|
2021-04-05 19:40:33 -05:00
|
|
|
c.Router = engine
|
|
|
|
c.Router.UseEncodedPath()
|
|
|
|
|
2022-03-07 07:50:15 -05:00
|
|
|
monitoring.SetServerInfo(c.Metrics, c.Config.Commit, c.Config.BinaryType, c.Config.GoVersion,
|
|
|
|
c.Config.DistSpecVersion)
|
|
|
|
|
2022-10-05 05:21:14 -05:00
|
|
|
//nolint: contextcheck
|
2021-10-05 04:12:22 -05:00
|
|
|
_ = NewRouteHandler(c)
|
|
|
|
|
|
|
|
addr := fmt.Sprintf("%s:%s", c.Config.HTTP.Address, c.Config.HTTP.Port)
|
|
|
|
server := &http.Server{
|
2022-10-05 05:21:14 -05:00
|
|
|
Addr: addr,
|
|
|
|
Handler: c.Router,
|
|
|
|
IdleTimeout: idleTimeout,
|
|
|
|
ReadHeaderTimeout: readHeaderTimeout,
|
2021-10-05 04:12:22 -05:00
|
|
|
}
|
|
|
|
c.Server = server
|
|
|
|
|
|
|
|
// Create the listener
|
2021-12-13 14:23:31 -05:00
|
|
|
listener, err := net.Listen("tcp", addr)
|
2021-10-05 04:12:22 -05:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-09-09 00:41:13 -05:00
|
|
|
if c.Config.HTTP.Port == "0" || c.Config.HTTP.Port == "" {
|
|
|
|
chosenAddr, ok := listener.Addr().(*net.TCPAddr)
|
|
|
|
if !ok {
|
|
|
|
c.Log.Error().Str("port", c.Config.HTTP.Port).Msg("invalid addr type")
|
|
|
|
|
|
|
|
return errors.ErrBadType
|
|
|
|
}
|
|
|
|
|
|
|
|
c.chosenPort = chosenAddr.Port
|
|
|
|
|
|
|
|
c.Log.Info().Int("port", chosenAddr.Port).IPAddr("address", chosenAddr.IP).Msg(
|
|
|
|
"port is unspecified, listening on kernel chosen port",
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
chosenPort, _ := strconv.ParseInt(c.Config.HTTP.Port, 10, 64)
|
|
|
|
|
|
|
|
c.chosenPort = int(chosenPort)
|
|
|
|
}
|
|
|
|
|
2021-10-05 04:12:22 -05:00
|
|
|
if c.Config.HTTP.TLS != nil && c.Config.HTTP.TLS.Key != "" && c.Config.HTTP.TLS.Cert != "" {
|
2022-03-01 15:57:56 -05:00
|
|
|
server.TLSConfig = &tls.Config{
|
|
|
|
CipherSuites: []uint16{
|
|
|
|
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
|
|
|
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
|
|
|
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
|
|
|
|
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
|
|
|
|
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
|
|
|
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
|
|
|
},
|
|
|
|
CurvePreferences: []tls.CurveID{
|
|
|
|
tls.CurveP256,
|
|
|
|
tls.X25519,
|
|
|
|
},
|
|
|
|
PreferServerCipherSuites: true,
|
|
|
|
MinVersion: tls.VersionTLS12,
|
|
|
|
}
|
|
|
|
|
2021-10-05 04:12:22 -05:00
|
|
|
if c.Config.HTTP.TLS.CACert != "" {
|
|
|
|
clientAuth := tls.VerifyClientCertIfGiven
|
2023-09-01 13:13:53 -05:00
|
|
|
if c.Config.IsMTLSAuthEnabled() {
|
2021-10-05 04:12:22 -05:00
|
|
|
clientAuth = tls.RequireAndVerifyClientCert
|
|
|
|
}
|
|
|
|
|
2022-09-02 07:56:02 -05:00
|
|
|
caCert, err := os.ReadFile(c.Config.HTTP.TLS.CACert)
|
2021-10-05 04:12:22 -05:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
caCertPool := x509.NewCertPool()
|
|
|
|
|
|
|
|
if !caCertPool.AppendCertsFromPEM(caCert) {
|
|
|
|
panic(errors.ErrBadCACert)
|
|
|
|
}
|
|
|
|
|
2022-03-01 15:57:56 -05:00
|
|
|
server.TLSConfig.ClientAuth = clientAuth
|
|
|
|
server.TLSConfig.ClientCAs = caCertPool
|
2021-10-05 04:12:22 -05:00
|
|
|
}
|
|
|
|
|
2021-12-13 14:23:31 -05:00
|
|
|
return server.ServeTLS(listener, c.Config.HTTP.TLS.Cert, c.Config.HTTP.TLS.Key)
|
2021-10-05 04:12:22 -05:00
|
|
|
}
|
|
|
|
|
2021-12-13 14:23:31 -05:00
|
|
|
return server.Serve(listener)
|
2021-10-05 04:12:22 -05:00
|
|
|
}
|
|
|
|
|
2023-02-10 00:04:52 -05:00
|
|
|
func (c *Controller) Init(reloadCtx context.Context) error {
|
|
|
|
// print the current configuration, but strip secrets
|
|
|
|
c.Log.Info().Interface("params", c.Config.Sanitize()).Msg("configuration settings")
|
|
|
|
|
|
|
|
// print the current runtime environment
|
|
|
|
DumpRuntimeParams(c.Log)
|
|
|
|
|
|
|
|
var enabled bool
|
|
|
|
if c.Config != nil &&
|
|
|
|
c.Config.Extensions != nil &&
|
|
|
|
c.Config.Extensions.Metrics != nil &&
|
|
|
|
*c.Config.Extensions.Metrics.Enable {
|
|
|
|
enabled = true
|
|
|
|
}
|
|
|
|
|
|
|
|
c.Metrics = monitoring.NewMetricsServer(enabled, c.Log)
|
|
|
|
|
2023-05-26 13:08:19 -05:00
|
|
|
if err := c.InitImageStore(); err != nil { //nolint:contextcheck
|
2023-02-10 00:04:52 -05:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-07-18 12:27:26 -05:00
|
|
|
if err := c.InitMetaDB(reloadCtx); err != nil {
|
2023-02-10 00:04:52 -05:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
c.InitCVEInfo()
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Controller) InitCVEInfo() {
|
|
|
|
// Enable CVE extension if extension config is provided
|
|
|
|
if c.Config != nil && c.Config.Extensions != nil {
|
2023-09-22 13:49:17 -05:00
|
|
|
c.CveScanner = ext.GetCveScanner(c.Config, c.StoreController, c.MetaDB, c.Log)
|
2023-02-10 00:04:52 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-26 13:08:19 -05:00
|
|
|
func (c *Controller) InitImageStore() error {
|
2022-06-24 08:08:47 -05:00
|
|
|
linter := ext.GetLinter(c.Config, c.Log)
|
|
|
|
|
2023-05-26 13:08:19 -05:00
|
|
|
storeController, err := storage.New(c.Config, linter, c.Metrics, c.Log)
|
2022-08-10 17:28:52 -05:00
|
|
|
if err != nil {
|
2023-05-26 13:08:19 -05:00
|
|
|
return err
|
2022-08-10 17:28:52 -05:00
|
|
|
}
|
|
|
|
|
2023-05-26 13:08:19 -05:00
|
|
|
c.StoreController = storeController
|
2022-11-02 17:53:08 -05:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-10-16 22:03:42 -05:00
|
|
|
func (c *Controller) initCookieStore() error {
|
|
|
|
// setup sessions cookie store used to preserve logged in user in web sessions
|
|
|
|
if c.Config.IsBasicAuthnEnabled() {
|
|
|
|
cookieStore, err := NewCookieStore(c.StoreController)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
c.CookieStore = cookieStore
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-07-18 12:27:26 -05:00
|
|
|
func (c *Controller) InitMetaDB(reloadCtx context.Context) error {
|
2023-08-02 13:58:34 -05:00
|
|
|
// init metaDB if search is enabled or we need to store user profiles, api keys or signatures
|
|
|
|
if c.Config.IsSearchEnabled() || c.Config.IsBasicAuthnEnabled() || c.Config.IsImageTrustEnabled() {
|
2023-07-18 12:27:26 -05:00
|
|
|
driver, err := meta.New(c.Config.Storage.StorageConfig, c.Log) //nolint:contextcheck
|
2023-01-09 15:37:44 -05:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-09-08 02:03:58 -05:00
|
|
|
err = ext.SetupExtensions(c.Config, driver, c.Log) //nolint:contextcheck
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-01-09 15:37:44 -05:00
|
|
|
err = driver.PatchDB()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-07-18 12:27:26 -05:00
|
|
|
err = meta.ParseStorage(driver, c.StoreController, c.Log)
|
2023-01-09 15:37:44 -05:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-07-18 12:27:26 -05:00
|
|
|
c.MetaDB = driver
|
2023-01-09 15:37:44 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-09-14 04:34:18 -05:00
|
|
|
func (c *Controller) LoadNewConfig(reloadCtx context.Context, newConfig *config.Config) {
|
2022-02-10 09:17:49 -05:00
|
|
|
// reload access control config
|
2023-09-14 04:34:18 -05:00
|
|
|
c.Config.HTTP.AccessControl = newConfig.HTTP.AccessControl
|
2022-02-10 09:17:49 -05:00
|
|
|
|
2023-09-14 04:34:18 -05:00
|
|
|
// reload periodical gc config
|
|
|
|
c.Config.Storage.GCInterval = newConfig.Storage.GCInterval
|
|
|
|
c.Config.Storage.GC = newConfig.Storage.GC
|
|
|
|
c.Config.Storage.GCDelay = newConfig.Storage.GCDelay
|
|
|
|
c.Config.Storage.GCReferrers = newConfig.Storage.GCReferrers
|
2023-05-31 12:26:23 -05:00
|
|
|
|
|
|
|
// reload background tasks
|
2023-09-14 04:34:18 -05:00
|
|
|
if newConfig.Extensions != nil {
|
|
|
|
if c.Config.Extensions == nil {
|
|
|
|
c.Config.Extensions = &extconf.ExtensionConfig{}
|
|
|
|
}
|
|
|
|
|
2023-05-31 12:26:23 -05:00
|
|
|
// reload sync extension
|
2023-09-14 04:34:18 -05:00
|
|
|
c.Config.Extensions.Sync = newConfig.Extensions.Sync
|
|
|
|
|
|
|
|
// reload only if search is enabled and reloaded config has search extension (can't setup routes at this stage)
|
|
|
|
if c.Config.Extensions.Search != nil && *c.Config.Extensions.Search.Enable {
|
|
|
|
if newConfig.Extensions.Search != nil {
|
|
|
|
c.Config.Extensions.Search.CVE = newConfig.Extensions.Search.CVE
|
2023-05-31 12:26:23 -05:00
|
|
|
}
|
|
|
|
}
|
2023-09-14 04:34:18 -05:00
|
|
|
|
2023-05-31 12:26:23 -05:00
|
|
|
// reload scrub extension
|
2023-09-14 04:34:18 -05:00
|
|
|
c.Config.Extensions.Scrub = newConfig.Extensions.Scrub
|
2023-05-31 12:26:23 -05:00
|
|
|
} else {
|
|
|
|
c.Config.Extensions = nil
|
2022-02-10 09:17:49 -05:00
|
|
|
}
|
|
|
|
|
2023-07-06 06:17:49 -05:00
|
|
|
c.InitCVEInfo()
|
|
|
|
|
2023-05-31 12:26:23 -05:00
|
|
|
c.StartBackgroundTasks(reloadCtx)
|
|
|
|
|
|
|
|
c.Log.Info().Interface("reloaded params", c.Config.Sanitize()).
|
|
|
|
Msg("loaded new configuration settings")
|
2022-02-10 09:17:49 -05:00
|
|
|
}
|
|
|
|
|
2021-12-02 12:45:26 -05:00
|
|
|
func (c *Controller) Shutdown() {
|
|
|
|
ctx := context.Background()
|
|
|
|
_ = c.Server.Shutdown(ctx)
|
|
|
|
}
|
2022-03-21 13:40:37 -05:00
|
|
|
|
|
|
|
func (c *Controller) StartBackgroundTasks(reloadCtx context.Context) {
|
2023-07-04 03:03:29 -05:00
|
|
|
taskScheduler := scheduler.NewScheduler(c.Config, c.Log)
|
2022-09-23 00:27:56 -05:00
|
|
|
taskScheduler.RunScheduler(reloadCtx)
|
|
|
|
|
|
|
|
// Enable running garbage-collect periodically for DefaultStore
|
2023-08-07 14:55:19 -05:00
|
|
|
if c.Config.Storage.GC {
|
2023-09-22 13:51:20 -05:00
|
|
|
gc := gc.NewGarbageCollect(c.StoreController.DefaultStore, c.MetaDB, gc.Options{
|
|
|
|
Referrers: c.Config.Storage.GCReferrers,
|
|
|
|
Delay: c.Config.Storage.GCDelay,
|
|
|
|
RetentionDelay: c.Config.Storage.UntaggedImageRetentionDelay,
|
|
|
|
}, c.Log)
|
|
|
|
|
|
|
|
gc.CleanImageStorePeriodically(c.Config.Storage.GCInterval, taskScheduler)
|
2022-09-23 00:27:56 -05:00
|
|
|
}
|
|
|
|
|
2023-04-07 11:49:24 -05:00
|
|
|
// Enable running dedupe blobs both ways (dedupe or restore deduped blobs)
|
|
|
|
c.StoreController.DefaultStore.RunDedupeBlobs(time.Duration(0), taskScheduler)
|
|
|
|
|
2022-03-21 13:40:37 -05:00
|
|
|
// Enable extensions if extension config is provided for DefaultStore
|
|
|
|
if c.Config != nil && c.Config.Extensions != nil {
|
2022-04-27 01:00:20 -05:00
|
|
|
ext.EnableMetricsExtension(c.Config, c.Log, c.Config.Storage.RootDirectory)
|
2023-09-22 13:49:17 -05:00
|
|
|
ext.EnableSearchExtension(c.Config, c.StoreController, c.MetaDB, taskScheduler, c.CveScanner, c.Log)
|
2022-03-21 13:40:37 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if c.Config.Storage.SubPaths != nil {
|
2022-09-23 00:27:56 -05:00
|
|
|
for route, storageConfig := range c.Config.Storage.SubPaths {
|
|
|
|
// Enable running garbage-collect periodically for subImageStore
|
2023-08-07 14:55:19 -05:00
|
|
|
if storageConfig.GC {
|
2023-09-22 13:51:20 -05:00
|
|
|
gc := gc.NewGarbageCollect(c.StoreController.SubStore[route], c.MetaDB,
|
|
|
|
gc.Options{
|
|
|
|
Referrers: storageConfig.GCReferrers,
|
|
|
|
Delay: storageConfig.GCDelay,
|
|
|
|
RetentionDelay: storageConfig.UntaggedImageRetentionDelay,
|
|
|
|
}, c.Log)
|
|
|
|
|
|
|
|
gc.CleanImageStorePeriodically(storageConfig.GCInterval, taskScheduler)
|
2022-09-23 00:27:56 -05:00
|
|
|
}
|
|
|
|
|
2022-03-21 13:40:37 -05:00
|
|
|
// Enable extensions if extension config is provided for subImageStore
|
|
|
|
if c.Config != nil && c.Config.Extensions != nil {
|
2022-04-27 01:00:20 -05:00
|
|
|
ext.EnableMetricsExtension(c.Config, c.Log, storageConfig.RootDirectory)
|
2022-03-21 13:40:37 -05:00
|
|
|
}
|
2023-04-07 11:49:24 -05:00
|
|
|
|
|
|
|
// Enable running dedupe blobs both ways (dedupe or restore deduped blobs) for subpaths
|
|
|
|
substore := c.StoreController.SubStore[route]
|
|
|
|
if substore != nil {
|
|
|
|
substore.RunDedupeBlobs(time.Duration(0), taskScheduler)
|
|
|
|
}
|
2022-03-21 13:40:37 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.Config.Extensions != nil {
|
2023-05-31 12:26:23 -05:00
|
|
|
ext.EnableScrubExtension(c.Config, c.Log, c.StoreController, taskScheduler)
|
2023-09-05 11:48:56 -05:00
|
|
|
//nolint: contextcheck
|
2023-07-18 12:27:26 -05:00
|
|
|
syncOnDemand, err := ext.EnableSyncExtension(c.Config, c.MetaDB, c.StoreController, taskScheduler, c.Log)
|
2023-05-31 12:26:23 -05:00
|
|
|
if err != nil {
|
|
|
|
c.Log.Error().Err(err).Msg("unable to start sync extension")
|
2022-03-21 13:40:37 -05:00
|
|
|
}
|
|
|
|
|
2023-05-31 12:26:23 -05:00
|
|
|
c.SyncOnDemand = syncOnDemand
|
2022-05-09 17:30:11 -05:00
|
|
|
}
|
2023-07-06 06:57:59 -05:00
|
|
|
|
2023-10-16 22:03:42 -05:00
|
|
|
if c.CookieStore != nil {
|
|
|
|
c.CookieStore.RunSessionCleaner(taskScheduler)
|
|
|
|
}
|
|
|
|
|
2023-08-02 13:58:34 -05:00
|
|
|
// we can later move enabling the other scheduled tasks inside the call below
|
|
|
|
ext.EnableScheduledTasks(c.Config, taskScheduler, c.MetaDB, c.Log) //nolint: contextcheck
|
2022-03-21 13:40:37 -05:00
|
|
|
}
|
2023-05-31 12:26:23 -05:00
|
|
|
|
|
|
|
type SyncOnDemand interface {
|
2023-09-05 11:48:56 -05:00
|
|
|
SyncImage(ctx context.Context, repo, reference string) error
|
|
|
|
SyncReference(ctx context.Context, repo string, subjectDigestStr string, referenceType string) error
|
2023-05-31 12:26:23 -05:00
|
|
|
}
|