blob: 800e13994451e9883aed43c230cee044bff9fc82 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// The following enables go generate to generate the doc.go file.
//go:generate go run $JIRI_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
package main
import (
"database/sql"
"fmt"
"net"
"net/http"
"os"
"strings"
_ "github.com/mattn/go-sqlite3"
"v.io/v23"
"v.io/v23/context"
"v.io/x/lib/cmdline"
"v.io/x/lib/dbutil"
"v.io/x/ref/lib/signals"
"v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/roaming"
"v.io/x/ref/services/ben/benarchd/internal"
)
var (
flagStore string
flagHTTPAddr string
flagPublicHTTPAddr string
flagName string
flagAssets string
cmdRoot = &cmdline.Command{
Runner: v23cmd.RunnerFunc(run),
Name: "benarchd",
Short: "Runs the daemon that archives benchmark results",
Long: `
Command benarchd implements a benchmark archival daemon.
It provides a Vanadium RPC service to accept results to archive (typically
provided by the benup tool - https://godoc.org/v.io/x/ref/services/ben/benup)
and a web-interface to browse the results.
A SQL database is used for persistent storage, configured via the --store
flag.
`,
}
)
func run(ctx *context.T, env *cmdline.Env, args []string) error {
// Initialize assets to be used by the web interface
assets, err := internal.NewAssets(flagAssets)
if err != nil {
return err
}
// Initialize the store
driver, dataSource, err := parseStore(ctx, flagStore)
if err != nil {
return err
}
var db *sql.DB
switch driver {
case "sqlconfig":
// I'll admit, I have no clude of SERIALIZABLE is the right choice.
db, err = dbutil.NewSqlDBConnFromFile(dataSource, "SERIALIZABLE")
default:
db, err = sql.Open(driver, dataSource)
}
if err != nil {
return err
}
defer db.Close()
store, err := internal.NewSQLStore(driver, db)
if err != nil {
return err
}
// Start the HTTP service
ln, err := net.Listen("tcp", flagHTTPAddr)
if err != nil {
return err
}
ctx.Infof("HTTP server at http://%v", ln.Addr())
go http.Serve(ln, internal.NewHTTPHandler(assets, store))
// Start the v23 RPC service
pubAddr := fmt.Sprintf("http://%v", ln.Addr())
if flagPublicHTTPAddr != "" {
pubAddr = flagPublicHTTPAddr
}
_, v23server, err := v23.WithNewServer(ctx, flagName, internal.NewArchiver(store, pubAddr+"/?q="), internal.Authorizer())
if err != nil {
return err
}
if eps := v23server.Status().Endpoints; len(eps) > 0 {
ctx.Infof("v23 server at %v", eps[0].Name())
}
<-signals.ShutdownOnSignals(ctx)
return nil
}
func parseStore(ctx *context.T, spec string) (driver, dataSource string, err error) {
if len(spec) == 0 {
spec = fmt.Sprintf("sqlite3:%v/benarchd.db", os.TempDir())
ctx.Infof("No --store specified, using %q", spec)
}
pos := strings.Index(spec, ":")
if pos < 0 {
return "", "", fmt.Errorf("invalid --store, must be in the format <engine>:<parameters>")
}
return spec[:pos], spec[pos+1:], nil
}
func main() {
cmdline.HideGlobalFlagsExcept()
cmdRoot.Flags.StringVar(&flagName, "name", "", "Vanadium object name to export this service under")
cmdRoot.Flags.StringVar(&flagStore, "store", "", "Specification of the persistent store to use. Format: <engine>:<parameters>, where <engine> can be 'sqlite3', 'mysql' or 'sqlconfig'. For 'sqlconfig', <parameters> is a path to a file containing a JSON-serialized SqlConfig (https://godoc.org/v.io/x/lib/dbutil#SqlConfig), for the others it is the data source name (e.g., filename for sqlite3)")
cmdRoot.Flags.StringVar(&flagPublicHTTPAddr, "exthttp", "", "The address of the HTTP server to advertise externally, typically used if the HTTP server is running behind a proxy or on a machine that is unaware of its publicly accessible hostname/IP address. If empty, derived from --http.")
cmdRoot.Flags.StringVar(&flagHTTPAddr, "http", "127.0.0.1:0", "Address on which to serve HTTP requests")
cmdRoot.Flags.StringVar(&flagAssets, "assets", "", "If set, the directory containing assets (template definitions, css, javascript files etc.) to use in the web interface. If not set, compiled-in assets will be used instead.")
cmdline.Main(cmdRoot)
}