func Tutum() beam.Sender { backend := beam.NewServer() backend.OnSpawn(beam.Handler(func(ctx *beam.Message) error { if len(ctx.Args) == 2 { tutum.User = ctx.Args[0] tutum.ApiKey = ctx.Args[1] } if !tutum.IsAuthenticated() { return fmt.Errorf("You need to provide your Tutum credentials in ~/.tutum or environment variables TUTUM_USER and TUTUM_APIKEY") } tutumDockerConnector, err := newConnector(tutumConnectorHost, tutumConnectorVersion) if err != nil { return fmt.Errorf("%v", err) } t := &tutumBackend{ tutumDockerConnector: tutumDockerConnector, Server: beam.NewServer(), } t.Server.OnAttach(beam.Handler(t.attach)) t.Server.OnStart(beam.Handler(t.ack)) t.Server.OnLs(beam.Handler(t.ls)) t.Server.OnSpawn(beam.Handler(t.spawn)) _, err = ctx.Ret.Send(&beam.Message{Verb: beam.Ack, Ret: t.Server}) return err })) return backend }
func (t *tutumBackend) newContainer(id string) beam.Sender { c := &tutumContainer{tutumBackend: t, id: id} instance := beam.NewServer() instance.OnGet(beam.Handler(c.get)) instance.OnStart(beam.Handler(c.start)) instance.OnStop(beam.Handler(c.stop)) return instance }
func (b *dockerClientBackend) newContainer(id string) beam.Sender { c := &container{backend: b, id: id} instance := beam.NewServer() instance.OnAttach(beam.Handler(c.attach)) instance.OnStart(beam.Handler(c.start)) instance.OnStop(beam.Handler(c.stop)) instance.OnGet(beam.Handler(c.get)) return instance }
func cmdDaemon(c *cli.Context) { app := beam.NewServer() app.OnLog(beam.Handler(func(msg *beam.Message) error { log.Printf("%s\n", strings.Join(msg.Args, " ")) return nil })) app.OnError(beam.Handler(func(msg *beam.Message) error { Fatalf("Fatal: %v", strings.Join(msg.Args[:1], "")) return nil })) back := backends.New() if len(c.Args()) == 0 { names, err := back.Ls() if err != nil { Fatalf("ls: %v", err) } fmt.Println(strings.Join(names, "\n")) return } var previousInstanceR beam.Receiver // FIXME: refactor into a Pipeline for idx, backendArg := range c.Args() { bName, bArgs, err := parseCmd(backendArg) if err != nil { Fatalf("parse: %v", err) } _, backend, err := back.Attach(bName) if err != nil { Fatalf("%s: %v\n", bName, err) } instance, err := backend.Spawn(bArgs...) if err != nil { Fatalf("spawn %s: %v\n", bName, err) } instanceR, instanceW, err := instance.Attach("") if err != nil { Fatalf("attach: %v", err) } go func(r beam.Receiver, w beam.Sender, idx int) { if r != nil { beam.Copy(w, r) } w.Close() }(previousInstanceR, instanceW, idx) if err := instance.Start(); err != nil { Fatalf("start: %v", err) } previousInstanceR = instanceR } _, err := beam.Copy(app, previousInstanceR) if err != nil { Fatalf("copy: %v", err) } }
// The Debug service is an example of intercepting messages between a receiver and a sender. // The service also exposes messages passing through it for debug purposes. func Debug() beam.Sender { dbgInstance := &debug{ service: beam.NewServer(), } sender := beam.NewServer() sender.OnSpawn(beam.Handler(dbgInstance.spawn)) return sender }
func Shipyard() beam.Sender { backend := beam.NewServer() backend.OnSpawn(beam.Handler(func(ctx *beam.Message) error { if len(ctx.Args) != 3 { return fmt.Errorf("Shipyard: Usage <shipyard URL> <user> <pass>") } c := &shipyard{url: ctx.Args[0], user: ctx.Args[1], pass: ctx.Args[2]} c.Server = beam.NewServer() c.Server.OnAttach(beam.Handler(c.attach)) c.Server.OnStart(beam.Handler(c.start)) c.Server.OnLs(beam.Handler(c.containers)) c.OnGet(beam.Handler(c.containerInspect)) _, err := ctx.Ret.Send(&beam.Message{Verb: beam.Ack, Ret: c.Server}) return err })) return backend }
func Simulator() beam.Sender { s := beam.NewServer() s.OnSpawn(beam.Handler(func(ctx *beam.Message) error { containers := ctx.Args instance := beam.Task(func(in beam.Receiver, out beam.Sender) { beam.Obj(out).Log("[simulator] starting\n") s := beam.NewServer() s.OnLs(beam.Handler(func(msg *beam.Message) error { beam.Obj(out).Log("[simulator] generating fake list of objects...\n") beam.Obj(msg.Ret).Set(containers...) return nil })) beam.Copy(s, in) }) ctx.Ret.Send(&beam.Message{Verb: beam.Ack, Ret: instance}) return nil })) return s }
func Aggregate() beam.Sender { backend := beam.NewServer() backend.OnSpawn(beam.Handler(func(ctx *beam.Message) error { allBackends := New() instance := beam.NewServer() a, err := newAggregator(allBackends, instance, ctx.Args) if err != nil { return err } instance.OnAttach(beam.Handler(a.attach)) instance.OnStart(beam.Handler(a.start)) instance.OnLs(beam.Handler(a.ls)) _, err = ctx.Ret.Send(&beam.Message{Verb: beam.Ack, Ret: instance}) return err })) return backend }
func cmdDaemon(c *cli.Context) { app := beam.NewServer() app.OnLog(beam.Handler(func(msg *beam.Message) error { utils.Debugf("%s", strings.Join(msg.Args, " ")) return nil })) app.OnError(beam.Handler(func(msg *beam.Message) error { Fatalf("Fatal: %v", strings.Join(msg.Args[:1], "")) return nil })) backend := beam.Object{backends.Forward()} dockerHost := os.Getenv("DOCKER_HOST") if dockerHost == "" { dockerHost = "unix:///var/run/docker.sock" } instance, err := backend.Spawn(dockerHost) if err != nil { Fatalf("spawn: %v\n", err) } instanceR, instanceW, err := instance.Attach("") if err != nil { Fatalf("attach: %v", err) } defer instanceW.Close() go beam.Copy(app, instanceR) if err := instance.Start(); err != nil { Fatalf("start: %v", err) } err = doCmd(instance, c.Args()) if err != nil { Fatalf("%v", err) } }
func DockerClientWithConfig(config *DockerClientConfig) beam.Sender { backend := beam.NewServer() backend.OnSpawn(beam.Handler(func(ctx *beam.Message) error { if len(ctx.Args) != 1 { return fmt.Errorf("dockerclient: spawn takes exactly 1 argument, got %d", len(ctx.Args)) } client := newClient() client.scheme = config.Scheme client.urlHost = config.URLHost client.transport.TLSClientConfig = config.TLSClientConfig client.setURL(ctx.Args[0]) b := &dockerClientBackend{ client: client, Server: beam.NewServer(), } b.Server.OnAttach(beam.Handler(b.attach)) b.Server.OnStart(beam.Handler(b.start)) b.Server.OnLs(beam.Handler(b.ls)) b.Server.OnSpawn(beam.Handler(b.spawn)) _, err := ctx.Ret.Send(&beam.Message{Verb: beam.Ack, Ret: b.Server}) return err })) return backend }
func DockerServer() beam.Sender { backend := beam.NewServer() backend.OnSpawn(beam.Handler(func(ctx *beam.Message) error { instance := beam.Task(func(in beam.Receiver, out beam.Sender) { url := "tcp://localhost:4243" if len(ctx.Args) > 0 { url = ctx.Args[0] } err := listenAndServe(url, out) if err != nil { fmt.Printf("listenAndServe: %v", err) } }) _, err := ctx.Ret.Send(&beam.Message{Verb: beam.Ack, Ret: instance}) return err })) return backend }
func FakeClient() beam.Sender { backend := beam.NewServer() backend.OnSpawn(beam.Handler(func(ctx *beam.Message) error { // Instantiate a new fakeclient instance instance := beam.Task(func(in beam.Receiver, out beam.Sender) { fmt.Printf("fake client!\n") defer fmt.Printf("end of fake client!\n") o := beam.Obj(out) o.Log("fake client starting") defer o.Log("fake client terminating") for { time.Sleep(1 * time.Second) o.Log("fake client heartbeat!") } }) _, err := ctx.Ret.Send(&beam.Message{Verb: beam.Ack, Ret: instance}) return err })) return backend }
func Orchard() beam.Sender { backend := beam.NewServer() backend.OnSpawn(beam.Handler(func(ctx *beam.Message) error { if len(ctx.Args) != 2 { return fmt.Errorf("orchard: spawn expects 2 arguments: API token and name of host") } apiToken, hostName := ctx.Args[0], ctx.Args[1] apiClient := &api.HTTPClient{ BaseURL: "https://api.orchardup.com/v2", Token: apiToken, } host, err := apiClient.GetHost(hostName) if err != nil { return err } url := fmt.Sprintf("tcp://%s:4243", host.IPAddress) tlsConfig, err := getTLSConfig([]byte(host.ClientCert), []byte(host.ClientKey)) if err != nil { return err } backend := DockerClientWithConfig(&DockerClientConfig{ Scheme: "https", URLHost: host.IPAddress, TLSClientConfig: tlsConfig, }) forwardBackend := beam.Obj(backend) forwardInstance, err := forwardBackend.Spawn(url) if err != nil { return err } _, err = ctx.Ret.Send(&beam.Message{Verb: beam.Ack, Ret: forwardInstance}) return err })) return backend }
func Debug() beam.Sender { backend := beam.NewServer() backend.OnSpawn(beam.Handler(func(ctx *beam.Message) error { instance := beam.Task(func(in beam.Receiver, out beam.Sender) { for { msg, err := in.Receive(beam.Ret) if err != nil { fmt.Printf("debug receive: %v", err) return } fmt.Printf("[DEBUG] %s %s\n", msg.Verb, strings.Join(msg.Args, " ")) if _, err := out.Send(msg); err != nil { fmt.Printf("debug send: %v", err) return } } }) _, err := ctx.Ret.Send(&beam.Message{Verb: beam.Ack, Ret: instance}) return err })) return backend }
// Spawn will return a new instance as the Ret channel of the message sent back func (dbg *debug) spawn(msg *beam.Message) (err error) { // By sending back a task, beam will run the function with the in and out arguments // set to the services present before and after this one in the pipeline. instance := beam.Task(func(in beam.Receiver, out beam.Sender) { // Setup our channels dbg.in = in dbg.out = out // Set up the debug interceptor dbg.service.Catchall(beam.Handler(dbg.catchall)) // Copy everything from the receiver to our service. By copying like this in the task // we can use the catchall handler instead of handling the message here. beam.Copy(dbg.service, in) }) // Inform the system of our new instance msg.Ret.Send(&beam.Message{ Verb: beam.Ack, Ret: instance, }) return }
func Exec() beam.Sender { e := beam.NewServer() e.OnSpawn(beam.Handler(func(msg *beam.Message) error { if len(msg.Args) < 1 { return fmt.Errorf("usage: SPAWN exec|... <config>") } if msg.Args[0] != "exec" { return fmt.Errorf("invalid command: %s", msg.Args[0]) } var config struct { Path string Args []string } if err := json.Unmarshal([]byte(msg.Args[1]), &config); err != nil { config.Path = msg.Args[1] config.Args = msg.Args[2:] } cmd := &command{ Cmd: exec.Command(config.Path, config.Args...), Server: beam.NewServer(), } cmd.OnAttach(beam.Handler(func(msg *beam.Message) error { stdout, err := cmd.StdoutPipe() if err != nil { return err } stdin, err := cmd.StdinPipe() if err != nil { return err } inR, inW := beam.Pipe() if _, err := msg.Ret.Send(&beam.Message{Verb: beam.Ack, Ret: inW}); err != nil { return err } out := beam.Obj(msg.Ret) go func() { defer stdin.Close() for { msg, err := inR.Receive(0) if err != nil { return } if msg.Verb == beam.Log && len(msg.Args) > 0 { fmt.Fprintf(stdin, "%s\n", strings.TrimRight(msg.Args[0], "\r\n")) } } }() cmd.tasks.Add(1) go func() { defer cmd.tasks.Done() scanner := bufio.NewScanner(stdout) for scanner.Scan() { if scanner.Err() != io.EOF && scanner.Err() != nil { return } if err := out.Log(scanner.Text()); err != nil { out.Error("%v", err) return } } }() cmd.tasks.Wait() return nil })) cmd.OnStart(beam.Handler(func(msg *beam.Message) error { cmd.tasks.Add(1) if err := cmd.Cmd.Start(); err != nil { return err } go func() { defer cmd.tasks.Done() if err := cmd.Cmd.Wait(); err != nil { beam.Obj(msg.Ret).Log("%s exited status=%v", cmd.Cmd.Path, err) } }() msg.Ret.Send(&beam.Message{Verb: beam.Ack}) return nil })) if _, err := msg.Ret.Send(&beam.Message{Verb: beam.Ack, Ret: cmd}); err != nil { return err } return nil })) return e }