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

Improve install code to avoid low-level mistakes. #17779

Merged
merged 47 commits into from
Dec 1, 2021
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
c5ff560
Improve install code to avoid low-level mistakes.
wxiaoguang Nov 23, 2021
2bd7628
Check app.ini in cmd
wxiaoguang Nov 23, 2021
fc2404a
Fix setting i18n order
wxiaoguang Nov 23, 2021
384a32a
fix
wxiaoguang Nov 23, 2021
86fec99
fix
wxiaoguang Nov 23, 2021
2721c0c
fix
wxiaoguang Nov 23, 2021
0bf4489
fix typo
wxiaoguang Nov 23, 2021
61e17ca
Update models/db/engine.go
wxiaoguang Nov 24, 2021
2ae647a
Merge branch 'main' into improve-install
wxiaoguang Nov 24, 2021
6c9564a
refactor database package, check SECRET_KEY to prevent overwriting
wxiaoguang Nov 24, 2021
430c48e
Merge branch 'main' into improve-install
wxiaoguang Nov 24, 2021
7bc1792
optimize installation check
wxiaoguang Nov 24, 2021
056989d
fix rename
wxiaoguang Nov 24, 2021
bd8ff1e
rename generateSaveInternalToken
wxiaoguang Nov 24, 2021
0f6df8d
Merge branch 'main' into improve-install
wxiaoguang Nov 24, 2021
4b1ae31
Merge branch 'main' into improve-install
wxiaoguang Nov 24, 2021
44d8c8e
Merge branch 'main' into improve-install
wxiaoguang Nov 25, 2021
a0a438d
Add logs
wxiaoguang Nov 25, 2021
ce8846e
Remove unnecessary db quote
wxiaoguang Nov 25, 2021
89c37b6
fix log
wxiaoguang Nov 25, 2021
4378c90
Merge branch 'main' into improve-install
wxiaoguang Nov 26, 2021
15e7bab
Merge remote-tracking branch 'origin/main' into improve-install
zeripath Nov 26, 2021
61fb4d9
Adjust install page messages and appearances
zeripath Nov 26, 2021
c1235fa
Add testing for empty app.ini on setting.NewContext and only allow we…
zeripath Nov 26, 2021
edc5ed0
Merge pull request #2 from zeripath/improve-install
wxiaoguang Nov 27, 2021
f15d610
Improve setting.NewContext
wxiaoguang Nov 27, 2021
8f4a4ec
Merge branch 'main' into improve-install
wxiaoguang Nov 27, 2021
fbaf635
Only create APP_DATA_PATH if necessary
wxiaoguang Nov 27, 2021
c75e9e7
Merge branch 'improve-install' of github.com:wxiaoguang/gitea into im…
wxiaoguang Nov 27, 2021
4fb54ff
fix lint
wxiaoguang Nov 27, 2021
bef7edd
Fix NewContext call
wxiaoguang Nov 27, 2021
7fe5264
Fix unit test
wxiaoguang Nov 27, 2021
1bcd824
fix unit test
wxiaoguang Nov 27, 2021
13eaef5
Fix unit test
wxiaoguang Nov 27, 2021
acda572
test
wxiaoguang Nov 27, 2021
47dded1
fix test
wxiaoguang Nov 27, 2021
007a7d4
Update modules/setting/setting.go
wxiaoguang Nov 27, 2021
bc36dc5
Update modules/setting/directory.go
wxiaoguang Nov 27, 2021
815d8f9
Update modules/setting/directory.go
wxiaoguang Nov 27, 2021
3c240c5
Update cmd/web.go
wxiaoguang Nov 27, 2021
17b98f9
Update contrib/environment-to-ini/environment-to-ini.go
wxiaoguang Nov 27, 2021
cedb452
Update models/db/engine.go
wxiaoguang Nov 27, 2021
fc0b0d3
Update modules/private/internal.go
wxiaoguang Nov 27, 2021
d95d1db
Update modules/setting/directory.go
wxiaoguang Nov 27, 2021
8dbbc10
Rename setting.NewContextXxx to setting.LoadXxx
wxiaoguang Nov 27, 2021
eb6bb8e
Merge branch 'main' into improve-install
wxiaoguang Nov 27, 2021
30965a6
Merge branch 'main' into improve-install
lunny Dec 1, 2021
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
17 changes: 12 additions & 5 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"syscall"

