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  }