blob: 8778b54c949dbd65a1d15dbb3fcf2d5c4a9e963f [file] [log] [blame]
Robin Thellend18205cf2014-10-21 13:53:59 -07001package main
Robin Thellend6b17da72014-05-14 09:55:14 -07002
3import (
4 "fmt"
Robin Thellend6b17da72014-05-14 09:55:14 -07005 "time"
6
Jiri Simsa519c5072014-09-17 21:37:57 -07007 "veyron.io/veyron/veyron/lib/cmdline"
Robin Thellend6b17da72014-05-14 09:55:14 -07008
Jiri Simsa519c5072014-09-17 21:37:57 -07009 "veyron.io/veyron/veyron2/context"
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070010 "veyron.io/veyron/veyron2/naming"
11 "veyron.io/veyron/veyron2/options"
Jiri Simsa519c5072014-09-17 21:37:57 -070012 "veyron.io/veyron/veyron2/rt"
13 "veyron.io/veyron/veyron2/services/mounttable"
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070014 "veyron.io/veyron/veyron2/services/mounttable/types"
Robin Thellend6b17da72014-05-14 09:55:14 -070015)
16
Todd Wang702385a2014-11-07 01:54:08 -080017func bindMT(ctx context.T, name string) (mounttable.MountTableClientMethods, error) {
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070018 e, err := rt.R().Namespace().ResolveToMountTableX(ctx, name)
Bogdan Caprita4a021b12014-05-22 10:40:59 -070019 if err != nil {
20 return nil, err
21 }
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070022 if len(e.Servers) == 0 {
Bogdan Caprita4a021b12014-05-22 10:40:59 -070023 return nil, fmt.Errorf("Failed to find any mount tables at %q", name)
24 }
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070025 var servers []string
26 for _, s := range e.Servers {
27 servers = append(servers, naming.JoinAddressName(s.Server, e.Name))
28 }
29 fmt.Println(servers)
Todd Wang702385a2014-11-07 01:54:08 -080030 return mounttable.MountTableClient(servers[0]), nil
Bogdan Caprita4a021b12014-05-22 10:40:59 -070031}
32
Robin Thellend6b17da72014-05-14 09:55:14 -070033var cmdGlob = &cmdline.Command{
34 Run: runGlob,
35 Name: "glob",
36 Short: "returns all matching entries in the mount table",
37 Long: "returns all matching entries in the mount table",
Bogdan Capritadecd1052014-11-08 16:15:54 -080038 ArgsName: "[<mount name>] <pattern>",
Robin Thellend6b17da72014-05-14 09:55:14 -070039 ArgsLong: `
Bogdan Capritadecd1052014-11-08 16:15:54 -080040<mount name> is a mount name on a mount table. Defaults to namespace root.
Robin Thellend6b17da72014-05-14 09:55:14 -070041<pattern> is a glob pattern that is matched against all the entries below the
42specified mount name.
43`,
44}
45
46func runGlob(cmd *cmdline.Command, args []string) error {
Bogdan Capritadecd1052014-11-08 16:15:54 -080047 if len(args) == 1 {
48 args = append([]string{""}, args...)
49 }
Robin Thellend6b17da72014-05-14 09:55:14 -070050 if expected, got := 2, len(args); expected != got {
Todd Wanga615e4d2014-09-29 16:56:05 -070051 return cmd.UsageErrorf("glob: incorrect number of arguments, expected %d, got %d", expected, got)
Robin Thellend6b17da72014-05-14 09:55:14 -070052 }
Matt Rosencrantz137b8d22014-08-18 09:56:15 -070053 ctx, cancel := rt.R().NewContext().WithTimeout(time.Minute)
54 defer cancel()
55 c, err := bindMT(ctx, args[0])
Robin Thellend6b17da72014-05-14 09:55:14 -070056 if err != nil {
57 return fmt.Errorf("bind error: %v", err)
58 }
Matt Rosencrantz137b8d22014-08-18 09:56:15 -070059 stream, err := c.Glob(ctx, args[1])
Robin Thellend6b17da72014-05-14 09:55:14 -070060 if err != nil {
61 return err
62 }
Shyam Jayaraman97b9dca2014-07-31 13:30:46 -070063 rStream := stream.RecvStream()
64 for rStream.Advance() {
65 buf := rStream.Value()
Shyam Jayaramanc4aed6e2014-07-22 14:25:06 -070066
Robin Thellend6b17da72014-05-14 09:55:14 -070067 fmt.Fprint(cmd.Stdout(), buf.Name)
68 for _, s := range buf.Servers {
69 fmt.Fprintf(cmd.Stdout(), " %s (TTL %s)", s.Server, time.Duration(s.TTL)*time.Second)
70 }
71 fmt.Fprintln(cmd.Stdout())
72 }
Shyam Jayaramanc4aed6e2014-07-22 14:25:06 -070073
Shyam Jayaraman97b9dca2014-07-31 13:30:46 -070074 if err := rStream.Err(); err != nil {
Shyam Jayaramanc4aed6e2014-07-22 14:25:06 -070075 return fmt.Errorf("advance error: %v", err)
76 }
Robin Thellend6b17da72014-05-14 09:55:14 -070077 err = stream.Finish()
78 if err != nil {
79 return fmt.Errorf("finish error: %v", err)
80 }
81 return nil
82}
83
84var cmdMount = &cmdline.Command{
85 Run: runMount,
86 Name: "mount",
87 Short: "Mounts a server <name> onto a mount table",
88 Long: "Mounts a server <name> onto a mount table",
89 ArgsName: "<mount name> <name> <ttl>",
90 ArgsLong: `
91<mount name> is a mount name on a mount table.
Bogdan Capritad9281a32014-07-02 14:40:39 -070092<name> is the rooted object name of the server.
Robin Thellend6b17da72014-05-14 09:55:14 -070093<ttl> is the TTL of the new entry. It is a decimal number followed by a unit
94suffix (s, m, h). A value of 0s represents an infinite duration.
95`,
96}
97
98func runMount(cmd *cmdline.Command, args []string) error {
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070099 got := len(args)
100 if got < 2 || got > 4 {
101 return cmd.UsageErrorf("mount: incorrect number of arguments, expected 2, 3, or 4, got %d", got)
102 }
103 var flags types.MountFlag
104 var seconds uint32
105 if got >= 3 {
106 ttl, err := time.ParseDuration(args[2])
107 if err != nil {
108 return fmt.Errorf("TTL parse error: %v", err)
109 }
110 seconds = uint32(ttl.Seconds())
111 }
112 if got >= 4 {
113 for _, c := range args[3] {
114 switch c {
115 case 'M':
116 flags |= types.MountFlag(types.MT)
117 case 'R':
118 flags |= types.MountFlag(types.Replace)
119 }
120 }
Robin Thellend6b17da72014-05-14 09:55:14 -0700121 }
Matt Rosencrantz137b8d22014-08-18 09:56:15 -0700122 ctx, cancel := rt.R().NewContext().WithTimeout(time.Minute)
123 defer cancel()
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -0700124 call, err := rt.R().Client().StartCall(ctx, args[0], "Mount", []interface{}{args[1], seconds, 0}, options.NoResolve(true))
Robin Thellend6b17da72014-05-14 09:55:14 -0700125 if err != nil {
126 return err
127 }
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -0700128 if ierr := call.Finish(&err); ierr != nil {
129 return ierr
130 }
Robin Thellend6b17da72014-05-14 09:55:14 -0700131
132 fmt.Fprintln(cmd.Stdout(), "Name mounted successfully.")
133 return nil
134}
135
136var cmdUnmount = &cmdline.Command{
137 Run: runUnmount,
138 Name: "unmount",
139 Short: "removes server <name> from the mount table",
140 Long: "removes server <name> from the mount table",
141 ArgsName: "<mount name> <name>",
142 ArgsLong: `
143<mount name> is a mount name on a mount table.
Bogdan Capritad9281a32014-07-02 14:40:39 -0700144<name> is the rooted object name of the server.
Robin Thellend6b17da72014-05-14 09:55:14 -0700145`,
146}
147
148func runUnmount(cmd *cmdline.Command, args []string) error {
149 if expected, got := 2, len(args); expected != got {
Todd Wanga615e4d2014-09-29 16:56:05 -0700150 return cmd.UsageErrorf("unmount: incorrect number of arguments, expected %d, got %d", expected, got)
Robin Thellend6b17da72014-05-14 09:55:14 -0700151 }
Matt Rosencrantz137b8d22014-08-18 09:56:15 -0700152 ctx, cancel := rt.R().NewContext().WithTimeout(time.Minute)
153 defer cancel()
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -0700154 call, err := rt.R().Client().StartCall(ctx, args[0], "Unmount", []interface{}{args[1]}, options.NoResolve(true))
Robin Thellend6b17da72014-05-14 09:55:14 -0700155 if err != nil {
156 return err
157 }
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -0700158 if ierr := call.Finish(&err); ierr != nil {
159 return ierr
160 }
Robin Thellend6b17da72014-05-14 09:55:14 -0700161
162 fmt.Fprintln(cmd.Stdout(), "Name unmounted successfully.")
163 return nil
164}
165
166var cmdResolveStep = &cmdline.Command{
167 Run: runResolveStep,
168 Name: "resolvestep",
169 Short: "takes the next step in resolving a name.",
170 Long: "takes the next step in resolving a name.",
171 ArgsName: "<mount name>",
172 ArgsLong: `
173<mount name> is a mount name on a mount table.
174`,
175}
176
177func runResolveStep(cmd *cmdline.Command, args []string) error {
178 if expected, got := 1, len(args); expected != got {
Todd Wanga615e4d2014-09-29 16:56:05 -0700179 return cmd.UsageErrorf("mount: incorrect number of arguments, expected %d, got %d", expected, got)
Robin Thellend6b17da72014-05-14 09:55:14 -0700180 }
Matt Rosencrantz137b8d22014-08-18 09:56:15 -0700181 ctx, cancel := rt.R().NewContext().WithTimeout(time.Minute)
182 defer cancel()
David Why Use Two When One Will Do Presotto8b4dbbf2014-11-06 10:50:14 -0800183 call, err := rt.R().Client().StartCall(ctx, args[0], "ResolveStepX", []interface{}{}, options.NoResolve(true))
Robin Thellend6b17da72014-05-14 09:55:14 -0700184 if err != nil {
David Why Use Two When One Will Do Presotto8b4dbbf2014-11-06 10:50:14 -0800185 return err
Robin Thellend6b17da72014-05-14 09:55:14 -0700186 }
David Why Use Two When One Will Do Presotto8b4dbbf2014-11-06 10:50:14 -0800187 var entry types.MountEntry
188 if ierr := call.Finish(&entry, &err); ierr != nil {
189 return ierr
190 }
Robin Thellend6b17da72014-05-14 09:55:14 -0700191 if err != nil {
192 return err
193 }
194
David Why Use Two When One Will Do Presotto6f9f5742014-10-20 16:27:05 -0700195 fmt.Fprintf(cmd.Stdout(), "Servers: %v Suffix: %q MT: %v\n", entry.Servers, entry.Name, entry.MT)
Robin Thellend6b17da72014-05-14 09:55:14 -0700196 return nil
197}
198
Robin Thellend18205cf2014-10-21 13:53:59 -0700199func root() *cmdline.Command {
Robin Thellend6b17da72014-05-14 09:55:14 -0700200 return &cmdline.Command{
Todd Wangfcb72a52014-10-01 09:53:56 -0700201 Name: "mounttable",
202 Short: "Tool for interacting with a Veyron mount table",
203 Long: `
204The mounttable tool facilitates interaction with a Veyron mount table.
205`,
Robin Thellend6b17da72014-05-14 09:55:14 -0700206 Children: []*cmdline.Command{cmdGlob, cmdMount, cmdUnmount, cmdResolveStep},
207 }
208}