github.com/vlifesystems/rulehunter@v0.0.0-20180501090014-673078aa4a83/cmd/cmd.go (about) 1 // Copyright (C) 2016-2018 vLife Systems Ltd <http://vlifesystems.com> 2 // Licensed under an MIT licence. Please see LICENSE.md for details. 3 4 package cmd 5 6 import ( 7 "fmt" 8 "os" 9 "path/filepath" 10 "time" 11 12 "github.com/kardianos/service" 13 "github.com/vlifesystems/rulehunter/config" 14 "github.com/vlifesystems/rulehunter/html" 15 "github.com/vlifesystems/rulehunter/logger" 16 "github.com/vlifesystems/rulehunter/program" 17 "github.com/vlifesystems/rulehunter/progress" 18 "github.com/vlifesystems/rulehunter/quitter" 19 ) 20 21 type Setup struct { 22 prg *program.Program 23 svc service.Service 24 cfg *config.Config 25 } 26 27 func InitSetup( 28 l logger.Logger, 29 q *quitter.Quitter, 30 configFilename string, 31 ) (*Setup, error) { 32 config, err := config.Load(configFilename) 33 if err != nil { 34 return nil, errConfigLoad{filename: configFilename, err: err} 35 } 36 37 if err := buildConfigDirs(config); err != nil { 38 return nil, err 39 } 40 41 pm, err := progress.NewMonitor( 42 filepath.Join(config.BuildDir, "progress"), 43 ) 44 if err != nil { 45 return nil, err 46 } 47 prg := program.New(config, pm, l, q) 48 49 s, err := newService(prg, flagUser, configFilename) 50 if err != nil { 51 return nil, err 52 } 53 svcLogger, err := s.Logger(nil) 54 if err != nil { 55 return nil, err 56 } 57 58 l.SetSvcLogger(svcLogger) 59 h := html.New(config, pm, l) 60 go l.Run(q) 61 go h.Run(q) 62 63 for i := 0; i < 10; i++ { 64 // This helps to ensure that quitter is properly established 65 // in goroutine before returning and being able to call Quit on quitter 66 if l.Running() && h.Running() { 67 break 68 } 69 time.Sleep(10 * time.Millisecond) 70 } 71 return &Setup{ 72 prg: prg, 73 svc: s, 74 cfg: config, 75 }, nil 76 } 77 78 func newService( 79 prg *program.Program, 80 user string, 81 configFilename string, 82 ) (service.Service, error) { 83 svcConfig := &service.Config{ 84 Name: "rulehunter", 85 DisplayName: "Rulehunter server", 86 Description: "Rulehunter finds rules in data based on user defined goals.", 87 } 88 89 if user != "" { 90 svcConfig.UserName = user 91 } 92 93 if len(os.Args) >= 2 && os.Args[1] == "service" { 94 svcConfig.Arguments = []string{ 95 "serve", 96 fmt.Sprintf("--config=%s", configFilename), 97 } 98 } else { 99 svcConfig.Arguments = os.Args[1:] 100 } 101 return service.New(prg, svcConfig) 102 } 103 104 func buildConfigDirs(cfg *config.Config) error { 105 // File mode permission: 106 // No special permission bits 107 // User: Read, Write Execute 108 // Group: None 109 // Other: None 110 const modePerm = 0700 111 112 dirs := []string{ 113 filepath.Join(cfg.WWWDir, "reports"), 114 filepath.Join(cfg.WWWDir, "progress"), 115 filepath.Join(cfg.BuildDir, "progress"), 116 filepath.Join(cfg.BuildDir, "reports"), 117 } 118 for _, dir := range dirs { 119 if err := os.MkdirAll(dir, modePerm); err != nil { 120 return err 121 } 122 } 123 124 return nil 125 }