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

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

Merged
merged 5 commits into from
Jan 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
130 changes: 130 additions & 0 deletions cmd/doctor.go
Original file line number Diff line number Diff line change
@@ -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 {
lunny marked this conversation as resolved.
Show resolved Hide resolved
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
}
25 changes: 25 additions & 0 deletions docs/content/doc/usage/command-line.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,3 +289,28 @@ This command is idempotent.

#### convert
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.
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ arguments - which can alternatively be run by running the subcommand web.`
cmd.CmdMigrate,
cmd.CmdKeys,
cmd.CmdConvert,
cmd.CmdDoctor,
}
// Now adjust these commands to add our global configuration options

Expand Down