main.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. package main
  2. import (
  3. "flag"
  4. log "github.com/sirupsen/logrus"
  5. "github.com/OliveTin/OliveTin/internal/entityfiles"
  6. "github.com/OliveTin/OliveTin/internal/executor"
  7. grpcapi "github.com/OliveTin/OliveTin/internal/grpcapi"
  8. "github.com/OliveTin/OliveTin/internal/httpservers"
  9. "github.com/OliveTin/OliveTin/internal/installationinfo"
  10. "github.com/OliveTin/OliveTin/internal/oncalendarfile"
  11. "github.com/OliveTin/OliveTin/internal/oncron"
  12. "github.com/OliveTin/OliveTin/internal/onfileindir"
  13. "github.com/OliveTin/OliveTin/internal/onstartup"
  14. "github.com/OliveTin/OliveTin/internal/servicehost"
  15. updatecheck "github.com/OliveTin/OliveTin/internal/updatecheck"
  16. "os"
  17. "strconv"
  18. config "github.com/OliveTin/OliveTin/internal/config"
  19. "github.com/fsnotify/fsnotify"
  20. "github.com/spf13/viper"
  21. )
  22. var (
  23. cfg *config.Config
  24. version = "dev"
  25. commit = "nocommit"
  26. date = "nodate"
  27. )
  28. func init() {
  29. initLog()
  30. initViperConfig(initCliFlags())
  31. initCheckEnvironment()
  32. initInstallationInfo()
  33. log.Info("OliveTin initialization complete")
  34. }
  35. func initLog() {
  36. logFormat := os.Getenv("OLIVETIN_LOG_FORMAT")
  37. if logFormat == "json" {
  38. log.SetFormatter(&log.JSONFormatter{})
  39. } else {
  40. log.SetFormatter(&log.TextFormatter{
  41. ForceQuote: true,
  42. DisableTimestamp: true,
  43. })
  44. }
  45. // Use debug this early on to catch details about startup errors. The
  46. // default config will raise the log level later, if not set.
  47. log.SetLevel(log.DebugLevel) // Default to debug, to catch cfg issue
  48. }
  49. func initCliFlags() string {
  50. var configDir string
  51. flag.StringVar(&configDir, "configdir", ".", "Config directory path")
  52. var printVersion bool
  53. flag.BoolVar(&printVersion, "version", false, "Prints the version number and exits")
  54. flag.Parse()
  55. // This log message should be the first log message OliveTin prints.
  56. if printVersion {
  57. logStartupMessage("OliveTin is just printing the startup message")
  58. os.Exit(1)
  59. } else {
  60. logStartupMessage("OliveTin initializing")
  61. }
  62. log.WithFields(log.Fields{
  63. "value": configDir,
  64. }).Debugf("Value of -configdir flag")
  65. return configDir
  66. }
  67. func getBasePort() int {
  68. var err error
  69. defaultPort := 1337
  70. basePort := defaultPort
  71. envPort := os.Getenv("PORT")
  72. if envPort != "" {
  73. basePort, err = strconv.Atoi(os.Getenv("PORT"))
  74. if err != nil {
  75. log.Errorf("Error converting port to int. %s", err)
  76. os.Exit(1)
  77. }
  78. }
  79. if defaultPort != basePort {
  80. log.WithFields(log.Fields{
  81. "basePort": basePort,
  82. }).Debug("Base port")
  83. }
  84. return basePort
  85. }
  86. func initViperConfig(configDir string) {
  87. viper.AutomaticEnv()
  88. viper.SetConfigName("config.yaml")
  89. viper.SetConfigType("yaml")
  90. viper.AddConfigPath(configDir)
  91. viper.AddConfigPath(servicehost.GetConfigFilePath())
  92. viper.AddConfigPath("/config") // For containers.
  93. viper.AddConfigPath("/etc/OliveTin/")
  94. if err := viper.ReadInConfig(); err != nil {
  95. log.Errorf("Config file error at startup. %s", err)
  96. os.Exit(1)
  97. }
  98. cfg = config.DefaultConfigWithBasePort(getBasePort())
  99. viper.WatchConfig()
  100. viper.OnConfigChange(func(e fsnotify.Event) {
  101. log.Infof("Config file changed: %s", viper.ConfigFileUsed())
  102. config.Reload(cfg)
  103. })
  104. config.Reload(cfg)
  105. }
  106. func initInstallationInfo() {
  107. installationinfo.Config = cfg
  108. installationinfo.Build.Version = version
  109. installationinfo.Build.Commit = commit
  110. installationinfo.Build.Date = date
  111. }
  112. func logStartupMessage(message string) {
  113. log.WithFields(log.Fields{
  114. "version": version,
  115. "commit": commit,
  116. "date": date,
  117. }).Info(message)
  118. }
  119. func initCheckEnvironment() {
  120. warnIfPuidGuid()
  121. }
  122. func warnIfPuidGuid() {
  123. if os.Getenv("PUID") != "" || os.Getenv("PGID") != "" {
  124. log.Warnf("PUID or PGID seem to be set to something, but they are ignored by OliveTin. Please check https://docs.olivetin.app/no-puid-pgid.html")
  125. }
  126. }
  127. func main() {
  128. servicehost.Start(cfg.ServiceHostMode)
  129. log.WithFields(log.Fields{
  130. "configDir": cfg.GetDir(),
  131. }).Infof("OliveTin started")
  132. log.Debugf("Config: %+v", cfg)
  133. executor := executor.DefaultExecutor(cfg)
  134. executor.RebuildActionMap()
  135. executor.AddListener(httpservers.ExecutionListener)
  136. config.AddListener(executor.RebuildActionMap)
  137. go onstartup.Execute(cfg, executor)
  138. go oncron.Schedule(cfg, executor)
  139. go onfileindir.WatchFilesInDirectory(cfg, executor)
  140. go oncalendarfile.Schedule(cfg, executor)
  141. entityfiles.AddListener(httpservers.OnEntityChanged)
  142. entityfiles.AddListener(executor.RebuildActionMap)
  143. go entityfiles.SetupEntityFileWatchers(cfg)
  144. go updatecheck.StartUpdateChecker(cfg)
  145. go grpcapi.Start(cfg, executor)
  146. httpservers.StartServers(cfg)
  147. }