conf: overhaul database settings

pull/5940/head
ᴜɴᴋɴᴡᴏɴ 2020-02-22 18:58:16 +08:00
parent c4a0a40473
commit 5efbde4fe9
No known key found for this signature in database
GPG Key ID: B43718D76E30A238
15 changed files with 153 additions and 136 deletions

View File

@ -20,6 +20,8 @@ All notable changes to Gogs are documented in this file.
- Configuration option `APP_NAME` is deprecated and will end support in 0.13.0, please start using `BRAND_NAME`.
- Configuration option `[server] ROOT_URL` is deprecated and will end support in 0.13.0, please start using `[server] EXTERNAL_URL`.
- Configuration option `[server] LANDING_PAGE` is deprecated and will end support in 0.13.0, please start using `[server] LANDING_URL`.
- Configuration option `[database] DB_TYPE` is deprecated and will end support in 0.13.0, please start using `[database] TYPE`.
- Configuration option `[database] PASSWD` is deprecated and will end support in 0.13.0, please start using `[database] PASSWORD`.
### Fixed

View File

@ -133,6 +133,19 @@ FILE_MAX_SIZE = 3
; The maximum number of files per upload.
MAX_FILES = 5
[database]
; The database backend, either "postgres", "mysql" "sqlite3" or "mssql".
; You can connect to TiDB with MySQL protocol.
TYPE = postgres
HOST = 127.0.0.1:5432
NAME = gogs
USER = gogs
PASSWORD =
; For "postgres" only, either "disable", "require" or "verify-full".
SSL_MODE = disable
; For "sqlite3" only, make sure to use absolute path.
PATH = data/gogs.db
; Attachment settings for releases
[release.attachment]
; Whether attachments are enabled. Defaults to `true`
@ -167,18 +180,6 @@ ANGLED_QUOTES = true
; Value for Access-Control-Allow-Origin header, default is not to present
ACCESS_CONTROL_ALLOW_ORIGIN =
[database]
; Either "mysql", "postgres" or "sqlite3", you can connect to TiDB with MySQL protocol
DB_TYPE = mysql
HOST = 127.0.0.1:3306
NAME = gogs
USER = root
PASSWD =
; For "postgres" only, either "disable", "require" or "verify-full"
SSL_MODE = disable
; For "sqlite3" and "tidb", use absolute path when you start as service
PATH = data/gogs.db
[admin]
; Disable regular (non-admin) users to create organizations
DISABLE_REGULAR_ORG_CREATION = false

View File

