mirror of
https://github.com/project-zot/zot.git
synced 2024-12-16 21:56:37 -05:00
dd1fc1e866
Since we want to conform to dist-spec, sometimes the gc and dedupe optimizations conflict with the conformance tests that are being run. So allow them to be turned off via configuration params.
97 lines
2.5 KiB
Go
97 lines
2.5 KiB
Go
package api
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net"
|
|
"net/http"
|
|
"os"
|
|
|
|
"github.com/anuvu/zot/errors"
|
|
"github.com/anuvu/zot/pkg/log"
|
|
"github.com/anuvu/zot/pkg/storage"
|
|
"github.com/gorilla/handlers"
|
|
"github.com/gorilla/mux"
|
|
)
|
|
|
|
type Controller struct {
|
|
Config *Config
|
|
Router *mux.Router
|
|
ImageStore *storage.ImageStore
|
|
Log log.Logger
|
|
Server *http.Server
|
|
}
|
|
|
|
func NewController(config *Config) *Controller {
|
|
return &Controller{Config: config, Log: log.NewLogger(config.Log.Level, config.Log.Output)}
|
|
}
|
|
|
|
func (c *Controller) Run() error {
|
|
// validate configuration
|
|
if err := c.Config.Validate(c.Log); err != nil {
|
|
c.Log.Error().Err(err).Msg("configuration validation failed")
|
|
return err
|
|
}
|
|
|
|
// print the current configuration, but strip secrets
|
|
c.Log.Info().Interface("params", c.Config.Sanitize()).Msg("configuration settings")
|
|
|
|
engine := mux.NewRouter()
|
|
engine.Use(log.SessionLogger(c.Log), handlers.RecoveryHandler(handlers.RecoveryLogger(c.Log),
|
|
handlers.PrintRecoveryStack(false)))
|
|
|
|
c.ImageStore = storage.NewImageStore(c.Config.Storage.RootDirectory, c.Config.Storage.GC,
|
|
c.Config.Storage.Dedupe, c.Log)
|
|
if c.ImageStore == nil {
|
|
// we can't proceed without at least a image store
|
|
os.Exit(1)
|
|
}
|
|
|
|
c.Router = engine
|
|
c.Router.UseEncodedPath()
|
|
_ = NewRouteHandler(c)
|
|
|
|
addr := fmt.Sprintf("%s:%s", c.Config.HTTP.Address, c.Config.HTTP.Port)
|
|
server := &http.Server{Addr: addr, Handler: c.Router}
|
|
c.Server = server
|
|
|
|
// Create the listener
|
|
l, err := net.Listen("tcp", addr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if c.Config.HTTP.TLS != nil && c.Config.HTTP.TLS.Key != "" && c.Config.HTTP.TLS.Cert != "" {
|
|
if c.Config.HTTP.TLS.CACert != "" {
|
|
clientAuth := tls.VerifyClientCertIfGiven
|
|
if (c.Config.HTTP.Auth == nil || c.Config.HTTP.Auth.HTPasswd.Path == "") && !c.Config.HTTP.AllowReadAccess {
|
|
clientAuth = tls.RequireAndVerifyClientCert
|
|
}
|
|
|
|
caCert, err := ioutil.ReadFile(c.Config.HTTP.TLS.CACert)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
caCertPool := x509.NewCertPool()
|
|
|
|
if !caCertPool.AppendCertsFromPEM(caCert) {
|
|
panic(errors.ErrBadCACert)
|
|
}
|
|
|
|
server.TLSConfig = &tls.Config{
|
|
ClientAuth: clientAuth,
|
|
ClientCAs: caCertPool,
|
|
PreferServerCipherSuites: true,
|
|
MinVersion: tls.VersionTLS12,
|
|
}
|
|
server.TLSConfig.BuildNameToCertificate()
|
|
}
|
|
|
|
return server.ServeTLS(l, c.Config.HTTP.TLS.Cert, c.Config.HTTP.TLS.Key)
|
|
}
|
|
|
|
return server.Serve(l)
|
|
}
|