Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow app developers to override default appConfig template #9550

Merged
merged 22 commits into from
Jun 23, 2021
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions server/config/toml.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
tmos "github.com/tendermint/tendermint/libs/os"
)

const defaultConfigTemplate = `# This is a TOML config file.
const DefaultConfigTemplate = `# This is a TOML config file.
# For more information, see https://github.com/toml-lang/toml

###############################################################################
Expand Down Expand Up @@ -210,7 +210,7 @@ func init() {

tmpl := template.New("appConfigFileTemplate")

if configTemplate, err = tmpl.Parse(defaultConfigTemplate); err != nil {
if configTemplate, err = tmpl.Parse(DefaultConfigTemplate); err != nil {
panic(err)
}
}
Expand All @@ -224,9 +224,19 @@ func ParseConfig(v *viper.Viper) (*Config, error) {
return conf, err
}

func SetConfigTemplate(customTemplate string) {
anilcse marked this conversation as resolved.
Show resolved Hide resolved
var err error

tmpl := template.New("appConfigFileTemplate")

if configTemplate, err = tmpl.Parse(customTemplate); err != nil {
panic(err)
}
}

// WriteConfigFile renders config using the template and writes it to
// configFilePath.
func WriteConfigFile(configFilePath string, config *Config) {
func WriteConfigFile(configFilePath string, config interface{}) {
var buffer bytes.Buffer

if err := configTemplate.Execute(&buffer, config); err != nil {
Expand Down
23 changes: 15 additions & 8 deletions server/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func bindFlags(basename string, cmd *cobra.Command, v *viper.Viper) (err error)
// the Tendermint configuration. The Viper literal is used to read and parse
// the application configuration. Command handlers can fetch the server Context
// to get the Tendermint configuration or to get access to Viper.
func InterceptConfigsPreRunHandler(cmd *cobra.Command) error {
func InterceptConfigsPreRunHandler(cmd *cobra.Command, customAppConfigTemplate string, customAppConfig interface{}) error {
serverCtx := NewDefaultContext()

// Get the executable name and configure the viper instance so that environmental
Expand All @@ -123,7 +123,7 @@ func InterceptConfigsPreRunHandler(cmd *cobra.Command) error {
serverCtx.Viper.AutomaticEnv()

// intercept configuration files, using both Viper instances separately
config, err := interceptConfigs(serverCtx.Viper)
config, err := interceptConfigs(serverCtx.Viper, customAppConfigTemplate, customAppConfig)
if err != nil {
return err
}
Expand Down Expand Up @@ -181,7 +181,7 @@ func SetCmdServerContext(cmd *cobra.Command, serverCtx *Context) error {
// configuration file. The Tendermint configuration file is parsed given a root
// Viper object, whereas the application is parsed with the private package-aware
// viperCfg object.
func interceptConfigs(rootViper *viper.Viper) (*tmcfg.Config, error) {
func interceptConfigs(rootViper *viper.Viper, customAppTemplate string, customConfig interface{}) (*tmcfg.Config, error) {
rootDir := rootViper.GetString(flags.FlagHome)
configPath := filepath.Join(rootDir, "config")
tmCfgFile := filepath.Join(configPath, "config.toml")
Expand Down Expand Up @@ -226,12 +226,19 @@ func interceptConfigs(rootViper *viper.Viper) (*tmcfg.Config, error) {

appCfgFilePath := filepath.Join(configPath, "app.toml")
if _, err := os.Stat(appCfgFilePath); os.IsNotExist(err) {
appConf, err := config.ParseConfig(rootViper)
if err != nil {
return nil, fmt.Errorf("failed to parse %s: %w", appCfgFilePath, err)
}
if customAppTemplate != "" {
config.SetConfigTemplate(customAppTemplate)

err = rootViper.Unmarshal(customConfig)
config.WriteConfigFile(appCfgFilePath, customConfig)
} else {
appConf, err := config.ParseConfig(rootViper)
if err != nil {
return nil, fmt.Errorf("failed to parse %s: %w", appCfgFilePath, err)
}

config.WriteConfigFile(appCfgFilePath, appConf)
config.WriteConfigFile(appCfgFilePath, appConf)
}
}

rootViper.SetConfigType("toml")
Expand Down
45 changes: 43 additions & 2 deletions simapp/simd/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"path/filepath"

serverconfig "github.com/cosmos/cosmos-sdk/server/config"
"github.com/spf13/cast"
"github.com/spf13/cobra"
tmcli "github.com/tendermint/tendermint/libs/cli"
Expand All @@ -14,7 +15,7 @@ import (

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
config "github.com/cosmos/cosmos-sdk/client/config"
"github.com/cosmos/cosmos-sdk/client/config"
"github.com/cosmos/cosmos-sdk/client/debug"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/keys"
Expand Down Expand Up @@ -66,7 +67,10 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
return err
}

return server.InterceptConfigsPreRunHandler(cmd)
// this is optional
customAppTemplate, customAppConfig := initConfig()

return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig)
},
}

Expand All @@ -75,6 +79,43 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
return rootCmd, encodingConfig
}

// initConfig helps to override default appConfig template and settings.
// return; if no custom configuration is required for the application.
func initConfig() (customAppTemplate string, customAppConfig interface{}) {
fedekunze marked this conversation as resolved.
Show resolved Hide resolved
// WASMConfig defines configuration for the wasm module.
type WASMConfig struct {
// This is the maximum sdk gas (wasm and storage) that we allow for any x/wasm "smart" queries
QueryGasLimit uint64 `mapstructure:"query_gas_limit"`

// Address defines the gRPC-web server to listen on
LruSize uint64 `mapstructure:"lru_size"`
}

type CustomAppConfig struct {
serverconfig.Config

WASM WASMConfig `mapstructure:"wasm"`
}

customAppConfig = CustomAppConfig{
Config: *serverconfig.DefaultConfig(),
WASM: WASMConfig{
LruSize: 1,
QueryGasLimit: 300000,
},
}

customAppTemplate = serverconfig.DefaultConfigTemplate + `
[wasm]
# This is the maximum sdk gas (wasm and storage) that we allow for any x/wasm "smart" queries
query_gas_limit = 300000
# This is the number of wasm vm instances we keep cached in memory for speed-up
# Warning: this is currently unstable and may lead to crashes, best to keep for 0 unless testing locally
lru_size = 0`

return
}

func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
cfg := sdk.GetConfig()
cfg.Seal()
Expand Down