blob: 5046a0932650b0ea01ef62fcd5e75a3276dafcb6 [file] [log] [blame]
Robin Thellend18205cf2014-10-21 13:53:59 -07001package main
Robin Thellend6b17da72014-05-14 09:55:14 -07002
3import (
Robin Thellend39ac3232014-12-02 09:50:41 -08004 "errors"
Robin Thellend6b17da72014-05-14 09:55:14 -07005 "fmt"
Robin Thellend6b17da72014-05-14 09:55:14 -07006 "time"
7
Matt Rosencrantz6edab562015-01-12 11:07:55 -08008 "v.io/core/veyron2"
Matt Rosencrantz89445a42015-01-05 13:32:37 -08009 "v.io/core/veyron2/context"
Jiri Simsa764efb72014-12-25 20:57:03 -080010 "v.io/core/veyron2/ipc"
11 "v.io/core/veyron2/naming"
12 "v.io/core/veyron2/options"
Todd Wang478fcf92014-12-26 12:37:37 -080013 "v.io/lib/cmdline"
Robin Thellend6b17da72014-05-14 09:55:14 -070014)
15
16var cmdGlob = &cmdline.Command{
17 Run: runGlob,
18 Name: "glob",
19 Short: "returns all matching entries in the mount table",
20 Long: "returns all matching entries in the mount table",
Bogdan Capritadecd1052014-11-08 16:15:54 -080021 ArgsName: "[<mount name>] <pattern>",
Robin Thellend6b17da72014-05-14 09:55:14 -070022 ArgsLong: `
Bogdan Capritadecd1052014-11-08 16:15:54 -080023<mount name> is a mount name on a mount table. Defaults to namespace root.
Robin Thellend6b17da72014-05-14 09:55:14 -070024<pattern> is a glob pattern that is matched against all the entries below the
25specified mount name.
26`,
27}
28
29func runGlob(cmd *cmdline.Command, args []string) error {
Matt Rosencrantza5ad2722015-01-22 11:17:47 -080030 ctx, cancel := context.WithTimeout(gctx, time.Minute)
Matt Rosencrantzd599e382015-01-12 11:13:32 -080031 defer cancel()
32
Bogdan Capritadecd1052014-11-08 16:15:54 -080033 if len(args) == 1 {
Matt Rosencrantzd599e382015-01-12 11:13:32 -080034 roots := veyron2.GetNamespace(ctx).Roots()
Robin Thellend39ac3232014-12-02 09:50:41 -080035 if len(roots) == 0 {
36 return errors.New("no namespace root")
37 }
38 args = append([]string{roots[0]}, args...)
Bogdan Capritadecd1052014-11-08 16:15:54 -080039 }
Robin Thellend6b17da72014-05-14 09:55:14 -070040 if expected, got := 2, len(args); expected != got {
Todd Wanga615e4d2014-09-29 16:56:05 -070041 return cmd.UsageErrorf("glob: incorrect number of arguments, expected %d, got %d", expected, got)
Robin Thellend6b17da72014-05-14 09:55:14 -070042 }
Matt Rosencrantzd599e382015-01-12 11:13:32 -080043
Robin Thellend39ac3232014-12-02 09:50:41 -080044 name, pattern := args[0], args[1]
Matt Rosencrantz6edab562015-01-12 11:07:55 -080045 client := veyron2.GetClient(ctx)
46 call, err := client.StartCall(ctx, name, ipc.GlobMethod, []interface{}{pattern}, options.NoResolve{})
Robin Thellend6b17da72014-05-14 09:55:14 -070047 if err != nil {
48 return err
49 }
Robin Thellend39ac3232014-12-02 09:50:41 -080050 for {
51 var me naming.VDLMountEntry
52 if err := call.Recv(&me); err != nil {
53 break
54 }
55 fmt.Fprint(cmd.Stdout(), me.Name)
56 for _, s := range me.Servers {
Robin Thellend6b17da72014-05-14 09:55:14 -070057 fmt.Fprintf(cmd.Stdout(), " %s (TTL %s)", s.Server, time.Duration(s.TTL)*time.Second)
58 }
59 fmt.Fprintln(cmd.Stdout())
60 }
Robin Thellend39ac3232014-12-02 09:50:41 -080061 if ferr := call.Finish(&err); ferr != nil {
62 err = ferr
Shyam Jayaramanc4aed6e2014-07-22 14:25:06 -070063 }
Robin Thellend39ac3232014-12-02 09:50:41 -080064 return err
Robin Thellend6b17da72014-05-14 09:55:14 -070065}
66
67var cmdMount = &cmdline.Command{
68 Run: runMount,
69 Name: "mount",
70 Short: "Mounts a server <name> onto a mount table",
71 Long: "Mounts a server <name> onto a mount table",
72 ArgsName: "<mount name> <name> <ttl>",
73 ArgsLong: `
74<mount name> is a mount name on a mount table.
Bogdan Capritad9281a32014-07-02 14:40:39 -070075<name> is the rooted object name of the server.
Robin Thellend6b17da72014-05-14 09:55:14 -070076<ttl> is the TTL of the new entry. It is a decimal number followed by a unit
77suffix (s, m, h). A value of 0s represents an infinite duration.
78`,
79}
80
81func runMount(cmd *cmdline.Command, args []string) error {
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070082 got := len(args)
83 if got < 2 || got > 4 {
84 return cmd.UsageErrorf("mount: incorrect number of arguments, expected 2, 3, or 4, got %d", got)
85 }
Todd Wang1aa57692014-11-11 13:53:29 -080086 var flags naming.MountFlag
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070087 var seconds uint32
88 if got >= 3 {
89 ttl, err := time.ParseDuration(args[2])
90 if err != nil {
91 return fmt.Errorf("TTL parse error: %v", err)
92 }
93 seconds = uint32(ttl.Seconds())
94 }
95 if got >= 4 {
96 for _, c := range args[3] {
97 switch c {
98 case 'M':
Todd Wang1aa57692014-11-11 13:53:29 -080099 flags |= naming.MountFlag(naming.MT)
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -0700100 case 'R':
Todd Wang1aa57692014-11-11 13:53:29 -0800101 flags |= naming.MountFlag(naming.Replace)
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -0700102 }
103 }
Robin Thellend6b17da72014-05-14 09:55:14 -0700104 }
Matt Rosencrantza5ad2722015-01-22 11:17:47 -0800105 ctx, cancel := context.WithTimeout(gctx, time.Minute)
Matt Rosencrantz137b8d22014-08-18 09:56:15 -0700106 defer cancel()
Matt Rosencrantz6edab562015-01-12 11:07:55 -0800107 client := veyron2.GetClient(ctx)
108 call, err := client.StartCall(ctx, args[0], "Mount", []interface{}{args[1], seconds, 0}, options.NoResolve{})
Robin Thellend6b17da72014-05-14 09:55:14 -0700109 if err != nil {
110 return err
111 }
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -0700112 if ierr := call.Finish(&err); ierr != nil {
Robin Thellend39ac3232014-12-02 09:50:41 -0800113 err = ierr
114 }
115 if err != nil {
116 return err
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -0700117 }
Robin Thellend6b17da72014-05-14 09:55:14 -0700118
119 fmt.Fprintln(cmd.Stdout(), "Name mounted successfully.")
120 return nil
121}
122
123var cmdUnmount = &cmdline.Command{
124 Run: runUnmount,
125 Name: "unmount",
126 Short: "removes server <name> from the mount table",
127 Long: "removes server <name> from the mount table",
128 ArgsName: "<mount name> <name>",
129 ArgsLong: `
130<mount name> is a mount name on a mount table.
Bogdan Capritad9281a32014-07-02 14:40:39 -0700131<name> is the rooted object name of the server.
Robin Thellend6b17da72014-05-14 09:55:14 -0700132`,
133}
134
135func runUnmount(cmd *cmdline.Command, args []string) error {
136 if expected, got := 2, len(args); expected != got {
Todd Wanga615e4d2014-09-29 16:56:05 -0700137 return cmd.UsageErrorf("unmount: incorrect number of arguments, expected %d, got %d", expected, got)
Robin Thellend6b17da72014-05-14 09:55:14 -0700138 }
Matt Rosencrantza5ad2722015-01-22 11:17:47 -0800139 ctx, cancel := context.WithTimeout(gctx, time.Minute)
Matt Rosencrantz137b8d22014-08-18 09:56:15 -0700140 defer cancel()
Matt Rosencrantz6edab562015-01-12 11:07:55 -0800141 client := veyron2.GetClient(ctx)
142 call, err := client.StartCall(ctx, args[0], "Unmount", []interface{}{args[1]}, options.NoResolve{})
Robin Thellend6b17da72014-05-14 09:55:14 -0700143 if err != nil {
144 return err
145 }
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -0700146 if ierr := call.Finish(&err); ierr != nil {
Robin Thellend39ac3232014-12-02 09:50:41 -0800147 err = ierr
148 }
149 if err != nil {
150 return err
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -0700151 }
Robin Thellend6b17da72014-05-14 09:55:14 -0700152
153 fmt.Fprintln(cmd.Stdout(), "Name unmounted successfully.")
Robin Thellend39ac3232014-12-02 09:50:41 -0800154 return err
Robin Thellend6b17da72014-05-14 09:55:14 -0700155}
156
157var cmdResolveStep = &cmdline.Command{
158 Run: runResolveStep,
159 Name: "resolvestep",
160 Short: "takes the next step in resolving a name.",
161 Long: "takes the next step in resolving a name.",
162 ArgsName: "<mount name>",
163 ArgsLong: `
164<mount name> is a mount name on a mount table.
165`,
166}
167
168func runResolveStep(cmd *cmdline.Command, args []string) error {
169 if expected, got := 1, len(args); expected != got {
Todd Wanga615e4d2014-09-29 16:56:05 -0700170 return cmd.UsageErrorf("mount: incorrect number of arguments, expected %d, got %d", expected, got)
Robin Thellend6b17da72014-05-14 09:55:14 -0700171 }
Matt Rosencrantza5ad2722015-01-22 11:17:47 -0800172 ctx, cancel := context.WithTimeout(gctx, time.Minute)
Matt Rosencrantz137b8d22014-08-18 09:56:15 -0700173 defer cancel()
Matt Rosencrantz6edab562015-01-12 11:07:55 -0800174 client := veyron2.GetClient(ctx)
David Why Use Two When One Will Do Presottod3aa6632015-01-20 10:15:39 -0800175 call, err := client.StartCall(ctx, args[0], "ResolveStep", []interface{}{}, options.NoResolve{})
Robin Thellend6b17da72014-05-14 09:55:14 -0700176 if err != nil {
David Why Use Two When One Will Do Presotto8b4dbbf2014-11-06 10:50:14 -0800177 return err
Robin Thellend6b17da72014-05-14 09:55:14 -0700178 }
Todd Wang1aa57692014-11-11 13:53:29 -0800179 var entry naming.VDLMountEntry
David Why Use Two When One Will Do Presotto8b4dbbf2014-11-06 10:50:14 -0800180 if ierr := call.Finish(&entry, &err); ierr != nil {
Robin Thellend39ac3232014-12-02 09:50:41 -0800181 err = ierr
David Why Use Two When One Will Do Presotto8b4dbbf2014-11-06 10:50:14 -0800182 }
Robin Thellend6b17da72014-05-14 09:55:14 -0700183 if err != nil {
184 return err
185 }
186
David Why Use Two When One Will Do Presotto6f9f5742014-10-20 16:27:05 -0700187 fmt.Fprintf(cmd.Stdout(), "Servers: %v Suffix: %q MT: %v\n", entry.Servers, entry.Name, entry.MT)
Robin Thellend6b17da72014-05-14 09:55:14 -0700188 return nil
189}
190
Robin Thellend18205cf2014-10-21 13:53:59 -0700191func root() *cmdline.Command {
Robin Thellend6b17da72014-05-14 09:55:14 -0700192 return &cmdline.Command{
Todd Wangfcb72a52014-10-01 09:53:56 -0700193 Name: "mounttable",
194 Short: "Tool for interacting with a Veyron mount table",
195 Long: `
196The mounttable tool facilitates interaction with a Veyron mount table.
197`,
Robin Thellend6b17da72014-05-14 09:55:14 -0700198 Children: []*cmdline.Command{cmdGlob, cmdMount, cmdUnmount, cmdResolveStep},
199 }
200}