pkg/cfgstruct: tie defaults to releases (#1787)

* tie defaults to releases

this change makes it so that by default, the flag defaults are
chosen based on whether the build was built as a release build or
an ordinary build. release builds by default get release defaults,
whereas ordinary builds by default get dev defaults.

any binary can have its defaults changed by specifying

 --defaults=dev

or

 --defaults=release

Change-Id: I6d216aa345d211c69ad913159d492fac77b12c64

* make release defaults more clear

this change extends cfgstruct structs to support either
a 'default' tag, or a pair of 'devDefault' and 'releaseDefault'
tags, but not both, for added clarity

Change-Id: Ia098be1fa84b932fdfe90a4a4d027ffb95e249c6

* clarify cfgstruct.DefaultsFlag

Change-Id: I55f2ff9080ebbc0ce83abf956e085242a92f883e
This commit is contained in:
JT Olio 2019-04-19 12:17:30 -06:00 committed by GitHub
parent 9331557b78
commit 2744a26b60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 188 additions and 135 deletions

View File

@ -42,7 +42,6 @@ var (
confDir string
identityDir string
isDev bool
)
const (
@ -54,11 +53,11 @@ func init() {
defaultIdentityDir := fpath.ApplicationDir("storj", "identity", "bootstrap")
cfgstruct.SetupFlag(zap.L(), rootCmd, &confDir, "config-dir", defaultConfDir, "main directory for bootstrap configuration")
cfgstruct.SetupFlag(zap.L(), rootCmd, &identityDir, "identity-dir", defaultIdentityDir, "main directory for bootstrap identity credentials")
cfgstruct.DevFlag(rootCmd, &isDev, false, "use development and test configuration settings")
defaults := cfgstruct.DefaultsFlag(rootCmd)
rootCmd.AddCommand(runCmd)
rootCmd.AddCommand(setupCmd)
cfgstruct.Bind(runCmd.Flags(), &runCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.BindSetup(setupCmd.Flags(), &setupCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(runCmd.Flags(), &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.BindSetup(setupCmd.Flags(), &setupCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
}
func cmdRun(cmd *cobra.Command, args []string) (err error) {

View File

@ -49,7 +49,6 @@ var (
confDir string
identityDir string
isDev bool
)
func cmdRun(cmd *cobra.Command, args []string) error {
@ -69,7 +68,7 @@ func main() {
cfgstruct.SetupFlag(zap.L(), rootCmd, &confDir, "config-dir", defaultConfDir, "main directory for certificates configuration")
//cfgstruct.SetupFlag(zap.L(), rootCmd, &identityDir, "identity-dir", fpath.ApplicationDir("storj", "identity", "bootstrap"), "main directory for bootstrap identity credentials")
rootCmd.PersistentFlags().StringVar(&identityDir, "identity-dir", defaultIdentityDir, "main directory for storagenode identity credentials")
cfgstruct.DevFlag(rootCmd, &isDev, false, "use development and test configuration settings")
defaults := cfgstruct.DefaultsFlag(rootCmd)
rootCmd.AddCommand(authCmd)
rootCmd.AddCommand(runCmd)
@ -83,15 +82,15 @@ func main() {
authCmd.AddCommand(authInfoCmd)
authCmd.AddCommand(authExportCmd)
cfgstruct.Bind(authCreateCmd.Flags(), &config, isDev, cfgstruct.ConfDir(confDir))
cfgstruct.Bind(authInfoCmd.Flags(), &config, isDev, cfgstruct.ConfDir(confDir))
cfgstruct.Bind(authExportCmd.Flags(), &config, isDev, cfgstruct.ConfDir(confDir))
cfgstruct.Bind(runCmd.Flags(), &config, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.BindSetup(setupCmd.Flags(), &config, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(signCmd.Flags(), &signCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(verifyCmd.Flags(), &verifyCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(claimsExportCmd.Flags(), &claimsExportCfg, isDev, cfgstruct.ConfDir(confDir))
cfgstruct.Bind(claimDeleteCmd.Flags(), &claimsDeleteCfg, isDev, cfgstruct.ConfDir(confDir))
cfgstruct.Bind(authCreateCmd.Flags(), &config, defaults, cfgstruct.ConfDir(confDir))
cfgstruct.Bind(authInfoCmd.Flags(), &config, defaults, cfgstruct.ConfDir(confDir))
cfgstruct.Bind(authExportCmd.Flags(), &config, defaults, cfgstruct.ConfDir(confDir))
cfgstruct.Bind(runCmd.Flags(), &config, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.BindSetup(setupCmd.Flags(), &config, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(signCmd.Flags(), &signCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(verifyCmd.Flags(), &verifyCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(claimsExportCmd.Flags(), &claimsExportCfg, defaults, cfgstruct.ConfDir(confDir))
cfgstruct.Bind(claimDeleteCmd.Flags(), &claimsDeleteCfg, defaults, cfgstruct.ConfDir(confDir))
process.Exec(rootCmd)
}

View File

@ -63,7 +63,6 @@ var (
confDir string
identityDir string
isDev bool
)
func init() {
@ -71,12 +70,12 @@ func init() {
defaultIdentityDir := fpath.ApplicationDir("storj", "identity", "gateway")
cfgstruct.SetupFlag(zap.L(), rootCmd, &confDir, "config-dir", defaultConfDir, "main directory for gateway configuration")
cfgstruct.SetupFlag(zap.L(), rootCmd, &identityDir, "identity-dir", defaultIdentityDir, "main directory for gateway identity credentials")
cfgstruct.DevFlag(rootCmd, &isDev, false, "use development and test configuration settings")
defaults := cfgstruct.DefaultsFlag(rootCmd)
rootCmd.AddCommand(runCmd)
rootCmd.AddCommand(setupCmd)
cfgstruct.Bind(runCmd.Flags(), &runCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.BindSetup(setupCmd.Flags(), &setupCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(runCmd.Flags(), &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.BindSetup(setupCmd.Flags(), &setupCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
}
func cmdSetup(cmd *cobra.Command, args []string) (err error) {

View File

@ -46,13 +46,13 @@ var (
Concurrency int `help:"worker concurrency" default:"4"`
OutputDir string `help:"output directory to place keys" default:"."`
}
isDev bool
defaults cfgstruct.BindOpt
)
func init() {
cfgstruct.DevFlag(rootCmd, &isDev, false, "use development and test configuration settings")
defaults = cfgstruct.DefaultsFlag(rootCmd)
rootCmd.AddCommand(keyGenerateCmd)
cfgstruct.Bind(keyGenerateCmd.Flags(), &keyCfg, isDev)
cfgstruct.Bind(keyGenerateCmd.Flags(), &keyCfg, defaults)
}
func cmdKeyGenerate(cmd *cobra.Command, args []string) (err error) {

View File

@ -106,11 +106,11 @@ func init() {
caCmd.AddCommand(revokeCACmd)
caCmd.AddCommand(revokePeerCACmd)
cfgstruct.Bind(newCACmd.Flags(), &newCACfg, isDev, cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(getIDCmd.Flags(), &getIDCfg, isDev, cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(caExtCmd.Flags(), &caExtCfg, isDev, cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(revokeCACmd.Flags(), &revokeCACfg, isDev, cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(revokePeerCACmd.Flags(), &revokePeerCACfg, isDev, cfgstruct.ConfDir(defaultConfigDir), cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(newCACmd.Flags(), &newCACfg, defaults, cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(getIDCmd.Flags(), &getIDCfg, defaults, cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(caExtCmd.Flags(), &caExtCfg, defaults, cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(revokeCACmd.Flags(), &revokeCACfg, defaults, cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(revokePeerCACmd.Flags(), &revokePeerCACfg, defaults, cfgstruct.ConfDir(defaultConfigDir), cfgstruct.IdentityDir(defaultIdentityDir))
}
func cmdNewCA(cmd *cobra.Command, args []string) error {

View File

@ -67,9 +67,9 @@ func init() {
idCmd.AddCommand(leafExtCmd)
idCmd.AddCommand(revokeLeafCmd)
cfgstruct.Bind(newIDCmd.Flags(), &newIDCfg, isDev, cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(leafExtCmd.Flags(), &leafExtCfg, isDev, cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(revokeLeafCmd.Flags(), &revokeLeafCfg, isDev, cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(newIDCmd.Flags(), &newIDCfg, defaults, cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(leafExtCmd.Flags(), &leafExtCfg, defaults, cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(revokeLeafCmd.Flags(), &revokeLeafCfg, defaults, cfgstruct.IdentityDir(defaultIdentityDir))
}
func cmdNewID(cmd *cobra.Command, args []string) (err error) {

View File

@ -67,8 +67,8 @@ func init() {
rootCmd.AddCommand(newServiceCmd)
rootCmd.AddCommand(authorizeCmd)
cfgstruct.Bind(newServiceCmd.Flags(), &config, isDev, cfgstruct.ConfDir(defaultConfigDir), cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(authorizeCmd.Flags(), &config, isDev, cfgstruct.ConfDir(defaultConfigDir), cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(newServiceCmd.Flags(), &config, defaults, cfgstruct.ConfDir(defaultConfigDir), cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(authorizeCmd.Flags(), &config, defaults, cfgstruct.ConfDir(defaultConfigDir), cfgstruct.IdentityDir(defaultIdentityDir))
}
func main() {

View File

@ -33,7 +33,7 @@ var (
func init() {
rootCmd.AddCommand(revocationsCmd)
cfgstruct.Bind(revocationsCmd.Flags(), &revCfg, isDev, cfgstruct.ConfDir(defaultConfigDir), cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(revocationsCmd.Flags(), &revCfg, defaults, cfgstruct.ConfDir(defaultConfigDir), cfgstruct.IdentityDir(defaultIdentityDir))
}
func cmdRevocations(cmd *cobra.Command, args []string) error {

View File

@ -39,15 +39,14 @@ var (
cacheCfg struct {
cacheConfig
}
isDev bool
)
func init() {
cfgstruct.DevFlag(rootCmd, &isDev, false, "use development and test configuration settings")
defaults := cfgstruct.DefaultsFlag(rootCmd)
rootCmd.AddCommand(addCmd)
rootCmd.AddCommand(listCmd)
cfgstruct.Bind(addCmd.Flags(), &cacheCfg, isDev)
cfgstruct.Bind(listCmd.Flags(), &cacheCfg, isDev)
cfgstruct.Bind(addCmd.Flags(), &cacheCfg, defaults)
cfgstruct.Bind(listCmd.Flags(), &cacheCfg, defaults)
}
func cmdList(cmd *cobra.Command, args []string) (err error) {

View File

@ -84,7 +84,6 @@ var (
}
confDir string
identityDir string
isDev bool
)
func init() {
@ -92,18 +91,18 @@ func init() {
defaultIdentityDir := fpath.ApplicationDir("storj", "identity", "satellite")
cfgstruct.SetupFlag(zap.L(), rootCmd, &confDir, "config-dir", defaultConfDir, "main directory for satellite configuration")
cfgstruct.SetupFlag(zap.L(), rootCmd, &identityDir, "identity-dir", defaultIdentityDir, "main directory for satellite identity credentials")
cfgstruct.DevFlag(rootCmd, &isDev, true, "use development and test configuration settings")
defaults := cfgstruct.DefaultsFlag(rootCmd)
rootCmd.AddCommand(runCmd)
rootCmd.AddCommand(setupCmd)
rootCmd.AddCommand(diagCmd)
rootCmd.AddCommand(qdiagCmd)
rootCmd.AddCommand(reportsCmd)
reportsCmd.AddCommand(nodeUsageCmd)
cfgstruct.Bind(runCmd.Flags(), &runCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.BindSetup(setupCmd.Flags(), &setupCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(diagCmd.Flags(), &diagCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(qdiagCmd.Flags(), &qdiagCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(nodeUsageCmd.Flags(), &nodeUsageCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(runCmd.Flags(), &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.BindSetup(setupCmd.Flags(), &setupCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(diagCmd.Flags(), &diagCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(qdiagCmd.Flags(), &qdiagCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(nodeUsageCmd.Flags(), &nodeUsageCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
}
func cmdRun(cmd *cobra.Command, args []string) (err error) {

View File

@ -32,9 +32,8 @@ func main() {
Short: "stat receiving",
RunE: Main,
}
isDev := false
cfgstruct.DevFlag(cmd, &isDev, false, "use development and test configuration settings")
cfgstruct.Bind(cmd.Flags(), &Config, isDev, cfgstruct.ConfDir(defaultConfDir))
defaults := cfgstruct.DefaultsFlag(cmd)
cfgstruct.Bind(cmd.Flags(), &Config, defaults, cfgstruct.ConfDir(defaultConfDir))
cmd.Flags().String("config", filepath.Join(defaultConfDir, "config.yaml"), "path to configuration")
process.Exec(cmd)
}

View File

@ -77,7 +77,6 @@ var (
confDir string
identityDir string
useColor bool
isDev bool
)
const (
@ -91,18 +90,18 @@ func init() {
defaultDiagDir = filepath.Join(defaultConfDir, "storage")
cfgstruct.SetupFlag(zap.L(), rootCmd, &confDir, "config-dir", defaultConfDir, "main directory for storagenode configuration")
cfgstruct.SetupFlag(zap.L(), rootCmd, &identityDir, "identity-dir", defaultIdentityDir, "main directory for storagenode identity credentials")
cfgstruct.DevFlag(rootCmd, &isDev, false, "use development and test configuration settings")
defaults := cfgstruct.DefaultsFlag(rootCmd)
rootCmd.PersistentFlags().BoolVar(&useColor, "color", false, "use color in user interface")
rootCmd.AddCommand(runCmd)
rootCmd.AddCommand(setupCmd)
rootCmd.AddCommand(configCmd)
rootCmd.AddCommand(diagCmd)
rootCmd.AddCommand(dashboardCmd)
cfgstruct.Bind(runCmd.Flags(), &runCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.BindSetup(setupCmd.Flags(), &setupCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.BindSetup(configCmd.Flags(), &setupCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(diagCmd.Flags(), &diagCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(dashboardCmd.Flags(), &dashboardCfg, isDev, cfgstruct.ConfDir(defaultDiagDir))
cfgstruct.Bind(runCmd.Flags(), &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.BindSetup(setupCmd.Flags(), &setupCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.BindSetup(configCmd.Flags(), &setupCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(diagCmd.Flags(), &diagCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(dashboardCmd.Flags(), &dashboardCfg, defaults, cfgstruct.ConfDir(defaultDiagDir))
}
func databaseConfig(config storagenode.Config) storagenodedb.Config {

View File

@ -48,7 +48,7 @@ func addCmd(cmd *cobra.Command, root *cobra.Command) *cobra.Command {
defaultIdentityDir = identityDirParam
}
cfgstruct.Bind(cmd.Flags(), &cfg, isDev, cfgstruct.ConfDir(defaultConfDir), cfgstruct.IdentityDir(defaultIdentityDir))
cfgstruct.Bind(cmd.Flags(), &cfg, defaults, cfgstruct.ConfDir(defaultConfDir), cfgstruct.IdentityDir(defaultIdentityDir))
return cmd
}

View File

@ -31,7 +31,7 @@ var (
setupCfg UplinkFlags
confDir string
identityDir string
isDev bool
defaults cfgstruct.BindOpt
// Error is the default uplink setup errs class
Error = errs.Class("uplink setup error")
@ -42,9 +42,9 @@ func init() {
defaultIdentityDir := fpath.ApplicationDir("storj", "identity", "uplink")
cfgstruct.SetupFlag(zap.L(), RootCmd, &confDir, "config-dir", defaultConfDir, "main directory for uplink configuration")
cfgstruct.SetupFlag(zap.L(), RootCmd, &identityDir, "identity-dir", defaultIdentityDir, "main directory for uplink identity credentials")
cfgstruct.DevFlag(RootCmd, &isDev, false, "use development and test configuration settings")
defaults = cfgstruct.DefaultsFlag(RootCmd)
RootCmd.AddCommand(setupCmd)
cfgstruct.BindSetup(setupCmd.Flags(), &setupCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.BindSetup(setupCmd.Flags(), &setupCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
}
func cmdSetup(cmd *cobra.Command, args []string) (err error) {

View File

@ -38,7 +38,6 @@ var (
setupCfg versioncontrol.Config
confDir string
isDev bool
)
const (
@ -48,11 +47,11 @@ const (
func init() {
defaultConfDir := fpath.ApplicationDir("storj", "versioncontrol")
cfgstruct.SetupFlag(zap.L(), rootCmd, &confDir, "config-dir", defaultConfDir, "main directory for versioncontrol configuration")
cfgstruct.DevFlag(rootCmd, &isDev, false, "use development and test configuration settings")
defaults := cfgstruct.DefaultsFlag(rootCmd)
rootCmd.AddCommand(runCmd)
rootCmd.AddCommand(setupCmd)
cfgstruct.Bind(runCmd.Flags(), &runCfg, isDev, cfgstruct.ConfDir(confDir))
cfgstruct.BindSetup(setupCmd.Flags(), &setupCfg, isDev, cfgstruct.ConfDir(confDir))
cfgstruct.Bind(runCmd.Flags(), &runCfg, defaults, cfgstruct.ConfDir(confDir))
cfgstruct.BindSetup(setupCmd.Flags(), &setupCfg, defaults, cfgstruct.ConfDir(confDir))
}
func cmdRun(cmd *cobra.Command, args []string) (err error) {

View File

@ -22,7 +22,7 @@ var (
)
func init() {
cfgstruct.Bind(pflag.CommandLine, &identityConfig, true, cfgstruct.ConfDir("$HOME/.storj/gw"))
cfgstruct.Bind(pflag.CommandLine, &identityConfig, cfgstruct.UseDevDefaults(), cfgstruct.ConfDir("$HOME/.storj/gw"))
}
func main() {

View File

@ -312,7 +312,7 @@ func (uplink *Uplink) GetConfig(satellite *satellite.Peer) uplink.Config {
func getDefaultConfig() uplink.Config {
config := uplink.Config{}
cfgstruct.Bind(&pflag.FlagSet{}, &config, true)
cfgstruct.Bind(&pflag.FlagSet{}, &config, cfgstruct.UseDevDefaults())
return config
}

View File

@ -17,7 +17,7 @@ import (
// Config contains configurable values for rollup
type Config struct {
Interval time.Duration `help:"how frequently rollup should run" devDefault:"120s" default:"6h"`
Interval time.Duration `help:"how frequently rollup should run" devDefault:"120s" releaseDefault:"6h"`
MaxAlphaUsage memory.Size `help:"the bandwidth and storage usage limit for the alpha release" default:"25GB"`
}

View File

@ -21,7 +21,7 @@ import (
// Config contains configurable values for the tally service
type Config struct {
Interval time.Duration `help:"how frequently the tally service should run" default:"1h" devDefault:"30s"`
Interval time.Duration `help:"how frequently the tally service should run" releaseDefault:"1h" devDefault:"30s"`
}
// Service is the tally service for data stored on each storage node

View File

@ -17,26 +17,22 @@ import (
"go.uber.org/zap"
"storj.io/storj/internal/memory"
"storj.io/storj/internal/version"
)
// BindOpt is an option for the Bind method
type BindOpt func(vars map[string]confVar)
type BindOpt struct {
isDev *bool
varfn func(vars map[string]confVar)
}
// ConfDir sets variables for default options called $CONFDIR and $CONFNAME.
func ConfDir(path string) BindOpt {
val := filepath.Clean(os.ExpandEnv(path))
return BindOpt(func(vars map[string]confVar) {
return BindOpt{varfn: func(vars map[string]confVar) {
vars["CONFDIR"] = confVar{val: val, nested: false}
vars["CONFNAME"] = confVar{val: val, nested: false}
})
}
// IdentityDir sets a variable for the default option called $IDENTITYDIR.
func IdentityDir(path string) BindOpt {
val := filepath.Clean(os.ExpandEnv(path))
return BindOpt(func(vars map[string]confVar) {
vars["IDENTITYDIR"] = confVar{val: val, nested: false}
})
}}
}
// ConfDirNested sets variables for default options called $CONFDIR and $CONFNAME.
@ -44,10 +40,36 @@ func IdentityDir(path string) BindOpt {
// descending into substructs.
func ConfDirNested(confdir string) BindOpt {
val := filepath.Clean(os.ExpandEnv(confdir))
return BindOpt(func(vars map[string]confVar) {
return BindOpt{varfn: func(vars map[string]confVar) {
vars["CONFDIR"] = confVar{val: val, nested: true}
vars["CONFNAME"] = confVar{val: val, nested: true}
})
}}
}
// IdentityDir sets a variable for the default option called $IDENTITYDIR.
func IdentityDir(path string) BindOpt {
val := filepath.Clean(os.ExpandEnv(path))
return BindOpt{varfn: func(vars map[string]confVar) {
vars["IDENTITYDIR"] = confVar{val: val, nested: false}
}}
}
// UseDevDefaults forces the bind call to use development defaults unless
// UseReleaseDefaults is provided as a subsequent option.
// Without either, Bind will default to determining which defaults to use
// based on version.Build.Release
func UseDevDefaults() BindOpt {
dev := true
return BindOpt{isDev: &dev}
}
// UseReleaseDefaults forces the bind call to use release defaults unless
// UseDevDefaults is provided as a subsequent option.
// Without either, Bind will default to determining which defaults to use
// based on version.Build.Release
func UseReleaseDefaults() BindOpt {
dev := false
return BindOpt{isDev: &dev}
}
type confVar struct {
@ -58,25 +80,31 @@ type confVar struct {
// Bind sets flags on a FlagSet that match the configuration struct
// 'config'. This works by traversing the config struct using the 'reflect'
// package. Will ignore fields with `setup:"true"` tag.
func Bind(flags FlagSet, config interface{}, isDev bool, opts ...BindOpt) {
bind(flags, config, false, isDev, opts...)
func Bind(flags FlagSet, config interface{}, opts ...BindOpt) {
bind(flags, config, false, opts...)
}
// BindSetup sets flags on a FlagSet that match the configuration struct
// 'config'. This works by traversing the config struct using the 'reflect'
// package.
func BindSetup(flags FlagSet, config interface{}, isDev bool, opts ...BindOpt) {
bind(flags, config, true, isDev, opts...)
func BindSetup(flags FlagSet, config interface{}, opts ...BindOpt) {
bind(flags, config, true, opts...)
}
func bind(flags FlagSet, config interface{}, setupCommand bool, isDev bool, opts ...BindOpt) {
func bind(flags FlagSet, config interface{}, setupCommand bool, opts ...BindOpt) {
ptrtype := reflect.TypeOf(config)
if ptrtype.Kind() != reflect.Ptr {
panic(fmt.Sprintf("invalid config type: %#v. Expecting pointer to struct.", config))
}
isDev := !version.Build.Release
vars := map[string]confVar{}
for _, opt := range opts {
opt(vars)
if opt.varfn != nil {
opt.varfn(vars)
}
if opt.isDev != nil {
isDev = *opt.isDev
}
}
bindConfig(flags, "", reflect.ValueOf(config).Elem(), vars, setupCommand, false, isDev)
@ -133,11 +161,11 @@ func bindConfig(flags FlagSet, prefix string, val reflect.Value, vars map[string
}
default:
help := field.Tag.Get("help")
def := field.Tag.Get("default")
var def string
if isDev {
if devDefault, ok := field.Tag.Lookup("devDefault"); ok {
def = devDefault
}
def = getDefault(field.Tag, "devDefault", "releaseDefault", "default", flagname)
} else {
def = getDefault(field.Tag, "releaseDefault", "devDefault", "default", flagname)
}
fieldaddr := fieldval.Addr().Interface()
check := func(err error) {
@ -193,6 +221,22 @@ func bindConfig(flags FlagSet, prefix string, val reflect.Value, vars map[string
}
}
func getDefault(tag reflect.StructTag, preferred, opposite, fallback, flagname string) string {
if val, ok := tag.Lookup(preferred); ok {
if _, oppositeExists := tag.Lookup(opposite); !oppositeExists {
panic(fmt.Sprintf("%q defined but %q missing for %v", preferred, opposite, flagname))
}
if _, fallbackExists := tag.Lookup(fallback); fallbackExists {
panic(fmt.Sprintf("%q defined along with %q fallback for %v", preferred, fallback, flagname))
}
return val
}
if _, oppositeExists := tag.Lookup(opposite); oppositeExists {
panic(fmt.Sprintf("%q missing but %q defined for %v", preferred, opposite, flagname))
}
return tag.Get(fallback)
}
func setBoolAnnotation(flagset interface{}, name, key string) {
flags, ok := flagset.(*pflag.FlagSet)
if !ok {
@ -219,6 +263,11 @@ func FindIdentityDirParam() string {
return FindFlagEarly("identity-dir")
}
// FindDefaultsParam returns '--defaults' param from os.Args (if it exists)
func FindDefaultsParam() string {
return FindFlagEarly("defaults")
}
// FindFlagEarly retrieves the value of a flag before `flag.Parse` has been called
func FindFlagEarly(flagName string) string {
// workaround to have early access to 'dir' param
@ -232,7 +281,7 @@ func FindFlagEarly(flagName string) string {
return ""
}
//SetupFlag sets up flags that are needed before `flag.Parse` has been called
// SetupFlag sets up flags that are needed before `flag.Parse` has been called
func SetupFlag(log *zap.Logger, cmd *cobra.Command, dest *string, name, value, usage string) {
if foundValue := FindFlagEarly(name); foundValue != "" {
value = foundValue
@ -243,18 +292,30 @@ func SetupFlag(log *zap.Logger, cmd *cobra.Command, dest *string, name, value, u
}
}
//DevFlag sets up the dev flag, which is needed before `flag.Parse` has been called
func DevFlag(cmd *cobra.Command, dest *bool, value bool, usage string) {
for _, arg := range os.Args {
if strings.HasPrefix(arg, "--dev=") {
if val, err := strconv.ParseBool(strings.TrimPrefix(arg, "--dev=")); err == nil {
value = val
break
// DefaultsFlag sets up the defaults=dev/release flag options, which is needed
// before `flag.Parse` has been called
func DefaultsFlag(cmd *cobra.Command) BindOpt {
// define a flag so that the flag parsing system will be happy.
defaults := "dev"
if version.Build.Release {
defaults = "release"
}
} else if arg == "--dev" {
value = true
break
// we're actually going to ignore this flag entirely and parse the commandline
// arguments early instead
_ = cmd.PersistentFlags().String("defaults", defaults,
"determines which set of configuration defaults to use. can either be 'dev' or 'release'")
foundDefaults := strings.ToLower(FindDefaultsParam())
if foundDefaults == "" {
foundDefaults = defaults
}
switch foundDefaults {
case "dev":
return UseDevDefaults()
case "release":
return UseReleaseDefaults()
default:
panic(fmt.Sprintf("unsupported defaults value %q", FindDefaultsParam()))
}
cmd.PersistentFlags().BoolVar(dest, "dev", value, usage)
}

View File

@ -22,22 +22,22 @@ func assertEqual(actual, expected interface{}) {
func TestBind(t *testing.T) {
f := pflag.NewFlagSet("test", pflag.PanicOnError)
var c struct {
String string `default:"" devDefault:"dev"`
Bool bool `default:"false" devDefault:"true"`
Int64 int64 `default:"0" devDefault:"1"`
Int int `default:"0" devDefault:"2"`
Uint64 uint64 `default:"0" devDefault:"3"`
Uint uint `default:"0" devDefault:"4"`
Float64 float64 `default:"0" devDefault:"5.5"`
Duration time.Duration `default:"0" devDefault:"1h"`
String string `default:""`
Bool bool `releaseDefault:"false" devDefault:"true"`
Int64 int64 `releaseDefault:"0" devDefault:"1"`
Int int `default:"0"`
Uint64 uint64 `default:"0"`
Uint uint `default:"0"`
Float64 float64 `default:"0"`
Duration time.Duration `default:"0"`
Struct struct {
AnotherString string `default:"" devDefault:"dev2"`
AnotherString string `default:""`
}
Fields [10]struct {
AnotherInt int `default:"0" devDefault:"6"`
AnotherInt int `default:"0"`
}
}
Bind(f, &c, false)
Bind(f, &c, UseReleaseDefaults())
assertEqual(c.String, string(""))
assertEqual(c.Bool, bool(false))
@ -88,7 +88,7 @@ func TestConfDir(t *testing.T) {
}
}
}
Bind(f, &c, false, ConfDir("confpath"))
Bind(f, &c, UseReleaseDefaults(), ConfDir("confpath"))
assertEqual(f.Lookup("string").DefValue, "-confpath+")
assertEqual(f.Lookup("my-struct1.string").DefValue, "1confpath2")
assertEqual(f.Lookup("my-struct1.my-struct2.string").DefValue, "2confpath3")
@ -105,7 +105,7 @@ func TestNesting(t *testing.T) {
}
}
}
Bind(f, &c, false, ConfDirNested("confpath"))
Bind(f, &c, UseReleaseDefaults(), ConfDirNested("confpath"))
assertEqual(f.Lookup("string").DefValue, "-confpath+")
assertEqual(f.Lookup("my-struct1.string").DefValue, filepath.FromSlash("1confpath/my-struct12"))
assertEqual(f.Lookup("my-struct1.my-struct2.string").DefValue, filepath.FromSlash("2confpath/my-struct1/my-struct23"))
@ -114,22 +114,22 @@ func TestNesting(t *testing.T) {
func TestBindDevDefaults(t *testing.T) {
f := pflag.NewFlagSet("test", pflag.PanicOnError)
var c struct {
String string `default:"" devDefault:"dev"`
Bool bool `default:"false" devDefault:"true"`
Int64 int64 `default:"0" devDefault:"1"`
Int int `default:"0" devDefault:"2"`
Uint64 uint64 `default:"0" devDefault:"3"`
Uint uint `default:"0" devDefault:"4"`
Float64 float64 `default:"0" devDefault:"5.5"`
Duration time.Duration `default:"0" devDefault:"1h"`
String string `default:"dev"`
Bool bool `releaseDefault:"false" devDefault:"true"`
Int64 int64 `releaseDefault:"0" devDefault:"1"`
Int int `default:"2"`
Uint64 uint64 `default:"3"`
Uint uint `releaseDefault:"0" devDefault:"4"`
Float64 float64 `default:"5.5"`
Duration time.Duration `default:"1h"`
Struct struct {
AnotherString string `default:"" devDefault:"dev2"`
AnotherString string `default:"dev2"`
}
Fields [10]struct {
AnotherInt int `default:"0" devDefault:"6"`
AnotherInt int `default:"6"`
}
}
Bind(f, &c, true)
Bind(f, &c, UseDevDefaults())
assertEqual(c.String, string("dev"))
assertEqual(c.Bool, bool(true))

View File

@ -66,9 +66,9 @@ func TestUploadDownload(t *testing.T) {
// bind default values to config
var gwCfg config
cfgstruct.Bind(&pflag.FlagSet{}, &gwCfg, true)
cfgstruct.Bind(&pflag.FlagSet{}, &gwCfg, cfgstruct.UseDevDefaults())
var uplinkCfg uplink.Config
cfgstruct.Bind(&pflag.FlagSet{}, &uplinkCfg, true)
cfgstruct.Bind(&pflag.FlagSet{}, &uplinkCfg, cfgstruct.UseDevDefaults())
// minio config directory
gwCfg.Minio.Dir = ctx.Dir("minio")

View File

@ -14,7 +14,7 @@ type Config struct {
Path string `help:"path to store data in" default:"$CONFDIR/storage"`
WhitelistedSatelliteIDs string `help:"a comma-separated list of approved satellite node ids" default:""`
SatelliteIDRestriction bool `help:"if true, only allow data from approved satellites" devDefault:"false" default:"true"`
SatelliteIDRestriction bool `help:"if true, only allow data from approved satellites" devDefault:"false" releaseDefault:"true"`
AllocatedDiskSpace memory.Size `user:"true" help:"total allocated disk space in bytes" default:"1TB"`
AllocatedBandwidth memory.Size `user:"true" help:"total allocated bandwidth in bytes" default:"500GiB"`
KBucketRefreshInterval time.Duration `help:"how frequently Kademlia bucket should be refreshed with node stats" default:"1h0m0s"`

View File

@ -31,10 +31,10 @@ import (
type RSConfig struct {
MaxBufferMem memory.Size `help:"maximum buffer memory (in bytes) to be allocated for read buffers" default:"4MiB"`
ErasureShareSize memory.Size `help:"the size of each new erasure sure in bytes" default:"1KiB"`
MinThreshold int `help:"the minimum pieces required to recover a segment. k." default:"29" devDefault:"4"`
RepairThreshold int `help:"the minimum safe pieces before a repair is triggered. m." default:"35" devDefault:"6"`
SuccessThreshold int `help:"the desired total pieces for a segment. o." default:"80" devDefault:"8"`
MaxThreshold int `help:"the largest amount of pieces to encode to. n." default:"95" devDefault:"10"`
MinThreshold int `help:"the minimum pieces required to recover a segment. k." releaseDefault:"29" devDefault:"4"`
RepairThreshold int `help:"the minimum safe pieces before a repair is triggered. m." releaseDefault:"35" devDefault:"6"`
SuccessThreshold int `help:"the desired total pieces for a segment. o." releaseDefault:"80" devDefault:"8"`
MaxThreshold int `help:"the largest amount of pieces to encode to. n." releaseDefault:"95" devDefault:"10"`
}
// EncryptionConfig is a configuration struct that keeps details about
@ -50,7 +50,7 @@ type EncryptionConfig struct {
// to talk to the rest of the network.
type ClientConfig struct {
APIKey string `default:"" help:"the api key to use for the satellite" noprefix:"true"`
SatelliteAddr string `default:"127.0.0.1:7777" devDefault:"127.0.0.1:10000" help:"the address to use for the satellite" noprefix:"true"`
SatelliteAddr string `releaseDefault:"127.0.0.1:7777" devDefault:"127.0.0.1:10000" help:"the address to use for the satellite" noprefix:"true"`
MaxInlineSize memory.Size `help:"max inline segment size in bytes" default:"4KiB"`
SegmentSize memory.Size `help:"the size of a segment in bytes" default:"64MiB"`
}