mirror of
https://github.com/dutchcoders/transfer.sh.git
synced 2024-12-04 18:00:19 +01:00
cb6e5cb0c7
* use dep for vendoring * lets encrypt * moved web to transfer.sh-web repo * single command install * added first tests
127 lines
4.9 KiB
Go
127 lines
4.9 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/golang/gddo/database"
|
|
"github.com/golang/gddo/log"
|
|
|
|
"github.com/spf13/pflag"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
const (
|
|
gaeProjectEnvVar = "GAE_LONG_APP_ID"
|
|
)
|
|
|
|
const (
|
|
ConfigMaxAge = "max_age"
|
|
ConfigGetTimeout = "get_timeout"
|
|
ConfigRobotThreshold = "robot"
|
|
ConfigAssetsDir = "assets"
|
|
ConfigFirstGetTimeout = "first_get_timeout"
|
|
ConfigBindAddress = "http"
|
|
ConfigProject = "project"
|
|
ConfigTrustProxyHeaders = "trust_proxy_headers"
|
|
ConfigSidebar = "sidebar"
|
|
ConfigDefaultGOOS = "default_goos"
|
|
ConfigSourcegraphURL = "sourcegraph_url"
|
|
ConfigGithubInterval = "github_interval"
|
|
ConfigCrawlInterval = "crawl_interval"
|
|
ConfigDialTimeout = "dial_timeout"
|
|
ConfigRequestTimeout = "request_timeout"
|
|
)
|
|
|
|
// Initialize configuration
|
|
func init() {
|
|
ctx := context.Background()
|
|
|
|
// Automatically detect if we are on App Engine.
|
|
if os.Getenv(gaeProjectEnvVar) != "" {
|
|
viper.Set("on_appengine", true)
|
|
} else {
|
|
viper.Set("on_appengine", false)
|
|
}
|
|
|
|
// Setup command line flags
|
|
flags := buildFlags()
|
|
flags.Parse(os.Args)
|
|
if err := viper.BindPFlags(flags); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Also fetch from enviorment
|
|
viper.SetEnvPrefix("gddo")
|
|
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
|
|
viper.AutomaticEnv()
|
|
|
|
// Automatically get project ID from env on Google App Engine
|
|
viper.BindEnv(ConfigProject, gaeProjectEnvVar)
|
|
|
|
// Read from config.
|
|
readViperConfig(ctx)
|
|
|
|
log.Info(ctx, "config values loaded", "values", viper.AllSettings())
|
|
}
|
|
|
|
func buildFlags() *pflag.FlagSet {
|
|
flags := pflag.NewFlagSet("default", pflag.ExitOnError)
|
|
|
|
flags.StringP("config", "c", "", "path to motd config file")
|
|
flags.String("project", "", "Google Cloud Platform project used for Google services")
|
|
// TODO(stephenmw): flags.Bool("enable-admin-pages", false, "When true, enables /admin pages")
|
|
flags.Float64(ConfigRobotThreshold, 100, "Request counter threshold for robots.")
|
|
flags.String(ConfigAssetsDir, filepath.Join(defaultBase("github.com/golang/gddo/gddo-server"), "assets"), "Base directory for templates and static files.")
|
|
flags.Duration(ConfigGetTimeout, 8*time.Second, "Time to wait for package update from the VCS.")
|
|
flags.Duration(ConfigFirstGetTimeout, 5*time.Second, "Time to wait for first fetch of package from the VCS.")
|
|
flags.Duration(ConfigMaxAge, 24*time.Hour, "Update package documents older than this age.")
|
|
flags.String(ConfigBindAddress, ":8080", "Listen for HTTP connections on this address.")
|
|
flags.Bool(ConfigSidebar, false, "Enable package page sidebar.")
|
|
flags.String(ConfigDefaultGOOS, "", "Default GOOS to use when building package documents.")
|
|
flags.Bool(ConfigTrustProxyHeaders, false, "If enabled, identify the remote address of the request using X-Real-Ip in header.")
|
|
flags.String(ConfigSourcegraphURL, "https://sourcegraph.com", "Link to global uses on Sourcegraph based at this URL (no need for trailing slash).")
|
|
flags.Duration(ConfigGithubInterval, 0, "Github updates crawler sleeps for this duration between fetches. Zero disables the crawler.")
|
|
flags.Duration(ConfigCrawlInterval, 0, "Package updater sleeps for this duration between package updates. Zero disables updates.")
|
|
flags.Duration(ConfigDialTimeout, 5*time.Second, "Timeout for dialing an HTTP connection.")
|
|
flags.Duration(ConfigRequestTimeout, 20*time.Second, "Time out for roundtripping an HTTP request.")
|
|
|
|
// TODO(stephenmw): pass these variables at database creation time.
|
|
flags.StringVar(&database.RedisServer, "db-server", database.RedisServer, "URI of Redis server.")
|
|
flags.DurationVar(&database.RedisIdleTimeout, "db-idle-timeout", database.RedisIdleTimeout, "Close Redis connections after remaining idle for this duration.")
|
|
flags.BoolVar(&database.RedisLog, "db-log", database.RedisLog, "Log database commands")
|
|
|
|
return flags
|
|
}
|
|
|
|
// readViperConfig finds and then parses a config file. It will log.Fatal if the
|
|
// config file was specified or could not parse. Otherwise it will only warn
|
|
// that it failed to load the config.
|
|
func readViperConfig(ctx context.Context) {
|
|
viper.AddConfigPath(".")
|
|
viper.AddConfigPath("/etc")
|
|
viper.SetConfigName("gddo")
|
|
if viper.GetString("config") != "" {
|
|
viper.SetConfigFile(viper.GetString("config"))
|
|
}
|
|
|
|
if err := viper.ReadInConfig(); err != nil {
|
|
// If a config exists but could not be parsed, we should bail.
|
|
if _, ok := err.(viper.ConfigParseError); ok {
|
|
log.Fatal(ctx, "failed to parse config", "error", err)
|
|
}
|
|
|
|
// If the user specified a config file location in flags or env and
|
|
// we failed to load it, we should bail. If not, it is just a warning.
|
|
if viper.GetString("config") != "" {
|
|
log.Fatal(ctx, "failed to load configuration file", "error", err)
|
|
} else {
|
|
log.Warn(ctx, "failed to load configuration file", "error", err)
|
|
}
|
|
} else {
|
|
log.Info(ctx, "loaded configuration file successfully", "path", viper.ConfigFileUsed())
|
|
}
|
|
}
|