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 confDir string
identityDir string identityDir string
isDev bool
) )
const ( const (
@ -54,11 +53,11 @@ func init() {
defaultIdentityDir := fpath.ApplicationDir("storj", "identity", "bootstrap") 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, &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.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(runCmd)
rootCmd.AddCommand(setupCmd) rootCmd.AddCommand(setupCmd)
cfgstruct.Bind(runCmd.Flags(), &runCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) cfgstruct.Bind(runCmd.Flags(), &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
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 cmdRun(cmd *cobra.Command, args []string) (err error) { func cmdRun(cmd *cobra.Command, args []string) (err error) {

View File

@ -49,7 +49,6 @@ var (
confDir string confDir string
identityDir string identityDir string
isDev bool
) )
func cmdRun(cmd *cobra.Command, args []string) error { 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, &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") //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") 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(authCmd)
rootCmd.AddCommand(runCmd) rootCmd.AddCommand(runCmd)
@ -83,15 +82,15 @@ func main() {
authCmd.AddCommand(authInfoCmd) authCmd.AddCommand(authInfoCmd)
authCmd.AddCommand(authExportCmd) authCmd.AddCommand(authExportCmd)
cfgstruct.Bind(authCreateCmd.Flags(), &config, isDev, cfgstruct.ConfDir(confDir)) cfgstruct.Bind(authCreateCmd.Flags(), &config, defaults, cfgstruct.ConfDir(confDir))
cfgstruct.Bind(authInfoCmd.Flags(), &config, isDev, cfgstruct.ConfDir(confDir)) cfgstruct.Bind(authInfoCmd.Flags(), &config, defaults, cfgstruct.ConfDir(confDir))
cfgstruct.Bind(authExportCmd.Flags(), &config, isDev, cfgstruct.ConfDir(confDir)) cfgstruct.Bind(authExportCmd.Flags(), &config, defaults, cfgstruct.ConfDir(confDir))
cfgstruct.Bind(runCmd.Flags(), &config, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) cfgstruct.Bind(runCmd.Flags(), &config, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.BindSetup(setupCmd.Flags(), &config, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) cfgstruct.BindSetup(setupCmd.Flags(), &config, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(signCmd.Flags(), &signCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) cfgstruct.Bind(signCmd.Flags(), &signCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(verifyCmd.Flags(), &verifyCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) cfgstruct.Bind(verifyCmd.Flags(), &verifyCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(claimsExportCmd.Flags(), &claimsExportCfg, isDev, cfgstruct.ConfDir(confDir)) cfgstruct.Bind(claimsExportCmd.Flags(), &claimsExportCfg, defaults, cfgstruct.ConfDir(confDir))
cfgstruct.Bind(claimDeleteCmd.Flags(), &claimsDeleteCfg, isDev, cfgstruct.ConfDir(confDir)) cfgstruct.Bind(claimDeleteCmd.Flags(), &claimsDeleteCfg, defaults, cfgstruct.ConfDir(confDir))
process.Exec(rootCmd) process.Exec(rootCmd)
} }

View File

@ -63,7 +63,6 @@ var (
confDir string confDir string
identityDir string identityDir string
isDev bool
) )
func init() { func init() {
@ -71,12 +70,12 @@ func init() {
defaultIdentityDir := fpath.ApplicationDir("storj", "identity", "gateway") 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, &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.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(runCmd)
rootCmd.AddCommand(setupCmd) rootCmd.AddCommand(setupCmd)
cfgstruct.Bind(runCmd.Flags(), &runCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) cfgstruct.Bind(runCmd.Flags(), &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
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) { func cmdSetup(cmd *cobra.Command, args []string) (err error) {

View File

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

View File

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

View File

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

View File

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

View File

@ -33,7 +33,7 @@ var (
func init() { func init() {
rootCmd.AddCommand(revocationsCmd) 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 { func cmdRevocations(cmd *cobra.Command, args []string) error {

View File

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

View File

@ -84,7 +84,6 @@ var (
} }
confDir string confDir string
identityDir string identityDir string
isDev bool
) )
func init() { func init() {
@ -92,18 +91,18 @@ func init() {
defaultIdentityDir := fpath.ApplicationDir("storj", "identity", "satellite") 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, &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.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(runCmd)
rootCmd.AddCommand(setupCmd) rootCmd.AddCommand(setupCmd)
rootCmd.AddCommand(diagCmd) rootCmd.AddCommand(diagCmd)
rootCmd.AddCommand(qdiagCmd) rootCmd.AddCommand(qdiagCmd)
rootCmd.AddCommand(reportsCmd) rootCmd.AddCommand(reportsCmd)
reportsCmd.AddCommand(nodeUsageCmd) reportsCmd.AddCommand(nodeUsageCmd)
cfgstruct.Bind(runCmd.Flags(), &runCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) cfgstruct.Bind(runCmd.Flags(), &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.BindSetup(setupCmd.Flags(), &setupCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) cfgstruct.BindSetup(setupCmd.Flags(), &setupCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(diagCmd.Flags(), &diagCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) cfgstruct.Bind(diagCmd.Flags(), &diagCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(qdiagCmd.Flags(), &qdiagCfg, isDev, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) cfgstruct.Bind(qdiagCmd.Flags(), &qdiagCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
cfgstruct.Bind(nodeUsageCmd.Flags(), &nodeUsageCfg, isDev, 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) { func cmdRun(cmd *cobra.Command, args []string) (err error) {

View File

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

View File

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

View File

@ -31,7 +31,7 @@ var (
setupCfg UplinkFlags setupCfg UplinkFlags
confDir string confDir string
identityDir string identityDir string
isDev bool defaults cfgstruct.BindOpt
// Error is the default uplink setup errs class // Error is the default uplink setup errs class
Error = errs.Class("uplink setup error") Error = errs.Class("uplink setup error")
@ -42,9 +42,9 @@ func init() {
defaultIdentityDir := fpath.ApplicationDir("storj", "identity", "uplink") 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, &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.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) 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) { func cmdSetup(cmd *cobra.Command, args []string) (err error) {

View File

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

View File

@ -22,7 +22,7 @@ var (
) )
func init() { 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() { func main() {

View File

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

View File

@ -17,7 +17,7 @@ import (
// Config contains configurable values for rollup // Config contains configurable values for rollup
type Config struct { 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"` 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 // Config contains configurable values for the tally service
type Config struct { 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 // Service is the tally service for data stored on each storage node

View File

@ -17,26 +17,22 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
"storj.io/storj/internal/memory" "storj.io/storj/internal/memory"
"storj.io/storj/internal/version"
) )
// BindOpt is an option for the Bind method // 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. // ConfDir sets variables for default options called $CONFDIR and $CONFNAME.
func ConfDir(path string) BindOpt { func ConfDir(path string) BindOpt {
val := filepath.Clean(os.ExpandEnv(path)) 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["CONFDIR"] = confVar{val: val, nested: false}
vars["CONFNAME"] = 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. // ConfDirNested sets variables for default options called $CONFDIR and $CONFNAME.
@ -44,10 +40,36 @@ func IdentityDir(path string) BindOpt {
// descending into substructs. // descending into substructs.
func ConfDirNested(confdir string) BindOpt { func ConfDirNested(confdir string) BindOpt {
val := filepath.Clean(os.ExpandEnv(confdir)) 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["CONFDIR"] = confVar{val: val, nested: true}
vars["CONFNAME"] = 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 { type confVar struct {
@ -58,25 +80,31 @@ type confVar struct {
// Bind sets flags on a FlagSet that match the configuration struct // Bind sets flags on a FlagSet that match the configuration struct
// 'config'. This works by traversing the config struct using the 'reflect' // 'config'. This works by traversing the config struct using the 'reflect'
// package. Will ignore fields with `setup:"true"` tag. // package. Will ignore fields with `setup:"true"` tag.
func Bind(flags FlagSet, config interface{}, isDev bool, opts ...BindOpt) { func Bind(flags FlagSet, config interface{}, opts ...BindOpt) {
bind(flags, config, false, isDev, opts...) bind(flags, config, false, opts...)
} }
// BindSetup sets flags on a FlagSet that match the configuration struct // BindSetup sets flags on a FlagSet that match the configuration struct
// 'config'. This works by traversing the config struct using the 'reflect' // 'config'. This works by traversing the config struct using the 'reflect'
// package. // package.
func BindSetup(flags FlagSet, config interface{}, isDev bool, opts ...BindOpt) { func BindSetup(flags FlagSet, config interface{}, opts ...BindOpt) {
bind(flags, config, true, isDev, opts...) 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) ptrtype := reflect.TypeOf(config)
if ptrtype.Kind() != reflect.Ptr { if ptrtype.Kind() != reflect.Ptr {
panic(fmt.Sprintf("invalid config type: %#v. Expecting pointer to struct.", config)) panic(fmt.Sprintf("invalid config type: %#v. Expecting pointer to struct.", config))
} }
isDev := !version.Build.Release
vars := map[string]confVar{} vars := map[string]confVar{}
for _, opt := range opts { 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) 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: default:
help := field.Tag.Get("help") help := field.Tag.Get("help")
def := field.Tag.Get("default") var def string
if isDev { if isDev {
if devDefault, ok := field.Tag.Lookup("devDefault"); ok { def = getDefault(field.Tag, "devDefault", "releaseDefault", "default", flagname)
def = devDefault } else {
} def = getDefault(field.Tag, "releaseDefault", "devDefault", "default", flagname)
} }
fieldaddr := fieldval.Addr().Interface() fieldaddr := fieldval.Addr().Interface()
check := func(err error) { 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) { func setBoolAnnotation(flagset interface{}, name, key string) {
flags, ok := flagset.(*pflag.FlagSet) flags, ok := flagset.(*pflag.FlagSet)
if !ok { if !ok {
@ -219,6 +263,11 @@ func FindIdentityDirParam() string {
return FindFlagEarly("identity-dir") 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 // FindFlagEarly retrieves the value of a flag before `flag.Parse` has been called
func FindFlagEarly(flagName string) string { func FindFlagEarly(flagName string) string {
// workaround to have early access to 'dir' param // workaround to have early access to 'dir' param
@ -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 // DefaultsFlag sets up the defaults=dev/release flag options, which is needed
func DevFlag(cmd *cobra.Command, dest *bool, value bool, usage string) { // before `flag.Parse` has been called
for _, arg := range os.Args { func DefaultsFlag(cmd *cobra.Command) BindOpt {
if strings.HasPrefix(arg, "--dev=") { // define a flag so that the flag parsing system will be happy.
if val, err := strconv.ParseBool(strings.TrimPrefix(arg, "--dev=")); err == nil { defaults := "dev"
value = val if version.Build.Release {
break defaults = "release"
} }
} else if arg == "--dev" { // we're actually going to ignore this flag entirely and parse the commandline
value = true // arguments early instead
break _ = 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) { func TestBind(t *testing.T) {
f := pflag.NewFlagSet("test", pflag.PanicOnError) f := pflag.NewFlagSet("test", pflag.PanicOnError)
var c struct { var c struct {
String string `default:"" devDefault:"dev"` String string `default:""`
Bool bool `default:"false" devDefault:"true"` Bool bool `releaseDefault:"false" devDefault:"true"`
Int64 int64 `default:"0" devDefault:"1"` Int64 int64 `releaseDefault:"0" devDefault:"1"`
Int int `default:"0" devDefault:"2"` Int int `default:"0"`
Uint64 uint64 `default:"0" devDefault:"3"` Uint64 uint64 `default:"0"`
Uint uint `default:"0" devDefault:"4"` Uint uint `default:"0"`
Float64 float64 `default:"0" devDefault:"5.5"` Float64 float64 `default:"0"`
Duration time.Duration `default:"0" devDefault:"1h"` Duration time.Duration `default:"0"`
Struct struct { Struct struct {
AnotherString string `default:"" devDefault:"dev2"` AnotherString string `default:""`
} }
Fields [10]struct { 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.String, string(""))
assertEqual(c.Bool, bool(false)) 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("string").DefValue, "-confpath+")
assertEqual(f.Lookup("my-struct1.string").DefValue, "1confpath2") assertEqual(f.Lookup("my-struct1.string").DefValue, "1confpath2")
assertEqual(f.Lookup("my-struct1.my-struct2.string").DefValue, "2confpath3") 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("string").DefValue, "-confpath+")
assertEqual(f.Lookup("my-struct1.string").DefValue, filepath.FromSlash("1confpath/my-struct12")) 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")) 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) { func TestBindDevDefaults(t *testing.T) {
f := pflag.NewFlagSet("test", pflag.PanicOnError) f := pflag.NewFlagSet("test", pflag.PanicOnError)
var c struct { var c struct {
String string `default:"" devDefault:"dev"` String string `default:"dev"`
Bool bool `default:"false" devDefault:"true"` Bool bool `releaseDefault:"false" devDefault:"true"`
Int64 int64 `default:"0" devDefault:"1"` Int64 int64 `releaseDefault:"0" devDefault:"1"`
Int int `default:"0" devDefault:"2"` Int int `default:"2"`
Uint64 uint64 `default:"0" devDefault:"3"` Uint64 uint64 `default:"3"`
Uint uint `default:"0" devDefault:"4"` Uint uint `releaseDefault:"0" devDefault:"4"`
Float64 float64 `default:"0" devDefault:"5.5"` Float64 float64 `default:"5.5"`
Duration time.Duration `default:"0" devDefault:"1h"` Duration time.Duration `default:"1h"`
Struct struct { Struct struct {
AnotherString string `default:"" devDefault:"dev2"` AnotherString string `default:"dev2"`
} }
Fields [10]struct { 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.String, string("dev"))
assertEqual(c.Bool, bool(true)) assertEqual(c.Bool, bool(true))

View File

@ -66,9 +66,9 @@ func TestUploadDownload(t *testing.T) {
// bind default values to config // bind default values to config
var gwCfg config var gwCfg config
cfgstruct.Bind(&pflag.FlagSet{}, &gwCfg, true) cfgstruct.Bind(&pflag.FlagSet{}, &gwCfg, cfgstruct.UseDevDefaults())
var uplinkCfg uplink.Config var uplinkCfg uplink.Config
cfgstruct.Bind(&pflag.FlagSet{}, &uplinkCfg, true) cfgstruct.Bind(&pflag.FlagSet{}, &uplinkCfg, cfgstruct.UseDevDefaults())
// minio config directory // minio config directory
gwCfg.Minio.Dir = ctx.Dir("minio") 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"` Path string `help:"path to store data in" default:"$CONFDIR/storage"`
WhitelistedSatelliteIDs string `help:"a comma-separated list of approved satellite node ids" default:""` 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"` 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"` 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"` 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 { type RSConfig struct {
MaxBufferMem memory.Size `help:"maximum buffer memory (in bytes) to be allocated for read buffers" default:"4MiB"` 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"` 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"` 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." default:"35" devDefault:"6"` 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." default:"80" devDefault:"8"` 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." default:"95" devDefault:"10"` 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 // EncryptionConfig is a configuration struct that keeps details about
@ -50,7 +50,7 @@ type EncryptionConfig struct {
// to talk to the rest of the network. // to talk to the rest of the network.
type ClientConfig struct { type ClientConfig struct {
APIKey string `default:"" help:"the api key to use for the satellite" noprefix:"true"` 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"` 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"` SegmentSize memory.Size `help:"the size of a segment in bytes" default:"64MiB"`
} }