You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

181 lines
3.9 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package cmd
  5. import (
  6. "bufio"
  7. "fmt"
  8. "io"
  9. "io/ioutil"
  10. "os"
  11. "path"
  12. "runtime"
  13. "strings"
  14. "github.com/codegangsta/cli"
  15. "github.com/gogits/gogs/models"
  16. "github.com/gogits/gogs/modules/setting"
  17. )
  18. var CmdFix = cli.Command{
  19. Name: "fix",
  20. Usage: "This command for upgrade from old version",
  21. Action: runFix,
  22. Subcommands: fixCommands,
  23. Flags: []cli.Flag{},
  24. }
  25. func runFix(ctx *cli.Context) {
  26. }
  27. var fixCommands = []cli.Command{
  28. {
  29. Name: "location",
  30. Usage: "Change Gogs app location",
  31. Description: `Command location fixes location change of Gogs
  32. gogs fix location <old Gogs path>
  33. `,
  34. Action: runFixLocation,
  35. },
  36. }
  37. // rewriteAuthorizedKeys replaces old Gogs path to the new one.
  38. func rewriteAuthorizedKeys(sshPath, oldPath, newPath string) error {
  39. fr, err := os.Open(sshPath)
  40. if err != nil {
  41. return err
  42. }
  43. defer fr.Close()
  44. tmpPath := sshPath + ".tmp"
  45. fw, err := os.Create(tmpPath)
  46. if err != nil {
  47. return err
  48. }
  49. defer fw.Close()
  50. oldPath = "command=\"" + oldPath + " serv"
  51. newPath = "command=\"" + newPath + " serv"
  52. buf := bufio.NewReader(fr)
  53. for {
  54. line, errRead := buf.ReadString('\n')
  55. line = strings.TrimSpace(line)
  56. if errRead != nil {
  57. if errRead != io.EOF {
  58. return errRead
  59. }
  60. // Reached end of file, if nothing to read then break,
  61. // otherwise handle the last line.
  62. if len(line) == 0 {
  63. break
  64. }
  65. }
  66. // Still finding the line, copy the line that currently read.
  67. if _, err = fw.WriteString(strings.Replace(line, oldPath, newPath, 1) + "\n"); err != nil {
  68. return err
  69. }
  70. if errRead == io.EOF {
  71. break
  72. }
  73. }
  74. if err = os.Remove(sshPath); err != nil {
  75. return err
  76. }
  77. return os.Rename(tmpPath, sshPath)
  78. }
  79. func rewriteUpdateHook(path, appPath string) error {
  80. if runtime.GOOS == "windows" {
  81. rp := strings.NewReplacer("\\", "/")
  82. appPath = "\"" + rp.Replace(appPath) + "\""
  83. } else {
  84. rp := strings.NewReplacer("\\", "/", " ", "\\ ")
  85. appPath = rp.Replace(appPath)
  86. }
  87. if err := ioutil.WriteFile(path, []byte(fmt.Sprintf(models.TPL_UPDATE_HOOK,
  88. setting.ScriptType, appPath)), os.ModePerm); err != nil {
  89. return err
  90. }
  91. return nil
  92. }
  93. func walkDir(rootPath, recPath, appPath string, depth int) error {
  94. depth++
  95. if depth > 3 {
  96. return nil
  97. } else if depth == 3 {
  98. if err := rewriteUpdateHook(path.Join(rootPath, "hooks/update"), appPath); err != nil {
  99. return err
  100. }
  101. }
  102. dir, err := os.Open(rootPath)
  103. if err != nil {
  104. return err
  105. }
  106. defer dir.Close()
  107. fis, err := dir.Readdir(0)
  108. if err != nil {
  109. return err
  110. }
  111. for _, fi := range fis {
  112. if strings.Contains(fi.Name(), ".DS_Store") {
  113. continue
  114. }
  115. relPath := path.Join(recPath, fi.Name())
  116. curPath := path.Join(rootPath, fi.Name())
  117. if fi.IsDir() {
  118. if err = walkDir(curPath, relPath, appPath, depth); err != nil {
  119. return err
  120. }
  121. }
  122. }
  123. return nil
  124. }
  125. func runFixLocation(ctx *cli.Context) {
  126. if len(ctx.Args()) != 1 {
  127. fmt.Println("Incorrect arguments number, expect 1")
  128. os.Exit(2)
  129. }
  130. execPath, _ := setting.ExecPath()
  131. oldPath := ctx.Args().First()
  132. fmt.Printf("Old location: %s\n", oldPath)
  133. fmt.Println("This command should be executed in the new Gogs path")
  134. fmt.Printf("Do you want to change Gogs app path from old location to:\n")
  135. fmt.Printf("-> %s?\n", execPath)
  136. fmt.Print("Press <enter> to continue, use <Ctrl+c> to exit.")
  137. fmt.Scanln()
  138. // Fix in authorized_keys file.
  139. sshPath := path.Join(models.SshPath, "authorized_keys")
  140. fmt.Printf("Fixing pathes in file: %s\n", sshPath)
  141. if err := rewriteAuthorizedKeys(sshPath, oldPath, execPath); err != nil {
  142. fmt.Println(err)
  143. os.Exit(1)
  144. }
  145. // Fix position in gogs-repositories.
  146. setting.NewConfigContext()
  147. fmt.Printf("Fixing pathes in repositories: %s\n", setting.RepoRootPath)
  148. if err := walkDir(setting.RepoRootPath, "", execPath, 0); err != nil {
  149. fmt.Println(err)
  150. os.Exit(1)
  151. }
  152. fmt.Println("Fix position finished!")
  153. }