func recv(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 1 { fatalf("recv needs one anchor argument") } w, _ := parseGlob(args[0]) u, ok := c.Walk(w).Get().(client.Chan) if !ok { fatalf("not a channel") } msgr, err := u.Recv() if err != nil { fatalf("recv error: %v", err) } io.Copy(os.Stdout, msgr) // if _, err = io.Copy(os.Stdout, msgr); err != nil { // fatalf("transmission error: %v", err) // } }
func mkdkr(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 1 { fatalf("mkdkr needs an anchor argument") } w, _ := parseGlob(args[0]) buf, _ := ioutil.ReadAll(os.Stdin) var run docker.Run if err := json.Unmarshal(buf, &run); err != nil { fatalf("command json not parsing: %v", err) } if x.Bool("scrub") { run.Scrub = true } _, err := c.Walk(w).MakeDocker(run) if err != nil { fatalf("mkdkr error: %s", err) } }
func join(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 2 { fatalf("join needs one anchor argument and one circuit address argument") } // Verify the target circuit address is valid if _, err := n.ParseAddr(args[1]); err != nil { fatalf("argument %q is not a valid circuit address", args[1]) } // w, _ := parseGlob(args[0]) switch u := c.Walk(w).Get().(type) { case client.Server: if err := u.Rejoin(args[1]); err != nil { fatalf("error: %v", err) } default: fatalf("not a server") } }
func wait(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 1 { fatalf("wait needs one anchor argument") } w, _ := parseGlob(args[0]) // var stat interface{} var err error switch u := c.Walk(w).Get().(type) { case client.Proc: stat, err = u.Wait() case docker.Container: stat, err = u.Wait() default: fatalf("anchor is not a process or a docker container") } if err != nil { fatalf("wait error: %v", err) } buf, _ := json.MarshalIndent(stat, "", "\t") fmt.Println(string(buf)) }
// circuit mkproc /X1234/hola/charlie << EOF // { … } // EOF // TODO: Proc element disappears if command misspelled and error condition not obvious. func mkproc(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 1 { fatalf("mkproc needs an anchor argument") } w, _ := parseGlob(args[0]) buf, _ := ioutil.ReadAll(os.Stdin) var cmd client.Cmd if err := json.Unmarshal(buf, &cmd); err != nil { fatalf("command json not parsing: %v", err) } p, err := c.Walk(w).MakeProc(cmd) if err != nil { fatalf("mkproc error: %s", err) } ps := p.Peek() if ps.Exit != nil { fatalf("%v", ps.Exit) } }
func stdin(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 1 { fatalf("stdin needs one anchor argument") } w, _ := parseGlob(args[0]) u, ok := c.Walk(w).Get().(interface { Stdin() io.WriteCloser }) if !ok { fatalf("not a process or a container") } q := u.Stdin() if _, err := io.Copy(q, os.Stdin); err != nil { fatalf("transmission error: %v", err) } if err := q.Close(); err != nil { fatalf("error closing stdin: %v", err) } }
// circuit peek /X1234/hola/charlie func peek(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 1 { fatalf("peek needs one anchor argument") } w, _ := parseGlob(args[0]) switch t := c.Walk(w).Get().(type) { case client.Server: buf, _ := json.MarshalIndent(t.Peek(), "", "\t") fmt.Println(string(buf)) case client.Chan: buf, _ := json.MarshalIndent(t.Stat(), "", "\t") fmt.Println(string(buf)) case client.Proc: buf, _ := json.MarshalIndent(t.Peek(), "", "\t") fmt.Println(string(buf)) case client.Subscription: buf, _ := json.MarshalIndent(t.Peek(), "", "\t") fmt.Println(string(buf)) case nil: buf, _ := json.MarshalIndent(nil, "", "\t") fmt.Println(string(buf)) default: fatalf("unknown element") } }
func dial(x *cli.Context) *client.Client { var dialAddr string switch { case x.IsSet("dial"): dialAddr = x.String("dial") case os.Getenv("CIRCUIT") != "": buf, err := ioutil.ReadFile(os.Getenv("CIRCUIT")) if err != nil { fatalf("circuit environment file %s is not readable: %v", os.Getenv("CIRCUIT"), err) } dialAddr = strings.TrimSpace(string(buf)) default: buf, err := ioutil.ReadFile(".circuit") if err != nil { fatalf("no dial address available; use flag -d or set CIRCUIT to a file name") } dialAddr = strings.TrimSpace(string(buf)) } defer func() { if r := recover(); r != nil { fatalf("addressed server is gone or a newer one is in place") } }() return client.Dial(dialAddr) }
func recv(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 1 { fatalf("recv needs one anchor argument") } w, _ := parseGlob(args[0]) switch u := c.Walk(w).Get().(type) { case client.Chan: msgr, err := u.Recv() if err != nil { fatalf("recv error: %v", err) } io.Copy(os.Stdout, msgr) case client.Subscription: v, ok := u.Consume() if !ok { fatalf("eof") } fmt.Println(v) os.Stdout.Sync() default: fatalf("not a channel or subscription") } }
func server(c *cli.Context) { println("CIRCUIT 2014 gocircuit.org") var err error if c.Bool("docker") { cmd, err := docker.Init() if err != nil { log.Fatalf("cannot use docker: %v", err) } log.Printf("Enabling docker elements, using %s", cmd) } // parse arguments var tcpaddr = parseAddr(c) // server bind address var join n.Addr // join address of another circuit server if c.IsSet("join") { if join, err = n.ParseAddr(c.String("join")); err != nil { log.Fatalf("join address does not parse (%s)", err) } } var multicast = parseDiscover(c) // server instance working directory var varDir string if !c.IsSet("var") { varDir = path.Join(os.TempDir(), fmt.Sprintf("%s-%%W-P%04d", n.Scheme, os.Getpid())) } else { varDir = c.String("var") } // start circuit runtime addr := load(tcpaddr, varDir, readkey(c)) // tissue + locus kin, xkin, rip := tissue.NewKin() xlocus := locus.NewLocus(kin, rip) // joining switch { case join != nil: kin.ReJoin(join) case multicast != nil: log.Printf("Using UDP multicast discovery on address %s", multicast.String()) go assemble.NewAssembler(addr, multicast).AssembleServer( func(joinAddr n.Addr) { kin.ReJoin(joinAddr) }, ) default: log.Println("Singleton server.") } circuit.Listen(tissue.ServiceName, xkin) circuit.Listen(LocusName, xlocus) <-(chan int)(nil) }
func scrb(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 1 { fatalf("scrub needs one anchor argument") } w, _ := parseGlob(args[0]) c.Walk(w).Scrub() }
func parseDiscover(c *cli.Context) *net.UDPAddr { var src string if c.IsSet("discover") { src = c.String("discover") } else if os.Getenv("CIRCUIT_DISCOVER") != "" { src = os.Getenv("CIRCUIT_DISCOVER") } else { return nil } multicast, err := net.ResolveUDPAddr("udp", src) if err != nil { log.Fatalf("udp multicast address for discovery and assembly does not parse (%s)", err) } return multicast }
func clos(x *cli.Context) { c := dial(x) args := x.Args() if len(args) != 1 { fatalf("close needs one anchor argument") } w, _ := parseGlob(args[0]) u, ok := c.Walk(w).Get().(client.Chan) if !ok { fatalf("not a channel") } if err := u.Close(); err != nil { fatalf("close error: %v", err) } }
// circuit ls /Q123/apps/charlie // circuit ls /... func ls(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 1 { println("ls needs a glob argument") os.Exit(1) } w, ellipses := parseGlob(args[0]) list(0, "/", c.Walk(w), ellipses) }
func parseDiscover(c *cli.Context) *net.UDPAddr { var src string switch { case c.String("discover") != "": src = c.String("discover") case os.Getenv("CIRCUIT_DISCOVER") != "": src = os.Getenv("CIRCUIT_DISCOVER") default: return nil } multicast, err := net.ResolveUDPAddr("udp", src) if err != nil { log.Fatalf("udp multicast address for discovery and assembly does not parse (%s)", err) } return multicast }
// circuit mk@leave /X1234/hola/listy func mkonleave(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 1 { fatalf("mk@leave needs an anchor argument") } w, _ := parseGlob(args[0]) _, err := c.Walk(w).MakeOnLeave() if err != nil { fatalf("mk@leave error: %s", err) } }
func suicide(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 1 { fatalf("suicide needs one server anchor argument") } w, _ := parseGlob(args[0]) u, ok := c.Walk(w).Get().(client.Server) if !ok { fatalf("not a server") } u.Suicide() }
func readkey(x *cli.Context) (key []byte) { var hmac string switch { case x.IsSet("hmac"): hmac = x.String("hmac") case os.Getenv("CIRCUIT_HMAC") != "": hmac = os.Getenv("CIRCUIT_HMAC") default: return nil } b64, err := ioutil.ReadFile(hmac) if err != nil { fatalf("problem reading private key file (%s): %v", hmac, err) } if key, err = base64.StdEncoding.DecodeString(string(b64)); err != nil { fatalf("problem decoding base64 private key: %v", err) } return }
func nunset(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 2 { fatalf("unset needs an anchor and a resource name arguments") } w, _ := parseGlob(args[0]) switch u := c.Walk(w).Get().(type) { case client.Nameserver: u.Unset(args[1]) default: fatalf("not a nameserver element") } }
func sgnl(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 2 { fatalf("signal needs an anchor and a signal name arguments") } w, _ := parseGlob(args[0]) u, ok := c.Walk(w).Get().(client.Proc) if !ok { fatalf("not a process") } if err := u.Signal(args[1]); err != nil { fatalf("signal error: %v", err) } }
func stdout(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 1 { fatalf("stdout needs one anchor argument") } w, _ := parseGlob(args[0]) u, ok := c.Walk(w).Get().(interface { Stdout() io.ReadCloser }) if !ok { fatalf("not a process or a container") } io.Copy(os.Stdout, u.Stdout()) }
func stderr(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 1 { fatalf("stderr needs one anchor argument") } w, _ := parseGlob(args[0]) u, ok := c.Walk(w).Get().(client.Proc) if !ok { fatalf("not a process") } io.Copy(os.Stdout, u.Stderr()) // if _, err := io.Copy(os.Stdout, u.Stderr()); err != nil { // fatalf("transmission error: %v", err) // } }
func mkdns(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) < 1 { fatalf("mkdns needs an anchor and an optional address arguments") } var addr string if len(args) == 2 { addr = args[1] } w, _ := parseGlob(args[0]) _, err := c.Walk(w).MakeNameserver(addr) if err != nil { fatalf("mkdns error: %s", err) } }
// circuit mkchan /X1234/hola/charlie 0 func mkchan(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 2 { fatalf("mkchan needs an anchor and a capacity arguments") } w, _ := parseGlob(args[0]) a := c.Walk(w) n, err := strconv.Atoi(args[1]) if err != nil || n < 0 { fatalf("second argument to mkchan must be a non-negative integral capacity") } if _, err = a.MakeChan(n); err != nil { fatalf("mkchan error: %s", err) } }
func wait(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 1 { fatalf("wait needs one anchor argument") } w, _ := parseGlob(args[0]) u, ok := c.Walk(w).Get().(client.Proc) if !ok { fatalf("not a process") } stat, err := u.Wait() if err != nil { fatalf("wait error: %v", err) } buf, _ := json.MarshalIndent(stat, "", "\t") fmt.Println(string(buf)) }
func stack(x *cli.Context) { defer func() { if r := recover(); r != nil { fatalf("error, likely due to missing server or misspelled anchor: %v", r) } }() c := dial(x) args := x.Args() if len(args) != 1 { fatalf("recv needs one anchor argument") } w, _ := parseGlob(args[0]) switch u := c.Walk(w).Get().(type) { case client.Server: r, err := u.Profile("goroutine") if err != nil { fatalf("error: %v", err) } io.Copy(os.Stdout, r) default: fatalf("not a server") } }
func parseAddr(c *cli.Context) *net.TCPAddr { switch { case c.IsSet("addr"): addr, err := net.ResolveTCPAddr("tcp", c.String("addr")) if err != nil { log.Fatalf("resolve %s (%s)\n", addr, err) } if len(addr.IP) == 0 { addr.IP = net.IPv4zero } return addr case c.IsSet("if"): ifc, err := net.InterfaceByName(c.String("if")) if err != nil { log.Fatalf("interface %s not found (%v)", c.String("if"), err) } addrs, err := ifc.Addrs() if err != nil { log.Fatalf("interface address cannot be retrieved (%v)", err) } if len(addrs) == 0 { log.Fatalf("no addresses associated with this interface") } for _, a := range addrs { // pick the IPv4 one ipn := a.(*net.IPNet) if ipn.IP.To4() == nil { continue } return &net.TCPAddr{IP: ipn.IP} } log.Fatal("specified interface has no IPv4 addresses") default: log.Fatal("either an -addr or an -if option is required to start a server") } panic(0) }
func dial(x *cli.Context) *client.Client { switch { case x.IsSet("dial"): defer func() { if r := recover(); r != nil { fatalf("addressed server is gone or authentication failed") } }() return client.Dial(x.String("dial"), readkey(x)) case x.IsSet("discover"): defer func() { if r := recover(); r != nil { fatalf("multicast address is unresponsive or authentication failed") } }() return client.DialDiscover(x.String("discover"), readkey(x)) case os.Getenv("CIRCUIT") != "": buf, err := ioutil.ReadFile(os.Getenv("CIRCUIT")) if err != nil { fatalf("circuit environment file %s is not readable: %v", os.Getenv("CIRCUIT"), err) } defer func() { if r := recover(); r != nil { fatalf("addressed server is gone or authentication failed") } }() return client.Dial(strings.TrimSpace(string(buf)), readkey(x)) case os.Getenv("CIRCUIT_DISCOVER") != "": defer func() { if r := recover(); r != nil { fatalf("multicast address is unresponsive or authentication failed") } }() return client.DialDiscover(os.Getenv("CIRCUIT_DISCOVER"), readkey(x)) } fatalf("no dial or discovery addresses available; use -dial or -discover") panic(0) }
func server(c *cli.Context) { println("CIRCUIT 2014 gocircuit.org") log.Println("Starting circuit server") // parse arguments if !c.IsSet("addr") { log.Fatal("server network address not given; use -addr") } var err error var join n.Addr if c.IsSet("join") { if join, err = n.ParseAddr(c.String("join")); err != nil { log.Fatalf("join address does not parse (%s)", err) } } var mutexDir string if !c.IsSet("mutex") { mutexDir = path.Join(os.TempDir(), fmt.Sprintf("%s-%%W-P%04d", n.Scheme, os.Getpid())) } else { mutexDir = c.String("mutex") } // start circuit runtime load(c.String("addr"), mutexDir) // kinfolk join var xjoin circuit.PermX dontPanic(func() { xjoin = circuit.Dial(join, KinfolkName) }, "join") // locus kin, xkin, kinJoin, kinLeave := kinfolk.NewKin(xjoin) xlocus := locus.NewLocus(kin, kinJoin, kinLeave) circuit.Listen(KinfolkName, xkin) circuit.Listen(LocusName, xlocus) <-(chan int)(nil) }