General refactor of the cmd package (#3328)
* General refactor of the cmd package * Address breakage in runCreateUser * Place "common" functions into cmd.gorelease/v1.15
parent
079273e2ff
commit
2b52f77e1b
78
cmd/admin.go
78
cmd/admin.go
|
@ -20,9 +20,7 @@ var (
|
||||||
// CmdAdmin represents the available admin sub-command.
|
// CmdAdmin represents the available admin sub-command.
|
||||||
CmdAdmin = cli.Command{
|
CmdAdmin = cli.Command{
|
||||||
Name: "admin",
|
Name: "admin",
|
||||||
Usage: "Perform admin operations on command line",
|
Usage: "Command line interface to perform common administrative operations",
|
||||||
Description: `Allow using internal logic of Gitea without hacking into the source code
|
|
||||||
to make automatic initialization process more smoothly`,
|
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []cli.Command{
|
||||||
subcmdCreateUser,
|
subcmdCreateUser,
|
||||||
subcmdChangePassword,
|
subcmdChangePassword,
|
||||||
|
@ -37,17 +35,14 @@ to make automatic initialization process more smoothly`,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "name",
|
Name: "name",
|
||||||
Value: "",
|
|
||||||
Usage: "Username",
|
Usage: "Username",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "password",
|
Name: "password",
|
||||||
Value: "",
|
|
||||||
Usage: "User password",
|
Usage: "User password",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "email",
|
Name: "email",
|
||||||
Value: "",
|
|
||||||
Usage: "User email address",
|
Usage: "User email address",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
|
@ -88,56 +83,42 @@ to make automatic initialization process more smoothly`,
|
||||||
)
|
)
|
||||||
|
|
||||||
func runChangePassword(c *cli.Context) error {
|
func runChangePassword(c *cli.Context) error {
|
||||||
if !c.IsSet("password") {
|
if err := argsSet(c, "username", "password"); err != nil {
|
||||||
return fmt.Errorf("Password is not specified")
|
return err
|
||||||
} else if !c.IsSet("username") {
|
|
||||||
return fmt.Errorf("Username is not specified")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setting.NewContext()
|
if err := initDB(); err != nil {
|
||||||
models.LoadConfigs()
|
return err
|
||||||
|
|
||||||
setting.NewXORMLogService(false)
|
|
||||||
if err := models.SetEngine(); err != nil {
|
|
||||||
return fmt.Errorf("models.SetEngine: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uname := c.String("username")
|
uname := c.String("username")
|
||||||
user, err := models.GetUserByName(uname)
|
user, err := models.GetUserByName(uname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%v", err)
|
return err
|
||||||
}
|
}
|
||||||
if user.Salt, err = models.GetUserSalt(); err != nil {
|
if user.Salt, err = models.GetUserSalt(); err != nil {
|
||||||
return fmt.Errorf("%v", err)
|
return err
|
||||||
}
|
}
|
||||||
user.HashPassword(c.String("password"))
|
user.HashPassword(c.String("password"))
|
||||||
if err := models.UpdateUserCols(user, "passwd", "salt"); err != nil {
|
if err := models.UpdateUserCols(user, "passwd", "salt"); err != nil {
|
||||||
return fmt.Errorf("%v", err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("User '%s' password has been successfully updated!\n", uname)
|
fmt.Printf("%s's password has been successfully updated!\n", user.Name)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runCreateUser(c *cli.Context) error {
|
func runCreateUser(c *cli.Context) error {
|
||||||
if !c.IsSet("name") {
|
if err := argsSet(c, "name", "password", "email"); err != nil {
|
||||||
return fmt.Errorf("Username is not specified")
|
return err
|
||||||
} else if !c.IsSet("password") {
|
|
||||||
return fmt.Errorf("Password is not specified")
|
|
||||||
} else if !c.IsSet("email") {
|
|
||||||
return fmt.Errorf("Email is not specified")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.IsSet("config") {
|
if c.IsSet("config") {
|
||||||
setting.CustomConf = c.String("config")
|
setting.CustomConf = c.String("config")
|
||||||
}
|
}
|
||||||
|
|
||||||
setting.NewContext()
|
if err := initDB(); err != nil {
|
||||||
models.LoadConfigs()
|
return err
|
||||||
|
|
||||||
setting.NewXORMLogService(false)
|
|
||||||
if err := models.SetEngine(); err != nil {
|
|
||||||
return fmt.Errorf("models.SetEngine: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := models.CreateUser(&models.User{
|
if err := models.CreateUser(&models.User{
|
||||||
|
@ -155,13 +136,8 @@ func runCreateUser(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func runRepoSyncReleases(c *cli.Context) error {
|
func runRepoSyncReleases(c *cli.Context) error {
|
||||||
|
if err := initDB(); err != nil {
|
||||||
setting.NewContext()
|
return err
|
||||||
models.LoadConfigs()
|
|
||||||
|
|
||||||
setting.NewXORMLogService(false)
|
|
||||||
if err := models.SetEngine(); err != nil {
|
|
||||||
return fmt.Errorf("models.SetEngine: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Trace("Synchronizing repository releases (this may take a while)")
|
log.Trace("Synchronizing repository releases (this may take a while)")
|
||||||
|
@ -172,8 +148,7 @@ func runRepoSyncReleases(c *cli.Context) error {
|
||||||
Private: true,
|
Private: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(4, "SearchRepositoryByName: %v", err)
|
return fmt.Errorf("SearchRepositoryByName: %v", err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
if len(repos) == 0 {
|
if len(repos) == 0 {
|
||||||
break
|
break
|
||||||
|
@ -187,11 +162,7 @@ func runRepoSyncReleases(c *cli.Context) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
oldnum, err := models.GetReleaseCountByRepoID(repo.ID,
|
oldnum, err := getReleaseCount(repo.ID)
|
||||||
models.FindReleasesOptions{
|
|
||||||
IncludeDrafts: false,
|
|
||||||
IncludeTags: true,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn(" GetReleaseCountByRepoID: %v", err)
|
log.Warn(" GetReleaseCountByRepoID: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -202,11 +173,7 @@ func runRepoSyncReleases(c *cli.Context) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
count, err = models.GetReleaseCountByRepoID(repo.ID,
|
count, err = getReleaseCount(repo.ID)
|
||||||
models.FindReleasesOptions{
|
|
||||||
IncludeDrafts: false,
|
|
||||||
IncludeTags: true,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn(" GetReleaseCountByRepoID: %v", err)
|
log.Warn(" GetReleaseCountByRepoID: %v", err)
|
||||||
continue
|
continue
|
||||||
|
@ -219,3 +186,12 @@ func runRepoSyncReleases(c *cli.Context) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getReleaseCount(id int64) (int64, error) {
|
||||||
|
return models.GetReleaseCountByRepoID(
|
||||||
|
id,
|
||||||
|
models.FindReleasesOptions{
|
||||||
|
IncludeTags: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
26
cmd/cert.go
26
cmd/cert.go
|
@ -90,16 +90,16 @@ func pemBlockForKey(priv interface{}) *pem.Block {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func runCert(ctx *cli.Context) error {
|
func runCert(c *cli.Context) error {
|
||||||
if len(ctx.String("host")) == 0 {
|
if err := argsSet(c, "host"); err != nil {
|
||||||
log.Fatal("Missing required --host parameter")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var priv interface{}
|
var priv interface{}
|
||||||
var err error
|
var err error
|
||||||
switch ctx.String("ecdsa-curve") {
|
switch c.String("ecdsa-curve") {
|
||||||
case "":
|
case "":
|
||||||
priv, err = rsa.GenerateKey(rand.Reader, ctx.Int("rsa-bits"))
|
priv, err = rsa.GenerateKey(rand.Reader, c.Int("rsa-bits"))
|
||||||
case "P224":
|
case "P224":
|
||||||
priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
|
priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
|
||||||
case "P256":
|
case "P256":
|
||||||
|
@ -109,23 +109,23 @@ func runCert(ctx *cli.Context) error {
|
||||||
case "P521":
|
case "P521":
|
||||||
priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
|
priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unrecognized elliptic curve: %q", ctx.String("ecdsa-curve"))
|
log.Fatalf("Unrecognized elliptic curve: %q", c.String("ecdsa-curve"))
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to generate private key: %v", err)
|
log.Fatalf("Failed to generate private key: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var notBefore time.Time
|
var notBefore time.Time
|
||||||
if len(ctx.String("start-date")) == 0 {
|
if startDate := c.String("start-date"); startDate != "" {
|
||||||
notBefore = time.Now()
|
notBefore, err = time.Parse("Jan 2 15:04:05 2006", startDate)
|
||||||
} else {
|
|
||||||
notBefore, err = time.Parse("Jan 2 15:04:05 2006", ctx.String("start-date"))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to parse creation date: %v", err)
|
log.Fatalf("Failed to parse creation date: %v", err)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
notBefore = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
notAfter := notBefore.Add(ctx.Duration("duration"))
|
notAfter := notBefore.Add(c.Duration("duration"))
|
||||||
|
|
||||||
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
||||||
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
||||||
|
@ -147,7 +147,7 @@ func runCert(ctx *cli.Context) error {
|
||||||
BasicConstraintsValid: true,
|
BasicConstraintsValid: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
hosts := strings.Split(ctx.String("host"), ",")
|
hosts := strings.Split(c.String("host"), ",")
|
||||||
for _, h := range hosts {
|
for _, h := range hosts {
|
||||||
if ip := net.ParseIP(h); ip != nil {
|
if ip := net.ParseIP(h); ip != nil {
|
||||||
template.IPAddresses = append(template.IPAddresses, ip)
|
template.IPAddresses = append(template.IPAddresses, ip)
|
||||||
|
@ -156,7 +156,7 @@ func runCert(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.Bool("ca") {
|
if c.Bool("ca") {
|
||||||
template.IsCA = true
|
template.IsCA = true
|
||||||
template.KeyUsage |= x509.KeyUsageCertSign
|
template.KeyUsage |= x509.KeyUsageCertSign
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
// Copyright 2018 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 provides subcommands to the gitea binary - such as "web" or
|
||||||
|
// "admin".
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
// argsSet checks that all the required arguments are set. args is a list of
|
||||||
|
// arguments that must be set in the passed Context.
|
||||||
|
func argsSet(c *cli.Context, args ...string) error {
|
||||||
|
for _, a := range args {
|
||||||
|
if !c.IsSet(a) {
|
||||||
|
return errors.New(a + " is not set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func initDB() error {
|
||||||
|
setting.NewContext()
|
||||||
|
models.LoadConfigs()
|
||||||
|
|
||||||
|
setting.NewXORMLogService(false)
|
||||||
|
if err := models.SetEngine(); err != nil {
|
||||||
|
return fmt.Errorf("models.SetEngine: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
16
cmd/dump.go
16
cmd/dump.go
|
@ -68,19 +68,19 @@ func runDump(ctx *cli.Context) error {
|
||||||
if _, err := os.Stat(tmpDir); os.IsNotExist(err) {
|
if _, err := os.Stat(tmpDir); os.IsNotExist(err) {
|
||||||
log.Fatalf("Path does not exist: %s", tmpDir)
|
log.Fatalf("Path does not exist: %s", tmpDir)
|
||||||
}
|
}
|
||||||
TmpWorkDir, err := ioutil.TempDir(tmpDir, "gitea-dump-")
|
tmpWorkDir, err := ioutil.TempDir(tmpDir, "gitea-dump-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to create tmp work directory: %v", err)
|
log.Fatalf("Failed to create tmp work directory: %v", err)
|
||||||
}
|
}
|
||||||
log.Printf("Creating tmp work dir: %s", TmpWorkDir)
|
log.Printf("Creating tmp work dir: %s", tmpWorkDir)
|
||||||
|
|
||||||
// work-around #1103
|
// work-around #1103
|
||||||
if os.Getenv("TMPDIR") == "" {
|
if os.Getenv("TMPDIR") == "" {
|
||||||
os.Setenv("TMPDIR", TmpWorkDir)
|
os.Setenv("TMPDIR", tmpWorkDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
reposDump := path.Join(TmpWorkDir, "gitea-repo.zip")
|
reposDump := path.Join(tmpWorkDir, "gitea-repo.zip")
|
||||||
dbDump := path.Join(TmpWorkDir, "gitea-db.sql")
|
dbDump := path.Join(tmpWorkDir, "gitea-db.sql")
|
||||||
|
|
||||||
log.Printf("Dumping local repositories...%s", setting.RepoRootPath)
|
log.Printf("Dumping local repositories...%s", setting.RepoRootPath)
|
||||||
zip.Verbose = ctx.Bool("verbose")
|
zip.Verbose = ctx.Bool("verbose")
|
||||||
|
@ -146,10 +146,10 @@ func runDump(ctx *cli.Context) error {
|
||||||
log.Printf("Can't change file access permissions mask to 0600: %v", err)
|
log.Printf("Can't change file access permissions mask to 0600: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Removing tmp work dir: %s", TmpWorkDir)
|
log.Printf("Removing tmp work dir: %s", tmpWorkDir)
|
||||||
|
|
||||||
if err := os.RemoveAll(TmpWorkDir); err != nil {
|
if err := os.RemoveAll(tmpWorkDir); err != nil {
|
||||||
log.Fatalf("Failed to remove %s: %v", TmpWorkDir, err)
|
log.Fatalf("Failed to remove %s: %v", tmpWorkDir, err)
|
||||||
}
|
}
|
||||||
log.Printf("Finish dumping in file %s", fileName)
|
log.Printf("Finish dumping in file %s", fileName)
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ var (
|
||||||
},
|
},
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []cli.Command{
|
||||||
subcmdHookPreReceive,
|
subcmdHookPreReceive,
|
||||||
subcmdHookUpadte,
|
subcmdHookUpdate,
|
||||||
subcmdHookPostReceive,
|
subcmdHookPostReceive,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ var (
|
||||||
Description: "This command should only be called by Git",
|
Description: "This command should only be called by Git",
|
||||||
Action: runHookPreReceive,
|
Action: runHookPreReceive,
|
||||||
}
|
}
|
||||||
subcmdHookUpadte = cli.Command{
|
subcmdHookUpdate = cli.Command{
|
||||||
Name: "update",
|
Name: "update",
|
||||||
Usage: "Delegate update Git hook",
|
Usage: "Delegate update Git hook",
|
||||||
Description: "This command should only be called by Git",
|
Description: "This command should only be called by Git",
|
||||||
|
|
|
@ -121,11 +121,9 @@ func runWeb(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var listenAddr string
|
listenAddr := setting.HTTPAddr
|
||||||
if setting.Protocol == setting.UnixSocket {
|
if setting.Protocol != setting.UnixSocket {
|
||||||
listenAddr = fmt.Sprintf("%s", setting.HTTPAddr)
|
listenAddr += ":" + setting.HTTPPort
|
||||||
} else {
|
|
||||||
listenAddr = fmt.Sprintf("%s:%s", setting.HTTPAddr, setting.HTTPPort)
|
|
||||||
}
|
}
|
||||||
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubURL)
|
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubURL)
|
||||||
|
|
||||||
|
@ -135,6 +133,7 @@ func runWeb(ctx *cli.Context) error {
|
||||||
|
|
||||||
if setting.EnablePprof {
|
if setting.EnablePprof {
|
||||||
go func() {
|
go func() {
|
||||||
|
log.Info("Starting pprof server on localhost:6060")
|
||||||
log.Info("%v", http.ListenAndServe("localhost:6060", nil))
|
log.Info("%v", http.ListenAndServe("localhost:6060", nil))
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue