예제 #1
0
func Task(f func(in libswarm.Receiver, out libswarm.Sender)) libswarm.Sender {
	var running bool
	var l sync.RWMutex
	inR, inW := libswarm.Pipe()
	outR, outW := libswarm.Pipe()
	obj := libswarm.NewServer()
	obj.OnVerb(libswarm.Attach, libswarm.Handler(func(msg *libswarm.Message) error {
		msg.Ret.Send(&libswarm.Message{Verb: libswarm.Ack, Ret: inW})
		fmt.Printf("copying task output from %#v to %#v\n", outR, msg.Ret)
		defer fmt.Printf("(DONE) copying task output from %#v to %#v\n", outR, msg.Ret)
		libswarm.Copy(msg.Ret, outR)
		return nil
	}))
	obj.OnVerb(libswarm.Start, libswarm.Handler(func(msg *libswarm.Message) error {
		l.RLock()
		r := running
		l.RUnlock()
		if r {
			return fmt.Errorf("already running")
		}
		l.Lock()
		go f(inR, outW)
		running = true
		l.Unlock()
		msg.Ret.Send(&libswarm.Message{Verb: libswarm.Ack})
		return nil
	}))
	return obj
}
예제 #2
0
func NewTree() *Tree {
	t := &Tree{
		Server:   libswarm.NewServer(),
		children: make(map[string]libswarm.Sender),
	}
	t.OnVerb(libswarm.Attach, libswarm.Handler(func(msg *libswarm.Message) error {
		if len(msg.Args) == 0 || msg.Args[0] == "" {
			msg.Ret.Send(&libswarm.Message{Verb: libswarm.Ack, Ret: t})
			return nil
		}
		if child, exists := t.children[msg.Args[0]]; exists {
			msg.Ret.Send(&libswarm.Message{Verb: libswarm.Ack, Ret: child})
			return nil
		}
		libswarm.AsClient(msg.Ret).Error("not found")
		return nil
	}))
	t.OnVerb(libswarm.Ls, libswarm.Handler(func(msg *libswarm.Message) error {
		names := make([]string, 0, len(t.children))
		for name := range t.children {
			names = append(names, name)
		}
		sort.Strings(names)
		libswarm.AsClient(msg.Ret).Set(names...)
		return nil
	}))
	return t
}
예제 #3
0
func Tutum() libswarm.Sender {
	backend := libswarm.NewServer()
	backend.OnVerb(libswarm.Spawn, libswarm.Handler(func(ctx *libswarm.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:               libswarm.NewServer(),
		}
		t.Server.OnVerb(libswarm.Attach, libswarm.Handler(t.attach))
		t.Server.OnVerb(libswarm.Start, libswarm.Handler(t.ack))
		t.Server.OnVerb(libswarm.Ls, libswarm.Handler(t.ls))
		t.Server.OnVerb(libswarm.Spawn, libswarm.Handler(t.spawn))
		_, err = ctx.Ret.Send(&libswarm.Message{Verb: libswarm.Ack, Ret: t.Server})
		return err
	}))
	return backend
}
예제 #4
0
func (t *tutumBackend) newContainer(id string) libswarm.Sender {
	c := &tutumContainer{tutumBackend: t, id: id}
	instance := libswarm.NewServer()
	instance.OnVerb(libswarm.Get, libswarm.Handler(c.get))
	instance.OnVerb(libswarm.Start, libswarm.Handler(c.start))
	instance.OnVerb(libswarm.Stop, libswarm.Handler(c.stop))
	return instance
}
예제 #5
0
파일: ec2.go 프로젝트: rgbkrk/libswarm
func Ec2() libswarm.Sender {
	backend := libswarm.NewServer()
	backend.OnVerb(libswarm.Spawn, libswarm.Handler(func(ctx *libswarm.Message) error {
		var config, err = newConfig(ctx.Args)

		if err != nil {
			return err
		}

		ec2Conn, err := awsInit(config)

		if err != nil {
			return err
		}

		client := &ec2Client{config, ec2Conn, libswarm.NewServer(), nil, nil, nil}

		client.Server.OnVerb(libswarm.Spawn, libswarm.Handler(client.spawn))
		client.Server.OnVerb(libswarm.Start, libswarm.Handler(client.start))
		client.Server.OnVerb(libswarm.Stop, libswarm.Handler(client.stop))
		client.Server.OnVerb(libswarm.Attach, libswarm.Handler(client.attach))
		client.Server.OnVerb(libswarm.Ls, libswarm.Handler(client.ls))
		client.Server.OnVerb(libswarm.Get, libswarm.Handler(client.get))

		signalHandler(client)
		_, err = ctx.Ret.Send(&libswarm.Message{Verb: libswarm.Ack, Ret: client.Server})

		return err
	}))

	return backend
}
예제 #6
0
// 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() libswarm.Sender {
	dbgInstance := &debug{
		service: libswarm.NewServer(),
	}

	sender := libswarm.NewServer()
	sender.OnVerb(libswarm.Spawn, libswarm.Handler(dbgInstance.spawn))
	return sender
}
예제 #7
0
func Simulator() libswarm.Sender {
	s := libswarm.NewServer()
	s.OnVerb(libswarm.Spawn, libswarm.Handler(func(ctx *libswarm.Message) error {
		containers := ctx.Args
		instance := utils.Task(func(in libswarm.Receiver, out libswarm.Sender) {
			libswarm.AsClient(out).Log("[simulator] starting\n")
			s := libswarm.NewServer()
			s.OnVerb(libswarm.Ls, libswarm.Handler(func(msg *libswarm.Message) error {
				libswarm.AsClient(out).Log("[simulator] generating fake list of objects...\n")
				libswarm.AsClient(msg.Ret).Set(containers...)
				return nil
			}))
			libswarm.Copy(s, in)
		})
		ctx.Ret.Send(&libswarm.Message{Verb: libswarm.Ack, Ret: instance})
		return nil
	}))
	return s
}
예제 #8
0
func Shipyard() libswarm.Sender {
	backend := libswarm.NewServer()
	backend.OnVerb(libswarm.Spawn, libswarm.Handler(func(ctx *libswarm.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 = libswarm.NewServer()
		c.Server.OnVerb(libswarm.Attach, libswarm.Handler(c.attach))
		c.Server.OnVerb(libswarm.Start, libswarm.Handler(c.start))
		c.Server.OnVerb(libswarm.Ls, libswarm.Handler(c.containers))
		c.OnVerb(libswarm.Get, libswarm.Handler(c.containerInspect))
		_, err := ctx.Ret.Send(&libswarm.Message{Verb: libswarm.Ack, Ret: c.Server})
		return err
	}))
	return backend
}
예제 #9
0
func DockerServer() libswarm.Sender {
	backend := libswarm.NewServer()
	backend.OnVerb(libswarm.Spawn, libswarm.Handler(func(ctx *libswarm.Message) error {
		instance := utils.Task(func(in libswarm.Receiver, out libswarm.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(&libswarm.Message{Verb: libswarm.Ack, Ret: instance})
		return err
	}))
	return backend
}
예제 #10
0
func FakeClient() libswarm.Sender {
	backend := libswarm.NewServer()
	backend.OnVerb(libswarm.Spawn, libswarm.Handler(func(ctx *libswarm.Message) error {
		// Instantiate a new fakeclient instance
		instance := utils.Task(func(in libswarm.Receiver, out libswarm.Sender) {
			fmt.Printf("fake client!\n")
			defer fmt.Printf("end of fake client!\n")
			o := libswarm.AsClient(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(&libswarm.Message{Verb: libswarm.Ack, Ret: instance})
		return err
	}))
	return backend
}
예제 #11
0
// Spawn will return a new instance as the Ret channel of the message sent back
func (dbg *debug) spawn(msg *libswarm.Message) (err error) {
	// By sending back a task, libswarm will run the function with the in and out arguments
	// set to the services present before and after this one in the pipeline.
	instance := utils.Task(func(in libswarm.Receiver, out libswarm.Sender) {
		// Setup our channels
		dbg.out = out

		// Set up the debug interceptor
		dbg.service.Catchall(libswarm.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.
		libswarm.Copy(dbg.service, in)
	})

	// Inform the system of our new instance
	msg.Ret.Send(&libswarm.Message{
		Verb: libswarm.Ack,
		Ret:  instance,
	})

	return
}
예제 #12
0
func Exec() libswarm.Sender {
	e := libswarm.NewServer()
	e.OnVerb(libswarm.Spawn, libswarm.Handler(func(msg *libswarm.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: libswarm.NewServer(),
		}
		cmd.OnVerb(libswarm.Attach, libswarm.Handler(func(msg *libswarm.Message) error {
			stdout, err := cmd.StdoutPipe()
			if err != nil {
				return err
			}
			stdin, err := cmd.StdinPipe()
			if err != nil {
				return err
			}
			inR, inW := libswarm.Pipe()
			if _, err := msg.Ret.Send(&libswarm.Message{Verb: libswarm.Ack, Ret: inW}); err != nil {
				return err
			}
			out := libswarm.AsClient(msg.Ret)
			go func() {
				defer stdin.Close()
				for {
					msg, err := inR.Receive(0)
					if err != nil {
						return
					}
					if msg.Verb == libswarm.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.OnVerb(libswarm.Start, libswarm.Handler(func(msg *libswarm.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 {
					libswarm.AsClient(msg.Ret).Log("%s exited status=%v", cmd.Cmd.Path, err)
				}
			}()
			msg.Ret.Send(&libswarm.Message{Verb: libswarm.Ack})
			return nil
		}))
		if _, err := msg.Ret.Send(&libswarm.Message{Verb: libswarm.Ack, Ret: cmd}); err != nil {
			return err
		}
		return nil
	}))
	return e
}