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.

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