service.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // Package service allows to start and stop the SFTPGo service
  2. package service
  3. import (
  4. "path/filepath"
  5. "github.com/rs/zerolog"
  6. "github.com/drakkan/sftpgo/config"
  7. "github.com/drakkan/sftpgo/dataprovider"
  8. "github.com/drakkan/sftpgo/httpd"
  9. "github.com/drakkan/sftpgo/logger"
  10. "github.com/drakkan/sftpgo/sftpd"
  11. "github.com/drakkan/sftpgo/utils"
  12. )
  13. const (
  14. logSender = "service"
  15. )
  16. var (
  17. chars = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
  18. )
  19. // Service defines the SFTPGo service
  20. type Service struct {
  21. ConfigDir string
  22. ConfigFile string
  23. LogFilePath string
  24. LogMaxSize int
  25. LogMaxBackups int
  26. LogMaxAge int
  27. PortableMode int
  28. PortableUser dataprovider.User
  29. LogCompress bool
  30. LogVerbose bool
  31. Profiler bool
  32. Shutdown chan bool
  33. }
  34. // Start initializes the service
  35. func (s *Service) Start() error {
  36. logLevel := zerolog.DebugLevel
  37. if !s.LogVerbose {
  38. logLevel = zerolog.InfoLevel
  39. }
  40. if !filepath.IsAbs(s.LogFilePath) && utils.IsFileInputValid(s.LogFilePath) {
  41. s.LogFilePath = filepath.Join(s.ConfigDir, s.LogFilePath)
  42. }
  43. logger.InitLogger(s.LogFilePath, s.LogMaxSize, s.LogMaxBackups, s.LogMaxAge, s.LogCompress, logLevel)
  44. if s.PortableMode == 1 {
  45. logger.EnableConsoleLogger(logLevel)
  46. if len(s.LogFilePath) == 0 {
  47. logger.DisableLogger()
  48. }
  49. }
  50. version := utils.GetAppVersion()
  51. logger.Info(logSender, "", "starting SFTPGo %v, config dir: %v, config file: %v, log max size: %v log max backups: %v "+
  52. "log max age: %v log verbose: %v, log compress: %v, profile: %v", version.GetVersionAsString(), s.ConfigDir, s.ConfigFile,
  53. s.LogMaxSize, s.LogMaxBackups, s.LogMaxAge, s.LogVerbose, s.LogCompress, s.Profiler)
  54. // in portable mode we don't read configuration from file
  55. if s.PortableMode != 1 {
  56. err := config.LoadConfig(s.ConfigDir, s.ConfigFile)
  57. if err != nil {
  58. logger.Error(logSender, "", "error loading configuration: %v", err)
  59. }
  60. }
  61. providerConf := config.GetProviderConf()
  62. err := dataprovider.Initialize(providerConf, s.ConfigDir)
  63. if err != nil {
  64. logger.Error(logSender, "", "error initializing data provider: %v", err)
  65. logger.ErrorToConsole("error initializing data provider: %v", err)
  66. return err
  67. }
  68. httpConfig := config.GetHTTPConfig()
  69. httpConfig.Initialize(s.ConfigDir)
  70. dataProvider := dataprovider.GetProvider()
  71. sftpdConf := config.GetSFTPDConfig()
  72. httpdConf := config.GetHTTPDConfig()
  73. if s.PortableMode == 1 {
  74. // create the user for portable mode
  75. err = dataprovider.AddUser(dataProvider, s.PortableUser)
  76. if err != nil {
  77. logger.ErrorToConsole("error adding portable user: %v", err)
  78. return err
  79. }
  80. }
  81. sftpd.SetDataProvider(dataProvider)
  82. go func() {
  83. logger.Debug(logSender, "", "initializing SFTP server with config %+v", sftpdConf)
  84. if err := sftpdConf.Initialize(s.ConfigDir); err != nil {
  85. logger.Error(logSender, "", "could not start SFTP server: %v", err)
  86. logger.ErrorToConsole("could not start SFTP server: %v", err)
  87. }
  88. s.Shutdown <- true
  89. }()
  90. if httpdConf.BindPort > 0 {
  91. httpd.SetDataProvider(dataProvider)
  92. go func() {
  93. if err := httpdConf.Initialize(s.ConfigDir, s.Profiler); err != nil {
  94. logger.Error(logSender, "", "could not start HTTP server: %v", err)
  95. logger.ErrorToConsole("could not start HTTP server: %v", err)
  96. }
  97. s.Shutdown <- true
  98. }()
  99. } else {
  100. logger.Debug(logSender, "", "HTTP server not started, disabled in config file")
  101. if s.PortableMode != 1 {
  102. logger.DebugToConsole("HTTP server not started, disabled in config file")
  103. }
  104. }
  105. return nil
  106. }
  107. // Wait blocks until the service exits
  108. func (s *Service) Wait() {
  109. if s.PortableMode != 1 {
  110. registerSigHup()
  111. }
  112. <-s.Shutdown
  113. }
  114. // Stop terminates the service unblocking the Wait method
  115. func (s *Service) Stop() {
  116. close(s.Shutdown)
  117. logger.Debug(logSender, "", "Service stopped")
  118. }