github.com/psyb0t/mattermost-server@v4.6.1-0.20180125161845-5503a1351abf+incompatible/cmd/platform/server.go (about) 1 // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package main 5 6 import ( 7 "os" 8 "os/signal" 9 "syscall" 10 "time" 11 12 l4g "github.com/alecthomas/log4go" 13 "github.com/mattermost/mattermost-server/api" 14 "github.com/mattermost/mattermost-server/api4" 15 "github.com/mattermost/mattermost-server/app" 16 "github.com/mattermost/mattermost-server/manualtesting" 17 "github.com/mattermost/mattermost-server/model" 18 "github.com/mattermost/mattermost-server/utils" 19 "github.com/mattermost/mattermost-server/web" 20 "github.com/mattermost/mattermost-server/wsapi" 21 "github.com/spf13/cobra" 22 ) 23 24 const ( 25 SESSIONS_CLEANUP_BATCH_SIZE = 1000 26 ) 27 28 var MaxNotificationsPerChannelDefault int64 = 1000000 29 30 var serverCmd = &cobra.Command{ 31 Use: "server", 32 Short: "Run the Mattermost server", 33 RunE: runServerCmd, 34 } 35 36 func runServerCmd(cmd *cobra.Command, args []string) error { 37 config, err := cmd.Flags().GetString("config") 38 if err != nil { 39 return err 40 } 41 42 disableConfigWatch, _ := cmd.Flags().GetBool("disableconfigwatch") 43 44 runServer(config, disableConfigWatch) 45 return nil 46 } 47 48 func runServer(configFileLocation string, disableConfigWatch bool) { 49 options := []app.Option{app.ConfigFile(configFileLocation)} 50 if disableConfigWatch { 51 options = append(options, app.DisableConfigWatch) 52 } 53 54 a, err := app.New(options...) 55 if err != nil { 56 l4g.Error(err.Error()) 57 return 58 } 59 defer a.Shutdown() 60 61 utils.TestConnection(a.Config()) 62 63 pwd, _ := os.Getwd() 64 l4g.Info(utils.T("mattermost.current_version"), model.CurrentVersion, model.BuildNumber, model.BuildDate, model.BuildHash, model.BuildHashEnterprise) 65 l4g.Info(utils.T("mattermost.entreprise_enabled"), model.BuildEnterpriseReady) 66 l4g.Info(utils.T("mattermost.working_dir"), pwd) 67 l4g.Info(utils.T("mattermost.config_file"), utils.FindConfigFile(configFileLocation)) 68 69 backend, appErr := a.FileBackend() 70 if appErr == nil { 71 appErr = backend.TestConnection() 72 } 73 if appErr != nil { 74 l4g.Error("Problem with file storage settings: " + appErr.Error()) 75 } 76 77 if model.BuildEnterpriseReady == "true" { 78 a.LoadLicense() 79 } 80 81 a.InitPlugins(*a.Config().PluginSettings.Directory, *a.Config().PluginSettings.ClientDirectory, nil) 82 a.AddConfigListener(func(prevCfg, cfg *model.Config) { 83 if *cfg.PluginSettings.Enable { 84 a.InitPlugins(*cfg.PluginSettings.Directory, *a.Config().PluginSettings.ClientDirectory, nil) 85 } else { 86 a.ShutDownPlugins() 87 } 88 }) 89 90 a.StartServer() 91 api4.Init(a, a.Srv.Router, false) 92 api3 := api.Init(a, a.Srv.Router) 93 wsapi.Init(a, a.Srv.WebSocketRouter) 94 web.Init(api3) 95 96 if !utils.IsLicensed() && len(a.Config().SqlSettings.DataSourceReplicas) > 1 { 97 l4g.Warn(utils.T("store.sql.read_replicas_not_licensed.critical")) 98 a.UpdateConfig(func(cfg *model.Config) { 99 cfg.SqlSettings.DataSourceReplicas = cfg.SqlSettings.DataSourceReplicas[:1] 100 }) 101 } 102 103 if !utils.IsLicensed() { 104 a.UpdateConfig(func(cfg *model.Config) { 105 cfg.TeamSettings.MaxNotificationsPerChannel = &MaxNotificationsPerChannelDefault 106 }) 107 } 108 109 a.ReloadConfig() 110 111 // Enable developer settings if this is a "dev" build 112 if model.BuildNumber == "dev" { 113 a.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableDeveloper = true }) 114 } 115 116 resetStatuses(a) 117 118 // If we allow testing then listen for manual testing URL hits 119 if a.Config().ServiceSettings.EnableTesting { 120 manualtesting.Init(api3) 121 } 122 123 a.EnsureDiagnosticId() 124 125 go runSecurityJob(a) 126 go runDiagnosticsJob(a) 127 go runSessionCleanupJob(a) 128 go runTokenCleanupJob(a) 129 go runCommandWebhookCleanupJob(a) 130 131 if complianceI := a.Compliance; complianceI != nil { 132 complianceI.StartComplianceDailyJob() 133 } 134 135 if a.Cluster != nil { 136 a.RegisterAllClusterMessageHandlers() 137 a.Cluster.StartInterNodeCommunication() 138 } 139 140 if a.Metrics != nil { 141 a.Metrics.StartServer() 142 } 143 144 if a.Elasticsearch != nil { 145 a.Go(func() { 146 if err := a.Elasticsearch.Start(); err != nil { 147 l4g.Error(err.Error()) 148 } 149 }) 150 } 151 152 if *a.Config().JobSettings.RunJobs { 153 a.Jobs.StartWorkers() 154 } 155 if *a.Config().JobSettings.RunScheduler { 156 a.Jobs.StartSchedulers() 157 } 158 159 // wait for kill signal before attempting to gracefully shutdown 160 // the running service 161 c := make(chan os.Signal, 1) 162 signal.Notify(c, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) 163 <-c 164 165 if a.Cluster != nil { 166 a.Cluster.StopInterNodeCommunication() 167 } 168 169 if a.Metrics != nil { 170 a.Metrics.StopServer() 171 } 172 173 a.Jobs.StopSchedulers() 174 a.Jobs.StopWorkers() 175 } 176 177 func runSecurityJob(a *app.App) { 178 doSecurity(a) 179 model.CreateRecurringTask("Security", func() { 180 doSecurity(a) 181 }, time.Hour*4) 182 } 183 184 func runDiagnosticsJob(a *app.App) { 185 doDiagnostics(a) 186 model.CreateRecurringTask("Diagnostics", func() { 187 doDiagnostics(a) 188 }, time.Hour*24) 189 } 190 191 func runTokenCleanupJob(a *app.App) { 192 doTokenCleanup(a) 193 model.CreateRecurringTask("Token Cleanup", func() { 194 doTokenCleanup(a) 195 }, time.Hour*1) 196 } 197 198 func runCommandWebhookCleanupJob(a *app.App) { 199 doCommandWebhookCleanup(a) 200 model.CreateRecurringTask("Command Hook Cleanup", func() { 201 doCommandWebhookCleanup(a) 202 }, time.Hour*1) 203 } 204 205 func runSessionCleanupJob(a *app.App) { 206 doSessionCleanup(a) 207 model.CreateRecurringTask("Session Cleanup", func() { 208 doSessionCleanup(a) 209 }, time.Hour*24) 210 } 211 212 func resetStatuses(a *app.App) { 213 if result := <-a.Srv.Store.Status().ResetAll(); result.Err != nil { 214 l4g.Error(utils.T("mattermost.reset_status.error"), result.Err.Error()) 215 } 216 } 217 218 func doSecurity(a *app.App) { 219 a.DoSecurityUpdateCheck() 220 } 221 222 func doDiagnostics(a *app.App) { 223 if *a.Config().LogSettings.EnableDiagnostics { 224 a.SendDailyDiagnostics() 225 } 226 } 227 228 func doTokenCleanup(a *app.App) { 229 a.Srv.Store.Token().Cleanup() 230 } 231 232 func doCommandWebhookCleanup(a *app.App) { 233 a.Srv.Store.CommandWebhook().Cleanup() 234 } 235 236 func doSessionCleanup(a *app.App) { 237 a.Srv.Store.Session().Cleanup(model.GetMillis(), SESSIONS_CLEANUP_BATCH_SIZE) 238 }