github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/cmd/mattermost/commands/server.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package commands 5 6 import ( 7 "net" 8 "os" 9 "os/signal" 10 "syscall" 11 12 "github.com/mattermost/mattermost-server/v5/api4" 13 "github.com/mattermost/mattermost-server/v5/app" 14 "github.com/mattermost/mattermost-server/v5/config" 15 "github.com/mattermost/mattermost-server/v5/manualtesting" 16 "github.com/mattermost/mattermost-server/v5/mlog" 17 "github.com/mattermost/mattermost-server/v5/utils" 18 "github.com/mattermost/mattermost-server/v5/web" 19 "github.com/mattermost/mattermost-server/v5/wsapi" 20 "github.com/mattermost/viper" 21 "github.com/pkg/errors" 22 "github.com/spf13/cobra" 23 ) 24 25 var serverCmd = &cobra.Command{ 26 Use: "server", 27 Short: "Run the Mattermost server", 28 RunE: serverCmdF, 29 SilenceUsage: true, 30 } 31 32 func init() { 33 RootCmd.AddCommand(serverCmd) 34 RootCmd.RunE = serverCmdF 35 } 36 37 func serverCmdF(command *cobra.Command, args []string) error { 38 configDSN := viper.GetString("config") 39 40 disableConfigWatch, _ := command.Flags().GetBool("disableconfigwatch") 41 usedPlatform, _ := command.Flags().GetBool("platform") 42 43 interruptChan := make(chan os.Signal, 1) 44 45 if err := utils.TranslationsPreInit(); err != nil { 46 return errors.Wrapf(err, "unable to load Mattermost translation files") 47 } 48 configStore, err := config.NewStore(configDSN, !disableConfigWatch) 49 if err != nil { 50 return errors.Wrap(err, "failed to load configuration") 51 } 52 53 return runServer(configStore, disableConfigWatch, usedPlatform, interruptChan) 54 } 55 56 func runServer(configStore config.Store, disableConfigWatch bool, usedPlatform bool, interruptChan chan os.Signal) error { 57 options := []app.Option{ 58 app.ConfigStore(configStore), 59 app.RunJobs, 60 app.JoinCluster, 61 app.StartSearchEngine, 62 app.StartMetrics, 63 } 64 server, err := app.NewServer(options...) 65 if err != nil { 66 mlog.Critical(err.Error()) 67 return err 68 } 69 defer server.Shutdown() 70 71 if usedPlatform { 72 mlog.Error("The platform binary has been deprecated, please switch to using the mattermost binary.") 73 } 74 75 api := api4.Init(server, server.AppOptions, server.Router) 76 wsapi.Init(server) 77 web.New(server, server.AppOptions, server.Router) 78 api4.InitLocal(server, server.AppOptions, server.LocalRouter) 79 80 serverErr := server.Start() 81 if serverErr != nil { 82 mlog.Critical(serverErr.Error()) 83 return serverErr 84 } 85 86 // If we allow testing then listen for manual testing URL hits 87 if *server.Config().ServiceSettings.EnableTesting { 88 manualtesting.Init(api) 89 } 90 91 notifyReady() 92 93 // wait for kill signal before attempting to gracefully shutdown 94 // the running service 95 signal.Notify(interruptChan, syscall.SIGINT, syscall.SIGTERM) 96 <-interruptChan 97 98 return nil 99 } 100 101 func notifyReady() { 102 // If the environment vars provide a systemd notification socket, 103 // notify systemd that the server is ready. 104 systemdSocket := os.Getenv("NOTIFY_SOCKET") 105 if systemdSocket != "" { 106 mlog.Info("Sending systemd READY notification.") 107 108 err := sendSystemdReadyNotification(systemdSocket) 109 if err != nil { 110 mlog.Error(err.Error()) 111 } 112 } 113 } 114 115 func sendSystemdReadyNotification(socketPath string) error { 116 msg := "READY=1" 117 addr := &net.UnixAddr{ 118 Name: socketPath, 119 Net: "unixgram", 120 } 121 conn, err := net.DialUnix(addr.Net, nil, addr) 122 if err != nil { 123 return err 124 } 125 defer conn.Close() 126 _, err = conn.Write([]byte(msg)) 127 return err 128 }