blob: f1ff8fa3d308c71182200a0bbdd8a399a30617e0 [file] [log] [blame]
package core
import (
"fmt"
"io"
"os"
"strings"
"veyron.io/veyron/veyron2"
"veyron.io/veyron/veyron2/context"
"veyron.io/veyron/veyron2/naming"
"veyron.io/veyron/veyron2/rt"
"veyron.io/veyron/veyron/lib/modules"
"veyron.io/veyron/veyron/profiles"
mounttable "veyron.io/veyron/veyron/services/mounttable/lib"
)
func init() {
modules.RegisterChild(RootMTCommand, "", rootMountTable)
modules.RegisterChild(MTCommand, `<mount point>
reads NAMESPACE_ROOT from its environment and mounts a new mount table at <mount point>`, mountTable)
modules.RegisterChild(LSExternalCommand, `<glob>...
issues glob requests using the current processes namespace library`,
ls)
}
func mountTable(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
if len(args) != 2 {
return fmt.Errorf("expected exactly one argument: <mount point>")
}
return runMT(false, stdin, stdout, stderr, env, args...)
}
func rootMountTable(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
if len(args) != 1 {
return fmt.Errorf("expected no arguments")
}
return runMT(true, stdin, stdout, stderr, env, args...)
}
func runMT(root bool, stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
r := rt.Init()
server, err := r.NewServer(veyron2.ServesMountTableOpt(true))
if err != nil {
return fmt.Errorf("root failed: %v", err)
}
mp := ""
if !root {
mp = args[1]
}
mt, err := mounttable.NewMountTable("")
if err != nil {
return fmt.Errorf("mounttable.NewMountTable failed: %s", err)
}
ep, err := server.ListenX(profiles.LocalListenSpec)
if err != nil {
return fmt.Errorf("server.Listen failed: %s", err)
}
if err := server.Serve(mp, mt); err != nil {
return fmt.Errorf("root failed: %s", err)
}
name := naming.JoinAddressName(ep.String(), "")
fmt.Fprintf(stdout, "MT_NAME=%s\n", name)
fmt.Fprintf(stdout, "MT_ADDR=%s\n", ep.String())
fmt.Fprintf(stdout, "PID=%d\n", os.Getpid())
modules.WaitForEOF(stdin)
return nil
}
func ls(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
details := false
args = args[1:] // skip over comamnd name
if len(args) > 0 && args[0] == "-l" {
details = true
args = args[1:]
}
ns := rt.R().Namespace()
entry := 0
output := ""
for _, pattern := range args {
ch, err := ns.Glob(rt.R().NewContext(), pattern)
if err != nil {
return err
}
for n := range ch {
if details {
output += fmt.Sprintf("R%d=%s[", entry, n.Name)
t := ""
for _, s := range n.Servers {
t += fmt.Sprintf("%s:%s, ", s.Server, s.TTL)
}
t = strings.TrimSuffix(t, ", ")
output += fmt.Sprintf("%s]\n", t)
entry += 1
} else {
if len(n.Name) > 0 {
output += fmt.Sprintf("R%d=%s\n", entry, n.Name)
entry += 1
}
}
}
}
fmt.Fprintf(stdout, "RN=%d\n", entry)
fmt.Fprint(stdout, output)
return nil
}
type resolver func(ctx context.T, name string) (names []string, err error)
func resolve(fn resolver, stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
if len(args) != 2 {
return fmt.Errorf("wrong # args")
}
name := args[1]
servers, err := fn(rt.R().NewContext(), name)
if err != nil {
fmt.Fprintf(stdout, "RN=0\n")
return err
}
fmt.Fprintf(stdout, "RN=%d\n", len(servers))
for i, s := range servers {
fmt.Fprintf(stdout, "R%d=%s\n", i, s)
}
return nil
}
func resolveObject(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
return resolve(rt.R().Namespace().Resolve, stdin, stdout, stderr, env, args...)
}
func resolveMT(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
return resolve(rt.R().Namespace().ResolveToMountTable, stdin, stdout, stderr, env, args...)
}
func setNamespaceRoots(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
ns := rt.R().Namespace()
if len(args) < 2 {
return fmt.Errorf("wrong # args")
}
return ns.SetRoots(args[1:]...)
}