github.com/emc-advanced-dev/unik@v0.0.0-20190717152701-a58d3e8e33b7/cmd/daemon.go (about) 1 package cmd 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 9 "github.com/sirupsen/logrus" 10 "github.com/spf13/cobra" 11 "gopkg.in/yaml.v2" 12 13 "net/url" 14 15 "github.com/emc-advanced-dev/pkg/errors" 16 "github.com/solo-io/unik/pkg/config" 17 "github.com/solo-io/unik/pkg/daemon" 18 unikutil "github.com/solo-io/unik/pkg/util" 19 ) 20 21 var daemonRuntimeFolder, daemonConfigFile, logFile string 22 var debugMode, trace bool 23 24 var daemonCmd = &cobra.Command{ 25 Use: "daemon", 26 Short: "Runs the unik backend (daemon)", 27 Long: `Run this command to start the unik daemon process. 28 This should normally be left running as a long-running background process. 29 The daemon requires that docker is installed and running on the your system. 30 Necessary docker containers must be built for the daemon to work properly; 31 Run 'make' in the unik root directory to build all necessary containers. 32 33 Daemon also requires a configuration file with credentials and configuration info 34 for desired providers. 35 36 Example usage: 37 unik daemon --f ./my-config.yaml --port 12345 --debug --trace --logfile logs.txt 38 39 # will start the daemon using config file at my-config.yaml 40 # running on port 12345 41 # debug mode activated 42 # trace mode activated 43 # outputting logs to logs.txt 44 `, 45 Run: func(cmd *cobra.Command, args []string) { 46 if err := func() error { 47 48 // set unik home 49 config.Internal.UnikHome = daemonRuntimeFolder 50 51 if daemonConfigFile == "" { 52 daemonConfigFile = filepath.Join(config.Internal.UnikHome, "daemon-config.yaml") 53 } 54 55 if err := readDaemonConfig(); err != nil { 56 return err 57 } 58 59 //don't print vsphere password 60 redactions := []string{} 61 for _, vsphereConfig := range daemonConfig.Providers.Vsphere { 62 redactions = append(redactions, vsphereConfig.VspherePassword, url.QueryEscape(vsphereConfig.VspherePassword)) 63 } 64 logrus.SetFormatter(&unikutil.RedactedTextFormatter{ 65 Redactions: redactions, 66 }) 67 68 if debugMode { 69 logrus.SetLevel(logrus.DebugLevel) 70 } 71 if trace { 72 logrus.AddHook(&unikutil.AddTraceHook{true}) 73 } 74 if logFile != "" { 75 os.Create(logFile) 76 f, err := os.OpenFile(logFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777) 77 if err != nil { 78 return errors.New(fmt.Sprintf("failed to open log file %s for writing", logFile), err) 79 } 80 logrus.AddHook(&unikutil.TeeHook{f}) 81 } 82 83 logrus.WithField("config", daemonConfig).Info("daemon started") 84 d, err := daemon.NewUnikDaemon(daemonConfig) 85 if err != nil { 86 return errors.New("daemon failed to initialize", err) 87 } 88 d.Run(port) 89 return nil 90 }(); err != nil { 91 logrus.Errorf("running daemon failed: %v", err) 92 os.Exit(-1) 93 } 94 }, 95 } 96 97 func init() { 98 RootCmd.AddCommand(daemonCmd) 99 daemonCmd.Flags().StringVar(&daemonRuntimeFolder, "d", getHomeDir()+"/.unik/", "daemon runtime folder - where state is stored. (default is $HOME/.unik/)") 100 daemonCmd.Flags().StringVar(&daemonConfigFile, "f", "", "daemon config file (default is {RuntimeFolder}/daemon-config.yaml)") 101 daemonCmd.Flags().IntVar(&port, "port", 3000, "<int, optional> listening port for daemon") 102 daemonCmd.Flags().BoolVar(&debugMode, "debug", false, "<bool, optional> more verbose logging for the daemon") 103 daemonCmd.Flags().BoolVar(&trace, "trace", false, "<bool, optional> add stack trace to daemon logs") 104 daemonCmd.Flags().StringVar(&logFile, "logfile", "", "<string, optional> output logs to file (in addition to stdout)") 105 } 106 107 var daemonConfig config.DaemonConfig 108 109 func readDaemonConfig() error { 110 data, err := ioutil.ReadFile(daemonConfigFile) 111 if err != nil { 112 errMsg := fmt.Sprintf("failed to read daemon configuration file at " + daemonConfigFile + `\n 113 See documentation at http://github.com/emc-advanced-dev/unik for creating daemon config.'`) 114 return errors.New(errMsg, err) 115 } 116 if err := yaml.Unmarshal(data, &daemonConfig); err != nil { 117 errMsg := fmt.Sprintf("failed to parse daemon configuration yaml at " + daemonConfigFile + `\n 118 Please ensure config file contains valid yaml.'`) 119 return errors.New(errMsg, err) 120 } 121 return nil 122 }