Add a new command doctor to check if some wrong configurations on gitea instance (#9095)

* add doctor

* Add a new command doctor to check if some wrong configurations on gitea instance

* fix import

* use regex match authorized_keys on doctor

* Add documentation
This commit is contained in:
Lunny Xiao 2020-01-11 22:24:57 +08:00 committed by Antoine GIRARD
parent f2e6c4538e
commit f69f5a9f10
3 changed files with 156 additions and 0 deletions

130
cmd/doctor.go Normal file
View file

@ -0,0 +1,130 @@
// Copyright 2019 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 cmd
import (
"bufio"
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli"
)
// CmdDoctor represents the available doctor sub-command.
var CmdDoctor = cli.Command{
Name: "doctor",
Usage: "Diagnose the problems",
Description: "A command to diagnose the problems of current gitea instance according the given configuration.",
Action: runDoctor,
}
type check struct {
title string
f func(ctx *cli.Context) ([]string, error)
}
// checklist represents list for all checks
var checklist = []check{
{
title: "Check if OpenSSH authorized_keys file id correct",
f: runDoctorLocationMoved,
},
// more checks please append here
}
func runDoctor(ctx *cli.Context) error {
err := initDB()
fmt.Println("Using app.ini at", setting.CustomConf)
if err != nil {
fmt.Println(err)
fmt.Println("Check if you are using the right config file. You can use a --config directive to specify one.")
return nil
}
for i, check := range checklist {
fmt.Println("[", i+1, "]", check.title)
if messages, err := check.f(ctx); err != nil {
fmt.Println("Error:", err)
} else if len(messages) > 0 {
for _, message := range messages {
fmt.Println("-", message)
}
} else {
fmt.Println("OK.")
}
fmt.Println()
}
return nil
}
func exePath() (string, error) {
file, err := exec.LookPath(os.Args[0])
if err != nil {
return "", err
}
return filepath.Abs(file)
}
func runDoctorLocationMoved(ctx *cli.Context) ([]string, error) {
if setting.SSH.StartBuiltinServer || !setting.SSH.CreateAuthorizedKeysFile {
return nil, nil
}
fPath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
f, err := os.Open(fPath)
if err != nil {
return nil, err
}
defer f.Close()
var firstline string
scanner := bufio.NewScanner(f)
for scanner.Scan() {
firstline = strings.TrimSpace(scanner.Text())
if len(firstline) == 0 || firstline[0] == '#' {
continue
}
break
}
// command="/Volumes/data/Projects/gitea/gitea/gitea --config
if len(firstline) > 0 {
exp := regexp.MustCompile(`^[ \t]*(?:command=")([^ ]+) --config='([^']+)' serv key-([^"]+)",(?:[^ ]+) ssh-rsa ([^ ]+) ([^ ]+)[ \t]*$`)
// command="/home/user/gitea --config='/home/user/etc/app.ini' serv key-999",option-1,option-2,option-n ssh-rsa public-key-value key-name
res := exp.FindStringSubmatch(firstline)
if res == nil {
return nil, errors.New("Unknow authorized_keys format")
}
giteaPath := res[1] // => /home/user/gitea
iniPath := res[2] // => /home/user/etc/app.ini
p, err := exePath()
if err != nil {
return nil, err
}
p, err = filepath.Abs(p)
if err != nil {
return nil, err
}
if len(giteaPath) > 0 && giteaPath != p {
return []string{fmt.Sprintf("Gitea exe path wants %s but %s on %s", p, giteaPath, fPath)}, nil
}
if len(iniPath) > 0 && iniPath != setting.CustomConf {
return []string{fmt.Sprintf("Gitea config path wants %s but %s on %s", setting.CustomConf, iniPath, fPath)}, nil
}
}
return nil, nil
}

View file

@ -289,3 +289,28 @@ This command is idempotent.
#### convert #### convert
Converts an existing MySQL database from utf8 to utf8mb4. Converts an existing MySQL database from utf8 to utf8mb4.
#### doctor
Diagnose the problems of current gitea instance according the given configuration.
Currently there are a check list below:
- Check if OpenSSH authorized_keys file id correct
When your gitea instance support OpenSSH, your gitea instance binary path will be written to `authorized_keys`
when there is any public key added or changed on your gitea instance.
Sometimes if you moved or renamed your gitea binary when upgrade and you haven't run `Update the '.ssh/authorized_keys' file with Gitea SSH keys. (Not needed for the built-in SSH server.)` on your Admin Panel. Then all pull/push via SSH will not be work.
This check will help you to check if it works well.
For contributors, if you want to add more checks, you can wrie ad new function like `func(ctx *cli.Context) ([]string, error)` and
append it to `doctor.go`.
```go
var checklist = []check{
{
title: "Check if OpenSSH authorized_keys file id correct",
f: runDoctorLocationMoved,
},
// more checks please append here
}
```
This function will receive a command line context and return a list of details about the problems or error.

View file

@ -68,6 +68,7 @@ arguments - which can alternatively be run by running the subcommand web.`
cmd.CmdMigrate, cmd.CmdMigrate,
cmd.CmdKeys, cmd.CmdKeys,
cmd.CmdConvert, cmd.CmdConvert,
cmd.CmdDoctor,
} }
// Now adjust these commands to add our global configuration options // Now adjust these commands to add our global configuration options