2014-12-02 02:36:20 +01:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
_ "net/http/pprof"
|
|
|
|
"os"
|
|
|
|
|
|
|
|
log "github.com/Sirupsen/logrus"
|
2014-12-13 02:49:06 +01:00
|
|
|
"github.com/bugsnag/bugsnag-go"
|
2014-12-18 21:30:19 +01:00
|
|
|
"github.com/gorilla/handlers"
|
2014-12-13 02:49:06 +01:00
|
|
|
"github.com/yvasiyarov/gorelic"
|
|
|
|
|
2014-12-24 01:01:38 +01:00
|
|
|
_ "github.com/docker/distribution/auth/silly"
|
|
|
|
_ "github.com/docker/distribution/auth/token"
|
|
|
|
"github.com/docker/distribution/configuration"
|
2015-01-06 19:37:27 +01:00
|
|
|
"github.com/docker/distribution/registry"
|
2014-12-24 01:01:38 +01:00
|
|
|
_ "github.com/docker/distribution/storagedriver/filesystem"
|
|
|
|
_ "github.com/docker/distribution/storagedriver/inmemory"
|
2015-01-12 22:02:22 +01:00
|
|
|
_ "github.com/docker/distribution/storagedriver/s3"
|
2015-01-30 00:32:49 +01:00
|
|
|
"github.com/docker/distribution/version"
|
2014-12-02 02:36:20 +01:00
|
|
|
)
|
|
|
|
|
2015-01-30 00:32:49 +01:00
|
|
|
var showVersion bool
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
flag.BoolVar(&showVersion, "version", false, "show the version and exit")
|
|
|
|
}
|
|
|
|
|
2014-12-02 02:36:20 +01:00
|
|
|
func main() {
|
|
|
|
flag.Usage = usage
|
|
|
|
flag.Parse()
|
|
|
|
|
2015-01-30 00:32:49 +01:00
|
|
|
if showVersion {
|
2015-01-30 00:53:26 +01:00
|
|
|
version.PrintVersion()
|
2015-01-30 00:32:49 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2014-12-02 02:36:20 +01:00
|
|
|
config, err := resolveConfiguration()
|
|
|
|
if err != nil {
|
|
|
|
fatalf("configuration error: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
app := registry.NewApp(*config)
|
2014-12-13 02:49:06 +01:00
|
|
|
handler := configureReporting(app)
|
|
|
|
handler = handlers.CombinedLoggingHandler(os.Stdout, handler)
|
2014-12-02 02:36:20 +01:00
|
|
|
log.SetLevel(logLevel(config.Loglevel))
|
|
|
|
|
2015-02-02 23:38:47 +01:00
|
|
|
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)
|
|
|
|
}
|
2014-12-02 02:36:20 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
2014-12-13 02:49:06 +01:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|