2020-12-02 07:56:04 +03:00
// Copyright 2020 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package doctor
import (
2021-11-07 06:11:27 +03:00
"context"
2020-12-02 07:56:04 +03:00
"fmt"
"sort"
"strings"
2021-09-19 14:49:59 +03:00
"code.gitea.io/gitea/models/db"
2020-12-02 07:56:04 +03:00
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
)
// Check represents a Doctor check
type Check struct {
Title string
Name string
IsDefault bool
2022-01-20 02:26:57 +03:00
Run func ( ctx context . Context , logger log . Logger , autofix bool ) error
2020-12-02 07:56:04 +03:00
AbortIfFailed bool
SkipDatabaseInitialization bool
Priority int
}
type wrappedLevelLogger struct {
log . LevelLogger
}
func ( w * wrappedLevelLogger ) Log ( skip int , level log . Level , format string , v ... interface { } ) error {
return w . LevelLogger . Log (
skip + 1 ,
level ,
" - %s " + format ,
append (
[ ] interface { } {
log . NewColoredValueBytes (
fmt . Sprintf ( "[%s]" , strings . ToUpper ( level . String ( ) [ 0 : 1 ] ) ) ,
level . Color ( ) ) ,
} , v ... ) ... )
}
2021-11-07 06:11:27 +03:00
func initDBDisableConsole ( ctx context . Context , disableConsole bool ) error {
2021-12-01 10:50:01 +03:00
setting . LoadFromExisting ( )
2020-12-02 07:56:04 +03:00
setting . InitDBConfig ( )
setting . NewXORMLogService ( disableConsole )
2021-11-07 06:11:27 +03:00
if err := db . InitEngine ( ctx ) ; err != nil {
2020-12-02 07:56:04 +03:00
return fmt . Errorf ( "models.SetEngine: %v" , err )
}
return nil
}
// Checks is the list of available commands
var Checks [ ] * Check
// RunChecks runs the doctor checks for the provided list
2021-11-07 06:11:27 +03:00
func RunChecks ( ctx context . Context , logger log . Logger , autofix bool , checks [ ] * Check ) error {
2020-12-02 07:56:04 +03:00
wrappedLogger := log . LevelLoggerLogger {
LevelLogger : & wrappedLevelLogger { logger } ,
}
dbIsInit := false
for i , check := range checks {
if ! dbIsInit && ! check . SkipDatabaseInitialization {
// Only open database after the most basic configuration check
setting . EnableXORMLog = false
2021-11-07 06:11:27 +03:00
if err := initDBDisableConsole ( ctx , true ) ; err != nil {
2020-12-02 07:56:04 +03:00
logger . Error ( "Error whilst initializing the database: %v" , err )
logger . Error ( "Check if you are using the right config file. You can use a --config directive to specify one." )
return nil
}
dbIsInit = true
}
logger . Info ( "[%d] %s" , log . NewColoredIDValue ( i + 1 ) , check . Title )
logger . Flush ( )
2022-01-20 02:26:57 +03:00
if err := check . Run ( ctx , & wrappedLogger , autofix ) ; err != nil {
2020-12-02 07:56:04 +03:00
if check . AbortIfFailed {
logger . Critical ( "FAIL" )
return err
}
logger . Error ( "ERROR" )
} else {
logger . Info ( "OK" )
logger . Flush ( )
}
}
return nil
}
// Register registers a command with the list
func Register ( command * Check ) {
Checks = append ( Checks , command )
sort . SliceStable ( Checks , func ( i , j int ) bool {
if Checks [ i ] . Priority == Checks [ j ] . Priority {
return Checks [ i ] . Name < Checks [ j ] . Name
}
if Checks [ i ] . Priority == 0 {
return false
}
return Checks [ i ] . Priority < Checks [ j ] . Priority
} )
}