From b1b6def5bcb016d555e8078af404e8e2fa948748 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 20 Feb 2014 14:53:56 +0800 Subject: [PATCH] improved ssh supports --- conf/app.ini | 4 ++++ gogs.go | 3 +-- models/models.go | 2 ++ models/repo.go | 29 +++++++++++++++++++++-------- models/user.go | 23 +++++++++++++++++++++-- serve.go | 35 +++++++++++++++++------------------ 6 files changed, 66 insertions(+), 30 deletions(-) diff --git a/conf/app.ini b/conf/app.ini index c8953cc5f2..0003ad0325 100644 --- a/conf/app.ini +++ b/conf/app.ini @@ -1,4 +1,8 @@ APP_NAME = Gogs - Go Git Service +RUN_USER = git + +[repository] +ROOT = /home/git/gogs-repositories [server] HTTP_ADDR = diff --git a/gogs.go b/gogs.go index 63ad3318c7..bf2586d886 100644 --- a/gogs.go +++ b/gogs.go @@ -17,7 +17,7 @@ import ( // Test that go1.1 tag above is included in builds. main.go refers to this definition. const go11tag = true -const APP_VER = "0.0.0.0219" +const APP_VER = "0.0.0.0220" func init() { runtime.GOMAXPROCS(runtime.NumCPU()) @@ -36,5 +36,4 @@ func main() { cli.BoolFlag{"noterm", "disable color output"}, }...) app.Run(os.Args) - println("wo cao???") } diff --git a/models/models.go b/models/models.go index 8341f99616..0f8fcac1a8 100644 --- a/models/models.go +++ b/models/models.go @@ -77,6 +77,8 @@ func setEngine() { //x.ShowSQL = true log.Trace("Initialized database -> %s", dbName) + + RepoRootPath = utils.Cfg.MustValue("repository", "ROOT") } func init() { diff --git a/models/repo.go b/models/repo.go index d48c9a9787..27807303f9 100644 --- a/models/repo.go +++ b/models/repo.go @@ -11,6 +11,7 @@ import ( "time" git "github.com/libgit2/git2go" + "github.com/qiniu/log" ) type Repo struct { @@ -35,7 +36,7 @@ func IsRepositoryExist(user *User, reposName string) (bool, error) { } s, err := os.Stat(filepath.Join(RepoRootPath, user.Name, reposName)) if err != nil { - return false, err + return false, nil } return s.IsDir(), nil } @@ -44,9 +45,7 @@ func IsRepositoryExist(user *User, reposName string) (bool, error) { // create a repository for a user or orgnaziation // func CreateRepository(user *User, reposName string) (*Repo, error) { - p := filepath.Join(RepoRootPath, user.Name) - os.MkdirAll(p, os.ModePerm) - f := filepath.Join(p, reposName+".git") + f := RepoPath(user.Name, reposName) _, err := git.InitRepository(f, false) if err != nil { return nil, err @@ -58,19 +57,28 @@ func CreateRepository(user *User, reposName string) (*Repo, error) { session.Begin() _, err = session.Insert(&repo) if err != nil { - os.RemoveAll(f) + err2 := os.RemoveAll(f) + if err2 != nil { + log.Error("delete repo directory %s/%s failed", user.Name, reposName) + } session.Rollback() return nil, err } _, err = session.Exec("update user set num_repos = num_repos + 1 where id = ?", user.Id) if err != nil { - os.RemoveAll(f) + err2 := os.RemoveAll(f) + if err2 != nil { + log.Error("delete repo directory %s/%s failed", user.Name, reposName) + } session.Rollback() return nil, err } err = session.Commit() if err != nil { - os.RemoveAll(f) + err2 := os.RemoveAll(f) + if err2 != nil { + log.Error("delete repo directory %s/%s failed", user.Name, reposName) + } session.Rollback() return nil, err } @@ -100,6 +108,10 @@ func UnWatchRepository() { } +func RepoPath(userName, repoName string) string { + return filepath.Join(UserPath(userName), repoName+".git") +} + // DeleteRepository deletes a repository for a user or orgnaztion. func DeleteRepository(user *User, reposName string) (err error) { session := orm.NewSession() @@ -115,8 +127,9 @@ func DeleteRepository(user *User, reposName string) (err error) { session.Rollback() return err } - if err = os.RemoveAll(filepath.Join(RepoRootPath, user.Name, reposName+".git")); err != nil { + if err = os.RemoveAll(RepoPath(user.Name, reposName)); err != nil { // TODO: log and delete manully + log.Error("delete repo %s/%s failed", user.Name, reposName) return err } return nil diff --git a/models/user.go b/models/user.go index 2527a19774..4618273b3d 100644 --- a/models/user.go +++ b/models/user.go @@ -7,12 +7,15 @@ package models import ( "errors" "fmt" + "os" + "path/filepath" "strings" "time" "github.com/dchest/scrypt" "github.com/gogits/gogs/utils" + "github.com/gogits/gogs/utils/log" ) // User types. @@ -96,10 +99,22 @@ func RegisterUser(user *User) (err error) { user.LowerName = strings.ToLower(user.Name) user.Avatar = utils.EncodeMd5(user.Email) - user.Updated = time.Now() user.EncodePasswd() _, err = orm.Insert(user) - return err + if err != nil { + return err + } + + err = os.MkdirAll(UserPath(user.Name), os.ModePerm) + if err != nil { + _, err2 := orm.Id(user.Id).Delete(&User{}) + if err2 != nil { + log.Error("create userpath %s failed and delete table record faild", + user.Name) + } + return err + } + return nil } // UpdateUser updates user's information. @@ -129,6 +144,10 @@ func (user *User) EncodePasswd() error { return err } +func UserPath(userName string) string { + return filepath.Join(RepoRootPath, userName) +} + func GetUserByKeyId(keyId int64) (*User, error) { user := new(User) has, err := orm.Sql("select a.* from user as a, public_key as b where a.id = b.owner_id and b.id=?", keyId).Get(user) diff --git a/serve.go b/serve.go index 066faa30ec..6b4caa1dd7 100644 --- a/serve.go +++ b/serve.go @@ -4,7 +4,6 @@ import ( "fmt" "os" "os/exec" - "path/filepath" "strconv" "strings" @@ -66,16 +65,12 @@ func runServ(*cli.Context) { return } - f, _ := os.Create("test2.log") - f.WriteString(cmd) - f.Close() - - log.Info("cmd is %s", cmd) + println(cmd) verb, args := parseCmd(cmd) - rr := strings.SplitN(strings.Trim(args, "'"), "/", 1) + rr := strings.SplitN(strings.Trim(args, "'"), "/", 2) if len(rr) != 2 { - fmt.Printf("Unavilable repository") + println("Unavilable repository", args) return } repoName := rr[1] @@ -84,6 +79,9 @@ func runServ(*cli.Context) { } isWrite := In(verb, COMMANDS_WRITE) isRead := In(verb, COMMANDS_READONLY) + + println("repoPath:", models.RepoPath(user.Name, repoName)) + switch { case isWrite: has, err := models.HasAccess(user.Name, repoName, COMMANDS_WRITE[verb]) @@ -92,7 +90,7 @@ func runServ(*cli.Context) { return } if !has { - fmt.Println("You have no right to access this repository") + println("You have no right to access this repository") return } case isRead: @@ -109,36 +107,36 @@ func runServ(*cli.Context) { } } if !has { - fmt.Println("You have no right to access this repository") + println("You have no right to access this repository") return } default: - fmt.Println("Unknown command") + println("Unknown command") return } isExist, err := models.IsRepositoryExist(user, repoName) if err != nil { - fmt.Println("Inernel error") + println("Inernel error:", err.Error()) return } if !isExist { if isRead { - fmt.Println("Repository is not exist") + println("Repository", user.Name+"/"+repoName, "is not exist") return } else if isWrite { _, err := models.CreateRepository(user, repoName) if err != nil { - fmt.Println("Create repository failed") + println("Create repository failed") return } } } - fullPath := filepath.Join(models.RepoRootPath, user.Name, repoName+".git") + fullPath := models.RepoPath(user.Name, repoName) newcmd := fmt.Sprintf("%s '%s'", verb, fullPath) - fmt.Println(newcmd) + println(newcmd) gitcmd := exec.Command("git", "shell", "-c", newcmd) gitcmd.Stdout = os.Stdout gitcmd.Stderr = os.Stderr @@ -150,13 +148,14 @@ func runServ(*cli.Context) { } func parseCmd(cmd string) (string, string) { - ss := strings.SplitN(cmd, " ", 1) + ss := strings.SplitN(cmd, " ", 2) if len(ss) != 2 { return "", "" } + verb, args := ss[0], ss[1] if verb == "git" { - ss = strings.SplitN(args, " ", 1) + ss = strings.SplitN(args, " ", 2) args = ss[1] verb = fmt.Sprintf("%s %s", verb, ss[0]) }