server.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * Rufs - Remote Union File System
  3. *
  4. * Copyright 2017 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the MIT
  7. * License, If a copy of the MIT License was not distributed with this
  8. * file, You can obtain one at https://opensource.org/licenses/MIT.
  9. */
  10. package main
  11. import (
  12. "flag"
  13. "fmt"
  14. "os"
  15. "os/signal"
  16. "path/filepath"
  17. "sync"
  18. "syscall"
  19. "devt.de/krotik/common/datautil"
  20. "devt.de/krotik/common/errorutil"
  21. "devt.de/krotik/common/fileutil"
  22. "devt.de/krotik/rufs"
  23. "devt.de/krotik/rufs/config"
  24. )
  25. /*
  26. DefaultServerConfigFile is the default config file when running in server mode
  27. */
  28. const DefaultServerConfigFile = "rufs.server.json"
  29. /*
  30. serverCli handles the server command line.
  31. */
  32. func serverCli() error {
  33. var err error
  34. serverConfigFile := flag.String("config", DefaultServerConfigFile, "Server configuration file")
  35. secretFile, certDir := commonCliOptions()
  36. showHelp := flag.Bool("help", false, "Show this help message")
  37. flag.Usage = func() {
  38. fmt.Println()
  39. fmt.Println(fmt.Sprintf("Usage of %s server [options]", os.Args[0]))
  40. fmt.Println()
  41. flag.PrintDefaults()
  42. fmt.Println()
  43. fmt.Println("The server will automatically create a default config file and")
  44. fmt.Println("default directories if nothing is specified.")
  45. fmt.Println()
  46. }
  47. flag.CommandLine.Parse(os.Args[2:])
  48. if *showHelp {
  49. flag.Usage()
  50. return nil
  51. }
  52. // Load secret and ssl certificate
  53. secret, cert, err := loadSecretAndCert(*secretFile, *certDir)
  54. if err == nil {
  55. // Load configuration
  56. var cfg map[string]interface{}
  57. defaultConfig := datautil.MergeMaps(config.DefaultBranchExportConfig)
  58. delete(defaultConfig, config.BranchSecret)
  59. // Set environment specific values for default config
  60. if ip, lerr := externalIP(); lerr == nil {
  61. defaultConfig[config.BranchName] = ip
  62. defaultConfig[config.RPCHost] = ip
  63. }
  64. cfg, err = fileutil.LoadConfig(*serverConfigFile, defaultConfig)
  65. errorutil.AssertOk(err)
  66. cfg[config.BranchSecret] = secret
  67. fmt.Println(fmt.Sprintf("Using config: %s", *serverConfigFile))
  68. // Ensure the local shared folder actually exists
  69. if ok, _ := fileutil.PathExists(cfg[config.LocalFolder].(string)); !ok {
  70. os.MkdirAll(cfg[config.LocalFolder].(string), 0777)
  71. }
  72. absLocalFolder, _ := filepath.Abs(cfg[config.LocalFolder].(string))
  73. fmt.Println(fmt.Sprintf("Exporting folder: %s", absLocalFolder))
  74. // We got everything together let's start
  75. var branch *rufs.Branch
  76. if branch, err = rufs.NewBranch(cfg, cert); err == nil {
  77. // Attach SIGINT handler - on unix and windows this is send
  78. // when the user presses ^C (Control-C).
  79. sigchan := make(chan os.Signal)
  80. signal.Notify(sigchan, syscall.SIGINT)
  81. // Create a wait group to wait for the os signal
  82. wg := sync.WaitGroup{}
  83. // Kick off a polling thread which waits for the signal
  84. go func() {
  85. for true {
  86. signal := <-sigchan
  87. if signal == syscall.SIGINT {
  88. // Shutdown the branch
  89. branch.Shutdown()
  90. break
  91. }
  92. }
  93. // Done waiting main thread can exit
  94. wg.Done()
  95. }()
  96. // Suspend main thread until branch is shutdown
  97. wg.Add(1)
  98. wg.Wait()
  99. }
  100. }
  101. return err
  102. }