service.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "os"
  6. "path/filepath"
  7. "github.com/kardianos/service"
  8. "github.com/sirupsen/logrus"
  9. "github.com/slackhq/nebula"
  10. )
  11. var logger service.Logger
  12. type program struct {
  13. configPath *string
  14. configTest *bool
  15. build string
  16. control *nebula.Control
  17. }
  18. func (p *program) Start(s service.Service) error {
  19. // Start should not block.
  20. logger.Info("Nebula service starting.")
  21. l := logrus.New()
  22. HookLogger(l)
  23. config := nebula.NewConfig(l)
  24. err := config.Load(*p.configPath)
  25. if err != nil {
  26. return fmt.Errorf("failed to load config: %s", err)
  27. }
  28. p.control, err = nebula.Main(config, *p.configTest, Build, l, nil)
  29. if err != nil {
  30. return err
  31. }
  32. p.control.Start()
  33. return nil
  34. }
  35. func (p *program) Stop(s service.Service) error {
  36. logger.Info("Nebula service stopping.")
  37. p.control.Stop()
  38. return nil
  39. }
  40. func doService(configPath *string, configTest *bool, build string, serviceFlag *string) {
  41. if *configPath == "" {
  42. ex, err := os.Executable()
  43. if err != nil {
  44. panic(err)
  45. }
  46. *configPath = filepath.Dir(ex) + "/config.yaml"
  47. }
  48. svcConfig := &service.Config{
  49. Name: "Nebula",
  50. DisplayName: "Nebula Network Service",
  51. Description: "Nebula network connectivity daemon for encrypted communications",
  52. Arguments: []string{"-service", "run", "-config", *configPath},
  53. }
  54. prg := &program{
  55. configPath: configPath,
  56. configTest: configTest,
  57. build: build,
  58. }
  59. // Here are what the different loggers are doing:
  60. // - `log` is the standard go log utility, meant to be used while the process is still attached to stdout/stderr
  61. // - `logger` is the service log utility that may be attached to a special place depending on OS (Windows will have it attached to the event log)
  62. // - above, in `Run` we create a `logrus.Logger` which is what nebula expects to use
  63. s, err := service.New(prg, svcConfig)
  64. if err != nil {
  65. log.Fatal(err)
  66. }
  67. errs := make(chan error, 5)
  68. logger, err = s.Logger(errs)
  69. if err != nil {
  70. log.Fatal(err)
  71. }
  72. go func() {
  73. for {
  74. err := <-errs
  75. if err != nil {
  76. // Route any errors from the system logger to stdout as a best effort to notice issues there
  77. log.Print(err)
  78. }
  79. }
  80. }()
  81. switch *serviceFlag {
  82. case "run":
  83. err = s.Run()
  84. if err != nil {
  85. // Route any errors to the system logger
  86. logger.Error(err)
  87. }
  88. default:
  89. err := service.Control(s, *serviceFlag)
  90. if err != nil {
  91. log.Printf("Valid actions: %q\n", service.ControlAction)
  92. log.Fatal(err)
  93. }
  94. return
  95. }
  96. }