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.

303 lines
8.9 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
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 routers
  5. import (
  6. "errors"
  7. "os"
  8. "os/exec"
  9. "path"
  10. "path/filepath"
  11. "strings"
  12. "github.com/Unknwon/com"
  13. "github.com/Unknwon/macaron"
  14. "github.com/go-xorm/xorm"
  15. "gopkg.in/ini.v1"
  16. "github.com/gogits/gogs/models"
  17. "github.com/gogits/gogs/modules/auth"
  18. "github.com/gogits/gogs/modules/base"
  19. "github.com/gogits/gogs/modules/cron"
  20. "github.com/gogits/gogs/modules/log"
  21. "github.com/gogits/gogs/modules/mailer"
  22. "github.com/gogits/gogs/modules/middleware"
  23. "github.com/gogits/gogs/modules/setting"
  24. "github.com/gogits/gogs/modules/social"
  25. )
  26. const (
  27. INSTALL base.TplName = "install"
  28. )
  29. func checkRunMode() {
  30. switch setting.Cfg.Section("").Key("RUN_MODE").String() {
  31. case "prod":
  32. macaron.Env = macaron.PROD
  33. setting.ProdMode = true
  34. case "test":
  35. macaron.Env = macaron.TEST
  36. }
  37. log.Info("Run Mode: %s", strings.Title(macaron.Env))
  38. }
  39. func NewServices() {
  40. setting.NewServices()
  41. social.NewOauthService()
  42. }
  43. // GlobalInit is for global configuration reload-able.
  44. func GlobalInit() {
  45. setting.NewConfigContext()
  46. log.Trace("Custom path: %s", setting.CustomPath)
  47. log.Trace("Log path: %s", setting.LogRootPath)
  48. mailer.NewMailerContext()
  49. models.LoadModelsConfig()
  50. NewServices()
  51. if setting.InstallLock {
  52. models.LoadRepoConfig()
  53. models.NewRepoContext()
  54. if err := models.NewEngine(); err != nil {
  55. log.Fatal(4, "Fail to initialize ORM engine: %v", err)
  56. }
  57. models.HasEngine = true
  58. cron.NewCronContext()
  59. log.NewGitLogger(path.Join(setting.LogRootPath, "http.log"))
  60. }
  61. if models.EnableSQLite3 {
  62. log.Info("SQLite3 Enabled")
  63. }
  64. checkRunMode()
  65. }
  66. func InstallInit(ctx *middleware.Context) {
  67. if setting.InstallLock {
  68. ctx.Handle(404, "Install", errors.New("Installation is prohibited"))
  69. return
  70. }
  71. ctx.Data["Title"] = ctx.Tr("install.install")
  72. ctx.Data["PageIsInstall"] = true
  73. ctx.Data["DbOptions"] = []string{"MySQL", "PostgreSQL", "SQLite3"}
  74. }
  75. func Install(ctx *middleware.Context) {
  76. form := auth.InstallForm{}
  77. // Database settings
  78. form.DbHost = models.DbCfg.Host
  79. form.DbUser = models.DbCfg.User
  80. form.DbName = models.DbCfg.Name
  81. form.DbPath = models.DbCfg.Path
  82. curDbOp := ""
  83. if models.EnableSQLite3 {
  84. curDbOp = "SQLite3" // Default when enabled.
  85. }
  86. ctx.Data["CurDbOption"] = curDbOp
  87. // Application general settings
  88. form.AppName = setting.AppName
  89. form.RepoRootPath = setting.RepoRootPath
  90. // Note(unknwon): it's hard for Windows users change a running user,
  91. // so just use current one if config says default.
  92. if setting.IsWindows && setting.RunUser == "git" {
  93. form.RunUser = os.Getenv("USER")
  94. if len(form.RunUser) == 0 {
  95. form.RunUser = os.Getenv("USERNAME")
  96. }
  97. } else {
  98. form.RunUser = setting.RunUser
  99. }
  100. form.Domain = setting.Domain
  101. form.HTTPPort = setting.HttpPort
  102. form.AppUrl = setting.AppUrl
  103. // E-mail service settings
  104. if setting.MailService != nil {
  105. form.SMTPHost = setting.MailService.Host
  106. form.SMTPFrom = setting.MailService.From
  107. form.SMTPEmail = setting.MailService.User
  108. }
  109. form.RegisterConfirm = setting.Service.RegisterEmailConfirm
  110. form.MailNotify = setting.Service.EnableNotifyMail
  111. // Server and other services settings
  112. form.OfflineMode = setting.OfflineMode
  113. form.DisableRegistration = setting.Service.DisableRegistration
  114. form.RequireSignInView = setting.Service.RequireSignInView
  115. auth.AssignForm(form, ctx.Data)
  116. ctx.HTML(200, INSTALL)
  117. }
  118. func InstallPost(ctx *middleware.Context, form auth.InstallForm) {
  119. ctx.Data["CurDbOption"] = form.DbType
  120. if ctx.HasError() {
  121. if ctx.HasValue("Err_SMTPEmail") {
  122. ctx.Data["Err_SMTP"] = true
  123. }
  124. if ctx.HasValue("Err_AdminName") ||
  125. ctx.HasValue("Err_AdminPasswd") ||
  126. ctx.HasValue("Err_AdminEmail") {
  127. ctx.Data["Err_Admin"] = true
  128. }
  129. ctx.HTML(200, INSTALL)
  130. return
  131. }
  132. if _, err := exec.LookPath("git"); err != nil {
  133. ctx.RenderWithErr(ctx.Tr("install.test_git_failed", err), INSTALL, &form)
  134. return
  135. }
  136. // Pass basic check, now test configuration.
  137. // Test database setting.
  138. dbTypes := map[string]string{"MySQL": "mysql", "PostgreSQL": "postgres", "SQLite3": "sqlite3"}
  139. models.DbCfg.Type = dbTypes[form.DbType]
  140. models.DbCfg.Host = form.DbHost
  141. models.DbCfg.User = form.DbUser
  142. models.DbCfg.Passwd = form.DbPasswd
  143. models.DbCfg.Name = form.DbName
  144. models.DbCfg.SSLMode = form.SSLMode
  145. models.DbCfg.Path = form.DbPath
  146. if models.DbCfg.Type == "sqlite3" && len(models.DbCfg.Path) == 0 {
  147. ctx.Data["Err_DbPath"] = true
  148. ctx.RenderWithErr(ctx.Tr("install.err_empty_sqlite_path"), INSTALL, &form)
  149. return
  150. }
  151. // Set test engine.
  152. var x *xorm.Engine
  153. if err := models.NewTestEngine(x); err != nil {
  154. if strings.Contains(err.Error(), `Unknown database type: sqlite3`) {
  155. ctx.Data["Err_DbType"] = true
  156. ctx.RenderWithErr(ctx.Tr("install.sqlite3_not_available", "http://gogs.io/docs/installation/install_from_binary.html"), INSTALL, &form)
  157. } else {
  158. ctx.Data["Err_DbSetting"] = true
  159. ctx.RenderWithErr(ctx.Tr("install.invalid_db_setting", err), INSTALL, &form)
  160. }
  161. return
  162. }
  163. // Test repository root path.
  164. if err := os.MkdirAll(form.RepoRootPath, os.ModePerm); err != nil {
  165. ctx.Data["Err_RepoRootPath"] = true
  166. ctx.RenderWithErr(ctx.Tr("install.invalid_repo_path", err), INSTALL, &form)
  167. return
  168. }
  169. // Check run user.
  170. curUser := os.Getenv("USER")
  171. if len(curUser) == 0 {
  172. curUser = os.Getenv("USERNAME")
  173. }
  174. if form.RunUser != curUser {
  175. ctx.Data["Err_RunUser"] = true
  176. ctx.RenderWithErr(ctx.Tr("install.run_user_not_match", form.RunUser, curUser), INSTALL, &form)
  177. return
  178. }
  179. // Check admin password.
  180. if form.AdminPasswd != form.AdminConfirmPasswd {
  181. ctx.Data["Err_AdminPasswd"] = true
  182. ctx.RenderWithErr(ctx.Tr("form.password_not_match"), INSTALL, form)
  183. return
  184. }
  185. if form.AppUrl[len(form.AppUrl)-1] != '/' {
  186. form.AppUrl += "/"
  187. }
  188. // Save settings.
  189. cfg := ini.Empty()
  190. if com.IsFile(setting.CustomConf) {
  191. // Keeps custom settings if there is already something.
  192. if err := cfg.Append(setting.CustomConf); err != nil {
  193. log.Error(4, "Fail to load custom conf '%s': %v", setting.CustomConf, err)
  194. }
  195. }
  196. cfg.Section("database").Key("DB_TYPE").SetValue(models.DbCfg.Type)
  197. cfg.Section("database").Key("HOST").SetValue(models.DbCfg.Host)
  198. cfg.Section("database").Key("NAME").SetValue(models.DbCfg.Name)
  199. cfg.Section("database").Key("USER").SetValue(models.DbCfg.User)
  200. cfg.Section("database").Key("PASSWD").SetValue(models.DbCfg.Passwd)
  201. cfg.Section("database").Key("SSL_MODE").SetValue(models.DbCfg.SSLMode)
  202. cfg.Section("database").Key("PATH").SetValue(models.DbCfg.Path)
  203. cfg.Section("").Key("APP_NAME").SetValue(form.AppName)
  204. cfg.Section("repository").Key("ROOT").SetValue(form.RepoRootPath)
  205. cfg.Section("").Key("RUN_USER").SetValue(form.RunUser)
  206. cfg.Section("server").Key("DOMAIN").SetValue(form.Domain)
  207. cfg.Section("server").Key("HTTP_PORT").SetValue(form.HTTPPort)
  208. cfg.Section("server").Key("ROOT_URL").SetValue(form.AppUrl)
  209. if len(strings.TrimSpace(form.SMTPHost)) > 0 {
  210. cfg.Section("mailer").Key("ENABLED").SetValue("true")
  211. cfg.Section("mailer").Key("HOST").SetValue(form.SMTPHost)
  212. cfg.Section("mailer").Key("FROM").SetValue(form.SMTPFrom)
  213. cfg.Section("mailer").Key("USER").SetValue(form.SMTPEmail)
  214. cfg.Section("mailer").Key("PASSWD").SetValue(form.SMTPPasswd)
  215. } else {
  216. cfg.Section("mailer").Key("ENABLED").SetValue("false")
  217. }
  218. cfg.Section("service").Key("REGISTER_EMAIL_CONFIRM").SetValue(com.ToStr(form.RegisterConfirm))
  219. cfg.Section("service").Key("ENABLE_NOTIFY_MAIL").SetValue(com.ToStr(form.MailNotify))
  220. cfg.Section("server").Key("OFFLINE_MODE").SetValue(com.ToStr(form.OfflineMode))
  221. cfg.Section("service").Key("DISABLE_REGISTRATION").SetValue(com.ToStr(form.DisableRegistration))
  222. cfg.Section("service").Key("REQUIRE_SIGNIN_VIEW").SetValue(com.ToStr(form.RequireSignInView))
  223. cfg.Section("").Key("RUN_MODE").SetValue("prod")
  224. cfg.Section("session").Key("PROVIDER").SetValue("file")
  225. cfg.Section("log").Key("MODE").SetValue("file")
  226. cfg.Section("log").Key("LEVEL").SetValue("Info")
  227. cfg.Section("security").Key("INSTALL_LOCK").SetValue("true")
  228. cfg.Section("security").Key("SECRET_KEY").SetValue(base.GetRandomString(15))
  229. os.MkdirAll(filepath.Dir(setting.CustomConf), os.ModePerm)
  230. if err := cfg.SaveTo(setting.CustomConf); err != nil {
  231. ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), INSTALL, &form)
  232. return
  233. }
  234. GlobalInit()
  235. // Create admin account.
  236. if len(form.AdminName) > 0 {
  237. if err := models.CreateUser(&models.User{
  238. Name: form.AdminName,
  239. Email: form.AdminEmail,
  240. Passwd: form.AdminPasswd,
  241. IsAdmin: true,
  242. IsActive: true,
  243. }); err != nil {
  244. if !models.IsErrUserAlreadyExist(err) {
  245. setting.InstallLock = false
  246. ctx.Data["Err_AdminName"] = true
  247. ctx.Data["Err_AdminEmail"] = true
  248. ctx.RenderWithErr(ctx.Tr("install.invalid_admin_setting", err), INSTALL, &form)
  249. return
  250. }
  251. log.Info("Admin account already exist")
  252. }
  253. }
  254. log.Info("First-time run install finished!")
  255. ctx.Flash.Success(ctx.Tr("install.install_success"))
  256. ctx.Redirect(form.AppUrl + "user/login")
  257. }