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

install.go 11 kB

11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
9 years ago
11 years ago
11 years ago
9 years ago
11 years ago
11 years ago
11 years ago
11 years ago
9 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  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/user"
  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. }
  36. log.Info("Run Mode: %s", strings.Title(macaron.Env))
  37. }
  38. func NewServices() {
  39. setting.NewServices()
  40. mailer.NewContext()
  41. }
  42. // GlobalInit is for global configuration reload-able.
  43. func GlobalInit() {
  44. setting.NewContext()
  45. log.Trace("Custom path: %s", setting.CustomPath)
  46. log.Trace("Log path: %s", setting.LogRootPath)
  47. models.LoadConfigs()
  48. NewServices()
  49. if setting.InstallLock {
  50. models.LoadRepoConfig()
  51. models.NewRepoContext()
  52. if err := models.NewEngine(); err != nil {
  53. log.Fatal(4, "Fail to initialize ORM engine: %v", err)
  54. }
  55. models.HasEngine = true
  56. cron.NewContext()
  57. models.InitDeliverHooks()
  58. log.NewGitLogger(path.Join(setting.LogRootPath, "http.log"))
  59. }
  60. if models.EnableSQLite3 {
  61. log.Info("SQLite3 Supported")
  62. }
  63. if models.EnableTidb {
  64. log.Info("TiDB 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. dbOpts := []string{"MySQL", "PostgreSQL"}
  76. if models.EnableSQLite3 {
  77. dbOpts = append(dbOpts, "SQLite3")
  78. }
  79. if models.EnableTidb {
  80. dbOpts = append(dbOpts, "TiDB")
  81. }
  82. ctx.Data["DbOptions"] = dbOpts
  83. }
  84. func Install(ctx *middleware.Context) {
  85. form := auth.InstallForm{}
  86. // Database settings
  87. form.DbHost = models.DbCfg.Host
  88. form.DbUser = models.DbCfg.User
  89. form.DbName = models.DbCfg.Name
  90. form.DbPath = models.DbCfg.Path
  91. ctx.Data["CurDbOption"] = "MySQL"
  92. switch models.DbCfg.Type {
  93. case "postgres":
  94. ctx.Data["CurDbOption"] = "PostgreSQL"
  95. case "sqlite3":
  96. if models.EnableSQLite3 {
  97. ctx.Data["CurDbOption"] = "SQLite3"
  98. }
  99. case "tidb":
  100. if models.EnableTidb {
  101. ctx.Data["CurDbOption"] = "TiDB"
  102. }
  103. }
  104. // Application general settings
  105. form.AppName = setting.AppName
  106. form.RepoRootPath = setting.RepoRootPath
  107. // Note(unknwon): it's hard for Windows users change a running user,
  108. // so just use current one if config says default.
  109. if setting.IsWindows && setting.RunUser == "git" {
  110. form.RunUser = user.CurrentUsername()
  111. } else {
  112. form.RunUser = setting.RunUser
  113. }
  114. form.Domain = setting.Domain
  115. form.SSHPort = setting.SSHPort
  116. form.HTTPPort = setting.HttpPort
  117. form.AppUrl = setting.AppUrl
  118. // E-mail service settings
  119. if setting.MailService != nil {
  120. form.SMTPHost = setting.MailService.Host
  121. form.SMTPFrom = setting.MailService.From
  122. form.SMTPEmail = setting.MailService.User
  123. }
  124. form.RegisterConfirm = setting.Service.RegisterEmailConfirm
  125. form.MailNotify = setting.Service.EnableNotifyMail
  126. // Server and other services settings
  127. form.OfflineMode = setting.OfflineMode
  128. form.DisableGravatar = setting.DisableGravatar
  129. form.DisableRegistration = setting.Service.DisableRegistration
  130. form.EnableCaptcha = setting.Service.EnableCaptcha
  131. form.RequireSignInView = setting.Service.RequireSignInView
  132. auth.AssignForm(form, ctx.Data)
  133. ctx.HTML(200, INSTALL)
  134. }
  135. func InstallPost(ctx *middleware.Context, form auth.InstallForm) {
  136. ctx.Data["CurDbOption"] = form.DbType
  137. if ctx.HasError() {
  138. if ctx.HasValue("Err_SMTPEmail") {
  139. ctx.Data["Err_SMTP"] = true
  140. }
  141. if ctx.HasValue("Err_AdminName") ||
  142. ctx.HasValue("Err_AdminPasswd") ||
  143. ctx.HasValue("Err_AdminEmail") {
  144. ctx.Data["Err_Admin"] = true
  145. }
  146. ctx.HTML(200, INSTALL)
  147. return
  148. }
  149. if _, err := exec.LookPath("git"); err != nil {
  150. ctx.RenderWithErr(ctx.Tr("install.test_git_failed", err), INSTALL, &form)
  151. return
  152. }
  153. // Pass basic check, now test configuration.
  154. // Test database setting.
  155. dbTypes := map[string]string{"MySQL": "mysql", "PostgreSQL": "postgres", "SQLite3": "sqlite3", "TiDB": "tidb"}
  156. models.DbCfg.Type = dbTypes[form.DbType]
  157. models.DbCfg.Host = form.DbHost
  158. models.DbCfg.User = form.DbUser
  159. models.DbCfg.Passwd = form.DbPasswd
  160. models.DbCfg.Name = form.DbName
  161. models.DbCfg.SSLMode = form.SSLMode
  162. models.DbCfg.Path = form.DbPath
  163. if (models.DbCfg.Type == "sqlite3" || models.DbCfg.Type == "tidb") &&
  164. len(models.DbCfg.Path) == 0 {
  165. ctx.Data["Err_DbPath"] = true
  166. ctx.RenderWithErr(ctx.Tr("install.err_empty_db_path"), INSTALL, &form)
  167. return
  168. } else if models.DbCfg.Type == "tidb" &&
  169. strings.ContainsAny(path.Base(models.DbCfg.Path), ".-") {
  170. ctx.Data["Err_DbPath"] = true
  171. ctx.RenderWithErr(ctx.Tr("install.err_invalid_tidb_name"), INSTALL, &form)
  172. return
  173. }
  174. // Set test engine.
  175. var x *xorm.Engine
  176. if err := models.NewTestEngine(x); err != nil {
  177. if strings.Contains(err.Error(), `Unknown database type: sqlite3`) {
  178. ctx.Data["Err_DbType"] = true
  179. ctx.RenderWithErr(ctx.Tr("install.sqlite3_not_available", "http://gogs.io/docs/installation/install_from_binary.html"), INSTALL, &form)
  180. } else {
  181. ctx.Data["Err_DbSetting"] = true
  182. ctx.RenderWithErr(ctx.Tr("install.invalid_db_setting", err), INSTALL, &form)
  183. }
  184. return
  185. }
  186. // Test repository root path.
  187. if err := os.MkdirAll(form.RepoRootPath, os.ModePerm); err != nil {
  188. ctx.Data["Err_RepoRootPath"] = true
  189. ctx.RenderWithErr(ctx.Tr("install.invalid_repo_path", err), INSTALL, &form)
  190. return
  191. }
  192. // Check run user.
  193. curUser := user.CurrentUsername()
  194. if form.RunUser != curUser {
  195. ctx.Data["Err_RunUser"] = true
  196. ctx.RenderWithErr(ctx.Tr("install.run_user_not_match", form.RunUser, curUser), INSTALL, &form)
  197. return
  198. }
  199. // Check logic loophole between disable self-registration and no admin account.
  200. if form.DisableRegistration && len(form.AdminName) == 0 {
  201. ctx.Data["Err_Services"] = true
  202. ctx.Data["Err_Admin"] = true
  203. ctx.RenderWithErr(ctx.Tr("install.no_admin_and_disable_registration"), INSTALL, form)
  204. return
  205. }
  206. // Check admin password.
  207. if len(form.AdminName) > 0 && len(form.AdminPasswd) == 0 {
  208. ctx.Data["Err_Admin"] = true
  209. ctx.Data["Err_AdminPasswd"] = true
  210. ctx.RenderWithErr(ctx.Tr("install.err_empty_admin_password"), INSTALL, form)
  211. return
  212. }
  213. if form.AdminPasswd != form.AdminConfirmPasswd {
  214. ctx.Data["Err_Admin"] = true
  215. ctx.Data["Err_AdminPasswd"] = true
  216. ctx.RenderWithErr(ctx.Tr("form.password_not_match"), INSTALL, form)
  217. return
  218. }
  219. if form.AppUrl[len(form.AppUrl)-1] != '/' {
  220. form.AppUrl += "/"
  221. }
  222. // Save settings.
  223. cfg := ini.Empty()
  224. if com.IsFile(setting.CustomConf) {
  225. // Keeps custom settings if there is already something.
  226. if err := cfg.Append(setting.CustomConf); err != nil {
  227. log.Error(4, "Fail to load custom conf '%s': %v", setting.CustomConf, err)
  228. }
  229. }
  230. cfg.Section("database").Key("DB_TYPE").SetValue(models.DbCfg.Type)
  231. cfg.Section("database").Key("HOST").SetValue(models.DbCfg.Host)
  232. cfg.Section("database").Key("NAME").SetValue(models.DbCfg.Name)
  233. cfg.Section("database").Key("USER").SetValue(models.DbCfg.User)
  234. cfg.Section("database").Key("PASSWD").SetValue(models.DbCfg.Passwd)
  235. cfg.Section("database").Key("SSL_MODE").SetValue(models.DbCfg.SSLMode)
  236. cfg.Section("database").Key("PATH").SetValue(models.DbCfg.Path)
  237. cfg.Section("").Key("APP_NAME").SetValue(form.AppName)
  238. cfg.Section("repository").Key("ROOT").SetValue(form.RepoRootPath)
  239. cfg.Section("").Key("RUN_USER").SetValue(form.RunUser)
  240. cfg.Section("server").Key("DOMAIN").SetValue(form.Domain)
  241. cfg.Section("server").Key("HTTP_PORT").SetValue(form.HTTPPort)
  242. cfg.Section("server").Key("ROOT_URL").SetValue(form.AppUrl)
  243. if form.SSHPort == 0 {
  244. cfg.Section("server").Key("DISABLE_SSH").SetValue("true")
  245. } else {
  246. cfg.Section("server").Key("DISABLE_SSH").SetValue("false")
  247. cfg.Section("server").Key("SSH_PORT").SetValue(com.ToStr(form.SSHPort))
  248. }
  249. if len(strings.TrimSpace(form.SMTPHost)) > 0 {
  250. cfg.Section("mailer").Key("ENABLED").SetValue("true")
  251. cfg.Section("mailer").Key("HOST").SetValue(form.SMTPHost)
  252. cfg.Section("mailer").Key("FROM").SetValue(form.SMTPFrom)
  253. cfg.Section("mailer").Key("USER").SetValue(form.SMTPEmail)
  254. cfg.Section("mailer").Key("PASSWD").SetValue(form.SMTPPasswd)
  255. } else {
  256. cfg.Section("mailer").Key("ENABLED").SetValue("false")
  257. }
  258. cfg.Section("service").Key("REGISTER_EMAIL_CONFIRM").SetValue(com.ToStr(form.RegisterConfirm))
  259. cfg.Section("service").Key("ENABLE_NOTIFY_MAIL").SetValue(com.ToStr(form.MailNotify))
  260. cfg.Section("server").Key("OFFLINE_MODE").SetValue(com.ToStr(form.OfflineMode))
  261. cfg.Section("picture").Key("DISABLE_GRAVATAR").SetValue(com.ToStr(form.DisableGravatar))
  262. cfg.Section("service").Key("DISABLE_REGISTRATION").SetValue(com.ToStr(form.DisableRegistration))
  263. cfg.Section("service").Key("ENABLE_CAPTCHA").SetValue(com.ToStr(form.EnableCaptcha))
  264. cfg.Section("service").Key("REQUIRE_SIGNIN_VIEW").SetValue(com.ToStr(form.RequireSignInView))
  265. cfg.Section("").Key("RUN_MODE").SetValue("prod")
  266. cfg.Section("session").Key("PROVIDER").SetValue("file")
  267. cfg.Section("log").Key("MODE").SetValue("file")
  268. cfg.Section("log").Key("LEVEL").SetValue("Info")
  269. cfg.Section("security").Key("INSTALL_LOCK").SetValue("true")
  270. cfg.Section("security").Key("SECRET_KEY").SetValue(base.GetRandomString(15))
  271. os.MkdirAll(filepath.Dir(setting.CustomConf), os.ModePerm)
  272. if err := cfg.SaveTo(setting.CustomConf); err != nil {
  273. ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), INSTALL, &form)
  274. return
  275. }
  276. GlobalInit()
  277. // Create admin account.
  278. if len(form.AdminName) > 0 {
  279. if err := models.CreateUser(&models.User{
  280. Name: form.AdminName,
  281. Email: form.AdminEmail,
  282. Passwd: form.AdminPasswd,
  283. IsAdmin: true,
  284. IsActive: true,
  285. }); err != nil {
  286. if !models.IsErrUserAlreadyExist(err) {
  287. setting.InstallLock = false
  288. ctx.Data["Err_AdminName"] = true
  289. ctx.Data["Err_AdminEmail"] = true
  290. ctx.RenderWithErr(ctx.Tr("install.invalid_admin_setting", err), INSTALL, &form)
  291. return
  292. }
  293. log.Info("Admin account already exist")
  294. }
  295. }
  296. log.Info("First-time run install finished!")
  297. ctx.Flash.Success(ctx.Tr("install.install_success"))
  298. ctx.Redirect(form.AppUrl + "user/login")
  299. }