Move install pages out of main macaron routes (#13195)
* Move install pages out of main macaron loop Signed-off-by: Andrew Thornton <art27@cantab.net> * Update templates/post-install.tmpl Co-authored-by: Lauris BH <lauris@nix.lv> * remove prefetch Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
		
							parent
							
								
									3ddf3f93d6
								
							
						
					
					
						commit
						2f1353a2f3
					
				
					 10 changed files with 234 additions and 115 deletions
				
			
		
							
								
								
									
										141
									
								
								cmd/web.go
									
									
									
									
									
								
							
							
						
						
									
										141
									
								
								cmd/web.go
									
									
									
									
									
								
							|  | @ -19,6 +19,8 @@ import ( | ||||||
| 	"code.gitea.io/gitea/routers" | 	"code.gitea.io/gitea/routers" | ||||||
| 	"code.gitea.io/gitea/routers/routes" | 	"code.gitea.io/gitea/routers/routes" | ||||||
| 
 | 
 | ||||||
|  | 	"gitea.com/macaron/macaron" | ||||||
|  | 
 | ||||||
| 	context2 "github.com/gorilla/context" | 	context2 "github.com/gorilla/context" | ||||||
| 	"github.com/unknwon/com" | 	"github.com/unknwon/com" | ||||||
| 	"github.com/urfave/cli" | 	"github.com/urfave/cli" | ||||||
|  | @ -114,6 +116,39 @@ func runWeb(ctx *cli.Context) error { | ||||||
| 		setting.WritePIDFile = true | 		setting.WritePIDFile = true | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	// Flag for port number in case first time run conflict.
 | ||||||
|  | 	if ctx.IsSet("port") { | ||||||
|  | 		if err := setPort(ctx.String("port")); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Perform pre-initialization
 | ||||||
|  | 	needsInstall := routers.PreInstallInit(graceful.GetManager().HammerContext()) | ||||||
|  | 	if needsInstall { | ||||||
|  | 		m := routes.NewMacaron() | ||||||
|  | 		routes.RegisterInstallRoute(m) | ||||||
|  | 		err := listen(m, false) | ||||||
|  | 		select { | ||||||
|  | 		case <-graceful.GetManager().IsShutdown(): | ||||||
|  | 			<-graceful.GetManager().Done() | ||||||
|  | 			log.Info("PID: %d Gitea Web Finished", os.Getpid()) | ||||||
|  | 			log.Close() | ||||||
|  | 			return err | ||||||
|  | 		default: | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		NoInstallListener() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if setting.EnablePprof { | ||||||
|  | 		go func() { | ||||||
|  | 			log.Info("Starting pprof server on localhost:6060") | ||||||
|  | 			log.Info("%v", http.ListenAndServe("localhost:6060", nil)) | ||||||
|  | 		}() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	log.Info("Global init") | ||||||
| 	// Perform global initialization
 | 	// Perform global initialization
 | ||||||
| 	routers.GlobalInit(graceful.GetManager().HammerContext()) | 	routers.GlobalInit(graceful.GetManager().HammerContext()) | ||||||
| 
 | 
 | ||||||
|  | @ -121,41 +156,49 @@ func runWeb(ctx *cli.Context) error { | ||||||
| 	m := routes.NewMacaron() | 	m := routes.NewMacaron() | ||||||
| 	routes.RegisterRoutes(m) | 	routes.RegisterRoutes(m) | ||||||
| 
 | 
 | ||||||
| 	// Flag for port number in case first time run conflict.
 | 	err := listen(m, true) | ||||||
| 	if ctx.IsSet("port") { | 	<-graceful.GetManager().Done() | ||||||
| 		setting.AppURL = strings.Replace(setting.AppURL, setting.HTTPPort, ctx.String("port"), 1) | 	log.Info("PID: %d Gitea Web Finished", os.Getpid()) | ||||||
| 		setting.HTTPPort = ctx.String("port") | 	log.Close() | ||||||
|  | 	return err | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| 		switch setting.Protocol { | func setPort(port string) error { | ||||||
| 		case setting.UnixSocket: | 	setting.AppURL = strings.Replace(setting.AppURL, setting.HTTPPort, port, 1) | ||||||
| 		case setting.FCGI: | 	setting.HTTPPort = port | ||||||
| 		case setting.FCGIUnix: |  | ||||||
| 		default: |  | ||||||
| 			// Save LOCAL_ROOT_URL if port changed
 |  | ||||||
| 			cfg := ini.Empty() |  | ||||||
| 			if com.IsFile(setting.CustomConf) { |  | ||||||
| 				// Keeps custom settings if there is already something.
 |  | ||||||
| 				if err := cfg.Append(setting.CustomConf); err != nil { |  | ||||||
| 					return fmt.Errorf("Failed to load custom conf '%s': %v", setting.CustomConf, err) |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 
 | 
 | ||||||
| 			defaultLocalURL := string(setting.Protocol) + "://" | 	switch setting.Protocol { | ||||||
| 			if setting.HTTPAddr == "0.0.0.0" { | 	case setting.UnixSocket: | ||||||
| 				defaultLocalURL += "localhost" | 	case setting.FCGI: | ||||||
| 			} else { | 	case setting.FCGIUnix: | ||||||
| 				defaultLocalURL += setting.HTTPAddr | 	default: | ||||||
| 			} | 		// Save LOCAL_ROOT_URL if port changed
 | ||||||
| 			defaultLocalURL += ":" + setting.HTTPPort + "/" | 		cfg := ini.Empty() | ||||||
| 
 | 		if com.IsFile(setting.CustomConf) { | ||||||
| 			cfg.Section("server").Key("LOCAL_ROOT_URL").SetValue(defaultLocalURL) | 			// Keeps custom settings if there is already something.
 | ||||||
| 
 | 			if err := cfg.Append(setting.CustomConf); err != nil { | ||||||
| 			if err := cfg.SaveTo(setting.CustomConf); err != nil { | 				return fmt.Errorf("Failed to load custom conf '%s': %v", setting.CustomConf, err) | ||||||
| 				return fmt.Errorf("Error saving generated JWT Secret to custom config: %v", err) |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
|  | 		defaultLocalURL := string(setting.Protocol) + "://" | ||||||
|  | 		if setting.HTTPAddr == "0.0.0.0" { | ||||||
|  | 			defaultLocalURL += "localhost" | ||||||
|  | 		} else { | ||||||
|  | 			defaultLocalURL += setting.HTTPAddr | ||||||
|  | 		} | ||||||
|  | 		defaultLocalURL += ":" + setting.HTTPPort + "/" | ||||||
|  | 
 | ||||||
|  | 		cfg.Section("server").Key("LOCAL_ROOT_URL").SetValue(defaultLocalURL) | ||||||
|  | 
 | ||||||
|  | 		if err := cfg.SaveTo(setting.CustomConf); err != nil { | ||||||
|  | 			return fmt.Errorf("Error saving generated JWT Secret to custom config: %v", err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func listen(m *macaron.Macaron, handleRedirector bool) error { | ||||||
| 	listenAddr := setting.HTTPAddr | 	listenAddr := setting.HTTPAddr | ||||||
| 	if setting.Protocol != setting.UnixSocket && setting.Protocol != setting.FCGIUnix { | 	if setting.Protocol != setting.UnixSocket && setting.Protocol != setting.FCGIUnix { | ||||||
| 		listenAddr = net.JoinHostPort(listenAddr, setting.HTTPPort) | 		listenAddr = net.JoinHostPort(listenAddr, setting.HTTPPort) | ||||||
|  | @ -166,37 +209,40 @@ func runWeb(ctx *cli.Context) error { | ||||||
| 		log.Info("LFS server enabled") | 		log.Info("LFS server enabled") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if setting.EnablePprof { |  | ||||||
| 		go func() { |  | ||||||
| 			log.Info("Starting pprof server on localhost:6060") |  | ||||||
| 			log.Info("%v", http.ListenAndServe("localhost:6060", nil)) |  | ||||||
| 		}() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var err error | 	var err error | ||||||
| 	switch setting.Protocol { | 	switch setting.Protocol { | ||||||
| 	case setting.HTTP: | 	case setting.HTTP: | ||||||
| 		NoHTTPRedirector() | 		if handleRedirector { | ||||||
|  | 			NoHTTPRedirector() | ||||||
|  | 		} | ||||||
| 		err = runHTTP("tcp", listenAddr, context2.ClearHandler(m)) | 		err = runHTTP("tcp", listenAddr, context2.ClearHandler(m)) | ||||||
| 	case setting.HTTPS: | 	case setting.HTTPS: | ||||||
| 		if setting.EnableLetsEncrypt { | 		if setting.EnableLetsEncrypt { | ||||||
| 			err = runLetsEncrypt(listenAddr, setting.Domain, setting.LetsEncryptDirectory, setting.LetsEncryptEmail, context2.ClearHandler(m)) | 			err = runLetsEncrypt(listenAddr, setting.Domain, setting.LetsEncryptDirectory, setting.LetsEncryptEmail, context2.ClearHandler(m)) | ||||||
| 			break | 			break | ||||||
| 		} | 		} | ||||||
| 		if setting.RedirectOtherPort { | 		if handleRedirector { | ||||||
| 			go runHTTPRedirector() | 			if setting.RedirectOtherPort { | ||||||
| 		} else { | 				go runHTTPRedirector() | ||||||
| 			NoHTTPRedirector() | 			} else { | ||||||
|  | 				NoHTTPRedirector() | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 		err = runHTTPS("tcp", listenAddr, setting.CertFile, setting.KeyFile, context2.ClearHandler(m)) | 		err = runHTTPS("tcp", listenAddr, setting.CertFile, setting.KeyFile, context2.ClearHandler(m)) | ||||||
| 	case setting.FCGI: | 	case setting.FCGI: | ||||||
| 		NoHTTPRedirector() | 		if handleRedirector { | ||||||
|  | 			NoHTTPRedirector() | ||||||
|  | 		} | ||||||
| 		err = runFCGI("tcp", listenAddr, context2.ClearHandler(m)) | 		err = runFCGI("tcp", listenAddr, context2.ClearHandler(m)) | ||||||
| 	case setting.UnixSocket: | 	case setting.UnixSocket: | ||||||
| 		NoHTTPRedirector() | 		if handleRedirector { | ||||||
|  | 			NoHTTPRedirector() | ||||||
|  | 		} | ||||||
| 		err = runHTTP("unix", listenAddr, context2.ClearHandler(m)) | 		err = runHTTP("unix", listenAddr, context2.ClearHandler(m)) | ||||||
| 	case setting.FCGIUnix: | 	case setting.FCGIUnix: | ||||||
| 		NoHTTPRedirector() | 		if handleRedirector { | ||||||
|  | 			NoHTTPRedirector() | ||||||
|  | 		} | ||||||
| 		err = runFCGI("unix", listenAddr, context2.ClearHandler(m)) | 		err = runFCGI("unix", listenAddr, context2.ClearHandler(m)) | ||||||
| 	default: | 	default: | ||||||
| 		log.Fatal("Invalid protocol: %s", setting.Protocol) | 		log.Fatal("Invalid protocol: %s", setting.Protocol) | ||||||
|  | @ -206,8 +252,5 @@ func runWeb(ctx *cli.Context) error { | ||||||
| 		log.Critical("Failed to start server: %v", err) | 		log.Critical("Failed to start server: %v", err) | ||||||
| 	} | 	} | ||||||
| 	log.Info("HTTP Listener: %s Closed", listenAddr) | 	log.Info("HTTP Listener: %s Closed", listenAddr) | ||||||
| 	<-graceful.GetManager().Done() | 	return err | ||||||
| 	log.Info("PID: %d Gitea Web Finished", os.Getpid()) |  | ||||||
| 	log.Close() |  | ||||||
| 	return nil |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -37,6 +37,12 @@ func NoMainListener() { | ||||||
| 	graceful.GetManager().InformCleanup() | 	graceful.GetManager().InformCleanup() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // NoInstallListener tells our cleanup routine that we will not be using a possibly provided listener
 | ||||||
|  | // for our install HTTP/HTTPS service
 | ||||||
|  | func NoInstallListener() { | ||||||
|  | 	graceful.GetManager().InformCleanup() | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func runFCGI(network, listenAddr string, m http.Handler) error { | func runFCGI(network, listenAddr string, m http.Handler) error { | ||||||
| 	// This needs to handle stdin as fcgi point
 | 	// This needs to handle stdin as fcgi point
 | ||||||
| 	fcgiServer := graceful.NewServer(network, listenAddr) | 	fcgiServer := graceful.NewServer(network, listenAddr) | ||||||
|  |  | ||||||
|  | @ -26,12 +26,6 @@ type ToggleOptions struct { | ||||||
| // Toggle returns toggle options as middleware
 | // Toggle returns toggle options as middleware
 | ||||||
| func Toggle(options *ToggleOptions) macaron.Handler { | func Toggle(options *ToggleOptions) macaron.Handler { | ||||||
| 	return func(ctx *Context) { | 	return func(ctx *Context) { | ||||||
| 		// Cannot view any page before installation.
 |  | ||||||
| 		if !setting.InstallLock { |  | ||||||
| 			ctx.Redirect(setting.AppSubURL + "/install") |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		isAPIPath := auth.IsAPIPath(ctx.Req.URL.Path) | 		isAPIPath := auth.IsAPIPath(ctx.Req.URL.Path) | ||||||
| 
 | 
 | ||||||
| 		// Check prohibit login users.
 | 		// Check prohibit login users.
 | ||||||
|  |  | ||||||
|  | @ -31,7 +31,7 @@ const ( | ||||||
| //
 | //
 | ||||||
| // If you add an additional place you must increment this number
 | // If you add an additional place you must increment this number
 | ||||||
| // and add a function to call manager.InformCleanup if it's not going to be used
 | // and add a function to call manager.InformCleanup if it's not going to be used
 | ||||||
| const numberOfServersToCreate = 3 | const numberOfServersToCreate = 4 | ||||||
| 
 | 
 | ||||||
| // Manager represents the graceful server manager interface
 | // Manager represents the graceful server manager interface
 | ||||||
| var manager *Manager | var manager *Manager | ||||||
|  |  | ||||||
|  | @ -162,7 +162,7 @@ func (srv *Server) Serve(serve ServeFunction) error { | ||||||
| 	srv.setState(stateTerminate) | 	srv.setState(stateTerminate) | ||||||
| 	GetManager().ServerDone() | 	GetManager().ServerDone() | ||||||
| 	// use of closed means that the listeners are closed - i.e. we should be shutting down - return nil
 | 	// use of closed means that the listeners are closed - i.e. we should be shutting down - return nil
 | ||||||
| 	if err != nil && strings.Contains(err.Error(), "use of closed") { | 	if err == nil || strings.Contains(err.Error(), "use of closed") || strings.Contains(err.Error(), "http: Server closed") { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 	return err | 	return err | ||||||
|  |  | ||||||
							
								
								
									
										120
									
								
								routers/init.go
									
									
									
									
									
								
							
							
						
						
									
										120
									
								
								routers/init.go
									
									
									
									
									
								
							|  | @ -117,9 +117,46 @@ func InitLocales() { | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // PreInstallInit preloads the configuration to check if we need to run install
 | ||||||
|  | func PreInstallInit(ctx context.Context) bool { | ||||||
|  | 	setting.NewContext() | ||||||
|  | 	if !setting.InstallLock { | ||||||
|  | 		log.Trace("AppPath: %s", setting.AppPath) | ||||||
|  | 		log.Trace("AppWorkPath: %s", setting.AppWorkPath) | ||||||
|  | 		log.Trace("Custom path: %s", setting.CustomPath) | ||||||
|  | 		log.Trace("Log path: %s", setting.LogRootPath) | ||||||
|  | 		log.Trace("Preparing to run install page") | ||||||
|  | 		InitLocales() | ||||||
|  | 		if setting.EnableSQLite3 { | ||||||
|  | 			log.Info("SQLite3 Supported") | ||||||
|  | 		} | ||||||
|  | 		setting.InitDBConfig() | ||||||
|  | 		svg.Init() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return !setting.InstallLock | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PostInstallInit rereads the settings and starts up the database
 | ||||||
|  | func PostInstallInit(ctx context.Context) { | ||||||
|  | 	setting.NewContext() | ||||||
|  | 	setting.InitDBConfig() | ||||||
|  | 	if setting.InstallLock { | ||||||
|  | 		if err := initDBEngine(ctx); err == nil { | ||||||
|  | 			log.Info("ORM engine initialization successful!") | ||||||
|  | 		} else { | ||||||
|  | 			log.Fatal("ORM engine initialization failed: %v", err) | ||||||
|  | 		} | ||||||
|  | 		svg.Init() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // GlobalInit is for global configuration reload-able.
 | // GlobalInit is for global configuration reload-able.
 | ||||||
| func GlobalInit(ctx context.Context) { | func GlobalInit(ctx context.Context) { | ||||||
| 	setting.NewContext() | 	setting.NewContext() | ||||||
|  | 	if !setting.InstallLock { | ||||||
|  | 		log.Fatal("Gitea is not installed") | ||||||
|  | 	} | ||||||
| 	if err := git.Init(ctx); err != nil { | 	if err := git.Init(ctx); err != nil { | ||||||
| 		log.Fatal("Git module init failed: %v", err) | 		log.Fatal("Git module init failed: %v", err) | ||||||
| 	} | 	} | ||||||
|  | @ -134,59 +171,50 @@ func GlobalInit(ctx context.Context) { | ||||||
| 
 | 
 | ||||||
| 	NewServices() | 	NewServices() | ||||||
| 
 | 
 | ||||||
| 	if setting.InstallLock { | 	highlight.NewContext() | ||||||
| 		highlight.NewContext() | 	external.RegisterParsers() | ||||||
| 		external.RegisterParsers() | 	markup.Init() | ||||||
| 		markup.Init() | 	if err := initDBEngine(ctx); err == nil { | ||||||
| 		if err := initDBEngine(ctx); err == nil { | 		log.Info("ORM engine initialization successful!") | ||||||
| 			log.Info("ORM engine initialization successful!") | 	} else { | ||||||
| 		} else { | 		log.Fatal("ORM engine initialization failed: %v", err) | ||||||
| 			log.Fatal("ORM engine initialization failed: %v", err) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if err := models.InitOAuth2(); err != nil { |  | ||||||
| 			log.Fatal("Failed to initialize OAuth2 support: %v", err) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		models.NewRepoContext() |  | ||||||
| 
 |  | ||||||
| 		// Booting long running goroutines.
 |  | ||||||
| 		cron.NewContext() |  | ||||||
| 		issue_indexer.InitIssueIndexer(false) |  | ||||||
| 		code_indexer.Init() |  | ||||||
| 		if err := stats_indexer.Init(); err != nil { |  | ||||||
| 			log.Fatal("Failed to initialize repository stats indexer queue: %v", err) |  | ||||||
| 		} |  | ||||||
| 		mirror_service.InitSyncMirrors() |  | ||||||
| 		webhook.InitDeliverHooks() |  | ||||||
| 		if err := pull_service.Init(); err != nil { |  | ||||||
| 			log.Fatal("Failed to initialize test pull requests queue: %v", err) |  | ||||||
| 		} |  | ||||||
| 		if err := task.Init(); err != nil { |  | ||||||
| 			log.Fatal("Failed to initialize task scheduler: %v", err) |  | ||||||
| 		} |  | ||||||
| 		eventsource.GetManager().Init() |  | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	if err := models.InitOAuth2(); err != nil { | ||||||
|  | 		log.Fatal("Failed to initialize OAuth2 support: %v", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	models.NewRepoContext() | ||||||
|  | 
 | ||||||
|  | 	// Booting long running goroutines.
 | ||||||
|  | 	cron.NewContext() | ||||||
|  | 	issue_indexer.InitIssueIndexer(false) | ||||||
|  | 	code_indexer.Init() | ||||||
|  | 	if err := stats_indexer.Init(); err != nil { | ||||||
|  | 		log.Fatal("Failed to initialize repository stats indexer queue: %v", err) | ||||||
|  | 	} | ||||||
|  | 	mirror_service.InitSyncMirrors() | ||||||
|  | 	webhook.InitDeliverHooks() | ||||||
|  | 	if err := pull_service.Init(); err != nil { | ||||||
|  | 		log.Fatal("Failed to initialize test pull requests queue: %v", err) | ||||||
|  | 	} | ||||||
|  | 	if err := task.Init(); err != nil { | ||||||
|  | 		log.Fatal("Failed to initialize task scheduler: %v", err) | ||||||
|  | 	} | ||||||
|  | 	eventsource.GetManager().Init() | ||||||
|  | 
 | ||||||
| 	if setting.EnableSQLite3 { | 	if setting.EnableSQLite3 { | ||||||
| 		log.Info("SQLite3 Supported") | 		log.Info("SQLite3 Supported") | ||||||
| 	} | 	} | ||||||
| 	checkRunMode() | 	checkRunMode() | ||||||
| 
 | 
 | ||||||
| 	// Now because Install will re-run GlobalInit once it has set InstallLock
 | 	if setting.SSH.StartBuiltinServer { | ||||||
| 	// we can't tell if the ssh port will remain unused until that's done.
 | 		ssh.Listen(setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs) | ||||||
| 	// However, see FIXME comment in install.go
 | 		log.Info("SSH server started on %s:%d. Cipher list (%v), key exchange algorithms (%v), MACs (%v)", setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs) | ||||||
| 	if setting.InstallLock { | 	} else { | ||||||
| 		if setting.SSH.StartBuiltinServer { | 		ssh.Unused() | ||||||
| 			ssh.Listen(setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs) |  | ||||||
| 			log.Info("SSH server started on %s:%d. Cipher list (%v), key exchange algorithms (%v), MACs (%v)", setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs) |  | ||||||
| 		} else { |  | ||||||
| 			ssh.Unused() |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if setting.InstallLock { |  | ||||||
| 		sso.Init() |  | ||||||
| 	} | 	} | ||||||
|  | 	sso.Init() | ||||||
| 
 | 
 | ||||||
| 	svg.Init() | 	svg.Init() | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ | ||||||
| package routers | package routers | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"errors" | 	"net/http" | ||||||
| 	"os" | 	"os" | ||||||
| 	"os/exec" | 	"os/exec" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
|  | @ -27,13 +27,15 @@ import ( | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
| 	// tplInstall template for installation page
 | 	// tplInstall template for installation page
 | ||||||
| 	tplInstall base.TplName = "install" | 	tplInstall     base.TplName = "install" | ||||||
|  | 	tplPostInstall base.TplName = "post-install" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // InstallInit prepare for rendering installation page
 | // InstallInit prepare for rendering installation page
 | ||||||
| func InstallInit(ctx *context.Context) { | func InstallInit(ctx *context.Context) { | ||||||
| 	if setting.InstallLock { | 	if setting.InstallLock { | ||||||
| 		ctx.NotFound("Install", errors.New("Installation is prohibited")) | 		ctx.Header().Add("Refresh", "1; url="+setting.AppURL+"user/login") | ||||||
|  | 		ctx.HTML(200, tplPostInstall) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -357,7 +359,8 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	GlobalInit(graceful.GetManager().HammerContext()) | 	// Re-read settings
 | ||||||
|  | 	PostInstallInit(ctx.Req.Context()) | ||||||
| 
 | 
 | ||||||
| 	// Create admin account
 | 	// Create admin account
 | ||||||
| 	if len(form.AdminName) > 0 { | 	if len(form.AdminName) > 0 { | ||||||
|  | @ -380,6 +383,11 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) { | ||||||
| 			u, _ = models.GetUserByName(u.Name) | 			u, _ = models.GetUserByName(u.Name) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		days := 86400 * setting.LogInRememberDays | ||||||
|  | 		ctx.SetCookie(setting.CookieUserName, u.Name, days, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) | ||||||
|  | 		ctx.SetSuperSecureCookie(base.EncodeMD5(u.Rands+u.Passwd), | ||||||
|  | 			setting.CookieRememberName, u.Name, days, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) | ||||||
|  | 
 | ||||||
| 		// Auto-login for admin
 | 		// Auto-login for admin
 | ||||||
| 		if err = ctx.Session.Set("uid", u.ID); err != nil { | 		if err = ctx.Session.Set("uid", u.ID); err != nil { | ||||||
| 			ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form) | 			ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form) | ||||||
|  | @ -397,12 +405,18 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	log.Info("First-time run install finished!") | 	log.Info("First-time run install finished!") | ||||||
| 	// FIXME: This isn't really enough to completely take account of new configuration
 | 
 | ||||||
| 	// We should really be restarting:
 |  | ||||||
| 	// - On windows this is probably just a simple restart
 |  | ||||||
| 	// - On linux we can't just use graceful.RestartProcess() everything that was passed in on LISTEN_FDS
 |  | ||||||
| 	//   (active or not) needs to be passed out and everything new passed out too.
 |  | ||||||
| 	//   This means we need to prevent the cleanup goroutine from running prior to the second GlobalInit
 |  | ||||||
| 	ctx.Flash.Success(ctx.Tr("install.install_success")) | 	ctx.Flash.Success(ctx.Tr("install.install_success")) | ||||||
| 	ctx.Redirect(form.AppURL + "user/login") | 
 | ||||||
|  | 	ctx.Header().Add("Refresh", "1; url="+setting.AppURL+"user/login") | ||||||
|  | 	ctx.HTML(200, tplPostInstall) | ||||||
|  | 
 | ||||||
|  | 	// Now get the http.Server from this request and shut it down
 | ||||||
|  | 	// NB: This is not our hammerable graceful shutdown this is http.Server.Shutdown
 | ||||||
|  | 	srv := ctx.Req.Context().Value(http.ServerContextKey).(*http.Server) | ||||||
|  | 	go func() { | ||||||
|  | 		if err := srv.Shutdown(graceful.GetManager().HammerContext()); err != nil { | ||||||
|  | 			log.Error("Unable to shutdown the install server! Error: %v", err) | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -301,6 +301,15 @@ func NewMacaron() *macaron.Macaron { | ||||||
| 	return m | 	return m | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // RegisterInstallRoute registers the install routes
 | ||||||
|  | func RegisterInstallRoute(m *macaron.Macaron) { | ||||||
|  | 	m.Combo("/", routers.InstallInit).Get(routers.Install). | ||||||
|  | 		Post(binding.BindIgnErr(auth.InstallForm{}), routers.InstallPost) | ||||||
|  | 	m.NotFound(func(ctx *context.Context) { | ||||||
|  | 		ctx.Redirect(setting.AppURL, 302) | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // RegisterRoutes routes routes to Macaron
 | // RegisterRoutes routes routes to Macaron
 | ||||||
| func RegisterRoutes(m *macaron.Macaron) { | func RegisterRoutes(m *macaron.Macaron) { | ||||||
| 	reqSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: true}) | 	reqSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: true}) | ||||||
|  |  | ||||||
|  | @ -10,7 +10,7 @@ | ||||||
| 
 | 
 | ||||||
| 				<p>{{.i18n.Tr "install.docker_helper" "https://docs.gitea.io/en-us/install-with-docker/" | Safe}}</p> | 				<p>{{.i18n.Tr "install.docker_helper" "https://docs.gitea.io/en-us/install-with-docker/" | Safe}}</p> | ||||||
| 
 | 
 | ||||||
| 				<form class="ui form" action="{{AppSubUrl}}/install" method="post"> | 				<form class="ui form" action="{{AppSubUrl}}/" method="post"> | ||||||
| 					<!-- Database Settings --> | 					<!-- Database Settings --> | ||||||
| 					<h4 class="ui dividing header">{{.i18n.Tr "install.db_title"}}</h4> | 					<h4 class="ui dividing header">{{.i18n.Tr "install.db_title"}}</h4> | ||||||
| 					<p>{{.i18n.Tr "install.requite_db_desc"}}</p> | 					<p>{{.i18n.Tr "install.requite_db_desc"}}</p> | ||||||
|  | @ -307,4 +307,5 @@ | ||||||
| 		</div> | 		</div> | ||||||
| 	</div> | 	</div> | ||||||
| </div> | </div> | ||||||
|  | <img style="display: none" src="{{StaticUrlPrefix}}/img/loading.png"/> | ||||||
| {{template "base/footer" .}} | {{template "base/footer" .}} | ||||||
|  |  | ||||||
							
								
								
									
										24
									
								
								templates/post-install.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								templates/post-install.tmpl
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | ||||||
|  | {{template "base/head" .}} | ||||||
|  | <div class="install"> | ||||||
|  |     <div class="ui container"> | ||||||
|  | 		<div class="ui grid"> | ||||||
|  | 			<div class="sixteen wide column content"> | ||||||
|  | 				<div class="home"> | ||||||
|  | 					<div class="ui stackable middle very relaxed page grid"> | ||||||
|  | 						<div id="repo_migrating" class="sixteen wide center aligned centered column"> | ||||||
|  | 							<div> | ||||||
|  | 								<img src="{{StaticUrlPrefix}}/img/loading.png"/> | ||||||
|  | 							</div> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="ui stackable middle very relaxed page grid"> | ||||||
|  | 						<div class="sixteen wide center aligned centered column"> | ||||||
|  | 							<p><a href="{{AppUrl}}user/login">{{AppUrl}}user/login</a></p> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 				</div> | ||||||
|  | 			</div> | ||||||
|  | 		</div> | ||||||
|  | 	</div> | ||||||
|  | </div> | ||||||
|  | {{template "base/footer" .}} | ||||||
		Loading…
	
		Reference in a new issue