"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"

Expand Down Expand Up @@ -56,16 +57,22 @@ func confirm() (bool, error) {
}
}

func initDB(ctx context.Context) error {
return initDBDisableConsole(ctx, false)
func ensureInstallLock() {
if !setting.InstallLock {
log.Fatal("invalid app.ini (no installation flag), please use the correctly installed config file")
}
}

func initDBDisableConsole(ctx context.Context, disableConsole bool) error {
func initDB(ctx context.Context) error {
setting.NewContext()
setting.InitDBConfig()
setting.NewXORMLogService(disableConsole)
setting.NewXORMLogService(false)

if setting.Database.Type == "" {
return errors.New("invalid database settings in app.ini, please use the correctly installed config file")
}
if err := db.InitEngine(ctx); err != nil {
return fmt.Errorf("models.SetEngine: %v", err)
return fmt.Errorf("cmd.initDB: %v", err)
}
return nil
}
Expand Down
1 change: 0 additions & 1 deletion cmd/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ func runConvert(ctx *cli.Context) error {
log.Info("Custom path: %s", setting.CustomPath)
log.Info("Log path: %s", setting.LogRootPath)
log.Info("Configuration file: %s", setting.CustomConf)
setting.InitDBConfig()

if !setting.Database.UseMySQL {
fmt.Println("This command can only be used with a MySQL database")
Expand Down
2 changes: 2 additions & 0 deletions cmd/doctor.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ You should back-up your database before doing this and ensure that your database
}

func runRecreateTable(ctx *cli.Context) error {
ensureInstallLock()

// Redirect the default golog to here
golog.SetFlags(0)
golog.SetPrefix("")
Expand Down
1 change: 0 additions & 1 deletion cmd/dump_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ func runDumpRepository(ctx *cli.Context) error {
log.Info("Custom path: %s", setting.CustomPath)
log.Info("Log path: %s", setting.LogRootPath)
log.Info("Configuration file: %s", setting.CustomConf)
setting.InitDBConfig()

var (
serviceType structs.GitServiceType
Expand Down
1 change: 0 additions & 1 deletion cmd/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ func runMigrate(ctx *cli.Context) error {
log.Info("Custom path: %s", setting.CustomPath)
log.Info("Log path: %s", setting.LogRootPath)
log.Info("Configuration file: %s", setting.CustomConf)
setting.InitDBConfig()

if err := db.InitEngineWithMigration(context.Background(), migrations.Migrate); err != nil {
log.Fatal("Failed to initialize ORM engine: %v", err)
Expand Down
1 change: 0 additions & 1 deletion cmd/migrate_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ func runMigrateStorage(ctx *cli.Context) error {
log.Info("Custom path: %s", setting.CustomPath)
log.Info("Log path: %s", setting.LogRootPath)
log.Info("Configuration file: %s", setting.CustomConf)
setting.InitDBConfig()

if err := db.InitEngineWithMigration(context.Background(), migrations.Migrate); err != nil {
log.Fatal("Failed to initialize ORM engine: %v", err)
Expand Down
59 changes: 24 additions & 35 deletions models/db/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ package db
import (
"context"
"database/sql"
"errors"
"fmt"
"io"
"reflect"
Expand Down Expand Up @@ -126,40 +125,46 @@ func SyncAllTables() error {
return x.StoreEngine("InnoDB").Sync2(tables...)
}

// InitEngine sets the xorm.Engine
func InitEngine(ctx context.Context) (err error) {
x, err = NewEngine()
// InitEngine initializes the xorm.Engine and set it as db.DefaultContext
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
func InitEngine(ctx context.Context) error {
eng, err := NewEngine()
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return fmt.Errorf("Failed to connect to database: %v", err)
}

x.SetMapper(names.GonicMapper{})
eng.SetMapper(names.GonicMapper{})
// WARNING: for serv command, MUST remove the output to os.stdout,
// so use log file to instead print to stdout.
x.SetLogger(NewXORMLogger(setting.Database.LogSQL))
x.ShowSQL(setting.Database.LogSQL)
x.SetMaxOpenConns(setting.Database.MaxOpenConns)
x.SetMaxIdleConns(setting.Database.MaxIdleConns)
x.SetConnMaxLifetime(setting.Database.ConnMaxLifetime)
eng.SetLogger(NewXORMLogger(setting.Database.LogSQL))
eng.ShowSQL(setting.Database.LogSQL)
eng.SetMaxOpenConns(setting.Database.MaxOpenConns)
eng.SetMaxIdleConns(setting.Database.MaxIdleConns)
eng.SetConnMaxLifetime(setting.Database.ConnMaxLifetime)
eng.SetDefaultContext(ctx)

SetDefaultEngine(ctx, eng)
return nil
}

// SetDefaultEngine sets the default engine for db
func SetDefaultEngine(ctx context.Context, eng *xorm.Engine) {
zeripath marked this conversation as resolved.
Show resolved Hide resolved
x = eng
DefaultContext = &Context{
Context: ctx,
e: x,
}
x.SetDefaultContext(ctx)
return nil
}

// SetEngine is used by unit test code
func SetEngine(eng *xorm.Engine) {
x = eng
DefaultContext = &Context{
Context: context.Background(),
e: x,
// UnsetDefaultEngine closes and unsets the default engine
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
func UnsetDefaultEngine() {
if x != nil {
_ = x.Close()
x = nil
}
DefaultContext = nil
}

// InitEngineWithMigration initializes a new xorm.Engine
// InitEngineWithMigration initializes a new xorm.Engine and set it as db.DefaultContext
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
// This function must never call .Sync2() if the provided migration function fails.
// When called from the "doctor" command, the migration function is a version check
// that prevents the doctor from fixing anything in the database if the migration level
Expand Down Expand Up @@ -226,14 +231,6 @@ func NamesToBean(names ...string) ([]interface{}, error) {
return beans, nil
}

// Ping tests if database is alive
func Ping() error {
if x != nil {
return x.Ping()
}
return errors.New("database not configured")
}

// DumpDatabase dumps all data from database according the special database SQL syntax to file system.
func DumpDatabase(filePath, dbType string) error {
var tbs []*schemas.Table
Expand Down Expand Up @@ -291,11 +288,3 @@ func GetMaxID(beanOrTableName interface{}) (maxID int64, err error) {
_, err = x.Select("MAX(id)").Table(beanOrTableName).Get(&maxID)
return
}

// FindByMaxID filled results as the condition from database
func FindByMaxID(maxID int64, limit int, results interface{}) error {
return x.Where("id <= ?", maxID).
OrderBy("id DESC").
Limit(limit).
Find(results)
}
3 changes: 2 additions & 1 deletion models/unittest/testdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package unittest

import (
"context"
"fmt"
"net/url"
"os"
Expand Down Expand Up @@ -124,7 +125,7 @@ func CreateTestEngine(opts FixturesOptions) error {
return err
}
x.SetMapper(names.GonicMapper{})
db.SetEngine(x)
db.SetDefaultEngine(context.Background(), x)

if err = db.SyncAllTables(); err != nil {
return err
Expand Down
7 changes: 4 additions & 3 deletions modules/private/internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"context"
"crypto/tls"
"fmt"
"log"
"net"
"net/http"

Expand All @@ -17,6 +18,9 @@ import (
)

func newRequest(ctx context.Context, url, method string) *httplib.Request {
if setting.InternalToken == "" {
log.Fatal("no internal token, can not send internal request to server. please use correct app.ini")
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
}
return httplib.NewRequest(url, method).
SetContext(ctx).
Header("Authorization",
Expand Down Expand Up @@ -44,9 +48,6 @@ func newInternalRequest(ctx context.Context, url, method string) *httplib.Reques
})
if setting.Protocol == setting.UnixSocket {
req.SetTransport(&http.Transport{
Dial: func(_, _ string) (net.Conn, error) {
return net.Dial("unix", setting.HTTPAddr)
},
DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) {
var d net.Dialer
return d.DialContext(ctx, "unix", setting.HTTPAddr)
Expand Down
44 changes: 18 additions & 26 deletions modules/setting/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,10 @@ func NewContext() {
SuccessfulTokensCacheSize = sec.Key("SUCCESSFUL_TOKENS_CACHE_SIZE").MustInt(20)

InternalToken = loadInternalToken(sec)
if InstallLock && InternalToken == "" {
lunny marked this conversation as resolved.
Show resolved Hide resolved
// if Gitea has been installed but the InternalToken hasn't been generated (upgrade from an old release), we should generate
GenerateSaveInternalToken()
}

cfgdata := sec.Key("PASSWORD_COMPLEXITY").Strings(",")
if len(cfgdata) == 0 {
Expand Down Expand Up @@ -968,19 +972,11 @@ func NewContext() {

Langs = Cfg.Section("i18n").Key("LANGS").Strings(",")
if len(Langs) == 0 {
Langs = []string{
"en-US", "zh-CN", "zh-HK", "zh-TW", "de-DE", "fr-FR", "nl-NL", "lv-LV",
"ru-RU", "uk-UA", "ja-JP", "es-ES", "pt-BR", "pt-PT", "pl-PL", "bg-BG",
"it-IT", "fi-FI", "tr-TR", "cs-CZ", "sr-SP", "sv-SE", "ko-KR", "el-GR",
"fa-IR", "hu-HU", "id-ID", "ml-IN"}
Langs = defaultI18nLangs()
}
Names = Cfg.Section("i18n").Key("NAMES").Strings(",")
if len(Names) == 0 {
Names = []string{"English", "简体中文", "繁體中文(香港)", "繁體中文(台灣)", "Deutsch",
"français", "Nederlands", "latviešu", "русский", "Українська", "日本語",
"español", "português do Brasil", "Português de Portugal", "polski", "български",
"italiano", "suomi", "Türkçe", "čeština", "српски", "svenska", "한국어", "ελληνικά",
"فارسی", "magyar nyelv", "bahasa Indonesia", "മലയാളം"}
Names = defaultI18nNames()
}

ShowFooterBranding = Cfg.Section("other").Key("SHOW_FOOTER_BRANDING").MustBool(false)
Expand Down Expand Up @@ -1047,8 +1043,8 @@ func parseAuthorizedPrincipalsAllow(values []string) ([]string, bool) {

func loadInternalToken(sec *ini.Section) string {
uri := sec.Key("INTERNAL_TOKEN_URI").String()
if len(uri) == 0 {
return loadOrGenerateInternalToken(sec)
if uri == "" {
return sec.Key("INTERNAL_TOKEN").String()
}
tempURI, err := url.Parse(uri)
if err != nil {
Expand Down Expand Up @@ -1085,21 +1081,17 @@ func loadInternalToken(sec *ini.Section) string {
return ""
}

func loadOrGenerateInternalToken(sec *ini.Section) string {
var err error
token := sec.Key("INTERNAL_TOKEN").String()
if len(token) == 0 {
token, err = generate.NewInternalToken()
if err != nil {
log.Fatal("Error generate internal token: %v", err)
}

// Save secret
CreateOrAppendToCustomConf(func(cfg *ini.File) {
cfg.Section("security").Key("INTERNAL_TOKEN").SetValue(token)
})
// GenerateSaveInternalToken generates and saves the internal token to app.ini
func GenerateSaveInternalToken() {
token, err := generate.NewInternalToken()
if err != nil {
log.Fatal("Error generate internal token: %v", err)
}
return token

InternalToken = token
CreateOrAppendToCustomConf(func(cfg *ini.File) {
cfg.Section("security").Key("INTERNAL_TOKEN").SetValue(token)
})
}

// MakeAbsoluteAssetURL returns the absolute asset url prefix without a trailing slash
Expand Down
51 changes: 51 additions & 0 deletions modules/setting/setting_i18n.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package setting

// defaultI18nLangNames must be a slice, we need the order
var defaultI18nLangNames = []string{
"en-US", "English",
"zh-CN", "简体中文",
"zh-HK", "繁體中文(香港)",
"zh-TW", "繁體中文(台灣)",
"de-DE", "Deutsch",
"fr-FR", "français",
"nl-NL", "Nederlands",
"lv-LV", "latviešu",
"ru-RU", "русский",
"uk-UA", "Українська",
"ja-JP", "日本語",
"es-ES", "español",
"pt-BR", "português do Brasil",
"pt-PT", "Português de Portugal",
"pl-PL", "polski",
"bg-BG", "български",
"it-IT", "italiano",
"fi-FI", "suomi",
"tr-TR", "Türkçe",
"cs-CZ", "čeština",
"sr-SP", "српски",
"sv-SE", "svenska",
"ko-KR", "한국어",
"el-GR", "ελληνικά",
"fa-IR", "فارسی",
"hu-HU", "magyar nyelv",
"id-ID", "bahasa Indonesia",
"ml-IN", "മലയാളം",
}

func defaultI18nLangs() (res []string) {
for i := 0; i < len(defaultI18nLangNames); i += 2 {
res = append(res, defaultI18nLangNames[i])
}
return
}

func defaultI18nNames() (res []string) {
for i := 0; i < len(defaultI18nLangNames); i += 2 {
res = append(res, defaultI18nLangNames[i+1])
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
}
return
}
7 changes: 7 additions & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ ssl_mode = SSL
charset = Charset
path = Path
sqlite_helper = File path for the SQLite3 database.<br>Enter an absolute path if you run Gitea as a service.
reinstall_error = You are trying to re-install in an existing Gitea database
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
reinstall_confirm_message = In most cases, you should use your existing "app.ini" to run Gitea. Re-installing in an existing Gitea database would cause potential problems. If you know what you are doing, mark these tips as checked to continue.
reinstall_confirm_check_1 = The data encrypted by the secret keys in app.ini will be lost, users may not be able to log in with 2FA/OTP.
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
reinstall_confirm_check_2 = The repositories and settings may need to be re-synchronized.
reinstall_confirm_check_3 = I have lost my app.ini and I have to re-install, I know these risks.
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
err_empty_db_path = The SQLite3 database path cannot be empty.
no_admin_and_disable_registration = You cannot disable user self-registration without creating an administrator account.
err_empty_admin_password = The administrator password cannot be empty.
Expand Down Expand Up @@ -205,6 +210,8 @@ sqlite3_not_available = This Gitea version does not support SQLite3. Please down
invalid_db_setting = The database settings are invalid: %v
invalid_repo_path = The repository root path is invalid: %v
run_user_not_match = The 'run as' username is not the current username: %s -> %s
internal_token_failed = Failed to generate internal token: %v
secret_key_failed = Failed to generate secret key: %v
save_config_failed = Failed to save configuration: %v
invalid_admin_setting = Administrator account setting is invalid: %v
install_success = Welcome! Thank you for choosing Gitea. Have fun and take care!
Expand Down
Loading