Merge "mocknet: fix a race in V23CloseAtMessage"
diff --git a/cmd/principal/main.go b/cmd/principal/main.go
index f2a3de6..b604464 100644
--- a/cmd/principal/main.go
+++ b/cmd/principal/main.go
@@ -91,10 +91,19 @@
Runner: v23cmd.RunnerFunc(func(ctx *context.T, env *cmdline.Env, args []string) error {
p := v23.GetPrincipal(ctx)
if flagDumpShort {
- fmt.Printf("%v\n", p.BlessingStore().Default())
+ fmt.Printf("%s\n", printAnnotatedBlessingsNames(p.BlessingStore().Default()))
return nil
}
fmt.Printf("Public key : %v\n", p.PublicKey())
+ // NOTE(caprita): We print the default blessings name
+ // twice (it's also printed as part of the blessing
+ // store below) -- the reason we print it here is to
+ // expose whether the blessings are expired. Ideally,
+ // the blessings store would print the expiry
+ // information about each blessing in the store, but
+ // that would require deeper changes beyond the
+ // principal tool.
+ fmt.Printf("Default Blessings : %s\n", printAnnotatedBlessingsNames(p.BlessingStore().Default()))
fmt.Println("---------------- BlessingStore ----------------")
fmt.Printf("%v", p.BlessingStore().DebugString())
fmt.Println("---------------- BlessingRoots ----------------")
@@ -127,12 +136,7 @@
if err != nil {
return fmt.Errorf("failed to decode certificate chains: %v", err)
}
- // If the Blessings are expired, print a message saying so.
- expiredMessage := ""
- if exp := blessings.Expiry(); !exp.IsZero() && exp.Before(time.Now()) {
- expiredMessage = " [EXPIRED]"
- }
- fmt.Printf("Blessings : %v%s\n", blessings, expiredMessage)
+ fmt.Printf("Blessings : %s\n", printAnnotatedBlessingsNames(blessings))
fmt.Printf("PublicKey : %v\n", blessings.PublicKey())
fmt.Printf("Certificate chains : %d\n", len(wire.CertificateChains))
for idx, chain := range wire.CertificateChains {
@@ -787,6 +791,15 @@
}
)
+func printAnnotatedBlessingsNames(b security.Blessings) string {
+ // If the Blessings are expired, print a message saying so.
+ expiredMessage := ""
+ if exp := b.Expiry(); !exp.IsZero() && exp.Before(time.Now()) {
+ expiredMessage = " [EXPIRED]"
+ }
+ return fmt.Sprintf("%v%s", b, expiredMessage)
+}
+
func blessArgs(args []string) (tobless, extension, remoteKey, remoteToken string, err error) {
if len(flagRemoteArgFile) > 0 && (len(flagBlessRemoteKey)+len(flagBlessRemoteToken) > 0) {
return "", "", "", "", fmt.Errorf("--remote-key and --remote-token cannot be provided with --remote-arg-file")
diff --git a/cmd/principal/principal_v23_test.go b/cmd/principal/principal_v23_test.go
index 734b4d1..9e80947 100644
--- a/cmd/principal/principal_v23_test.go
+++ b/cmd/principal/principal_v23_test.go
@@ -128,9 +128,10 @@
func V23TestDump(t *v23tests.T) {
var (
- outputDir = t.NewTempDir("")
- bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
- aliceDir = filepath.Join(outputDir, "alice")
+ outputDir = t.NewTempDir("")
+ bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
+ aliceDir = filepath.Join(outputDir, "alice")
+ aliceExpiredDir = filepath.Join(outputDir, "alice-expired")
)
bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
@@ -138,6 +139,7 @@
blessEnv := credEnv(aliceDir)
got := removePublicKeys(bin.WithEnv(blessEnv).Start("dump").Output())
want := `Public key : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
+Default Blessings : alice
---------------- BlessingStore ----------------
Default Blessings alice
Peer pattern Blessings
@@ -149,6 +151,35 @@
if want != got {
t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
}
+
+ got = bin.WithEnv(blessEnv).Start("dump", "-s").Output()
+ want = "alice\n"
+ if want != got {
+ t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
+ }
+
+ bin.Start("--v23.credentials="+aliceDir, "fork", "--for", "-1h", aliceExpiredDir, "expired").WaitOrDie(os.Stdout, os.Stderr)
+ blessEnv = credEnv(aliceExpiredDir)
+ got = removePublicKeys(bin.WithEnv(blessEnv).Start("dump").Output())
+ want = `Public key : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
+Default Blessings : alice/expired [EXPIRED]
+---------------- BlessingStore ----------------
+Default Blessings alice/expired
+Peer pattern Blessings
+... alice/expired
+---------------- BlessingRoots ----------------
+Public key Pattern
+XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX [alice]
+`
+ if want != got {
+ t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
+ }
+
+ got = bin.WithEnv(blessEnv).Start("dump", "-s").Output()
+ want = "alice/expired [EXPIRED]\n"
+ if want != got {
+ t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
+ }
}
func V23TestGetRecognizedRoots(t *v23tests.T) {
@@ -286,6 +317,7 @@
// first "bless" command. (alice/friend/carol).
got := removePublicKeys(bin.Start("--v23.credentials="+carolDir, "dump").Output())
want := `Public key : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
+Default Blessings : alice/friend/carol
---------------- BlessingStore ----------------
Default Blessings alice/friend/carol
Peer pattern Blessings
@@ -324,6 +356,7 @@
{
got := removePublicKeys(bin.Start("--v23.credentials="+alicePhoneDir, "dump").Output())
want := `Public key : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
+Default Blessings : alice/phone
---------------- BlessingStore ----------------
Default Blessings alice/phone
Peer pattern Blessings
@@ -359,6 +392,7 @@
{
got := removePublicKeys(bin.Start("--v23.credentials="+alicePhoneCalendarDir, "dump").Output())
want := `Public key : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
+Default Blessings : alice/phone/calendar
---------------- BlessingStore ----------------
Default Blessings alice/phone/calendar
Peer pattern Blessings
diff --git a/cmd/servicerunner/doc.go b/cmd/servicerunner/doc.go
new file mode 100644
index 0000000..939f99d
--- /dev/null
+++ b/cmd/servicerunner/doc.go
@@ -0,0 +1,74 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+// +build wspr
+
+/*
+Command servicerunner runs several Vanadium services, including the mounttable,
+proxy and wspr. It prints a JSON map with their vars to stdout (as a single
+line), then waits forever.
+
+Usage:
+ servicerunner [flags]
+
+The servicerunner flags are:
+ -identd=
+ Name of wspr identd server.
+ -port=8124
+ Port for wspr to listen on.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -external-http-addr=
+ External address on which the HTTP server listens on. If none is provided the
+ server will only listen on -http-addr.
+ -http-addr=localhost:0
+ Address on which the HTTP server listens on.
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -tls-config=
+ Comma-separated list of TLS certificate and private key files. This must be
+ provided.
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/cmd/servicerunner/main.go b/cmd/servicerunner/main.go
index d08ae2b..aa944cc 100644
--- a/cmd/servicerunner/main.go
+++ b/cmd/servicerunner/main.go
@@ -5,10 +5,13 @@
// +build wspr
//
// We restrict to a special build-tag since it's required by wsprlib.
+//
+// Manually run the following to generate the doc.go file. This isn't a
+// go:generate comment, since generate also needs to be run with -tags=wspr,
+// which is troublesome for presubmit tests.
+//
+// cd $V23_ROOT/release/go/src && go run v.io/x/lib/cmdline/testdata/gendoc.go -tags=wspr v.io/x/ref/cmd/servicerunner -help
-// Command servicerunner runs several Vanadium services, including the
-// mounttable, proxy and wspr. It prints a JSON map with their vars to stdout
-// (as a single line), then waits forever.
package main
import (
@@ -23,24 +26,46 @@
"v.io/v23/options"
"v.io/v23/rpc"
"v.io/v23/security"
-
+ "v.io/x/lib/cmdline"
"v.io/x/ref/envvar"
"v.io/x/ref/lib/signals"
"v.io/x/ref/runtime/factories/generic"
"v.io/x/ref/services/identity/identitylib"
"v.io/x/ref/services/mounttable/mounttablelib"
+ "v.io/x/ref/services/wspr/wsprlib"
"v.io/x/ref/test/expect"
"v.io/x/ref/test/modules"
)
-func panicOnError(err error) {
- if err != nil {
- panic(err)
- }
-}
+var (
+ port int
+ identd string
+)
func init() {
+ wsprlib.OverrideCaveatValidation()
+ cmdServiceRunner.Flags.IntVar(&port, "port", 8124, "Port for wspr to listen on.")
+ cmdServiceRunner.Flags.StringVar(&identd, "identd", "", "Name of wspr identd server.")
modules.RegisterChild("rootMT", ``, rootMT)
+ modules.RegisterChild(wsprdCommand, modules.Usage(&cmdServiceRunner.Flags), startWSPR)
+}
+
+const wsprdCommand = "wsprd"
+
+func main() {
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdServiceRunner)
+}
+
+var cmdServiceRunner = &cmdline.Command{
+ Runner: cmdline.RunnerFunc(run),
+ Name: "servicerunner",
+ Short: "Runs several services, including the mounttable, proxy and wspr.",
+ Long: `
+Command servicerunner runs several Vanadium services, including the mounttable,
+proxy and wspr. It prints a JSON map with their vars to stdout (as a single
+line), then waits forever.
+`,
}
func rootMT(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
@@ -101,17 +126,20 @@
return nil
}
-func main() {
+func run(env *cmdline.Env, args []string) error {
+ // The dispatch to modules children must occur after the call to cmdline.Main
+ // (which calls cmdline.Parse), so that servicerunner flags are registered on
+ // the global flag.CommandLine.
if modules.IsModulesChildProcess() {
- panicOnError(modules.Dispatch())
- return
+ return modules.Dispatch()
}
+ // We must wait until after we've dispatched to children before calling
+ // v23.Init, otherwise we'll end up initializing twice.
ctx, shutdown := v23.Init()
defer shutdown()
vars := map[string]string{}
-
sh, err := modules.NewShell(ctx, nil, false, nil)
if err != nil {
panic(fmt.Sprintf("modules.NewShell: %s", err))
@@ -119,8 +147,12 @@
defer sh.Cleanup(os.Stderr, os.Stderr)
h, err := sh.Start("rootMT", nil, "--v23.tcp.protocol=ws", "--v23.tcp.address=127.0.0.1:0")
- panicOnError(err)
- panicOnError(updateVars(h, vars, "MT_NAME"))
+ if err != nil {
+ return err
+ }
+ if err := updateVars(h, vars, "MT_NAME"); err != nil {
+ return err
+ }
// Set envvar.NamespacePrefix env var, consumed downstream.
sh.SetVar(envvar.NamespacePrefix, vars["MT_NAME"])
@@ -132,17 +164,46 @@
defer proxyShutdown()
vars["PROXY_NAME"] = proxyEndpoint.Name()
- h, err = sh.Start(WSPRDCommand, nil, "--v23.tcp.protocol=ws", "--v23.tcp.address=127.0.0.1:0", "--v23.proxy=test/proxy", "--identd=test/identd")
- panicOnError(err)
- panicOnError(updateVars(h, vars, "WSPR_ADDR"))
+ h, err = sh.Start(wsprdCommand, nil, "--v23.tcp.protocol=ws", "--v23.tcp.address=127.0.0.1:0", "--v23.proxy=test/proxy", "--identd=test/identd")
+ if err != nil {
+ return err
+ }
+ if err := updateVars(h, vars, "WSPR_ADDR"); err != nil {
+ return err
+ }
h, err = sh.Start(identitylib.TestIdentitydCommand, nil, "--v23.tcp.protocol=ws", "--v23.tcp.address=127.0.0.1:0", "--v23.proxy=test/proxy", "--http-addr=localhost:0")
- panicOnError(err)
- panicOnError(updateVars(h, vars, "TEST_IDENTITYD_NAME", "TEST_IDENTITYD_HTTP_ADDR"))
+ if err != nil {
+ return err
+ }
+ if err := updateVars(h, vars, "TEST_IDENTITYD_NAME", "TEST_IDENTITYD_HTTP_ADDR"); err != nil {
+ return err
+ }
bytes, err := json.Marshal(vars)
- panicOnError(err)
+ if err != nil {
+ return err
+ }
fmt.Println(string(bytes))
<-signals.ShutdownOnSignals(ctx)
+ return nil
+}
+
+func startWSPR(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
+ ctx, shutdown := v23.Init()
+ defer shutdown()
+
+ l := v23.GetListenSpec(ctx)
+ proxy := wsprlib.NewWSPR(ctx, port, &l, identd, nil)
+ defer proxy.Shutdown()
+
+ addr := proxy.Listen()
+ go func() {
+ proxy.Serve()
+ }()
+
+ fmt.Fprintf(stdout, "WSPR_ADDR=%s\n", addr)
+ modules.WaitForEOF(stdin)
+ return nil
}
diff --git a/cmd/servicerunner/wspr.go b/cmd/servicerunner/wspr.go
deleted file mode 100644
index f8fd122..0000000
--- a/cmd/servicerunner/wspr.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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.
-
-// +build wspr
-//
-// We restrict to a special build-tag in order to enable
-// security.OverrideCaveatValidation, which isn't generally available.
-
-package main
-
-import (
- "flag"
- "fmt"
- "io"
-
- "v.io/v23"
-
- "v.io/x/ref/services/wspr/wsprlib"
- "v.io/x/ref/test/modules"
-)
-
-var (
- port *int = flag.CommandLine.Int("port", 0, "Port to listen on.")
- identd *string = flag.CommandLine.String("identd", "", "identd server name. Must be set.")
-)
-
-const WSPRDCommand = "wsprd"
-
-func init() {
- wsprlib.OverrideCaveatValidation()
- modules.RegisterChild(WSPRDCommand, modules.Usage(flag.CommandLine), startWSPR)
-}
-
-func startWSPR(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
- ctx, shutdown := v23.Init()
- defer shutdown()
-
- l := v23.GetListenSpec(ctx)
- proxy := wsprlib.NewWSPR(ctx, *port, &l, *identd, nil)
- defer proxy.Shutdown()
-
- addr := proxy.Listen()
- go func() {
- proxy.Serve()
- }()
-
- fmt.Fprintf(stdout, "WSPR_ADDR=%s\n", addr)
- modules.WaitForEOF(stdin)
- return nil
-}
diff --git a/examples/rps/rpsbot/doc.go b/examples/rps/rpsbot/doc.go
new file mode 100644
index 0000000..d30af8e
--- /dev/null
+++ b/examples/rps/rpsbot/doc.go
@@ -0,0 +1,71 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command rpsbot repeatedly runs automated games, implementing all three roles. It
+publishes itself as player, judge, and scorekeeper. Then, it initiates games
+with other players, in a loop. As soon as one game is over, it starts a new one.
+
+Usage:
+ rpsbot [flags]
+
+The rpsbot flags are:
+ -acl-file=
+ File containing JSON-encoded Permissions.
+ -name=
+ Identifier to publish as (defaults to user@hostname).
+ -num-games=-1
+ Number of games to play (-1 means unlimited).
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+ specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+ explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+ Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/examples/rps/rpsbot/main.go b/examples/rps/rpsbot/main.go
index 3206d9a..4fbcaab 100644
--- a/examples/rps/rpsbot/main.go
+++ b/examples/rps/rpsbot/main.go
@@ -2,42 +2,57 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Command rpsbot repeatedly runs automated games, implementing all three roles.
-// It publishes itself as player, judge, and scorekeeper. Then, it initiates
-// games with other players, in a loop. As soon as one game is over, it starts a
-// new one.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
- "flag"
"fmt"
"math/rand"
"time"
"v.io/v23"
"v.io/v23/context"
+ "v.io/x/lib/cmdline"
"v.io/x/lib/vlog"
"v.io/x/ref/examples/rps"
"v.io/x/ref/examples/rps/internal"
"v.io/x/ref/lib/signals"
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/roaming"
)
var (
- name = flag.String("name", "", "identifier to publish itself as (defaults to user@hostname)")
- numGames = flag.Int("num-games", -1, "number of games to play (-1 means unlimited)")
- permsFile = flag.String("acl-file", "", "file containing the JSON-encoded Permissions")
+ name, aclFile string
+ numGames int
)
func main() {
- ctx, shutdown := v23.Init()
- defer shutdown()
+ cmdRoot.Flags.StringVar(&name, "name", "", "Identifier to publish as (defaults to user@hostname).")
+ cmdRoot.Flags.StringVar(&aclFile, "acl-file", "", "File containing JSON-encoded Permissions.")
+ cmdRoot.Flags.IntVar(&numGames, "num-games", -1, "Number of games to play (-1 means unlimited).")
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdRoot)
+}
- auth := internal.NewAuthorizer(*permsFile)
+var cmdRoot = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runBot),
+ Name: "rpsbot",
+ Short: "repeatedly runs automated games",
+ Long: `
+Command rpsbot repeatedly runs automated games, implementing all three roles.
+It publishes itself as player, judge, and scorekeeper. Then, it initiates games
+with other players, in a loop. As soon as one game is over, it starts a new one.
+`,
+}
+
+func runBot(ctx *context.T, env *cmdline.Env, args []string) error {
+ auth := internal.NewAuthorizer(aclFile)
server, err := v23.NewServer(ctx)
if err != nil {
- vlog.Fatalf("NewServer failed: %v", err)
+ return fmt.Errorf("NewServer failed: %v", err)
}
rand.Seed(time.Now().UnixNano())
@@ -46,32 +61,33 @@
listenSpec := v23.GetListenSpec(ctx)
eps, err := server.Listen(listenSpec)
if err != nil {
- vlog.Fatalf("Listen(%v) failed: %v", listenSpec, err)
+ return fmt.Errorf("Listen(%v) failed: %v", listenSpec, err)
}
- if *name == "" {
- *name = internal.CreateName()
+ if name == "" {
+ name = internal.CreateName()
}
names := []string{
- fmt.Sprintf("rps/judge/%s", *name),
- fmt.Sprintf("rps/player/%s", *name),
- fmt.Sprintf("rps/scorekeeper/%s", *name),
+ fmt.Sprintf("rps/judge/%s", name),
+ fmt.Sprintf("rps/player/%s", name),
+ fmt.Sprintf("rps/scorekeeper/%s", name),
}
if err := server.Serve(names[0], rps.RockPaperScissorsServer(rpsService), auth); err != nil {
- vlog.Fatalf("Serve(%v) failed: %v", names[0], err)
+ return fmt.Errorf("Serve(%v) failed: %v", names[0], err)
}
for _, n := range names[1:] {
if err := server.AddName(n); err != nil {
- vlog.Fatalf("(%v) failed: %v", n, err)
+ return fmt.Errorf("(%v) failed: %v", n, err)
}
}
vlog.Infof("Listening on endpoint %s (published as %v)", eps, names)
go initiateGames(ctx, rpsService)
<-signals.ShutdownOnSignals(ctx)
+ return nil
}
func initiateGames(ctx *context.T, rpsService *RPS) {
- for i := 0; i < *numGames || *numGames == -1; i++ {
+ for i := 0; i < numGames || numGames == -1; i++ {
if err := rpsService.Player().InitiateGame(ctx); err != nil {
vlog.Infof("Failed to initiate game: %v", err)
}
diff --git a/examples/rps/rpsplayer/doc.go b/examples/rps/rpsplayer/doc.go
new file mode 100644
index 0000000..139c943
--- /dev/null
+++ b/examples/rps/rpsplayer/doc.go
@@ -0,0 +1,68 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command rpsplayer implements the Player interface, which enables a human to play
+the game.
+
+Usage:
+ rpsplayer [flags]
+
+The rpsplayer flags are:
+ -acl-file=
+ File containing JSON-encoded Permissions.
+ -name=
+ Identifier to publish as (defaults to user@hostname).
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+ specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+ explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+ Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/examples/rps/rpsplayer/main.go b/examples/rps/rpsplayer/main.go
index 456bd80..f24515b 100644
--- a/examples/rps/rpsplayer/main.go
+++ b/examples/rps/rpsplayer/main.go
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Command rpsplayer implements the Player interface, which enables a human to
-// play the game.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
"errors"
- "flag"
"fmt"
"sort"
"strings"
@@ -21,22 +21,35 @@
"v.io/v23/rpc"
"v.io/v23/security"
"v.io/v23/vtrace"
+ "v.io/x/lib/cmdline"
"v.io/x/lib/vlog"
"v.io/x/ref/examples/rps"
"v.io/x/ref/examples/rps/internal"
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/roaming"
)
-var (
- name = flag.String("name", "", "identifier to publish itself as (defaults to user@hostname)")
- permsFile = flag.String("acl-file", "", "file containing the JSON-encoded Permissions")
-)
+var name, aclFile string
func main() {
- rootctx, shutdown := v23.Init()
- defer shutdown()
+ cmdRoot.Flags.StringVar(&name, "name", "", "Identifier to publish as (defaults to user@hostname).")
+ cmdRoot.Flags.StringVar(&aclFile, "acl-file", "", "File containing JSON-encoded Permissions.")
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdRoot)
+}
+var cmdRoot = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runPlayer),
+ Name: "rpsplayer",
+ Short: "Implements the Player interface",
+ Long: `
+Command rpsplayer implements the Player interface, which enables a human to play
+the game.
+`,
+}
+
+func runPlayer(rootctx *context.T, env *cmdline.Env, args []string) error {
for {
ctx, _ := vtrace.WithNewTrace(rootctx)
if selectOne([]string{"Initiate Game", "Wait For Challenge"}) == 0 {
@@ -50,6 +63,7 @@
break
}
}
+ return nil
}
type gameChallenge struct {
@@ -119,10 +133,10 @@
if err != nil {
vlog.Fatalf("Listen(%v) failed: %v", listenSpec, err)
}
- if *name == "" {
- *name = internal.CreateName()
+ if name == "" {
+ name = internal.CreateName()
}
- if err := server.Serve(fmt.Sprintf("rps/player/%s", *name), rps.PlayerServer(&impl{ch: ch}), internal.NewAuthorizer(*permsFile)); err != nil {
+ if err := server.Serve(fmt.Sprintf("rps/player/%s", name), rps.PlayerServer(&impl{ch: ch}), internal.NewAuthorizer(aclFile)); err != nil {
vlog.Fatalf("Serve failed: %v", err)
}
vlog.Infof("Listening on endpoint /%s", ep)
diff --git a/examples/rps/rpsscorekeeper/doc.go b/examples/rps/rpsscorekeeper/doc.go
new file mode 100644
index 0000000..9a529f0
--- /dev/null
+++ b/examples/rps/rpsscorekeeper/doc.go
@@ -0,0 +1,67 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command rpsscorekeeper implements the ScoreKeeper interface. It publishes
+itself as a score keeper for the rock-paper-scissors game and prints out all the
+score cards it receives to stdout.
+
+Usage:
+ rpsscorekeeper [flags]
+
+The rpsscorekeeper flags are:
+ -acl-file=
+ File containing JSON-encoded Permissions.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+ specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+ explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+ Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/examples/rps/rpsscorekeeper/main.go b/examples/rps/rpsscorekeeper/main.go
index 8348a9d..3ec7224 100644
--- a/examples/rps/rpsscorekeeper/main.go
+++ b/examples/rps/rpsscorekeeper/main.go
@@ -2,13 +2,12 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Command rpsscorekeeper implements the ScoreKeeper interface. It publishes
-// itself as a score keeper for the rock-paper-scissors game and prints out all
-// the score cards it receives to stdout.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
- "flag"
"fmt"
"os"
@@ -16,16 +15,33 @@
"v.io/v23/context"
"v.io/v23/rpc"
"v.io/v23/security"
+ "v.io/x/lib/cmdline"
"v.io/x/lib/vlog"
"v.io/x/ref/examples/rps"
"v.io/x/ref/examples/rps/internal"
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/roaming"
)
-var (
- permsFile = flag.String("acl-file", "", "file containing the JSON-encoded Permissions")
-)
+var aclFile string
+
+func main() {
+ cmdRoot.Flags.StringVar(&aclFile, "acl-file", "", "File containing JSON-encoded Permissions.")
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdRoot)
+}
+
+var cmdRoot = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runScoreKeeper),
+ Name: "rpsscorekeeper",
+ Short: "Implements the ScoreKeeper interface",
+ Long: `
+Command rpsscorekeeper implements the ScoreKeeper interface. It publishes
+itself as a score keeper for the rock-paper-scissors game and prints out all the
+score cards it receives to stdout.
+`,
+}
type impl struct {
ch chan rps.ScoreCard
@@ -38,13 +54,10 @@
return nil
}
-func main() {
- ctx, shutdown := v23.Init()
- defer shutdown()
-
+func runScoreKeeper(ctx *context.T, env *cmdline.Env, args []string) error {
server, err := v23.NewServer(ctx)
if err != nil {
- vlog.Fatalf("NewServer failed: %v", err)
+ return fmt.Errorf("NewServer failed: %v", err)
}
defer server.Stop()
@@ -54,18 +67,19 @@
listenSpec := v23.GetListenSpec(ctx)
ep, err := server.Listen(listenSpec)
if err != nil {
- vlog.Fatalf("Listen(%v) failed: %v", listenSpec, err)
+ return fmt.Errorf("Listen(%v) failed: %v", listenSpec, err)
}
hostname, err := os.Hostname()
if err != nil {
- vlog.Fatalf("os.Hostname failed: %v", err)
+ return fmt.Errorf("os.Hostname failed: %v", err)
}
- if err := server.Serve(fmt.Sprintf("rps/scorekeeper/%s", hostname), rps.ScoreKeeperServer(rpsService), internal.NewAuthorizer(*permsFile)); err != nil {
- vlog.Fatalf("Serve failed: %v", err)
+ if err := server.Serve(fmt.Sprintf("rps/scorekeeper/%s", hostname), rps.ScoreKeeperServer(rpsService), internal.NewAuthorizer(aclFile)); err != nil {
+ return fmt.Errorf("Serve failed: %v", err)
}
vlog.Infof("Listening on endpoint /%s", ep)
for score := range ch {
fmt.Print("======================\n", internal.FormatScoreCard(score))
}
+ return nil
}
diff --git a/examples/tunnel/tunneld/doc.go b/examples/tunnel/tunneld/doc.go
new file mode 100644
index 0000000..d300fab
--- /dev/null
+++ b/examples/tunnel/tunneld/doc.go
@@ -0,0 +1,65 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command tunneld runs the tunneld daemon, which implements the Tunnel interface.
+
+Usage:
+ tunneld [flags]
+
+The tunneld flags are:
+ -name=
+ Name to publish the server as.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+ specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+ explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+ Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/examples/tunnel/tunneld/main.go b/examples/tunnel/tunneld/main.go
index 2b0900b..05a44c2 100644
--- a/examples/tunnel/tunneld/main.go
+++ b/examples/tunnel/tunneld/main.go
@@ -2,50 +2,65 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Daemon tunneld implements the Tunnel interface.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
- "flag"
"fmt"
"v.io/v23"
+ "v.io/v23/context"
+ "v.io/x/lib/cmdline"
"v.io/x/lib/vlog"
"v.io/x/ref/examples/tunnel"
"v.io/x/ref/lib/security/securityflag"
"v.io/x/ref/lib/signals"
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/roaming"
)
-var (
- name = flag.String("name", "", "name at which to publish the server")
-)
+var name string
func main() {
- ctx, shutdown := v23.Init()
- defer shutdown()
+ cmdRoot.Flags.StringVar(&name, "name", "", "Name to publish the server as.")
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdRoot)
+}
+var cmdRoot = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runTunnelD),
+ Name: "tunneld",
+ Short: "Runs the tunneld daemon",
+ Long: `
+Command tunneld runs the tunneld daemon, which implements the Tunnel interface.
+`,
+}
+
+func runTunnelD(ctx *context.T, env *cmdline.Env, args []string) error {
auth := securityflag.NewAuthorizerOrDie()
server, err := v23.NewServer(ctx)
if err != nil {
- vlog.Fatalf("NewServer failed: %v", err)
+ return fmt.Errorf("NewServer failed: %v", err)
}
defer server.Stop()
listenSpec := v23.GetListenSpec(ctx)
if _, err := server.Listen(listenSpec); err != nil {
- vlog.Fatalf("Listen(%v) failed: %v", listenSpec, err)
+ return fmt.Errorf("Listen(%v) failed: %v", listenSpec, err)
}
- if err := server.Serve(*name, tunnel.TunnelServer(&T{}), auth); err != nil {
- vlog.Fatalf("Serve(%v) failed: %v", *name, err)
+ if err := server.Serve(name, tunnel.TunnelServer(&T{}), auth); err != nil {
+ return fmt.Errorf("Serve(%v) failed: %v", name, err)
}
status := server.Status()
vlog.Infof("Listening on: %v", status.Endpoints)
if len(status.Endpoints) > 0 {
fmt.Printf("NAME=%s\n", status.Endpoints[0].Name())
}
- vlog.Infof("Published as %q", *name)
+ vlog.Infof("Published as %q", name)
<-signals.ShutdownOnSignals(ctx)
+ return nil
}
diff --git a/examples/tunnel/vsh/doc.go b/examples/tunnel/vsh/doc.go
new file mode 100644
index 0000000..84fbb9b
--- /dev/null
+++ b/examples/tunnel/vsh/doc.go
@@ -0,0 +1,95 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command vsh runs the Vanadium shell, a Tunnel client that can be used to run
+shell commands or start an interactive shell on a remote tunneld server.
+
+To open an interactive shell, use:
+ vsh <object name>
+
+To run a shell command, use:
+ vsh <object name> <command to run>
+
+The -L flag will forward connections from a local port to a remote address
+through the tunneld service. The flag value is localaddr,remoteaddr. E.g.
+ -L :14141,www.google.com:80
+
+vsh can't be used directly with tools like rsync because vanadium object names
+don't look like traditional hostnames, which rsync doesn't understand. For
+compatibility with such tools, vsh has a special feature that allows passing the
+vanadium object name via the VSH_NAME environment variable.
+
+ $ VSH_NAME=<object name> rsync -avh -e vsh /foo/* myhost:/foo/
+
+In this example, the "myhost" host will be substituted with $VSH_NAME by vsh and
+rsync will work as expected.
+
+Usage:
+ vsh [flags] <object name> [command]
+
+<object name> is the Vanadium object name to connect to.
+
+[command] is the shell command and args to run, for non-interactive vsh.
+
+The vsh flags are:
+ -L=
+ Forward local to remote, format is "localaddr,remoteaddr".
+ -N=false
+ Do not execute a shell. Only do port forwarding.
+ -T=false
+ Disable pseudo-terminal allocation.
+ -local_protocol=tcp
+ Local network protocol for port forwarding.
+ -remote_protocol=tcp
+ Remote network protocol for port forwarding.
+ -t=false
+ Force allocation of pseudo-terminal.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/examples/tunnel/vsh/main.go b/examples/tunnel/vsh/main.go
index 94ec21c..90cda41 100644
--- a/examples/tunnel/vsh/main.go
+++ b/examples/tunnel/vsh/main.go
@@ -2,113 +2,109 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Command vsh is a Tunnel client that can be used to start a shell on the
-// server.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
"errors"
- "flag"
"fmt"
"net"
"os"
- "path"
"strings"
- "v.io/v23"
"v.io/v23/context"
+ "v.io/x/lib/cmdline"
"v.io/x/lib/vlog"
"v.io/x/ref/examples/tunnel"
"v.io/x/ref/examples/tunnel/internal"
"v.io/x/ref/lib/signals"
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/generic"
)
var (
- disablePty = flag.Bool("T", false, "Disable pseudo-terminal allocation.")
- forcePty = flag.Bool("t", false, "Force allocation of pseudo-terminal.")
-
- portforward = flag.String("L", "", "localaddr,remoteaddr Forward local 'localaddr' to 'remoteaddr'")
- lprotocol = flag.String("local_protocol", "tcp", "Local network protocol for port forwarding")
- rprotocol = flag.String("remote_protocol", "tcp", "Remote network protocol for port forwarding")
-
- noshell = flag.Bool("N", false, "Do not execute a shell. Only do port forwarding.")
+ disablePty, forcePty, noshell bool
+ portforward, lprotocol, rprotocol string
)
-func init() {
- flag.Usage = func() {
- bname := path.Base(os.Args[0])
- fmt.Fprintf(os.Stderr, `%s: Vanadium Shell.
+func main() {
+ cmdVsh.Flags.BoolVar(&disablePty, "T", false, "Disable pseudo-terminal allocation.")
+ cmdVsh.Flags.BoolVar(&forcePty, "t", false, "Force allocation of pseudo-terminal.")
+ cmdVsh.Flags.BoolVar(&noshell, "N", false, "Do not execute a shell. Only do port forwarding.")
+ cmdVsh.Flags.StringVar(&portforward, "L", "", `Forward local to remote, format is "localaddr,remoteaddr".`)
+ cmdVsh.Flags.StringVar(&lprotocol, "local_protocol", "tcp", "Local network protocol for port forwarding.")
+ cmdVsh.Flags.StringVar(&rprotocol, "remote_protocol", "tcp", "Remote network protocol for port forwarding.")
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdVsh)
+}
-This tool is used to run shell commands or an interactive shell on a remote
-tunneld service.
+var cmdVsh = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runVsh),
+ Name: "vsh",
+ Short: "Vanadium shell",
+ Long: `
+Command vsh runs the Vanadium shell, a Tunnel client that can be used to run
+shell commands or start an interactive shell on a remote tunneld server.
To open an interactive shell, use:
- %s <object name>
+ vsh <object name>
To run a shell command, use:
- %s <object name> <command to run>
+ vsh <object name> <command to run>
The -L flag will forward connections from a local port to a remote address
through the tunneld service. The flag value is localaddr,remoteaddr. E.g.
-L :14141,www.google.com:80
-%s can't be used directly with tools like rsync because vanadium object names
+vsh can't be used directly with tools like rsync because vanadium object names
don't look like traditional hostnames, which rsync doesn't understand. For
-compatibility with such tools, %s has a special feature that allows passing the
+compatibility with such tools, vsh has a special feature that allows passing the
vanadium object name via the VSH_NAME environment variable.
- $ VSH_NAME=<object name> rsync -avh -e %s /foo/* v23:/foo/
+ $ VSH_NAME=<object name> rsync -avh -e vsh /foo/* myhost:/foo/
-In this example, the "v23" host will be substituted with $VSH_NAME by %s and
+In this example, the "myhost" host will be substituted with $VSH_NAME by vsh and
rsync will work as expected.
+`,
+ ArgsName: "<object name> [command]",
+ ArgsLong: `
+<object name> is the Vanadium object name to connect to.
-Full flags:
-`, os.Args[0], bname, bname, bname, bname, os.Args[0], bname)
- flag.PrintDefaults()
- }
+[command] is the shell command and args to run, for non-interactive vsh.
+`,
}
-func main() {
- // Work around the fact that os.Exit doesn't run deferred functions.
- os.Exit(realMain())
-}
-
-func realMain() int {
- ctx, shutdown := v23.Init()
- defer shutdown()
-
- oname, cmd, err := objectNameAndCommandLine()
+func runVsh(ctx *context.T, env *cmdline.Env, args []string) error {
+ oname, cmd, err := objectNameAndCommandLine(args)
if err != nil {
- flag.Usage()
- fmt.Fprintf(os.Stderr, "\n%v\n", err)
- return 1
+ return env.UsageErrorf("%v", err)
}
t := tunnel.TunnelClient(oname)
- if len(*portforward) > 0 {
+ if len(portforward) > 0 {
go runPortForwarding(ctx, t, oname)
}
- if *noshell {
+ if noshell {
<-signals.ShutdownOnSignals(ctx)
- return 0
+ return nil
}
opts := shellOptions(cmd)
stream, err := t.Shell(ctx, cmd, opts)
if err != nil {
- fmt.Fprintf(os.Stderr, "Error: %v\n", err)
- return 1
+ return err
}
if opts.UsePty {
saved := internal.EnterRawTerminalMode()
defer internal.RestoreTerminalSettings(saved)
}
- runIOManager(os.Stdin, os.Stdout, os.Stderr, stream)
+ runIOManager(env.Stdin, env.Stdout, env.Stderr, stream)
exitMsg := fmt.Sprintf("Connection to %s closed.", oname)
exitStatus, err := stream.Finish()
@@ -120,15 +116,15 @@
// Otherwise, the exit message might get confused with the output
// of the command that was run.
if err != nil {
- fmt.Fprintln(os.Stderr, exitMsg)
+ fmt.Fprintln(env.Stderr, exitMsg)
} else if len(cmd) == 0 {
fmt.Println(exitMsg)
}
- return int(exitStatus)
+ return cmdline.ErrExitCode(exitStatus)
}
func shellOptions(cmd string) (opts tunnel.ShellOpts) {
- opts.UsePty = (len(cmd) == 0 || *forcePty) && !*disablePty
+ opts.UsePty = (len(cmd) == 0 || forcePty) && !disablePty
opts.Environment = environment()
ws, err := internal.GetWindowSize()
if err != nil {
@@ -154,8 +150,7 @@
// send to the server. The object name is the first non-flag argument.
// The command line is the concatenation of all non-flag arguments excluding
// the object name.
-func objectNameAndCommandLine() (string, string, error) {
- args := flag.Args()
+func objectNameAndCommandLine(args []string) (string, string, error) {
if len(args) < 1 {
return "", "", errors.New("object name missing")
}
@@ -175,8 +170,8 @@
}
func runPortForwarding(ctx *context.T, t tunnel.TunnelClientMethods, oname string) {
- // *portforward is localaddr,remoteaddr
- parts := strings.Split(*portforward, ",")
+ // portforward is localaddr,remoteaddr
+ parts := strings.Split(portforward, ",")
var laddr, raddr string
if len(parts) != 2 {
vlog.Fatalf("-L flag expects 2 values separated by a comma")
@@ -184,9 +179,9 @@
laddr = parts[0]
raddr = parts[1]
- ln, err := net.Listen(*lprotocol, laddr)
+ ln, err := net.Listen(lprotocol, laddr)
if err != nil {
- vlog.Fatalf("net.Listen(%q, %q) failed: %v", *lprotocol, laddr, err)
+ vlog.Fatalf("net.Listen(%q, %q) failed: %v", lprotocol, laddr, err)
}
defer ln.Close()
vlog.VI(1).Infof("Listening on %q", ln.Addr())
@@ -196,9 +191,9 @@
vlog.Infof("Accept failed: %v", err)
continue
}
- stream, err := t.Forward(ctx, *rprotocol, raddr)
+ stream, err := t.Forward(ctx, rprotocol, raddr)
if err != nil {
- vlog.Infof("Tunnel(%q, %q) failed: %v", *rprotocol, raddr, err)
+ vlog.Infof("Tunnel(%q, %q) failed: %v", rprotocol, raddr, err)
conn.Close()
continue
}
diff --git a/lib/apilog/log.go b/lib/apilog/log.go
new file mode 100644
index 0000000..3eb4f92
--- /dev/null
+++ b/lib/apilog/log.go
@@ -0,0 +1,165 @@
+// 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.
+
+// Package apilog provides a function to be used in conjunction with vtrace
+// and logcop automatically injected logging calls. These are called on
+// entry/exit for methods that implements a v23 API call.
+package apilog
+
+import (
+ "fmt"
+ "path"
+ "reflect"
+ "runtime"
+ "sync/atomic"
+
+ "v.io/x/lib/vlog"
+
+ "v.io/v23/context"
+)
+
+// logCallLogLevel is the log level beyond which calls are logged.
+const logCallLogLevel = 1
+
+func callerFuncName() string {
+ var funcName string
+ const stackSkip = 1
+ pc, _, _, ok := runtime.Caller(stackSkip + 1)
+ if ok {
+ function := runtime.FuncForPC(pc)
+ if function != nil {
+ funcName = path.Base(function.Name())
+ }
+ }
+ return funcName
+}
+
+// TODO(cnicolaou): remove LogCall from vlog.
+
+// LogCall logs that its caller has been called given the arguments
+// passed to it. It returns a function that is supposed to be called
+// when the caller returns, logging the caller’s return along with the
+// arguments it is provided with.
+// File name and line number of the call site and a randomly generated
+// invocation identifier is logged automatically. The path through which
+// the caller function returns will be logged automatically too.
+//
+// The canonical way to use LogCall is along the lines of the following:
+//
+// func Function(ctx *context.T, a Type1, b Type2) ReturnType {
+// defer apilog.LogCall(ctx, a, b)(ctx)
+// // ... function body ...
+// return retVal
+// }
+//
+// To log the return value as the function returns, the following
+// pattern should be used. Note that pointers to the output
+// variables should be passed to the returning function, not the
+// variables themselves. Also note that nil can be used when a context.T
+// is not available:
+//
+// func Function(a Type1, b Type2) (r ReturnType) {
+// defer apilog.LogCall(nil, a, b)(nil, &r)
+// // ... function body ...
+// return computeReturnValue()
+// }
+//
+// Note that when using this pattern, you do not need to actually
+// assign anything to the named return variable explicitly. A regular
+// return statement would automatically do the proper return variable
+// assignments.
+//
+// The log injector tool will automatically insert a LogCall invocation
+// into all implementations of the public API it runs, unless a Valid
+// Log Construct is found. A Valid Log Construct is defined as one of
+// the following at the beginning of the function body (i.e. should not
+// be preceded by any non-whitespace or non-comment tokens):
+// 1. defer apilog.LogCall(optional arguments)(optional pointers to return values)
+// 2. defer apilog.LogCallf(argsFormat, optional arguments)(returnValuesFormat, optional pointers to return values)
+// 3. // nologcall
+//
+// The comment "// nologcall" serves as a hint to log injection and
+// checking tools to exclude the function from their consideration.
+// It is used as follows:
+//
+// func FunctionWithoutLogging(args ...interface{}) {
+// // nologcall
+// // ... function body ...
+// }
+//
+func LogCall(ctx *context.T, v ...interface{}) func(*context.T, ...interface{}) {
+ if !vlog.V(logCallLogLevel) { // TODO(mattr): add call to vtrace.
+ return func(*context.T, ...interface{}) {}
+ }
+ callerFuncName := callerFuncName()
+ invocationId := newInvocationIdentifier()
+ var output string
+ if len(v) > 0 {
+ output = fmt.Sprintf("call[%s %s]: args:%v", callerFuncName, invocationId, v)
+ } else {
+ output = fmt.Sprintf("call[%s %s]", callerFuncName, invocationId)
+ }
+ vlog.Info(output)
+ // TODO(mattr): annotate vtrace span.
+ return func(ctx *context.T, v ...interface{}) {
+ var output string
+ if len(v) > 0 {
+ output = fmt.Sprintf("return[%s %s]: %v", callerFuncName, invocationId, derefSlice(v))
+ } else {
+ output = fmt.Sprintf("return[%s %s]", callerFuncName, invocationId)
+ }
+ vlog.Info(output)
+ // TODO(mattr): annotate vtrace span.
+ }
+}
+
+// LogCallf behaves identically to LogCall, except it lets the caller to
+// customize the log messages via format specifiers, like the following:
+//
+// func Function(a Type1, b Type2) (r, t ReturnType) {
+// defer apilog.LogCallf(nil, "a: %v, b: %v", a, b)(nil, "(r,t)=(%v,%v)", &r, &t)
+// // ... function body ...
+// return finalR, finalT
+// }
+//
+func LogCallf(ctx *context.T, format string, v ...interface{}) func(*context.T, string, ...interface{}) {
+ if !vlog.V(logCallLogLevel) { // TODO(mattr): add call to vtrace.
+ return func(*context.T, string, ...interface{}) {}
+ }
+ callerFuncName := callerFuncName()
+ invocationId := newInvocationIdentifier()
+ output := fmt.Sprintf("call[%s %s]: %s", callerFuncName, invocationId, fmt.Sprintf(format, v...))
+ vlog.Info(output)
+ // TODO(mattr): annotate vtrace span.
+ return func(ctx *context.T, format string, v ...interface{}) {
+ output := fmt.Sprintf("return[%s %s]: %v", callerFuncName, invocationId, fmt.Sprintf(format, derefSlice(v)...))
+ vlog.Info(output)
+ // TODO(mattr): annotate vtrace span.
+ }
+}
+
+func derefSlice(slice []interface{}) []interface{} {
+ o := make([]interface{}, 0, len(slice))
+ for _, x := range slice {
+ o = append(o, reflect.Indirect(reflect.ValueOf(x)).Interface())
+ }
+ return o
+}
+
+var invocationCounter uint64 = 0
+
+// newInvocationIdentifier generates a unique identifier for a method invocation
+// to make it easier to match up log lines for the entry and exit of a function
+// when looking at a log transcript.
+func newInvocationIdentifier() string {
+ const (
+ charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"
+ charSetLen = uint64(len(charSet))
+ )
+ r := []byte{'@'}
+ for n := atomic.AddUint64(&invocationCounter, 1); n > 0; n /= charSetLen {
+ r = append(r, charSet[n%charSetLen])
+ }
+ return string(r)
+}
diff --git a/lib/vdl/codegen/java/file_client_interface.go b/lib/vdl/codegen/java/file_client_interface.go
index ffc17c8..229dbfa 100644
--- a/lib/vdl/codegen/java/file_client_interface.go
+++ b/lib/vdl/codegen/java/file_client_interface.go
@@ -19,7 +19,7 @@
package {{ .PackagePath }};
{{ .ServiceDoc }}
-{{ .AccessModifier }} interface {{ .ServiceName }}Client {{ .Extends }} {
+public interface {{ .ServiceName }}Client {{ .Extends }} {
{{ range $method := .Methods }}
{{/* If this method has multiple return arguments, generate the class. */}}
{{ if $method.IsMultipleRet }}
@@ -33,8 +33,8 @@
{{/* Generate the method signature. */}}
{{ $method.Doc }}
- {{ $method.AccessModifier }} {{ $method.RetType }} {{ $method.Name }}(final io.v.v23.context.VContext context{{ $method.Args }}) throws io.v.v23.verror.VException;
- {{ $method.AccessModifier }} {{ $method.RetType }} {{ $method.Name }}(final io.v.v23.context.VContext context{{ $method.Args }}, final io.v.v23.Options vOpts) throws io.v.v23.verror.VException;
+ {{ $method.RetType }} {{ $method.Name }}(final io.v.v23.context.VContext context{{ $method.Args }}) throws io.v.v23.verror.VException;
+ {{ $method.RetType }} {{ $method.Name }}(final io.v.v23.context.VContext context{{ $method.Args }}, final io.v.v23.Options vOpts) throws io.v.v23.verror.VException;
{{ end }}
}
`
@@ -45,7 +45,6 @@
}
type clientInterfaceMethod struct {
- AccessModifier string
Args string
Doc string
Name string
@@ -85,7 +84,6 @@
retArgs[i].Type = javaType(method.OutArgs[i].Type, false, env)
}
return clientInterfaceMethod{
- AccessModifier: accessModifierForName(method.Name),
Args: javaDeclarationArgStr(method.InArgs, env, true),
Doc: method.Doc,
Name: vdlutil.FirstRuneToLower(method.Name),
@@ -105,23 +103,21 @@
methods[i] = processClientInterfaceMethod(iface, method, env)
}
data := struct {
- FileDoc string
- AccessModifier string
- Extends string
- Methods []clientInterfaceMethod
- PackagePath string
- ServiceDoc string
- ServiceName string
- Source string
+ FileDoc string
+ Extends string
+ Methods []clientInterfaceMethod
+ PackagePath string
+ ServiceDoc string
+ ServiceName string
+ Source string
}{
- FileDoc: iface.File.Package.FileDoc,
- AccessModifier: accessModifierForName(iface.Name),
- Extends: javaClientExtendsStr(iface.Embeds),
- Methods: methods,
- PackagePath: javaPath(javaGenPkgPath(iface.File.Package.GenPath)),
- ServiceDoc: javaDoc(iface.Doc),
- ServiceName: javaServiceName,
- Source: iface.File.BaseName,
+ FileDoc: iface.File.Package.FileDoc,
+ Extends: javaClientExtendsStr(iface.Embeds),
+ Methods: methods,
+ PackagePath: javaPath(javaGenPkgPath(iface.File.Package.GenPath)),
+ ServiceDoc: javaDoc(iface.Doc),
+ ServiceName: javaServiceName,
+ Source: iface.File.BaseName,
}
var buf bytes.Buffer
err := parseTmpl("client interface", clientInterfaceTmpl).Execute(&buf, data)
diff --git a/lib/vdl/codegen/java/file_server_interface.go b/lib/vdl/codegen/java/file_server_interface.go
index d3d8891..4e50cbd 100644
--- a/lib/vdl/codegen/java/file_server_interface.go
+++ b/lib/vdl/codegen/java/file_server_interface.go
@@ -22,7 +22,7 @@
@io.v.v23.vdl.VServer(
serverWrapper = {{ .ServerWrapperPath }}.class
)
-{{ .AccessModifier }} interface {{ .ServiceName }}Server {{ .Extends }} {
+public interface {{ .ServiceName }}Server {{ .Extends }} {
{{ range $method := .Methods }}
{{/* If this method has multiple return arguments, generate the class. */}}
{{ if $method.IsMultipleRet }}
@@ -36,7 +36,7 @@
{{/* Generate the method signature. */}}
{{ $method.Doc }}
- {{ $method.AccessModifier }} {{ $method.RetType }} {{ $method.Name }}(final io.v.v23.context.VContext ctx, final io.v.v23.rpc.ServerCall call{{ $method.Args }}) throws io.v.v23.verror.VException;
+ {{ $method.RetType }} {{ $method.Name }}(final io.v.v23.context.VContext ctx, final io.v.v23.rpc.ServerCall call{{ $method.Args }}) throws io.v.v23.verror.VException;
{{ end }}
}
`
@@ -58,7 +58,6 @@
}
type serverInterfaceMethod struct {
- AccessModifier string
Args string
Doc string
Name string
@@ -84,7 +83,6 @@
}
return serverInterfaceMethod{
- AccessModifier: accessModifierForName(method.Name),
Args: args,
Doc: method.Doc,
Name: vdlutil.FirstRuneToLower(method.Name),
@@ -105,7 +103,6 @@
javaServiceName := vdlutil.FirstRuneToUpper(iface.Name)
data := struct {
FileDoc string
- AccessModifier string
Extends string
Methods []serverInterfaceMethod
PackagePath string
@@ -116,7 +113,6 @@
Source string
}{
FileDoc: iface.File.Package.FileDoc,
- AccessModifier: accessModifierForName(iface.Name),
Extends: javaServerExtendsStr(iface.Embeds),
Methods: methods,
PackagePath: javaPath(javaGenPkgPath(iface.File.Package.GenPath)),
diff --git a/runtime/internal/rpc/benchmark/benchmark/doc.go b/runtime/internal/rpc/benchmark/benchmark/doc.go
new file mode 100644
index 0000000..e9eaa9a
--- /dev/null
+++ b/runtime/internal/rpc/benchmark/benchmark/doc.go
@@ -0,0 +1,105 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command benchmark runs the benchmark client.
+
+Usage:
+ benchmark [flags]
+
+The benchmark flags are:
+ -chunk_count=0
+ Number of chunks to send per streaming RPC (if zero, use non-streaming RPC).
+ -iterations=100
+ Number of iterations to run.
+ -mux_chunk_count=0
+ Number of chunks to send in background.
+ -mux_payload_size=0
+ Size of payload to send in background.
+ -payload_size=0
+ Size of payload in bytes.
+ -server=
+ Address of the server to connect to.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -test.bench=
+ regular expression to select benchmarks to run
+ -test.benchmem=false
+ print memory allocations for benchmarks
+ -test.benchtime=1s
+ approximate run time for each benchmark
+ -test.blockprofile=
+ write a goroutine blocking profile to the named file after execution
+ -test.blockprofilerate=1
+ if >= 0, calls runtime.SetBlockProfileRate()
+ -test.coverprofile=
+ write a coverage profile to the named file after execution
+ -test.cpu=
+ comma-separated list of number of CPUs to use for each test
+ -test.cpuprofile=
+ write a cpu profile to the named file during execution
+ -test.memprofile=
+ write a memory profile to the named file after execution
+ -test.memprofilerate=0
+ if >=0, sets runtime.MemProfileRate
+ -test.outputdir=
+ directory in which to write profiles
+ -test.parallel=1
+ maximum test parallelism
+ -test.run=
+ regular expression to select tests and examples to run
+ -test.short=false
+ run smaller test suite to save time
+ -test.timeout=0
+ if positive, sets an aggregate time limit for all tests
+ -test.v=false
+ verbose: print additional output
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+ specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+ explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+ Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/runtime/internal/rpc/benchmark/benchmark/main.go b/runtime/internal/rpc/benchmark/benchmark/main.go
index 1afe697..b74bd81 100644
--- a/runtime/internal/rpc/benchmark/benchmark/main.go
+++ b/runtime/internal/rpc/benchmark/benchmark/main.go
@@ -2,58 +2,70 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// A simple command-line tool to run the benchmark client.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
- "flag"
"fmt"
- "os"
"testing"
"time"
+ "v.io/v23/context"
+ "v.io/x/lib/cmdline"
+ "v.io/x/lib/vlog"
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/generic"
"v.io/x/ref/runtime/internal/rpc/benchmark/internal"
- tbm "v.io/x/ref/test/benchmark"
-
- "v.io/v23"
- "v.io/x/lib/vlog"
+ "v.io/x/ref/test/benchmark"
)
var (
- server = flag.String("server", "", "address of the server to connect to")
-
- iterations = flag.Int("iterations", 100, "number of iterations to run")
-
- chunkCnt = flag.Int("chunk_count", 0, "number of chunks to send per streaming RPC (if zero, use non-streaming RPC)")
- payloadSize = flag.Int("payload_size", 0, "size of payload in bytes")
- chunkCntMux = flag.Int("mux_chunk_count", 0, "number of chunks to send in background")
- payloadSizeMux = flag.Int("mux_payload_size", 0, "size of payload to send in background")
+ server string
+ iterations, chunkCnt, payloadSize, chunkCntMux, payloadSizeMux int
)
func main() {
- ctx, shutdown := v23.Init()
- defer shutdown()
+ cmdRoot.Flags.StringVar(&server, "server", "", "Address of the server to connect to.")
+ cmdRoot.Flags.IntVar(&iterations, "iterations", 100, "Number of iterations to run.")
+ cmdRoot.Flags.IntVar(&chunkCnt, "chunk_count", 0, "Number of chunks to send per streaming RPC (if zero, use non-streaming RPC).")
+ cmdRoot.Flags.IntVar(&payloadSize, "payload_size", 0, "Size of payload in bytes.")
+ cmdRoot.Flags.IntVar(&chunkCntMux, "mux_chunk_count", 0, "Number of chunks to send in background.")
+ cmdRoot.Flags.IntVar(&payloadSizeMux, "mux_payload_size", 0, "Size of payload to send in background.")
- if *chunkCntMux > 0 && *payloadSizeMux > 0 {
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdRoot)
+}
+
+var cmdRoot = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runBenchmark),
+ Name: "benchmark",
+ Short: "Run the benchmark client",
+ Long: "Command benchmark runs the benchmark client.",
+}
+
+func runBenchmark(ctx *context.T, env *cmdline.Env, args []string) error {
+ if chunkCntMux > 0 && payloadSizeMux > 0 {
dummyB := testing.B{}
- _, stop := internal.StartEchoStream(&dummyB, ctx, *server, 0, *chunkCntMux, *payloadSizeMux, nil)
+ _, stop := internal.StartEchoStream(&dummyB, ctx, server, 0, chunkCntMux, payloadSizeMux, nil)
defer stop()
- vlog.Infof("Started background streaming (chunk_size=%d, payload_size=%d)", *chunkCntMux, *payloadSizeMux)
+ vlog.Infof("Started background streaming (chunk_size=%d, payload_size=%d)", chunkCntMux, payloadSizeMux)
}
dummyB := testing.B{}
- stats := tbm.NewStats(16)
+ stats := benchmark.NewStats(16)
now := time.Now()
- if *chunkCnt == 0 {
- internal.CallEcho(&dummyB, ctx, *server, *iterations, *payloadSize, stats)
+ if chunkCnt == 0 {
+ internal.CallEcho(&dummyB, ctx, server, iterations, payloadSize, stats)
} else {
- internal.CallEchoStream(&dummyB, ctx, *server, *iterations, *chunkCnt, *payloadSize, stats)
+ internal.CallEchoStream(&dummyB, ctx, server, iterations, chunkCnt, payloadSize, stats)
}
elapsed := time.Since(now)
- fmt.Printf("iterations: %d chunk_count: %d payload_size: %d\n", *iterations, *chunkCnt, *payloadSize)
+ fmt.Printf("iterations: %d chunk_count: %d payload_size: %d\n", iterations, chunkCnt, payloadSize)
fmt.Printf("elapsed time: %v\n", elapsed)
- stats.Print(os.Stdout)
+ stats.Print(env.Stdout)
+ return nil
}
diff --git a/runtime/internal/rpc/benchmark/benchmarkd/doc.go b/runtime/internal/rpc/benchmark/benchmarkd/doc.go
new file mode 100644
index 0000000..b00942c
--- /dev/null
+++ b/runtime/internal/rpc/benchmark/benchmarkd/doc.go
@@ -0,0 +1,91 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command benchmarkd runs the benchmark server.
+
+Usage:
+ benchmarkd
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -test.bench=
+ regular expression to select benchmarks to run
+ -test.benchmem=false
+ print memory allocations for benchmarks
+ -test.benchtime=1s
+ approximate run time for each benchmark
+ -test.blockprofile=
+ write a goroutine blocking profile to the named file after execution
+ -test.blockprofilerate=1
+ if >= 0, calls runtime.SetBlockProfileRate()
+ -test.coverprofile=
+ write a coverage profile to the named file after execution
+ -test.cpu=
+ comma-separated list of number of CPUs to use for each test
+ -test.cpuprofile=
+ write a cpu profile to the named file during execution
+ -test.memprofile=
+ write a memory profile to the named file after execution
+ -test.memprofilerate=0
+ if >=0, sets runtime.MemProfileRate
+ -test.outputdir=
+ directory in which to write profiles
+ -test.parallel=1
+ maximum test parallelism
+ -test.run=
+ regular expression to select tests and examples to run
+ -test.short=false
+ run smaller test suite to save time
+ -test.timeout=0
+ if positive, sets an aggregate time limit for all tests
+ -test.v=false
+ verbose: print additional output
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+ specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+ explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+ Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/runtime/internal/rpc/benchmark/benchmarkd/main.go b/runtime/internal/rpc/benchmark/benchmarkd/main.go
index a9ce539..e5053fd 100644
--- a/runtime/internal/rpc/benchmark/benchmarkd/main.go
+++ b/runtime/internal/rpc/benchmark/benchmarkd/main.go
@@ -2,24 +2,38 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// A simple command-line tool to run the benchmark server.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
"v.io/v23"
+ "v.io/v23/context"
+ "v.io/x/lib/cmdline"
"v.io/x/lib/vlog"
-
"v.io/x/ref/lib/signals"
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/roaming"
"v.io/x/ref/runtime/internal/rpc/benchmark/internal"
)
func main() {
- ctx, shutdown := v23.Init()
- defer shutdown()
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdRoot)
+}
+var cmdRoot = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runBenchmarkD),
+ Name: "benchmarkd",
+ Short: "Run the benchmark server",
+ Long: "Command benchmarkd runs the benchmark server.",
+}
+
+func runBenchmarkD(ctx *context.T, env *cmdline.Env, args []string) error {
ep, stop := internal.StartServer(ctx, v23.GetListenSpec(ctx))
vlog.Infof("Listening on %s", ep.Name())
defer stop()
<-signals.ShutdownOnSignals(ctx)
+ return nil
}
diff --git a/runtime/internal/rpc/stress/stress/doc.go b/runtime/internal/rpc/stress/stress/doc.go
new file mode 100644
index 0000000..5e37ed6
--- /dev/null
+++ b/runtime/internal/rpc/stress/stress/doc.go
@@ -0,0 +1,156 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command stress is a tool to stress/load test RPC by issuing randomly generated
+requests.
+
+Usage:
+ stress <command>
+
+The stress commands are:
+ stress Run stress test
+ stats Print out stress stats of servers
+ load Run load test
+ stop Stop servers
+ help Display help for commands or topics
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+ specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+ explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+ Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+
+Stress stress
+
+Run stress test
+
+Usage:
+ stress stress [flags] <server> ...
+
+<server> ... A list of servers to connect to.
+
+The stress stress flags are:
+ -duration=1m0s
+ duration of the test to run
+ -format=text
+ Stats output format; either text or json
+ -max-chunk-count=1000
+ maximum number of chunks to send per streaming RPC
+ -max-payload-size=10000
+ maximum size of payload in bytes
+ -workers=1
+ number of test workers to run
+
+Stress stats
+
+Print out stress stats of servers
+
+Usage:
+ stress stats [flags] <server> ...
+
+<server> ... A list of servers to connect to.
+
+The stress stats flags are:
+ -format=text
+ Stats output format; either text or json
+
+Stress load
+
+Run load test
+
+Usage:
+ stress load [flags] <server> ...
+
+<server> ... A list of servers to connect to.
+
+The stress load flags are:
+ -cpu=0
+ number of cpu cores to use; if zero, use the number of servers to test
+ -duration=1m0s
+ duration of the test to run
+ -format=text
+ Stats output format; either text or json
+ -payload-size=1000
+ size of payload in bytes
+
+Stress stop
+
+Stop servers
+
+Usage:
+ stress stop <server> ...
+
+<server> ... A list of servers to stop.
+
+Stress help
+
+Help with no args displays the usage of the parent command.
+
+Help with args displays the usage of the specified sub-command or help topic.
+
+"help ..." recursively displays help for all commands and topics.
+
+Usage:
+ stress help [flags] [command/topic ...]
+
+[command/topic ...] optionally identifies a specific sub-command or help topic.
+
+The stress help flags are:
+ -style=compact
+ The formatting style for help output:
+ compact - Good for compact cmdline output.
+ full - Good for cmdline output, shows all global flags.
+ godoc - Good for godoc processing.
+ Override the default by setting the CMDLINE_STYLE environment variable.
+ -width=<terminal width>
+ Format output to this target width in runes, or unlimited if width < 0.
+ Defaults to the terminal width if available. Override the default by setting
+ the CMDLINE_WIDTH environment variable.
+*/
+package main
diff --git a/runtime/internal/rpc/stress/stress/main.go b/runtime/internal/rpc/stress/stress/main.go
index 8645cad..03d3950 100644
--- a/runtime/internal/rpc/stress/stress/main.go
+++ b/runtime/internal/rpc/stress/stress/main.go
@@ -2,6 +2,9 @@
// 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 $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go .
+
package main
import (
@@ -37,7 +40,7 @@
cmdRoot := &cmdline.Command{
Name: "stress",
Short: "Tool to stress/load test RPC",
- Long: "Tool to stress/load test RPC by issuing randomly generated requests",
+ Long: "Command stress is a tool to stress/load test RPC by issuing randomly generated requests.",
Children: []*cmdline.Command{
cmdStressTest,
cmdStressStats,
@@ -45,5 +48,6 @@
cmdStopServers,
},
}
+ cmdline.HideGlobalFlagsExcept()
cmdline.Main(cmdRoot)
}
diff --git a/runtime/internal/rpc/stress/stressd/doc.go b/runtime/internal/rpc/stress/stressd/doc.go
new file mode 100644
index 0000000..29e8a4c
--- /dev/null
+++ b/runtime/internal/rpc/stress/stressd/doc.go
@@ -0,0 +1,65 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command stressd runs the stress-test server.
+
+Usage:
+ stressd [flags]
+
+The stressd flags are:
+ -duration=0
+ Duration of the stress test to run; if zero, there is no limit.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+ specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+ explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+ Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/runtime/internal/rpc/stress/stressd/main.go b/runtime/internal/rpc/stress/stressd/main.go
index 3286e7f..71ae935 100644
--- a/runtime/internal/rpc/stress/stressd/main.go
+++ b/runtime/internal/rpc/stress/stressd/main.go
@@ -2,38 +2,50 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// A simple command-line tool to run the benchmark server.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
- "flag"
+ "fmt"
"runtime"
"time"
"v.io/v23"
+ "v.io/v23/context"
+ "v.io/x/lib/cmdline"
"v.io/x/lib/vlog"
-
"v.io/x/ref/lib/signals"
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/static"
"v.io/x/ref/runtime/internal/rpc/stress/internal"
)
-var (
- duration = flag.Duration("duration", 0, "duration of the stress test to run; if zero, there is no limit.")
-)
+var duration time.Duration
func main() {
- runtime.GOMAXPROCS(runtime.NumCPU())
+ cmdRoot.Flags.DurationVar(&duration, "duration", 0, "Duration of the stress test to run; if zero, there is no limit.")
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdRoot)
+}
- ctx, shutdown := v23.Init()
- defer shutdown()
+var cmdRoot = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runStressD),
+ Name: "stressd",
+ Short: "Run the stress-test server",
+ Long: "Command stressd runs the stress-test server.",
+}
+
+func runStressD(ctx *context.T, env *cmdline.Env, args []string) error {
+ runtime.GOMAXPROCS(runtime.NumCPU())
server, ep, stop := internal.StartServer(ctx, v23.GetListenSpec(ctx))
vlog.Infof("listening on %s", ep.Name())
var timeout <-chan time.Time
- if *duration > 0 {
- timeout = time.After(*duration)
+ if duration > 0 {
+ timeout = time.After(duration)
}
select {
case <-timeout:
@@ -42,7 +54,8 @@
}
if err := server.Stop(); err != nil {
- vlog.Fatalf("Stop() failed: %v", err)
+ return fmt.Errorf("Stop() failed: %v", err)
}
vlog.Info("stopped.")
+ return nil
}
diff --git a/services/agent/agentd/doc.go b/services/agent/agentd/doc.go
new file mode 100644
index 0000000..58fce80
--- /dev/null
+++ b/services/agent/agentd/doc.go
@@ -0,0 +1,78 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command agentd runs the security agent daemon, which holds a private key in
+memory and makes it available to a subprocess.
+
+Loads the private key specified in privatekey.pem in V23_CREDENTIALS into
+memory, then starts the specified command with access to the private key via the
+agent protocol instead of directly reading from disk.
+
+Usage:
+ agentd [flags] command [command_args...]
+
+The command is started as a subprocess with the given [command_args...].
+
+The agentd flags are:
+ -additional-principals=
+ If non-empty, allow for the creation of new principals and save them in this
+ directory.
+ -new-principal-blessing-name=
+ If creating a new principal (--v23.credentials does not exist), then have it
+ blessed with this name.
+ -no-passphrase=false
+ If true, user will not be prompted for principal encryption passphrase.
+ -restart-exit-code=
+ If non-empty, will restart the command when it exits, provided that the
+ command's exit code matches the value of this flag. The value must be an
+ integer, or an integer preceded by '!' (in which case all exit codes except
+ the flag will trigger a restart).
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/services/agent/agentd/main.go b/services/agent/agentd/main.go
index 5956c79..7a0c214 100644
--- a/services/agent/agentd/main.go
+++ b/services/agent/agentd/main.go
@@ -2,8 +2,9 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Daemon agentd holds a private key in memory and makes it available to a
-// subprocess via the agent protocol.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
@@ -21,6 +22,7 @@
"v.io/v23"
"v.io/v23/security"
"v.io/v23/verror"
+ "v.io/x/lib/cmdline"
"v.io/x/lib/vlog"
"v.io/x/ref/envvar"
vsecurity "v.io/x/ref/lib/security"
@@ -37,46 +39,51 @@
errCantReadPassphrase = verror.Register(pkgPath+".errCantReadPassphrase", verror.NoRetry, "{1:}{2:} failed to read passphrase{:_}")
errNeedPassphrase = verror.Register(pkgPath+".errNeedPassphrase", verror.NoRetry, "{1:}{2:} Passphrase required for decrypting principal{:_}")
errCantParseRestartExitCode = verror.Register(pkgPath+".errCantParseRestartExitCode", verror.NoRetry, "{1:}{2:} Failed to parse restart exit code{:_}")
+
+ keypath, restartExitCode, newname string
+ noPassphrase bool
)
-var (
- keypath = flag.String("additional-principals", "", "If non-empty, allow for the creation of new principals and save them in this directory.")
- noPassphrase = flag.Bool("no-passphrase", false, "If true, user will not be prompted for principal encryption passphrase.")
+func main() {
+ cmdAgentD.Flags.StringVar(&keypath, "additional-principals", "", "If non-empty, allow for the creation of new principals and save them in this directory.")
+ cmdAgentD.Flags.BoolVar(&noPassphrase, "no-passphrase", false, "If true, user will not be prompted for principal encryption passphrase.")
// TODO(caprita): We use the exit code of the child to determine if the
// agent should restart it. Consider changing this to use the unix
// socket for this purpose.
- restartExitCode = flag.String("restart-exit-code", "", "If non-empty, will restart the command when it exits, provided that the command's exit code matches the value of this flag. The value must be an integer, or an integer preceded by '!' (in which case all exit codes except the flag will trigger a restart.")
+ cmdAgentD.Flags.StringVar(&restartExitCode, "restart-exit-code", "", "If non-empty, will restart the command when it exits, provided that the command's exit code matches the value of this flag. The value must be an integer, or an integer preceded by '!' (in which case all exit codes except the flag will trigger a restart).")
- newname = flag.String("new-principal-blessing-name", "", "If creating a new principal (--v23.credentials does not exist), then have it blessed with this name.")
-)
+ cmdAgentD.Flags.StringVar(&newname, "new-principal-blessing-name", "", "If creating a new principal (--v23.credentials does not exist), then have it blessed with this name.")
-func main() {
- os.Exit(Main())
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdAgentD)
}
-func Main() int {
- flag.Usage = func() {
- fmt.Fprintf(os.Stderr, `Usage: %s [agent options] command command_args...
+var cmdAgentD = &cmdline.Command{
+ Runner: cmdline.RunnerFunc(runAgentD),
+ Name: "agentd",
+ Short: "Holds a private key in memory and makes it available to a subprocess",
+ Long: fmt.Sprintf(`
+Command agentd runs the security agent daemon, which holds a private key in
+memory and makes it available to a subprocess.
Loads the private key specified in privatekey.pem in %v into memory, then
starts the specified command with access to the private key via the
agent protocol instead of directly reading from disk.
+`, envvar.Credentials),
+ ArgsName: "command [command_args...]",
+ ArgsLong: `
+The command is started as a subprocess with the given [command_args...].
+`,
+}
-`, os.Args[0], envvar.Credentials)
- flag.PrintDefaults()
- }
- flag.Parse()
- if len(flag.Args()) < 1 {
- fmt.Fprintln(os.Stderr, "Need at least one argument.")
- flag.Usage()
- return 1
+func runAgentD(env *cmdline.Env, args []string) error {
+ if len(args) < 1 {
+ return env.UsageErrorf("Need at least one argument.")
}
var restartOpts restartOptions
if err := restartOpts.parse(); err != nil {
- fmt.Fprintln(os.Stderr, err)
- flag.Usage()
- return 1
+ return env.UsageErrorf("%v", err)
}
// This is a bit tricky. We're trying to share the runtime's
@@ -93,26 +100,26 @@
f.Set("")
}
if len(dir) == 0 {
- vlog.Fatalf("The %v environment variable must be set to a directory: %q", envvar.Credentials, os.Getenv(envvar.Credentials))
+ return env.UsageErrorf("The %v environment variable must be set to a directory: %q", envvar.Credentials, os.Getenv(envvar.Credentials))
}
p, passphrase, err := newPrincipalFromDir(dir)
if err != nil {
- vlog.Fatalf("failed to create new principal from dir(%s): %v", dir, err)
+ return fmt.Errorf("failed to create new principal from dir(%s): %v", dir, err)
}
// Clear out the environment variable before v23.Init.
if err = envvar.ClearCredentials(); err != nil {
- vlog.Fatalf("envvar.ClearCredentials: %v", err)
+ return fmt.Errorf("envvar.ClearCredentials: %v", err)
}
ctx, shutdown := v23.Init()
defer shutdown()
if ctx, err = v23.WithPrincipal(ctx, p); err != nil {
- vlog.Panicf("failed to set principal for ctx: %v", err)
+ return fmt.Errorf("failed to set principal for ctx: %v", err)
}
- if *keypath == "" && passphrase != nil {
+ if keypath == "" && passphrase != nil {
// If we're done with the passphrase, zero it out so it doesn't stay in memory
for i := range passphrase {
passphrase[i] = 0
@@ -124,15 +131,15 @@
var sock, mgrSock *os.File
var endpoint string
if sock, endpoint, err = server.RunAnonymousAgent(ctx, p, childAgentFd); err != nil {
- vlog.Fatalf("RunAnonymousAgent: %v", err)
+ return fmt.Errorf("RunAnonymousAgent: %v", err)
}
if err = os.Setenv(envvar.AgentEndpoint, endpoint); err != nil {
- vlog.Fatalf("setenv: %v", err)
+ return fmt.Errorf("setenv: %v", err)
}
- if *keypath != "" {
- if mgrSock, err = server.RunKeyManager(ctx, *keypath, passphrase); err != nil {
- vlog.Fatalf("RunKeyManager: %v", err)
+ if keypath != "" {
+ if mgrSock, err = server.RunKeyManager(ctx, keypath, passphrase); err != nil {
+ return fmt.Errorf("RunKeyManager: %v", err)
}
}
@@ -140,9 +147,9 @@
for {
// Run the client and wait for it to finish.
cmd := exec.Command(flag.Args()[0], flag.Args()[1:]...)
- cmd.Stdin = os.Stdin
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
+ cmd.Stdin = env.Stdin
+ cmd.Stdout = env.Stdout
+ cmd.Stderr = env.Stderr
cmd.ExtraFiles = []*os.File{sock}
if mgrSock != nil {
@@ -151,7 +158,7 @@
err = cmd.Start()
if err != nil {
- vlog.Fatalf("Error starting child: %v", err)
+ return fmt.Errorf("Error starting child: %v", err)
}
shutdown := make(chan struct{})
go func() {
@@ -178,7 +185,10 @@
// right after cmd.Start().
sock.Close()
mgrSock.Close()
- return exitCode
+ if exitCode != 0 {
+ return cmdline.ErrExitCode(exitCode)
+ }
+ return nil
}
func newPrincipalFromDir(dir string) (security.Principal, []byte, error) {
@@ -195,7 +205,7 @@
func handleDoesNotExist(dir string) (security.Principal, []byte, error) {
fmt.Println("Private key file does not exist. Creating new private key...")
var pass []byte
- if !*noPassphrase {
+ if !noPassphrase {
var err error
if pass, err = getPassword("Enter passphrase (entering nothing will store unencrypted): "); err != nil {
return nil, nil, verror.New(errCantReadPassphrase, nil, err)
@@ -205,7 +215,7 @@
if err != nil {
return nil, pass, err
}
- name := *newname
+ name := newname
if len(name) == 0 {
name = "agent_principal"
}
@@ -214,7 +224,7 @@
}
func handlePassphrase(dir string) (security.Principal, []byte, error) {
- if *noPassphrase {
+ if noPassphrase {
return nil, nil, verror.New(errNeedPassphrase, nil)
}
pass, err := getPassword("Private key file is encrypted. Please enter passphrase.\nEnter passphrase: ")
@@ -300,7 +310,7 @@
}
func (opts *restartOptions) parse() error {
- code := *restartExitCode
+ code := restartExitCode
if code == "" {
return nil
}
diff --git a/services/agent/agentlib/agent_v23_test.go b/services/agent/agentlib/agent_v23_test.go
index cecdcc0..dcd9646 100644
--- a/services/agent/agentlib/agent_v23_test.go
+++ b/services/agent/agentlib/agent_v23_test.go
@@ -48,15 +48,18 @@
fmt.Fprintln(agent.Stdin(), "BADPASSWORD")
agent.ExpectEOF()
var stdout, stderr bytes.Buffer
- if err := agent.Wait(&stdout, &stderr); err == nil {
+ err := agent.Wait(&stdout, &stderr)
+ if err == nil {
i.Fatalf("expected an error.STDOUT:%v\nSTDERR:%v\n", stdout.String(), stderr.String())
- } else if got, want := err.Error(), "exit status 255"; got != want {
- i.Fatalf("Got %q, want %q", got, want)
- } else if got, want := stderr.String(), "passphrase incorrect for decrypting private key"; !strings.Contains(got, want) {
- i.Fatalf("Got %q, wanted it to contain %q", got, want)
+ }
+ if got, want := err.Error(), "exit status 1"; got != want {
+ i.Errorf("Got %q, want %q", got, want)
+ }
+ if got, want := stderr.String(), "passphrase incorrect for decrypting private key"; !strings.Contains(got, want) {
+ i.Errorf("Got %q, wanted it to contain %q", got, want)
}
if err := agent.Error(); err != nil {
- i.Fatal(err)
+ i.Error(err)
}
}
diff --git a/services/agent/internal/pingpong/doc.go b/services/agent/internal/pingpong/doc.go
new file mode 100644
index 0000000..606ad9a
--- /dev/null
+++ b/services/agent/internal/pingpong/doc.go
@@ -0,0 +1,60 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command pingpong runs a pingpong client or server. If no args are given the
+server is run, otherwise the client is run.
+
+Usage:
+ pingpong [server]
+
+If [server] is specified, pingpong is run in client mode, and connects to the
+named server.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/services/agent/internal/pingpong/main.go b/services/agent/internal/pingpong/main.go
index 559d4a1..24265f7 100644
--- a/services/agent/internal/pingpong/main.go
+++ b/services/agent/internal/pingpong/main.go
@@ -2,22 +2,46 @@
// 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 $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
- "flag"
"fmt"
"v.io/v23"
"v.io/v23/context"
"v.io/v23/rpc"
"v.io/v23/security"
+ "v.io/x/lib/cmdline"
"v.io/x/lib/vlog"
"v.io/x/ref/lib/signals"
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/generic"
)
+func main() {
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdPingPong)
+}
+
+var cmdPingPong = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runPingPong),
+ Name: "pingpong",
+ Short: "Runs pingpong client or server",
+ Long: `
+Command pingpong runs a pingpong client or server. If no args are given the
+server is run, otherwise the client is run.
+`,
+ ArgsName: "[server]",
+ ArgsLong: `
+If [server] is specified, pingpong is run in client mode, and connects to the
+named server.
+`,
+}
+
type pongd struct{}
func (f *pongd) Ping(ctx *context.T, call rpc.ServerCall, message string) (result string, err error) {
@@ -26,49 +50,48 @@
return fmt.Sprintf("pong (client:%v server:%v)", client, server), nil
}
-func clientMain(ctx *context.T, server string) {
+func clientMain(ctx *context.T, server string) error {
fmt.Println("Pinging...")
pong, err := PingPongClient(server).Ping(ctx, "ping")
if err != nil {
- vlog.Fatal("error pinging: ", err)
+ return fmt.Errorf("error pinging: %v", err)
}
fmt.Println(pong)
+ return nil
}
-func serverMain(ctx *context.T) {
+func serverMain(ctx *context.T) error {
s, err := v23.NewServer(ctx)
if err != nil {
- vlog.Fatal("failure creating server: ", err)
+ return fmt.Errorf("failure creating server: %v", err)
}
vlog.Info("Waiting for ping")
spec := rpc.ListenSpec{Addrs: rpc.ListenAddrs{{"tcp", "127.0.0.1:0"}}}
- if endpoints, err := s.Listen(spec); err == nil {
- fmt.Printf("NAME=%v\n", endpoints[0].Name())
- } else {
- vlog.Fatal("error listening to service:", err)
+ endpoints, err := s.Listen(spec)
+ if err != nil {
+ return fmt.Errorf("error listening to service: %v", err)
}
+ fmt.Printf("NAME=%v\n", endpoints[0].Name())
// Provide an empty name, no need to mount on any mounttable.
//
// Use the default authorization policy (nil authorizer), which will
// only authorize clients if the blessings of the client is a prefix of
// that of the server or vice-versa.
if err := s.Serve("", PingPongServer(&pongd{}), nil); err != nil {
- vlog.Fatal("error serving service: ", err)
+ return fmt.Errorf("error serving service: %v", err)
}
// Wait forever.
<-signals.ShutdownOnSignals(ctx)
+ return nil
}
-func main() {
- ctx, shutdown := v23.Init()
- defer shutdown()
-
- if len(flag.Args()) == 0 {
- serverMain(ctx)
- } else if len(flag.Args()) == 1 {
- clientMain(ctx, flag.Args()[0])
- } else {
- vlog.Fatalf("Expected at most one argument, the object name of the server. Got %v", flag.Args())
+func runPingPong(ctx *context.T, env *cmdline.Env, args []string) error {
+ switch len(args) {
+ case 0:
+ return serverMain(ctx)
+ case 1:
+ return clientMain(ctx, args[0])
}
+ return env.UsageErrorf("Too many arguments")
}
diff --git a/services/agent/internal/test_principal/doc.go b/services/agent/internal/test_principal/doc.go
new file mode 100644
index 0000000..d99fe3f
--- /dev/null
+++ b/services/agent/internal/test_principal/doc.go
@@ -0,0 +1,56 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command test_principal runs tests against a principal.
+
+Usage:
+ test_principal
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/services/agent/internal/test_principal/main.go b/services/agent/internal/test_principal/main.go
index 3da8db6..120e55f 100644
--- a/services/agent/internal/test_principal/main.go
+++ b/services/agent/internal/test_principal/main.go
@@ -2,6 +2,9 @@
// 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 $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
@@ -14,8 +17,11 @@
"runtime"
"v.io/v23"
+ "v.io/v23/context"
"v.io/v23/security"
+ "v.io/x/lib/cmdline"
"v.io/x/ref/envvar"
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/generic"
)
@@ -29,25 +35,23 @@
}
func main() {
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdTestPrincipal)
+}
+
+var cmdTestPrincipal = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runTestPrincipal),
+ Name: "test_principal",
+ Short: "Runs tests against a principal",
+ Long: "Command test_principal runs tests against a principal.",
+}
+
+func runTestPrincipal(ctx *context.T, env *cmdline.Env, args []string) error {
var errors []string
- defer func() {
- if len(errors) == 0 {
- return
- }
- // Print out all errors and exit with failure.
- for _, e := range errors {
- fmt.Fprintln(os.Stderr, e)
- }
- os.Exit(1)
- }()
errorf := func(format string, args ...interface{}) {
_, file, line, _ := runtime.Caller(1)
errors = append(errors, fmt.Sprintf("%v:%d: %v", file, line, fmt.Sprintf(format, args...)))
}
-
- ctx, shutdown := v23.Init()
- defer shutdown()
-
p := v23.GetPrincipal(ctx)
// Make sure we're running under a pristine agent to begin with.
// The agent aims to be transparent, so use a collection of heuristics
@@ -131,4 +135,13 @@
if forpeer := p.BlessingStore().ForPeer("superman/friend"); !reflect.DeepEqual(forpeer, b) {
errorf("BlessingStore().ForPeer returned %v and not %v", forpeer, b)
}
+
+ if len(errors) > 0 {
+ // Print out all errors and exit with failure.
+ for _, e := range errors {
+ fmt.Fprintln(env.Stderr, e)
+ }
+ return cmdline.ErrExitCode(1)
+ }
+ return nil
}
diff --git a/services/application/applicationd/doc.go b/services/application/applicationd/doc.go
new file mode 100644
index 0000000..f86ff46
--- /dev/null
+++ b/services/application/applicationd/doc.go
@@ -0,0 +1,68 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command applicationd runs the application daemon, which implements the
+v.io/x/ref/services/repository.Application interface.
+
+Usage:
+ applicationd [flags]
+
+The applicationd flags are:
+ -name=
+ Name to mount the application repository as.
+ -store=
+ Local directory to store application envelopes in.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+ specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+ explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+ Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/services/application/applicationd/main.go b/services/application/applicationd/main.go
index 1ba1cbf..0d3756c 100644
--- a/services/application/applicationd/main.go
+++ b/services/application/applicationd/main.go
@@ -2,58 +2,74 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Daemon applicationd implements the v.io/x/ref/services/repository.Application
-// interface.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
- "flag"
+ "fmt"
"v.io/v23"
+ "v.io/v23/context"
+ "v.io/x/lib/cmdline"
"v.io/x/lib/vlog"
-
"v.io/x/ref/lib/signals"
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/roaming"
)
-var (
- name = flag.String("name", "", "name to mount the application repository as")
- store = flag.String("store", "", "local directory to store application envelopes in")
-)
+var name, store string
func main() {
- ctx, shutdown := v23.Init()
- defer shutdown()
+ cmdAppD.Flags.StringVar(&name, "name", "", "Name to mount the application repository as.")
+ cmdAppD.Flags.StringVar(&store, "store", "", "Local directory to store application envelopes in.")
- if *store == "" {
- vlog.Fatalf("Specify a directory for storing application envelopes using --store=<name>")
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdAppD)
+}
+
+var cmdAppD = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runAppD),
+ Name: "applicationd",
+ Short: "Runs the application daemon.",
+ Long: `
+Command applicationd runs the application daemon, which implements the
+v.io/x/ref/services/repository.Application interface.
+`,
+}
+
+func runAppD(ctx *context.T, env *cmdline.Env, args []string) error {
+ if store == "" {
+ return env.UsageErrorf("Specify a directory for storing application envelopes using --store=<name>")
}
server, err := v23.NewServer(ctx)
if err != nil {
- vlog.Fatalf("NewServer() failed: %v", err)
+ return fmt.Errorf("NewServer() failed: %v", err)
}
defer server.Stop()
- dispatcher, err := NewDispatcher(*store)
+ dispatcher, err := NewDispatcher(store)
if err != nil {
- vlog.Fatalf("NewDispatcher() failed: %v", err)
+ return fmt.Errorf("NewDispatcher() failed: %v", err)
}
ls := v23.GetListenSpec(ctx)
endpoints, err := server.Listen(ls)
if err != nil {
- vlog.Fatalf("Listen(%s) failed: %v", ls, err)
+ return fmt.Errorf("Listen(%s) failed: %v", ls, err)
}
- if err := server.ServeDispatcher(*name, dispatcher); err != nil {
- vlog.Fatalf("Serve(%v) failed: %v", *name, err)
+ if err := server.ServeDispatcher(name, dispatcher); err != nil {
+ return fmt.Errorf("Serve(%v) failed: %v", name, err)
}
epName := endpoints[0].Name()
- if *name != "" {
- vlog.Infof("Application repository serving at %q (%q)", *name, epName)
+ if name != "" {
+ vlog.Infof("Application repository serving at %q (%q)", name, epName)
} else {
vlog.Infof("Application repository serving at %q", epName)
}
// Wait until shutdown.
<-signals.ShutdownOnSignals(ctx)
+ return nil
}
diff --git a/services/binary/binaryd/doc.go b/services/binary/binaryd/doc.go
new file mode 100644
index 0000000..ab358a6
--- /dev/null
+++ b/services/binary/binaryd/doc.go
@@ -0,0 +1,70 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command binaryd runs the binary daemon, which implements the
+v.io/v23/services/repository.Binary interface.
+
+Usage:
+ binaryd [flags]
+
+The binaryd flags are:
+ -http=:0
+ TCP address on which the HTTP server runs.
+ -name=
+ Name to mount the binary repository as.
+ -root-dir=
+ Root directory for the binary repository.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+ specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+ explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+ Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/services/binary/binaryd/main.go b/services/binary/binaryd/main.go
index efb5761..883f080 100644
--- a/services/binary/binaryd/main.go
+++ b/services/binary/binaryd/main.go
@@ -2,32 +2,50 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Daemon binaryd implements the v.io/v23/services/repository.Binary interface.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
- "flag"
+ "fmt"
"net"
"net/http"
"os"
"v.io/v23"
"v.io/v23/context"
- "v.io/x/lib/vlog"
-
+ "v.io/x/lib/cmdline"
"v.io/x/lib/netstate"
+ "v.io/x/lib/vlog"
"v.io/x/ref/lib/signals"
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/roaming"
"v.io/x/ref/services/internal/binarylib"
)
const defaultDepth = 3
-var (
- name = flag.String("name", "", "name to mount the binary repository as")
- rootDirFlag = flag.String("root-dir", "", "root directory for the binary repository")
- httpAddr = flag.String("http", ":0", "TCP address on which the HTTP server runs")
-)
+var name, rootDirFlag, httpAddr string
+
+func main() {
+ cmdBinaryD.Flags.StringVar(&name, "name", "", "Name to mount the binary repository as.")
+ cmdBinaryD.Flags.StringVar(&rootDirFlag, "root-dir", "", "Root directory for the binary repository.")
+ cmdBinaryD.Flags.StringVar(&httpAddr, "http", ":0", "TCP address on which the HTTP server runs.")
+
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdBinaryD)
+}
+
+var cmdBinaryD = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runBinaryD),
+ Name: "binaryd",
+ Short: "Runs the binary daemon.",
+ Long: `
+Command binaryd runs the binary daemon, which implements the
+v.io/v23/services/repository.Binary interface.
+`,
+}
// toIPPort tries to swap in the 'best' accessible IP for the host part of the
// address, if the provided address has an unspecified IP.
@@ -52,27 +70,21 @@
return net.JoinHostPort(host, port)
}
-func main() {
- ctx, shutdown := v23.Init()
- defer shutdown()
-
- rootDir, err := binarylib.SetupRootDir(*rootDirFlag)
+func runBinaryD(ctx *context.T, env *cmdline.Env, args []string) error {
+ rootDir, err := binarylib.SetupRootDir(rootDirFlag)
if err != nil {
- vlog.Errorf("SetupRootDir(%q) failed: %v", *rootDirFlag, err)
- return
+ return fmt.Errorf("SetupRootDir(%q) failed: %v", rootDirFlag, err)
}
vlog.Infof("Binary repository rooted at %v", rootDir)
- listener, err := net.Listen("tcp", *httpAddr)
+ listener, err := net.Listen("tcp", httpAddr)
if err != nil {
- vlog.Errorf("Listen(%s) failed: %v", *httpAddr, err)
- os.Exit(1)
+ return fmt.Errorf("Listen(%s) failed: %v", httpAddr, err)
}
rootURL := toIPPort(ctx, listener.Addr().String())
state, err := binarylib.NewState(rootDir, rootURL, defaultDepth)
if err != nil {
- vlog.Errorf("NewState(%v, %v, %v) failed: %v", rootDir, rootURL, defaultDepth, err)
- return
+ return fmt.Errorf("NewState(%v, %v, %v) failed: %v", rootDir, rootURL, defaultDepth, err)
}
vlog.Infof("Binary repository HTTP server at: %q", rootURL)
go func() {
@@ -83,32 +95,29 @@
}()
server, err := v23.NewServer(ctx)
if err != nil {
- vlog.Errorf("NewServer() failed: %v", err)
- return
+ return fmt.Errorf("NewServer() failed: %v", err)
}
defer server.Stop()
ls := v23.GetListenSpec(ctx)
endpoints, err := server.Listen(ls)
if err != nil {
- vlog.Errorf("Listen(%s) failed: %v", ls, err)
- return
+ return fmt.Errorf("Listen(%s) failed: %v", ls, err)
}
dis, err := binarylib.NewDispatcher(v23.GetPrincipal(ctx), state)
if err != nil {
- vlog.Errorf("NewDispatcher() failed: %v\n", err)
- return
+ return fmt.Errorf("NewDispatcher() failed: %v\n", err)
}
- if err := server.ServeDispatcher(*name, dis); err != nil {
- vlog.Errorf("ServeDispatcher(%v) failed: %v", *name, err)
- return
+ if err := server.ServeDispatcher(name, dis); err != nil {
+ return fmt.Errorf("ServeDispatcher(%v) failed: %v", name, err)
}
epName := endpoints[0].Name()
- if *name != "" {
- vlog.Infof("Binary repository serving at %q (%q)", *name, epName)
+ if name != "" {
+ vlog.Infof("Binary repository serving at %q (%q)", name, epName)
} else {
vlog.Infof("Binary repository serving at %q", epName)
}
// Wait until shutdown.
<-signals.ShutdownOnSignals(ctx)
+ return nil
}
diff --git a/services/build/buildd/doc.go b/services/build/buildd/doc.go
new file mode 100644
index 0000000..2113099
--- /dev/null
+++ b/services/build/buildd/doc.go
@@ -0,0 +1,71 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command buildd runs the builder daemon, which implements the
+v.io/v23/services/build.Builder interface.
+
+Usage:
+ buildd [flags]
+
+The buildd flags are:
+ -gobin=go
+ Path to the Go compiler.
+ -goroot=<GOROOT>
+ GOROOT to use with the Go compiler. The default is the value of the GOROOT
+ environment variable.
+ -name=
+ Name to mount the build server as.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+ specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+ explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+ Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/services/build/buildd/main.go b/services/build/buildd/main.go
index c4dc55c..ed25222 100644
--- a/services/build/buildd/main.go
+++ b/services/build/buildd/main.go
@@ -2,49 +2,64 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Daemon buildd implements the v.io/v23/services/build.Builder interface.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
- "flag"
+ "fmt"
"os"
"v.io/v23"
+ "v.io/v23/context"
"v.io/v23/services/build"
+ "v.io/x/lib/cmdline"
"v.io/x/lib/vlog"
"v.io/x/ref/lib/security/securityflag"
"v.io/x/ref/lib/signals"
-
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/roaming"
)
-var (
- gobin = flag.String("gobin", "go", "path to the Go compiler")
- goroot = flag.String("goroot", os.Getenv("GOROOT"), "GOROOT to use with the Go compiler")
- name = flag.String("name", "", "name to mount the build server as")
-)
+var gobin, goroot, name string
func main() {
- ctx, shutdown := v23.Init()
- defer shutdown()
+ cmdBuildD.Flags.StringVar(&gobin, "gobin", "go", "Path to the Go compiler.")
+ cmdBuildD.Flags.StringVar(&goroot, "goroot", os.Getenv("GOROOT"), "GOROOT to use with the Go compiler. The default is the value of the GOROOT environment variable.")
+ cmdBuildD.Flags.Lookup("goroot").DefValue = "<GOROOT>"
+ cmdBuildD.Flags.StringVar(&name, "name", "", "Name to mount the build server as.")
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdBuildD)
+}
+
+var cmdBuildD = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runBuildD),
+ Name: "buildd",
+ Short: "Runs the builder daemon.",
+ Long: `
+Command buildd runs the builder daemon, which implements the
+v.io/v23/services/build.Builder interface.
+`,
+}
+
+func runBuildD(ctx *context.T, env *cmdline.Env, args []string) error {
server, err := v23.NewServer(ctx)
if err != nil {
- vlog.Errorf("NewServer() failed: %v", err)
- return
+ return fmt.Errorf("NewServer() failed: %v", err)
}
ls := v23.GetListenSpec(ctx)
endpoint, err := server.Listen(ls)
if err != nil {
- vlog.Errorf("Listen(%s) failed: %v", ls, err)
- return
+ return fmt.Errorf("Listen(%s) failed: %v", ls, err)
}
- if err := server.Serve(*name, build.BuilderServer(NewBuilderService(*gobin, *goroot)), securityflag.NewAuthorizerOrDie()); err != nil {
- vlog.Errorf("Serve(%v) failed: %v", *name, err)
- return
+ if err := server.Serve(name, build.BuilderServer(NewBuilderService(gobin, goroot)), securityflag.NewAuthorizerOrDie()); err != nil {
+ return fmt.Errorf("Serve(%v) failed: %v", name, err)
}
vlog.Infof("Build server running at endpoint=%q", endpoint)
// Wait until shutdown.
<-signals.ShutdownOnSignals(ctx)
+ return nil
}
diff --git a/services/device/internal/impl/device_service.go b/services/device/internal/impl/device_service.go
index 4b612d1..58bc028 100644
--- a/services/device/internal/impl/device_service.go
+++ b/services/device/internal/impl/device_service.go
@@ -447,7 +447,7 @@
return verror.New(ErrOperationFailed, nil, fmt.Sprintf("EvalSymlinks(%v) failed: %v", os.Args[0], err))
}
- if err := os.MkdirAll(logs, 0700); err != nil {
+ if err := os.MkdirAll(logs, 0711); err != nil {
return verror.New(ErrOperationFailed, nil, fmt.Sprintf("MkdirAll(%v) failed: %v", logs, err))
}
stderrLog, stdoutLog := filepath.Join(logs, "STDERR"), filepath.Join(logs, "STDOUT")
diff --git a/services/device/mgmt_v23_test.go b/services/device/mgmt_v23_test.go
index 585c57f..31fce30 100644
--- a/services/device/mgmt_v23_test.go
+++ b/services/device/mgmt_v23_test.go
@@ -70,13 +70,41 @@
}
func V23TestDeviceManager(i *v23tests.T) {
+ u, err := user.Current()
+ if err != nil {
+ i.Fatalf("couldn't get the current user: %v", err)
+ }
+ testCore(i, u.Username, "", false)
+}
+
+func V23TestDeviceManagerMultiUser(i *v23tests.T) {
+ u, err := user.Current()
+ if err != nil {
+ i.Fatalf("couldn't get the current user: %v", err)
+ }
+
+ if u.Username == "veyron" && runTestOnThisPlatform {
+ // We are running on the builder so run the multiuser
+ // test with default user names. These will be created as
+ // required.
+ makeTestAccounts(i)
+ testCore(i, "vana", "devicemanager", true)
+ return
+ }
+
+ if len(deviceUserFlag) > 0 && len(appUserFlag) > 0 {
+ testCore(i, appUserFlag, deviceUserFlag, true)
+ } else {
+ i.Logf("Test skipped because running in multiuser mode requires --appuser and --deviceuser flags")
+ }
+}
+
+func testCore(i *v23tests.T, appUser, deviceUser string, withSuid bool) {
defer fmt.Fprintf(os.Stderr, "--------------- SHUTDOWN ---------------\n")
userFlag := "--single_user"
- withSuid := false
tempDir := ""
- if len(deviceUserFlag) > 0 && len(appUserFlag) > 0 {
- withSuid = true
- i.Logf("device user %s, app user %s", deviceUserFlag, appUserFlag)
+
+ if withSuid {
// When running --with_suid, TMPDIR must grant the
// invoking user rwx permissions and world x permissions for
// all parent directories back to /. Otherwise, the
@@ -85,14 +113,6 @@
// in /var that is 0700. This is unworkable so force
// TMPDIR to /tmp in this case.
tempDir = "/tmp"
- } else if len(deviceUserFlag) > 0 || len(appUserFlag) > 0 {
- i.Fatalf("Running in multiuser mode requires --appuser and --deviceuser")
- } else {
- u, err := user.Current()
- if err != nil {
- i.Fatalf("couldn't get the current user: %v", err)
- }
- appUserFlag = u.Username
}
var (
@@ -156,7 +176,7 @@
}
if withSuid {
- deviceScriptArguments = append(deviceScriptArguments, "--devuser="+deviceUserFlag)
+ deviceScriptArguments = append(deviceScriptArguments, "--devuser="+deviceUser)
} else {
deviceScriptArguments = append(deviceScriptArguments, userFlag)
}
@@ -221,10 +241,10 @@
mtEP := resolve(mtName)
if withSuid {
- deviceBin.Start("associate", "add", mtName+"/devmgr/device", appUserFlag, "root/alice")
+ deviceBin.Start("associate", "add", mtName+"/devmgr/device", appUser, "root/alice")
aai := deviceBin.Start("associate", "list", mtName+"/devmgr/device")
- if got, expected := strings.Trim(aai.Output(), "\n "), "root/alice "+appUserFlag; got != expected {
+ if got, expected := strings.Trim(aai.Output(), "\n "), "root/alice "+appUser; got != expected {
i.Fatalf("association test, got %v, expected %v", got, expected)
}
}
@@ -329,8 +349,8 @@
if err != nil {
i.Errorf("getUserForPid could not determine the user running pid %v", pid)
}
- if uname != appUserFlag {
- i.Errorf("app expected to be running as %v but is running as %v", appUserFlag, uname)
+ if uname != appUser {
+ i.Errorf("app expected to be running as %v but is running as %v", appUser, uname)
}
// Verify the app's default blessing.
diff --git a/services/device/util_darwin_test.go b/services/device/util_darwin_test.go
index 2a91405..f3ec7f4 100644
--- a/services/device/util_darwin_test.go
+++ b/services/device/util_darwin_test.go
@@ -4,4 +4,13 @@
package device_test
+import (
+ "v.io/x/ref/test/v23tests"
+)
+
+const runTestOnThisPlatform = false
const psFlags = "-ej"
+
+// TODO(rjkroege): Complete test implementation on Darwin.
+func makeTestAccounts(*v23tests.T) {
+}
diff --git a/services/device/util_linux_test.go b/services/device/util_linux_test.go
index bb96666..00f2343 100644
--- a/services/device/util_linux_test.go
+++ b/services/device/util_linux_test.go
@@ -4,4 +4,25 @@
package device_test
+import (
+ "os"
+ "os/user"
+
+ "v.io/x/ref/test/v23tests"
+)
+
const psFlags = "-ef"
+
+func makeTestAccounts(i *v23tests.T) {
+ userAddCmd := i.BinaryFromPath("/usr/bin/sudo")
+
+ if _, err := user.Lookup("vana"); err != nil {
+ userAddCmd.Start("/usr/sbin/adduser", "--no-create-home", "vana").WaitOrDie(os.Stdout, os.Stderr)
+ }
+
+ if _, err := user.Lookup("devicemanager"); err != nil {
+ userAddCmd.Start("/usr/sbin/adduser", "--no-create-home", "devicemanager").Wait(os.Stdout, os.Stderr)
+ }
+}
+
+const runTestOnThisPlatform = true
diff --git a/services/device/v23_test.go b/services/device/v23_test.go
index 597fed2..3eeab2f 100644
--- a/services/device/v23_test.go
+++ b/services/device/v23_test.go
@@ -23,3 +23,7 @@
func TestV23DeviceManager(t *testing.T) {
v23tests.RunTest(t, V23TestDeviceManager)
}
+
+func TestV23DeviceManagerMultiUser(t *testing.T) {
+ v23tests.RunTest(t, V23TestDeviceManagerMultiUser)
+}
diff --git a/services/identity/identityd/doc.go b/services/identity/identityd/doc.go
new file mode 100644
index 0000000..76b91c1
--- /dev/null
+++ b/services/identity/identityd/doc.go
@@ -0,0 +1,111 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command identityd runs a daemon HTTP server that uses OAuth to create
+security.Blessings objects.
+
+Starts an HTTP server that brokers blessings after authenticating through OAuth.
+
+To generate TLS certificates so the HTTP server can use SSL:
+ go run $(go list -f {{.Dir}} "crypto/tls")/generate_cert.go --host <IP address>
+
+To use Google as an OAuth provider the -google-config-* flags must be set to
+point to the a JSON file obtained after registering the application with the
+Google Developer Console at https://cloud.google.com/console
+
+More details on Google OAuth at:
+ https://developers.google.com/accounts/docs/OAuth2Login
+
+More details on the design of identityd at:
+ https://v.io/designdocs/identity-service.html
+
+Usage:
+ identityd [flags]
+
+The identityd flags are:
+ -assets-prefix=
+ Host serving the web assets for the identity server.
+ -external-http-addr=
+ External address on which the HTTP server listens on. If none is provided
+ the server will only listen on -http-addr.
+ -google-config-android=
+ Path to the JSON-encoded OAuth client configuration for Android applications
+ that obtain blessings from this server (via the
+ OAuthBlesser.BlessUsingAccessToken RPC) from this server.
+ -google-config-chrome=
+ Path to the JSON-encoded OAuth client configuration for Chrome browser
+ applications that obtain blessings from this server (via the
+ OAuthBlesser.BlessUsingAccessToken RPC) from this server.
+ -google-config-web=
+ Path to JSON-encoded OAuth client configuration for the web application that
+ renders the audit log for blessings provided by this provider.
+ -http-addr=localhost:8125
+ Address on which the HTTP server listens on.
+ -mount-prefix=identity
+ Mount name prefix to use. May be rooted.
+ -sql-config=
+ Path to file containing a json object of the following form:
+ {
+ "dataSourceName": "[username[:password]@][protocol[(address)]]/dbname", (the connection string required by go-sql-driver)
+ "tlsServerName": "serverName", (the domain name of the sql server for ssl)
+ "rootCertPath": "/path/server-ca.pem", (the root certificate of the sql server for ssl)
+ "clientCertPath": "/path/client-cert.pem", (the client certificate for ssl)
+ "clientKeyPath": "/path/client-key.pem" (the client private key for ssl)
+ }
+ -tls-config=
+ Comma-separated list of TLS certificate and private key files, in that order.
+ This must be provided.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+ specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+ explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+ Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/services/identity/identityd/main.go b/services/identity/identityd/main.go
index c483d89..37f5bff3 100644
--- a/services/identity/identityd/main.go
+++ b/services/identity/identityd/main.go
@@ -2,23 +2,22 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Daemon identityd is an HTTP server that uses OAuth to create
-// security.Blessings objects.
-//
-// For more information on our setup of the identity server see:
-// https://docs.google.com/document/d/1ebQ1sQn95cFu8yQM36rpJ8mQvsU29aa1o03ADhi52BM
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
"database/sql"
- "flag"
"fmt"
"os"
"time"
"v.io/v23"
+ "v.io/v23/context"
+ "v.io/x/lib/cmdline"
"v.io/x/lib/vlog"
-
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/static"
"v.io/x/ref/services/identity/internal/auditor"
"v.io/x/ref/services/identity/internal/blesser"
@@ -26,51 +25,79 @@
"v.io/x/ref/services/identity/internal/oauth"
"v.io/x/ref/services/identity/internal/revocation"
"v.io/x/ref/services/identity/internal/server"
- "v.io/x/ref/services/identity/internal/util"
)
var (
- // Configuration for various Google OAuth-based clients.
- googleConfigWeb = flag.String("google-config-web", "", "Path to JSON-encoded OAuth client configuration for the web application that renders the audit log for blessings provided by this provider.")
- googleConfigChrome = flag.String("google-config-chrome", "", "Path to the JSON-encoded OAuth client configuration for Chrome browser applications that obtain blessings from this server (via the OAuthBlesser.BlessUsingAccessToken RPC) from this server.")
- googleConfigAndroid = flag.String("google-config-android", "", "Path to the JSON-encoded OAuth client configuration for Android applications that obtain blessings from this server (via the OAuthBlesser.BlessUsingAccessToken RPC) from this server.")
- emailClassifier util.EmailClassifier
-
- // Flags controlling the HTTP server
- externalHttpAddr = flag.String("external-http-addr", "", "External address on which the HTTP server listens on. If none is provided the server will only listen on -http-addr.")
- httpAddr = flag.String("http-addr", "localhost:8125", "Address on which the HTTP server listens on.")
- tlsConfig = flag.String("tls-config", "", "Comma-separated list of TLS certificate and private key files, in that order. This must be provided.")
- assetsPrefix = flag.String("assets-prefix", "", "host serving the web assets for the identity server")
- mountPrefix = flag.String("mount-prefix", "identity", "mount name prefix to use. May be rooted.")
+ googleConfigWeb, googleConfigChrome, googleConfigAndroid string
+ externalHttpAddr, httpAddr, tlsConfig, assetsPrefix, mountPrefix string
)
-func main() {
- flag.Var(&emailClassifier, "email-classifier", "A comma-separated list of <domain>=<prefix> pairs. For example 'google.com=internal,v.io=trusted'. When specified, then the blessings generated for email address of <domain> will use the extension <prefix>/<email> instead of the default extension of users/<email>.")
- flag.Usage = usage
- ctx, shutdown := v23.Init()
- defer shutdown()
+func init() {
+ // Configuration for various Google OAuth-based clients.
+ cmdIdentityD.Flags.StringVar(&googleConfigWeb, "google-config-web", "", "Path to JSON-encoded OAuth client configuration for the web application that renders the audit log for blessings provided by this provider.")
+ cmdIdentityD.Flags.StringVar(&googleConfigChrome, "google-config-chrome", "", "Path to the JSON-encoded OAuth client configuration for Chrome browser applications that obtain blessings from this server (via the OAuthBlesser.BlessUsingAccessToken RPC) from this server.")
+ cmdIdentityD.Flags.StringVar(&googleConfigAndroid, "google-config-android", "", "Path to the JSON-encoded OAuth client configuration for Android applications that obtain blessings from this server (via the OAuthBlesser.BlessUsingAccessToken RPC) from this server.")
+ // Flags controlling the HTTP server
+ cmdIdentityD.Flags.StringVar(&externalHttpAddr, "external-http-addr", "", "External address on which the HTTP server listens on. If none is provided the server will only listen on -http-addr.")
+ cmdIdentityD.Flags.StringVar(&httpAddr, "http-addr", "localhost:8125", "Address on which the HTTP server listens on.")
+ cmdIdentityD.Flags.StringVar(&tlsConfig, "tls-config", "", "Comma-separated list of TLS certificate and private key files, in that order. This must be provided.")
+ cmdIdentityD.Flags.StringVar(&assetsPrefix, "assets-prefix", "", "Host serving the web assets for the identity server.")
+ cmdIdentityD.Flags.StringVar(&mountPrefix, "mount-prefix", "identity", "Mount name prefix to use. May be rooted.")
+}
+
+func main() {
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdIdentityD)
+}
+
+var cmdIdentityD = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runIdentityD),
+ Name: "identityd",
+ Short: "Runs HTTP server that creates security.Blessings objects",
+ Long: `
+Command identityd runs a daemon HTTP server that uses OAuth to create
+security.Blessings objects.
+
+Starts an HTTP server that brokers blessings after authenticating through OAuth.
+
+To generate TLS certificates so the HTTP server can use SSL:
+ go run $(go list -f {{.Dir}} "crypto/tls")/generate_cert.go --host <IP address>
+
+To use Google as an OAuth provider the -google-config-* flags must be set to
+point to the a JSON file obtained after registering the application with the
+Google Developer Console at https://cloud.google.com/console
+
+More details on Google OAuth at:
+ https://developers.google.com/accounts/docs/OAuth2Login
+
+More details on the design of identityd at:
+ https://v.io/designdocs/identity-service.html
+`,
+}
+
+func runIdentityD(ctx *context.T, env *cmdline.Env, args []string) error {
var sqlDB *sql.DB
var err error
- if len(*sqlConf) > 0 {
- if sqlDB, err = dbFromConfigFile(*sqlConf); err != nil {
- vlog.Fatalf("failed to create sqlDB: %v", err)
+ if sqlConf != "" {
+ if sqlDB, err = dbFromConfigFile(sqlConf); err != nil {
+ return env.UsageErrorf("Failed to create sqlDB: %v", err)
}
}
- googleoauth, err := oauth.NewGoogleOAuth(*googleConfigWeb)
+ googleoauth, err := oauth.NewGoogleOAuth(googleConfigWeb)
if err != nil {
- vlog.Fatalf("Failed to setup GoogleOAuth: %v", err)
+ return env.UsageErrorf("Failed to setup GoogleOAuth: %v", err)
}
auditor, reader, err := auditor.NewSQLBlessingAuditor(sqlDB)
if err != nil {
- vlog.Fatalf("Failed to create sql auditor from config: %v", err)
+ return fmt.Errorf("Failed to create sql auditor from config: %v", err)
}
revocationManager, err := revocation.NewRevocationManager(sqlDB)
if err != nil {
- vlog.Fatalf("Failed to start RevocationManager: %v", err)
+ return fmt.Errorf("Failed to start RevocationManager: %v", err)
}
listenSpec := v23.GetListenSpec(ctx)
@@ -80,44 +107,25 @@
reader,
revocationManager,
googleOAuthBlesserParams(googleoauth, revocationManager),
- caveats.NewBrowserCaveatSelector(*assetsPrefix),
- &emailClassifier,
- *assetsPrefix,
- *mountPrefix)
- s.Serve(ctx, &listenSpec, *externalHttpAddr, *httpAddr, *tlsConfig)
-}
-
-func usage() {
- fmt.Fprintf(os.Stderr, `%s starts an HTTP server that brokers blessings after authenticating through OAuth.
-
-To generate TLS certificates so the HTTP server can use SSL:
-go run $(go list -f {{.Dir}} "crypto/tls")/generate_cert.go --host <IP address>
-
-To use Google as an OAuth provider the --google-config-* flags must be set to point to
-the a JSON file obtained after registering the application with the Google Developer Console
-at https://cloud.google.com/console
-
-More details on Google OAuth at:
-https://developers.google.com/accounts/docs/OAuth2Login
-
-Flags:
-`, os.Args[0])
- flag.PrintDefaults()
+ caveats.NewBrowserCaveatSelector(assetsPrefix),
+ assetsPrefix,
+ mountPrefix)
+ s.Serve(ctx, &listenSpec, externalHttpAddr, httpAddr, tlsConfig)
+ return nil
}
func googleOAuthBlesserParams(oauthProvider oauth.OAuthProvider, revocationManager revocation.RevocationManager) blesser.OAuthBlesserParams {
params := blesser.OAuthBlesserParams{
OAuthProvider: oauthProvider,
BlessingDuration: 365 * 24 * time.Hour,
- EmailClassifier: &emailClassifier,
RevocationManager: revocationManager,
}
- if clientID, err := getOAuthClientID(*googleConfigChrome); err != nil {
+ if clientID, err := getOAuthClientID(googleConfigChrome); err != nil {
vlog.Info(err)
} else {
params.AccessTokenClients = append(params.AccessTokenClients, oauth.AccessTokenClient{Name: "chrome", ClientID: clientID})
}
- if clientID, err := getOAuthClientID(*googleConfigAndroid); err != nil {
+ if clientID, err := getOAuthClientID(googleConfigAndroid); err != nil {
vlog.Info(err)
} else {
params.AccessTokenClients = append(params.AccessTokenClients, oauth.AccessTokenClient{Name: "android", ClientID: clientID})
diff --git a/services/identity/identityd/sql.go b/services/identity/identityd/sql.go
index fc5c127..7b8b09e 100644
--- a/services/identity/identityd/sql.go
+++ b/services/identity/identityd/sql.go
@@ -9,7 +9,6 @@
"crypto/x509"
"database/sql"
"encoding/json"
- "flag"
"fmt"
"io/ioutil"
@@ -17,7 +16,10 @@
)
// Flag controlling auditing and revocation of Blessing operations.
-var sqlConf = flag.String("sql-config", "", `Path to file containing a json object of the following form:
+var sqlConf string
+
+func init() {
+ cmdIdentityD.Flags.StringVar(&sqlConf, "sql-config", "", `Path to file containing a json object of the following form:
{
"dataSourceName": "[username[:password]@][protocol[(address)]]/dbname", (the connection string required by go-sql-driver)
"tlsServerName": "serverName", (the domain name of the sql server for ssl)
@@ -25,6 +27,7 @@
"clientCertPath": "/path/client-cert.pem", (the client certificate for ssl)
"clientKeyPath": "/path/client-key.pem" (the client private key for ssl)
}`)
+}
// The key used by both go-sql-driver and tls for ssl.
const tlsRegisteredKey = "identitydTLS"
diff --git a/services/identity/identitylib/test_identityd.go b/services/identity/identitylib/test_identityd.go
index 1559091..03cdf0a 100644
--- a/services/identity/identitylib/test_identityd.go
+++ b/services/identity/identitylib/test_identityd.go
@@ -94,7 +94,6 @@
revocationManager,
params,
caveats.NewMockCaveatSelector(),
- nil,
"",
"identity")
diff --git a/services/identity/internal/blesser/macaroon.go b/services/identity/internal/blesser/macaroon.go
index c96c7cf..4a035d2 100644
--- a/services/identity/internal/blesser/macaroon.go
+++ b/services/identity/internal/blesser/macaroon.go
@@ -6,6 +6,7 @@
import (
"fmt"
+ "strings"
"time"
"v.io/x/ref/services/identity"
@@ -48,6 +49,13 @@
if len(m.Caveats) == 0 {
m.Caveats = []security.Caveat{security.UnconstrainedUse()}
}
+ var extension string
+ // TODO(ashankar): Remove after the transition from running identityd as "dev.v.io/root" to "dev.v.io/u" is complete.
+ if local := security.LocalBlessingNames(ctx, secCall); len(local) == 1 && strings.HasSuffix(local[0], security.ChainSeparator+"u") {
+ extension = m.Name
+ } else {
+ extension = strings.Join([]string{"users", m.Name}, security.ChainSeparator)
+ }
return secCall.LocalPrincipal().Bless(secCall.RemoteBlessings().PublicKey(),
- secCall.LocalBlessings(), m.Name, m.Caveats[0], m.Caveats[1:]...)
+ secCall.LocalBlessings(), extension, m.Caveats[0], m.Caveats[1:]...)
}
diff --git a/services/identity/internal/blesser/macaroon_test.go b/services/identity/internal/blesser/macaroon_test.go
index 7e537f6..3306825 100644
--- a/services/identity/internal/blesser/macaroon_test.go
+++ b/services/identity/internal/blesser/macaroon_test.go
@@ -35,7 +35,7 @@
if _, err := blesser.Bless(ctx, call, newMacaroon(t, key, m)); err == nil || err.Error() != wantErr {
t.Errorf("Bless(...) failed with error: %v, want: %v", err, wantErr)
}
- m = oauth.BlessingMacaroon{Creation: time.Now(), Name: "user", Caveats: []security.Caveat{cOnlyMethodFoo}}
+ m = oauth.BlessingMacaroon{Creation: time.Now(), Name: "bugsbunny", Caveats: []security.Caveat{cOnlyMethodFoo}}
b, err := blesser.Bless(ctx, call, newMacaroon(t, key, m))
if err != nil {
t.Errorf("Bless failed: %v", err)
@@ -51,13 +51,13 @@
t.Errorf("Got blessing with info %v, want nil", got)
}
// But once it recognizes the provider, it should see exactly the name
- // "provider/user" for the caveat cOnlyMethodFoo.
+ // "provider/users/bugsbunny" for the caveat cOnlyMethodFoo.
user.AddToRoots(b)
binfo := user.BlessingsInfo(b)
if num := len(binfo); num != 1 {
t.Errorf("Got blessings with %d names, want exactly one name", num)
}
- wantName := "provider/user"
+ wantName := "provider/users/bugsbunny"
if got, want := binfo[wantName], []security.Caveat{cOnlyMethodFoo}; !reflect.DeepEqual(got, want) {
t.Errorf("binfo[%q]: Got %v, want %v", wantName, got, want)
}
diff --git a/services/identity/internal/blesser/oauth.go b/services/identity/internal/blesser/oauth.go
index 127658d..e79c9c2 100644
--- a/services/identity/internal/blesser/oauth.go
+++ b/services/identity/internal/blesser/oauth.go
@@ -12,7 +12,6 @@
"v.io/x/ref/services/identity"
"v.io/x/ref/services/identity/internal/oauth"
"v.io/x/ref/services/identity/internal/revocation"
- "v.io/x/ref/services/identity/internal/util"
"v.io/v23/context"
"v.io/v23/rpc"
@@ -24,7 +23,6 @@
authcodeClient struct{ ID, Secret string }
accessTokenClients []oauth.AccessTokenClient
duration time.Duration
- emailClassifier *util.EmailClassifier
dischargerLocation string
revocationManager revocation.RevocationManager
}
@@ -35,8 +33,6 @@
OAuthProvider oauth.OAuthProvider
// The OAuth client IDs and names for the clients of the BlessUsingAccessToken RPCs.
AccessTokenClients []oauth.AccessTokenClient
- // Determines prefixes used for blessing extensions based on email address.
- EmailClassifier *util.EmailClassifier
// The object name of the discharger service. If this is empty then revocation caveats will not be granted.
DischargerLocation string
// The revocation manager that generates caveats and manages revocation.
@@ -56,7 +52,6 @@
return identity.OAuthBlesserServer(&oauthBlesser{
oauthProvider: p.OAuthProvider,
duration: p.BlessingDuration,
- emailClassifier: p.EmailClassifier,
dischargerLocation: p.DischargerLocation,
revocationManager: p.RevocationManager,
accessTokenClients: p.AccessTokenClients,
@@ -69,10 +64,10 @@
if err != nil {
return noblessings, "", err
}
- return b.bless(call.Security(), email, clientName)
+ return b.bless(ctx, call.Security(), email, clientName)
}
-func (b *oauthBlesser) bless(call security.Call, email, clientName string) (security.Blessings, string, error) {
+func (b *oauthBlesser) bless(ctx *context.T, call security.Call, email, clientName string) (security.Blessings, string, error) {
var noblessings security.Blessings
self := call.LocalPrincipal()
if self == nil {
@@ -88,16 +83,22 @@
if err != nil {
return noblessings, "", err
}
- extension := strings.Join([]string{
- b.emailClassifier.Classify(email),
- email,
- // Append clientName (e.g., "android", "chrome") to the email and then bless under that.
- // Since blessings issued by this process do not have many caveats on them and typically
- // have a large expiry duration, we include the clientName in the extension so that
- // servers can explicitly distinguish these clients while specifying authorization policies
- // (say, via AccessLists).
- clientName,
- }, security.ChainSeparator)
+ var parts []string
+ // TODO(ashankar): Remove this - here only for the transition from
+ // running identityd as "dev.v.io/root" to running it as "dev.v.io/u"
+ // At that point, can also remove the "ctx" argument to this method.
+ if bnames := security.LocalBlessingNames(ctx, call); len(bnames) == 1 && strings.HasSuffix(bnames[0], security.ChainSeparator+"u") {
+ parts = []string{email}
+ } else {
+ parts = []string{"users", email}
+ }
+ // Append clientName (e.g., "android", "chrome") to the email and then bless under that.
+ // Since blessings issued by this process do not have many caveats on them and typically
+ // have a large expiry duration, we include the clientName in the extension so that
+ // servers can explicitly distinguish these clients while specifying authorization policies
+ // (say, via AccessLists).
+ parts = append(parts, clientName)
+ extension := strings.Join(parts, security.ChainSeparator)
blessing, err := self.Bless(call.RemoteBlessings().PublicKey(), call.LocalBlessings(), extension, caveat)
if err != nil {
return noblessings, "", err
diff --git a/services/identity/internal/identityd_test/doc.go b/services/identity/internal/identityd_test/doc.go
new file mode 100644
index 0000000..d7d7b6e
--- /dev/null
+++ b/services/identity/internal/identityd_test/doc.go
@@ -0,0 +1,86 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command identityd_test runs a daemon HTTP server that uses OAuth to create
+security.Blessings objects.
+
+Starts a test version of the identityd server that mocks out oauth, auditing,
+and revocation.
+
+To generate TLS certificates so the HTTP server can use SSL:
+ go run $(go list -f {{.Dir}} "crypto/tls")/generate_cert.go --host <IP address>
+
+Usage:
+ identityd_test [flags]
+
+The identityd_test flags are:
+ -assets-prefix=
+ Host serving the web assets for the identity server.
+ -browser=false
+ Whether to open a browser caveat selector.
+ -external-http-addr=
+ External address on which the HTTP server listens on. If none is provided
+ the server will only listen on -http-addr.
+ -http-addr=localhost:0
+ Address on which the HTTP server listens on.
+ -mount-prefix=identity
+ Mount name prefix to use. May be rooted.
+ -oauth-email=testemail@example.com
+ Username for the mock oauth to put in the returned blessings.
+ -tls-config=
+ Comma-separated list of TLS certificate and private key files, in that order.
+ This must be provided.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+ specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+ explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+ Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/services/identity/internal/identityd_test/main.go b/services/identity/internal/identityd_test/main.go
index 59e0f0d..f9cccac 100644
--- a/services/identity/internal/identityd_test/main.go
+++ b/services/identity/internal/identityd_test/main.go
@@ -2,19 +2,20 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// HTTP server that uses OAuth to create security.Blessings objects.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
"flag"
- "fmt"
"net"
- "os"
"time"
"v.io/v23"
- "v.io/x/lib/vlog"
-
+ "v.io/v23/context"
+ "v.io/x/lib/cmdline"
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/static"
"v.io/x/ref/services/identity/internal/auditor"
"v.io/x/ref/services/identity/internal/blesser"
@@ -26,49 +27,72 @@
)
var (
- // Flags controlling the HTTP server
- externalHttpAddr = flag.String("external-http-addr", "", "External address on which the HTTP server listens on. If none is provided the server will only listen on -http-addr.")
- httpAddr = flag.String("http-addr", "localhost:0", "Address on which the HTTP server listens on.")
- tlsConfig = flag.String("tls-config", "", "Comma-separated list of TLS certificate and private key files, in that order. This must be provided.")
- assetsPrefix = flag.String("assets-prefix", "", "host serving the web assets for the identity server")
- mountPrefix = flag.String("mount-prefix", "identity", "mount name prefix to use. May be rooted.")
- browser = flag.Bool("browser", false, "whether to open a browser caveat selector")
- oauthEmail = flag.String("oauth-email", "testemail@example.com", "Username for the mock oauth to put in the returned blessings")
+ externalHttpAddr, httpAddr, tlsConfig, assetsPrefix, mountPrefix string
+ browser bool
+ oauthEmail string
)
-func main() {
- flag.Usage = usage
- ctx, shutdown := v23.Init()
- defer shutdown()
+func init() {
+ // Flags controlling the HTTP server
+ cmdTest.Flags.StringVar(&externalHttpAddr, "external-http-addr", "", "External address on which the HTTP server listens on. If none is provided the server will only listen on -http-addr.")
+ cmdTest.Flags.StringVar(&httpAddr, "http-addr", "localhost:0", "Address on which the HTTP server listens on.")
+ cmdTest.Flags.StringVar(&tlsConfig, "tls-config", "", "Comma-separated list of TLS certificate and private key files, in that order. This must be provided.")
+ cmdTest.Flags.StringVar(&assetsPrefix, "assets-prefix", "", "Host serving the web assets for the identity server.")
+ cmdTest.Flags.StringVar(&mountPrefix, "mount-prefix", "identity", "Mount name prefix to use. May be rooted.")
+ cmdTest.Flags.BoolVar(&browser, "browser", false, "Whether to open a browser caveat selector.")
+ cmdTest.Flags.StringVar(&oauthEmail, "oauth-email", "testemail@example.com", "Username for the mock oauth to put in the returned blessings.")
+}
+func main() {
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdTest)
+}
+
+var cmdTest = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runIdentityDTest),
+ Name: "identityd_test",
+ Short: "Runs HTTP server that creates security.Blessings objects",
+ Long: `
+Command identityd_test runs a daemon HTTP server that uses OAuth to create
+security.Blessings objects.
+
+Starts a test version of the identityd server that mocks out oauth, auditing,
+and revocation.
+
+To generate TLS certificates so the HTTP server can use SSL:
+ go run $(go list -f {{.Dir}} "crypto/tls")/generate_cert.go --host <IP address>
+`,
+}
+
+func runIdentityDTest(ctx *context.T, env *cmdline.Env, args []string) error {
// Duration to use for tls cert and blessing duration.
duration := 365 * 24 * time.Hour
// If no tlsConfig has been provided, write and use our own.
if flag.Lookup("tls-config").Value.String() == "" {
- addr := *externalHttpAddr
- if *externalHttpAddr == "" {
- addr = *httpAddr
+ addr := externalHttpAddr
+ if externalHttpAddr == "" {
+ addr = httpAddr
}
host, _, err := net.SplitHostPort(addr)
if err != nil {
// NOTE(caprita): The (non-test) identityd binary
// accepts an address with no port. Should this test
// binary do the same instead?
- vlog.Fatalf("Failed to parse %q: %v", addr, err)
+ return env.UsageErrorf("Failed to parse http address %q: %v", addr, err)
}
certFile, keyFile, err := util.WriteCertAndKey(host, duration)
if err != nil {
- vlog.Fatal(err)
+ return err
}
if err := flag.Set("tls-config", certFile+","+keyFile); err != nil {
- vlog.Fatal(err)
+ return err
}
}
auditor, reader := auditor.NewMockBlessingAuditor()
revocationManager := revocation.NewMockRevocationManager()
- oauthProvider := oauth.NewMockOAuth(*oauthEmail)
+ oauthProvider := oauth.NewMockOAuth(oauthEmail)
params := blesser.OAuthBlesserParams{
OAuthProvider: oauthProvider,
@@ -77,8 +101,8 @@
}
caveatSelector := caveats.NewMockCaveatSelector()
- if *browser {
- caveatSelector = caveats.NewBrowserCaveatSelector(*assetsPrefix)
+ if browser {
+ caveatSelector = caveats.NewBrowserCaveatSelector(assetsPrefix)
}
listenSpec := v23.GetListenSpec(ctx)
@@ -89,20 +113,8 @@
revocationManager,
params,
caveatSelector,
- nil,
- *assetsPrefix,
- *mountPrefix)
- s.Serve(ctx, &listenSpec, *externalHttpAddr, *httpAddr, *tlsConfig)
-}
-
-func usage() {
- fmt.Fprintf(os.Stderr, `%s starts a test version of the identityd server that
-mocks out oauth, auditing, and revocation.
-
-To generate TLS certificates so the HTTP server can use SSL:
-go run $(go list -f {{.Dir}} "crypto/tls")/generate_cert.go --host <IP address>
-
-Flags:
-`, os.Args[0])
- flag.PrintDefaults()
+ assetsPrefix,
+ mountPrefix)
+ s.Serve(ctx, &listenSpec, externalHttpAddr, httpAddr, tlsConfig)
+ return nil
}
diff --git a/services/identity/internal/oauth/handler.go b/services/identity/internal/oauth/handler.go
index c2de6ab..50c753a 100644
--- a/services/identity/internal/oauth/handler.go
+++ b/services/identity/internal/oauth/handler.go
@@ -75,10 +75,6 @@
// MacaroonBlessingService is the object name to which macaroons create by this HTTP
// handler can be exchanged for a blessing.
MacaroonBlessingService string
- // EmailClassifier is used to decide the prefix used for blessing extensions.
- // For example, if EmailClassifier.Classify("foo@bar.com") returns "guests",
- // then the email foo@bar.com will receive the blessing "guests/foo@bar.com".
- EmailClassifier *util.EmailClassifier
// OAuthProvider is used to authenticate and get a blessee email.
OAuthProvider OAuthProvider
// CaveatSelector is used to obtain caveats from the user when seeking a blessing.
@@ -387,10 +383,13 @@
util.HTTPServerError(w, fmt.Errorf("failed to get server blessings"))
return
}
- parts := []string{
- string(localBlessings[0]),
- h.args.EmailClassifier.Classify(email),
- email,
+ var parts []string
+ // TODO(ashankar): Remove after the transition from running identityd
+ // as "dev.v.io/root" to "dev.v.io/u" is complete.
+ if local := string(localBlessings[0]); strings.HasSuffix(local, security.ChainSeparator+"u") {
+ parts = []string{local, email}
+ } else {
+ parts = []string{local, "users", email}
}
fullBlessingName := strings.Join(parts, security.ChainSeparator)
if err := h.args.CaveatSelector.Render(fullBlessingName, outputMacaroon, redirectURL(h.args.Addr, sendMacaroonRoute), w, r); err != nil {
@@ -416,10 +415,7 @@
util.HTTPBadRequest(w, r, fmt.Errorf("failed to create caveats: %v", err))
return
}
- parts := []string{
- h.args.EmailClassifier.Classify(inputMacaroon.Email),
- inputMacaroon.Email,
- }
+ parts := []string{inputMacaroon.Email}
if len(blessingExtension) > 0 {
parts = append(parts, blessingExtension)
}
diff --git a/services/identity/internal/server/identityd.go b/services/identity/internal/server/identityd.go
index 9a34e15..4294c71 100644
--- a/services/identity/internal/server/identityd.go
+++ b/services/identity/internal/server/identityd.go
@@ -35,7 +35,6 @@
"v.io/x/ref/services/identity/internal/oauth"
"v.io/x/ref/services/identity/internal/revocation"
"v.io/x/ref/services/identity/internal/templates"
- "v.io/x/ref/services/identity/internal/util"
)
const (
@@ -57,7 +56,6 @@
revocationManager revocation.RevocationManager
oauthBlesserParams blesser.OAuthBlesserParams
caveatSelector caveats.CaveatSelector
- emailClassifier *util.EmailClassifier
rootedObjectAddrs []naming.Endpoint
assetsPrefix string
mountNamePrefix string
@@ -68,7 +66,7 @@
// - auditor and blessingLogReader to audit the root principal and read audit logs
// - revocationManager to store revocation data and grant discharges
// - oauthBlesserParams to configure the identity.OAuthBlesser service
-func NewIdentityServer(oauthProvider oauth.OAuthProvider, auditor audit.Auditor, blessingLogReader auditor.BlessingLogReader, revocationManager revocation.RevocationManager, oauthBlesserParams blesser.OAuthBlesserParams, caveatSelector caveats.CaveatSelector, emailClassifier *util.EmailClassifier, assetsPrefix, mountNamePrefix string) *IdentityServer {
+func NewIdentityServer(oauthProvider oauth.OAuthProvider, auditor audit.Auditor, blessingLogReader auditor.BlessingLogReader, revocationManager revocation.RevocationManager, oauthBlesserParams blesser.OAuthBlesserParams, caveatSelector caveats.CaveatSelector, assetsPrefix, mountNamePrefix string) *IdentityServer {
return &IdentityServer{
oauthProvider: oauthProvider,
auditor: auditor,
@@ -76,7 +74,6 @@
revocationManager: revocationManager,
oauthBlesserParams: oauthBlesserParams,
caveatSelector: caveatSelector,
- emailClassifier: emailClassifier,
assetsPrefix: assetsPrefix,
mountNamePrefix: mountNamePrefix,
}
@@ -166,7 +163,6 @@
MacaroonBlessingService: naming.JoinAddressName(published[0], macaroonService),
OAuthProvider: s.oauthProvider,
CaveatSelector: s.caveatSelector,
- EmailClassifier: s.emailClassifier,
AssetsPrefix: s.assetsPrefix,
}
if s.revocationManager != nil {
diff --git a/services/identity/internal/util/classify.go b/services/identity/internal/util/classify.go
deleted file mode 100644
index 40e0663..0000000
--- a/services/identity/internal/util/classify.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// 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.
-
-package util
-
-import (
- "fmt"
- "strings"
- "sync"
-)
-
-const defaultClass = "users"
-
-// EmailClassifier classifies/categorizes email addresses based on the domain.
-type EmailClassifier struct {
- mu sync.RWMutex
- m map[string]string
-}
-
-// Classify returns the classification of email.
-func (c *EmailClassifier) Classify(email string) string {
- if c == nil {
- return defaultClass
- }
- parts := strings.Split(email, "@")
- if len(parts) != 2 {
- return defaultClass
- }
- domain := parts[1]
- c.mu.RLock()
- defer c.mu.RUnlock()
- if class := c.m[domain]; len(class) > 0 {
- return class
- }
- return defaultClass
-}
-
-// Set implements flag.Value.
-//
-// value should be a comma-separated list of <domain>=<class> pairs.
-func (c *EmailClassifier) Set(value string) error {
- m := make(map[string]string)
- for _, entry := range strings.Split(value, ",") {
- pair := strings.Split(entry, "=")
- if len(pair) != 2 {
- return fmt.Errorf("invalid pair %q: must be in <domain>=<class> format", entry)
- }
- domain := strings.TrimSpace(pair[0])
- class := strings.TrimSpace(pair[1])
- if len(domain) == 0 {
- return fmt.Errorf("empty domain in %q", entry)
- }
- if len(class) == 0 {
- return fmt.Errorf("empty class in %q", entry)
- }
- m[domain] = class
- }
- c.mu.Lock()
- c.m = m
- c.mu.Unlock()
- return nil
-}
-
-// Get implements flag.Getter.
-func (c *EmailClassifier) Get() interface{} {
- return c
-}
-
-func (c *EmailClassifier) String() string {
- c.mu.RLock()
- defer c.mu.RUnlock()
- return fmt.Sprintf("%v", c.m)
-}
diff --git a/services/identity/internal/util/classify_test.go b/services/identity/internal/util/classify_test.go
deleted file mode 100644
index 859d86d..0000000
--- a/services/identity/internal/util/classify_test.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// 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.
-
-package util
-
-import (
- "flag"
- "testing"
-)
-
-func TestEmailClassifier(t *testing.T) {
- fs := flag.NewFlagSet("TestEmailClassifier", flag.PanicOnError)
- var c EmailClassifier
- fs.Var(&c, "myflag", "my usage")
- if err := fs.Parse([]string{"--myflag", "foo.com=internal,bar.com=external"}); err != nil {
- t.Fatal(err)
- }
- tests := []struct {
- in, out string
- }{
- {"batman@foo.com", "internal"},
- {"bugsbunny@foo.com.com", "users"},
- {"daffyduck@bar.com", "external"},
- {"joker@other.com", "users"},
- }
- for _, test := range tests {
- if got := c.Classify(test.in); got != test.out {
- t.Errorf("%q: Got %q, want %q", test.in, got, test.out)
- }
- }
-}
diff --git a/services/mounttable/mounttabled/doc.go b/services/mounttable/mounttabled/doc.go
new file mode 100644
index 0000000..8c86b66
--- /dev/null
+++ b/services/mounttable/mounttabled/doc.go
@@ -0,0 +1,77 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command mounttabled runs the mounttable daemon, which implements the
+v.io/v23/services/mounttable interfaces.
+
+Usage:
+ mounttabled [flags]
+
+The mounttabled flags are:
+ -acls=
+ AccessList file. Default is to allow all access.
+ -name=
+ If provided, causes the mount table to mount itself under this name. The
+ name may be absolute for a remote mount table service (e.g. "/<remote mt
+ address>//some/suffix") or could be relative to this process' default mount
+ table (e.g. "some/suffix").
+ -neighborhood-name=
+ If provided, enables sharing with the local neighborhood with the provided
+ name. The address of this mounttable will be published to the neighboorhood
+ and everything in the neighborhood will be visible on this mounttable.
+ -persist-dir=
+ Directory in which to persist permissions.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+ specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+ explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+ Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/services/mounttable/mounttabled/mounttable.go b/services/mounttable/mounttabled/mounttable.go
index 7616d2b..2bc4363 100644
--- a/services/mounttable/mounttabled/mounttable.go
+++ b/services/mounttable/mounttabled/mounttable.go
@@ -2,37 +2,50 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Daemon mounttabled implements the v.io/v23/services/mounttable interfaces.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
- "flag"
"fmt"
- "os"
"v.io/v23"
+ "v.io/v23/context"
+ "v.io/x/lib/cmdline"
"v.io/x/lib/vlog"
-
"v.io/x/ref/lib/signals"
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/roaming"
"v.io/x/ref/services/mounttable/mounttablelib"
)
-var (
- mountName = flag.String("name", "", `<name>, if provided, causes the mount table to mount itself under that name. The name may be absolute for a remote mount table service (e.g., "/<remote mt address>//some/suffix") or could be relative to this process' default mount table (e.g., "some/suffix").`)
- aclFile = flag.String("acls", "", "AccessList file. Default is to allow all access.")
- nhName = flag.String("neighborhood-name", "", `<nh name>, if provided, will enable sharing with the local neighborhood with the provided name. The address of this mounttable will be published to the neighboorhood and everything in the neighborhood will be visible on this mounttable.`)
- persistDir = flag.String("persist-dir", "", `Directory in which to persist permissions.`)
-)
+var mountName, aclFile, nhName, persistDir string
func main() {
- ctx, shutdown := v23.Init()
- defer shutdown()
+ cmdMTD.Flags.StringVar(&mountName, "name", "", `If provided, causes the mount table to mount itself under this name. The name may be absolute for a remote mount table service (e.g. "/<remote mt address>//some/suffix") or could be relative to this process' default mount table (e.g. "some/suffix").`)
+ cmdMTD.Flags.StringVar(&aclFile, "acls", "", "AccessList file. Default is to allow all access.")
+ cmdMTD.Flags.StringVar(&nhName, "neighborhood-name", "", `If provided, enables sharing with the local neighborhood with the provided name. The address of this mounttable will be published to the neighboorhood and everything in the neighborhood will be visible on this mounttable.`)
+ cmdMTD.Flags.StringVar(&persistDir, "persist-dir", "", `Directory in which to persist permissions.`)
- name, stop, err := mounttablelib.StartServers(ctx, v23.GetListenSpec(ctx), *mountName, *nhName, *aclFile, *persistDir, "mounttable")
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdMTD)
+}
+
+var cmdMTD = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runMountTableD),
+ Name: "mounttabled",
+ Short: "Runs the mounttable interface daemon",
+ Long: `
+Command mounttabled runs the mounttable daemon, which implements the
+v.io/v23/services/mounttable interfaces.
+`,
+}
+
+func runMountTableD(ctx *context.T, env *cmdline.Env, args []string) error {
+ name, stop, err := mounttablelib.StartServers(ctx, v23.GetListenSpec(ctx), mountName, nhName, aclFile, persistDir, "mounttable")
if err != nil {
- vlog.Errorf("mounttablelib.StartServers failed: %v", err)
- os.Exit(1)
+ return fmt.Errorf("mounttablelib.StartServers failed: %v", err)
}
defer stop()
@@ -42,4 +55,5 @@
// Wait until signal is received.
vlog.Info("Received signal ", <-signals.ShutdownOnSignals(ctx))
+ return nil
}
diff --git a/services/profile/profiled/doc.go b/services/profile/profiled/doc.go
new file mode 100644
index 0000000..07c2b63
--- /dev/null
+++ b/services/profile/profiled/doc.go
@@ -0,0 +1,68 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command profiled runs the profile daemon, which implements the
+v.io/x/ref/services/repository.Profile interface.
+
+Usage:
+ profiled [flags]
+
+The profiled flags are:
+ -name=
+ Name to mount the profile repository as.
+ -store=
+ Local directory to store profiles in.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+ specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+ explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+ Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/services/profile/profiled/main.go b/services/profile/profiled/main.go
index 9dd307f..9fd3b35 100644
--- a/services/profile/profiled/main.go
+++ b/services/profile/profiled/main.go
@@ -2,54 +2,70 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Daemon profiled implements the v.io/x/ref/services/repository.Profile
-// interface.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
- "flag"
+ "fmt"
"v.io/v23"
+ "v.io/v23/context"
+ "v.io/x/lib/cmdline"
"v.io/x/lib/vlog"
"v.io/x/ref/lib/security/securityflag"
"v.io/x/ref/lib/signals"
-
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/roaming"
)
-var (
- name = flag.String("name", "", "name to mount the profile repository as")
- store = flag.String("store", "", "local directory to store profiles in")
-)
+var name, store string
func main() {
- ctx, shutdown := v23.Init()
- defer shutdown()
+ cmdProfileD.Flags.StringVar(&name, "name", "", "Name to mount the profile repository as.")
+ cmdProfileD.Flags.StringVar(&store, "store", "", "Local directory to store profiles in.")
- if *store == "" {
- vlog.Fatalf("Specify a directory for storing profiles using --store=<name>")
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdProfileD)
+}
+
+var cmdProfileD = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runProfileD),
+ Name: "profiled",
+ Short: "Runs the profile daemon.",
+ Long: `
+Command profiled runs the profile daemon, which implements the
+v.io/x/ref/services/repository.Profile interface.
+`,
+}
+
+func runProfileD(ctx *context.T, env *cmdline.Env, args []string) error {
+ if store == "" {
+ return env.UsageErrorf("Specify a directory for storing profiles using --store=<name>")
}
server, err := v23.NewServer(ctx)
if err != nil {
- vlog.Fatalf("NewServer() failed: %v", err)
+ return fmt.Errorf("NewServer() failed: %v", err)
}
- dispatcher, err := NewDispatcher(*store, securityflag.NewAuthorizerOrDie())
+ dispatcher, err := NewDispatcher(store, securityflag.NewAuthorizerOrDie())
if err != nil {
- vlog.Fatalf("NewDispatcher() failed: %v", err)
+ return fmt.Errorf("NewDispatcher() failed: %v", err)
}
ls := v23.GetListenSpec(ctx)
endpoint, err := server.Listen(ls)
if err != nil {
- vlog.Fatalf("Listen(%s) failed: %v", ls, err)
+ return fmt.Errorf("Listen(%s) failed: %v", ls, err)
}
- if err := server.ServeDispatcher(*name, dispatcher); err != nil {
- vlog.Fatalf("ServeDispatcher(%v) failed: %v", *name, err)
+ if err := server.ServeDispatcher(name, dispatcher); err != nil {
+ return fmt.Errorf("ServeDispatcher(%v) failed: %v", name, err)
}
vlog.Infof("Profile repository running at endpoint=%q", endpoint)
// Wait until shutdown.
<-signals.ShutdownOnSignals(ctx)
+ return nil
}
diff --git a/services/proxy/proxyd/doc.go b/services/proxy/proxyd/doc.go
new file mode 100644
index 0000000..7fd0915
--- /dev/null
+++ b/services/proxy/proxyd/doc.go
@@ -0,0 +1,77 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command proxyd is a daemon that listens for connections from Vanadium services
+(typically behind NATs) and proxies these services to the outside world.
+
+Usage:
+ proxyd [flags]
+
+The proxyd flags are:
+ -access-list=
+ Blessings that are authorized to listen via the proxy. JSON-encoded
+ representation of access.AccessList. An empty string implies the default
+ authorization policy.
+ -healthz-address=
+ Network address on which the HTTP healthz server runs. It is intended to be
+ used with a load balancer. The load balancer must be able to reach this
+ address in order to verify that the proxy server is running.
+ -name=
+ Name to mount the proxy as.
+ -published-address=
+ DEPRECATED - the proxy now uses listenspecs and the address chooser
+ mechanism.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+ specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+ explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+ Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/services/proxy/proxyd/main.go b/services/proxy/proxyd/main.go
index 920c7ad..2804ef6 100644
--- a/services/proxy/proxyd/main.go
+++ b/services/proxy/proxyd/main.go
@@ -2,51 +2,65 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Daemon proxyd listens for connections from Vanadium services (typically
-// behind NATs) and proxies these services to the outside world.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
"bytes"
"encoding/json"
- "flag"
"fmt"
"net/http"
"time"
"v.io/v23"
+ "v.io/v23/context"
"v.io/v23/rpc"
"v.io/v23/security"
"v.io/v23/security/access"
+ "v.io/x/lib/cmdline"
"v.io/x/lib/vlog"
-
"v.io/x/ref/lib/signals"
+ "v.io/x/ref/lib/v23cmd"
"v.io/x/ref/runtime/factories/static"
)
-var (
- pubAddress = flag.String("published-address", "", "deprecated - the proxy now uses listenspecs and the address chooser mechanism")
- healthzAddr = flag.String("healthz-address", "", "Network address on which the HTTP healthz server runs. It is intended to be used with a load balancer. The load balancer must be able to reach this address in order to verify that the proxy server is running")
- name = flag.String("name", "", "Name to mount the proxy as")
- acl = flag.String("access-list", "", "Blessings that are authorized to listen via the proxy. JSON-encoded representation of access.AccessList. An empty string implies the default authorization policy.")
-)
+var pubAddress, healthzAddr, name, acl string
func main() {
- ctx, shutdown := v23.Init()
- defer shutdown()
+ cmdProxyD.Flags.StringVar(&pubAddress, "published-address", "", "DEPRECATED - the proxy now uses listenspecs and the address chooser mechanism.")
+ cmdProxyD.Flags.StringVar(&healthzAddr, "healthz-address", "", "Network address on which the HTTP healthz server runs. It is intended to be used with a load balancer. The load balancer must be able to reach this address in order to verify that the proxy server is running.")
+ cmdProxyD.Flags.StringVar(&name, "name", "", "Name to mount the proxy as.")
+ cmdProxyD.Flags.StringVar(&acl, "access-list", "", "Blessings that are authorized to listen via the proxy. JSON-encoded representation of access.AccessList. An empty string implies the default authorization policy.")
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdProxyD)
+}
+
+var cmdProxyD = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runProxyD),
+ Name: "proxyd",
+ Short: "Proxies services to the outside world",
+ Long: `
+Command proxyd is a daemon that listens for connections from Vanadium services
+(typically behind NATs) and proxies these services to the outside world.
+`,
+}
+
+func runProxyD(ctx *context.T, env *cmdline.Env, args []string) error {
listenSpec := v23.GetListenSpec(ctx)
if len(listenSpec.Addrs) != 1 {
- vlog.Fatalf("proxyd can only listen on one address: %v", listenSpec.Addrs)
+ return env.UsageErrorf("proxyd can only listen on one address: %v", listenSpec.Addrs)
}
if listenSpec.Proxy != "" {
- vlog.Fatalf("proxyd cannot listen through another proxy")
+ return env.UsageErrorf("proxyd cannot listen through another proxy")
}
var authorizer security.Authorizer
- if len(*acl) > 0 {
+ if len(acl) > 0 {
var list access.AccessList
- if err := json.NewDecoder(bytes.NewBufferString(*acl)).Decode(&list); err != nil {
- vlog.Fatalf("invalid --access-list: %v", err)
+ if err := json.NewDecoder(bytes.NewBufferString(acl)).Decode(&list); err != nil {
+ return env.UsageErrorf("invalid -access-list: %v", err)
}
// Always add ourselves, for the the reserved methods server
// started below.
@@ -55,13 +69,13 @@
authorizer = list
}
- proxyShutdown, proxyEndpoint, err := static.NewProxy(ctx, listenSpec, authorizer, *name)
+ proxyShutdown, proxyEndpoint, err := static.NewProxy(ctx, listenSpec, authorizer, name)
if err != nil {
- vlog.Fatal(err)
+ return err
}
defer proxyShutdown()
- if len(*name) > 0 {
+ if len(name) > 0 {
// Print out a directly accessible name for the proxy table so
// that integration tests can reliably read it from stdout.
fmt.Printf("NAME=%s\n", proxyEndpoint.Name())
@@ -69,30 +83,31 @@
fmt.Printf("Proxy listening on %s\n", proxyEndpoint)
}
- if len(*healthzAddr) != 0 {
- go startHealthzServer(*healthzAddr)
+ if len(healthzAddr) != 0 {
+ go startHealthzServer(healthzAddr)
}
// Start an RPC Server that listens through the proxy itself. This
// server will serve reserved methods only.
server, err := v23.NewServer(ctx)
if err != nil {
- vlog.Fatalf("NewServer failed: %v", err)
+ return fmt.Errorf("NewServer failed: %v", err)
}
defer server.Stop()
ls := rpc.ListenSpec{Proxy: proxyEndpoint.Name()}
if _, err := server.Listen(ls); err != nil {
- vlog.Fatalf("Listen(%v) failed: %v", ls, err)
+ return fmt.Errorf("Listen(%v) failed: %v", ls, err)
}
var monitoringName string
- if len(*name) > 0 {
- monitoringName = *name + "-mon"
+ if len(name) > 0 {
+ monitoringName = name + "-mon"
}
if err := server.ServeDispatcher(monitoringName, &nilDispatcher{}); err != nil {
- vlog.Fatalf("ServeDispatcher(%v) failed: %v", monitoringName, err)
+ return fmt.Errorf("ServeDispatcher(%v) failed: %v", monitoringName, err)
}
<-signals.ShutdownOnSignals(ctx)
+ return nil
}
type nilDispatcher struct{}
diff --git a/services/role/roled/doc.go b/services/role/roled/doc.go
new file mode 100644
index 0000000..7f0ea03
--- /dev/null
+++ b/services/role/roled/doc.go
@@ -0,0 +1,67 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command roled runs the Role interface daemon.
+
+Usage:
+ roled [flags]
+
+The roled flags are:
+ -config-dir=
+ The directory where the role configuration files are stored.
+ -name=
+ The name to publish for this service.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+ specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+ explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+ Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/services/role/roled/main.go b/services/role/roled/main.go
index aea1ab7..42bce3f 100644
--- a/services/role/roled/main.go
+++ b/services/role/roled/main.go
@@ -2,57 +2,67 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Daemon roled implements the Role interface.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
- "flag"
"fmt"
- "os"
"v.io/v23"
-
+ "v.io/v23/context"
+ "v.io/x/lib/cmdline"
"v.io/x/lib/vlog"
"v.io/x/ref/lib/signals"
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/static"
irole "v.io/x/ref/services/role/roled/internal"
)
-var (
- configDir = flag.String("config-dir", "", "The directory where the role configuration files are stored.")
- name = flag.String("name", "", "The name to publish for this service.")
-)
+var configDir, name string
func main() {
- ctx, shutdown := v23.Init()
- defer shutdown()
+ cmdRoleD.Flags.StringVar(&configDir, "config-dir", "", "The directory where the role configuration files are stored.")
+ cmdRoleD.Flags.StringVar(&name, "name", "", "The name to publish for this service.")
- if len(*configDir) == 0 {
- fmt.Fprintf(os.Stderr, "--config-dir must be specified\n")
- os.Exit(1)
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdRoleD)
+}
+
+var cmdRoleD = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runRoleD),
+ Name: "roled",
+ Short: "Runs the Role interface daemon.",
+ Long: "Command roled runs the Role interface daemon.",
+}
+
+func runRoleD(ctx *context.T, env *cmdline.Env, args []string) error {
+ if len(configDir) == 0 {
+ return env.UsageErrorf("-config-dir must be specified")
}
- if len(*name) == 0 {
- fmt.Fprintf(os.Stderr, "--name must be specified\n")
- os.Exit(1)
+ if len(name) == 0 {
+ return env.UsageErrorf("-name must be specified")
}
server, err := v23.NewServer(ctx)
if err != nil {
- vlog.Fatalf("NewServer failed: %v", err)
+ return fmt.Errorf("NewServer failed: %v", err)
}
listenSpec := v23.GetListenSpec(ctx)
eps, err := server.Listen(listenSpec)
if err != nil {
- vlog.Fatalf("Listen(%v) failed: %v", listenSpec, err)
+ return fmt.Errorf("Listen(%v) failed: %v", listenSpec, err)
}
vlog.Infof("Listening on: %q", eps)
- if err := server.ServeDispatcher(*name, irole.NewDispatcher(*configDir, *name)); err != nil {
- vlog.Fatalf("ServeDispatcher(%q) failed: %v", *name, err)
+ if err := server.ServeDispatcher(name, irole.NewDispatcher(configDir, name)); err != nil {
+ return fmt.Errorf("ServeDispatcher(%q) failed: %v", name, err)
}
- if len(*name) > 0 {
- fmt.Printf("NAME=%s\n", *name)
+ if len(name) > 0 {
+ fmt.Printf("NAME=%s\n", name)
} else if len(eps) > 0 {
fmt.Printf("NAME=%s\n", eps[0].Name())
}
<-signals.ShutdownOnSignals(ctx)
+ return nil
}
diff --git a/services/wspr/browsprd/main_nacl.go b/services/wspr/browsprd/main_nacl.go
index dcc23c3..4d07423 100644
--- a/services/wspr/browsprd/main_nacl.go
+++ b/services/wspr/browsprd/main_nacl.go
@@ -21,6 +21,7 @@
vsecurity "v.io/x/ref/lib/security"
_ "v.io/x/ref/runtime/factories/chrome"
"v.io/x/ref/runtime/internal/lib/websocket"
+ "v.io/x/ref/services/wspr/internal/app"
"v.io/x/ref/services/wspr/internal/browspr"
"v.io/x/ref/services/wspr/internal/channel/channel_nacl"
"v.io/x/ref/services/wspr/internal/rpc/server"
@@ -298,14 +299,14 @@
// HandleBrowsprMessage handles one-way messages of the type "browsprMsg" by
// sending them to browspr's handler.
-func (inst *browsprInstance) HandleBrowsprMessage(instanceId int32, origin string, message ppapi.Var) error {
- str, err := message.AsString()
+func (inst *browsprInstance) HandleBrowsprMessage(instanceId int32, origin string, varMsg ppapi.Var) error {
+ msg, err := varToMessage(varMsg)
if err != nil {
- return fmt.Errorf("Error while converting message to string: %v", err)
+ return fmt.Errorf("Invalid message: %v", err)
}
- vlog.VI(1).Infof("Calling browspr's HandleMessage: instanceId %d origin %s message %s", instanceId, origin, str)
- if err := inst.browspr.HandleMessage(instanceId, origin, str); err != nil {
+ vlog.VI(1).Infof("Calling browspr's HandleMessage: instanceId %d origin %s message %s", instanceId, origin, msg)
+ if err := inst.browspr.HandleMessage(instanceId, origin, msg); err != nil {
return fmt.Errorf("Error while handling message in browspr: %v", err)
}
return nil
@@ -415,3 +416,25 @@
func (*browsprInstance) MouseLockLost() {
vlog.VI(2).Infof("Got to MouseLockLost()")
}
+
+func varToMessage(v ppapi.Var) (app.Message, error) {
+ var msg app.Message
+ id, err := v.LookupIntValuedKey("id")
+ if err != nil {
+ return msg, err
+ }
+ ty, err := v.LookupIntValuedKey("type")
+ if err != nil {
+ return msg, err
+ }
+ data, err := v.LookupStringValuedKey("data")
+ if err != nil {
+ // OK for message to have empty data.
+ data = ""
+ }
+
+ msg.Id = int32(id)
+ msg.Data = data
+ msg.Type = app.MessageType(ty)
+ return msg, nil
+}
diff --git a/services/wspr/internal/app/app.go b/services/wspr/internal/app/app.go
index de2ebae..1063717 100644
--- a/services/wspr/internal/app/app.go
+++ b/services/wspr/internal/app/app.go
@@ -167,7 +167,7 @@
if blessings, ok := item.(security.Blessings); ok {
item = principal.ConvertBlessingsToHandle(blessings, c.blessingsCache.GetOrAddHandle(blessings))
}
- vomItem, err := lib.VomEncode(item)
+ vomItem, err := lib.HexVomEncode(item)
if err != nil {
w.Error(verror.New(marshallingError, ctx, item, err))
continue
@@ -442,7 +442,7 @@
)
func (l *localCall) Send(item interface{}) error {
- vomItem, err := lib.VomEncode(item)
+ vomItem, err := lib.HexVomEncode(item)
if err != nil {
err = verror.New(marshallingError, l.ctx, item, err)
l.w.Error(err)
@@ -732,7 +732,7 @@
// parseVeyronRequest parses a json rpc request into a RpcRequest object.
func (c *Controller) parseVeyronRequest(data string) (*RpcRequest, error) {
var msg RpcRequest
- if err := lib.VomDecode(data, &msg); err != nil {
+ if err := lib.HexVomDecode(data, &msg); err != nil {
return nil, err
}
vlog.VI(2).Infof("RpcRequest: %s.%s(..., streaming=%v)", msg.Name, msg.Method, msg.IsStreaming)
diff --git a/services/wspr/internal/app/app.go.orig b/services/wspr/internal/app/app.go.orig
index fcefaa8..7243674 100644
--- a/services/wspr/internal/app/app.go.orig
+++ b/services/wspr/internal/app/app.go.orig
@@ -161,7 +161,7 @@
if blessings, ok := item.(security.Blessings); ok {
item = principal.ConvertBlessingsToHandle(blessings, c.blessingsCache.GetOrAddHandle(blessings))
}
- vomItem, err := lib.VomEncode(item)
+ vomItem, err := lib.HexVomEncode(item)
if err != nil {
w.Error(verror.New(marshallingError, ctx, item, err))
continue
@@ -205,7 +205,7 @@
OutArgs: results,
TraceResponse: vtrace.GetResponse(ctx),
}
- encoded, err := lib.VomEncode(response)
+ encoded, err := lib.HexVomEncode(response)
if err != nil {
w.Error(err)
return
@@ -430,7 +430,7 @@
)
func (l *localCall) Send(item interface{}) error {
- vomItem, err := lib.VomEncode(item)
+ vomItem, err := lib.HexVomEncode(item)
if err != nil {
err = verror.New(marshallingError, l.ctx, item, err)
l.w.Error(err)
@@ -717,7 +717,7 @@
// parseVeyronRequest parses a json rpc request into a RpcRequest object.
func (c *Controller) parseVeyronRequest(data string) (*RpcRequest, error) {
var msg RpcRequest
- if err := lib.VomDecode(data, &msg); err != nil {
+ if err := lib.HexVomDecode(data, &msg); err != nil {
return nil, err
}
vlog.VI(2).Infof("RpcRequest: %s.%s(..., streaming=%v)", msg.Name, msg.Method, msg.IsStreaming)
diff --git a/services/wspr/internal/app/app_test.go b/services/wspr/internal/app/app_test.go
index 991f2dc..ae7bf91 100644
--- a/services/wspr/internal/app/app_test.go
+++ b/services/wspr/internal/app/app_test.go
@@ -202,7 +202,7 @@
}
go func() {
for _, value := range testCase.streamingInputs {
- controller.SendOnStream(0, lib.VomEncodeOrDie(value), &writer)
+ controller.SendOnStream(0, lib.HexVomEncodeOrDie(value), &writer)
}
controller.CloseStream(0)
}()
@@ -223,7 +223,7 @@
}
func makeRPCResponse(outArgs ...*vdl.Value) string {
- return lib.VomEncodeOrDie(RpcResponse{
+ return lib.HexVomEncodeOrDie(RpcResponse{
OutArgs: outArgs,
TraceResponse: vtrace.Response{},
})
@@ -259,19 +259,19 @@
numOutArgs: 1,
expectedStream: []lib.Response{
lib.Response{
- Message: lib.VomEncodeOrDie(int32(1)),
+ Message: lib.HexVomEncodeOrDie(int32(1)),
Type: lib.ResponseStream,
},
lib.Response{
- Message: lib.VomEncodeOrDie(int32(3)),
+ Message: lib.HexVomEncodeOrDie(int32(3)),
Type: lib.ResponseStream,
},
lib.Response{
- Message: lib.VomEncodeOrDie(int32(6)),
+ Message: lib.HexVomEncodeOrDie(int32(6)),
Type: lib.ResponseStream,
},
lib.Response{
- Message: lib.VomEncodeOrDie(int32(10)),
+ Message: lib.HexVomEncodeOrDie(int32(10)),
Type: lib.ResponseStream,
},
lib.Response{
@@ -312,7 +312,17 @@
if err != nil {
return nil, fmt.Errorf("unable to start mounttable: %v", err)
}
- proxySpec := rpc.ListenSpec{Addrs: rpc.ListenAddrs{{"tcp", "127.0.0.1:0"}}}
+ proxySpec := rpc.ListenSpec{
+ Addrs: rpc.ListenAddrs{
+ // This '0' label is required by go vet.
+ // TODO(suharshs): Remove the '0' label once []ListenAddr is used
+ // instead of ListenAdders.
+ 0: {
+ Protocol: "tcp",
+ Address: "127.0.0.1:0",
+ },
+ },
+ }
proxyShutdown, proxyEndpoint, err := generic.NewProxy(ctx, proxySpec, security.AllowEveryone())
if err != nil {
return nil, fmt.Errorf("unable to start proxy: %v", err)
@@ -379,7 +389,7 @@
vomClientStream := []string{}
for _, m := range testCase.clientStream {
- vomClientStream = append(vomClientStream, lib.VomEncodeOrDie(m))
+ vomClientStream = append(vomClientStream, lib.HexVomEncodeOrDie(m))
}
mock := &mockJSServer{
t: t,
diff --git a/services/wspr/internal/app/granter.go b/services/wspr/internal/app/granter.go
index 40df476..bd9d4a9 100644
--- a/services/wspr/internal/app/granter.go
+++ b/services/wspr/internal/app/granter.go
@@ -29,7 +29,7 @@
GranterHandle: g.granterHandle,
Call: server.ConvertSecurityCall(g.c, ctx, call, true),
}
- encoded, err := lib.VomEncode(request)
+ encoded, err := lib.HexVomEncode(request)
if err != nil {
return security.Blessings{}, err
}
@@ -64,7 +64,7 @@
func (g *granterStream) Send(item interface{}) error {
dataString := item.(string)
var gr *GranterResponse
- if err := lib.VomDecode(dataString, &gr); err != nil {
+ if err := lib.HexVomDecode(dataString, &gr); err != nil {
return fmt.Errorf("error decoding granter response: %v", err)
}
g.c <- gr
diff --git a/services/wspr/internal/app/mock_jsServer_test.go b/services/wspr/internal/app/mock_jsServer_test.go
index 1113022..1c3bf96 100644
--- a/services/wspr/internal/app/mock_jsServer_test.go
+++ b/services/wspr/internal/app/mock_jsServer_test.go
@@ -14,6 +14,7 @@
"v.io/v23/vdl"
"v.io/v23/vdlroot/signature"
+ "v.io/v23/verror"
"v.io/v23/vom"
"v.io/x/ref/internal/reflectutil"
"v.io/x/ref/services/wspr/internal/lib"
@@ -73,13 +74,16 @@
return fmt.Errorf("Unknown message type: %d", responseType)
}
-func internalErrJSON(args interface{}) string {
- return fmt.Sprintf(`{"err": {
- "idAction": {
- "id": "v.io/v23/verror.Internal",
- "action": 0
- },
- "paramList": ["%v"]}, "results":[null]}`, args)
+func internalErr(args interface{}) string {
+ err := verror.E{
+ ID: verror.ID("v.io/v23/verror.Internal"),
+ Action: verror.ActionCode(0),
+ ParamList: []interface{}{args},
+ }
+
+ return lib.HexVomEncodeOrDie(server.LookupReply{
+ Err: err,
+ })
}
func (m *mockJSServer) Error(err error) {
@@ -108,26 +112,23 @@
}()
m.controllerReady.RLock()
defer m.controllerReady.RUnlock()
+
msg, err := normalize(v)
if err != nil {
- m.controller.HandleLookupResponse(m.flowCount, internalErrJSON(err))
+ m.controller.HandleLookupResponse(m.flowCount, internalErr(err))
return nil
}
expected := map[string]interface{}{"serverId": 0.0, "suffix": "adder"}
if !reflect.DeepEqual(msg, expected) {
- m.controller.HandleLookupResponse(m.flowCount, internalErrJSON(fmt.Sprintf("got: %v, want: %v", msg, expected)))
+ m.controller.HandleLookupResponse(m.flowCount, internalErr(fmt.Sprintf("got: %v, want: %v", msg, expected)))
return nil
}
- bytes, err := json.Marshal(map[string]interface{}{
- "handle": 0,
- "signature": lib.VomEncodeOrDie(m.serviceSignature),
- "hasAuthorizer": m.hasAuthorizer,
+ lookupReply := lib.HexVomEncodeOrDie(server.LookupReply{
+ Handle: 0,
+ Signature: m.serviceSignature,
+ HasAuthorizer: m.hasAuthorizer,
})
- if err != nil {
- m.controller.HandleLookupResponse(m.flowCount, internalErrJSON(fmt.Sprintf("failed to serialize %v", err)))
- return nil
- }
- m.controller.HandleLookupResponse(m.flowCount, string(bytes))
+ m.controller.HandleLookupResponse(m.flowCount, lookupReply)
return nil
}
@@ -147,62 +148,58 @@
m.hasCalledAuth = true
if !m.hasAuthorizer {
- m.controller.HandleAuthResponse(m.flowCount, internalErrJSON("unexpected auth request"))
+ m.controller.HandleAuthResponse(m.flowCount, internalErr("unexpected auth request"))
return nil
}
var msg server.AuthRequest
- if err := lib.VomDecode(v.(string), &msg); err != nil {
- m.controller.HandleAuthResponse(m.flowCount, internalErrJSON(fmt.Sprintf("error decoding %v:", err)))
+ if err := lib.HexVomDecode(v.(string), &msg); err != nil {
+ m.controller.HandleAuthResponse(m.flowCount, internalErr(fmt.Sprintf("error decoding %v:", err)))
return nil
}
if msg.Handle != 0 {
- m.controller.HandleAuthResponse(m.flowCount, internalErrJSON(fmt.Sprintf("unexpected handled: %v", msg.Handle)))
+ m.controller.HandleAuthResponse(m.flowCount, internalErr(fmt.Sprintf("unexpected handled: %v", msg.Handle)))
return nil
}
call := msg.Call
if field, got, want := "Method", call.Method, lib.LowercaseFirstCharacter(m.method); got != want {
- m.controller.HandleAuthResponse(m.flowCount, internalErrJSON(fmt.Sprintf("unexpected value for %s: got %v, want %v", field, got, want)))
+ m.controller.HandleAuthResponse(m.flowCount, internalErr(fmt.Sprintf("unexpected value for %s: got %v, want %v", field, got, want)))
return nil
}
if field, got, want := "Suffix", call.Suffix, "adder"; got != want {
- m.controller.HandleAuthResponse(m.flowCount, internalErrJSON(fmt.Sprintf("unexpected value for %s: got %v, want %v", field, got, want)))
+ m.controller.HandleAuthResponse(m.flowCount, internalErr(fmt.Sprintf("unexpected value for %s: got %v, want %v", field, got, want)))
return nil
}
// We expect localBlessings and remoteBlessings to be set and the publicKey be a string
if !validateBlessing(call.LocalBlessings) {
- m.controller.HandleAuthResponse(m.flowCount, internalErrJSON(fmt.Sprintf("bad localblessing:%v", call.LocalBlessings)))
+ m.controller.HandleAuthResponse(m.flowCount, internalErr(fmt.Sprintf("bad localblessing:%v", call.LocalBlessings)))
return nil
}
if !validateBlessing(call.RemoteBlessings) {
- m.controller.HandleAuthResponse(m.flowCount, internalErrJSON(fmt.Sprintf("bad remoteblessing:%v", call.RemoteBlessings)))
+ m.controller.HandleAuthResponse(m.flowCount, internalErr(fmt.Sprintf("bad remoteblessing:%v", call.RemoteBlessings)))
return nil
}
// We expect endpoints to be set
if !validateEndpoint(call.LocalEndpoint) {
- m.controller.HandleAuthResponse(m.flowCount, internalErrJSON(fmt.Sprintf("bad endpoint:%v", call.LocalEndpoint)))
+ m.controller.HandleAuthResponse(m.flowCount, internalErr(fmt.Sprintf("bad endpoint:%v", call.LocalEndpoint)))
return nil
}
if !validateEndpoint(call.RemoteEndpoint) {
- m.controller.HandleAuthResponse(m.flowCount, internalErrJSON(fmt.Sprintf("bad endpoint:%v", call.RemoteEndpoint)))
+ m.controller.HandleAuthResponse(m.flowCount, internalErr(fmt.Sprintf("bad endpoint:%v", call.RemoteEndpoint)))
return nil
}
- bytes, err := json.Marshal(map[string]interface{}{
- "err": m.authError,
+ authReply := lib.HexVomEncodeOrDie(server.AuthReply{
+ Err: m.authError,
})
- if err != nil {
- m.controller.HandleAuthResponse(m.flowCount, internalErrJSON(fmt.Sprintf("failed to serialize %v", err)))
- return nil
- }
- m.controller.HandleAuthResponse(m.flowCount, string(bytes))
+ m.controller.HandleAuthResponse(m.flowCount, authReply)
return nil
}
@@ -212,23 +209,23 @@
}()
if m.hasCalledAuth != m.hasAuthorizer {
- m.controller.HandleServerResponse(m.flowCount, internalErrJSON("authorizer hasn't been called yet"))
+ m.controller.HandleServerResponse(m.flowCount, internalErr("authorizer hasn't been called yet"))
return nil
}
var msg server.ServerRpcRequest
- if err := lib.VomDecode(v.(string), &msg); err != nil {
- m.controller.HandleServerResponse(m.flowCount, internalErrJSON(err))
+ if err := lib.HexVomDecode(v.(string), &msg); err != nil {
+ m.controller.HandleServerResponse(m.flowCount, internalErr(err))
return nil
}
if field, got, want := "Method", msg.Method, lib.LowercaseFirstCharacter(m.method); got != want {
- m.controller.HandleServerResponse(m.flowCount, internalErrJSON(fmt.Sprintf("unexpected value for %s: got %v, want %v", field, got, want)))
+ m.controller.HandleServerResponse(m.flowCount, internalErr(fmt.Sprintf("unexpected value for %s: got %v, want %v", field, got, want)))
return nil
}
if field, got, want := "Handle", msg.Handle, int32(0); got != want {
- m.controller.HandleServerResponse(m.flowCount, internalErrJSON(fmt.Sprintf("unexpected value for %s: got %v, want %v", field, got, want)))
+ m.controller.HandleServerResponse(m.flowCount, internalErr(fmt.Sprintf("unexpected value for %s: got %v, want %v", field, got, want)))
return nil
}
@@ -239,18 +236,18 @@
}
}
if field, got, want := "Args", vals, m.inArgs; !reflectutil.DeepEqual(got, want, &reflectutil.DeepEqualOpts{SliceEqNilEmpty: true}) {
- m.controller.HandleServerResponse(m.flowCount, internalErrJSON(fmt.Sprintf("unexpected value for %s: got %v, want %v", field, got, want)))
+ m.controller.HandleServerResponse(m.flowCount, internalErr(fmt.Sprintf("unexpected value for %s: got %v, want %v", field, got, want)))
return nil
}
call := msg.Call.SecurityCall
if field, got, want := "Suffix", call.Suffix, "adder"; got != want {
- m.controller.HandleServerResponse(m.flowCount, internalErrJSON(fmt.Sprintf("unexpected value for %s: got %v, want %v", field, got, want)))
+ m.controller.HandleServerResponse(m.flowCount, internalErr(fmt.Sprintf("unexpected value for %s: got %v, want %v", field, got, want)))
return nil
}
if !validateBlessing(call.RemoteBlessings) {
- m.controller.HandleServerResponse(m.flowCount, internalErrJSON(fmt.Sprintf("bad Remoteblessing:%v", call.RemoteBlessings)))
+ m.controller.HandleServerResponse(m.flowCount, internalErr(fmt.Sprintf("bad Remoteblessing:%v", call.RemoteBlessings)))
return nil
}
@@ -288,7 +285,7 @@
defer m.sender.Done()
m.controllerReady.RLock()
for _, v := range m.serverStream {
- m.controller.SendOnStream(m.rpcFlow, lib.VomEncodeOrDie(v), m)
+ m.controller.SendOnStream(m.rpcFlow, lib.HexVomEncodeOrDie(v), m)
}
m.controllerReady.RUnlock()
}
@@ -314,12 +311,9 @@
Results: []*vdl.Value{m.finalResponse},
Err: m.finalError,
}
- vomReply, err := lib.VomEncode(reply)
- if err != nil {
- m.t.Fatalf("Failed to serialize the reply: %v", err)
- }
+
m.controllerReady.RLock()
- m.controller.HandleServerResponse(m.rpcFlow, vomReply)
+ m.controller.HandleServerResponse(m.rpcFlow, lib.HexVomEncodeOrDie(reply))
m.controllerReady.RUnlock()
return nil
}
diff --git a/services/wspr/internal/app/stream.go b/services/wspr/internal/app/stream.go
index 1a8c653..74852c7 100644
--- a/services/wspr/internal/app/stream.go
+++ b/services/wspr/internal/app/stream.go
@@ -81,7 +81,7 @@
config := <-os.initChan
for msg := range os.messages {
var item interface{}
- if err := lib.VomDecode(msg.data, &item); err != nil {
+ if err := lib.HexVomDecode(msg.data, &item); err != nil {
msg.writer.Error(fmt.Errorf("failed to decode stream arg from %v: %v", msg.data, err))
break
}
diff --git a/services/wspr/internal/browspr/browspr.go b/services/wspr/internal/browspr/browspr.go
index 5052ed5..8971fc3 100644
--- a/services/wspr/internal/browspr/browspr.go
+++ b/services/wspr/internal/browspr/browspr.go
@@ -17,6 +17,7 @@
"v.io/v23/vtrace"
"v.io/x/lib/vlog"
"v.io/x/ref/services/wspr/internal/account"
+ "v.io/x/ref/services/wspr/internal/app"
"v.io/x/ref/services/wspr/internal/principal"
)
@@ -92,7 +93,7 @@
// HandleMessage handles most messages from javascript and forwards them to a
// Controller.
-func (b *Browspr) HandleMessage(instanceId int32, origin, msg string) error {
+func (b *Browspr) HandleMessage(instanceId int32, origin string, msg app.Message) error {
b.mu.Lock()
p, ok := b.activeInstances[instanceId]
b.mu.Unlock()
diff --git a/services/wspr/internal/browspr/browspr_test.go b/services/wspr/internal/browspr/browspr_test.go
index 7f54006..5a69168 100644
--- a/services/wspr/internal/browspr/browspr_test.go
+++ b/services/wspr/internal/browspr/browspr_test.go
@@ -7,7 +7,6 @@
import (
"bytes"
"encoding/hex"
- "encoding/json"
"strings"
"testing"
"time"
@@ -83,7 +82,17 @@
ctx, shutdown := test.InitForTest()
defer shutdown()
- proxySpec := rpc.ListenSpec{Addrs: rpc.ListenAddrs{{"tcp", "127.0.0.1:0"}}}
+ proxySpec := rpc.ListenSpec{
+ Addrs: rpc.ListenAddrs{
+ // This '0' label is required by go vet.
+ // TODO(suharshs): Remove the '0' label once []ListenAddr is used
+ // instead of ListenAdders.
+ 0: {
+ Protocol: "tcp",
+ Address: "127.0.0.1:0",
+ },
+ },
+ }
proxyShutdown, proxyEndpoint, err := generic.NewProxy(ctx, proxySpec, security.AllowEveryone())
if err != nil {
t.Fatalf("Failed to start proxy: %v", err)
@@ -195,13 +204,10 @@
}
vomRPC := hex.EncodeToString(buf.Bytes())
- msg, err := json.Marshal(app.Message{
+ msg := app.Message{
Id: 1,
Data: vomRPC,
Type: app.VeyronRequestMessage,
- })
- if err != nil {
- t.Fatalf("Failed to marshall app message to json: %v", err)
}
createInstanceMessage := CreateInstanceMessage{
@@ -212,7 +218,7 @@
}
_, err = browspr.HandleCreateInstanceRpc(vdl.ValueOf(createInstanceMessage))
- err = browspr.HandleMessage(msgInstanceId, msgOrigin, string(msg))
+ err = browspr.HandleMessage(msgInstanceId, msgOrigin, msg)
if err != nil {
t.Fatalf("Error while handling message: %v", err)
}
@@ -227,7 +233,7 @@
}
var outMsg app.Message
- if err := lib.VomDecode(receivedMsg, &outMsg); err != nil {
+ if err := lib.HexVomDecode(receivedMsg, &outMsg); err != nil {
t.Fatalf("Failed to unmarshall outgoing message: %v", err)
}
if outMsg.Id != int32(1) {
@@ -238,7 +244,7 @@
}
var responseMsg lib.Response
- if err := lib.VomDecode(outMsg.Data, &responseMsg); err != nil {
+ if err := lib.HexVomDecode(outMsg.Data, &responseMsg); err != nil {
t.Fatalf("Failed to unmarshall outgoing response: %v", err)
}
if responseMsg.Type != lib.ResponseFinal {
@@ -250,7 +256,7 @@
t.Errorf("Got unexpected response message body of type %T, expected type string", responseMsg.Message)
}
var result app.RpcResponse
- if err := lib.VomDecode(outArg, &result); err != nil {
+ if err := lib.HexVomDecode(outArg, &result); err != nil {
t.Errorf("Failed to vom decode args from %v: %v", outArg, err)
}
if got, want := result.OutArgs[0], vdl.StringValue("[InputValue]"); !vdl.EqualValue(got, want) {
diff --git a/services/wspr/internal/browspr/pipe.go b/services/wspr/internal/browspr/pipe.go
index 138e3ef..34280b4 100644
--- a/services/wspr/internal/browspr/pipe.go
+++ b/services/wspr/internal/browspr/pipe.go
@@ -5,9 +5,6 @@
package browspr
import (
- "encoding/json"
- "fmt"
-
"v.io/x/lib/vlog"
"v.io/x/ref/services/wspr/internal/app"
"v.io/x/ref/services/wspr/internal/lib"
@@ -85,16 +82,7 @@
p.controller.Cleanup()
}
-func (p *pipe) handleMessage(jsonMsg string) error {
- var msg app.Message
- if err := json.Unmarshal([]byte(jsonMsg), &msg); err != nil {
- fullErr := fmt.Errorf("Can't unmarshall message: %s error: %v", jsonMsg, err)
- // Send the failed to unmarshal error to the client.
- errWriter := &postMessageWriter{p: p}
- errWriter.Error(fullErr)
- return fullErr
- }
-
+func (p *pipe) handleMessage(msg app.Message) error {
writer := p.createWriter(msg.Id)
p.controller.HandleIncomingMessage(msg, writer)
return nil
diff --git a/services/wspr/internal/lib/vom.go b/services/wspr/internal/lib/hex_vom.go
similarity index 89%
rename from services/wspr/internal/lib/vom.go
rename to services/wspr/internal/lib/hex_vom.go
index 3864c4e..ded745dd 100644
--- a/services/wspr/internal/lib/vom.go
+++ b/services/wspr/internal/lib/hex_vom.go
@@ -12,7 +12,7 @@
"v.io/v23/vom"
)
-func VomEncode(v interface{}) (string, error) {
+func HexVomEncode(v interface{}) (string, error) {
var buf bytes.Buffer
encoder := vom.NewEncoder(&buf)
if err := encoder.Encode(v); err != nil {
@@ -21,15 +21,15 @@
return hex.EncodeToString(buf.Bytes()), nil
}
-func VomEncodeOrDie(v interface{}) string {
- s, err := VomEncode(v)
+func HexVomEncodeOrDie(v interface{}) string {
+ s, err := HexVomEncode(v)
if err != nil {
panic(err)
}
return s
}
-func VomDecode(data string, v interface{}) error {
+func HexVomDecode(data string, v interface{}) error {
binbytes, err := hex.DecodeString(data)
if err != nil {
return fmt.Errorf("Error decoding hex string %q: %v", data, err)
diff --git a/services/wspr/internal/rpc/server/dispatcher.go b/services/wspr/internal/rpc/server/dispatcher.go
index 6d8e2cc..fa76d75 100644
--- a/services/wspr/internal/rpc/server/dispatcher.go
+++ b/services/wspr/internal/rpc/server/dispatcher.go
@@ -5,8 +5,6 @@
package server
import (
- "bytes"
- "encoding/json"
"sync"
"v.io/v23/rpc"
@@ -30,22 +28,6 @@
createAuthorizer(handle int32, hasAuthorizer bool) (security.Authorizer, error)
}
-type lookupIntermediateReply struct {
- Handle int32
- HasAuthorizer bool
- HasGlobber bool
- Signature string
- Err *verror.E
-}
-
-type lookupReply struct {
- Handle int32
- HasAuthorizer bool
- HasGlobber bool
- Signature []signature.Interface
- Err *verror.E
-}
-
type dispatcherRequest struct {
ServerId uint32 `json:"serverId"`
Suffix string `json:"suffix"`
@@ -58,7 +40,7 @@
flowFactory flowFactory
invokerFactory invokerFactory
authFactory authFactory
- outstandingLookups map[int32]chan lookupReply
+ outstandingLookups map[int32]chan LookupReply
closed bool
}
@@ -71,7 +53,7 @@
flowFactory: flowFactory,
invokerFactory: invokerFactory,
authFactory: authFactory,
- outstandingLookups: make(map[int32]chan lookupReply),
+ outstandingLookups: make(map[int32]chan LookupReply),
}
}
@@ -82,7 +64,7 @@
for _, ch := range d.outstandingLookups {
verr := NewErrServerStopped(nil).(verror.E)
- ch <- lookupReply{Err: &verr}
+ ch <- LookupReply{Err: &verr}
}
}
@@ -95,7 +77,7 @@
return nil, nil, NewErrServerStopped(nil)
}
flow := d.flowFactory.createFlow()
- ch := make(chan lookupReply, 1)
+ ch := make(chan LookupReply, 1)
d.outstandingLookups[flow.ID] = ch
d.mu.Unlock()
@@ -105,7 +87,7 @@
}
if err := flow.Writer.Send(lib.ResponseDispatcherLookup, message); err != nil {
verr := verror.Convert(verror.ErrInternal, nil, err).(verror.E)
- ch <- lookupReply{Err: &verr}
+ ch <- LookupReply{Err: &verr}
}
reply := <-ch
@@ -145,27 +127,14 @@
return
}
- var intermediateReply lookupIntermediateReply
- decoder := json.NewDecoder(bytes.NewBufferString(data))
- if err := decoder.Decode(&intermediateReply); err != nil {
- err2 := verror.Convert(verror.ErrInternal, nil, err).(verror.E)
- intermediateReply = lookupIntermediateReply{Err: &err2}
+ var lookupReply LookupReply
+ if err := lib.HexVomDecode(data, &lookupReply); err != nil {
+ err2 := verror.Convert(verror.ErrInternal, nil, err)
+ lookupReply = LookupReply{Err: err2}
vlog.Errorf("unmarshaling invoke request failed: %v, %s", err, data)
}
- reply := lookupReply{
- Handle: intermediateReply.Handle,
- HasAuthorizer: intermediateReply.HasAuthorizer,
- HasGlobber: intermediateReply.HasGlobber,
- Err: intermediateReply.Err,
- }
- if reply.Err == nil && intermediateReply.Signature != "" {
- if err := lib.VomDecode(intermediateReply.Signature, &reply.Signature); err != nil {
- err2 := verror.Convert(verror.ErrInternal, nil, err).(verror.E)
- reply.Err = &err2
- }
- }
- ch <- reply
+ ch <- lookupReply
}
// StopServing implements dispatcher StopServing.
diff --git a/services/wspr/internal/rpc/server/dispatcher_test.go b/services/wspr/internal/rpc/server/dispatcher_test.go
index b869c6a..43039ae 100644
--- a/services/wspr/internal/rpc/server/dispatcher_test.go
+++ b/services/wspr/internal/rpc/server/dispatcher_test.go
@@ -14,6 +14,7 @@
"v.io/v23/security"
"v.io/v23/vdl"
"v.io/v23/vdlroot/signature"
+ "v.io/v23/verror"
"v.io/x/ref/services/wspr/internal/lib"
"v.io/x/ref/services/wspr/internal/lib/testwriter"
)
@@ -88,8 +89,12 @@
t.Errorf("failed to get dispatch request %v", err)
t.Fail()
}
- jsonResponse := fmt.Sprintf(`{"handle":1,"hasAuthorizer":false,"signature":"%s"}`, lib.VomEncodeOrDie(expectedSig))
- d.handleLookupResponse(0, jsonResponse)
+ reply := LookupReply{
+ Handle: 1,
+ HasAuthorizer: false,
+ Signature: expectedSig,
+ }
+ d.handleLookupResponse(0, lib.HexVomEncodeOrDie(reply))
}()
invoker, auth, err := d.Lookup("a/b")
@@ -133,8 +138,12 @@
t.Errorf("failed to get dispatch request %v", err)
t.Fail()
}
- jsonResponse := fmt.Sprintf(`{"handle":1,"hasAuthorizer":true,"signature":"%s"}`, lib.VomEncodeOrDie(expectedSig))
- d.handleLookupResponse(0, jsonResponse)
+ reply := LookupReply{
+ Handle: 1,
+ HasAuthorizer: true,
+ Signature: expectedSig,
+ }
+ d.handleLookupResponse(0, lib.HexVomEncodeOrDie(reply))
}()
invoker, auth, err := d.Lookup("a/b")
@@ -175,8 +184,10 @@
t.Errorf("failed to get dispatch request %v", err)
t.Fail()
}
- jsonResponse := `{"err":{"id":"v23/verror.Exists","msg":"bad stuff"}}`
- d.handleLookupResponse(0, jsonResponse)
+ reply := LookupReply{
+ Err: verror.New(verror.ErrNoExist, nil),
+ }
+ d.handleLookupResponse(0, lib.HexVomEncodeOrDie(reply))
}()
_, _, err := d.Lookup("a/b")
diff --git a/services/wspr/internal/rpc/server/server.go b/services/wspr/internal/rpc/server/server.go
index 9ce5ac9..f056c91 100644
--- a/services/wspr/internal/rpc/server/server.go
+++ b/services/wspr/internal/rpc/server/server.go
@@ -7,7 +7,6 @@
package server
import (
- "encoding/json"
"fmt"
"sync"
"time"
@@ -54,10 +53,6 @@
Context() *context.T
}
-type authReply struct {
- Err *verror.E
-}
-
// AuthRequest is a request for a javascript authorizer to run
// This is exported to make the app test easier.
type AuthRequest struct {
@@ -179,7 +174,7 @@
Args: vdlValArgs,
Call: rpcCall,
}
- vomMessage, err := lib.VomEncode(message)
+ vomMessage, err := lib.HexVomEncode(message)
if err != nil {
return errHandler(err)
}
@@ -288,7 +283,7 @@
Args: []*vdl.Value{vdl.ValueOf(pattern)},
Call: rpcCall,
}
- vomMessage, err := lib.VomEncode(message)
+ vomMessage, err := lib.HexVomEncode(message)
if err != nil {
return errHandler(err)
}
@@ -325,7 +320,7 @@
item = principal.ConvertBlessingsToHandle(blessings, blessingsCache.GetOrAddBlessingsHandle(blessings))
}
- vomItem, err := lib.VomEncode(item)
+ vomItem, err := lib.HexVomEncode(item)
if err != nil {
w.Error(verror.Convert(verror.ErrInternal, nil, err))
return
@@ -563,7 +558,7 @@
}
vlog.VI(0).Infof("Sending out auth request for %v, %v", flow.ID, message)
- vomMessage, err := lib.VomEncode(message)
+ vomMessage, err := lib.HexVomEncode(message)
if err != nil {
replyChan <- verror.Convert(verror.ErrInternal, nil, err)
} else if err := flow.Writer.Send(lib.ResponseAuthRequest, vomMessage); err != nil {
@@ -653,7 +648,7 @@
// Decode the result and send it through the channel
var reply lib.ServerRpcReply
- if err := lib.VomDecode(data, &reply); err != nil {
+ if err := lib.HexVomDecode(data, &reply); err != nil {
reply.Err = err
}
@@ -694,10 +689,10 @@
return
}
// Decode the result and send it through the channel
- var reply authReply
- if decoderErr := json.Unmarshal([]byte(data), &reply); decoderErr != nil {
- err := verror.Convert(verror.ErrInternal, nil, decoderErr).(verror.E)
- reply = authReply{Err: &err}
+ var reply AuthReply
+ if err := lib.HexVomDecode(data, &reply); err != nil {
+ err = verror.Convert(verror.ErrInternal, nil, err)
+ reply = AuthReply{Err: err}
}
vlog.VI(0).Infof("response received from JavaScript server for "+
@@ -725,7 +720,7 @@
}
var reply CaveatValidationResponse
- if err := lib.VomDecode(data, &reply); err != nil {
+ if err := lib.HexVomDecode(data, &reply); err != nil {
vlog.Errorf("failed to decode validation response %q: error %v", data, err)
ch <- []error{}
return
diff --git a/services/wspr/internal/rpc/server/server.vdl b/services/wspr/internal/rpc/server/server.vdl
index f069c39..790960c 100644
--- a/services/wspr/internal/rpc/server/server.vdl
+++ b/services/wspr/internal/rpc/server/server.vdl
@@ -7,6 +7,7 @@
import (
"time"
+ "signature"
"v.io/v23/security"
"v.io/v23/vtrace"
"v.io/x/ref/services/wspr/internal/principal"
@@ -60,3 +61,17 @@
Args []any
Call ServerRpcRequestCall
}
+
+// A reply from javascript to a lookup request.
+type LookupReply struct {
+ Handle int32
+ HasAuthorizer bool
+ HasGlobber bool
+ Signature []signature.Interface
+ Err error
+}
+
+// A reply from javascript to an auth request.
+type AuthReply struct {
+ Err error
+}
diff --git a/services/wspr/internal/rpc/server/server.vdl.go b/services/wspr/internal/rpc/server/server.vdl.go
index 4956bca..6a18704 100644
--- a/services/wspr/internal/rpc/server/server.vdl.go
+++ b/services/wspr/internal/rpc/server/server.vdl.go
@@ -16,6 +16,7 @@
// VDL user imports
"v.io/v23/security"
+ "v.io/v23/vdlroot/signature"
"v.io/v23/vdlroot/time"
"v.io/v23/vtrace"
"v.io/x/ref/services/wspr/internal/principal"
@@ -94,6 +95,30 @@
}) {
}
+// A reply from javascript to a lookup request.
+type LookupReply struct {
+ Handle int32
+ HasAuthorizer bool
+ HasGlobber bool
+ Signature []signature.Interface
+ Err error
+}
+
+func (LookupReply) __VDLReflect(struct {
+ Name string `vdl:"v.io/x/ref/services/wspr/internal/rpc/server.LookupReply"`
+}) {
+}
+
+// A reply from javascript to an auth request.
+type AuthReply struct {
+ Err error
+}
+
+func (AuthReply) __VDLReflect(struct {
+ Name string `vdl:"v.io/x/ref/services/wspr/internal/rpc/server.AuthReply"`
+}) {
+}
+
func init() {
vdl.Register((*Context)(nil))
vdl.Register((*SecurityCall)(nil))
@@ -101,6 +126,8 @@
vdl.Register((*CaveatValidationResponse)(nil))
vdl.Register((*ServerRpcRequestCall)(nil))
vdl.Register((*ServerRpcRequest)(nil))
+ vdl.Register((*LookupReply)(nil))
+ vdl.Register((*AuthReply)(nil))
}
var (
diff --git a/services/wspr/wsprd/doc.go b/services/wspr/wsprd/doc.go
new file mode 100644
index 0000000..e0c33d7
--- /dev/null
+++ b/services/wspr/wsprd/doc.go
@@ -0,0 +1,69 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+// +build wspr
+
+/*
+Command wsprd runs the wspr web socket proxy daemon.
+
+Usage:
+ wsprd [flags]
+
+The wsprd flags are:
+ -identd=
+ Name of identd server.
+ -port=8124
+ Port to listen on.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.permissions.file=map[]
+ specify a perms file as <name>:<permsfile>
+ -v23.permissions.literal=
+ explicitly specify the runtime perms as a JSON-encoded access.Permissions.
+ Overrides all --v23.permissions.file flags.
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/services/wspr/wsprd/main.go b/services/wspr/wsprd/main.go
index cde3f9f..dbc135f 100644
--- a/services/wspr/wsprd/main.go
+++ b/services/wspr/wsprd/main.go
@@ -6,34 +6,57 @@
//
// We restrict wsprd to a special build-tag in order to enable
// security.OverrideCaveatValidation, which isn't generally available.
+//
+// Manually run the following to generate the doc.go file. This isn't a
+// go:generate comment, since generate also needs to be run with -tags=wspr,
+// which is troublesome for presubmit tests.
+//
+// cd $V23_ROOT/release/go/src && go run v.io/x/lib/cmdline/testdata/gendoc.go -tags=wspr v.io/x/ref/services/wspr/wsprd -help
-// Daemon wsprd implements the wspr web socket proxy as a stand-alone server.
package main
import (
- "flag"
"fmt"
"net"
"v.io/v23"
+ "v.io/v23/context"
+ "v.io/x/lib/cmdline"
"v.io/x/ref/lib/signals"
+ "v.io/x/ref/lib/v23cmd"
// TODO(cnicolaou,benj): figure out how to support roaming as a chrome plugin
_ "v.io/x/ref/runtime/factories/roaming"
"v.io/x/ref/services/wspr/wsprlib"
)
-func main() {
+var (
+ port int
+ identd string
+)
+
+func init() {
wsprlib.OverrideCaveatValidation()
- port := flag.Int("port", 8124, "Port to listen on.")
- identd := flag.String("identd", "", "name of identd server.")
+ cmdWsprD.Flags.IntVar(&port, "port", 8124, "Port to listen on.")
+ cmdWsprD.Flags.StringVar(&identd, "identd", "", "Name of identd server.")
+}
- flag.Parse()
+func main() {
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdWsprD)
+}
- ctx, shutdown := v23.Init()
- defer shutdown()
+var cmdWsprD = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runWsprD),
+ Name: "wsprd",
+ Short: "Runs the wspr web socket proxy daemon",
+ Long: `
+Command wsprd runs the wspr web socket proxy daemon.
+`,
+}
+func runWsprD(ctx *context.T, env *cmdline.Env, args []string) error {
listenSpec := v23.GetListenSpec(ctx)
- proxy := wsprlib.NewWSPR(ctx, *port, &listenSpec, *identd, nil)
+ proxy := wsprlib.NewWSPR(ctx, port, &listenSpec, identd, nil)
defer proxy.Shutdown()
addr := proxy.Listen()
@@ -44,4 +67,5 @@
nhost, nport, _ := net.SplitHostPort(addr.String())
fmt.Printf("Listening on host: %s port: %s\n", nhost, nport)
<-signals.ShutdownOnSignals(ctx)
+ return nil
}
diff --git a/test/hello/helloclient/doc.go b/test/hello/helloclient/doc.go
new file mode 100644
index 0000000..b5467e0
--- /dev/null
+++ b/test/hello/helloclient/doc.go
@@ -0,0 +1,60 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command helloclient is a simple client mainly used in regression tests.
+
+Usage:
+ helloclient [flags]
+
+The helloclient flags are:
+ -name=
+ Name of the hello server.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/test/hello/helloclient/helloclient.go b/test/hello/helloclient/helloclient.go
index a50ad5d..c5c931a 100644
--- a/test/hello/helloclient/helloclient.go
+++ b/test/hello/helloclient/helloclient.go
@@ -2,37 +2,53 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Command helloclient is the simplest possible client. It is mainly used in simple
-// regression tests.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
- "flag"
+ "errors"
"fmt"
"time"
"v.io/v23"
"v.io/v23/context"
"v.io/v23/verror"
+ "v.io/x/lib/cmdline"
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/generic"
)
-var name *string = flag.String("name", "", "Name of the hello server")
+var name string
func main() {
- ctx, shutdown := v23.Init()
- defer shutdown()
+ cmdHelloClient.Flags.StringVar(&name, "name", "", "Name of the hello server.")
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdHelloClient)
+}
+var cmdHelloClient = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runHelloClient),
+ Name: "helloclient",
+ Short: "Simple client mainly used in regression tests.",
+ Long: `
+Command helloclient is a simple client mainly used in regression tests.
+`,
+}
+
+func runHelloClient(ctx *context.T, env *cmdline.Env, args []string) error {
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
var result string
- err := v23.GetClient(ctx).Call(ctx, *name, "Hello", nil, []interface{}{&result})
+ err := v23.GetClient(ctx).Call(ctx, name, "Hello", nil, []interface{}{&result})
if err != nil {
- panic(verror.DebugString(err))
+ return errors.New(verror.DebugString(err))
}
- if result != "hello" {
- panic(fmt.Sprintf("Unexpected result. Wanted %q, got %q", "hello", result))
+ if got, want := result, "hello"; got != want {
+ return fmt.Errorf("Unexpected result, got %q, want %q", got, want)
}
+ return nil
}
diff --git a/test/hello/helloserver/doc.go b/test/hello/helloserver/doc.go
new file mode 100644
index 0000000..4029e67
--- /dev/null
+++ b/test/hello/helloserver/doc.go
@@ -0,0 +1,60 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command helloserver is a simple server mainly used in regression tests.
+
+Usage:
+ helloserver [flags]
+
+The helloserver flags are:
+ -name=
+ Name to publish under.
+
+The global flags are:
+ -alsologtostderr=true
+ log to standard error as well as files
+ -log_backtrace_at=:0
+ when logging hits line file:N, emit a stack trace
+ -log_dir=
+ if non-empty, write log files to this directory
+ -logtostderr=false
+ log to standard error instead of files
+ -max_stack_buf_size=4292608
+ max size in bytes of the buffer to use for logging stack traces
+ -stderrthreshold=2
+ logs at or above this threshold go to stderr
+ -v=0
+ log level for V logs
+ -v23.credentials=
+ directory to use for storing security credentials
+ -v23.i18n-catalogue=
+ 18n catalogue files to load, comma separated
+ -v23.metadata=<just specify -v23.metadata to activate>
+ Displays metadata for the program and exits.
+ -v23.namespace.root=[/(dev.v.io/role/vprod/service/mounttabled)@ns.dev.v.io:8101]
+ local namespace root; can be repeated to provided multiple roots
+ -v23.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -v23.tcp.address=
+ address to listen on
+ -v23.tcp.protocol=wsh
+ protocol to listen with
+ -v23.vtrace.cache-size=1024
+ The number of vtrace traces to store in memory.
+ -v23.vtrace.collect-regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -v23.vtrace.dump-on-shutdown=true
+ If true, dump all stored traces on runtime shutdown.
+ -v23.vtrace.sample-rate=0
+ Rate (from 0.0 to 1.0) to sample vtrace traces.
+ -vmodule=
+ comma-separated list of pattern=N settings for file-filtered logging
+*/
+package main
diff --git a/test/hello/helloserver/helloserver.go b/test/hello/helloserver/helloserver.go
index 6ca4393..9acde0d 100644
--- a/test/hello/helloserver/helloserver.go
+++ b/test/hello/helloserver/helloserver.go
@@ -2,24 +2,40 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Daemon helloserver is the simplest possible server. It is mainly
-// used in simple regression tests.
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
+
package main
import (
- "flag"
"fmt"
- "os"
"v.io/v23"
"v.io/v23/context"
"v.io/v23/rpc"
"v.io/v23/security"
+ "v.io/x/lib/cmdline"
"v.io/x/ref/lib/signals"
+ "v.io/x/ref/lib/v23cmd"
_ "v.io/x/ref/runtime/factories/generic"
)
-var name *string = flag.String("name", "", "Name to publish under")
+var name string
+
+func main() {
+ cmdHelloServer.Flags.StringVar(&name, "name", "", "Name to publish under.")
+ cmdline.HideGlobalFlagsExcept()
+ cmdline.Main(cmdHelloServer)
+}
+
+var cmdHelloServer = &cmdline.Command{
+ Runner: v23cmd.RunnerFunc(runHelloServer),
+ Name: "helloserver",
+ Short: "Simple server mainly used in regression tests.",
+ Long: `
+Command helloserver is a simple server mainly used in regression tests.
+`,
+}
type helloServer struct{}
@@ -27,10 +43,7 @@
return "hello", nil
}
-func run() error {
- ctx, shutdown := v23.Init()
- defer shutdown()
-
+func runHelloServer(ctx *context.T, env *cmdline.Env, args []string) error {
server, err := v23.NewServer(ctx)
if err != nil {
return fmt.Errorf("NewServer: %v", err)
@@ -44,15 +57,9 @@
} else {
fmt.Println("SERVER_NAME=proxy")
}
- if err := server.Serve(*name, &helloServer{}, security.AllowEveryone()); err != nil {
+ if err := server.Serve(name, &helloServer{}, security.AllowEveryone()); err != nil {
return fmt.Errorf("Serve: %v", err)
}
<-signals.ShutdownOnSignals(ctx)
return nil
}
-
-func main() {
- if err := run(); err != nil {
- os.Exit(1)
- }
-}