forked from TrueCloudLab/distribution
9f5916b2c4
This changeset provides simple tls support for a registry instance. Simply providing a cert and key file are enough to get a tls registry running. If the certs are trusted by the client, tls can be used throughout the push and pull process. If more complex TLS options are required, it is recommend that a proxy be used. Contributions will be accepted to add more features, if necessary. Signed-off-by: Stephen J Day <stephen.day@docker.com>
144 lines
3.5 KiB
Go
144 lines
3.5 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"net/http"
|
|
_ "net/http/pprof"
|
|
"os"
|
|
|
|
log "github.com/Sirupsen/logrus"
|
|
"github.com/bugsnag/bugsnag-go"
|
|
"github.com/gorilla/handlers"
|
|
"github.com/yvasiyarov/gorelic"
|
|
|
|
_ "github.com/docker/distribution/auth/silly"
|
|
_ "github.com/docker/distribution/auth/token"
|
|
"github.com/docker/distribution/configuration"
|
|
"github.com/docker/distribution/registry"
|
|
_ "github.com/docker/distribution/storagedriver/filesystem"
|
|
_ "github.com/docker/distribution/storagedriver/inmemory"
|
|
_ "github.com/docker/distribution/storagedriver/s3"
|
|
"github.com/docker/distribution/version"
|
|
)
|
|
|
|
var showVersion bool
|
|
|
|
func init() {
|
|
flag.BoolVar(&showVersion, "version", false, "show the version and exit")
|
|
}
|
|
|
|
func main() {
|
|
flag.Usage = usage
|
|
flag.Parse()
|
|
|
|
if showVersion {
|
|
version.PrintVersion()
|
|
return
|
|
}
|
|
|
|
config, err := resolveConfiguration()
|
|
if err != nil {
|
|
fatalf("configuration error: %v", err)
|
|
}
|
|
|
|
app := registry.NewApp(*config)
|
|
handler := configureReporting(app)
|
|
handler = handlers.CombinedLoggingHandler(os.Stdout, handler)
|
|
log.SetLevel(logLevel(config.Loglevel))
|
|
|
|
if config.HTTP.TLS.Certificate == "" {
|
|
log.Infof("listening on %v", config.HTTP.Addr)
|
|
if err := http.ListenAndServe(config.HTTP.Addr, handler); err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
} else {
|
|
log.Infof("listening on %v, tls", config.HTTP.Addr)
|
|
if err := http.ListenAndServeTLS(config.HTTP.Addr, config.HTTP.TLS.Certificate, config.HTTP.TLS.Key, handler); err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func usage() {
|
|
fmt.Fprintln(os.Stderr, "usage:", os.Args[0], "<config>")
|
|
flag.PrintDefaults()
|
|
}
|
|
|
|
func fatalf(format string, args ...interface{}) {
|
|
fmt.Fprintf(os.Stderr, format+"\n", args...)
|
|
usage()
|
|
os.Exit(1)
|
|
}
|
|
|
|
func resolveConfiguration() (*configuration.Configuration, error) {
|
|
var configurationPath string
|
|
|
|
if flag.NArg() > 0 {
|
|
configurationPath = flag.Arg(0)
|
|
} else if os.Getenv("REGISTRY_CONFIGURATION_PATH") != "" {
|
|
configurationPath = os.Getenv("REGISTRY_CONFIGURATION_PATH")
|
|
}
|
|
|
|
if configurationPath == "" {
|
|
return nil, fmt.Errorf("configuration path unspecified")
|
|
}
|
|
|
|
fp, err := os.Open(configurationPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
config, err := configuration.Parse(fp)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error parsing %s: %v", configurationPath, err)
|
|
}
|
|
|
|
return config, nil
|
|
}
|
|
|
|
func logLevel(level configuration.Loglevel) log.Level {
|
|
l, err := log.ParseLevel(string(level))
|
|
if err != nil {
|
|
log.Warnf("error parsing level %q: %v", level, err)
|
|
l = log.InfoLevel
|
|
}
|
|
|
|
return l
|
|
}
|
|
|
|
func configureReporting(app *registry.App) http.Handler {
|
|
var handler http.Handler = app
|
|
|
|
if app.Config.Reporting.Bugsnag.APIKey != "" {
|
|
bugsnagConfig := bugsnag.Configuration{
|
|
APIKey: app.Config.Reporting.Bugsnag.APIKey,
|
|
// TODO(brianbland): provide the registry version here
|
|
// AppVersion: "2.0",
|
|
}
|
|
if app.Config.Reporting.Bugsnag.ReleaseStage != "" {
|
|
bugsnagConfig.ReleaseStage = app.Config.Reporting.Bugsnag.ReleaseStage
|
|
}
|
|
if app.Config.Reporting.Bugsnag.Endpoint != "" {
|
|
bugsnagConfig.Endpoint = app.Config.Reporting.Bugsnag.Endpoint
|
|
}
|
|
bugsnag.Configure(bugsnagConfig)
|
|
|
|
handler = bugsnag.Handler(handler)
|
|
}
|
|
|
|
if app.Config.Reporting.NewRelic.LicenseKey != "" {
|
|
agent := gorelic.NewAgent()
|
|
agent.NewrelicLicense = app.Config.Reporting.NewRelic.LicenseKey
|
|
if app.Config.Reporting.NewRelic.Name != "" {
|
|
agent.NewrelicName = app.Config.Reporting.NewRelic.Name
|
|
}
|
|
agent.CollectHTTPStat = true
|
|
agent.Verbose = true
|
|
agent.Run()
|
|
|
|
handler = agent.WrapHTTPHandler(handler)
|
|
}
|
|
|
|
return handler
|
|
}
|