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.

306 lines
9.0 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
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/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. macaron.ColorLog = false
  34. setting.ProdMode = true
  35. case "test":
  36. macaron.Env = macaron.TEST
  37. }
  38. log.Info("Run Mode: %s", strings.Title(macaron.Env))
  39. }
  40. func NewServices() {
  41. setting.NewServices()
  42. social.NewOauthService()
  43. }
  44. // GlobalInit is for global configuration reload-able.
  45. func GlobalInit() {
  46. setting.NewConfigContext()
  47. log.Trace("Custom path: %s", setting.CustomPath)
  48. log.Trace("Log path: %s", setting.LogRootPath)
  49. mailer.NewMailerContext()
  50. models.LoadModelsConfig()
  51. NewServices()
  52. if setting.InstallLock {
  53. models.LoadRepoConfig()
  54. models.NewRepoContext()
  55. if err := models.NewEngine(); err != nil {
  56. log.Fatal(4, "Fail to initialize ORM engine: %v", err)
  57. }
  58. models.HasEngine = true
  59. cron.NewCronContext()
  60. models.InitDeliverHooks()
  61. log.NewGitLogger(path.Join(setting.LogRootPath, "http.log"))
  62. }
  63. if models.EnableSQLite3 {
  64. log.Info("SQLite3 Supported")
  65. }
  66. checkRunMode()
  67. }
  68. func InstallInit(ctx *middleware.Context) {
  69. if setting.InstallLock {
  70. ctx.Handle(404, "Install", errors.New("Installation is prohibited"))
  71. return
  72. }
  73. ctx.Data["Title"] = ctx.Tr("install.install")
  74. ctx.Data["PageIsInstall"] = true
  75. ctx.Data["DbOptions"] = []string{"MySQL", "PostgreSQL", "SQLite3"}
  76. }
  77. func Install(ctx *middleware.Context) {
  78. form := auth.InstallForm{}
  79. // Database settings
  80. form.DbHost = models.DbCfg.Host
  81. form.DbUser = models.DbCfg.User
  82. form.DbName = models.DbCfg.Name
  83. form.DbPath = models.DbCfg.Path
  84. if models.EnableSQLite3 {
  85. ctx.Data["CurDbOption"] = "SQLite3" // Default when enabled.
  86. } else {
  87. ctx.Data["CurDbOption"] = "MySQL"
  88. }
  89. // Application general settings
  90. form.AppName = setting.AppName
  91. form.RepoRootPath = setting.RepoRootPath
  92. // Note(unknwon): it's hard for Windows users change a running user,
  93. // so just use current one if config says default.
  94. if setting.IsWindows && setting.RunUser == "git" {
  95. form.RunUser = os.Getenv("USER")
  96. if len(form.RunUser) == 0 {
  97. form.RunUser = os.Getenv("USERNAME")
  98. }
  99. } else {
  100. form.RunUser = setting.RunUser
  101. }
  102. form.Domain = setting.Domain
  103. form.HTTPPort = setting.HttpPort
  104. form.AppUrl = setting.AppUrl
  105. // E-mail service settings
  106. if setting.MailService != nil {
  107. form.SMTPHost = setting.MailService.Host
  108. form.SMTPFrom = setting.MailService.From
  109. form.SMTPEmail = setting.MailService.User
  110. }
  111. form.RegisterConfirm = setting.Service.RegisterEmailConfirm
  112. form.MailNotify = setting.Service.EnableNotifyMail
  113. // Server and other services settings
  114. form.OfflineMode = setting.OfflineMode
  115. form.DisableRegistration = setting.Service.DisableRegistration
  116. form.RequireSignInView = setting.Service.RequireSignInView
  117. auth.AssignForm(form, ctx.Data)
  118. ctx.HTML(200, INSTALL)
  119. }
  120. func InstallPost(ctx *middleware.Context, form auth.InstallForm) {
  121. ctx.Data["CurDbOption"] = form.DbType
  122. if ctx.HasError() {
  123. if ctx.HasValue("Err_SMTPEmail") {
  124. ctx.Data["Err_SMTP"] = true
  125. }
  126. if ctx.HasValue("Err_AdminName") ||
  127. ctx.HasValue("Err_AdminPasswd") ||
  128. ctx.HasValue("Err_AdminEmail") {
  129. ctx.Data["Err_Admin"] = true
  130. }
  131. ctx.HTML(200, INSTALL)
  132. return
  133. }
  134. if _, err := exec.LookPath("git"); err != nil {
  135. ctx.RenderWithErr(ctx.Tr("install.test_git_failed", err), INSTALL, &form)
  136. return
  137. }
  138. // Pass basic check, now test configuration.
  139. // Test database setting.
  140. dbTypes := map[string]string{"MySQL": "mysql", "PostgreSQL": "postgres", "SQLite3": "sqlite3"}
  141. models.DbCfg.Type = dbTypes[form.DbType]
  142. models.DbCfg.Host = form.DbHost
  143. models.DbCfg.User = form.DbUser
  144. models.DbCfg.Passwd = form.DbPasswd
  145. models.DbCfg.Name = form.DbName
  146. models.DbCfg.SSLMode = form.SSLMode
  147. models.DbCfg.Path = form.DbPath
  148. if models.DbCfg.Type == "sqlite3" && len(models.DbCfg.Path) == 0 {
  149. ctx.Data["Err_DbPath"] = true
  150. ctx.RenderWithErr(ctx.Tr("install.err_empty_sqlite_path"), INSTALL, &form)
  151. return
  152. }
  153. // Set test engine.
  154. var x *xorm.Engine
  155. if err := models.NewTestEngine(x); err != nil {
  156. if strings.Contains(err.Error(), `Unknown database type: sqlite3`) {
  157. ctx.Data["Err_DbType"] = true
  158. ctx.RenderWithErr(ctx.Tr("install.sqlite3_not_available", "http://gogs.io/docs/installation/install_from_binary.html"), INSTALL, &form)
  159. } else {
  160. ctx.Data["Err_DbSetting"] = true
  161. ctx.RenderWithErr(ctx.Tr("install.invalid_db_setting", err), INSTALL, &form)
  162. }
  163. return
  164. }
  165. // Test repository root path.
  166. if err := os.MkdirAll(form.RepoRootPath, os.ModePerm); err != nil {
  167. ctx.Data["Err_RepoRootPath"] = true
  168. ctx.RenderWithErr(ctx.Tr("install.invalid_repo_path", err), INSTALL, &form)
  169. return
  170. }
  171. // Check run user.
  172. curUser := os.Getenv("USER")
  173. if len(curUser) == 0 {
  174. curUser = os.Getenv("USERNAME")
  175. }
  176. if form.RunUser != curUser {
  177. ctx.Data["Err_RunUser"] = true
  178. ctx.RenderWithErr(ctx.Tr("install.run_user_not_match", form.RunUser, curUser), INSTALL, &form)
  179. return
  180. }
  181. // Check admin password.
  182. if form.AdminPasswd != form.AdminConfirmPasswd {
  183. ctx.Data["Err_Admin"] = true
  184. ctx.Data["Err_AdminPasswd"] = true
  185. ctx.RenderWithErr(ctx.Tr("form.password_not_match"), INSTALL, form)
  186. return
  187. }
  188. if form.AppUrl[len(form.AppUrl)-1] != '/' {
  189. form.AppUrl += "/"
  190. }
  191. // Save settings.
  192. cfg := ini.Empty()
  193. if com.IsFile(setting.CustomConf) {
  194. // Keeps custom settings if there is already something.
  195. if err := cfg.Append(setting.CustomConf); err != nil {
  196. log.Error(4, "Fail to load custom conf '%s': %v", setting.CustomConf, err)
  197. }
  198. }
  199. cfg.Section("database").Key("DB_TYPE").SetValue(models.DbCfg.Type)
  200. cfg.Section("database").Key("HOST").SetValue(models.DbCfg.Host)
  201. cfg.Section("database").Key("NAME").SetValue(models.DbCfg.Name)
  202. cfg.Section("database").Key("USER").SetValue(models.DbCfg.User)
  203. cfg.Section("database").Key("PASSWD").SetValue(models.DbCfg.Passwd)
  204. cfg.Section("database").Key("SSL_MODE").SetValue(models.DbCfg.SSLMode)
  205. cfg.Section("database").Key("PATH").SetValue(models.DbCfg.Path)
  206. cfg.Section("").Key("APP_NAME").SetValue(form.AppName)
  207. cfg.Section("repository").Key("ROOT").SetValue(form.RepoRootPath)
  208. cfg.Section("").Key("RUN_USER").SetValue(form.RunUser)
  209. cfg.Section("server").Key("DOMAIN").SetValue(form.Domain)
  210. cfg.Section("server").Key("HTTP_PORT").SetValue(form.HTTPPort)
  211. cfg.Section("server").Key("ROOT_URL").SetValue(form.AppUrl)
  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. }