@ -1216,22 +1216,22 @@ config.repo.upload.allowed_types = Upload allowed types
config.repo.upload.file_max_size = Upload file size limit
config.repo.upload.max_files = Upload files limit
config.db_config = Database configuration
config.db.type = Type
config.db.host = Host
config.db.name = Name
config.db.user = User
config.db.ssl_mode = SSL mode
config.db.ssl_mode_helper = (for "postgres" only)
config.db.path = Path
config.db.path_helper = (for "sqlite3"only)
config.log_file_root_path = Log File Root Path
config.reverse_auth_user = Reverse Authentication User
config.http_config = HTTP Configuration
config.http_access_control_allow_origin = Access Control Allow Origin
config.db_config = Database Configuration
config.db_type = Type
config.db_host = Host
config.db_name = Name
config.db_user = User
config.db_ssl_mode = SSL Mode
config.db_ssl_mode_helper = (for "postgres" only)
config.db_path = Path
config.db_path_helper = (for "sqlite3" and "tidb")
config.service_config = Service Configuration
config.register_email_confirm = Require Email Confirmation
config.disable_register = Disable Registration

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -146,7 +146,6 @@ func runCreateUser(c *cli.Context) error {
return errors.Wrap(err, "init configuration")
}
db.LoadConfigs()
db.SetEngine()
if err := db.CreateUser(&db.User{
@ -170,7 +169,6 @@ func adminDashboardOperation(operation func() error, successMessage string) func
return errors.Wrap(err, "init configuration")
}
db.LoadConfigs()
db.SetEngine()
if err := operation(); err != nil {

View File

@ -52,7 +52,6 @@ func runBackup(c *cli.Context) error {
return errors.Wrap(err, "init configuration")
}
db.LoadConfigs()
db.SetEngine()
tmpDir := c.String("tempdir")

View File

@ -99,7 +99,6 @@ func runRestore(c *cli.Context) error {
return errors.Wrap(err, "init configuration")
}
db.LoadConfigs()
db.SetEngine()
// Database

View File

@ -84,8 +84,6 @@ func setup(c *cli.Context, logPath string, connectDB bool) {
return
}
db.LoadConfigs()
if conf.UseSQLite3 {
_ = os.Chdir(conf.WorkDir())
}

View File

@ -182,6 +182,15 @@ func Init(customConf string) error {
Repository.Root = ensureAbs(Repository.Root)
Repository.Upload.TempPath = ensureAbs(Repository.Upload.TempPath)
// *******************************
// ----- Database settings -----
// *******************************
if err = File.Section("database").MapTo(&Database); err != nil {
return errors.Wrap(err, "mapping [database] section")
}
Database.Path = ensureAbs(Database.Path)
handleDeprecated()
// TODO

View File

@ -123,6 +123,22 @@ var (
MaxFiles int
} `ini:"repository.upload"`
}
// Database settings
Database struct {
Type string
Host string
Name string
User string
Password string
SSLMode string `ini:"SSL_MODE"`
Path string
// Deprecated: Use Type instead, will be removed in 0.13.
DbType string
// Deprecated: Use Password instead, will be removed in 0.13.
Passwd string
}
)
// handleDeprecated transfers deprecated values to the new ones when set.
@ -140,4 +156,13 @@ func handleDeprecated() {
Server.LandingURL = "/explore"
Server.LangdingPage = ""
}
if Database.DbType != "" {
Database.Type = Database.DbType
Database.DbType = ""
}
if Database.Passwd != "" {
Database.Password = Database.Passwd
Database.Passwd = ""
}
}

View File

