github.com/ashishbhate/mattermost-server@v5.11.1+incompatible/cmd/mattermost/commands/server.go (about)

     1  // Copyright (c) 2016-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/api4"
    13  	"github.com/mattermost/mattermost-server/app"
    14  	"github.com/mattermost/mattermost-server/config"
    15  	"github.com/mattermost/mattermost-server/manualtesting"
    16  	"github.com/mattermost/mattermost-server/mlog"
    17  	"github.com/mattermost/mattermost-server/utils"
    18  	"github.com/mattermost/mattermost-server/web"
    19  	"github.com/mattermost/mattermost-server/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 err
    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.StartElasticsearch,
    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  	serverErr := server.Start()
    76  	if serverErr != nil {
    77  		mlog.Critical(serverErr.Error())
    78  		return serverErr
    79  	}
    80  
    81  	api := api4.Init(server, server.AppOptions, server.Router)
    82  	wsapi.Init(server.FakeApp(), server.WebSocketRouter)
    83  	web.New(server, server.AppOptions, server.Router)
    84  
    85  	// If we allow testing then listen for manual testing URL hits
    86  	if *server.Config().ServiceSettings.EnableTesting {
    87  		manualtesting.Init(api)
    88  	}
    89  
    90  	notifyReady()
    91  
    92  	// wait for kill signal before attempting to gracefully shutdown
    93  	// the running service
    94  	signal.Notify(interruptChan, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
    95  	<-interruptChan
    96  
    97  	return nil
    98  }
    99  
   100  func notifyReady() {
   101  	// If the environment vars provide a systemd notification socket,
   102  	// notify systemd that the server is ready.
   103  	systemdSocket := os.Getenv("NOTIFY_SOCKET")
   104  	if systemdSocket != "" {
   105  		mlog.Info("Sending systemd READY notification.")
   106  
   107  		err := sendSystemdReadyNotification(systemdSocket)
   108  		if err != nil {
   109  			mlog.Error(err.Error())
   110  		}
   111  	}
   112  }
   113  
   114  func sendSystemdReadyNotification(socketPath string) error {
   115  	msg := "READY=1"
   116  	addr := &net.UnixAddr{
   117  		Name: socketPath,
   118  		Net:  "unixgram",
   119  	}
   120  	conn, err := net.DialUnix(addr.Net, nil, addr)
   121  	if err != nil {
   122  		return err
   123  	}
   124  	defer conn.Close()
   125  	_, err = conn.Write([]byte(msg))
   126  	return err
   127  }