root.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // Package cmd provides Command Line Interface support
  2. package cmd
  3. import (
  4. "fmt"
  5. "os"
  6. "strconv"
  7. "github.com/drakkan/sftpgo/config"
  8. "github.com/drakkan/sftpgo/utils"
  9. "github.com/spf13/cobra"
  10. "github.com/spf13/viper"
  11. )
  12. const (
  13. logSender = "cmd"
  14. configDirFlag = "config-dir"
  15. configDirKey = "config_dir"
  16. configFileFlag = "config-file"
  17. configFileKey = "config_file"
  18. logFilePathFlag = "log-file-path"
  19. logFilePathKey = "log_file_path"
  20. logMaxSizeFlag = "log-max-size"
  21. logMaxSizeKey = "log_max_size"
  22. logMaxBackupFlag = "log-max-backups"
  23. logMaxBackupKey = "log_max_backups"
  24. logMaxAgeFlag = "log-max-age"
  25. logMaxAgeKey = "log_max_age"
  26. logCompressFlag = "log-compress"
  27. logCompressKey = "log_compress"
  28. logVerboseFlag = "log-verbose"
  29. logVerboseKey = "log_verbose"
  30. defaultConfigDir = "."
  31. defaultConfigName = config.DefaultConfigName
  32. defaultLogFile = "sftpgo.log"
  33. defaultLogMaxSize = 10
  34. defaultLogMaxBackup = 5
  35. defaultLogMaxAge = 28
  36. defaultLogCompress = false
  37. defaultLogVerbose = true
  38. )
  39. var (
  40. configDir string
  41. configFile string
  42. logFilePath string
  43. logMaxSize int
  44. logMaxBackups int
  45. logMaxAge int
  46. logCompress bool
  47. logVerbose bool
  48. rootCmd = &cobra.Command{
  49. Use: "sftpgo",
  50. Short: "Full featured and highly configurable SFTP server",
  51. }
  52. )
  53. func init() {
  54. version := utils.GetAppVersion()
  55. rootCmd.Flags().BoolP("version", "v", false, "")
  56. rootCmd.Version = version.GetVersionAsString()
  57. rootCmd.SetVersionTemplate(`{{printf "SFTPGo version: "}}{{printf "%s" .Version}}
  58. `)
  59. }
  60. // Execute adds all child commands to the root command and sets flags appropriately.
  61. // This is called by main.main(). It only needs to happen once to the rootCmd.
  62. func Execute() {
  63. if err := rootCmd.Execute(); err != nil {
  64. fmt.Println(err)
  65. os.Exit(1)
  66. }
  67. }
  68. func addConfigFlags(cmd *cobra.Command) {
  69. viper.SetDefault(configDirKey, defaultConfigDir)
  70. viper.BindEnv(configDirKey, "SFTPGO_CONFIG_DIR")
  71. cmd.Flags().StringVarP(&configDir, configDirFlag, "c", viper.GetString(configDirKey),
  72. "Location for SFTPGo config dir. This directory should contain the \"sftpgo\" configuration file or the configured "+
  73. "config-file and it is used as the base for files with a relative path (eg. the private keys for the SFTP server, "+
  74. "the SQLite database if you use SQLite as data provider). This flag can be set using SFTPGO_CONFIG_DIR env var too.")
  75. viper.BindPFlag(configDirKey, cmd.Flags().Lookup(configDirFlag))
  76. viper.SetDefault(configFileKey, defaultConfigName)
  77. viper.BindEnv(configFileKey, "SFTPGO_CONFIG_FILE")
  78. cmd.Flags().StringVarP(&configFile, configFileFlag, "f", viper.GetString(configFileKey),
  79. "Name for SFTPGo configuration file. It must be the name of a file stored in config-dir not the absolute path to the "+
  80. "configuration file. The specified file name must have no extension we automatically load JSON, YAML, TOML, HCL and "+
  81. "Java properties. Therefore if you set \"sftpgo\" then \"sftpgo.json\", \"sftpgo.yaml\" and so on are searched. "+
  82. "This flag can be set using SFTPGO_CONFIG_FILE env var too.")
  83. viper.BindPFlag(configFileKey, cmd.Flags().Lookup(configFileFlag))
  84. }
  85. func addServeFlags(cmd *cobra.Command) {
  86. addConfigFlags(cmd)
  87. viper.SetDefault(logFilePathKey, defaultLogFile)
  88. viper.BindEnv(logFilePathKey, "SFTPGO_LOG_FILE_PATH")
  89. cmd.Flags().StringVarP(&logFilePath, logFilePathFlag, "l", viper.GetString(logFilePathKey),
  90. "Location for the log file. Leave empty to write logs to the standard output. This flag can be set using SFTPGO_LOG_FILE_PATH "+
  91. "env var too.")
  92. viper.BindPFlag(logFilePathKey, cmd.Flags().Lookup(logFilePathFlag))
  93. viper.SetDefault(logMaxSizeKey, defaultLogMaxSize)
  94. viper.BindEnv(logMaxSizeKey, "SFTPGO_LOG_MAX_SIZE")
  95. cmd.Flags().IntVarP(&logMaxSize, logMaxSizeFlag, "s", viper.GetInt(logMaxSizeKey),
  96. "Maximum size in megabytes of the log file before it gets rotated. This flag can be set using SFTPGO_LOG_MAX_SIZE "+
  97. "env var too. It is unused if log-file-path is empty.")
  98. viper.BindPFlag(logMaxSizeKey, cmd.Flags().Lookup(logMaxSizeFlag))
  99. viper.SetDefault(logMaxBackupKey, defaultLogMaxBackup)
  100. viper.BindEnv(logMaxBackupKey, "SFTPGO_LOG_MAX_BACKUPS")
  101. cmd.Flags().IntVarP(&logMaxBackups, "log-max-backups", "b", viper.GetInt(logMaxBackupKey),
  102. "Maximum number of old log files to retain. This flag can be set using SFTPGO_LOG_MAX_BACKUPS env var too. "+
  103. "It is unused if log-file-path is empty.")
  104. viper.BindPFlag(logMaxBackupKey, cmd.Flags().Lookup(logMaxBackupFlag))
  105. viper.SetDefault(logMaxAgeKey, defaultLogMaxAge)
  106. viper.BindEnv(logMaxAgeKey, "SFTPGO_LOG_MAX_AGE")
  107. cmd.Flags().IntVarP(&logMaxAge, "log-max-age", "a", viper.GetInt(logMaxAgeKey),
  108. "Maximum number of days to retain old log files. This flag can be set using SFTPGO_LOG_MAX_AGE env var too. "+
  109. "It is unused if log-file-path is empty.")
  110. viper.BindPFlag(logMaxAgeKey, cmd.Flags().Lookup(logMaxAgeFlag))
  111. viper.SetDefault(logCompressKey, defaultLogCompress)
  112. viper.BindEnv(logCompressKey, "SFTPGO_LOG_COMPRESS")
  113. cmd.Flags().BoolVarP(&logCompress, logCompressFlag, "z", viper.GetBool(logCompressKey), "Determine if the rotated "+
  114. "log files should be compressed using gzip. This flag can be set using SFTPGO_LOG_COMPRESS env var too. "+
  115. "It is unused if log-file-path is empty.")
  116. viper.BindPFlag(logCompressKey, cmd.Flags().Lookup(logCompressFlag))
  117. viper.SetDefault(logVerboseKey, defaultLogVerbose)
  118. viper.BindEnv(logVerboseKey, "SFTPGO_LOG_VERBOSE")
  119. cmd.Flags().BoolVarP(&logVerbose, logVerboseFlag, "v", viper.GetBool(logVerboseKey), "Enable verbose logs. "+
  120. "This flag can be set using SFTPGO_LOG_VERBOSE env var too.")
  121. viper.BindPFlag(logVerboseKey, cmd.Flags().Lookup(logVerboseFlag))
  122. }
  123. func getCustomServeFlags() []string {
  124. result := []string{}
  125. if configDir != defaultConfigDir {
  126. configDir = utils.CleanDirInput(configDir)
  127. result = append(result, "--"+configDirFlag)
  128. result = append(result, configDir)
  129. }
  130. if configFile != defaultConfigName {
  131. result = append(result, "--"+configFileFlag)
  132. result = append(result, configFile)
  133. }
  134. if logFilePath != defaultLogFile {
  135. result = append(result, "--"+logFilePathFlag)
  136. result = append(result, logFilePath)
  137. }
  138. if logMaxSize != defaultLogMaxSize {
  139. result = append(result, "--"+logMaxSizeFlag)
  140. result = append(result, strconv.Itoa(logMaxSize))
  141. }
  142. if logMaxBackups != defaultLogMaxBackup {
  143. result = append(result, "--"+logMaxBackupFlag)
  144. result = append(result, strconv.Itoa(logMaxBackups))
  145. }
  146. if logMaxAge != defaultLogMaxAge {
  147. result = append(result, "--"+logMaxAgeFlag)
  148. result = append(result, strconv.Itoa(logMaxAge))
  149. }
  150. if logVerbose != defaultLogVerbose {
  151. result = append(result, "--"+logVerboseFlag+"=false")
  152. }
  153. if logCompress != defaultLogCompress {
  154. result = append(result, "--"+logCompressFlag+"=true")
  155. }
  156. return result
  157. }