From a8989d7c4c4b7ee542730dc594cd6b8a69701cf7 Mon Sep 17 00:00:00 2001 From: Daylon Wilkins Date: Tue, 16 Dec 2025 06:43:01 -0800 Subject: [PATCH] Changed configuration file for function passing --- cmd/doltgres/main.go | 5 +- server/initialization/initialization.go | 3 +- servercfg/cfgdetails/config.go | 632 ++++++++++++++++++ servercfg/{ => cfgdetails}/minver_test.go | 2 +- .../testdata/minver_validation.txt | 16 +- servercfg/config.go | 627 +---------------- .../output/framework_test.go | 9 +- .../go/enginetest/doltgres_harness_test.go | 9 +- testing/go/framework.go | 21 +- testing/go/regression/tool/create_server.go | 13 +- testing/go/ssl_test.go | 23 +- utils/genminver_validation/main.go | 4 +- 12 files changed, 724 insertions(+), 640 deletions(-) create mode 100644 servercfg/cfgdetails/config.go rename servercfg/{ => cfgdetails}/minver_test.go (98%) rename servercfg/{ => cfgdetails}/testdata/minver_validation.txt (79%) diff --git a/cmd/doltgres/main.go b/cmd/doltgres/main.go index ac8f71f969..21120b69b3 100644 --- a/cmd/doltgres/main.go +++ b/cmd/doltgres/main.go @@ -41,6 +41,7 @@ import ( "github.com/dolthub/doltgresql/server" "github.com/dolthub/doltgresql/servercfg" + "github.com/dolthub/doltgresql/servercfg/cfgdetails" "github.com/dolthub/doltgresql/utils" ) @@ -320,7 +321,7 @@ func getDataDirFromParams(params map[string]*string) (string, dataDirType, error return dataDir, dataDirExplicitParam, nil } - if envDir := os.Getenv(servercfg.DOLTGRES_DATA_DIR); len(envDir) > 0 { + if envDir := os.Getenv(cfgdetails.DOLTGRES_DATA_DIR); len(envDir) > 0 { return envDir, dataDirEnv, nil } else { homeDir, err := env.GetCurrentUserHomeDir() @@ -328,7 +329,7 @@ func getDataDirFromParams(params map[string]*string) (string, dataDirType, error return "", dataDirDefault, errors.Errorf("failed to get current user's home directory: %w", err) } - dbDir := filepath.Join(homeDir, servercfg.DOLTGRES_DATA_DIR_DEFAULT) + dbDir := filepath.Join(homeDir, cfgdetails.DOLTGRES_DATA_DIR_DEFAULT) return dbDir, dataDirDefault, nil } } diff --git a/server/initialization/initialization.go b/server/initialization/initialization.go index 5b94103f1e..f15eb5becb 100644 --- a/server/initialization/initialization.go +++ b/server/initialization/initialization.go @@ -36,6 +36,7 @@ import ( "github.com/dolthub/doltgresql/server/tables/information_schema" "github.com/dolthub/doltgresql/server/tables/pgcatalog" doltgresservercfg "github.com/dolthub/doltgresql/servercfg" + "github.com/dolthub/doltgresql/servercfg/cfgdetails" ) var once = &sync.Once{} @@ -54,7 +55,7 @@ func Initialize(dEnv *env.DoltEnv, cfg *doltgresservercfg.DoltgresConfig) { aggregate.Init() cast.Init() framework.Initialize() - servercfg.DefaultUnixSocketFilePath = doltgresservercfg.DefaultPostgresUnixSocketFilePath + servercfg.DefaultUnixSocketFilePath = cfgdetails.DefaultPostgresUnixSocketFilePath tables.Init() pgcatalog.Init() information_schema.Init() diff --git a/servercfg/cfgdetails/config.go b/servercfg/cfgdetails/config.go new file mode 100644 index 0000000000..23c55333d7 --- /dev/null +++ b/servercfg/cfgdetails/config.go @@ -0,0 +1,632 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cfgdetails + +import ( + "path/filepath" + "strings" + "time" + "unicode" + "unicode/utf8" + + "github.com/dolthub/dolt/go/libraries/doltcore/env" + doltservercfg "github.com/dolthub/dolt/go/libraries/doltcore/servercfg" + "github.com/dolthub/go-mysql-server/sql" + "gopkg.in/yaml.v2" +) + +const ( + maxConnectionsKey = "max_connections" + readTimeoutKey = "net_read_timeout" + writeTimeoutKey = "net_write_timeout" + eventSchedulerKey = "event_scheduler" + + OverrideDataDirKey = "data_dir" +) + +const ( + LogLevel_Trace = "trace" + LogLevel_Debug = "debug" + LogLevel_Info = "info" + LogLevel_Warning = "warn" + LogLevel_Error = "error" + LogLevel_Fatal = "fatal" + LogLevel_Panic = "panic" +) + +const ( + DefaultHost = "localhost" + DefaultPort = 5432 + DefaultUser = "postgres" + DefaultPass = "password" + DefaultTimeout = 8 * 60 * 60 * 1000 // 8 hours, same as MySQL + DefaultReadOnly = false + DefaultLogLevel = LogLevel_Info + DefaultDoltTransactionCommit = false + DefaultMaxConnections = 100 + DefaultDataDir = "." + DefaultCfgDir = ".doltcfg" + DefaultPrivilegeFilePath = "privileges.db" + DefaultAuthFilePath = "auth.db" + DefaultBranchControlFilePath = "branch_control.db" + DefaultMetricsHost = "" + DefaultMetricsPort = -1 + DefaultAllowCleartextPasswords = false + DefaultPostgresUnixSocketFilePath = "/tmp/.s.PGSQL.5432" + DefaultMaxLoggedQueryLen = 0 + DefaultEncodeLoggedQuery = false +) + +// DOLTGRES_DATA_DIR is an environment variable that defines the location of DoltgreSQL databases +const DOLTGRES_DATA_DIR = "DOLTGRES_DATA_DIR" + +// DOLTGRES_DATA_DIR_DEFAULT is the portion to append to the user's home directory if DOLTGRES_DATA_DIR has not been specified +const DOLTGRES_DATA_DIR_DEFAULT = "doltgres/databases" + +var ConfigHelp = "Supported fields in the config.yaml file, and their default values, " + + "are as follows:\n\n" + InternalDefaultServerConfig().String() + +type PostgresReplicationConfig struct { + PostgresServerAddress *string `yaml:"postgres_server_address,omitempty" minver:"0.7.4"` + PostgresUser *string `yaml:"postgres_user,omitempty" minver:"0.7.4"` + PostgresPassword *string `yaml:"postgres_password,omitempty" minver:"0.7.4"` + PostgresDatabase *string `yaml:"postgres_database,omitempty" minver:"0.7.4"` + PostgresPort *int `yaml:"postgres_port,omitempty" minver:"0.7.4"` + SlotName *string `yaml:"slot_name,omitempty" minver:"0.7.4"` +} + +// DoltgresBehaviorConfig contains server configuration regarding how the server should behave +type DoltgresBehaviorConfig struct { + ReadOnly *bool `yaml:"read_only,omitempty" minver:"0.7.4"` + // Disable processing CLIENT_MULTI_STATEMENTS support on the + // sql server. Dolt's handling of CLIENT_MULTI_STATEMENTS is currently + // broken. If a client advertises to support it (mysql cli client + // does), and then sends statements that contain embedded unquoted ';'s + // (such as a CREATE TRIGGER), then those incoming queries will be + // misprocessed. + DisableClientMultiStatements *bool `yaml:"disable_client_multi_statements,omitempty" minver:"0.7.4"` + // DoltTransactionCommit enables the @@dolt_transaction_commit system variable, which + // automatically creates a Dolt commit when any SQL transaction is committed. + DoltTransactionCommit *bool `yaml:"dolt_transaction_commit,omitempty" minver:"0.7.4"` +} + +// DoltgresAutoGCBehavior implements Dolt's doltservercfg.AutoGCBehavior. +type DoltgresAutoGCBehavior struct { +} + +func (DoltgresAutoGCBehavior) Enable() bool { + return false +} + +func (DoltgresAutoGCBehavior) ArchiveLevel() int { + return 0 +} + +type DoltgresUserConfig struct { + Name *string `yaml:"name,omitempty" minver:"0.7.4"` + Password *string `yaml:"password,omitempty" minver:"0.7.4"` +} + +// DoltgresListenerConfig contains information on the network connection that the server will open +type DoltgresListenerConfig struct { + HostStr *string `yaml:"host,omitempty" minver:"0.7.4"` + PortNumber *int `yaml:"port,omitempty" minver:"0.7.4"` + ReadTimeoutMillis *uint64 `yaml:"read_timeout_millis,omitempty" minver:"0.7.4"` + WriteTimeoutMillis *uint64 `yaml:"write_timeout_millis,omitempty" minver:"0.7.4"` + // TLSKey is a file system path to an unencrypted private TLS key in PEM format. + TLSKey *string `yaml:"tls_key,omitempty" minver:"0.7.4"` + // TLSCert is a file system path to a TLS certificate chain in PEM format. + TLSCert *string `yaml:"tls_cert,omitempty" minver:"0.7.4"` + // RequireSecureTransport can enable a mode where non-TLS connections are turned away. + RequireSecureTransport *bool `yaml:"require_secure_transport,omitempty" minver:"0.7.4"` + // AllowCleartextPasswords enables use of cleartext passwords. + AllowCleartextPasswords *bool `yaml:"allow_cleartext_passwords,omitempty" minver:"0.7.4"` + // Socket is unix socket file path + Socket *string `yaml:"socket,omitempty" minver:"0.7.4"` +} + +// DoltgresPerformanceConfig contains configuration parameters for performance tweaking +type DoltgresPerformanceConfig struct { + QueryParallelism *int `yaml:"query_parallelism,omitempty" minver:"0.7.4"` +} + +type DoltgesMetricsConfig struct { + Labels map[string]string `yaml:"labels,omitempty" minver:"0.7.4"` + Host *string `yaml:"host,omitempty" minver:"0.7.4"` + Port *int `yaml:"port,omitempty" minver:"0.7.4"` + TlsCert *string `yaml:"tls_cert,omitempty" minver:"0.53.5"` + TlsKey *string `yaml:"tls_key,omitempty" minver:"0.53.5"` + TlsCa *string `yaml:"tls_ca,omitempty" minver:"0.53.5"` +} + +type DoltgresRemotesapiConfig struct { + Port *int `yaml:"port,omitempty" minver:"0.7.4"` + ReadOnly *bool `yaml:"read_only,omitempty" minver:"0.7.4"` +} + +type DoltgresUserSessionVars struct { + Name string `yaml:"name"` + Vars map[string]interface{} `yaml:"vars,omitempty"` +} + +// DoltgresConfig is the internal Doltgres configuration file implementation. This should not be used directly, and +// instead `servercfg.DoltgresConfig` should be used. +type DoltgresConfig struct { + LogLevelStr *string `yaml:"log_level,omitempty" minver:"0.7.4"` + MaxLenInLogs *int `yaml:"max_query_len_in_logs,omitempty" minver:"0.7.4"` + EncodeLoggedQuery *bool `yaml:"encode_logged_query,omitempty" minver:"0.7.4"` + BehaviorConfig *DoltgresBehaviorConfig `yaml:"behavior,omitempty" minver:"0.7.4"` + UserConfig *DoltgresUserConfig `yaml:"user,omitempty" minver:"0.7.4"` + ListenerConfig *DoltgresListenerConfig `yaml:"listener,omitempty" minver:"0.7.4"` + PerformanceConfig *DoltgresPerformanceConfig `yaml:"performance,omitempty" minver:"0.7.4"` + DataDirStr *string `yaml:"data_dir,omitempty" minver:"0.7.4"` + CfgDirStr *string `yaml:"cfg_dir,omitempty" minver:"0.7.4"` + MetricsConfig *DoltgesMetricsConfig `yaml:"metrics,omitempty" minver:"0.7.4"` + RemotesapiConfig *DoltgresRemotesapiConfig `yaml:"remotesapi,omitempty" minver:"0.7.4"` + PrivilegeFile *string `yaml:"privilege_file,omitempty" minver:"0.7.4"` + AuthFile *string `yaml:"auth_file,omitempty" minver:"0.54.4"` + BranchControlFile *string `yaml:"branch_control_file,omitempty" minver:"0.7.4"` + + // TODO: Rename to UserVars_ + Vars []DoltgresUserSessionVars `yaml:"user_session_vars,omitempty" minver:"0.7.4"` + SystemVariables map[string]interface{} `yaml:"system_variables,omitempty" minver:"0.7.4"` + Jwks []doltservercfg.JwksConfig `yaml:"jwks,omitempty" minver:"0.7.4"` + GoldenMysqlConn *string `yaml:"golden_mysql_conn,omitempty" minver:"0.7.4"` + + PostgresReplicationConfig *PostgresReplicationConfig `yaml:"postgres_replication,omitempty" minver:"0.7.4"` +} + +var _ doltservercfg.ServerConfig = (*DoltgresConfig)(nil) + +// Ptr is a helper function that returns a pointer to the value passed in. This is necessary to e.g. get a pointer to +// a const value without assigning to an intermediate variable. +func Ptr[T any](v T) *T { + return &v +} + +func (cfg *DoltgresConfig) AutoCommit() bool { + return true +} + +func (cfg *DoltgresConfig) DoltTransactionCommit() bool { + if cfg.BehaviorConfig == nil || cfg.BehaviorConfig.DoltTransactionCommit == nil { + return false + } + + return *cfg.BehaviorConfig.DoltTransactionCommit +} + +func (cfg *DoltgresConfig) DataDir() string { + if cfg.DataDirStr == nil { + return "" + } + + return *cfg.DataDirStr +} + +func (cfg *DoltgresConfig) CfgDir() string { + if cfg.CfgDirStr == nil { + return "" + } + + return *cfg.CfgDirStr +} + +func (cfg *DoltgresConfig) Host() string { + if cfg.ListenerConfig == nil || cfg.ListenerConfig.HostStr == nil { + return "localhost" + } + + return *cfg.ListenerConfig.HostStr +} + +func (cfg *DoltgresConfig) Port() int { + if cfg.ListenerConfig == nil || cfg.ListenerConfig.PortNumber == nil { + return 5432 + } + + return *cfg.ListenerConfig.PortNumber +} + +func (cfg *DoltgresConfig) User() string { + if cfg.UserConfig == nil || cfg.UserConfig.Name == nil { + return "postgres" + } + + return *cfg.UserConfig.Name +} + +func (cfg *DoltgresConfig) UserIsSpecified() bool { + return cfg.UserConfig != nil && cfg.UserConfig.Name != nil +} + +func (cfg *DoltgresConfig) Password() string { + if cfg.UserConfig == nil || cfg.UserConfig.Password == nil { + return "password" + } + + return *cfg.UserConfig.Password +} + +func (cfg *DoltgresConfig) ReadTimeout() uint64 { + if cfg.ListenerConfig == nil || cfg.ListenerConfig.ReadTimeoutMillis == nil { + return 0 + } + + return *cfg.ListenerConfig.ReadTimeoutMillis +} + +func (cfg *DoltgresConfig) WriteTimeout() uint64 { + if cfg.ListenerConfig == nil || cfg.ListenerConfig.WriteTimeoutMillis == nil { + return 0 + } + + return *cfg.ListenerConfig.WriteTimeoutMillis +} + +func (cfg *DoltgresConfig) ReadOnly() bool { + if cfg.BehaviorConfig == nil || cfg.BehaviorConfig.ReadOnly == nil { + return false + } + + return *cfg.BehaviorConfig.ReadOnly +} + +func (cfg *DoltgresConfig) LogLevel() doltservercfg.LogLevel { + if cfg.LogLevelStr == nil { + return doltservercfg.LogLevel_Info + } + + switch *cfg.LogLevelStr { + case LogLevel_Trace: + return doltservercfg.LogLevel_Trace + case LogLevel_Debug: + return doltservercfg.LogLevel_Debug + case LogLevel_Info: + return doltservercfg.LogLevel_Info + case LogLevel_Warning: + return doltservercfg.LogLevel_Warning + case LogLevel_Error: + return doltservercfg.LogLevel_Error + case LogLevel_Fatal: + return doltservercfg.LogLevel_Fatal + case LogLevel_Panic: + return doltservercfg.LogLevel_Panic + default: + return doltservercfg.LogLevel_Info + } +} + +func (cfg *DoltgresConfig) LogFormat() doltservercfg.LogFormat { + return doltservercfg.LogFormat_Text +} + +func (cfg *DoltgresConfig) MaxConnections() uint64 { + return 0 +} + +func (cfg *DoltgresConfig) MaxWaitConnections() uint32 { + return 0 +} + +func (cfg *DoltgresConfig) MaxWaitConnectionsTimeout() time.Duration { + return 0 +} + +func (cfg *DoltgresConfig) CACert() string { + // TODO: add support for specifying a CA server and configuration TLS for client cert authentication + return "" +} + +func (cfg *DoltgresConfig) TLSKey() string { + if cfg.ListenerConfig == nil || cfg.ListenerConfig.TLSKey == nil { + return "" + } + + return *cfg.ListenerConfig.TLSKey +} + +func (cfg *DoltgresConfig) TLSCert() string { + if cfg.ListenerConfig == nil || cfg.ListenerConfig.TLSCert == nil { + return "" + } + + return *cfg.ListenerConfig.TLSCert +} + +func (cfg *DoltgresConfig) RequireSecureTransport() bool { + if cfg.ListenerConfig == nil || cfg.ListenerConfig.RequireSecureTransport == nil { + return false + } + + return *cfg.ListenerConfig.RequireSecureTransport +} + +func (cfg *DoltgresConfig) RequireClientCert() bool { + // TODO: add support for verifying client certs + return false +} + +func (cfg *DoltgresConfig) MaxLoggedQueryLen() int { + if cfg.MaxLenInLogs == nil { + return 1000 + } + + return *cfg.MaxLenInLogs +} + +func (cfg *DoltgresConfig) ShouldEncodeLoggedQuery() bool { + if cfg.EncodeLoggedQuery == nil { + return false + } + + return *cfg.EncodeLoggedQuery +} + +func (cfg *DoltgresConfig) DisableClientMultiStatements() bool { + if cfg.BehaviorConfig == nil || cfg.BehaviorConfig.DisableClientMultiStatements == nil { + return false + } + + return *cfg.BehaviorConfig.DisableClientMultiStatements +} + +func (cfg *DoltgresConfig) MetricsLabels() map[string]string { + if cfg.MetricsConfig == nil { + return nil + } + + return cfg.MetricsConfig.Labels +} + +func (cfg *DoltgresConfig) MetricsHost() string { + if cfg.MetricsConfig == nil || cfg.MetricsConfig.Host == nil { + return "" + } + + return *cfg.MetricsConfig.Host +} + +func (cfg *DoltgresConfig) MetricsPort() int { + if cfg.MetricsConfig == nil || cfg.MetricsConfig.Port == nil { + return 0 + } + + return *cfg.MetricsConfig.Port +} + +func (cfg *DoltgresConfig) MetricsTLSCert() string { + if cfg.MetricsConfig.TlsCert == nil { + return "" + } + + return *cfg.MetricsConfig.TlsCert +} + +func (cfg *DoltgresConfig) MetricsTLSKey() string { + if cfg.MetricsConfig.TlsKey == nil { + return "" + } + return *cfg.MetricsConfig.TlsKey +} + +func (cfg *DoltgresConfig) MetricsTLSCA() string { + if cfg.MetricsConfig.TlsCa == nil { + return "" + } + return *cfg.MetricsConfig.TlsCa +} + +func (cfg *DoltgresConfig) MetricsJwksConfig() *doltservercfg.JwksConfig { + return nil +} + +func (cfg *DoltgresConfig) MetricsJWTRequiredForLocalhost() bool { + return false +} + +func (cfg *DoltgresConfig) PrivilegeFilePath() string { + if cfg.PrivilegeFile == nil { + return "" + } + + return *cfg.PrivilegeFile +} + +func (cfg *DoltgresConfig) AuthFilePath() string { + if cfg.AuthFile == nil { + return "" + } + return *cfg.AuthFile +} + +func (cfg *DoltgresConfig) BranchControlFilePath() string { + if cfg.BranchControlFile == nil { + return "" + } + + return *cfg.BranchControlFile +} + +func (cfg *DoltgresConfig) UserVars() []doltservercfg.UserSessionVars { + var userVars []doltservercfg.UserSessionVars + for _, uv := range cfg.Vars { + userVars = append(userVars, doltservercfg.UserSessionVars{ + Name: uv.Name, + Vars: uv.Vars, + }) + } + + return userVars +} + +func (cfg *DoltgresConfig) SystemVars() map[string]interface{} { + if cfg.SystemVariables == nil { + return map[string]interface{}{} + } + + return cfg.SystemVariables +} + +func (cfg *DoltgresConfig) JwksConfig() []doltservercfg.JwksConfig { + return cfg.Jwks +} + +func (cfg *DoltgresConfig) AllowCleartextPasswords() bool { + if cfg.ListenerConfig == nil || cfg.ListenerConfig.AllowCleartextPasswords == nil { + return false + } + + return *cfg.ListenerConfig.AllowCleartextPasswords +} + +func (cfg *DoltgresConfig) Socket() string { + if cfg.ListenerConfig == nil || cfg.ListenerConfig.Socket == nil { + return "" + } + + return *cfg.ListenerConfig.Socket +} + +func (cfg *DoltgresConfig) RemotesapiPort() *int { + if cfg.RemotesapiConfig == nil { + return nil + } + + return cfg.RemotesapiConfig.Port +} + +func (cfg *DoltgresConfig) RemotesapiReadOnly() *bool { + if cfg.RemotesapiConfig == nil { + return nil + } + + return cfg.RemotesapiConfig.ReadOnly +} + +// MCPPort returns nil for Doltgres; MCP HTTP server is not configured here. +func (cfg *DoltgresConfig) MCPPort() *int { return nil } + +// MCPUser returns nil for Doltgres; MCP is not configured here. +func (cfg *DoltgresConfig) MCPUser() *string { return nil } + +// MCPPassword returns nil for Doltgres; MCP is not configured here. +func (cfg *DoltgresConfig) MCPPassword() *string { return nil } + +// MCPDatabase returns nil for Doltgres; MCP is not configured here. +func (cfg *DoltgresConfig) MCPDatabase() *string { return nil } + +func (cfg *DoltgresConfig) ClusterConfig() doltservercfg.ClusterConfig { + return nil +} + +func (cfg *DoltgresConfig) EventSchedulerStatus() string { + return "OFF" +} + +func (cfg *DoltgresConfig) AutoGCBehavior() doltservercfg.AutoGCBehavior { + return DoltgresAutoGCBehavior{} +} + +func (cfg *DoltgresConfig) BranchActivityTracking() bool { + // TODO In Dolt we require branch activity tracking to be configurable because it does incur a performance cost. + // We could make this configurable in Doltgres as well if we need to shave a couple percent off performance. + return true +} + +func (cfg *DoltgresConfig) ValueSet(value string) bool { + switch value { + case readTimeoutKey: + return cfg.ListenerConfig != nil && cfg.ListenerConfig.ReadTimeoutMillis != nil + case writeTimeoutKey: + return cfg.ListenerConfig != nil && cfg.ListenerConfig.WriteTimeoutMillis != nil + case maxConnectionsKey: + return false + case eventSchedulerKey: + return false + } + + return false +} + +func (*DoltgresConfig) Overrides() sql.EngineOverrides { + panic("Calling Overrides() on the internal DoltgresConfig should not be possible") +} + +func (cfg *DoltgresConfig) String() string { + data, err := yaml.Marshal(cfg) + + if err != nil { + return "Failed to marshal as yaml: " + err.Error() + } + + unformatted := string(data) + + // format the yaml to be easier to read. + lines := strings.Split(unformatted, "\n") + + var formatted []string + formatted = append(formatted, lines[0]) + for i := 1; i < len(lines); i++ { + if len(lines[i]) == 0 { + continue + } + + r, _ := utf8.DecodeRuneInString(lines[i]) + if !unicode.IsSpace(r) { + formatted = append(formatted, "") + } + + formatted = append(formatted, lines[i]) + } + + result := strings.Join(formatted, "\n") + return result +} + +// InternalDefaultServerConfig should not be called directly. Use `servercfg.DefaultServerConfig` instead. +func InternalDefaultServerConfig() *DoltgresConfig { + dataDir := "." + homeDir, err := env.GetCurrentUserHomeDir() + if err == nil { + dataDir = filepath.Join(homeDir, DOLTGRES_DATA_DIR_DEFAULT) + } + + return &DoltgresConfig{ + LogLevelStr: Ptr(string(DefaultLogLevel)), + EncodeLoggedQuery: Ptr(DefaultEncodeLoggedQuery), + BehaviorConfig: &DoltgresBehaviorConfig{ + ReadOnly: Ptr(DefaultReadOnly), + DoltTransactionCommit: Ptr(DefaultDoltTransactionCommit), + }, + UserConfig: &DoltgresUserConfig{ + Name: Ptr(DefaultUser), + Password: Ptr(DefaultPass), + }, + ListenerConfig: &DoltgresListenerConfig{ + HostStr: Ptr(DefaultHost), + PortNumber: Ptr(DefaultPort), + ReadTimeoutMillis: Ptr(uint64(DefaultTimeout)), + WriteTimeoutMillis: Ptr(uint64(DefaultTimeout)), + AllowCleartextPasswords: Ptr(DefaultAllowCleartextPasswords), + }, + + DataDirStr: Ptr(dataDir), + CfgDirStr: Ptr(filepath.Join(DefaultDataDir, DefaultCfgDir)), + PrivilegeFile: Ptr(filepath.Join(DefaultDataDir, DefaultCfgDir, DefaultPrivilegeFilePath)), + AuthFile: Ptr(filepath.Join(DefaultDataDir, DefaultCfgDir, DefaultAuthFilePath)), + BranchControlFile: Ptr(filepath.Join(DefaultDataDir, DefaultCfgDir, DefaultBranchControlFilePath)), + } +} diff --git a/servercfg/minver_test.go b/servercfg/cfgdetails/minver_test.go similarity index 98% rename from servercfg/minver_test.go rename to servercfg/cfgdetails/minver_test.go index 8251034507..3b1e78a888 100644 --- a/servercfg/minver_test.go +++ b/servercfg/cfgdetails/minver_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package servercfg +package cfgdetails import ( "testing" diff --git a/servercfg/testdata/minver_validation.txt b/servercfg/cfgdetails/testdata/minver_validation.txt similarity index 79% rename from servercfg/testdata/minver_validation.txt rename to servercfg/cfgdetails/testdata/minver_validation.txt index ea1b1c2be3..711bc1e78e 100644 --- a/servercfg/testdata/minver_validation.txt +++ b/servercfg/cfgdetails/testdata/minver_validation.txt @@ -4,14 +4,14 @@ LogLevelStr *string 0.7.4 log_level,omitempty MaxLenInLogs *int 0.7.4 max_query_len_in_logs,omitempty EncodeLoggedQuery *bool 0.7.4 encode_logged_query,omitempty -BehaviorConfig *servercfg.DoltgresBehaviorConfig 0.7.4 behavior,omitempty +BehaviorConfig *cfgdetails.DoltgresBehaviorConfig 0.7.4 behavior,omitempty -ReadOnly *bool 0.7.4 read_only,omitempty -DisableClientMultiStatements *bool 0.7.4 disable_client_multi_statements,omitempty -DoltTransactionCommit *bool 0.7.4 dolt_transaction_commit,omitempty -UserConfig *servercfg.DoltgresUserConfig 0.7.4 user,omitempty +UserConfig *cfgdetails.DoltgresUserConfig 0.7.4 user,omitempty -Name *string 0.7.4 name,omitempty -Password *string 0.7.4 password,omitempty -ListenerConfig *servercfg.DoltgresListenerConfig 0.7.4 listener,omitempty +ListenerConfig *cfgdetails.DoltgresListenerConfig 0.7.4 listener,omitempty -HostStr *string 0.7.4 host,omitempty -PortNumber *int 0.7.4 port,omitempty -ReadTimeoutMillis *uint64 0.7.4 read_timeout_millis,omitempty @@ -21,24 +21,24 @@ ListenerConfig *servercfg.DoltgresListenerConfig 0.7.4 listener,omitempty -RequireSecureTransport *bool 0.7.4 require_secure_transport,omitempty -AllowCleartextPasswords *bool 0.7.4 allow_cleartext_passwords,omitempty -Socket *string 0.7.4 socket,omitempty -PerformanceConfig *servercfg.DoltgresPerformanceConfig 0.7.4 performance,omitempty +PerformanceConfig *cfgdetails.DoltgresPerformanceConfig 0.7.4 performance,omitempty -QueryParallelism *int 0.7.4 query_parallelism,omitempty DataDirStr *string 0.7.4 data_dir,omitempty CfgDirStr *string 0.7.4 cfg_dir,omitempty -MetricsConfig *servercfg.DoltgesMetricsConfig 0.7.4 metrics,omitempty +MetricsConfig *cfgdetails.DoltgesMetricsConfig 0.7.4 metrics,omitempty -Labels map[string]string 0.7.4 labels,omitempty -Host *string 0.7.4 host,omitempty -Port *int 0.7.4 port,omitempty -TlsCert *string 0.53.5 tls_cert,omitempty -TlsKey *string 0.53.5 tls_key,omitempty -TlsCa *string 0.53.5 tls_ca,omitempty -RemotesapiConfig *servercfg.DoltgresRemotesapiConfig 0.7.4 remotesapi,omitempty +RemotesapiConfig *cfgdetails.DoltgresRemotesapiConfig 0.7.4 remotesapi,omitempty -Port *int 0.7.4 port,omitempty -ReadOnly *bool 0.7.4 read_only,omitempty PrivilegeFile *string 0.7.4 privilege_file,omitempty AuthFile *string 0.54.4 auth_file,omitempty BranchControlFile *string 0.7.4 branch_control_file,omitempty -Vars []servercfg.DoltgresUserSessionVars 0.7.4 user_session_vars,omitempty +Vars []cfgdetails.DoltgresUserSessionVars 0.7.4 user_session_vars,omitempty -Name string 0.0.0 name -Vars map[string]interface{} 0.0.0 vars,omitempty SystemVariables map[string]interface{} 0.7.4 system_variables,omitempty @@ -48,7 +48,7 @@ Jwks []servercfg.JwksConfig 0.7.4 jwks,omitempty -Claims map[string]string 0.0.0 claims -FieldsToLog []string 0.0.0 fields_to_log GoldenMysqlConn *string 0.7.4 golden_mysql_conn,omitempty -PostgresReplicationConfig *servercfg.PostgresReplicationConfig 0.7.4 postgres_replication,omitempty +PostgresReplicationConfig *cfgdetails.PostgresReplicationConfig 0.7.4 postgres_replication,omitempty -PostgresServerAddress *string 0.7.4 postgres_server_address,omitempty -PostgresUser *string 0.7.4 postgres_user,omitempty -PostgresPassword *string 0.7.4 postgres_password,omitempty diff --git a/servercfg/config.go b/servercfg/config.go index cf55f78ee0..d4763f8453 100755 --- a/servercfg/config.go +++ b/servercfg/config.go @@ -1,4 +1,4 @@ -// Copyright 2024 Dolthub, Inc. +// Copyright 2025 Dolthub, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,556 +15,29 @@ package servercfg import ( - "path/filepath" - "strings" - "time" - "unicode" - "unicode/utf8" - "github.com/cockroachdb/errors" - "github.com/dolthub/dolt/go/libraries/doltcore/env" - "github.com/dolthub/dolt/go/libraries/doltcore/servercfg" + doltservercfg "github.com/dolthub/dolt/go/libraries/doltcore/servercfg" "github.com/dolthub/dolt/go/libraries/utils/filesys" "github.com/dolthub/go-mysql-server/sql" "gopkg.in/yaml.v2" pgsql "github.com/dolthub/doltgresql/postgres/parser/parser/sql" "github.com/dolthub/doltgresql/server/expression" + "github.com/dolthub/doltgresql/servercfg/cfgdetails" ) -const ( - maxConnectionsKey = "max_connections" - readTimeoutKey = "net_read_timeout" - writeTimeoutKey = "net_write_timeout" - eventSchedulerKey = "event_scheduler" - - OverrideDataDirKey = "data_dir" -) - -const ( - LogLevel_Trace = "trace" - LogLevel_Debug = "debug" - LogLevel_Info = "info" - LogLevel_Warning = "warn" - LogLevel_Error = "error" - LogLevel_Fatal = "fatal" - LogLevel_Panic = "panic" -) - -const ( - DefaultHost = "localhost" - DefaultPort = 5432 - DefaultUser = "postgres" - DefaultPass = "password" - DefaultTimeout = 8 * 60 * 60 * 1000 // 8 hours, same as MySQL - DefaultReadOnly = false - DefaultLogLevel = LogLevel_Info - DefaultDoltTransactionCommit = false - DefaultMaxConnections = 100 - DefaultDataDir = "." - DefaultCfgDir = ".doltcfg" - DefaultPrivilegeFilePath = "privileges.db" - DefaultAuthFilePath = "auth.db" - DefaultBranchControlFilePath = "branch_control.db" - DefaultMetricsHost = "" - DefaultMetricsPort = -1 - DefaultAllowCleartextPasswords = false - DefaultPostgresUnixSocketFilePath = "/tmp/.s.PGSQL.5432" - DefaultMaxLoggedQueryLen = 0 - DefaultEncodeLoggedQuery = false -) - -// DOLTGRES_DATA_DIR is an environment variable that defines the location of DoltgreSQL databases -const DOLTGRES_DATA_DIR = "DOLTGRES_DATA_DIR" - -// DOLTGRES_DATA_DIR_DEFAULT is the portion to append to the user's home directory if DOLTGRES_DATA_DIR has not been specified -const DOLTGRES_DATA_DIR_DEFAULT = "doltgres/databases" - var ConfigHelp = "Supported fields in the config.yaml file, and their default values, " + "are as follows:\n\n" + DefaultServerConfig().String() -type PostgresReplicationConfig struct { - PostgresServerAddress *string `yaml:"postgres_server_address,omitempty" minver:"0.7.4"` - PostgresUser *string `yaml:"postgres_user,omitempty" minver:"0.7.4"` - PostgresPassword *string `yaml:"postgres_password,omitempty" minver:"0.7.4"` - PostgresDatabase *string `yaml:"postgres_database,omitempty" minver:"0.7.4"` - PostgresPort *int `yaml:"postgres_port,omitempty" minver:"0.7.4"` - SlotName *string `yaml:"slot_name,omitempty" minver:"0.7.4"` -} - -// BehaviorYAMLConfig contains server configuration regarding how the server should behave -type DoltgresBehaviorConfig struct { - ReadOnly *bool `yaml:"read_only,omitempty" minver:"0.7.4"` - // Disable processing CLIENT_MULTI_STATEMENTS support on the - // sql server. Dolt's handling of CLIENT_MULTI_STATEMENTS is currently - // broken. If a client advertises to support it (mysql cli client - // does), and then sends statements that contain embedded unquoted ';'s - // (such as a CREATE TRIGGER), then those incoming queries will be - // misprocessed. - DisableClientMultiStatements *bool `yaml:"disable_client_multi_statements,omitempty" minver:"0.7.4"` - // DoltTransactionCommit enables the @@dolt_transaction_commit system variable, which - // automatically creates a Dolt commit when any SQL transaction is committed. - DoltTransactionCommit *bool `yaml:"dolt_transaction_commit,omitempty" minver:"0.7.4"` -} - -// Implements dolt servercfg.AutoGCBehavior. -type DoltgresAutoGCBehavior struct { -} - -func (DoltgresAutoGCBehavior) Enable() bool { - return false -} - -func (DoltgresAutoGCBehavior) ArchiveLevel() int { - return 0 -} - -type DoltgresUserConfig struct { - Name *string `yaml:"name,omitempty" minver:"0.7.4"` - Password *string `yaml:"password,omitempty" minver:"0.7.4"` -} - -// DoltgresListenerConfig contains information on the network connection that the server will open -type DoltgresListenerConfig struct { - HostStr *string `yaml:"host,omitempty" minver:"0.7.4"` - PortNumber *int `yaml:"port,omitempty" minver:"0.7.4"` - ReadTimeoutMillis *uint64 `yaml:"read_timeout_millis,omitempty" minver:"0.7.4"` - WriteTimeoutMillis *uint64 `yaml:"write_timeout_millis,omitempty" minver:"0.7.4"` - // TLSKey is a file system path to an unencrypted private TLS key in PEM format. - TLSKey *string `yaml:"tls_key,omitempty" minver:"0.7.4"` - // TLSCert is a file system path to a TLS certificate chain in PEM format. - TLSCert *string `yaml:"tls_cert,omitempty" minver:"0.7.4"` - // RequireSecureTransport can enable a mode where non-TLS connections are turned away. - RequireSecureTransport *bool `yaml:"require_secure_transport,omitempty" minver:"0.7.4"` - // AllowCleartextPasswords enables use of cleartext passwords. - AllowCleartextPasswords *bool `yaml:"allow_cleartext_passwords,omitempty" minver:"0.7.4"` - // Socket is unix socket file path - Socket *string `yaml:"socket,omitempty" minver:"0.7.4"` -} - -// DoltgresPerformanceConfig contains configuration parameters for performance tweaking -type DoltgresPerformanceConfig struct { - QueryParallelism *int `yaml:"query_parallelism,omitempty" minver:"0.7.4"` -} - -type DoltgesMetricsConfig struct { - Labels map[string]string `yaml:"labels,omitempty" minver:"0.7.4"` - Host *string `yaml:"host,omitempty" minver:"0.7.4"` - Port *int `yaml:"port,omitempty" minver:"0.7.4"` - TlsCert *string `yaml:"tls_cert,omitempty" minver:"0.53.5"` - TlsKey *string `yaml:"tls_key,omitempty" minver:"0.53.5"` - TlsCa *string `yaml:"tls_ca,omitempty" minver:"0.53.5"` -} - -type DoltgresRemotesapiConfig struct { - Port *int `yaml:"port,omitempty" minver:"0.7.4"` - ReadOnly *bool `yaml:"read_only,omitempty" minver:"0.7.4"` -} - -type DoltgresUserSessionVars struct { - Name string `yaml:"name"` - Vars map[string]interface{} `yaml:"vars,omitempty"` -} - +// DoltgresConfig is the configuration file for Doltgres. type DoltgresConfig struct { - LogLevelStr *string `yaml:"log_level,omitempty" minver:"0.7.4"` - MaxLenInLogs *int `yaml:"max_query_len_in_logs,omitempty" minver:"0.7.4"` - EncodeLoggedQuery *bool `yaml:"encode_logged_query,omitempty" minver:"0.7.4"` - BehaviorConfig *DoltgresBehaviorConfig `yaml:"behavior,omitempty" minver:"0.7.4"` - UserConfig *DoltgresUserConfig `yaml:"user,omitempty" minver:"0.7.4"` - ListenerConfig *DoltgresListenerConfig `yaml:"listener,omitempty" minver:"0.7.4"` - PerformanceConfig *DoltgresPerformanceConfig `yaml:"performance,omitempty" minver:"0.7.4"` - DataDirStr *string `yaml:"data_dir,omitempty" minver:"0.7.4"` - CfgDirStr *string `yaml:"cfg_dir,omitempty" minver:"0.7.4"` - MetricsConfig *DoltgesMetricsConfig `yaml:"metrics,omitempty" minver:"0.7.4"` - RemotesapiConfig *DoltgresRemotesapiConfig `yaml:"remotesapi,omitempty" minver:"0.7.4"` - PrivilegeFile *string `yaml:"privilege_file,omitempty" minver:"0.7.4"` - AuthFile *string `yaml:"auth_file,omitempty" minver:"0.54.4"` - BranchControlFile *string `yaml:"branch_control_file,omitempty" minver:"0.7.4"` - - // TODO: Rename to UserVars_ - Vars []DoltgresUserSessionVars `yaml:"user_session_vars,omitempty" minver:"0.7.4"` - SystemVariables map[string]interface{} `yaml:"system_variables,omitempty" minver:"0.7.4"` - Jwks []servercfg.JwksConfig `yaml:"jwks,omitempty" minver:"0.7.4"` - GoldenMysqlConn *string `yaml:"golden_mysql_conn,omitempty" minver:"0.7.4"` - - PostgresReplicationConfig *PostgresReplicationConfig `yaml:"postgres_replication,omitempty" minver:"0.7.4"` -} - -var _ servercfg.ServerConfig = (*DoltgresConfig)(nil) - -// Ptr is a helper function that returns a pointer to the value passed in. This is necessary to e.g. get a pointer to -// a const value without assigning to an intermediate variable. -func Ptr[T any](v T) *T { - return &v -} - -func (cfg *DoltgresConfig) AutoCommit() bool { - return true -} - -func (cfg *DoltgresConfig) DoltTransactionCommit() bool { - if cfg.BehaviorConfig == nil || cfg.BehaviorConfig.DoltTransactionCommit == nil { - return false - } - - return *cfg.BehaviorConfig.DoltTransactionCommit -} - -func (cfg *DoltgresConfig) DataDir() string { - if cfg.DataDirStr == nil { - return "" - } - - return *cfg.DataDirStr -} - -func (cfg *DoltgresConfig) CfgDir() string { - if cfg.CfgDirStr == nil { - return "" - } - - return *cfg.CfgDirStr -} - -func (cfg *DoltgresConfig) Host() string { - if cfg.ListenerConfig == nil || cfg.ListenerConfig.HostStr == nil { - return "localhost" - } - - return *cfg.ListenerConfig.HostStr -} - -func (cfg *DoltgresConfig) Port() int { - if cfg.ListenerConfig == nil || cfg.ListenerConfig.PortNumber == nil { - return 5432 - } - - return *cfg.ListenerConfig.PortNumber -} - -func (cfg *DoltgresConfig) User() string { - if cfg.UserConfig == nil || cfg.UserConfig.Name == nil { - return "postgres" - } - - return *cfg.UserConfig.Name -} - -func (cfg *DoltgresConfig) UserIsSpecified() bool { - return cfg.UserConfig != nil && cfg.UserConfig.Name != nil -} - -func (cfg *DoltgresConfig) Password() string { - if cfg.UserConfig == nil || cfg.UserConfig.Password == nil { - return "password" - } - - return *cfg.UserConfig.Password -} - -func (cfg *DoltgresConfig) ReadTimeout() uint64 { - if cfg.ListenerConfig == nil || cfg.ListenerConfig.ReadTimeoutMillis == nil { - return 0 - } - - return *cfg.ListenerConfig.ReadTimeoutMillis -} - -func (cfg *DoltgresConfig) WriteTimeout() uint64 { - if cfg.ListenerConfig == nil || cfg.ListenerConfig.WriteTimeoutMillis == nil { - return 0 - } - - return *cfg.ListenerConfig.WriteTimeoutMillis -} - -func (cfg *DoltgresConfig) ReadOnly() bool { - if cfg.BehaviorConfig == nil || cfg.BehaviorConfig.ReadOnly == nil { - return false - } - - return *cfg.BehaviorConfig.ReadOnly -} - -func (cfg *DoltgresConfig) LogLevel() servercfg.LogLevel { - if cfg.LogLevelStr == nil { - return servercfg.LogLevel_Info - } - - switch *cfg.LogLevelStr { - case LogLevel_Trace: - return servercfg.LogLevel_Trace - case LogLevel_Debug: - return servercfg.LogLevel_Debug - case LogLevel_Info: - return servercfg.LogLevel_Info - case LogLevel_Warning: - return servercfg.LogLevel_Warning - case LogLevel_Error: - return servercfg.LogLevel_Error - case LogLevel_Fatal: - return servercfg.LogLevel_Fatal - case LogLevel_Panic: - return servercfg.LogLevel_Panic - default: - return servercfg.LogLevel_Info - } -} - -func (cfg *DoltgresConfig) LogFormat() servercfg.LogFormat { - return servercfg.LogFormat_Text -} - -func (cfg *DoltgresConfig) MaxConnections() uint64 { - return 0 -} - -func (cfg *DoltgresConfig) MaxWaitConnections() uint32 { - return 0 -} - -func (cfg *DoltgresConfig) MaxWaitConnectionsTimeout() time.Duration { - return 0 -} - -func (cfg *DoltgresConfig) CACert() string { - // TODO: add support for specifying a CA server and configuration TLS for client cert authentication - return "" -} - -func (cfg *DoltgresConfig) TLSKey() string { - if cfg.ListenerConfig == nil || cfg.ListenerConfig.TLSKey == nil { - return "" - } - - return *cfg.ListenerConfig.TLSKey -} - -func (cfg *DoltgresConfig) TLSCert() string { - if cfg.ListenerConfig == nil || cfg.ListenerConfig.TLSCert == nil { - return "" - } - - return *cfg.ListenerConfig.TLSCert -} - -func (cfg *DoltgresConfig) RequireSecureTransport() bool { - if cfg.ListenerConfig == nil || cfg.ListenerConfig.RequireSecureTransport == nil { - return false - } - - return *cfg.ListenerConfig.RequireSecureTransport + cfgdetails.DoltgresConfig } -func (cfg *DoltgresConfig) RequireClientCert() bool { - // TODO: add support for verifying client certs - return false -} +var _ doltservercfg.ServerConfig = (*DoltgresConfig)(nil) -func (cfg *DoltgresConfig) MaxLoggedQueryLen() int { - if cfg.MaxLenInLogs == nil { - return 1000 - } - - return *cfg.MaxLenInLogs -} - -func (cfg *DoltgresConfig) ShouldEncodeLoggedQuery() bool { - if cfg.EncodeLoggedQuery == nil { - return false - } - - return *cfg.EncodeLoggedQuery -} - -func (cfg *DoltgresConfig) DisableClientMultiStatements() bool { - if cfg.BehaviorConfig == nil || cfg.BehaviorConfig.DisableClientMultiStatements == nil { - return false - } - - return *cfg.BehaviorConfig.DisableClientMultiStatements -} - -func (cfg *DoltgresConfig) MetricsLabels() map[string]string { - if cfg.MetricsConfig == nil { - return nil - } - - return cfg.MetricsConfig.Labels -} - -func (cfg *DoltgresConfig) MetricsHost() string { - if cfg.MetricsConfig == nil || cfg.MetricsConfig.Host == nil { - return "" - } - - return *cfg.MetricsConfig.Host -} - -func (cfg *DoltgresConfig) MetricsPort() int { - if cfg.MetricsConfig == nil || cfg.MetricsConfig.Port == nil { - return 0 - } - - return *cfg.MetricsConfig.Port -} - -func (cfg *DoltgresConfig) MetricsTLSCert() string { - if cfg.MetricsConfig.TlsCert == nil { - return "" - } - - return *cfg.MetricsConfig.TlsCert -} - -func (cfg *DoltgresConfig) MetricsTLSKey() string { - if cfg.MetricsConfig.TlsKey == nil { - return "" - } - return *cfg.MetricsConfig.TlsKey -} - -func (cfg *DoltgresConfig) MetricsTLSCA() string { - if cfg.MetricsConfig.TlsCa == nil { - return "" - } - return *cfg.MetricsConfig.TlsCa -} - -func (cfg *DoltgresConfig) MetricsJwksConfig() *servercfg.JwksConfig { - return nil -} - -func (cfg *DoltgresConfig) MetricsJWTRequiredForLocalhost() bool { - return false -} - -func (cfg *DoltgresConfig) PrivilegeFilePath() string { - if cfg.PrivilegeFile == nil { - return "" - } - - return *cfg.PrivilegeFile -} - -func (cfg *DoltgresConfig) AuthFilePath() string { - if cfg.AuthFile == nil { - return "" - } - return *cfg.AuthFile -} - -func (cfg *DoltgresConfig) BranchControlFilePath() string { - if cfg.BranchControlFile == nil { - return "" - } - - return *cfg.BranchControlFile -} - -func (cfg *DoltgresConfig) UserVars() []servercfg.UserSessionVars { - var userVars []servercfg.UserSessionVars - for _, uv := range cfg.Vars { - userVars = append(userVars, servercfg.UserSessionVars{ - Name: uv.Name, - Vars: uv.Vars, - }) - } - - return userVars -} - -func (cfg *DoltgresConfig) SystemVars() map[string]interface{} { - if cfg.SystemVariables == nil { - return map[string]interface{}{} - } - - return cfg.SystemVariables -} - -func (cfg *DoltgresConfig) JwksConfig() []servercfg.JwksConfig { - return cfg.Jwks -} - -func (cfg *DoltgresConfig) AllowCleartextPasswords() bool { - if cfg.ListenerConfig == nil || cfg.ListenerConfig.AllowCleartextPasswords == nil { - return false - } - - return *cfg.ListenerConfig.AllowCleartextPasswords -} - -func (cfg *DoltgresConfig) Socket() string { - if cfg.ListenerConfig == nil || cfg.ListenerConfig.Socket == nil { - return "" - } - - return *cfg.ListenerConfig.Socket -} - -func (cfg *DoltgresConfig) RemotesapiPort() *int { - if cfg.RemotesapiConfig == nil { - return nil - } - - return cfg.RemotesapiConfig.Port -} - -func (cfg *DoltgresConfig) RemotesapiReadOnly() *bool { - if cfg.RemotesapiConfig == nil { - return nil - } - - return cfg.RemotesapiConfig.ReadOnly -} - -// MCPPort returns nil for Doltgres; MCP HTTP server is not configured here. -func (cfg *DoltgresConfig) MCPPort() *int { return nil } - -// MCPUser returns nil for Doltgres; MCP is not configured here. -func (cfg *DoltgresConfig) MCPUser() *string { return nil } - -// MCPPassword returns nil for Doltgres; MCP is not configured here. -func (cfg *DoltgresConfig) MCPPassword() *string { return nil } - -// MCPDatabase returns nil for Doltgres; MCP is not configured here. -func (cfg *DoltgresConfig) MCPDatabase() *string { return nil } - -func (cfg *DoltgresConfig) ClusterConfig() servercfg.ClusterConfig { - return nil -} - -func (cfg *DoltgresConfig) EventSchedulerStatus() string { - return "OFF" -} - -func (cfg *DoltgresConfig) AutoGCBehavior() servercfg.AutoGCBehavior { - return DoltgresAutoGCBehavior{} -} - -func (cfg *DoltgresConfig) BranchActivityTracking() bool { - // TODO In Dolt we require branch activity tracking to be configurable because it does incur a performance cost. - // We could make this configurable in Doltgres as well if we need to shave a couple percent off performance. - return true -} - -func (cfg *DoltgresConfig) ValueSet(value string) bool { - switch value { - case readTimeoutKey: - return cfg.ListenerConfig != nil && cfg.ListenerConfig.ReadTimeoutMillis != nil - case writeTimeoutKey: - return cfg.ListenerConfig != nil && cfg.ListenerConfig.WriteTimeoutMillis != nil - case maxConnectionsKey: - return false - case eventSchedulerKey: - return false - } - - return false -} - -func (cfg *DoltgresConfig) Overrides() sql.EngineOverrides { +// Overrides implements the interface doltservercfg.ServerConfig. +func (*DoltgresConfig) Overrides() sql.EngineOverrides { return sql.EngineOverrides{ Builder: sql.BuilderOverrides{ ParseTableAsColumn: expression.NewTableToComposite, @@ -574,46 +47,21 @@ func (cfg *DoltgresConfig) Overrides() sql.EngineOverrides { } } -func (cfg *DoltgresConfig) ToSqlServerConfig() servercfg.ServerConfig { +// ToSqlServerConfig returns this configuration struct as an implementation of the Dolt interface. +func (cfg *DoltgresConfig) ToSqlServerConfig() doltservercfg.ServerConfig { return cfg } -// DefaultServerConfig creates a `*DoltgresConfig` that has all of the options set to their default values. Used when -// no config.yaml file is provided. +// DefaultServerConfig creates a *DoltgresConfig that has all of the options set to their default values. Used when no +// config.yaml file is provided. func DefaultServerConfig() *DoltgresConfig { - dataDir := "." - homeDir, err := env.GetCurrentUserHomeDir() - if err == nil { - dataDir = filepath.Join(homeDir, DOLTGRES_DATA_DIR_DEFAULT) - } - - return &DoltgresConfig{ - LogLevelStr: Ptr(string(DefaultLogLevel)), - EncodeLoggedQuery: Ptr(DefaultEncodeLoggedQuery), - BehaviorConfig: &DoltgresBehaviorConfig{ - ReadOnly: Ptr(DefaultReadOnly), - DoltTransactionCommit: Ptr(DefaultDoltTransactionCommit), - }, - UserConfig: &DoltgresUserConfig{ - Name: Ptr(DefaultUser), - Password: Ptr(DefaultPass), - }, - ListenerConfig: &DoltgresListenerConfig{ - HostStr: Ptr(DefaultHost), - PortNumber: Ptr(DefaultPort), - ReadTimeoutMillis: Ptr(uint64(DefaultTimeout)), - WriteTimeoutMillis: Ptr(uint64(DefaultTimeout)), - AllowCleartextPasswords: Ptr(DefaultAllowCleartextPasswords), - }, - - DataDirStr: Ptr(dataDir), - CfgDirStr: Ptr(filepath.Join(DefaultDataDir, DefaultCfgDir)), - PrivilegeFile: Ptr(filepath.Join(DefaultDataDir, DefaultCfgDir, DefaultPrivilegeFilePath)), - AuthFile: Ptr(filepath.Join(DefaultDataDir, DefaultCfgDir, DefaultAuthFilePath)), - BranchControlFile: Ptr(filepath.Join(DefaultDataDir, DefaultCfgDir, DefaultBranchControlFilePath)), - } + internalCfg := cfgdetails.InternalDefaultServerConfig() + cfg := &DoltgresConfig{} + cfg.DoltgresConfig = *internalCfg + return cfg } +// ReadConfigFromYamlFile reads the given file from the file system at the specified path. func ReadConfigFromYamlFile(fs filesys.Filesys, configFilePath string) (*DoltgresConfig, error) { configFileData, err := fs.ReadFile(configFilePath) if err != nil { @@ -627,43 +75,14 @@ func ReadConfigFromYamlFile(fs filesys.Filesys, configFilePath string) (*Doltgre return ConfigFromYamlData(configFileData) } +// ConfigFromYamlData reads the configuration from the given file's bytes. func ConfigFromYamlData(configFileData []byte) (*DoltgresConfig, error) { - var cfg DoltgresConfig - err := yaml.UnmarshalStrict(configFileData, &cfg) + var internalCfg cfgdetails.DoltgresConfig + err := yaml.UnmarshalStrict(configFileData, &internalCfg) if err != nil { return nil, errors.Errorf("error unmarshalling config data: %w", err) } - - return &cfg, err -} - -func (cfg *DoltgresConfig) String() string { - data, err := yaml.Marshal(cfg) - - if err != nil { - return "Failed to marshal as yaml: " + err.Error() - } - - unformatted := string(data) - - // format the yaml to be easier to read. - lines := strings.Split(unformatted, "\n") - - var formatted []string - formatted = append(formatted, lines[0]) - for i := 1; i < len(lines); i++ { - if len(lines[i]) == 0 { - continue - } - - r, _ := utf8.DecodeRuneInString(lines[i]) - if !unicode.IsSpace(r) { - formatted = append(formatted, "") - } - - formatted = append(formatted, lines[i]) - } - - result := strings.Join(formatted, "\n") - return result + cfg := &DoltgresConfig{} + cfg.DoltgresConfig = internalCfg + return cfg, err } diff --git a/testing/generation/function_coverage/output/framework_test.go b/testing/generation/function_coverage/output/framework_test.go index e04e57a7b9..2992319708 100644 --- a/testing/generation/function_coverage/output/framework_test.go +++ b/testing/generation/function_coverage/output/framework_test.go @@ -35,6 +35,7 @@ import ( dserver "github.com/dolthub/doltgresql/server" "github.com/dolthub/doltgresql/servercfg" + "github.com/dolthub/doltgresql/servercfg/cfgdetails" "github.com/dolthub/doltgresql/utils" ) @@ -179,9 +180,11 @@ func CreateServer(t *testing.T, database string) (context.Context, *pgx.Conn, *s port, err := sql.GetEmptyPort() require.NoError(t, err) controller, err := dserver.RunInMemory(&servercfg.DoltgresConfig{ - ListenerConfig: &servercfg.DoltgresListenerConfig{ - PortNumber: &port, - HostStr: ptr("127.0.0.1"), + DoltgresConfig: cfgdetails.DoltgresConfig{ + ListenerConfig: &cfgdetails.DoltgresListenerConfig{ + PortNumber: &port, + HostStr: ptr("127.0.0.1"), + }, }, }, dserver.NewListener) require.NoError(t, err) diff --git a/testing/go/enginetest/doltgres_harness_test.go b/testing/go/enginetest/doltgres_harness_test.go index 46a7cb9772..1df39a140e 100644 --- a/testing/go/enginetest/doltgres_harness_test.go +++ b/testing/go/enginetest/doltgres_harness_test.go @@ -48,6 +48,7 @@ import ( "github.com/dolthub/doltgresql/server" "github.com/dolthub/doltgresql/servercfg" + "github.com/dolthub/doltgresql/servercfg/cfgdetails" ) type DoltgresHarness struct { @@ -611,9 +612,11 @@ const port = 5433 func NewDoltgresQueryEngine(t *testing.T, harness *DoltgresHarness) *DoltgresQueryEngine { ctrl, err := server.RunInMemory(&servercfg.DoltgresConfig{ - LogLevelStr: Ptr("debug"), - ListenerConfig: &servercfg.DoltgresListenerConfig{ - PortNumber: Ptr(port), + DoltgresConfig: cfgdetails.DoltgresConfig{ + LogLevelStr: Ptr("debug"), + ListenerConfig: &cfgdetails.DoltgresListenerConfig{ + PortNumber: Ptr(port), + }, }, }, server.NewListener) require.NoError(t, err) diff --git a/testing/go/framework.go b/testing/go/framework.go index 834c5a50ba..9b06605652 100644 --- a/testing/go/framework.go +++ b/testing/go/framework.go @@ -49,6 +49,7 @@ import ( "github.com/dolthub/doltgresql/server/functions" "github.com/dolthub/doltgresql/server/types" "github.com/dolthub/doltgresql/servercfg" + "github.com/dolthub/doltgresql/servercfg/cfgdetails" ) // runOnPostgres is a debug setting to redirect the test framework to a local running postgres server, @@ -388,11 +389,13 @@ func CreateServer(t *testing.T, database string) (context.Context, *Connection, func CreateServerWithPort(t *testing.T, database string, port int) (context.Context, *Connection, *svcs.Controller) { require.NotEmpty(t, database) controller, err := dserver.RunInMemory(&servercfg.DoltgresConfig{ - ListenerConfig: &servercfg.DoltgresListenerConfig{ - PortNumber: &port, - HostStr: &serverHost, + DoltgresConfig: cfgdetails.DoltgresConfig{ + ListenerConfig: &cfgdetails.DoltgresListenerConfig{ + PortNumber: &port, + HostStr: &serverHost, + }, + LogLevelStr: &testServerLogLevel, }, - LogLevelStr: &testServerLogLevel, }, dserver.NewListener) require.NoError(t, err) auth.ClearDatabase() @@ -420,11 +423,13 @@ func CreateServerLocalWithPort(t *testing.T, database string, port int) (context doltEnv := env.Load(ctx, env.GetCurrentUserHomeDir, fileSys, doltdb.LocalDirDoltDB, dserver.Version) controller, err := dserver.RunOnDisk(ctx, &servercfg.DoltgresConfig{ - ListenerConfig: &servercfg.DoltgresListenerConfig{ - PortNumber: &port, - HostStr: &serverHost, + DoltgresConfig: cfgdetails.DoltgresConfig{ + ListenerConfig: &cfgdetails.DoltgresListenerConfig{ + PortNumber: &port, + HostStr: &serverHost, + }, + LogLevelStr: &testServerLogLevel, }, - LogLevelStr: &testServerLogLevel, }, doltEnv) require.NoError(t, err) auth.ClearDatabase() diff --git a/testing/go/regression/tool/create_server.go b/testing/go/regression/tool/create_server.go index ddf245bd3b..cfd61973f5 100644 --- a/testing/go/regression/tool/create_server.go +++ b/testing/go/regression/tool/create_server.go @@ -25,6 +25,7 @@ import ( dserver "github.com/dolthub/doltgresql/server" "github.com/dolthub/doltgresql/servercfg" + "github.com/dolthub/doltgresql/servercfg/cfgdetails" ) // CreateDoltgresServer creates and returns a Doltgres server. @@ -34,12 +35,14 @@ func CreateDoltgresServer() (controller *svcs.Controller, port int, err error) { return nil, 0, err } address := "127.0.0.1" - logLevel := servercfg.LogLevel_Panic + logLevel := cfgdetails.LogLevel_Panic controller, err = dserver.RunInMemory(&servercfg.DoltgresConfig{ - LogLevelStr: &logLevel, - ListenerConfig: &servercfg.DoltgresListenerConfig{ - PortNumber: &port, - HostStr: &address, + DoltgresConfig: cfgdetails.DoltgresConfig{ + LogLevelStr: &logLevel, + ListenerConfig: &cfgdetails.DoltgresListenerConfig{ + PortNumber: &port, + HostStr: &address, + }, }, }, dserver.NewListener) if err != nil { diff --git a/testing/go/ssl_test.go b/testing/go/ssl_test.go index a2940a76cc..f9515db8f8 100644 --- a/testing/go/ssl_test.go +++ b/testing/go/ssl_test.go @@ -1,3 +1,17 @@ +// Copyright 2023 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package _go import ( @@ -17,6 +31,7 @@ import ( dserver "github.com/dolthub/doltgresql/server" "github.com/dolthub/doltgresql/servercfg" + "github.com/dolthub/doltgresql/servercfg/cfgdetails" ) type SSLListener struct { @@ -49,9 +64,11 @@ func TestSSL(t *testing.T) { port, err := sql.GetEmptyPort() require.NoError(t, err) controller, err := dserver.RunInMemory(&servercfg.DoltgresConfig{ - ListenerConfig: &servercfg.DoltgresListenerConfig{ - PortNumber: &port, - HostStr: ptr("127.0.0.1"), + DoltgresConfig: cfgdetails.DoltgresConfig{ + ListenerConfig: &cfgdetails.DoltgresListenerConfig{ + PortNumber: &port, + HostStr: ptr("127.0.0.1"), + }, }, }, NewSslListener) require.NoError(t, err) diff --git a/utils/genminver_validation/main.go b/utils/genminver_validation/main.go index 0722244c36..c7e2d2620d 100644 --- a/utils/genminver_validation/main.go +++ b/utils/genminver_validation/main.go @@ -21,7 +21,7 @@ import ( "github.com/dolthub/dolt/go/libraries/utils/minver" - "github.com/dolthub/doltgresql/servercfg" + "github.com/dolthub/doltgresql/servercfg/cfgdetails" ) func main() { @@ -31,7 +31,7 @@ func main() { outFile := os.Args[1] - err := minver.GenValidationFile(&servercfg.DoltgresConfig{}, outFile) + err := minver.GenValidationFile(&cfgdetails.DoltgresConfig{}, outFile) if err != nil { log.Fatal(err) }