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  }