Пример #1
0
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)
	}
}
Пример #2
0
func (a *aggregator) attach(ctx *beam.Message) error {
	if ctx.Args[0] != "" {
		// TODO: implement this?
		return fmt.Errorf("attaching to a child is not implemented")
	}

	if _, err := ctx.Ret.Send(&beam.Message{Verb: beam.Ack, Ret: a.server}); err != nil {
		return err
	}

	var copies sync.WaitGroup

	for _, b := range a.backends {
		r, _, err := b.Attach("")
		if err != nil {
			return err
		}
		copies.Add(1)
		go func() {
			log.Printf("copying output from %#v\n", b)
			beam.Copy(ctx.Ret, r)
			log.Printf("finished output from %#v\n", b)
			copies.Done()
		}()
	}

	copies.Wait()
	return nil
}
Пример #3
0
func (c *Conn) Send(msg *beam.Message) (beam.Receiver, error) {
	if msg.Att != nil {
		return nil, fmt.Errorf("file attachment not yet implemented in unix transport")
	}
	parts := []string{fmt.Sprintf("%d", msg.Verb)}
	parts = append(parts, msg.Args...)
	b := []byte(data.EncodeList(parts))
	// Setup nested streams
	var (
		fd  *os.File
		ret beam.Receiver
		err error
	)
	// Caller requested a return pipe
	if beam.RetPipe.Equals(msg.Ret) {
		local, remote, err := sendablePair()
		if err != nil {
			return nil, err
		}
		fd = remote
		ret = &Conn{local}
		// Caller specified its own return channel
	} else if msg.Ret != nil {
		// The specified return channel is a unix conn: engaging cheat mode!
		if retConn, ok := msg.Ret.(*Conn); ok {
			fd, err = retConn.UnixConn.File()
			if err != nil {
				return nil, fmt.Errorf("error passing return channel: %v", err)
			}
			// Close duplicate fd
			retConn.UnixConn.Close()
			// The specified return channel is an unknown type: proxy messages.
		} else {
			local, remote, err := sendablePair()
			if err != nil {
				return nil, fmt.Errorf("error passing return channel: %v", err)
			}
			fd = remote
			// FIXME: do we need a reference no all these background tasks?
			go func() {
				// Copy messages from the remote return channel to the local return channel.
				// When the remote return channel is closed, also close the local return channel.
				localConn := &Conn{local}
				beam.Copy(msg.Ret, localConn)
				msg.Ret.Close()
				localConn.Close()
			}()
		}
	}
	if err := c.UnixConn.Send(b, fd); err != nil {
		return nil, err
	}
	return ret, nil
}
Пример #4
0
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
}
Пример #5
0
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)
	}
}
Пример #6
0
// 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
}