Example #1
0
func main() {

	cli_app := cli.NewApp()
	cli_app.Name = AppName
	cli_app.Version = AppVersion

	app := &Application{
		App: cli_app,
	}

	cfg := config.GetDefaultConfig()

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "level, l",
			Value: "WARN",
			Usage: "change log level",
		},
	}

	app.Before = func(c *cli.Context) error {
		var err error

		cfgfile := filepath.Join(os.Getenv("HOME"), ".voyager")
		if util.FileExists(cfgfile) {
			err = cfg.LoadYaml(cfgfile)
			if err != nil {
				log.Errorf("load config %s: %s", cfgfile, err)
				return err
			}
		}
		app.Cfg = cfg
		gologging.SetLogLevel(c.String("level"))

		app.Ctx = context.Background()

		return nil
	}

	ping := cli.Command{
		Name:        "ping",
		Usage:       "ping rpc",
		Description: PingDescription,
		Flags:       PingFlags,
		Action:      app.Ping,
	}

	app.Commands = []cli.Command{
		ping,
	}
	app.Run(os.Args)

}
Example #2
0
func (app *Application) Setup(c *cli.Context) {
	log_level := c.String("log-level")
	verbose := c.Bool("verbose")
	service_dir := c.String("service-dir")
	active_dir := c.String("active-service-dir")
	log_dir := c.String("log-dir")
	enable := c.Bool("enable")
	disable := c.Bool("disable")
	run := c.String("run")
	log_run := c.String("log-run")

	script := c.StringSlice("script")
	restart := c.Bool("restart")
	uid := c.Int("uid")
	gid := c.Int("gid")

	args := c.Args()
	name := args.First()

	if verbose {
		gologging.SetLogLevel("trace")
	}
	if log_level != "" {
		gologging.SetLogLevel(log_level)
	}

	// template does nothing

	// make the runit api locally for these flags to function
	rcfg := runit.DefaultRunitConfig()
	if service_dir != "" {
		rcfg.ServiceDir = service_dir
	}
	if active_dir != "" {
		rcfg.ActiveDir = active_dir
	}
	rapi := runit.NewRunit(rcfg)

	if name == "" {
		log.Errorf("service name is required")
		return
	}
	if run == "" {
		log.Errorf("run command is required")
		return
	}

	if log_run != "" {
		log.Warnf("specifying log-run is not supported, argument is ignored")
	}

	log.Tracef("setup %s", name)

	lcfg := runit.DefaultLoggingConfig()
	if log_dir == "" {
		lcfg.Directory = filepath.Join(runit.DefaultLogDir, name)
	} else {
		lcfg.Directory = log_dir
	}

	var exec string
	if uid != 0 || gid != 0 {
		exec = fmt.Sprintf("chpst -u %d:%d %s", uid, gid, run)
	} else {
		exec = run
	}

	if enable {
		disable = false
	}

	// log_run is not supported

	cfg := &runit.ServiceConfig{
		Name:           name,
		Exec:           exec,
		Logging:        lcfg,
		Disabled:       disable,
		Activated:      true,
		RedirectStderr: true,
	}

	copts := &runit.CreateOptions{
		Force:   true,
		Restart: restart,
		Script:  script,
	}

	err := rapi.Create2(cfg, copts)
	if err != nil {
		log.Warnf("Create2 %s: %s", name, err)
	}

}
Example #3
0
func main() {
	c := cli.NewApp()
	c.Name = "runitcmd"
	c.Version = "0.0.1"
	c.Usage = "manage runit services"
	app := &Application{
		App: c,
	}

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "config, c",
			Usage: "override configuration file",
		},
		cli.StringFlag{
			Name:  "level, l",
			Value: "WARN",
			Usage: "change log level",
		},
		cli.StringFlag{
			Name:  "service-dir",
			Usage: "change service dir",
		},
		cli.StringFlag{
			Name:  "active-dir",
			Usage: "change active service dir",
		},
	}

	app.Before = func(c *cli.Context) error {
		gologging.SetLogLevel(c.String("level"))

		config_file := c.String("config")
		config_files := []string{
			"/etc/runitcmd.yaml",
		}

		user_config := filepath.Join(os.Getenv("HOME"), ".runitcmd.yaml")
		if config_file == "" {
			config_files = append(config_files, user_config)
		} else {
			config_files = []string{config_file}
		}

		app.Conf = GetDefaultConfig()
		for _, config_file := range config_files {
			_, err := os.Stat(config_file)
			if err != nil && os.IsNotExist(err) {
				continue
			}

			log.Tracef("Loading %s", config_file)
			err = app.Conf.LoadYaml(config_file)
			if err != nil {
				log.Warnf("load %s: %s", config_file, err)
			}
		}

		if app.Conf.Sudo {
			current_user, err := user.Current()
			if err == nil && current_user.Uid != "0" {
				log.Tracef("sudo uid:%s", current_user.Uid)

				argv0, err := exec.LookPath(os.Args[0])
				if err != nil {
					return err
				}

				sudo, err := exec.LookPath("sudo")
				if err != nil {
					log.Errorf("no sudo: %s", err)
					os.Exit(1)
				}

				args := []string{}
				args = append(args, sudo)
				args = append(args, "--")
				args = append(args, os.Args...)
				args[2] = argv0

				log.Tracef("sudo:%s args:%s", sudo, args)
				if err := syscall.Exec(args[0], args, os.Environ()); err != nil {
					log.Errorf("exec: %s", err)
					os.Exit(1)
				}
				// never reached
				panic("what")
				os.Exit(0)

			}

		}

		rcfg := runit.DefaultRunitConfig()
		service_dir := c.String("service-dir")
		active_dir := c.String("active-dir")
		if service_dir == "" {
			rcfg.ServiceDir = app.Conf.ServiceDir
		} else {
			rcfg.ServiceDir = service_dir
		}
		if active_dir == "" {
			rcfg.ActiveDir = app.Conf.ActiveDir
		} else {
			rcfg.ActiveDir = active_dir
		}

		app.Runit = runit.NewRunit(rcfg)

		return nil
	}

	app.Commands = []cli.Command{
		initList(app),
		initCreate(app),
		initSetup(app),
		initApply(app),
		initStatus(app),
		initImport(app),
		initExport(app),

		// more commands
		makeCommand("delete", app.Delete),
		makeCommand("activate", app.Activate),
		makeCommand("deactivate", app.Deactivate),
		makeCommand("enable", app.Enable),
		makeCommand("disable", app.Disable),
		makeCommand("reset", app.Reset),

		// commands
		makeCommand("up", app.Up),
		makeCommand("down", app.Down),
		makeCommand("pause", app.Pause),
		makeCommand("cont", app.Cont),
		makeCommand("hup", app.Cont),
		makeCommand("alarm", app.Cont),
		makeCommand("interrupt", app.Cont),
		makeCommand("quit", app.Quit),
		makeCommand("usr1", app.Usr1),
		makeCommand("usr2", app.Usr2),
		makeCommand("term", app.Term),
		makeCommand("kill", app.Kill),

		// lsb
		makeCommand("start", app.Start),
		makeCommand("stop", app.Stop),
		makeCommand("reload", app.Reload),
		makeCommand("restart", app.Restart),
		makeCommand("shutdown", app.Shutdown),
	}

	app.Run(os.Args)
}
Example #4
0
func main() {
	cfg := config.GetDefaultConfig()
	flag.StringVar(&cfg.Http.BindAddr, "bind", cfg.Http.BindAddr, "bind address")
	flag.StringVar(&cfg.LogLevel, "log", cfg.LogLevel, "log level")
	flag.Parse()

	var err error

	cfgfile := filepath.Join(os.Getenv("HOME"), ".voyager")
	if util.FileExists(cfgfile) {
		err = cfg.LoadYaml(cfgfile)
		if err != nil {
			log.Errorf("load config %s: %s", cfgfile, err)
			return
		}
	}

	if cfg.LogLevel != "" {
		gologging.SetLogLevel(cfg.LogLevel)
	}
	gologging.SetLogLevels(cfg.LogLevels)

	if log.IsTrace() {
		cfg.PrintYaml()
	}

	if cfg.AutoRestart {
		devrestarter.Init()
	}

	if util.FileExists(cfg.CacheDir) == false {
		err = os.MkdirAll(cfg.CacheDir, 0755)
		if err != nil {
			log.Errorf("cache dir error %s: %s", cfg.CacheDir, err)
			return
		}
	}

	if cfg.AutoUpgrade {
		gw := reload_git.NewGitWatch(".", "master")
		gw.Interval = 30
		gw.OnChange = func(dir, branch, lhash, rhash string) error {
			err = Shell("git", "pull")
			if err != nil {
				log.Warnf("git pull error: %s", err)
			}

			err = Shell("go", "install", "-v", "./...")
			if err != nil {
				log.Warnf("go install error: %s", err)
			}
			return err
		}

		err := gw.Start()
		if err != nil {
			log.Errorf("starting git watch %s", err)
			return
		}
	}

	cache := cache.NewFileCache(cfg.CacheDir)
	if err != nil {
		log.Errorf("cache error: %s %s", cfg.CacheDir, err)
		return
	}

	// core components
	handlerFactory := handler.NewHandlerFactory()
	pathLoader := handler.NewFilesystemPathLoader()

	layoutResolver := layout.NewLayoutResolver()

	voyLoader := voy.NewVoyLoader()

	root_template := template.New("root")
	template.Must(root_template.New("footer").Parse(footerTemplate))

	md := metadata.Pairs("request-secret", cfg.Rpc.Secret)
	ctx := context.Background()
	ctx = metadata.NewContext(ctx, md)

	// the HTTP server
	log.Infof("starting HTTP server at %s", cfg.Http.BindAddr)
	opts := &http_api.Options{
		Networks: cfg.ACL,
	}
	srv := http_api.NewServer(cfg.Http.BindAddr, opts)
	srv.Conf = cfg
	srv.Cache = cache
	srv.Factory = handlerFactory
	srv.PathLoader = pathLoader
	srv.Layout = layoutResolver
	srv.VoyFile = voyLoader
	srv.Ctx = ctx
	srv.Template = root_template
	srv.Dashboard = handler.NewDashboardHandler()
	srv.Dashboard.Ctx = ctx
	srv.Dashboard.VoyFile = voyLoader
	srv.Dashboard.Username = cfg.Username

	go func() {
		err = srv.Start()
		if err != nil {
			log.Errorf("starting server %s", err)
			return
		}
	}()

	// the RPC server
	log.Infof("starting RPC server at %s", cfg.Rpc.BindAddr)
	lis, err := net.Listen("tcp", cfg.Rpc.BindAddr)
	if err != nil {
		util.ExitIfError(err, "grpc listen %s: %s", cfg.Rpc.BindAddr, err)
	}
	http2_serv := grpc.NewServer()
	http2_api := api.MakeApi(cfg)
	http2_api.WithHandlerFactory(handlerFactory)

	http2_api.PathLoader = pathLoader
	http2_api.Layout = layoutResolver
	http2_api.VoyFile = voyLoader
	http2_api.ServerName = cfg.ServerName

	vapi.RegisterVApiServer(http2_serv, http2_api)

	log.Infof("finished initializing")

	log.Infof("%s", cfg.StartupBanner)

	err = http2_serv.Serve(lis)
	if err != nil {
		util.ExitIfError(err, "grpc serve %s: %s", cfg.Rpc.BindAddr, err)
	}

}