Merge "veyron/security: Update documentation for ACL formatting."
diff --git a/lib/cmdline/cmdline.go b/lib/cmdline/cmdline.go
index d6705e6..dcc5aee 100644
--- a/lib/cmdline/cmdline.go
+++ b/lib/cmdline/cmdline.go
@@ -15,7 +15,6 @@
package cmdline
import (
- "errors"
"flag"
"fmt"
"io"
@@ -23,9 +22,17 @@
"strings"
)
+// ErrExitCode may be returned by the Run function of a Command to cause the
+// program to exit with a specific error code.
+type ErrExitCode int
+
+func (x ErrExitCode) Error() string {
+ return fmt.Sprintf("exit code %d", x)
+}
+
// ErrUsage is returned to indicate an error in command usage; e.g. unknown
-// flags, subcommands or args.
-var ErrUsage = errors.New("usage error")
+// flags, subcommands or args. It corresponds to exit code 1.
+const ErrUsage = ErrExitCode(1)
// Command represents a single command in a command-line program. A program
// with subcommands is represented as a root Command with children representing
@@ -46,7 +53,8 @@
// Run is a function that runs cmd with args. If both Children and Run are
// specified, Run will only be called if none of the children match. It is an
- // error if neither is specified.
+ // error if neither is specified. The special ErrExitCode error may be
+ // returned to indicate the command should exit with a specific exit code.
Run func(cmd *Command, args []string) error
// parent holds the parent of this Command, or nil if this is the root.
@@ -107,8 +115,10 @@
return cmd.stderr
}
-// Errorf should be called to signal an invalid usage of the command.
-func (cmd *Command) Errorf(format string, v ...interface{}) error {
+// UsageErrorf prints the error message represented by the printf-style format
+// string and args, followed by the usage description of cmd. Returns ErrUsage
+// to make it easy to use from within the cmd.Run function.
+func (cmd *Command) UsageErrorf(format string, v ...interface{}) error {
fmt.Fprint(cmd.stderr, "ERROR: ")
fmt.Fprintf(cmd.stderr, format, v...)
fmt.Fprint(cmd.stderr, "\n\n")
@@ -236,7 +246,7 @@
return runHelp(child, subArgs, style)
}
}
- return cmd.Errorf("%s: unknown command %q", cmd.Name, subName)
+ return cmd.UsageErrorf("%s: unknown command %q", cmd.Name, subName)
}
// recursiveHelp prints help recursively via DFS from this cmd onward.
@@ -328,20 +338,20 @@
if cmd.Run != nil {
if cmd.ArgsName == "" && len(args) > 0 {
if len(cmd.Children) > 0 {
- return cmd.Errorf("%s: unknown command %q", cmd.Name, args[0])
+ return cmd.UsageErrorf("%s: unknown command %q", cmd.Name, args[0])
} else {
- return cmd.Errorf("%s doesn't take any arguments", cmd.Name)
+ return cmd.UsageErrorf("%s doesn't take any arguments", cmd.Name)
}
}
return cmd.Run(cmd, args)
}
switch {
case len(cmd.Children) == 0:
- return cmd.Errorf("%s: neither Children nor Run is specified", cmd.Name)
+ return cmd.UsageErrorf("%s: neither Children nor Run is specified", cmd.Name)
case len(args) > 0:
- return cmd.Errorf("%s: unknown command %q", cmd.Name, args[0])
+ return cmd.UsageErrorf("%s: unknown command %q", cmd.Name, args[0])
default:
- return cmd.Errorf("%s: no command specified", cmd.Name)
+ return cmd.UsageErrorf("%s: no command specified", cmd.Name)
}
}
@@ -352,8 +362,8 @@
func (cmd *Command) Main() {
cmd.Init(nil, os.Stdout, os.Stderr)
if err := cmd.Execute(os.Args[1:]); err != nil {
- if err == ErrUsage {
- os.Exit(1)
+ if code, ok := err.(ErrExitCode); ok {
+ os.Exit(int(code))
} else {
fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
os.Exit(2)
diff --git a/lib/cmdline/cmdline_test.go b/lib/cmdline/cmdline_test.go
index 6fdf3c5..e9c471b 100644
--- a/lib/cmdline/cmdline_test.go
+++ b/lib/cmdline/cmdline_test.go
@@ -25,7 +25,7 @@
if args[0] == "error" {
return errEcho
} else if args[0] == "bad_arg" {
- return cmd.Errorf("Invalid argument %v", args[0])
+ return cmd.UsageErrorf("Invalid argument %v", args[0])
}
}
if flagExtra {
diff --git a/profiles/platform_darwin.go b/profiles/platform_darwin.go
index 933b589..e6b2af3 100644
--- a/profiles/platform_darwin.go
+++ b/profiles/platform_darwin.go
@@ -10,7 +10,6 @@
"fmt"
"veyron.io/veyron/veyron2"
- "veyron.io/veyron/veyron2/security"
)
// Platform returns the description of the Platform this process is running on.
@@ -30,6 +29,5 @@
Machine: C.GoString(&t.machine[0]),
Node: C.GoString(&t.nodename[0]),
}
- d.Identity = security.FakePublicID(fmt.Sprintf("%s/%s/%s", d.Vendor, d.Model, d.Node))
return d, nil
}
diff --git a/runtimes/google/ipc/full_test.go b/runtimes/google/ipc/full_test.go
index be1655c..10e2baf 100644
--- a/runtimes/google/ipc/full_test.go
+++ b/runtimes/google/ipc/full_test.go
@@ -134,6 +134,9 @@
}
// Add a fakeTimeCaveat to allow the discharge to expire
expiry := fakeTimeCaveat(clock.Now())
+ if err := c.Dischargeable(ctx); err != nil {
+ return nil, fmt.Errorf("third-party caveat %v cannot be discharged for this context: %v", c, err)
+ }
return serverID.MintDischarge(c, ctx, time.Hour, []security.Caveat{newCaveat(expiry)})
}
diff --git a/security/audit/id_test.go b/security/audit/id_test.go
index 5a58432..8d01746 100644
--- a/security/audit/id_test.go
+++ b/security/audit/id_test.go
@@ -245,6 +245,7 @@
func (thirdPartyCaveat) Requirements() security.ThirdPartyRequirements {
return security.ThirdPartyRequirements{}
}
+func (thirdPartyCaveat) Dischargeable(security.Context) error { return nil }
// context implements security.Context
type context struct{}
diff --git a/security/util_test.go b/security/util_test.go
index 1da3c31..0e32e1d 100644
--- a/security/util_test.go
+++ b/security/util_test.go
@@ -87,6 +87,7 @@
func (tpCaveat) ID() (id string) { return }
func (tpCaveat) Location() (loc string) { return }
func (tpCaveat) Requirements() (r security.ThirdPartyRequirements) { return }
+func (tpCaveat) Dischargeable(security.Context) (err error) { return }
func TestCaveatUtil(t *testing.T) {
type C []security.Caveat
diff --git a/services/security/discharger/discharger.go b/services/security/discharger/discharger.go
index 5e701d1..b110866 100644
--- a/services/security/discharger/discharger.go
+++ b/services/security/discharger/discharger.go
@@ -23,6 +23,9 @@
if !ok {
return nil, fmt.Errorf("type %T does not implement security.ThirdPartyCaveat", caveatAny)
}
+ if err := caveat.Dischargeable(ctx); err != nil {
+ return nil, fmt.Errorf("third-party caveat %v cannot be discharged for this context: %v", caveat, err)
+ }
return d.id.MintDischarge(caveat, ctx, time.Minute, nil)
}
diff --git a/tools/application/impl/impl.go b/tools/application/impl/impl.go
index fccb840..8af0a9f 100644
--- a/tools/application/impl/impl.go
+++ b/tools/application/impl/impl.go
@@ -64,7 +64,7 @@
func runMatch(cmd *cmdline.Command, args []string) error {
if expected, got := 2, len(args); expected != got {
- return cmd.Errorf("match: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("match: incorrect number of arguments, expected %d, got %d", expected, got)
}
name, profiles := args[0], args[1]
app, err := repository.BindApplication(name)
@@ -95,7 +95,7 @@
func runPut(cmd *cmdline.Command, args []string) error {
if expected, got := 3, len(args); expected != got {
- return cmd.Errorf("put: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("put: incorrect number of arguments, expected %d, got %d", expected, got)
}
name, profiles, envelope := args[0], args[1], args[2]
app, err := repository.BindApplication(name)
@@ -128,7 +128,7 @@
func runRemove(cmd *cmdline.Command, args []string) error {
if expected, got := 2, len(args); expected != got {
- return cmd.Errorf("remove: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("remove: incorrect number of arguments, expected %d, got %d", expected, got)
}
name, profile := args[0], args[1]
app, err := repository.BindApplication(name)
@@ -157,7 +157,7 @@
func runEdit(cmd *cmdline.Command, args []string) error {
if expected, got := 2, len(args); expected != got {
- return cmd.Errorf("edit: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("edit: incorrect number of arguments, expected %d, got %d", expected, got)
}
name, profile := args[0], args[1]
app, err := repository.BindApplication(name)
diff --git a/tools/binary/impl/impl.go b/tools/binary/impl/impl.go
index f690e54..b5a1cec 100644
--- a/tools/binary/impl/impl.go
+++ b/tools/binary/impl/impl.go
@@ -18,7 +18,7 @@
func runDelete(cmd *cmdline.Command, args []string) error {
if expected, got := 1, len(args); expected != got {
- return cmd.Errorf("delete: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("delete: incorrect number of arguments, expected %d, got %d", expected, got)
}
von := args[0]
if err := binary.Delete(von); err != nil {
@@ -45,7 +45,7 @@
func runDownload(cmd *cmdline.Command, args []string) error {
if expected, got := 2, len(args); expected != got {
- return cmd.Errorf("download: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("download: incorrect number of arguments, expected %d, got %d", expected, got)
}
von, filename := args[0], args[1]
if err := binary.DownloadToFile(von, filename); err != nil {
@@ -72,7 +72,7 @@
func runUpload(cmd *cmdline.Command, args []string) error {
if expected, got := 2, len(args); expected != got {
- return cmd.Errorf("upload: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("upload: incorrect number of arguments, expected %d, got %d", expected, got)
}
von, filename := args[0], args[1]
if err := binary.UploadFromFile(von, filename); err != nil {
diff --git a/tools/mounttable/impl/impl.go b/tools/mounttable/impl/impl.go
index 9d9a96d..5d67326 100644
--- a/tools/mounttable/impl/impl.go
+++ b/tools/mounttable/impl/impl.go
@@ -38,7 +38,7 @@
func runGlob(cmd *cmdline.Command, args []string) error {
if expected, got := 2, len(args); expected != got {
- return cmd.Errorf("glob: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("glob: incorrect number of arguments, expected %d, got %d", expected, got)
}
ctx, cancel := rt.R().NewContext().WithTimeout(time.Minute)
defer cancel()
@@ -87,7 +87,7 @@
func runMount(cmd *cmdline.Command, args []string) error {
if expected, got := 3, len(args); expected != got {
- return cmd.Errorf("mount: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("mount: incorrect number of arguments, expected %d, got %d", expected, got)
}
ctx, cancel := rt.R().NewContext().WithTimeout(time.Minute)
defer cancel()
@@ -122,7 +122,7 @@
func runUnmount(cmd *cmdline.Command, args []string) error {
if expected, got := 2, len(args); expected != got {
- return cmd.Errorf("unmount: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("unmount: incorrect number of arguments, expected %d, got %d", expected, got)
}
ctx, cancel := rt.R().NewContext().WithTimeout(time.Minute)
defer cancel()
@@ -152,7 +152,7 @@
func runResolveStep(cmd *cmdline.Command, args []string) error {
if expected, got := 1, len(args); expected != got {
- return cmd.Errorf("mount: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("mount: incorrect number of arguments, expected %d, got %d", expected, got)
}
ctx, cancel := rt.R().NewContext().WithTimeout(time.Minute)
defer cancel()
diff --git a/tools/namespace/impl/impl.go b/tools/namespace/impl/impl.go
index 2c87e49..d8fe9a9 100644
--- a/tools/namespace/impl/impl.go
+++ b/tools/namespace/impl/impl.go
@@ -24,7 +24,7 @@
func runGlob(cmd *cmdline.Command, args []string) error {
if expected, got := 1, len(args); expected != got {
- return cmd.Errorf("glob: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("glob: incorrect number of arguments, expected %d, got %d", expected, got)
}
pattern := args[0]
ns := rt.R().Namespace()
@@ -61,7 +61,7 @@
func runMount(cmd *cmdline.Command, args []string) error {
if expected, got := 3, len(args); expected != got {
- return cmd.Errorf("mount: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("mount: incorrect number of arguments, expected %d, got %d", expected, got)
}
name := args[0]
server := args[1]
@@ -96,7 +96,7 @@
func runUnmount(cmd *cmdline.Command, args []string) error {
if expected, got := 2, len(args); expected != got {
- return cmd.Errorf("unmount: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("unmount: incorrect number of arguments, expected %d, got %d", expected, got)
}
name := args[0]
server := args[1]
@@ -122,7 +122,7 @@
func runResolve(cmd *cmdline.Command, args []string) error {
if expected, got := 1, len(args); expected != got {
- return cmd.Errorf("resolve: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("resolve: incorrect number of arguments, expected %d, got %d", expected, got)
}
name := args[0]
ns := rt.R().Namespace()
@@ -150,7 +150,7 @@
func runResolveToMT(cmd *cmdline.Command, args []string) error {
if expected, got := 1, len(args); expected != got {
- return cmd.Errorf("resolvetomt: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("resolvetomt: incorrect number of arguments, expected %d, got %d", expected, got)
}
name := args[0]
ns := rt.R().Namespace()
@@ -178,7 +178,7 @@
func runUnresolve(cmd *cmdline.Command, args []string) error {
if expected, got := 1, len(args); expected != got {
- return cmd.Errorf("unresolve: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("unresolve: incorrect number of arguments, expected %d, got %d", expected, got)
}
name := args[0]
ns := rt.R().Namespace()
diff --git a/tools/profile/impl/impl.go b/tools/profile/impl/impl.go
index 1a69555..4413896 100644
--- a/tools/profile/impl/impl.go
+++ b/tools/profile/impl/impl.go
@@ -23,7 +23,7 @@
func runLabel(cmd *cmdline.Command, args []string) error {
if expected, got := 1, len(args); expected != got {
- return cmd.Errorf("label: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("label: incorrect number of arguments, expected %d, got %d", expected, got)
}
name := args[0]
p, err := repository.BindProfile(name)
@@ -51,7 +51,7 @@
func runDescription(cmd *cmdline.Command, args []string) error {
if expected, got := 1, len(args); expected != got {
- return cmd.Errorf("description: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("description: incorrect number of arguments, expected %d, got %d", expected, got)
}
name := args[0]
p, err := repository.BindProfile(name)
@@ -79,7 +79,7 @@
func runSpecification(cmd *cmdline.Command, args []string) error {
if expected, got := 1, len(args); expected != got {
- return cmd.Errorf("spec: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("spec: incorrect number of arguments, expected %d, got %d", expected, got)
}
name := args[0]
p, err := repository.BindProfile(name)
@@ -107,7 +107,7 @@
func runPut(cmd *cmdline.Command, args []string) error {
if expected, got := 1, len(args); expected != got {
- return cmd.Errorf("put: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("put: incorrect number of arguments, expected %d, got %d", expected, got)
}
name := args[0]
p, err := repository.BindProfile(name)
@@ -144,7 +144,7 @@
func runRemove(cmd *cmdline.Command, args []string) error {
if expected, got := 1, len(args); expected != got {
- return cmd.Errorf("remove: incorrect number of arguments, expected %d, got %d", expected, got)
+ return cmd.UsageErrorf("remove: incorrect number of arguments, expected %d, got %d", expected, got)
}
name := args[0]
p, err := repository.BindProfile(name)
diff --git a/tools/vrpc/impl/impl.go b/tools/vrpc/impl/impl.go
index 3851bac..05483e9 100644
--- a/tools/vrpc/impl/impl.go
+++ b/tools/vrpc/impl/impl.go
@@ -50,7 +50,7 @@
func runDescribe(cmd *cmdline.Command, args []string) error {
if len(args) != 1 {
- return cmd.Errorf("describe: incorrect number of arguments, expected 1, got %d", len(args))
+ return cmd.UsageErrorf("describe: incorrect number of arguments, expected 1, got %d", len(args))
}
runtime := rt.R()
@@ -89,7 +89,7 @@
func runInvoke(cmd *cmdline.Command, args []string) error {
if len(args) < 2 {
- return cmd.Errorf("invoke: incorrect number of arguments, expected at least 2, got %d", len(args))
+ return cmd.UsageErrorf("invoke: incorrect number of arguments, expected at least 2, got %d", len(args))
}
server, method, args := args[0], args[1], args[2:]
@@ -117,7 +117,7 @@
}
if len(args) != len(methodSignature.InArgs) {
- return cmd.Errorf("invoke: incorrect number of arguments, expected %d, got %d", len(methodSignature.InArgs), len(args))
+ return cmd.UsageErrorf("invoke: incorrect number of arguments, expected %d, got %d", len(methodSignature.InArgs), len(args))
}
// Register all user-defined types you would like to use.
diff --git a/tools/vrpc/impl/impl_test.go b/tools/vrpc/impl/impl_test.go
index 0dd2811..2d44a19 100644
--- a/tools/vrpc/impl/impl_test.go
+++ b/tools/vrpc/impl/impl_test.go
@@ -275,8 +275,8 @@
}
testErrors := [][]string{
- []string{"EchoBool", "usage error"},
- []string{"DoesNotExit", "invoke: method DoesNotExit not found"},
+ []string{"EchoBool", "exit code 1"},
+ []string{"DoesNotExist", "invoke: method DoesNotExist not found"},
}
for _, test := range testErrors {
testError(t, cmd, append([]string{"invoke", name, test[0]}, test[2:]...), test[1])