2014-03-25 12:51:42 +04:00
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package routers
2014-03-28 15:26:22 +04:00
import (
"errors"
2014-03-30 01:50:51 +04:00
"os"
2014-04-08 23:27:35 +04:00
"os/exec"
2014-03-30 01:50:51 +04:00
"strings"
"github.com/Unknwon/goconfig"
2014-03-30 20:11:28 +04:00
"github.com/go-martini/martini"
2014-04-18 17:35:09 +04:00
"github.com/go-xorm/xorm"
2014-04-06 21:00:20 +04:00
qlog "github.com/qiniu/log"
2014-03-28 15:26:22 +04:00
"github.com/gogits/gogs/models"
2014-03-29 02:40:31 +04:00
"github.com/gogits/gogs/modules/auth"
2014-03-28 15:26:22 +04:00
"github.com/gogits/gogs/modules/base"
2014-04-13 05:30:09 +04:00
"github.com/gogits/gogs/modules/cron"
2014-03-30 01:50:51 +04:00
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/mailer"
2014-03-28 15:26:22 +04:00
"github.com/gogits/gogs/modules/middleware"
2014-04-14 02:12:07 +04:00
"github.com/gogits/gogs/modules/social"
2014-03-28 15:26:22 +04:00
)
2014-03-30 01:50:51 +04:00
// Check run mode(Default of martini is Dev).
func checkRunMode ( ) {
switch base . Cfg . MustValue ( "" , "RUN_MODE" ) {
case "prod" :
martini . Env = martini . Prod
2014-04-27 11:05:13 +04:00
base . ProdMode = true
2014-03-30 01:50:51 +04:00
case "test" :
martini . Env = martini . Test
}
log . Info ( "Run Mode: %s" , strings . Title ( martini . Env ) )
}
2014-04-14 02:12:07 +04:00
func NewServices ( ) {
base . NewBaseServices ( )
social . NewOauthService ( )
}
2014-03-30 01:50:51 +04:00
// GlobalInit is for global configuration reload-able.
func GlobalInit ( ) {
base . NewConfigContext ( )
mailer . NewMailerContext ( )
models . LoadModelsConfig ( )
models . LoadRepoConfig ( )
models . NewRepoContext ( )
2014-04-20 06:13:22 +04:00
NewServices ( )
2014-03-30 18:47:08 +04:00
if base . InstallLock {
if err := models . NewEngine ( ) ; err != nil {
2014-04-06 21:00:20 +04:00
qlog . Fatal ( err )
2014-03-30 18:47:08 +04:00
}
models . HasEngine = true
2014-04-20 06:13:22 +04:00
if models . EnableSQLite3 {
log . Info ( "SQLite3 Enabled" )
}
2014-04-13 05:30:09 +04:00
cron . NewCronContext ( )
2014-03-30 01:50:51 +04:00
}
checkRunMode ( )
}
2014-04-27 08:34:48 +04:00
func renderDbOption ( ctx * middleware . Context ) {
ctx . Data [ "DbOptions" ] = [ ] string { "MySQL" , "PostgreSQL" , "SQLite3" }
}
2014-04-11 00:36:50 +04:00
func Install ( ctx * middleware . Context , form auth . InstallForm ) {
2014-03-28 15:26:22 +04:00
if base . InstallLock {
ctx . Handle ( 404 , "install.Install" , errors . New ( "Installation is prohibited" ) )
return
}
2014-03-25 12:51:42 +04:00
ctx . Data [ "Title" ] = "Install"
2014-03-28 15:26:22 +04:00
ctx . Data [ "PageIsInstall" ] = true
2014-05-05 21:08:01 +04:00
// Get and assign values to install form.
2014-04-10 22:37:43 +04:00
if len ( form . Host ) == 0 {
form . Host = models . DbCfg . Host
}
if len ( form . User ) == 0 {
form . User = models . DbCfg . User
}
if len ( form . Passwd ) == 0 {
form . Passwd = models . DbCfg . Pwd
}
if len ( form . DatabaseName ) == 0 {
form . DatabaseName = models . DbCfg . Name
}
if len ( form . DatabasePath ) == 0 {
form . DatabasePath = models . DbCfg . Path
}
2014-03-30 01:50:51 +04:00
2014-04-10 22:37:43 +04:00
if len ( form . RepoRootPath ) == 0 {
form . RepoRootPath = base . RepoRootPath
}
if len ( form . RunUser ) == 0 {
form . RunUser = base . RunUser
}
if len ( form . Domain ) == 0 {
form . Domain = base . Domain
}
if len ( form . AppUrl ) == 0 {
form . AppUrl = base . AppUrl
}
2014-03-30 01:50:51 +04:00
2014-04-27 08:34:48 +04:00
renderDbOption ( ctx )
2014-05-05 21:08:01 +04:00
curDbOp := ""
2014-04-27 08:34:48 +04:00
if models . EnableSQLite3 {
2014-05-05 21:08:01 +04:00
curDbOp = "SQLite3" // Default when enabled.
2014-04-27 08:34:48 +04:00
}
2014-05-05 21:08:01 +04:00
ctx . Data [ "CurDbOption" ] = curDbOp
2014-04-27 08:34:48 +04:00
2014-04-10 22:37:43 +04:00
auth . AssignForm ( form , ctx . Data )
ctx . HTML ( 200 , "install" )
}
2014-04-11 00:36:50 +04:00
func InstallPost ( ctx * middleware . Context , form auth . InstallForm ) {
2014-04-10 22:37:43 +04:00
if base . InstallLock {
ctx . Handle ( 404 , "install.Install" , errors . New ( "Installation is prohibited" ) )
2014-03-28 15:26:22 +04:00
return
}
2014-03-30 01:50:51 +04:00
2014-04-10 22:37:43 +04:00
ctx . Data [ "Title" ] = "Install"
ctx . Data [ "PageIsInstall" ] = true
2014-04-27 08:34:48 +04:00
renderDbOption ( ctx )
2014-05-05 21:08:01 +04:00
ctx . Data [ "CurDbOption" ] = form . Database
2014-04-27 08:34:48 +04:00
2014-03-30 01:50:51 +04:00
if ctx . HasError ( ) {
ctx . HTML ( 200 , "install" )
return
}
2014-04-08 23:27:35 +04:00
if _ , err := exec . LookPath ( "git" ) ; err != nil {
ctx . RenderWithErr ( "Fail to test 'git' command: " + err . Error ( ) , "install" , & form )
return
}
2014-03-30 01:50:51 +04:00
// Pass basic check, now test configuration.
// Test database setting.
2014-04-27 08:34:48 +04:00
dbTypes := map [ string ] string { "MySQL" : "mysql" , "PostgreSQL" : "postgres" , "SQLite3" : "sqlite3" }
2014-03-30 01:50:51 +04:00
models . DbCfg . Type = dbTypes [ form . Database ]
models . DbCfg . Host = form . Host
models . DbCfg . User = form . User
models . DbCfg . Pwd = form . Passwd
models . DbCfg . Name = form . DatabaseName
models . DbCfg . SslMode = form . SslMode
models . DbCfg . Path = form . DatabasePath
2014-03-30 19:09:59 +04:00
// Set test engine.
2014-03-30 18:47:08 +04:00
var x * xorm . Engine
if err := models . NewTestEngine ( x ) ; err != nil {
2014-03-30 19:09:59 +04:00
if strings . Contains ( err . Error ( ) , ` Unknown database type: sqlite3 ` ) {
2014-03-30 17:39:44 +04:00
ctx . RenderWithErr ( "Your release version does not support SQLite3, please download the official binary version " +
2014-05-05 21:08:01 +04:00
"from http://gogs.io/docs/installation/install_from_binary.md, NOT the gobuild version." , "install" , & form )
2014-03-30 17:39:44 +04:00
} else {
ctx . RenderWithErr ( "Database setting is not correct: " + err . Error ( ) , "install" , & form )
}
2014-03-30 01:50:51 +04:00
return
}
// Test repository root path.
if err := os . MkdirAll ( form . RepoRootPath , os . ModePerm ) ; err != nil {
ctx . RenderWithErr ( "Repository root path is invalid: " + err . Error ( ) , "install" , & form )
return
}
2014-03-30 19:58:21 +04:00
// Check run user.
2014-04-12 07:52:08 +04:00
curUser := os . Getenv ( "USER" )
2014-03-30 19:58:21 +04:00
if len ( curUser ) == 0 {
2014-04-12 07:52:08 +04:00
curUser = os . Getenv ( "USERNAME" )
2014-03-30 19:58:21 +04:00
}
// Does not check run user when the install lock is off.
if form . RunUser != curUser {
ctx . RenderWithErr ( "Run user isn't the current user: " + form . RunUser + " -> " + curUser , "install" , & form )
return
}
2014-03-30 01:50:51 +04:00
// Save settings.
base . Cfg . SetValue ( "database" , "DB_TYPE" , models . DbCfg . Type )
base . Cfg . SetValue ( "database" , "HOST" , models . DbCfg . Host )
base . Cfg . SetValue ( "database" , "NAME" , models . DbCfg . Name )
base . Cfg . SetValue ( "database" , "USER" , models . DbCfg . User )
base . Cfg . SetValue ( "database" , "PASSWD" , models . DbCfg . Pwd )
base . Cfg . SetValue ( "database" , "SSL_MODE" , models . DbCfg . SslMode )
base . Cfg . SetValue ( "database" , "PATH" , models . DbCfg . Path )
base . Cfg . SetValue ( "repository" , "ROOT" , form . RepoRootPath )
base . Cfg . SetValue ( "" , "RUN_USER" , form . RunUser )
base . Cfg . SetValue ( "server" , "DOMAIN" , form . Domain )
base . Cfg . SetValue ( "server" , "ROOT_URL" , form . AppUrl )
2014-03-31 00:34:23 +04:00
if len ( strings . TrimSpace ( form . SmtpHost ) ) > 0 {
2014-03-30 01:50:51 +04:00
base . Cfg . SetValue ( "mailer" , "ENABLED" , "true" )
base . Cfg . SetValue ( "mailer" , "HOST" , form . SmtpHost )
base . Cfg . SetValue ( "mailer" , "USER" , form . SmtpEmail )
base . Cfg . SetValue ( "mailer" , "PASSWD" , form . SmtpPasswd )
base . Cfg . SetValue ( "service" , "REGISTER_EMAIL_CONFIRM" , base . ToStr ( form . RegisterConfirm == "on" ) )
base . Cfg . SetValue ( "service" , "ENABLE_NOTIFY_MAIL" , base . ToStr ( form . MailNotify == "on" ) )
}
2014-03-30 19:58:21 +04:00
base . Cfg . SetValue ( "" , "RUN_MODE" , "prod" )
2014-03-30 01:50:51 +04:00
base . Cfg . SetValue ( "security" , "INSTALL_LOCK" , "true" )
2014-03-30 19:58:21 +04:00
os . MkdirAll ( "custom/conf" , os . ModePerm )
2014-03-30 19:09:59 +04:00
if err := goconfig . SaveConfigFile ( base . Cfg , "custom/conf/app.ini" ) ; err != nil {
2014-03-30 01:50:51 +04:00
ctx . RenderWithErr ( "Fail to save configuration: " + err . Error ( ) , "install" , & form )
return
}
GlobalInit ( )
2014-03-30 19:09:59 +04:00
// Create admin account.
if _ , err := models . RegisterUser ( & models . User { Name : form . AdminName , Email : form . AdminEmail , Passwd : form . AdminPasswd ,
IsAdmin : true , IsActive : true } ) ; err != nil {
if err != models . ErrUserAlreadyExist {
2014-04-05 19:22:14 +04:00
base . InstallLock = false
2014-03-30 19:09:59 +04:00
ctx . RenderWithErr ( "Admin account setting is invalid: " + err . Error ( ) , "install" , & form )
return
}
2014-03-31 00:01:50 +04:00
log . Info ( "Admin account already exist" )
2014-03-30 19:09:59 +04:00
}
2014-03-30 01:50:51 +04:00
log . Info ( "First-time run install finished!" )
2014-04-10 22:37:43 +04:00
ctx . Flash . Success ( "Welcome! We're glad that you choose Gogs, have fun and take care." )
2014-03-30 01:50:51 +04:00
ctx . Redirect ( "/user/login" )
2014-03-25 12:51:42 +04:00
}