Skip to content

Commit

Permalink
Add a new command doctor to check if some wrong configurations on git…
Browse files Browse the repository at this point in the history
…ea 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
  • Loading branch information
lunny authored and sapk committed Jan 11, 2020
1 parent f2e6c45 commit f69f5a9
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 0 deletions.
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 {
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

0 comments on commit f69f5a9

Please sign in to comment.