коммит произвёл
GitHub
родитель
b826421716
Коммит
f0e4794cda
236
app/server.go
236
app/server.go
@@ -31,7 +31,6 @@ import (
|
||||
"golang.org/x/crypto/acme/autocert"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/app/email"
|
||||
"github.com/mattermost/mattermost-server/v6/app/featureflag"
|
||||
"github.com/mattermost/mattermost-server/v6/app/platform"
|
||||
"github.com/mattermost/mattermost-server/v6/app/request"
|
||||
"github.com/mattermost/mattermost-server/v6/app/teams"
|
||||
@@ -168,7 +167,6 @@ type Server struct {
|
||||
searchConfigListenerId string
|
||||
searchLicenseListenerId string
|
||||
loggerLicenseListenerId string
|
||||
configStore *configWrapper
|
||||
filestore filestore.FileBackend
|
||||
|
||||
platform *platform.PlatformService
|
||||
@@ -201,11 +199,6 @@ type Server struct {
|
||||
|
||||
tracer *tracing.Tracer
|
||||
|
||||
featureFlagSynchronizer *featureflag.Synchronizer
|
||||
featureFlagStop chan struct{}
|
||||
featureFlagStopped chan struct{}
|
||||
featureFlagSynchronizerMutex sync.Mutex
|
||||
|
||||
products map[string]Product
|
||||
}
|
||||
|
||||
@@ -237,7 +230,7 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
// and has dependency requirements with the previous step.
|
||||
//
|
||||
// Step 1: Config.
|
||||
if s.configStore == nil {
|
||||
if s.platform == nil {
|
||||
innerStore, err := config.NewFileStore("config.json", true)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to load config")
|
||||
@@ -247,7 +240,25 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
return nil, errors.Wrap(err, "failed to load config")
|
||||
}
|
||||
|
||||
s.configStore = &configWrapper{srv: s, Store: configStore}
|
||||
platformCfg := platform.ServiceConfig{
|
||||
ConfigStore: configStore,
|
||||
Logger: s.Log,
|
||||
StartMetrics: s.startMetrics,
|
||||
Cluster: s.Cluster,
|
||||
}
|
||||
if metricsInterface != nil {
|
||||
platformCfg.Metrics = metricsInterface(s, *configStore.Get().SqlSettings.DriverName, *configStore.Get().SqlSettings.DataSource)
|
||||
}
|
||||
|
||||
ps, sErr := platform.New(platformCfg)
|
||||
if sErr != nil {
|
||||
return nil, errors.Wrap(sErr, "failed to initialize platform")
|
||||
}
|
||||
s.platform = ps
|
||||
|
||||
if s.licenseValue.Load() != nil {
|
||||
ps.SetLicense(s.licenseValue.Load().(*model.License)) // in case license is set in server options
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2: Logging
|
||||
@@ -255,7 +266,7 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
mlog.Error("Could not initiate logging", mlog.Err(err))
|
||||
}
|
||||
|
||||
subpath, err := utils.GetSubpathFromConfig(s.Config())
|
||||
subpath, err := utils.GetSubpathFromConfig(s.platform.Config())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse SiteURL subpath")
|
||||
}
|
||||
@@ -264,12 +275,12 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
// This is called after initLogging() to avoid a race condition.
|
||||
mlog.Info("Server is initializing...", mlog.String("go_version", runtime.Version()))
|
||||
|
||||
s.httpService = httpservice.MakeHTTPService(s)
|
||||
s.httpService = httpservice.MakeHTTPService(s.platform)
|
||||
|
||||
// Step 3: Search Engine
|
||||
// Depends on Step 1 (config).
|
||||
searchEngine := searchengine.NewBroker(s.Config())
|
||||
bleveEngine := bleveengine.NewBleveEngine(s.Config())
|
||||
searchEngine := searchengine.NewBroker(s.platform.Config())
|
||||
bleveEngine := bleveengine.NewBleveEngine(s.platform.Config())
|
||||
if err := bleveEngine.Start(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -280,22 +291,6 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
// Depends on step 3 (s.SearchEngine must be non-nil)
|
||||
s.initEnterprise()
|
||||
|
||||
platformCfg := platform.ServiceConfig{
|
||||
ConfigStore: s.configStore.Store,
|
||||
Logger: s.Log,
|
||||
StartMetrics: s.startMetrics,
|
||||
Cluster: s.Cluster,
|
||||
}
|
||||
if metricsInterface != nil {
|
||||
platformCfg.Metrics = metricsInterface(s)
|
||||
}
|
||||
|
||||
ps, sErr := platform.New(platformCfg)
|
||||
if sErr != nil {
|
||||
return nil, errors.Wrap(sErr, "failed to initialize platform")
|
||||
}
|
||||
s.platform = ps
|
||||
|
||||
// Step 5: Cache provider.
|
||||
// At the moment we only have this implementation
|
||||
// in the future the cache provider will be built based on the loaded config
|
||||
@@ -308,7 +303,7 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
// Depends on Step 1 (config), 4 (metrics, cluster) and 5 (cacheProvider).
|
||||
if s.newStore == nil {
|
||||
s.newStore = func() (store.Store, error) {
|
||||
s.sqlStore = sqlstore.New(s.Config().SqlSettings, s.GetMetrics())
|
||||
s.sqlStore = sqlstore.New(s.platform.Config().SqlSettings, s.GetMetrics())
|
||||
|
||||
lcl, err2 := localcachelayer.NewLocalCacheLayer(
|
||||
retrylayer.New(s.sqlStore),
|
||||
@@ -323,10 +318,10 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
searchStore := searchlayer.NewSearchLayer(
|
||||
lcl,
|
||||
s.SearchEngine,
|
||||
s.Config(),
|
||||
s.platform.Config(),
|
||||
)
|
||||
|
||||
s.AddConfigListener(func(prevCfg, cfg *model.Config) {
|
||||
s.platform.AddConfigListener(func(prevCfg, cfg *model.Config) {
|
||||
searchStore.UpdateConfig(cfg)
|
||||
})
|
||||
|
||||
@@ -352,7 +347,7 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
UserStore: s.Store.User(),
|
||||
SessionStore: s.Store.Session(),
|
||||
OAuthStore: s.Store.OAuth(),
|
||||
ConfigFn: s.Config,
|
||||
ConfigFn: s.platform.Config,
|
||||
Metrics: s.GetMetrics(),
|
||||
Cluster: s.Cluster,
|
||||
LicenseFn: s.License,
|
||||
@@ -376,9 +371,9 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
}
|
||||
|
||||
license := s.License()
|
||||
insecure := s.Config().ServiceSettings.EnableInsecureOutgoingConnections
|
||||
insecure := s.platform.Config().ServiceSettings.EnableInsecureOutgoingConnections
|
||||
// Step 7: Initialize filestore
|
||||
backend, err := filestore.NewFileBackend(s.Config().FileSettings.ToFileBackendSettings(license != nil && *license.Features.Compliance, insecure != nil && *insecure))
|
||||
backend, err := filestore.NewFileBackend(s.platform.Config().FileSettings.ToFileBackendSettings(license != nil && *license.Features.Compliance, insecure != nil && *insecure))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to initialize filebackend")
|
||||
}
|
||||
@@ -398,7 +393,7 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
GroupStore: s.Store.Group(),
|
||||
Users: s.userService,
|
||||
WebHub: s,
|
||||
ConfigFn: s.Config,
|
||||
ConfigFn: s.platform.Config,
|
||||
LicenseFn: s.License,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -410,7 +405,7 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
|
||||
serviceMap := map[ServiceKey]any{
|
||||
ChannelKey: &channelsWrapper{srv: s},
|
||||
ConfigKey: s.configStore,
|
||||
ConfigKey: s.platform,
|
||||
LicenseKey: s.licenseWrapper,
|
||||
FilestoreKey: s.filestore,
|
||||
FileInfoStoreKey: &fileInfoWrapper{srv: s},
|
||||
@@ -441,7 +436,7 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
// below this. Otherwise, please add it to Channels struct in app/channels.go.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
if *s.Config().LogSettings.EnableDiagnostics && *s.Config().LogSettings.EnableSentry {
|
||||
if *s.platform.Config().LogSettings.EnableDiagnostics && *s.platform.Config().LogSettings.EnableSentry {
|
||||
if strings.Contains(SentryDSN, "placeholder") {
|
||||
mlog.Warn("Sentry reporting is enabled, but SENTRY_DSN is not set. Disabling reporting.")
|
||||
} else {
|
||||
@@ -468,7 +463,7 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if *s.Config().ServiceSettings.EnableOpenTracing {
|
||||
if *s.platform.Config().ServiceSettings.EnableOpenTracing {
|
||||
tracer, err2 := tracing.New()
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
@@ -496,7 +491,7 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
|
||||
s.createPushNotificationsHub(request.EmptyContext(s.GetLogger()))
|
||||
|
||||
if err2 := i18n.InitTranslations(*s.Config().LocalizationSettings.DefaultServerLocale, *s.Config().LocalizationSettings.DefaultClientLocale); err2 != nil {
|
||||
if err2 := i18n.InitTranslations(*s.platform.Config().LocalizationSettings.DefaultServerLocale, *s.platform.Config().LocalizationSettings.DefaultClientLocale); err2 != nil {
|
||||
return nil, errors.Wrapf(err2, "unable to load Mattermost translation files")
|
||||
}
|
||||
|
||||
@@ -515,7 +510,7 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
})
|
||||
s.htmlTemplateWatcher = htmlTemplateWatcher
|
||||
|
||||
s.configListenerId = s.AddConfigListener(func(_, _ *model.Config) {
|
||||
s.configListenerId = s.platform.AddConfigListener(func(_, _ *model.Config) {
|
||||
ch := s.Channels()
|
||||
ch.regenerateClientConfig()
|
||||
|
||||
@@ -544,9 +539,10 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
})
|
||||
|
||||
s.telemetryService = telemetry.New(New(ServerConnector(s.Channels())), s.Store, s.SearchEngine, s.Log)
|
||||
s.platform.SetTelemetryId(s.TelemetryId()) // TODO: move this into platform once telemetry service moved to platform.
|
||||
|
||||
emailService, err := email.NewService(email.ServiceConfig{
|
||||
ConfigFn: s.Config,
|
||||
ConfigFn: s.platform.Config,
|
||||
LicenseFn: s.License,
|
||||
GoFn: s.Go,
|
||||
TemplatesContainer: s.TemplatesContainer(),
|
||||
@@ -558,7 +554,7 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
}
|
||||
s.EmailService = emailService
|
||||
|
||||
s.setupFeatureFlags()
|
||||
s.platform.SetupFeatureFlags()
|
||||
|
||||
s.initJobs()
|
||||
|
||||
@@ -567,7 +563,7 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
if s.Jobs != nil {
|
||||
s.Jobs.HandleClusterLeaderChange(s.IsLeader())
|
||||
}
|
||||
s.setupFeatureFlags()
|
||||
s.platform.SetupFeatureFlags()
|
||||
})
|
||||
|
||||
// If configured with a subpath, redirect 404s at the root back into the subpath.
|
||||
@@ -578,12 +574,12 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
})
|
||||
}
|
||||
|
||||
if _, err = url.ParseRequestURI(*s.Config().ServiceSettings.SiteURL); err != nil {
|
||||
if _, err = url.ParseRequestURI(*s.platform.Config().ServiceSettings.SiteURL); err != nil {
|
||||
mlog.Error("SiteURL must be set. Some features will operate incorrectly if the SiteURL is not set. See documentation for details: https://docs.mattermost.com/configure/configuration-settings.html#site-url")
|
||||
}
|
||||
|
||||
// Start email batching because it's not like the other jobs
|
||||
s.AddConfigListener(func(_, _ *model.Config) {
|
||||
s.platform.AddConfigListener(func(_, _ *model.Config) {
|
||||
s.EmailService.InitEmailBatching()
|
||||
})
|
||||
|
||||
@@ -604,7 +600,7 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
|
||||
pwd, _ := os.Getwd()
|
||||
mlog.Info("Printing current working", mlog.String("directory", pwd))
|
||||
mlog.Info("Loaded config", mlog.String("source", s.configStore.String()))
|
||||
mlog.Info("Loaded config", mlog.String("source", s.platform.DescribeConfig()))
|
||||
|
||||
allowAdvancedLogging := license != nil && *license.Features.AdvancedLogging
|
||||
|
||||
@@ -626,7 +622,7 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
|
||||
// Enable developer settings if this is a "dev" build
|
||||
if model.BuildNumber == "dev" {
|
||||
s.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableDeveloper = true })
|
||||
s.platform.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableDeveloper = true })
|
||||
}
|
||||
|
||||
if s.startMetrics {
|
||||
@@ -649,13 +645,13 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
}
|
||||
})
|
||||
|
||||
s.SearchEngine.UpdateConfig(s.Config())
|
||||
s.SearchEngine.UpdateConfig(s.platform.Config())
|
||||
searchConfigListenerId, searchLicenseListenerId := s.StartSearchEngine()
|
||||
s.searchConfigListenerId = searchConfigListenerId
|
||||
s.searchLicenseListenerId = searchLicenseListenerId
|
||||
|
||||
// if enabled - perform initial product notices fetch
|
||||
if *s.Config().AnnouncementSettings.AdminNoticesEnabled || *s.Config().AnnouncementSettings.UserNoticesEnabled {
|
||||
if *s.platform.Config().AnnouncementSettings.AdminNoticesEnabled || *s.platform.Config().AnnouncementSettings.UserNoticesEnabled {
|
||||
go func() {
|
||||
appInstance := New(ServerConnector(s.Channels()))
|
||||
if err := appInstance.UpdateProductNotices(); err != nil {
|
||||
@@ -668,7 +664,7 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
s.AddConfigListener(func(old, new *model.Config) {
|
||||
s.platform.AddConfigListener(func(old, new *model.Config) {
|
||||
appInstance := New(ServerConnector(s.Channels()))
|
||||
if *old.GuestAccountsSettings.Enable && !*new.GuestAccountsSettings.Enable {
|
||||
c := request.EmptyContext(s.GetLogger())
|
||||
@@ -679,7 +675,7 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
})
|
||||
|
||||
// Disable active guest accounts on first run if guest accounts are disabled
|
||||
if !*s.Config().GuestAccountsSettings.Enable {
|
||||
if !*s.platform.Config().GuestAccountsSettings.Enable {
|
||||
appInstance := New(ServerConnector(s.Channels()))
|
||||
c := request.EmptyContext(s.GetLogger())
|
||||
if appErr := appInstance.DeactivateGuests(c); appErr != nil {
|
||||
@@ -703,7 +699,7 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
s.initPostMetadata()
|
||||
|
||||
// Dump the image cache if the proxy settings have changed. (need switch URLs to the correct proxy)
|
||||
s.AddConfigListener(func(oldCfg, newCfg *model.Config) {
|
||||
s.platform.AddConfigListener(func(oldCfg, newCfg *model.Config) {
|
||||
if (oldCfg.ImageProxySettings.Enable != newCfg.ImageProxySettings.Enable) ||
|
||||
(oldCfg.ImageProxySettings.ImageProxyType != newCfg.ImageProxySettings.ImageProxyType) ||
|
||||
(oldCfg.ImageProxySettings.RemoteImageProxyURL != newCfg.ImageProxySettings.RemoteImageProxyURL) ||
|
||||
@@ -755,18 +751,18 @@ func (s *Server) runJobs() {
|
||||
complianceI.StartComplianceDailyJob()
|
||||
}
|
||||
|
||||
if *s.Config().JobSettings.RunJobs && s.Jobs != nil {
|
||||
if *s.platform.Config().JobSettings.RunJobs && s.Jobs != nil {
|
||||
if err := s.Jobs.StartWorkers(); err != nil {
|
||||
mlog.Error("Failed to start job server workers", mlog.Err(err))
|
||||
}
|
||||
}
|
||||
if *s.Config().JobSettings.RunScheduler && s.Jobs != nil {
|
||||
if *s.platform.Config().JobSettings.RunScheduler && s.Jobs != nil {
|
||||
if err := s.Jobs.StartSchedulers(); err != nil {
|
||||
mlog.Error("Failed to start job server schedulers", mlog.Err(err))
|
||||
}
|
||||
}
|
||||
|
||||
if *s.Config().ServiceSettings.EnableAWSMetering {
|
||||
if *s.platform.Config().ServiceSettings.EnableAWSMetering {
|
||||
runReportToAWSMeterJob(s)
|
||||
}
|
||||
}
|
||||
@@ -786,7 +782,7 @@ func (s *Server) Channels() *Channels {
|
||||
// Return Database type (postgres or mysql) and current version of the schema
|
||||
func (s *Server) DatabaseTypeAndSchemaVersion() (string, string) {
|
||||
schemaVersion, _ := s.Store.GetDBSchemaVersion()
|
||||
return *s.Config().SqlSettings.DriverName, strconv.Itoa(schemaVersion)
|
||||
return *s.platform.Config().SqlSettings.DriverName, strconv.Itoa(schemaVersion)
|
||||
}
|
||||
|
||||
// initLogging initializes and configures the logger(s). This may be called more than once.
|
||||
@@ -809,7 +805,7 @@ func (s *Server) initLogging() error {
|
||||
s.NotificationsLog = l.With(mlog.String("logSource", "notifications"))
|
||||
}
|
||||
|
||||
if err := s.configureLogger("logging", s.Log, &s.Config().LogSettings, s.configStore.Store, config.GetLogFileLocation); err != nil {
|
||||
if err := s.platform.ConfigureLogger("logging", s.Log, &s.platform.Config().LogSettings, config.GetLogFileLocation); err != nil {
|
||||
// if the config is locked then a unit test has already configured and locked the logger; not an error.
|
||||
if !errors.Is(err, mlog.ErrConfigurationLock) {
|
||||
// revert to default logger if the config is invalid
|
||||
@@ -824,8 +820,8 @@ func (s *Server) initLogging() error {
|
||||
// Use the app logger as the global logger (eventually remove all instances of global logging).
|
||||
mlog.InitGlobalLogger(s.Log)
|
||||
|
||||
notificationLogSettings := config.GetLogSettingsFromNotificationsLogSettings(&s.Config().NotificationLogSettings)
|
||||
if err := s.configureLogger("notification logging", s.NotificationsLog, notificationLogSettings, s.configStore.Store, config.GetNotificationsLogFileLocation); err != nil {
|
||||
notificationLogSettings := config.GetLogSettingsFromNotificationsLogSettings(&s.platform.Config().NotificationLogSettings)
|
||||
if err := s.platform.ConfigureLogger("notification logging", s.NotificationsLog, notificationLogSettings, config.GetNotificationsLogFileLocation); err != nil {
|
||||
if !errors.Is(err, mlog.ErrConfigurationLock) {
|
||||
mlog.Error("Error configuring notification logger", mlog.Err(err))
|
||||
return err
|
||||
@@ -834,33 +830,6 @@ func (s *Server) initLogging() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// configureLogger applies the specified configuration to a logger.
|
||||
func (s *Server) configureLogger(name string, logger *mlog.Logger, logSettings *model.LogSettings, configStore *config.Store, getPath func(string) string) error {
|
||||
// Advanced logging is E20 only, however logging must be initialized before the license
|
||||
// file is loaded. If no valid E20 license exists then advanced logging will be
|
||||
// shutdown once license is loaded/checked.
|
||||
var err error
|
||||
dsn := *logSettings.AdvancedLoggingConfig
|
||||
var logConfigSrc config.LogConfigSrc
|
||||
if dsn != "" {
|
||||
logConfigSrc, err = config.NewLogConfigSrc(dsn, configStore)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid config source for %s, %w", name, err)
|
||||
}
|
||||
mlog.Info("Loaded configuration for "+name, mlog.String("source", dsn))
|
||||
}
|
||||
|
||||
cfg, err := config.MloggerConfigFromLoggerConfig(logSettings, logConfigSrc, getPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid config source for %s, %w", name, err)
|
||||
}
|
||||
|
||||
if err := logger.ConfigureTargets(cfg, nil); err != nil {
|
||||
return fmt.Errorf("invalid config for %s, %w", name, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// removeUnlicensedLogTargets removes any unlicensed log target types.
|
||||
func (s *Server) removeUnlicensedLogTargets(license *model.License) {
|
||||
if license != nil && *license.Features.AdvancedLogging {
|
||||
@@ -895,7 +864,7 @@ func (s *Server) startInterClusterServices(license *model.License) error {
|
||||
}
|
||||
|
||||
// Config check
|
||||
if !*s.Config().ExperimentalSettings.EnableRemoteClusterService {
|
||||
if !*s.platform.Config().ExperimentalSettings.EnableRemoteClusterService {
|
||||
mlog.Debug("Remote Cluster Service disabled via config")
|
||||
return nil
|
||||
}
|
||||
@@ -924,7 +893,7 @@ func (s *Server) startInterClusterServices(license *model.License) error {
|
||||
}
|
||||
|
||||
// Config check
|
||||
if !*s.Config().ExperimentalSettings.EnableSharedChannels {
|
||||
if !*s.platform.Config().ExperimentalSettings.EnableSharedChannels {
|
||||
mlog.Debug("Shared Channels Service disabled via config")
|
||||
return nil
|
||||
}
|
||||
@@ -1029,14 +998,16 @@ func (s *Server) Shutdown() {
|
||||
|
||||
s.WaitForGoroutines()
|
||||
|
||||
s.RemoveConfigListener(s.configListenerId)
|
||||
s.platform.RemoveConfigListener(s.configListenerId)
|
||||
s.stopSearchEngine()
|
||||
|
||||
s.Audit.Shutdown()
|
||||
|
||||
s.stopFeatureFlagUpdateJob()
|
||||
s.platform.StopFeatureFlagUpdateJob()
|
||||
|
||||
s.configStore.Close()
|
||||
if err = s.platform.ShutdownConfig(); err != nil {
|
||||
s.Log.Warn("Failed to shut down config store", mlog.Err(err))
|
||||
}
|
||||
|
||||
if s.Cluster != nil {
|
||||
s.Cluster.StopInterNodeCommunication()
|
||||
@@ -1239,23 +1210,23 @@ func (s *Server) Start() error {
|
||||
|
||||
s.checkPushNotificationServerURL()
|
||||
|
||||
s.ReloadConfig()
|
||||
s.platform.ReloadConfig()
|
||||
|
||||
mlog.Info("Starting Server...")
|
||||
|
||||
var handler http.Handler = s.RootRouter
|
||||
|
||||
if *s.Config().LogSettings.EnableDiagnostics && *s.Config().LogSettings.EnableSentry && !strings.Contains(SentryDSN, "placeholder") {
|
||||
if *s.platform.Config().LogSettings.EnableDiagnostics && *s.platform.Config().LogSettings.EnableSentry && !strings.Contains(SentryDSN, "placeholder") {
|
||||
sentryHandler := sentryhttp.New(sentryhttp.Options{
|
||||
Repanic: true,
|
||||
})
|
||||
handler = sentryHandler.Handle(handler)
|
||||
}
|
||||
|
||||
if allowedOrigins := *s.Config().ServiceSettings.AllowCorsFrom; allowedOrigins != "" {
|
||||
exposedCorsHeaders := *s.Config().ServiceSettings.CorsExposedHeaders
|
||||
allowCredentials := *s.Config().ServiceSettings.CorsAllowCredentials
|
||||
debug := *s.Config().ServiceSettings.CorsDebug
|
||||
if allowedOrigins := *s.platform.Config().ServiceSettings.AllowCorsFrom; allowedOrigins != "" {
|
||||
exposedCorsHeaders := *s.platform.Config().ServiceSettings.CorsExposedHeaders
|
||||
allowCredentials := *s.platform.Config().ServiceSettings.CorsAllowCredentials
|
||||
debug := *s.platform.Config().ServiceSettings.CorsDebug
|
||||
corsWrapper := cors.New(cors.Options{
|
||||
AllowedOrigins: strings.Fields(allowedOrigins),
|
||||
AllowedMethods: corsAllowedMethods,
|
||||
@@ -1274,10 +1245,10 @@ func (s *Server) Start() error {
|
||||
handler = corsWrapper.Handler(handler)
|
||||
}
|
||||
|
||||
if *s.Config().RateLimitSettings.Enable {
|
||||
if *s.platform.Config().RateLimitSettings.Enable {
|
||||
mlog.Info("RateLimiter is enabled")
|
||||
|
||||
rateLimiter, err2 := NewRateLimiter(&s.Config().RateLimitSettings, s.Config().ServiceSettings.TrustedProxyIPHeader)
|
||||
rateLimiter, err2 := NewRateLimiter(&s.platform.Config().RateLimitSettings, s.platform.Config().ServiceSettings.TrustedProxyIPHeader)
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
@@ -1292,15 +1263,15 @@ func (s *Server) Start() error {
|
||||
|
||||
s.Server = &http.Server{
|
||||
Handler: handler,
|
||||
ReadTimeout: time.Duration(*s.Config().ServiceSettings.ReadTimeout) * time.Second,
|
||||
WriteTimeout: time.Duration(*s.Config().ServiceSettings.WriteTimeout) * time.Second,
|
||||
IdleTimeout: time.Duration(*s.Config().ServiceSettings.IdleTimeout) * time.Second,
|
||||
ReadTimeout: time.Duration(*s.platform.Config().ServiceSettings.ReadTimeout) * time.Second,
|
||||
WriteTimeout: time.Duration(*s.platform.Config().ServiceSettings.WriteTimeout) * time.Second,
|
||||
IdleTimeout: time.Duration(*s.platform.Config().ServiceSettings.IdleTimeout) * time.Second,
|
||||
ErrorLog: errStdLog,
|
||||
}
|
||||
|
||||
addr := *s.Config().ServiceSettings.ListenAddress
|
||||
addr := *s.platform.Config().ServiceSettings.ListenAddress
|
||||
if addr == "" {
|
||||
if *s.Config().ServiceSettings.ConnectionSecurity == model.ConnSecurityTLS {
|
||||
if *s.platform.Config().ServiceSettings.ConnectionSecurity == model.ConnSecurityTLS {
|
||||
addr = ":https"
|
||||
} else {
|
||||
addr = ":http"
|
||||
@@ -1317,11 +1288,11 @@ func (s *Server) Start() error {
|
||||
mlog.Info(logListeningPort, mlog.String("address", listener.Addr().String()))
|
||||
|
||||
m := &autocert.Manager{
|
||||
Cache: autocert.DirCache(*s.Config().ServiceSettings.LetsEncryptCertificateCacheFile),
|
||||
Cache: autocert.DirCache(*s.platform.Config().ServiceSettings.LetsEncryptCertificateCacheFile),
|
||||
Prompt: autocert.AcceptTOS,
|
||||
}
|
||||
|
||||
if *s.Config().ServiceSettings.Forward80To443 {
|
||||
if *s.platform.Config().ServiceSettings.Forward80To443 {
|
||||
if host, port, err := net.SplitHostPort(addr); err != nil {
|
||||
mlog.Error("Unable to setup forwarding", mlog.Err(err))
|
||||
} else if port != "443" {
|
||||
@@ -1329,7 +1300,7 @@ func (s *Server) Start() error {
|
||||
} else {
|
||||
httpListenAddress := net.JoinHostPort(host, "http")
|
||||
|
||||
if *s.Config().ServiceSettings.UseLetsEncrypt {
|
||||
if *s.platform.Config().ServiceSettings.UseLetsEncrypt {
|
||||
server := &http.Server{
|
||||
Addr: httpListenAddress,
|
||||
Handler: m.HTTPHandler(nil),
|
||||
@@ -1353,21 +1324,21 @@ func (s *Server) Start() error {
|
||||
}()
|
||||
}
|
||||
}
|
||||
} else if *s.Config().ServiceSettings.UseLetsEncrypt {
|
||||
} else if *s.platform.Config().ServiceSettings.UseLetsEncrypt {
|
||||
return errors.New(i18n.T("api.server.start_server.forward80to443.disabled_while_using_lets_encrypt"))
|
||||
}
|
||||
|
||||
s.didFinishListen = make(chan struct{})
|
||||
go func() {
|
||||
var err error
|
||||
if *s.Config().ServiceSettings.ConnectionSecurity == model.ConnSecurityTLS {
|
||||
if *s.platform.Config().ServiceSettings.ConnectionSecurity == model.ConnSecurityTLS {
|
||||
|
||||
tlsConfig := &tls.Config{
|
||||
PreferServerCipherSuites: true,
|
||||
CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
|
||||
}
|
||||
|
||||
switch *s.Config().ServiceSettings.TLSMinVer {
|
||||
switch *s.platform.Config().ServiceSettings.TLSMinVer {
|
||||
case "1.0":
|
||||
tlsConfig.MinVersion = tls.VersionTLS10
|
||||
case "1.1":
|
||||
@@ -1385,11 +1356,11 @@ func (s *Server) Start() error {
|
||||
tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
|
||||
}
|
||||
|
||||
if len(s.Config().ServiceSettings.TLSOverwriteCiphers) == 0 {
|
||||
if len(s.platform.Config().ServiceSettings.TLSOverwriteCiphers) == 0 {
|
||||
tlsConfig.CipherSuites = defaultCiphers
|
||||
} else {
|
||||
var cipherSuites []uint16
|
||||
for _, cipher := range s.Config().ServiceSettings.TLSOverwriteCiphers {
|
||||
for _, cipher := range s.platform.Config().ServiceSettings.TLSOverwriteCiphers {
|
||||
value, ok := model.ServerTLSSupportedCiphers[cipher]
|
||||
|
||||
if !ok {
|
||||
@@ -1411,12 +1382,12 @@ func (s *Server) Start() error {
|
||||
certFile := ""
|
||||
keyFile := ""
|
||||
|
||||
if *s.Config().ServiceSettings.UseLetsEncrypt {
|
||||
if *s.platform.Config().ServiceSettings.UseLetsEncrypt {
|
||||
tlsConfig.GetCertificate = m.GetCertificate
|
||||
tlsConfig.NextProtos = append(tlsConfig.NextProtos, "h2")
|
||||
} else {
|
||||
certFile = *s.Config().ServiceSettings.TLSCertFile
|
||||
keyFile = *s.Config().ServiceSettings.TLSKeyFile
|
||||
certFile = *s.platform.Config().ServiceSettings.TLSCertFile
|
||||
keyFile = *s.platform.Config().ServiceSettings.TLSKeyFile
|
||||
}
|
||||
|
||||
s.Server.TLSConfig = tlsConfig
|
||||
@@ -1433,7 +1404,7 @@ func (s *Server) Start() error {
|
||||
close(s.didFinishListen)
|
||||
}()
|
||||
|
||||
if *s.Config().ServiceSettings.EnableLocalMode {
|
||||
if *s.platform.Config().ServiceSettings.EnableLocalMode {
|
||||
if err := s.startLocalModeServer(); err != nil {
|
||||
mlog.Critical(err.Error())
|
||||
}
|
||||
@@ -1451,7 +1422,7 @@ func (s *Server) startLocalModeServer() error {
|
||||
Handler: s.LocalRouter,
|
||||
}
|
||||
|
||||
socket := *s.configStore.Get().ServiceSettings.LocalModeSocketLocation
|
||||
socket := *s.platform.Config().ServiceSettings.LocalModeSocketLocation
|
||||
if err := os.RemoveAll(socket); err != nil {
|
||||
return errors.Wrapf(err, i18n.T("api.server.start_server.starting.critical"), err)
|
||||
}
|
||||
@@ -1495,7 +1466,7 @@ func (a *App) OriginChecker() func(*http.Request) bool {
|
||||
}
|
||||
|
||||
func (s *Server) checkPushNotificationServerURL() {
|
||||
notificationServer := *s.Config().EmailSettings.PushNotificationServer
|
||||
notificationServer := *s.platform.Config().EmailSettings.PushNotificationServer
|
||||
if strings.HasPrefix(notificationServer, "http://") {
|
||||
mlog.Warn("Your push notification server is configured with HTTP. For improved security, update to HTTPS in your configuration.")
|
||||
}
|
||||
@@ -1563,7 +1534,7 @@ func runReportToAWSMeterJob(s *Server) {
|
||||
}
|
||||
|
||||
func doReportUsageToAWSMeteringService(s *Server) {
|
||||
awsMeter := awsmeter.New(s.Store, s.Config())
|
||||
awsMeter := awsmeter.New(s.Store, s.platform.Config())
|
||||
if awsMeter == nil {
|
||||
mlog.Error("Cannot obtain instance of AWS Metering Service.")
|
||||
return
|
||||
@@ -1604,12 +1575,12 @@ func doSessionCleanup(s *Server) {
|
||||
}
|
||||
|
||||
func doJobsCleanup(s *Server) {
|
||||
if *s.Config().JobSettings.CleanupJobsThresholdDays < 0 {
|
||||
if *s.platform.Config().JobSettings.CleanupJobsThresholdDays < 0 {
|
||||
return
|
||||
}
|
||||
mlog.Debug("Cleaning up jobs store.")
|
||||
|
||||
dur := time.Duration(*s.Config().JobSettings.CleanupJobsThresholdDays) * time.Hour * 24
|
||||
dur := time.Duration(*s.platform.Config().JobSettings.CleanupJobsThresholdDays) * time.Hour * 24
|
||||
expiry := model.GetMillisForTime(time.Now().Add(-dur))
|
||||
err := s.Store.Job().Cleanup(expiry, jobsCleanupBatchSize)
|
||||
if err != nil {
|
||||
@@ -1618,12 +1589,12 @@ func doJobsCleanup(s *Server) {
|
||||
}
|
||||
|
||||
func doConfigCleanup(s *Server) {
|
||||
if *s.Config().JobSettings.CleanupConfigThresholdDays < 0 || !config.IsDatabaseDSN(s.ConfigStore().Store.String()) {
|
||||
if *s.platform.Config().JobSettings.CleanupConfigThresholdDays < 0 || !config.IsDatabaseDSN(s.platform.DescribeConfig()) {
|
||||
return
|
||||
}
|
||||
mlog.Info("Cleaning up configuration store.")
|
||||
|
||||
if err := s.ConfigStore().Store.CleanUp(); err != nil {
|
||||
if err := s.platform.CleanUpConfig(); err != nil {
|
||||
mlog.Warn("Error while cleaning up configurations", mlog.Err(err))
|
||||
}
|
||||
}
|
||||
@@ -1654,7 +1625,7 @@ func (s *Server) sendLicenseUpForRenewalEmail(users map[string]*model.User, lice
|
||||
if name == "" {
|
||||
name = user.Username
|
||||
}
|
||||
if err := s.EmailService.SendLicenseUpForRenewalEmail(user.Email, name, user.Locale, *s.Config().ServiceSettings.SiteURL, renewalLink, daysToExpiration); err != nil {
|
||||
if err := s.EmailService.SendLicenseUpForRenewalEmail(user.Email, name, user.Locale, *s.platform.Config().ServiceSettings.SiteURL, renewalLink, daysToExpiration); err != nil {
|
||||
mlog.Error("Error sending license up for renewal email to", mlog.String("user_email", user.Email), mlog.Err(err))
|
||||
countNotOks++
|
||||
}
|
||||
@@ -1735,7 +1706,7 @@ func (s *Server) doLicenseExpirationCheck() {
|
||||
|
||||
mlog.Debug("Sending license expired email.", mlog.String("user_email", user.Email))
|
||||
s.Go(func() {
|
||||
if err := s.SendRemoveExpiredLicenseEmail(user.Email, renewalLink, user.Locale, *s.Config().ServiceSettings.SiteURL); err != nil {
|
||||
if err := s.SendRemoveExpiredLicenseEmail(user.Email, renewalLink, user.Locale, *s.platform.Config().ServiceSettings.SiteURL); err != nil {
|
||||
mlog.Error("Error while sending the license expired email.", mlog.String("user_email", user.Email), mlog.Err(err))
|
||||
}
|
||||
})
|
||||
@@ -1765,7 +1736,7 @@ func (s *Server) StartSearchEngine() (string, string) {
|
||||
})
|
||||
}
|
||||
|
||||
configListenerId := s.AddConfigListener(func(oldConfig *model.Config, newConfig *model.Config) {
|
||||
configListenerId := s.platform.AddConfigListener(func(oldConfig *model.Config, newConfig *model.Config) {
|
||||
if s.SearchEngine == nil {
|
||||
return
|
||||
}
|
||||
@@ -1824,7 +1795,7 @@ func (s *Server) StartSearchEngine() (string, string) {
|
||||
}
|
||||
|
||||
func (s *Server) stopSearchEngine() {
|
||||
s.RemoveConfigListener(s.searchConfigListenerId)
|
||||
s.platform.RemoveConfigListener(s.searchConfigListenerId)
|
||||
s.RemoveLicenseListener(s.searchLicenseListenerId)
|
||||
if s.SearchEngine != nil && s.SearchEngine.ElasticsearchEngine != nil && s.SearchEngine.ElasticsearchEngine.IsActive() {
|
||||
s.SearchEngine.ElasticsearchEngine.Stop()
|
||||
@@ -1858,7 +1829,7 @@ func (ch *Channels) ClientConfigHash() string {
|
||||
}
|
||||
|
||||
func (s *Server) initJobs() {
|
||||
s.Jobs = jobs.NewJobServer(s, s.Store, s.GetMetrics())
|
||||
s.Jobs = jobs.NewJobServer(s.platform, s.Store, s.GetMetrics())
|
||||
|
||||
if jobsDataRetentionJobInterface != nil {
|
||||
builder := jobsDataRetentionJobInterface(s)
|
||||
@@ -2031,7 +2002,7 @@ func (s *Server) SetSharedChannelSyncService(sharedChannelService SharedChannelS
|
||||
}
|
||||
|
||||
func (s *Server) GetProfileImage(user *model.User) ([]byte, bool, *model.AppError) {
|
||||
if *s.Config().FileSettings.DriverName == "" {
|
||||
if *s.platform.Config().FileSettings.DriverName == "" {
|
||||
img, appErr := s.GetDefaultProfileImage(user)
|
||||
if appErr != nil {
|
||||
return nil, false, appErr
|
||||
@@ -2141,3 +2112,8 @@ func (a *App) GetAppliedSchemaMigrations() ([]model.AppliedMigration, *model.App
|
||||
}
|
||||
return table, nil
|
||||
}
|
||||
|
||||
// Expose platform service from server, this should be replaced with server itself in time.
|
||||
func (s *Server) Platform() *platform.PlatformService {
|
||||
return s.platform
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user