Beispiel #1
0
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
}
Beispiel #2
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
}
Beispiel #3
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
}
Beispiel #4
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
}
Beispiel #5
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
}
Beispiel #6
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
}
Beispiel #7
0
func (b *dockerClientBackend) newContainer(id string) libswarm.Sender {
	c := &container{backend: b, id: id}
	instance := libswarm.NewServer()
	instance.OnAttach(c.attach)
	instance.OnStart(c.start)
	instance.OnStop(c.stop)
	instance.OnGet(c.get)
	return instance
}
Beispiel #8
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
}
Beispiel #9
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
}
Beispiel #10
0
func Aggregate() libswarm.Sender {
	backend := libswarm.NewServer()
	backend.OnSpawn(func(cmd ...string) (libswarm.Sender, error) {
		allBackends := New()
		instance := libswarm.NewServer()

		a, err := newAggregator(allBackends, instance, cmd)
		if err != nil {
			return nil, err
		}

		instance.OnAttach(a.attach)
		instance.OnStart(a.start)
		instance.OnLs(a.ls)

		return instance, nil
	})
	return backend
}
Beispiel #11
0
func cmdDaemon(c *cli.Context) {
	app := libswarm.NewServer()
	app.OnLog(func(args ...string) error {
		log.Printf("%s\n", strings.Join(args, " "))
		return nil
	})
	app.OnError(func(args ...string) error {
		Fatalf("Fatal: %v", strings.Join(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 libswarm.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 libswarm.Receiver, w libswarm.Sender, idx int) {
			if r != nil {
				libswarm.Copy(w, r)
			}
			w.Close()
		}(previousInstanceR, instanceW, idx)
		if err := instance.Start(); err != nil {
			Fatalf("start: %v", err)
		}
		previousInstanceR = instanceR
	}
	_, err := libswarm.Copy(app, previousInstanceR)
	if err != nil {
		Fatalf("copy: %v", err)
	}
}
Beispiel #12
0
func DockerClientWithConfig(config *DockerClientConfig) libswarm.Sender {
	backend := libswarm.NewServer()
	backend.OnSpawn(func(cmd ...string) (libswarm.Sender, error) {
		if len(cmd) != 1 {
			return nil, fmt.Errorf("dockerclient: spawn takes exactly 1 argument, got %d", len(cmd))
		}
		client := newClient()
		client.scheme = config.Scheme
		client.urlHost = config.URLHost
		client.transport.TLSClientConfig = config.TLSClientConfig
		client.setURL(cmd[0])
		b := &dockerClientBackend{
			client: client,
			Server: libswarm.NewServer(),
		}
		b.Server.OnAttach(b.attach)
		b.Server.OnStart(b.start)
		b.Server.OnLs(b.ls)
		b.Server.OnSpawn(b.spawn)
		return b.Server, nil
	})
	return backend
}
Beispiel #13
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
}
Beispiel #14
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
}
Beispiel #15
0
func Orchard() libswarm.Sender {
	backend := libswarm.NewServer()
	backend.OnSpawn(func(cmd ...string) (libswarm.Sender, error) {
		if len(cmd) != 2 {
			return nil, fmt.Errorf("orchard: spawn expects 2 arguments: API token and name of host")
		}
		apiToken, hostName := cmd[0], cmd[1]

		apiClient := &api.HTTPClient{
			BaseURL: "https://api.orchardup.com/v2",
			Token:   apiToken,
		}

		host, err := apiClient.GetHost(hostName)
		if err != nil {
			return nil, err
		}

		url := fmt.Sprintf("tcp://%s:4243", host.IPAddress)
		tlsConfig, err := getTLSConfig([]byte(host.ClientCert), []byte(host.ClientKey))
		if err != nil {
			return nil, err
		}

		backend := DockerClientWithConfig(&DockerClientConfig{
			Scheme:          "https",
			URLHost:         host.IPAddress,
			TLSClientConfig: tlsConfig,
		})
		forwardBackend := libswarm.AsClient(backend)
		forwardInstance, err := forwardBackend.Spawn(url)
		if err != nil {
			return nil, err
		}

		return forwardInstance, nil
	})
	return backend
}
Beispiel #16
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
}