blob: b0104d5faca302599bdb9698091d7c0a48c99885 [file] [log] [blame]
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -07001package core
2
3import (
4 "fmt"
5 "io"
6 "os"
7 "strings"
8
Cosmos Nicolaou9ca249d2014-09-18 15:07:12 -07009 "veyron.io/veyron/veyron2/context"
Jiri Simsa519c5072014-09-17 21:37:57 -070010 "veyron.io/veyron/veyron2/naming"
Asim Shankarcc044212014-10-15 23:25:26 -070011 "veyron.io/veyron/veyron2/options"
Jiri Simsa519c5072014-09-17 21:37:57 -070012 "veyron.io/veyron/veyron2/rt"
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -070013
Jiri Simsa519c5072014-09-17 21:37:57 -070014 "veyron.io/veyron/veyron/lib/modules"
15 mounttable "veyron.io/veyron/veyron/services/mounttable/lib"
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -070016)
17
18func init() {
Cosmos Nicolaou1e78ccc2014-10-09 08:10:26 -070019 modules.RegisterChild(RootMTCommand, "", rootMountTable)
20 modules.RegisterChild(MTCommand, `<mount point>
21 reads NAMESPACE_ROOT from its environment and mounts a new mount table at <mount point>`, mountTable)
22 modules.RegisterChild(LSExternalCommand, `<glob>...
23 issues glob requests using the current processes namespace library`,
24 ls)
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -070025}
26
27func mountTable(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -070028 return runMT(false, stdin, stdout, stderr, env, args...)
29}
30
31func rootMountTable(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -070032 return runMT(true, stdin, stdout, stderr, env, args...)
33}
34
35func runMT(root bool, stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
Cosmos Nicolaou4e213d72014-10-26 22:21:52 -070036 r := rt.R()
Cosmos Nicolaoud811b072014-10-28 17:46:27 -070037 fl, args, err := parseListenFlags(args)
Cosmos Nicolaou4e213d72014-10-26 22:21:52 -070038 if err != nil {
Adam Sadovskyd21d95a2014-10-29 09:56:59 -070039 return fmt.Errorf("failed to parse args: %s", err)
Cosmos Nicolaou4e213d72014-10-26 22:21:52 -070040 }
Cosmos Nicolaou4e213d72014-10-26 22:21:52 -070041 lspec := initListenSpec(fl)
Asim Shankarcc044212014-10-15 23:25:26 -070042 server, err := r.NewServer(options.ServesMountTable(true))
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -070043 if err != nil {
44 return fmt.Errorf("root failed: %v", err)
45 }
46 mp := ""
47 if !root {
Cosmos Nicolaou4e213d72014-10-26 22:21:52 -070048 if err := checkArgs(args, 1, "<mount point>"); err != nil {
49 return err
50 }
51 mp = args[0]
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -070052 }
53 mt, err := mounttable.NewMountTable("")
54 if err != nil {
55 return fmt.Errorf("mounttable.NewMountTable failed: %s", err)
56 }
Cosmos Nicolaou4e213d72014-10-26 22:21:52 -070057 ep, err := server.Listen(lspec)
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -070058 if err != nil {
59 return fmt.Errorf("server.Listen failed: %s", err)
60 }
61 if err := server.Serve(mp, mt); err != nil {
62 return fmt.Errorf("root failed: %s", err)
63 }
64 name := naming.JoinAddressName(ep.String(), "")
Cosmos Nicolaouaddf4832014-09-10 21:36:54 -070065 fmt.Fprintf(stdout, "MT_NAME=%s\n", name)
Cosmos Nicolaou9c9918d2014-09-23 08:45:56 -070066 fmt.Fprintf(stdout, "MT_ADDR=%s\n", ep.String())
Cosmos Nicolaouaddf4832014-09-10 21:36:54 -070067 fmt.Fprintf(stdout, "PID=%d\n", os.Getpid())
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -070068 modules.WaitForEOF(stdin)
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -070069 return nil
70}
71
72func ls(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
73 details := false
Adam Sadovskyd21d95a2014-10-29 09:56:59 -070074 args = args[1:] // skip over command name
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -070075 if len(args) > 0 && args[0] == "-l" {
76 details = true
77 args = args[1:]
78 }
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -070079 ns := rt.R().Namespace()
Cosmos Nicolaou9ca249d2014-09-18 15:07:12 -070080 entry := 0
81 output := ""
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -070082 for _, pattern := range args {
83 ch, err := ns.Glob(rt.R().NewContext(), pattern)
84 if err != nil {
85 return err
86 }
87 for n := range ch {
88 if details {
Cosmos Nicolaou9ca249d2014-09-18 15:07:12 -070089 output += fmt.Sprintf("R%d=%s[", entry, n.Name)
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -070090 t := ""
91 for _, s := range n.Servers {
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070092 t += fmt.Sprintf("%s:%s, ", s.Server, s.Expires)
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -070093 }
94 t = strings.TrimSuffix(t, ", ")
Cosmos Nicolaou9ca249d2014-09-18 15:07:12 -070095 output += fmt.Sprintf("%s]\n", t)
96 entry += 1
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -070097 } else {
98 if len(n.Name) > 0 {
Cosmos Nicolaou9ca249d2014-09-18 15:07:12 -070099 output += fmt.Sprintf("R%d=%s\n", entry, n.Name)
100 entry += 1
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -0700101 }
102 }
Cosmos Nicolaou9ca249d2014-09-18 15:07:12 -0700103
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -0700104 }
105 }
Cosmos Nicolaou9ca249d2014-09-18 15:07:12 -0700106 fmt.Fprintf(stdout, "RN=%d\n", entry)
107 fmt.Fprint(stdout, output)
Cosmos Nicolaou0f0e8772014-09-10 21:29:25 -0700108 return nil
109}
Cosmos Nicolaou9ca249d2014-09-18 15:07:12 -0700110
111type resolver func(ctx context.T, name string) (names []string, err error)
112
113func resolve(fn resolver, stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
Cosmos Nicolaou4e213d72014-10-26 22:21:52 -0700114 if err := checkArgs(args[1:], 1, "<name>"); err != nil {
115 return err
Cosmos Nicolaou9ca249d2014-09-18 15:07:12 -0700116 }
Cosmos Nicolaoubbae3882014-10-02 22:58:19 -0700117 name := args[1]
Cosmos Nicolaou9ca249d2014-09-18 15:07:12 -0700118 servers, err := fn(rt.R().NewContext(), name)
119 if err != nil {
Cosmos Nicolaou9c9918d2014-09-23 08:45:56 -0700120 fmt.Fprintf(stdout, "RN=0\n")
Cosmos Nicolaou9ca249d2014-09-18 15:07:12 -0700121 return err
122 }
123 fmt.Fprintf(stdout, "RN=%d\n", len(servers))
124 for i, s := range servers {
125 fmt.Fprintf(stdout, "R%d=%s\n", i, s)
126 }
127 return nil
128}
129
130func resolveObject(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
131 return resolve(rt.R().Namespace().Resolve, stdin, stdout, stderr, env, args...)
132}
133
134func resolveMT(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
135 return resolve(rt.R().Namespace().ResolveToMountTable, stdin, stdout, stderr, env, args...)
136}
137
138func setNamespaceRoots(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
139 ns := rt.R().Namespace()
Cosmos Nicolaou4e213d72014-10-26 22:21:52 -0700140 if err := checkArgs(args, -1, "<name>..."); err != nil {
141 return err
Cosmos Nicolaoubbae3882014-10-02 22:58:19 -0700142 }
143 return ns.SetRoots(args[1:]...)
Cosmos Nicolaou9ca249d2014-09-18 15:07:12 -0700144}