Merge "go generate updates following v.io/c/12224"
diff --git a/services/device/device/debug.go b/services/device/device/debug.go
index 1ba6fc4..1b06b3c 100644
--- a/services/device/device/debug.go
+++ b/services/device/device/debug.go
@@ -15,7 +15,6 @@
)
var cmdDebug = &cmdline.Command{
- Runner: globRunner(runDebug),
Name: "debug",
Short: "Debug the device.",
Long: "Get internal debug information about application installations and instances.",
@@ -24,6 +23,10 @@
<app name patterns...> are vanadium object names or glob name patterns corresponding to application installations and instances.`,
}
+func init() {
+ globify(cmdDebug, runDebug, new(globSettings))
+}
+
func runDebug(entry globResult, ctx *context.T, stdout, _ io.Writer) error {
if description, err := device.DeviceClient(entry.name).Debug(ctx); err != nil {
return fmt.Errorf("Debug failed: %v", err)
diff --git a/services/device/device/doc.go b/services/device/device/doc.go
index 816a5c1..b42ff11 100644
--- a/services/device/device/doc.go
+++ b/services/device/device/doc.go
@@ -46,14 +46,6 @@
user specified by this flag
-dryrun=false
Elides root-requiring systemcalls.
- -installation-state=
- If non-empty, specifies allowed installation states (all others installations
- get filtered out). The value of the flag is a comma-separated list of values
- from among: [Active Uninstalled].
- -instance-state=
- If non-empty, specifies allowed instance states (all other instances get
- filtered out). The value of the flag is a comma-separated list of values from
- among: [Launching Running Dying NotRunning Updating Deleted].
-kill=false
Kill process ids given as command-line arguments.
-log_backtrace_at=:0
@@ -68,13 +60,6 @@
max size in bytes of the buffer to use for logging stack traces
-minuid=501
UIDs cannot be less than this number.
- -only-installations=false
- If set, only consider installations.
- -only-instances=false
- If set, only consider instances.
- -parallelism=BYKIND
- Specifies the level of parallelism for the handler execution. One of:
- BYKIND,FULL,NONE
-progname=unnamed_app
Visible name of the application, used in argv[0]
-rm=false
@@ -289,41 +274,109 @@
previous version of their current version
Usage:
- device revert <name patterns...>
+ device revert [flags] <name patterns...>
<name patterns...> are vanadium object names or glob name patterns corresponding
to the device manager service, or to application installations and instances.
+The device revert flags are:
+ -installation-state=
+ If non-empty, specifies allowed installation states (all others installations
+ get filtered out). The value of the flag is a comma-separated list of values
+ from among: [Active Uninstalled].
+ -instance-state=
+ If non-empty, specifies allowed instance states (all other instances get
+ filtered out). The value of the flag is a comma-separated list of values from
+ among: [Launching Running Dying NotRunning Updating Deleted].
+ -only-installations=false
+ If set, only consider installations.
+ -only-instances=false
+ If set, only consider instances.
+ -parallelism=BYKIND
+ Specifies the level of parallelism for the handler execution. One of: [BYKIND
+ FULL NONE].
+
Device update
Update the device manager or application instances and installations
Usage:
- device update <name patterns...>
+ device update [flags] <name patterns...>
<name patterns...> are vanadium object names or glob name patterns corresponding
to the device manager service, or to application installations and instances.
+The device update flags are:
+ -installation-state=
+ If non-empty, specifies allowed installation states (all others installations
+ get filtered out). The value of the flag is a comma-separated list of values
+ from among: [Active Uninstalled].
+ -instance-state=
+ If non-empty, specifies allowed instance states (all other instances get
+ filtered out). The value of the flag is a comma-separated list of values from
+ among: [Launching Running Dying NotRunning Updating Deleted].
+ -only-installations=false
+ If set, only consider installations.
+ -only-instances=false
+ If set, only consider instances.
+ -parallelism=BYKIND
+ Specifies the level of parallelism for the handler execution. One of: [BYKIND
+ FULL NONE].
+
Device status
Get the status of the device manager or application instances and installations.
Usage:
- device status <name patterns...>
+ device status [flags] <name patterns...>
<name patterns...> are vanadium object names or glob name patterns corresponding
to the device manager service, or to application installations and instances.
+The device status flags are:
+ -installation-state=
+ If non-empty, specifies allowed installation states (all others installations
+ get filtered out). The value of the flag is a comma-separated list of values
+ from among: [Active Uninstalled].
+ -instance-state=
+ If non-empty, specifies allowed instance states (all other instances get
+ filtered out). The value of the flag is a comma-separated list of values from
+ among: [Launching Running Dying NotRunning Updating Deleted].
+ -only-installations=false
+ If set, only consider installations.
+ -only-instances=false
+ If set, only consider instances.
+ -parallelism=FULL
+ Specifies the level of parallelism for the handler execution. One of: [BYKIND
+ FULL NONE].
+
Device debug
Get internal debug information about application installations and instances.
Usage:
- device debug <app name patterns...>
+ device debug [flags] <app name patterns...>
<app name patterns...> are vanadium object names or glob name patterns
corresponding to application installations and instances.
+The device debug flags are:
+ -installation-state=
+ If non-empty, specifies allowed installation states (all others installations
+ get filtered out). The value of the flag is a comma-separated list of values
+ from among: [Active Uninstalled].
+ -instance-state=
+ If non-empty, specifies allowed instance states (all other instances get
+ filtered out). The value of the flag is a comma-separated list of values from
+ among: [Launching Running Dying NotRunning Updating Deleted].
+ -only-installations=false
+ If set, only consider installations.
+ -only-instances=false
+ If set, only consider instances.
+ -parallelism=FULL
+ Specifies the level of parallelism for the handler execution. One of: [BYKIND
+ FULL NONE].
+
Device acl - Tool for setting device manager Permissions
The acl tool manages Permissions on the device manger, installations and
@@ -406,11 +459,28 @@
List application installations or instances.
Usage:
- device ls <app name patterns...>
+ device ls [flags] <app name patterns...>
<app name patterns...> are vanadium object names or glob name patterns
corresponding to application installations and instances.
+The device ls flags are:
+ -installation-state=
+ If non-empty, specifies allowed installation states (all others installations
+ get filtered out). The value of the flag is a comma-separated list of values
+ from among: [Active Uninstalled].
+ -instance-state=
+ If non-empty, specifies allowed instance states (all other instances get
+ filtered out). The value of the flag is a comma-separated list of values from
+ among: [Launching Running Dying NotRunning Updating Deleted].
+ -only-installations=false
+ If set, only consider installations.
+ -only-instances=false
+ If set, only consider instances.
+ -parallelism=FULL
+ Specifies the level of parallelism for the handler execution. One of: [BYKIND
+ FULL NONE].
+
Device help - Display help for commands or topics
Help with no args displays the usage of the parent command.
diff --git a/services/device/device/glob.go b/services/device/device/glob.go
index 63a0e4c..523e3ec 100644
--- a/services/device/device/glob.go
+++ b/services/device/device/glob.go
@@ -33,7 +33,10 @@
// and can be run concurrently. The handler should direct its output to the
// given stdout and stderr writers.
//
-// Typical usage:
+// There are three usage patterns, depending on the desired level of control
+// over the execution flow and settings manipulation.
+//
+// (1) Most control
//
// func myCmdHandler(entry globResult, ctx *context.T, stdout, stderr io.Writer) error {
// output := myCmdProcessing(entry)
@@ -43,7 +46,7 @@
//
// func runMyCmd(ctx *context.T, env *cmdline.Env, args []string) error {
// ...
-// err := run(ctx, env, args, myCmdHandler)
+// err := run(ctx, env, args, myCmdHandler, globSettings{})
// ...
// }
//
@@ -52,18 +55,35 @@
// ...
// }
//
-// Alternatively, if all runMyCmd does is to call run, you can use globRunner to
-// avoid having to define runMyCmd:
+// (2) Pre-packaged runner
+//
+// If all runMyCmd does is to call run, you can use globRunner to avoid having
+// to define runMyCmd:
//
// var cmdMyCmd = &cmdline.Command {
-// Runner: globRunner(myCmdHandler)
+// Runner: globRunner(myCmdHandler, &globSettings{}),
+// Name: "mycmd",
// ...
// }
+//
+// (3) Pre-packaged runner and glob settings flag configuration
+//
+// If, additionally, you want the globSettings to be configurable with
+// command-line flags, you can use globify instead:
+//
+// var cmdMyCmd = &cmdline.Command {
+// Name: "mycmd",
+// ...
+// }
+//
+// func init() {
+// globify(cmdMyCmd, myCmdHandler, &globSettings{}),
+// }
type globHandler func(entry globResult, ctx *context.T, stdout, stderr io.Writer) error
-func globRunner(handler globHandler) cmdline.Runner {
+func globRunner(handler globHandler, s *globSettings) cmdline.Runner {
return v23cmd.RunnerFunc(func(ctx *context.T, env *cmdline.Env, args []string) error {
- return run(ctx, env, args, handler)
+ return run(ctx, env, args, handler, *s)
})
}
@@ -113,10 +133,10 @@
// (instance/installation) and state. No de-duping of results is performed.
// The outputs from each of the handlers are sorted: installations first, then
// instances (and alphabetically by object name for each group).
-func run(ctx *context.T, env *cmdline.Env, args []string, handler globHandler) error {
+func run(ctx *context.T, env *cmdline.Env, args []string, handler globHandler, s globSettings) error {
results := glob(ctx, env, args)
sort.Sort(byTypeAndName(results))
- results = filterResults(results)
+ results = filterResults(results, s)
stdouts, stderrs := make([]bytes.Buffer, len(results)), make([]bytes.Buffer, len(results))
var errorCounter uint32 = 0
perResult := func(r globResult, index int) {
@@ -126,7 +146,7 @@
}
}
// TODO(caprita): Add unit test logic to cover all parallelism options.
- switch handlerParallelism {
+ switch s.handlerParallelism {
case fullParallelism:
var wg sync.WaitGroup
for i, r := range results {
@@ -172,16 +192,16 @@
return nil
}
-func filterResults(results []globResult) []globResult {
+func filterResults(results []globResult, s globSettings) []globResult {
var ret []globResult
for _, r := range results {
- switch s := r.status.(type) {
+ switch status := r.status.(type) {
case device.StatusInstance:
- if onlyInstallations || !instanceStateFilter.apply(s.Value.State) {
+ if s.onlyInstallations || !s.instanceStateFilter.apply(status.Value.State) {
continue
}
case device.StatusInstallation:
- if onlyInstances || !installationStateFilter.apply(s.Value.State) {
+ if s.onlyInstances || !s.installationStateFilter.apply(status.Value.State) {
continue
}
}
@@ -361,8 +381,6 @@
kindParallelism: "BYKIND",
}
-const defaultParallelism = kindParallelism
-
func init() {
if len(parallelismStrings) != int(sentinelParallelismFlag) {
panic(fmt.Sprintf("broken invariant: mismatching number of parallelism types"))
@@ -387,35 +405,52 @@
return fmt.Errorf("unrecognized parallelism type: %v", s)
}
-var (
+type globSettings struct {
instanceStateFilter instanceStateFlag
installationStateFilter installationStateFlag
onlyInstances bool
onlyInstallations bool
- handlerParallelism parallelismFlag = defaultParallelism
-)
+ handlerParallelism parallelismFlag
+ defaults *globSettings
+}
-func init() {
- // NOTE: When addind new flags or changing default values, remember to
- // also update ResetGlobFlags below.
- flag.Var(&instanceStateFilter, "instance-state", fmt.Sprintf("If non-empty, specifies allowed instance states (all other instances get filtered out). The value of the flag is a comma-separated list of values from among: %v.", device.InstanceStateAll))
- flag.Var(&installationStateFilter, "installation-state", fmt.Sprintf("If non-empty, specifies allowed installation states (all others installations get filtered out). The value of the flag is a comma-separated list of values from among: %v.", device.InstallationStateAll))
- flag.BoolVar(&onlyInstances, "only-instances", false, "If set, only consider instances.")
- flag.BoolVar(&onlyInstallations, "only-installations", false, "If set, only consider installations.")
+func (s *globSettings) reset() {
+ d := s.defaults
+ *s = *d
+ s.defaults = d
+}
+
+func (s *globSettings) setDefaults(d globSettings) {
+ s.defaults = new(globSettings)
+ *s.defaults = d
+}
+
+var allGlobSettings []*globSettings
+
+// ResetGlobSettings is meant for tests to restore the values of flag-configured
+// variables when running multiple commands in the same process.
+func ResetGlobSettings() {
+ for _, s := range allGlobSettings {
+ s.reset()
+ }
+}
+
+func defineGlobFlags(fs *flag.FlagSet, s *globSettings) {
+ fs.Var(&s.instanceStateFilter, "instance-state", fmt.Sprintf("If non-empty, specifies allowed instance states (all other instances get filtered out). The value of the flag is a comma-separated list of values from among: %v.", device.InstanceStateAll))
+ fs.Var(&s.installationStateFilter, "installation-state", fmt.Sprintf("If non-empty, specifies allowed installation states (all others installations get filtered out). The value of the flag is a comma-separated list of values from among: %v.", device.InstallationStateAll))
+ fs.BoolVar(&s.onlyInstances, "only-instances", false, "If set, only consider instances.")
+ fs.BoolVar(&s.onlyInstallations, "only-installations", false, "If set, only consider installations.")
var parallelismValues []string
for _, v := range parallelismStrings {
parallelismValues = append(parallelismValues, v)
}
sort.Strings(parallelismValues)
- flag.Var(&handlerParallelism, "parallelism", "Specifies the level of parallelism for the handler execution. One of: "+strings.Join(parallelismValues, ","))
+ fs.Var(&s.handlerParallelism, "parallelism", fmt.Sprintf("Specifies the level of parallelism for the handler execution. One of: %v.", parallelismValues))
}
-// ResetGlobFlags is meant for tests to restore the values of flag-configured
-// variables when running multiple commands in the same process.
-func ResetGlobFlags() {
- instanceStateFilter = make(instanceStateFlag)
- installationStateFilter = make(installationStateFlag)
- onlyInstances = false
- onlyInstallations = false
- handlerParallelism = defaultParallelism
+func globify(c *cmdline.Command, handler globHandler, s *globSettings) {
+ s.setDefaults(*s)
+ defineGlobFlags(&c.Flags, s)
+ c.Runner = globRunner(handler, s)
+ allGlobSettings = append(allGlobSettings, s)
}
diff --git a/services/device/device/ls.go b/services/device/device/ls.go
index 80939da..9767abc 100644
--- a/services/device/device/ls.go
+++ b/services/device/device/ls.go
@@ -14,7 +14,6 @@
)
var cmdLs = &cmdline.Command{
- Runner: globRunner(runLs),
Name: "ls",
Short: "List applications.",
Long: "List application installations or instances.",
@@ -23,6 +22,10 @@
<app name patterns...> are vanadium object names or glob name patterns corresponding to application installations and instances.`,
}
+func init() {
+ globify(cmdLs, runLs, new(globSettings))
+}
+
func runLs(entry globResult, _ *context.T, stdout, _ io.Writer) error {
fmt.Fprintf(stdout, "%v\n", entry.name)
return nil
diff --git a/services/device/device/ls_test.go b/services/device/device/ls_test.go
index 420dd05..1db54f4 100644
--- a/services/device/device/ls_test.go
+++ b/services/device/device/ls_test.go
@@ -159,6 +159,6 @@
if expected, got := c.expected, strings.TrimSpace(stdout.String()); got != expected {
t.Errorf("Unexpected output from ls. Got %q, expected %q", got, expected)
}
- cmd_device.ResetGlobFlags()
+ cmd_device.ResetGlobSettings()
}
}
diff --git a/services/device/device/status.go b/services/device/device/status.go
index d32430e..6123ec1 100644
--- a/services/device/device/status.go
+++ b/services/device/device/status.go
@@ -14,7 +14,6 @@
)
var cmdStatus = &cmdline.Command{
- Runner: globRunner(runStatus),
Name: "status",
Short: "Get device manager or application status.",
Long: "Get the status of the device manager or application instances and installations.",
@@ -23,6 +22,10 @@
<name patterns...> are vanadium object names or glob name patterns corresponding to the device manager service, or to application installations and instances.`,
}
+func init() {
+ globify(cmdStatus, runStatus, new(globSettings))
+}
+
func runStatus(entry globResult, _ *context.T, stdout, _ io.Writer) error {
switch s := entry.status.(type) {
case device.StatusInstance:
diff --git a/services/device/device/status_test.go b/services/device/device/status_test.go
index 4284226..0f2d8e0 100644
--- a/services/device/device/status_test.go
+++ b/services/device/device/status_test.go
@@ -69,5 +69,6 @@
if got, expected := appTape.Play(), []interface{}{"Status"}; !reflect.DeepEqual(expected, got) {
t.Errorf("invalid call sequence. Got %v, want %v", got, expected)
}
+ cmd_device.ResetGlobSettings()
}
}
diff --git a/services/device/device/update.go b/services/device/device/update.go
index e2d1f9a..33d7ecd 100644
--- a/services/device/device/update.go
+++ b/services/device/device/update.go
@@ -20,7 +20,6 @@
)
var cmdUpdate = &cmdline.Command{
- Runner: globRunner(runUpdate),
Name: "update",
Short: "Update the device manager or applications.",
Long: "Update the device manager or application instances and installations",
@@ -29,8 +28,11 @@
<name patterns...> are vanadium object names or glob name patterns corresponding to the device manager service, or to application installations and instances.`,
}
+func init() {
+ globify(cmdUpdate, runUpdate, &globSettings{handlerParallelism: kindParallelism})
+}
+
var cmdRevert = &cmdline.Command{
- Runner: globRunner(runRevert),
Name: "revert",
Short: "Revert the device manager or applications.",
Long: "Revert the device manager or application instances and installations to a previous version of their current version",
@@ -39,6 +41,10 @@
<name patterns...> are vanadium object names or glob name patterns corresponding to the device manager service, or to application installations and instances.`,
}
+func init() {
+ globify(cmdRevert, runRevert, &globSettings{handlerParallelism: kindParallelism})
+}
+
func instanceIsRunning(ctx *context.T, von string) (bool, error) {
status, err := device.ApplicationClient(von).Status(ctx)
if err != nil {
diff --git a/services/device/device/update_test.go b/services/device/device/update_test.go
index a6f0a40..07f7616 100644
--- a/services/device/device/update_test.go
+++ b/services/device/device/update_test.go
@@ -145,7 +145,7 @@
t.Errorf("Unexpected stimuli for %v. Want: %v, got %v.", n, want, got)
}
}
- cmd_device.ResetGlobFlags()
+ cmd_device.ResetGlobSettings()
}
}
}
diff --git a/services/mounttable/mounttablelib/mounttable.go b/services/mounttable/mounttablelib/mounttable.go
index a3582ff..2885228 100644
--- a/services/mounttable/mounttablelib/mounttable.go
+++ b/services/mounttable/mounttablelib/mounttable.go
@@ -70,7 +70,6 @@
serverCounter *stats.Integer
perUserNodeCounter *stats.Map
maxNodesPerUser int64
- userPrefixes []string
}
var _ rpc.Dispatcher = (*mountTable)(nil)
@@ -360,7 +359,7 @@
// findNode finds a node in the table and optionally creates a path to it.
//
// If a node is found, on return it and its parent are locked.
-func (mt *mountTable) findNode(ctx *context.T, call security.Call, elems []string, create bool, tags []mounttable.Tag) (*node, error) {
+func (mt *mountTable) findNode(ctx *context.T, call security.Call, elems []string, create bool, tags, ptags []mounttable.Tag) (*node, error) {
n, nelems, err := mt.traverse(ctx, call, elems, create)
if err != nil {
return nil, err
@@ -373,10 +372,18 @@
n.Unlock()
return nil, nil
}
+ // Either the node has to satisfy tags or the parent has to satisfy ptags.
if err := n.satisfies(mt, ctx, call, tags); err != nil {
- n.parent.Unlock()
- n.Unlock()
- return nil, err
+ if ptags == nil {
+ n.parent.Unlock()
+ n.Unlock()
+ return nil, err
+ }
+ if err := n.parent.satisfies(mt, ctx, call, ptags); err != nil {
+ n.parent.Unlock()
+ n.Unlock()
+ return nil, err
+ }
}
return n, nil
}
@@ -486,7 +493,7 @@
}
// Find/create node in namespace and add the mount.
- n, werr := mt.findNode(ctx, call.Security(), ms.elems, true, mountTags)
+ n, werr := mt.findNode(ctx, call.Security(), ms.elems, true, mountTags, nil)
if werr != nil {
return werr
}
@@ -579,7 +586,7 @@
func (ms *mountContext) Unmount(ctx *context.T, call rpc.ServerCall, server string) error {
vlog.VI(2).Infof("*********************Unmount %q, %s", ms.name, server)
mt := ms.mt
- n, err := mt.findNode(ctx, call.Security(), ms.elems, false, mountTags)
+ n, err := mt.findNode(ctx, call.Security(), ms.elems, false, mountTags, nil)
if err != nil {
return err
}
@@ -612,8 +619,9 @@
return verror.New(errCantDeleteRoot, ctx)
}
mt := ms.mt
- // Find and lock the parent node.
- n, err := mt.findNode(ctx, call.Security(), ms.elems, false, removeTags)
+ // Find and lock the parent node and parent node. Either the node or its parent has
+ // to satisfy removeTags.
+ n, err := mt.findNode(ctx, call.Security(), ms.elems, false, removeTags, removeTags)
if err != nil {
return err
}
@@ -758,7 +766,7 @@
go func() {
defer close(ch)
// If there was an access error, just ignore the entry, i.e., make it invisible.
- n, err := mt.findNode(ctx, scall, ms.elems, false, nil)
+ n, err := mt.findNode(ctx, scall, ms.elems, false, nil, nil)
if err != nil {
return
}
@@ -793,7 +801,7 @@
mt := ms.mt
// Find/create node in namespace and add the mount.
- n, err := mt.findNode(ctx, call.Security(), ms.elems, true, setTags)
+ n, err := mt.findNode(ctx, call.Security(), ms.elems, true, setTags, nil)
if err != nil {
return err
}
@@ -839,7 +847,7 @@
mt := ms.mt
// Find node in namespace and add the mount.
- n, err := mt.findNode(ctx, call.Security(), ms.elems, false, getTags)
+ n, err := mt.findNode(ctx, call.Security(), ms.elems, false, getTags, nil)
if err != nil {
return nil, "", err
}
@@ -864,8 +872,7 @@
if !ok {
return "", verror.New(errTooManyNodes, ctx)
}
- // If we have no prefixes defining users, don't bother with checking per user limits.
- if len(mt.userPrefixes) != 0 && count > mt.maxNodesPerUser {
+ if count > mt.maxNodesPerUser {
mt.perUserNodeCounter.Incr(creator, -1)
return "", verror.New(errTooManyNodes, ctx)
}
diff --git a/services/mounttable/mounttablelib/mounttable_test.go b/services/mounttable/mounttablelib/mounttable_test.go
index a8f9e7f..21a2f29 100644
--- a/services/mounttable/mounttablelib/mounttable_test.go
+++ b/services/mounttable/mounttablelib/mounttable_test.go
@@ -17,6 +17,7 @@
"v.io/v23"
"v.io/v23/context"
+ "v.io/v23/conventions"
"v.io/v23/naming"
"v.io/v23/options"
"v.io/v23/rpc"
@@ -483,7 +484,7 @@
{"alice", int64(defaultMaxNodesPerUser)},
{"bob", int64(0)},
{"root", int64(0)},
- {localUser, int64(3)},
+ {conventions.ServerUser, int64(3)},
}
for _, tc := range testcases {
name := "testAccessListTemplate/num-nodes-per-user/" + tc.key
@@ -601,6 +602,12 @@
checkExists(t, rootCtx, estr, "one/bright/day", false)
doDeleteNode(t, bobCtx, estr, "one/bright", true)
checkExists(t, rootCtx, estr, "one/bright", false)
+
+ // Make sure directory admin can delete directory children.
+ perms := access.Permissions{"Admin": access.AccessList{In: []security.BlessingPattern{"bob"}}}
+ doSetPermissions(t, bobCtx, estr, "hoohaa", perms, "", false)
+ doDeleteNode(t, rootCtx, estr, "hoohaa", true)
+ checkExists(t, rootCtx, estr, "hoohaa", false)
}
func TestServerFormat(t *testing.T) {
diff --git a/services/mounttable/mounttablelib/persistentstore.go b/services/mounttable/mounttablelib/persistentstore.go
index 0cb614d..a96eb19 100644
--- a/services/mounttable/mounttablelib/persistentstore.go
+++ b/services/mounttable/mounttablelib/persistentstore.go
@@ -131,7 +131,7 @@
}
elems := strings.Split(e.N, "/")
- n, err := mt.findNode(nil, nil, elems, true, nil)
+ n, err := mt.findNode(nil, nil, elems, true, nil, nil)
if n != nil || err == nil {
n.creator = e.C
if e.D {
diff --git a/services/mounttable/mounttablelib/versionedpermissions.go b/services/mounttable/mounttablelib/versionedpermissions.go
index 95a044a..d4da750 100644
--- a/services/mounttable/mounttablelib/versionedpermissions.go
+++ b/services/mounttable/mounttablelib/versionedpermissions.go
@@ -8,12 +8,12 @@
"encoding/json"
"io"
"os"
- "reflect"
"sort"
"strconv"
"strings"
"v.io/v23/context"
+ "v.io/v23/conventions"
"v.io/v23/security"
"v.io/v23/security/access"
"v.io/v23/services/mounttable"
@@ -143,17 +143,11 @@
}
// Create name and add the Permissions map to it.
- n, err := mt.findNode(nil, nil, elems, true, nil)
+ n, err := mt.findNode(nil, nil, elems, true, nil, nil)
if n != nil || err == nil {
vlog.VI(2).Infof("added perms %v to %s", perms, name)
if isPattern {
n.permsTemplate = perms
- // Save the pattern prefix as a prefix describing a user.
- prefix := strings.Join(elems[:len(elems)-1], "/")
- if prefix != "" {
- prefix += "/"
- }
- mt.userPrefixes = append(mt.userPrefixes, prefix)
} else {
n.vPerms, _ = n.vPerms.Set(nil, "", perms)
n.explicitPermissions = true
@@ -166,37 +160,9 @@
return nil
}
-// pickCreator returns a string matching the blessing of the user performing the creation. We do this using
-// the user prefixes found when parsing the config. Eventually we may need a better way to define user
-// prefixes.
-//
-// TODO(p): readdress this argument after we have some experience with real users.
+// pickCreator returns a string matching the blessing of the user performing the creation.
func (mt *mountTable) pickCreator(ctx *context.T, call security.Call) string {
- // For each blessing, look for one that has a matching user prefix. The creator is the perfix
- // plus one more element.
- //
- // The prefixes themselves come from the templates in the config that constrain node names to
- // match the user.
- blessings, _ := security.RemoteBlessingNames(ctx, call)
- for _, b := range blessings {
- for _, p := range mt.userPrefixes {
- sb := string(b)
- if !strings.HasPrefix(sb, p) {
- continue
- }
- suffix := strings.TrimPrefix(sb, p)
- elems := strings.Split(suffix, "/")
- return p + elems[0]
- }
- }
- if ctx == nil || call == nil {
- return localUser
- }
- if l, r := call.LocalBlessings().PublicKey(), call.RemoteBlessings().PublicKey(); l != nil && reflect.DeepEqual(l, r) {
- return localUser
- }
- if len(blessings) > 0 {
- return blessedUser
- }
- return unknownUser
+ ids := conventions.GetClientUserIds(ctx, call)
+ // Replace the slashes with something else or we'll confuse the stats package.
+ return strings.Replace(ids[0], "/", "\\", 0)
}