@ -49,10 +49,6 @@ var (
tables []interface{}
HasEngine bool
DbCfg struct {
Type, Host, Name, User, Passwd, Path, SSLMode string
}
EnableSQLite3 bool
)
@ -74,29 +70,6 @@ func init() {
}
}
func LoadConfigs() {
sec := conf.File.Section("database")
DbCfg.Type = sec.Key("DB_TYPE").String()
switch DbCfg.Type {
case "sqlite3":
conf.UseSQLite3 = true
case "mysql":
conf.UseMySQL = true
case "postgres":
conf.UsePostgreSQL = true
case "mssql":
conf.UseMSSQL = true
}
DbCfg.Host = sec.Key("HOST").String()
DbCfg.Name = sec.Key("NAME").String()
DbCfg.User = sec.Key("USER").String()
if len(DbCfg.Passwd) == 0 {
DbCfg.Passwd = sec.Key("PASSWD").String()
}
DbCfg.SSLMode = sec.Key("SSL_MODE").String()
DbCfg.Path = sec.Key("PATH").MustString("data/gogs.db")
}
// parsePostgreSQLHostPort parses given input in various forms defined in
// https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
// and returns proper host and port number.
@ -127,46 +100,55 @@ func parseMSSQLHostPort(info string) (string, string) {
}
func getEngine() (*xorm.Engine, error) {
connStr := ""
var Param string = "?"
if strings.Contains(DbCfg.Name, Param) {
Param := "?"
if strings.Contains(conf.Database.Name, Param) {
Param = "&"
}
switch DbCfg.Type {
connStr := ""
switch conf.Database.Type {
case "mysql":
if DbCfg.Host[0] == '/' { // looks like a unix socket
conf.UseMySQL = true
if conf.Database.Host[0] == '/' { // looks like a unix socket
connStr = fmt.Sprintf("%s:%s@unix(%s)/%s%scharset=utf8mb4&parseTime=true",
DbCfg.User, DbCfg.Passwd, DbCfg.Host, DbCfg.Name, Param)
conf.Database.User, conf.Database.Password, conf.Database.Host, conf.Database.Name, Param)
} else {
connStr = fmt.Sprintf("%s:%s@tcp(%s)/%s%scharset=utf8mb4&parseTime=true",
DbCfg.User, DbCfg.Passwd, DbCfg.Host, DbCfg.Name, Param)
conf.Database.User, conf.Database.Password, conf.Database.Host, conf.Database.Name, Param)
}
var engineParams = map[string]string{"rowFormat": "DYNAMIC"}
return xorm.NewEngineWithParams(DbCfg.Type, connStr, engineParams)
return xorm.NewEngineWithParams(conf.Database.Type, connStr, engineParams)
case "postgres":
host, port := parsePostgreSQLHostPort(DbCfg.Host)
conf.UsePostgreSQL = true
host, port := parsePostgreSQLHostPort(conf.Database.Host)
if host[0] == '/' { // looks like a unix socket
connStr = fmt.Sprintf("postgres://%s:%s@:%s/%s%ssslmode=%s&host=%s",
url.QueryEscape(DbCfg.User), url.QueryEscape(DbCfg.Passwd), port, DbCfg.Name, Param, DbCfg.SSLMode, host)
url.QueryEscape(conf.Database.User), url.QueryEscape(conf.Database.Password), port, conf.Database.Name, Param, conf.Database.SSLMode, host)
} else {
connStr = fmt.Sprintf("postgres://%s:%s@%s:%s/%s%ssslmode=%s",
url.QueryEscape(DbCfg.User), url.QueryEscape(DbCfg.Passwd), host, port, DbCfg.Name, Param, DbCfg.SSLMode)
url.QueryEscape(conf.Database.User), url.QueryEscape(conf.Database.Password), host, port, conf.Database.Name, Param, conf.Database.SSLMode)
}
case "mssql":
host, port := parseMSSQLHostPort(DbCfg.Host)
connStr = fmt.Sprintf("server=%s; port=%s; database=%s; user id=%s; password=%s;", host, port, DbCfg.Name, DbCfg.User, DbCfg.Passwd)
conf.UseMSSQL = true
host, port := parseMSSQLHostPort(conf.Database.Host)
connStr = fmt.Sprintf("server=%s; port=%s; database=%s; user id=%s; password=%s;", host, port, conf.Database.Name, conf.Database.User, conf.Database.Passwd)
case "sqlite3":
if !EnableSQLite3 {
return nil, errors.New("this binary version does not build support for SQLite3")
}
if err := os.MkdirAll(path.Dir(DbCfg.Path), os.ModePerm); err != nil {
if err := os.MkdirAll(path.Dir(conf.Database.Path), os.ModePerm); err != nil {
return nil, fmt.Errorf("create directories: %v", err)
}
connStr = "file:" + DbCfg.Path + "?cache=shared&mode=rwc"
conf.UseSQLite3 = true
connStr = "file:" + conf.Database.Path + "?cache=shared&mode=rwc"
default:
return nil, fmt.Errorf("unknown database type: %s", DbCfg.Type)
return nil, fmt.Errorf("unknown database type: %s", conf.Database.Type)
}
return xorm.NewEngine(DbCfg.Type, connStr)
return xorm.NewEngine(conf.Database.Type, connStr)
}
func NewTestEngine(x *xorm.Engine) (err error) {

View File

@ -200,13 +200,13 @@ func Config(c *context.Context) {
c.Data["Server"] = conf.Server
c.Data["SSH"] = conf.SSH
c.Data["Repository"] = conf.Repository
c.Data["Database"] = conf.Database
c.Data["LogRootPath"] = conf.LogRootPath
c.Data["ReverseProxyAuthUser"] = conf.ReverseProxyAuthUser
c.Data["HTTP"] = conf.HTTP
c.Data["DbCfg"] = db.DbCfg
c.Data["Service"] = conf.Service
c.Data["Webhook"] = conf.Webhook

View File

@ -64,7 +64,6 @@ func GlobalInit(customConf string) error {
log.Trace("Build time: %s", conf.BuildTime)
log.Trace("Build commit: %s", conf.BuildCommit)
db.LoadConfigs()
conf.NewServices()
mailer.NewContext()
@ -136,15 +135,15 @@ func Install(c *context.Context) {
f := form.Install{}
// Database settings
f.DbHost = db.DbCfg.Host
f.DbUser = db.DbCfg.User
f.DbName = db.DbCfg.Name
f.DbPath = db.DbCfg.Path
f.DbHost = conf.Database.Host
f.DbUser = conf.Database.User
f.DbName = conf.Database.Name
f.DbPath = conf.Database.Path
c.Data["CurDbOption"] = "MySQL"
switch db.DbCfg.Type {
case "postgres":
c.Data["CurDbOption"] = "PostgreSQL"
c.Data["CurDbOption"] = "PostgreSQL"
switch conf.Database.Type {
case "mysql":
c.Data["CurDbOption"] = "MySQL"
case "mssql":
c.Data["CurDbOption"] = "MSSQL"
case "sqlite3":
@ -217,16 +216,21 @@ func InstallPost(c *context.Context, f form.Install) {
// Pass basic check, now test configuration.
// Test database setting.
dbTypes := map[string]string{"MySQL": "mysql", "PostgreSQL": "postgres", "MSSQL": "mssql", "SQLite3": "sqlite3", "TiDB": "tidb"}
db.DbCfg.Type = dbTypes[f.DbType]
db.DbCfg.Host = f.DbHost
db.DbCfg.User = f.DbUser
db.DbCfg.Passwd = f.DbPasswd
db.DbCfg.Name = f.DbName
db.DbCfg.SSLMode = f.SSLMode
db.DbCfg.Path = f.DbPath
dbTypes := map[string]string{
"PostgreSQL": "postgres",
"MySQL": "mysql",
"MSSQL": "mssql",
"SQLite3": "sqlite3",
}
conf.Database.Type = dbTypes[f.DbType]
conf.Database.Host = f.DbHost
conf.Database.User = f.DbUser
conf.Database.Password = f.DbPasswd
conf.Database.Name = f.DbName
conf.Database.SSLMode = f.SSLMode
conf.Database.Path = f.DbPath
if db.DbCfg.Type == "sqlite3" && len(db.DbCfg.Path) == 0 {
if conf.Database.Type == "sqlite3" && len(conf.Database.Path) == 0 {
c.FormErr("DbPath")
c.RenderWithErr(c.Tr("install.err_empty_db_path"), INSTALL, &f)
return
@ -316,20 +320,20 @@ func InstallPost(c *context.Context, f form.Install) {
log.Error("Failed to load custom conf %q: %v", conf.CustomConf, err)
}
}
cfg.Section("database").Key("DB_TYPE").SetValue(db.DbCfg.Type)
cfg.Section("database").Key("HOST").SetValue(db.DbCfg.Host)
cfg.Section("database").Key("NAME").SetValue(db.DbCfg.Name)
cfg.Section("database").Key("USER").SetValue(db.DbCfg.User)
cfg.Section("database").Key("PASSWD").SetValue(db.DbCfg.Passwd)
cfg.Section("database").Key("SSL_MODE").SetValue(db.DbCfg.SSLMode)
cfg.Section("database").Key("PATH").SetValue(db.DbCfg.Path)
cfg.Section("database").Key("TYPE").SetValue(conf.Database.Type)
cfg.Section("database").Key("HOST").SetValue(conf.Database.Host)
cfg.Section("database").Key("NAME").SetValue(conf.Database.Name)
cfg.Section("database").Key("USER").SetValue(conf.Database.User)
cfg.Section("database").Key("PASSWORD").SetValue(conf.Database.Password)
cfg.Section("database").Key("SSL_MODE").SetValue(conf.Database.SSLMode)
cfg.Section("database").Key("PATH").SetValue(conf.Database.Path)
cfg.Section("").Key("APP_NAME").SetValue(f.AppName)
cfg.Section("").Key("BRAND_NAME").SetValue(f.AppName)
cfg.Section("repository").Key("ROOT").SetValue(f.RepoRootPath)
cfg.Section("").Key("RUN_USER").SetValue(f.RunUser)
cfg.Section("server").Key("DOMAIN").SetValue(f.Domain)
cfg.Section("server").Key("HTTP_PORT").SetValue(f.HTTPPort)
cfg.Section("server").Key("ROOT_URL").SetValue(f.AppUrl)
cfg.Section("server").Key("EXTERNAL_URL").SetValue(f.AppUrl)
if f.SSHPort == 0 {
cfg.Section("server").Key("DISABLE_SSH").SetValue("true")

View File

@ -6,7 +6,7 @@
<div class="twelve wide column content">
{{template "base/alert" .}}
{{/* Server settings */}}
{{/* Server settings */}}
<h4 class="ui top attached header">
{{.i18n.Tr "admin.config.server_config"}}
</h4>
@ -72,7 +72,7 @@
</dl>
</div>
{{/* SSH settings */}}
{{/* SSH settings */}}
<h4 class="ui top attached header">
{{.i18n.Tr "admin.config.ssh_config"}}
</h4>
@ -112,7 +112,7 @@
</dl>
</div>
{{/* Repository settings */}}
{{/* Repository settings */}}
<h4 class="ui top attached header">
{{.i18n.Tr "admin.config.repo_config"}}
</h4>
@ -161,6 +161,27 @@
</dl>
</div>
{{/* Database settings */}}
<h4 class="ui top attached header">
{{.i18n.Tr "admin.config.db_config"}}
</h4>
<div class="ui attached table segment">
<dl class="dl-horizontal admin-dl-horizontal">
<dt>{{.i18n.Tr "admin.config.db.type"}}</dt>
<dd>{{.Database.Type}}</dd>
<dt>{{.i18n.Tr "admin.config.db.host"}}</dt>
<dd>{{.Database.Host}}</dd>
<dt>{{.i18n.Tr "admin.config.db.name"}}</dt>
<dd>{{.Database.Name}}</dd>
<dt>{{.i18n.Tr "admin.config.db.user"}}</dt>
<dd>{{.Database.User}}</dd>
<dt>{{.i18n.Tr "admin.config.db.ssl_mode"}}</dt>
<dd>{{.Database.SSLMode}} {{.i18n.Tr "admin.config.db.ssl_mode_helper"}}</dd>
<dt>{{.i18n.Tr "admin.config.db.path"}}</dt>
<dd><code>{{.Database.Path}}</code> {{.i18n.Tr "admin.config.db.path_helper"}}</dd>
</dl>
</div>
<!-- HTTP Configuration -->
<h4 class="ui top attached header">
{{.i18n.Tr "admin.config.http_config"}}
@ -178,27 +199,6 @@
</dl>
</div>
<!-- Database Configuration -->
<h4 class="ui top attached header">
{{.i18n.Tr "admin.config.db_config"}}
</h4>
<div class="ui attached table segment">
<dl class="dl-horizontal admin-dl-horizontal">
<dt>{{.i18n.Tr "admin.config.db_type"}}</dt>
<dd>{{.DbCfg.Type}}</dd>
<dt>{{.i18n.Tr "admin.config.db_host"}}</dt>
<dd>{{.DbCfg.Host}}</dd>
<dt>{{.i18n.Tr "admin.config.db_name"}}</dt>
<dd>{{.DbCfg.Name}}</dd>
<dt>{{.i18n.Tr "admin.config.db_user"}}</dt>
<dd>{{.DbCfg.User}}</dd>
<dt>{{.i18n.Tr "admin.config.db_ssl_mode"}}</dt>
<dd>{{.DbCfg.SSLMode}} {{.i18n.Tr "admin.config.db_ssl_mode_helper"}}</dd>
<dt>{{.i18n.Tr "admin.config.db_path"}}</dt>
<dd>{{.DbCfg.Path}} {{.i18n.Tr "admin.config.db_path_helper"}}</dd>
</dl>
</div>
<h4 class="ui top attached header">
{{.i18n.Tr "admin.config.service_config"}}
</h4>