playground: remove files from old location now that the repos have moved
Change-Id: Id0a0bb18de7df28032b10a129e6c09e1c5e5f4b2
diff --git a/tools/playground/.gitignore b/tools/playground/.gitignore
deleted file mode 100644
index a25285a..0000000
--- a/tools/playground/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-builder/netrc
diff --git a/tools/playground/README.md b/tools/playground/README.md
deleted file mode 100644
index 94c9355..0000000
--- a/tools/playground/README.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# Building a Docker image and running the playground server locally
-
-## Docker setup
-
-Install Docker:
-
-* Goobuntu: http://go/installdocker
-* OS X: https://github.com/boot2docker/osx-installer/releases
-
-On Goobuntu, we recommend overriding the default graph dir (`/var/lib/docker`)
-to avoid filling up the root filesystem partition, which is quite small. To do
-so, add the following line to your `/etc/default/docker`:
-
- DOCKER_OPTS="${DOCKER_OPTS} -g /usr/local/google/docker"
-
-Start (or restart) the Docker daemon:
-
- $ sudo service docker restart
-
-Build the playground Docker image (this will take a while...):
-
- $ cp ~/.netrc $VEYRON_ROOT/veyron/go/src/veyron.io/veyron/veyron/tools/playground/builder/netrc
- $ sudo docker build -t playground $VEYRON_ROOT/veyron/go/src/veyron.io/veyron/veyron/tools/playground/builder/.
-
-Note: If you want to ensure an up-to-date version of veyron is installed in the
-Docker image, run the above command with the "--no-cache" flag.
-
-Test your image (without running compilerd):
-
- $ sudo docker run -i playground < /usr/local/google/home/sadovsky/dev/veyron-www/content/playgrounds/code/fortune/ex0-go/bundle.json
-
-## Running the playground server (compilerd)
-
-Install the playground binaries:
-
- $ veyron go install veyron.io/veyron/veyron/tools/playground/...
-
-Run the compiler binary as root:
-
- $ sudo $VEYRON_ROOT/veyron/go/bin/compilerd --shutdown=false --address=localhost:8181
-
-The server should now be running at http://localhost:8181 and responding to
-compile requests at http://localhost:8181/compile. Add `?pgaddr=localhost:8181`
-to any veyron-www page to make its embedded playgrounds talk to your server.
diff --git a/tools/playground/builder/Dockerfile b/tools/playground/builder/Dockerfile
deleted file mode 100644
index 5d86ab7..0000000
--- a/tools/playground/builder/Dockerfile
+++ /dev/null
@@ -1,63 +0,0 @@
-FROM ubuntu
-RUN /usr/sbin/useradd -d /home/playground -m playground
-
-# Install various prereqs.
-RUN apt-get update
-RUN apt-get install -y curl g++ git libc6-i386 make python
-
-# Install Go. Note, the apt-get "golang" target is too old.
-RUN (cd /tmp; curl -O https://storage.googleapis.com/golang/go1.3.3.linux-amd64.tar.gz)
-RUN tar -C /usr/local -xzf /tmp/go1.3.3.linux-amd64.tar.gz
-ENV PATH /usr/local/go/bin:$PATH
-
-ENV HOME /root
-ENV VEYRON_ROOT /usr/local/veyron
-ENV GOPATH /home/playground:$VEYRON_ROOT/veyron/go
-ENV VDLPATH $GOPATH
-
-# Setup veyron and veyron profiles.
-# Note: This will be cached! If you want to re-build the docker image using
-# fresh veyron code, you must pass "--no-cache" to the docker build command.
-# See README.md.
-ADD netrc /root/.netrc
-RUN curl -u veyron:D6HT]P,LrJ7e https://www.envyor.com/noproxy/veyron-setup.sh | bash
-RUN rm /root/.netrc
-RUN $VEYRON_ROOT/bin/veyron profile setup web
-
-# Install the veyron.js library.
-# TODO(nlacasse): Switch to "npm install -g veyron" once veyron.js is publicly
-# visible in NPM.
-WORKDIR /usr/local/veyron/veyron.js/
-# NOTE(sadovsky): NPM is flaky. If any of the NPM commands below fail, simply
-# retry them.
-RUN $VEYRON_ROOT/environment/cout/node/bin/npm install --production
-RUN $VEYRON_ROOT/environment/cout/node/bin/npm link
-WORKDIR /home/playground
-RUN $VEYRON_ROOT/environment/cout/node/bin/npm link veyron
-
-# Install Veyron Go dependencies.
-WORKDIR /usr/local/veyron/veyron
-ENV PATH $VEYRON_ROOT/veyron/go/bin:$VEYRON_ROOT/bin:$PATH
-RUN veyron go install veyron.io/veyron/...
-
-# Uncomment the following lines to install a version of the builder tool using
-# your local version of the code. This is useful when developing and testing
-# local changes.
-#RUN rm $VEYRON_ROOT/veyron/go/bin/builder
-#ADD main.go $VEYRON_ROOT/veyron/go/src/veyron.io/veyron/veyron/tools/playground/builder/main.go
-#ADD identity.go $VEYRON_ROOT/veyron/go/src/veyron.io/veyron/veyron/tools/playground/builder/identity.go
-#ADD services.go $VEYRON_ROOT/veyron/go/src/veyron.io/veyron/veyron/tools/playground/builder/services.go
-#ADD multi_writer.go $VEYRON_ROOT/veyron/go/src/veyron.io/veyron/veyron/tools/playground/builder/multi_writer.go
-#RUN veyron go install veyron.io/veyron/veyron/tools/playground/builder
-
-# Copy proxyd's main.go to builder/proxyd_main.go, then uncomment the following
-# lines to install a version of proxyd (used by the builder tool) using your
-# local version of the code. This is useful when developing and testing local
-# changes.
-#RUN rm $VEYRON_ROOT/veyron/go/bin/proxyd
-#ADD proxyd_main.go $VEYRON_ROOT/veyron/go/src/veyron.io/veyron/veyron/services/proxy/proxyd/main.go
-#RUN veyron go install veyron.io/veyron/veyron/services/proxy/proxyd
-
-USER playground
-WORKDIR /home/playground
-ENTRYPOINT /usr/local/veyron/veyron/go/bin/builder
diff --git a/tools/playground/builder/identity.go b/tools/playground/builder/identity.go
deleted file mode 100644
index 81584e5..0000000
--- a/tools/playground/builder/identity.go
+++ /dev/null
@@ -1,79 +0,0 @@
-// Functions to create and bless identities.
-
-package main
-
-import (
- "os"
- "path"
-)
-
-type identity struct {
- Name string
- Blesser string
- Duration string
- Files []string
-}
-
-func (id identity) create() error {
- if err := id.generate(); err != nil {
- return err
- }
- if id.Blesser != "" || id.Duration != "" {
- return id.bless()
- }
- return nil
-}
-
-func (id identity) generate() error {
- args := []string{"generate"}
- if id.Blesser == "" && id.Duration == "" {
- args = append(args, id.Name)
- }
- return runIdentity(args, path.Join("ids", id.Name))
-}
-
-func (id identity) bless() error {
- filename := path.Join("ids", id.Name)
- var blesser string
- if id.Blesser == "" {
- blesser = filename
- } else {
- blesser = path.Join("ids", id.Blesser)
- }
- args := []string{"bless", "--with", blesser}
- if id.Duration != "" {
- args = append(args, "--for", id.Duration)
- }
- args = append(args, filename, id.Name)
- tempfile := filename + ".tmp"
- if err := runIdentity(args, tempfile); err != nil {
- return err
- }
- return os.Rename(tempfile, filename)
-}
-
-func createIdentities(ids []identity) error {
- debug("Generating identities")
- if err := os.MkdirAll("ids", 0777); err != nil {
- return err
- }
- for _, id := range ids {
- if err := id.create(); err != nil {
- return err
- }
- }
- return nil
-}
-
-func runIdentity(args []string, filename string) error {
- cmd := makeCmd("", false, "identity", args...)
- out, err := os.Create(filename)
- if err != nil {
- return err
- }
- defer out.Close()
- // Note, here we actually overwrite cmd.Stdout (rather than adding a writer to
- // the multiWriter), so only stderr will be streamed back to the client.
- cmd.Stdout = out
- return cmd.Run()
-}
diff --git a/tools/playground/builder/main.go b/tools/playground/builder/main.go
deleted file mode 100644
index a249051..0000000
--- a/tools/playground/builder/main.go
+++ /dev/null
@@ -1,411 +0,0 @@
-// Compiles and runs code for the Veyron playground. Code is passed via os.Stdin
-// as a JSON encoded request struct.
-
-// NOTE(nlacasse): We use log.Panic() instead of log.Fatal() everywhere in this
-// file. We do this because log.Panic calls panic(), which allows any deferred
-// function to run. In particular, this will cause the mounttable and proxy
-// processes to be killed in the event of a compilation error. log.Fatal, on
-// the other hand, calls os.Exit(1), which does not call deferred functions,
-// and will leave proxy and mounttable processes running. This is not a big
-// deal for production environment, because the Docker instance gets cleaned up
-// after each run, but during development and testing these extra processes can
-// cause issues.
-
-package main
-
-import (
- "encoding/json"
- "flag"
- "fmt"
- "go/parser"
- "go/token"
- "io"
- "io/ioutil"
- "log"
- "os"
- "os/exec"
- "path"
- "path/filepath"
- "strconv"
- "strings"
- "sync"
- "syscall"
- "time"
-
- "veyron.io/veyron/veyron/tools/playground/event"
-)
-
-const runTimeout = 3 * time.Second
-
-var (
- verbose = flag.Bool("v", false, "Whether to output debug messages")
-
- includeServiceOutput = flag.Bool("includeServiceOutput", false,
- "Whether to stream service (mounttable, wspr, proxy) output to clients")
-
- // Whether we have stopped execution of running files.
- stopped = false
-
- mu sync.Mutex
-)
-
-// Type of data sent to the builder on stdin. Input should contain Files. We
-// look for a file whose Name ends with .id, and parse that into Identities.
-//
-// TODO(nlacasse): Update the identity parsing and usage to the new identity
-// APIs.
-//
-// TODO(ribrdb): Consider moving identity parsing into the http server.
-type request struct {
- Files []*codeFile
- Identities []identity
-}
-
-// Type of file data. Only Name and Body should be initially set. The other
-// fields are added as the file is parsed.
-type codeFile struct {
- Name string
- Body string
- // Language the file is written in. Inferred from the file extension.
- lang string
- // Identity to associate with the file's process.
- identity string
- // The executable flag denotes whether the file should be executed as
- // part of the playground run. This is currently used only for
- // javascript files, and go files with package "main".
- executable bool
- // Name of the binary (for go files).
- binaryName string
- // Running cmd process for the file.
- cmd *exec.Cmd
- // Any subprocesses that are needed to support running the file (e.g. wspr).
- subprocs []*os.Process
- // The index of the file in the request.
- index int
-}
-
-type exit struct {
- name string
- err error
-}
-
-func debug(args ...interface{}) {
- if *verbose {
- log.Println(args...)
- }
-}
-
-func panicOnError(err error) {
- if err != nil {
- log.Panic(err)
- }
-}
-
-func parseRequest(in io.Reader) (r request, err error) {
- debug("Parsing input")
- data, err := ioutil.ReadAll(in)
- if err == nil {
- err = json.Unmarshal(data, &r)
- }
- m := make(map[string]*codeFile)
- for i := 0; i < len(r.Files); i++ {
- f := r.Files[i]
- f.index = i
- if path.Ext(f.Name) == ".id" {
- err = json.Unmarshal([]byte(f.Body), &r.Identities)
- if err != nil {
- return
- }
- r.Files = append(r.Files[:i], r.Files[i+1:]...)
- i--
- } else {
- switch path.Ext(f.Name) {
- case ".js":
- // JavaScript files are always executable.
- f.executable = true
- f.lang = "js"
- case ".go":
- // Go files will be marked as executable if their package name is
- // "main". This happens in the "maybeSetExecutableAndBinaryName"
- // function.
- f.lang = "go"
- case ".vdl":
- f.lang = "vdl"
- default:
- return r, fmt.Errorf("Unknown file type: %q", f.Name)
- }
-
- basename := path.Base(f.Name)
- if _, ok := m[basename]; ok {
- return r, fmt.Errorf("Two files with same basename: %q", basename)
- }
- m[basename] = f
- }
- }
- if len(r.Identities) == 0 {
- // Run everything with the same identity if none are specified.
- r.Identities = append(r.Identities, identity{Name: "default"})
- for _, f := range r.Files {
- f.identity = "default"
- }
- } else {
- for _, identity := range r.Identities {
- for _, basename := range identity.Files {
- // Check that the file associated with the identity exists. We ignore
- // cases where it doesn't because the test .id files get used for
- // multiple different code files. See testdata/ids/authorized.id, for
- // example.
- if m[basename] != nil {
- m[basename].identity = identity.Name
- }
- }
- }
- }
- return
-}
-
-func writeFiles(files []*codeFile) error {
- debug("Writing files")
- for _, f := range files {
- if err := f.write(); err != nil {
- return fmt.Errorf("Error writing %s: %v", f.Name, err)
- }
- }
- return nil
-}
-
-func compileFiles(files []*codeFile) error {
- needToCompile := false
- for _, f := range files {
- if f.lang == "vdl" || f.lang == "go" {
- needToCompile = true
- break
- }
- }
- if !needToCompile {
- return nil
- }
-
- debug("Compiling files")
- pwd, err := os.Getwd()
- if err != nil {
- return err
- }
- os.Setenv("GOPATH", pwd+":"+os.Getenv("GOPATH"))
- os.Setenv("VDLPATH", pwd+":"+os.Getenv("VDLPATH"))
- // We set isService=false for compilation because "go install" only produces
- // output on error, and we always want clients to see such errors.
- return makeCmd("", false, "veyron", "go", "install", "./...").Run()
-}
-
-func runFiles(files []*codeFile) {
- debug("Running files")
- exit := make(chan exit)
- running := 0
- for _, f := range files {
- if f.executable {
- f.run(exit)
- running++
- }
- }
-
- timeout := time.After(runTimeout)
-
- for running > 0 {
- select {
- case <-timeout:
- panicOnError(writeEvent("", "stderr", "Playground exceeded deadline."))
- stopAll(files)
- case status := <-exit:
- if status.err == nil {
- panicOnError(writeEvent(status.name, "stdout", "Exited cleanly."))
- } else {
- panicOnError(writeEvent(status.name, "stderr", fmt.Sprintf("Exited with error: %v", status.err)))
- }
- running--
- stopAll(files)
- }
- }
-}
-
-func stopAll(files []*codeFile) {
- mu.Lock()
- defer mu.Unlock()
- if !stopped {
- stopped = true
- for _, f := range files {
- f.stop()
- }
- }
-}
-
-func (f *codeFile) maybeSetExecutableAndBinaryName() error {
- debug("Parsing package from", f.Name)
- file, err := parser.ParseFile(token.NewFileSet(), f.Name,
- strings.NewReader(f.Body), parser.PackageClauseOnly)
- if err != nil {
- return err
- }
- pkg := file.Name.String()
- if pkg == "main" {
- f.executable = true
- basename := path.Base(f.Name)
- f.binaryName = basename[:len(basename)-len(path.Ext(basename))]
- }
- return nil
-}
-
-func (f *codeFile) write() error {
- debug("Writing file", f.Name)
- if f.lang == "go" || f.lang == "vdl" {
- if err := f.maybeSetExecutableAndBinaryName(); err != nil {
- return err
- }
- }
- // Retain the original file tree structure.
- if err := os.MkdirAll(path.Dir(f.Name), 0755); err != nil {
- return err
- }
- return ioutil.WriteFile(f.Name, []byte(f.Body), 0644)
-}
-
-func (f *codeFile) startJs() error {
- wsprProc, wsprPort, err := startWspr(f.Name, f.identity)
- if err != nil {
- return fmt.Errorf("Error starting wspr: %v", err)
- }
- f.subprocs = append(f.subprocs, wsprProc)
- os.Setenv("WSPR", "http://localhost:"+strconv.Itoa(wsprPort))
- node := filepath.Join(os.Getenv("VEYRON_ROOT"), "environment", "cout", "node", "bin", "node")
- f.cmd = makeCmd(f.Name, false, node, f.Name)
- return f.cmd.Start()
-}
-
-func (f *codeFile) startGo() error {
- f.cmd = makeCmd(f.Name, false, filepath.Join("bin", f.binaryName))
- if f.identity != "" {
- f.cmd.Env = append(f.cmd.Env, fmt.Sprintf("VEYRON_IDENTITY=%s", filepath.Join("ids", f.identity)))
- }
- return f.cmd.Start()
-}
-
-func (f *codeFile) run(ch chan exit) {
- debug("Running", f.Name)
- err := func() error {
- mu.Lock()
- defer mu.Unlock()
- if stopped {
- return fmt.Errorf("Execution has stopped; not running %s", f.Name)
- }
-
- switch f.lang {
- case "go":
- return f.startGo()
- case "js":
- return f.startJs()
- default:
- return fmt.Errorf("Cannot run file: %v", f.Name)
- }
- }()
- if err != nil {
- debug("Failed to start", f.Name)
- ch <- exit{f.Name, err}
- return
- }
-
- // Wait for the process to exit and send result to channel.
- go func() {
- debug("Waiting for", f.Name)
- err := f.cmd.Wait()
- debug("Done waiting for", f.Name)
- ch <- exit{f.Name, err}
- }()
-}
-
-func (f *codeFile) stop() {
- debug("Attempting to stop", f.Name)
- if f.cmd == nil {
- debug("Cannot stop:", f.Name, "cmd is nil")
- } else if f.cmd.Process == nil {
- debug("Cannot stop:", f.Name, "cmd is not nil, but cmd.Process is nil")
- } else {
- debug("Sending SIGTERM to", f.Name)
- f.cmd.Process.Signal(syscall.SIGTERM)
- }
- for i, subproc := range f.subprocs {
- debug("Killing subprocess", i, "for", f.Name)
- subproc.Kill()
- }
-}
-
-// Creates a cmd whose outputs (stdout and stderr) are streamed to stdout as
-// json-encoded Event objects. If you want to watch the output streams yourself,
-// add your own writer(s) to the multiWriter before starting the command.
-func makeCmd(fileName string, isService bool, progName string, args ...string) *exec.Cmd {
- cmd := exec.Command(progName, args...)
- cmd.Env = os.Environ()
- stdout, stderr := newMultiWriter(), newMultiWriter()
- // TODO(sadovsky): Maybe annotate service output in the event stream.
- if !isService || *includeServiceOutput {
- stdout.Add(newEventStreamer(fileName, "stdout"))
- stderr.Add(newEventStreamer(fileName, "stderr"))
- }
- cmd.Stdout, cmd.Stderr = stdout, stderr
- return cmd
-}
-
-// Initialize using newEventStreamer.
-type eventStreamer struct {
- fileName string
- streamName string
-}
-
-var _ io.Writer = (*eventStreamer)(nil)
-
-func newEventStreamer(fileName, streamName string) *eventStreamer {
- return &eventStreamer{fileName: fileName, streamName: streamName}
-}
-
-func (es *eventStreamer) Write(p []byte) (n int, err error) {
- if err := writeEvent(es.fileName, es.streamName, string(p)); err != nil {
- return 0, err
- }
- return len(p), nil
-}
-
-func writeEvent(fileName, streamName, message string) error {
- e := event.Event{
- File: fileName,
- Message: message,
- Stream: streamName,
- Timestamp: time.Now().UnixNano(),
- }
- jsonEvent, err := json.Marshal(e)
- if err != nil {
- return err
- }
- // TODO(nlacasse): When we switch over to actually streaming events, we'll
- // probably need to trigger a flush here.
- os.Stdout.Write(append(jsonEvent, '\n'))
- return nil
-}
-
-func main() {
- flag.Parse()
- r, err := parseRequest(os.Stdin)
- panicOnError(err)
-
- panicOnError(createIdentities(r.Identities))
-
- mt, err := startMount(runTimeout)
- panicOnError(err)
- defer mt.Kill()
-
- proxy, err := startProxy()
- panicOnError(err)
- defer proxy.Kill()
-
- panicOnError(writeFiles(r.Files))
- panicOnError(compileFiles(r.Files))
- runFiles(r.Files)
-}
diff --git a/tools/playground/builder/multi_writer.go b/tools/playground/builder/multi_writer.go
deleted file mode 100644
index 60f3e88..0000000
--- a/tools/playground/builder/multi_writer.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// MultiWriter creates a writer that duplicates its writes to all the
-// provided writers, similar to the Unix tee(1) command.
-//
-// Similar to http://golang.org/src/pkg/io/multi.go.
-
-package main
-
-import (
- "io"
- "sync"
-)
-
-// Initialize using newMultiWriter.
-type multiWriter struct {
- writers []io.Writer
- mu sync.Mutex
- wrote bool
-}
-
-var _ io.Writer = (*multiWriter)(nil)
-
-func newMultiWriter() *multiWriter {
- return &multiWriter{writers: []io.Writer{}}
-}
-
-// Returns self for convenience.
-func (t *multiWriter) Add(w io.Writer) *multiWriter {
- t.mu.Lock()
- defer t.mu.Unlock()
- if t.wrote {
- panic("Tried to add writer after data has been written.")
- }
- t.writers = append(t.writers, w)
- return t
-}
-
-func (t *multiWriter) Write(p []byte) (n int, err error) {
- t.mu.Lock()
- t.wrote = true
- t.mu.Unlock()
- for _, w := range t.writers {
- n, err = w.Write(p)
- if err != nil {
- return
- }
- if n != len(p) {
- err = io.ErrShortWrite
- return
- }
- }
- return len(p), nil
-}
diff --git a/tools/playground/builder/services.go b/tools/playground/builder/services.go
deleted file mode 100644
index 346d286..0000000
--- a/tools/playground/builder/services.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// Functions to start services needed by the Veyron playground.
-// These should never trigger program exit.
-
-package main
-
-import (
- "bufio"
- "fmt"
- "io"
- "math/rand"
- "os"
- "os/exec"
- "path"
- "regexp"
- "strconv"
- "syscall"
- "time"
-)
-
-var (
- proxyName = "proxy"
-)
-
-// Note: This was copied from veyron/go/src/veyron/tools/findunusedport.
-// I would like to be able to import that package directly, but it defines a
-// main(), so can't be imported. An alternative solution would be to call the
-// 'findunusedport' binary, but that would require starting another process and
-// parsing the output. It seemed simpler to just copy the function here.
-func findUnusedPort() (int, error) {
- rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
- for i := 0; i < 1000; i++ {
- port := 1024 + rnd.Int31n(64512)
- fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
- if err != nil {
- continue
- }
- sa := &syscall.SockaddrInet4{Port: int(port)}
- if err := syscall.Bind(fd, sa); err != nil {
- continue
- }
- syscall.Close(fd)
- return int(port), nil
- }
- return 0, fmt.Errorf("Can't find unused port.")
-}
-
-// startMount starts a mounttabled process, and sets the NAMESPACE_ROOT env
-// variable to the mounttable's location. We run one mounttabled process for
-// the entire environment.
-func startMount(timeLimit time.Duration) (proc *os.Process, err error) {
- cmd := makeCmd("", true, "mounttabled", "--veyron.tcp.address=127.0.0.1:0")
-
- matches, err := startAndWaitFor(cmd, timeLimit, regexp.MustCompile("Mount table .+ endpoint: (.+)\n"))
- if err != nil {
- return nil, fmt.Errorf("Error starting mounttabled: %v", err)
- }
- endpoint := matches[1]
- if endpoint == "" {
- return nil, fmt.Errorf("Failed to get mounttable endpoint")
- }
- return cmd.Process, os.Setenv("NAMESPACE_ROOT", endpoint)
-}
-
-// startProxy starts a proxyd process. We run one proxyd process for the
-// entire environment.
-func startProxy() (proc *os.Process, err error) {
- port, err := findUnusedPort()
- if err != nil {
- return nil, err
- }
- cmd := makeCmd("", true, "proxyd", "-name="+proxyName, "-address=127.0.0.1:"+strconv.Itoa(port), "-http=")
- err = cmd.Start()
- if err != nil {
- return nil, err
- }
- return cmd.Process, err
-}
-
-// startWspr starts a wsprd process. We run one wsprd process for each
-// javascript file being run.
-func startWspr(fileName, identity string) (proc *os.Process, port int, err error) {
- port, err = findUnusedPort()
- if err != nil {
- return nil, port, err
- }
- cmd := makeCmd(fileName, true,
- "wsprd",
- // Verbose logging so we can watch the output for "Listening" log line.
- "-v=3",
- "-veyron.proxy="+proxyName,
- "-port="+strconv.Itoa(port),
- // Retry RPC calls for 3 seconds. If a client makes an RPC call before the
- // server is running, it won't immediately fail, but will retry while the
- // server is starting.
- // TODO(nlacasse): Remove this when javascript can tell wspr how long to
- // retry for. Right now it's a global setting in wspr.
- "-retry-timeout=3",
- // The identd server won't be used, so pass a fake name.
- "-identd=/unused")
- if identity != "" {
- cmd.Env = append(cmd.Env, fmt.Sprintf("VEYRON_IDENTITY=%s", path.Join("ids", identity)))
- }
- if _, err := startAndWaitFor(cmd, 3*time.Second, regexp.MustCompile("Listening")); err != nil {
- return nil, 0, fmt.Errorf("Error starting wspr: %v", err)
- }
- return cmd.Process, port, nil
-}
-
-// Helper function to start a command and wait for output. Arguments are a cmd
-// to run, a timeout, and a regexp. The slice of strings matched by the regexp
-// is returned.
-// TODO(nlacasse): Consider standardizing how services log when they start
-// listening, and their endpoints (if any). Then this could become a common
-// util function.
-func startAndWaitFor(cmd *exec.Cmd, timeout time.Duration, outputRegexp *regexp.Regexp) ([]string, error) {
- reader, writer := io.Pipe()
- // TODO(sadovsky): Why must we listen to both stdout and stderr? We should
- // know which one produces the "Listening" log line...
- cmd.Stdout.(*multiWriter).Add(writer)
- cmd.Stderr.(*multiWriter).Add(writer)
- err := cmd.Start()
- if err != nil {
- return nil, err
- }
-
- buf := bufio.NewReader(reader)
- t := time.After(timeout)
- ch := make(chan []string)
- go (func() {
- for line, err := buf.ReadString('\n'); err == nil; line, err = buf.ReadString('\n') {
- if matches := outputRegexp.FindStringSubmatch(line); matches != nil {
- ch <- matches
- }
- }
- close(ch)
- })()
- select {
- case <-t:
- return nil, fmt.Errorf("Timeout starting service.")
- case matches := <-ch:
- return matches, nil
- }
-}
diff --git a/tools/playground/compilerd/main.go b/tools/playground/compilerd/main.go
deleted file mode 100644
index d9d3827..0000000
--- a/tools/playground/compilerd/main.go
+++ /dev/null
@@ -1,282 +0,0 @@
-package main
-
-import (
- "bytes"
- "crypto/sha1"
- "encoding/json"
- "flag"
- "fmt"
- "io"
- "log"
- "math/rand"
- "net/http"
- "os"
- "os/exec"
- "os/signal"
- "syscall"
- "time"
-
- "github.com/golang/groupcache/lru"
-
- "veyron.io/veyron/veyron/tools/playground/event"
-)
-
-type ResponseBody struct {
- Errors string
- Events []event.Event
-}
-
-type CachedResponse struct {
- Status int
- Body ResponseBody
-}
-
-var (
- // This channel is closed when the server begins shutting down.
- // No values are ever sent to it.
- lameduck chan bool = make(chan bool)
-
- address = flag.String("address", ":8181", "address to listen on")
-
- // Note, shutdown triggers on SIGTERM or when the time limit is hit.
- shutdown = flag.Bool("shutdown", true, "whether to ever shutdown the machine")
-
- // Maximum request and response size. Same limit as imposed by Go tour.
- maxSize = 1 << 16
-
- // In-memory LRU cache of request/response bodies. Keys are sha1 sum of
- // request bodies (20 bytes each), values are of type CachedResponse.
- // NOTE(nlacasse): The cache size (10k) was chosen arbitrarily and should
- // perhaps be optimized.
- cache = lru.New(10000)
-)
-
-func healthz(w http.ResponseWriter, r *http.Request) {
- select {
- case <-lameduck:
- w.WriteHeader(http.StatusInternalServerError)
- default:
- w.Write([]byte("ok"))
- }
-}
-
-func handler(w http.ResponseWriter, r *http.Request) {
- // CORS headers.
- // TODO(nlacasse): Fill the origin header in with actual playground origin
- // before going to production.
- w.Header().Set("Access-Control-Allow-Origin", "*")
- w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS")
- w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding")
-
- // CORS sends an OPTIONS pre-flight request to make sure the request will be
- // allowed.
- if r.Method == "OPTIONS" {
- w.WriteHeader(http.StatusOK)
- return
- }
-
- if r.Body == nil || r.Method != "POST" {
- w.WriteHeader(http.StatusBadRequest)
- return
- }
-
- requestBody := streamToBytes(r.Body)
-
- if len(requestBody) > maxSize {
- responseBody := new(ResponseBody)
- responseBody.Errors = "Program too large."
- respondWithBody(w, http.StatusBadRequest, responseBody)
- return
- }
-
- // Hash the body and see if it's been cached. If so, return the cached
- // response status and body.
- // NOTE(sadovsky): In the client we may shift timestamps (based on current
- // time) and introduce a fake delay.
- requestBodyHash := sha1.Sum(requestBody)
- if cachedResponse, ok := cache.Get(requestBodyHash); ok {
- if cachedResponseStruct, ok := cachedResponse.(CachedResponse); ok {
- respondWithBody(w, cachedResponseStruct.Status, cachedResponseStruct.Body)
- return
- } else {
- log.Printf("Invalid cached response: %v\n", cachedResponse)
- cache.Remove(requestBodyHash)
- }
- }
-
- // TODO(nlacasse): It would be cool if we could stream the output
- // messages while the process is running, rather than waiting for it to
- // exit and dumping all the output then.
-
- id := <-uniq
-
- // TODO(sadovsky): Set runtime constraints on CPU and memory usage.
- // http://docs.docker.com/reference/run/#runtime-constraints-on-cpu-and-memory
- cmd := Docker("run", "-i", "--name", id, "playground")
- cmd.Stdin = bytes.NewReader(requestBody)
-
- // Builder will return all normal output as json events on stdout, and will
- // return unexpected errors on stderr.
- stdoutBuf, stderrBuf := new(bytes.Buffer), new(bytes.Buffer)
- cmd.Stdout, cmd.Stderr = stdoutBuf, stderrBuf
-
- // Arbitrary deadline (enough to compile, run, shutdown).
- timeout := time.After(5000 * time.Millisecond)
- exit := make(chan error)
-
- go func() { exit <- cmd.Run() }()
-
- select {
- case <-exit:
- case <-timeout:
- // TODO(sadovsky): Race condition. More output could show up after this
- // message.
- stderrBuf.Write([]byte("\nTime exceeded, killing...\n"))
- }
-
- // TODO(nlacasse): This takes a long time, during which the client is waiting
- // for a response. I tried moving it to after the response is sent, but a
- // subsequent request will trigger a new "docker run", which somehow has to
- // wait for this "docker rm" to finish. This caused some requests to timeout
- // unexpectedly.
- //
- // We should figure out a better way to run this, so that we can return
- // quickly, and not mess up other requests.
- //
- // Setting GOMAXPROCS may or may not help. See
- // https://github.com/docker/docker/issues/6480
- Docker("rm", "-f", id).Run()
-
- // If the response is bigger than the limit, cache the response and return an
- // error.
- if stdoutBuf.Len() > maxSize {
- status := http.StatusBadRequest
- responseBody := new(ResponseBody)
- responseBody.Errors = "Program output too large."
- cache.Add(requestBodyHash, CachedResponse{
- Status: status,
- Body: *responseBody,
- })
- respondWithBody(w, status, responseBody)
- return
- }
-
- responseBody := new(ResponseBody)
- // TODO(nlacasse): Make these errors Events, so that we can send them
- // back in the Events array. This will simplify streaming the events to the
- // client in realtime.
- responseBody.Errors = stderrBuf.String()
-
- // Decode the json events from stdout and add them to the responseBody.
- for line, err := stdoutBuf.ReadBytes('\n'); err == nil; line, err = stdoutBuf.ReadBytes('\n') {
- var e event.Event
- json.Unmarshal(line, &e)
- responseBody.Events = append(responseBody.Events, e)
- }
-
- cache.Add(requestBodyHash, CachedResponse{
- Status: http.StatusOK,
- Body: *responseBody,
- })
- respondWithBody(w, http.StatusOK, responseBody)
-}
-
-func respondWithBody(w http.ResponseWriter, status int, body interface{}) {
- bodyJson, _ := json.Marshal(body)
- w.Header().Add("Content-Type", "application/json")
- w.Header().Add("Content-Length", fmt.Sprintf("%d", len(bodyJson)))
- w.Write(bodyJson)
-
- // TODO(nlacasse): This flush doesn't really help us right now, but
- // we'll definitly need something like it when we switch to the
- // streaming model.
- if f, ok := w.(http.Flusher); ok {
- f.Flush()
- } else {
- log.Println("Cannot flush.")
- }
-}
-
-func streamToBytes(stream io.Reader) []byte {
- buf := new(bytes.Buffer)
- buf.ReadFrom(stream)
- return buf.Bytes()
-}
-
-func Docker(args ...string) *exec.Cmd {
- fullArgs := []string{"docker"}
- fullArgs = append(fullArgs, args...)
- return exec.Command("sudo", fullArgs...)
-}
-
-// A channel which returns unique ids for the containers.
-var uniq = make(chan string)
-
-func init() {
- val := time.Now().UnixNano()
- go func() {
- for {
- uniq <- fmt.Sprintf("playground_%d", val)
- val++
- }
- }()
-}
-
-func main() {
- flag.Parse()
-
- if *shutdown {
- limit_min := 60
- delay_min := limit_min/2 + rand.Intn(limit_min/2)
-
- // VMs will be periodically killed to prevent any owned VMs from causing
- // damage. We want to shutdown cleanly before then so we don't cause
- // requests to fail.
- go WaitForShutdown(time.Minute * time.Duration(delay_min))
- }
-
- http.HandleFunc("/compile", handler)
- http.HandleFunc("/healthz", healthz)
-
- log.Printf("Serving %s\n", *address)
- http.ListenAndServe(*address, nil)
-}
-
-func WaitForShutdown(limit time.Duration) {
- var beforeExit func() error
-
- // Shutdown if we get a SIGTERM.
- term := make(chan os.Signal, 1)
- signal.Notify(term, syscall.SIGTERM)
-
- // Or if the time limit expires.
- deadline := time.After(limit)
- log.Println("Shutting down at", time.Now().Add(limit))
-Loop:
- for {
- select {
- case <-deadline:
- // Shutdown the VM.
- log.Println("Deadline expired, shutting down.")
- beforeExit = exec.Command("sudo", "halt").Run
- break Loop
- case <-term:
- log.Println("Got SIGTERM, shutting down.")
- // VM is probably already shutting down, so just exit.
- break Loop
- }
- }
- // Fail health checks so we stop getting requests.
- close(lameduck)
- // Give running requests time to finish.
- time.Sleep(30 * time.Second)
-
- // Then go ahead and shutdown.
- if beforeExit != nil {
- err := beforeExit()
- if err != nil {
- panic(err)
- }
- }
- os.Exit(0)
-}
diff --git a/tools/playground/compilerd/pool_template.json b/tools/playground/compilerd/pool_template.json
deleted file mode 100644
index 41b54e4..0000000
--- a/tools/playground/compilerd/pool_template.json
+++ /dev/null
@@ -1,37 +0,0 @@
-{
- "template": {
- "action": {
- "commands": [
- "sudo mount /dev/sdb1 /mnt",
- "sudo docker load < /mnt/playground.tar.gz",
- "start-stop-daemon --start -c ribrdb --exec /mnt/compilerd &> /tmp/compilerd.out &"
- ]
- },
- "healthChecks": [{
- "name": "healthz",
- "path": "/healthz",
- "port": "8181",
- }],
- "vmParams": {
- "machineType": "n1-standard-1",
- "baseInstanceName": "pg-replica",
- "disksToCreate": [{
- "boot": "true",
- "initializeParams": {
- "sourceImage": "https://www.googleapis.com/compute/v1/projects/google-containers/global/images/container-vm-v20140522",
- "diskSizeGb": "200"
- }
- }],
- "disksToAttach": [{
- "source": "pg-data-20140820"
- }],
- "networkInterfaces": [{
- "network": "playground",
- "accessConfigs": [{
- "type": "ONE_TO_ONE_NAT",
- "name": "External NAT"
- }]
- }]
- }
- }
-}
diff --git a/tools/playground/compilerd/update.sh b/tools/playground/compilerd/update.sh
deleted file mode 100644
index e4d07fa..0000000
--- a/tools/playground/compilerd/update.sh
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/bin/bash
-
-# Script to rebuild and deploy the docker image and compiler to the playground
-# backends.
-#
-# Usage:
-# gcutil ssh --project google.com:veyron playground-master
-# sudo su - veyron
-# veyron project update
-# bash $VEYRON_ROOT/go/src/veyron.io/veyron/veyron/tools/playground/compilerd/update.sh
-
-set -e
-readonly DATE=$(date +%F)
-readonly DISK="pg-data-${DATE}"
-
-function unmount() {
- sudo umount /mnt
- gcloud compute --project "google.com:veyron" instances detach-disk --disk="$DISK" $(hostname) --zone us-central1-a
-}
-
-function cleanup() {
- if [[ -e /mnt/compilerd ]]; then
- unmount
- # if the disk was still mounted, nothing is using it so go ahead
- # and delete it.
- gcloud compute --project "google.com:veyron" disks delete "${DISK}" --zone "us-central1-a"
- fi
- sudo docker rm "${DISK}" || true
-}
-trap cleanup EXIT
-
-function main() {
- if [[ ! -e ~/.netrc ]]; then
- echo "Unable to access git, missing ~/.netrc"
- exit 1
- fi
-
- gcloud compute --project "google.com:veyron" disks create "${DISK}" --size "200" --zone "us-central1-a" --source-snapshot "pg-data-20140702" --type "pd-standard"
- gcloud compute --project "google.com:veyron" instances attach-disk --disk="$DISK" $(hostname) --zone us-central1-a
- sudo mount /dev/sdb1 /mnt
-
- # Build the docker image.
- cd ${VEYRON_ROOT}/veyron/go/src/veyron.io/veyron/veyron/tools/playground/builder
- cp ~/.netrc ./netrc
- sudo docker build --no-cache -t playground .
- rm -f ./netrc
-
- # Export the docker image to disk.
- sudo docker save -o /mnt/playground.tar.gz playground
-
- # Copy the compilerd binary from the docker image to the disk.
- sudo docker run --name=${DISK} playground || true
- sudo docker cp ${DISK}:/usr/local/veyron/veyron/go/bin/compilerd /tmp
- sudo mv /tmp/compilerd /mnt/compilerd
- sudo docker rm ${DISK}
-
- # Detach the disk so the backends can mount it.
- unmount
-
- # Update the template to use the new disk.
- cd ../compilerd
- sed -i -e s/pg-data-20140820/${DISK}/ pool_template.json
- gcloud preview replica-pools --zone=us-central1-a update-template --template=pool_template.json playground-pool
- git checkout -- pool_template.json
-
- # Rolling restart of the replicas.
- INSTANCES=$(gcloud preview replica-pools --zone=us-central1-a replicas --pool=playground-pool list|grep name:|cut -d: -f2)
- for i in ${INSTANCES}; do
- gcloud preview replica-pools --zone=us-central1-a replicas --pool=playground-pool restart ${i}
- sleep 5m
- done
-}
-
-main "$@"
diff --git a/tools/playground/event/event.go b/tools/playground/event/event.go
deleted file mode 100644
index 5a1c6cb..0000000
--- a/tools/playground/event/event.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package event
-
-// Note: This is in a seperate package because it is shared by both the builder
-// package and the compilerd package. Both of those define a main(), so one
-// cannot import the other.
-
-// Typed representation of data sent to stdin/stdout from a command. These
-// will be json-encoded and sent to the client.
-type Event struct {
- // File associated with the command.
- File string
- // The text sent to stdin/stderr.
- Message string
- // Stream that the message was sent to, either "stdout" or "stderr".
- Stream string
- // Unix time, the number of nanoseconds elapsed since January 1, 1970 UTC.
- Timestamp int64
-}
diff --git a/tools/playground/monitor.py b/tools/playground/monitor.py
deleted file mode 100755
index 300ef85..0000000
--- a/tools/playground/monitor.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/python2.7
-
-# This needs to run on a gce vm with the replica pool
-# service account scope (https://www.googleapis.com/auth/ndev.cloudman).
-#
-# You also need to enable preview in gcloud:
-# $ gcloud components update preview
-#
-# Then add it to your crontab, e.g.
-# */10 * * * * gcloud preview replica-pools --zone us-central1-a replicas --pool playground-pool list|monitor.py
-
-import os
-import datetime
-import subprocess
-import sys
-import yaml
-
-DESIRED = 2
-MAX_ALIVE_MIN = 60
-POOL = "playground-pool"
-
-def runCommand(*args):
- cmd = ['gcloud', 'preview', 'replica-pools', '--zone', 'us-central1-a']
- cmd.extend(args)
- subprocess.check_call(cmd)
-
-def resizePool(size):
- runCommand("resize", "--new-size", str(size), POOL)
-
-
-def shouldRestart(replica):
- if replica['status']['state'] == 'PERMANENTLY_FAILING':
- print "replica %s failed: %s" % (replica['name'], replica['status']['details'])
- return True
- return isTooOld(replica)
-
-
-def isTooOld(replica):
- start_text = replica['status']['vmStartTime']
- if start_text:
- start = yaml.load(start_text)
- uptime = datetime.datetime.now() - start
- return uptime.seconds > MAX_ALIVE_MIN * 60
-
-
-def restartReplica(replica):
- print "Restarting replica " + replica['name']
- resizePool(DESIRED + 1)
- runCommand("replicas", "--pool", POOL, "delete", replica['name'])
-
-
-def maybeRestartReplica(replica):
- if shouldRestart(replica):
- restartReplica(replica)
-
-
-def main():
- replicas = yaml.load_all(sys.stdin.read())
- for replica in replicas:
- maybeRestartReplica(replica)
-
-
-if __name__ == "__main__":
- main()
diff --git a/tools/playground/pgbundle/.gitignore b/tools/playground/pgbundle/.gitignore
deleted file mode 100644
index 93f1361..0000000
--- a/tools/playground/pgbundle/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-node_modules
-npm-debug.log
diff --git a/tools/playground/pgbundle/.jshintignore b/tools/playground/pgbundle/.jshintignore
deleted file mode 100644
index 3c3629e..0000000
--- a/tools/playground/pgbundle/.jshintignore
+++ /dev/null
@@ -1 +0,0 @@
-node_modules
diff --git a/tools/playground/pgbundle/.jshintrc b/tools/playground/pgbundle/.jshintrc
deleted file mode 100644
index b264540..0000000
--- a/tools/playground/pgbundle/.jshintrc
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "camelcase": true,
- "eqeqeq": true,
- "expr": true,
- "forin": true,
- "freeze": true,
- "immed": true,
- "indent": 2,
- "latedef": "nofunc",
- "maxlen": 80,
- "newcap": true,
- "noarg": true,
- "nonbsp": true,
- "nonew": true,
- "quotmark": "single",
- "sub": true,
- "trailing": true,
- "undef": true,
- "unused": "vars",
-
- "browser": true,
- "devel": true,
- "node": true,
-
- "globals": {
- }
-}
diff --git a/tools/playground/pgbundle/Makefile b/tools/playground/pgbundle/Makefile
deleted file mode 100644
index 43cd1c5..0000000
--- a/tools/playground/pgbundle/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-export SHELL := /bin/bash -euo pipefail
-
-node_modules: package.json
- npm prune
- npm install
- touch node_modules
-
-lint:
- jshint .
-
-.PHONY: lint
diff --git a/tools/playground/pgbundle/bin/pgbundle b/tools/playground/pgbundle/bin/pgbundle
deleted file mode 100755
index 599c379..0000000
--- a/tools/playground/pgbundle/bin/pgbundle
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/usr/bin/env node
-require('../index.js').run();
diff --git a/tools/playground/pgbundle/index.js b/tools/playground/pgbundle/index.js
deleted file mode 100644
index af60a98..0000000
--- a/tools/playground/pgbundle/index.js
+++ /dev/null
@@ -1,119 +0,0 @@
-var _ = require('lodash');
-var fs = require('fs');
-var glob = require('glob');
-var path = require('path');
-
-// Filename to write the data to.
-var BUNDLE_NAME = 'bundle.json';
-
-module.exports = {run: run};
-
-// TODO(nlacasse): improve this.
-function usage() {
- console.log('Usage: pgbundle [options] <path> [<path> <path> ...]');
- console.log('Options: --verbose: Enable verbose output.');
- process.exit(1);
-}
-
-// If the first line is "// +build OMIT", strip the line and return the
-// remaining lines.
-function stripBuildOmit(lines) {
- if (lines[0] === '// +build OMIT') {
- return _.rest(lines);
- }
- return lines;
-}
-
-// If the first line is an index comment, strip the line and return the index
-// and remaining lines.
-function getIndex(lines) {
- var index = null;
- var match = lines[0].match(/^\/\/\s*index=(\d+)/);
- if (match && match[1]) {
- index = match[1];
- lines = _.rest(lines);
- }
- return {
- index: index,
- lines: lines
- };
-}
-
-function shouldIgnore(fileName) {
- // Ignore directories.
- if (_.last(fileName) === '/') {
- return true;
- }
- // Ignore bundle files.
- if (fileName === BUNDLE_NAME) {
- return true;
- }
- // Ignore generated .vdl.go files.
- if ((/\.vdl\.go$/i).test(fileName)) {
- return true;
- }
- return false;
-}
-
-// Main function.
-function run() {
- // Get the paths from process.argv.
- var argv = require('minimist')(process.argv.slice(2));
- var dirs = argv._;
-
- // Make sure there is at least one path.
- if (!dirs || dirs.length === 0) {
- return usage();
- }
-
- // Loop over each path.
- _.each(dirs, function(dir) {
- var relpaths = glob.sync('**', {
- cwd: dir,
- mark: true // Add a '/' char to directory matches.
- });
-
- if (relpaths.length === 0) {
- return usage();
- }
-
- var out = {files: []};
-
- // Loop over each file.
- _.each(relpaths, function(relpath) {
- if (shouldIgnore(relpath)) {
- return;
- }
-
- var abspath = path.resolve(dir, relpath);
- var text = fs.readFileSync(abspath, {encoding: 'utf8'});
-
- var lines = text.split('\n');
- lines = stripBuildOmit(lines);
- var indexAndLines = getIndex(lines);
- var index = indexAndLines.index;
- lines = indexAndLines.lines;
-
- out.files.push({
- name: relpath,
- body: lines.join('\n'),
- index: index
- });
- });
-
- out.files = _.sortBy(out.files, 'index');
-
- // Drop the index fields -- we don't need them anymore.
- out.files = _.map(out.files, function(f) {
- return _.omit(f, 'index');
- });
-
- // Write the bundle.json.
- var outFile = path.resolve(dir, BUNDLE_NAME);
- fs.writeFileSync(outFile, JSON.stringify(out));
-
- if (argv.verbose) {
- console.log('Wrote ' + outFile);
- }
- });
-}
diff --git a/tools/playground/pgbundle/package.json b/tools/playground/pgbundle/package.json
deleted file mode 100644
index 71ef866..0000000
--- a/tools/playground/pgbundle/package.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "pgbundle",
- "description": "Playground file bundler",
- "version": "0.0.1",
- "bin": "./bin/pgbundle",
- "bugs": {
- "url": "https://github.com/veyron/pgbundle/issues"
- },
- "dependencies": {
- "glob": "^4.0.6",
- "lodash": "^2.4.1",
- "minimist": "^1.1.0"
- },
- "homepage": "https://github.com/veyron/pgbundle",
- "private": true,
- "repository": {
- "type": "git",
- "url": "https://github.com/veyron/pgbundle.git"
- }
-}
diff --git a/tools/playground/test.sh b/tools/playground/test.sh
deleted file mode 100755
index 9a8687a..0000000
--- a/tools/playground/test.sh
+++ /dev/null
@@ -1,125 +0,0 @@
-#!/bin/bash
-
-# Tests the playground builder tool.
-
-# TODO(sadovsky): Much of the setup code below also exists in
-# veyron-www/test/playground_test.sh.
-
-source "${VEYRON_ROOT}/scripts/lib/shell_test.sh"
-
-# Installs the veyron.js library and makes it accessible to javascript files in
-# the veyron playground test folder under the module name 'veyron'.
-install_veyron_js() {
- # TODO(nlacasse): Once veyron.js is publicly available in npm, replace this
- # with "npm install veyron".
- pushd "${VEYRON_ROOT}/veyron.js"
- npm link
- popd
- npm link veyron
-}
-
-# Installs the pgbundle tool.
-install_pgbundle() {
- pushd "${VEYRON_ROOT}/veyron/go/src/veyron.io/veyron/veyron/tools/playground/pgbundle"
- npm link
- popd
- npm link pgbundle
-}
-
-# Installs various go binaries.
-build_go_binaries() {
- # Note that "go build" puts built binaries in $(pwd), but only if they are
- # built one at a time. So much for the principle of least surprise...
- local -r V="veyron.io/veyron/veyron"
- veyron go build $V/tools/identity || shell_test::fail "line ${LINENO}: failed to build 'identity'"
- veyron go build $V/services/proxy/proxyd || shell_test::fail "line ${LINENO}: failed to build 'proxyd'"
- veyron go build $V/services/mounttable/mounttabled || shell_test::fail "line ${LINENO}: failed to build 'mounttabled'"
- veyron go build $V/tools/playground/builder || shell_test::fail "line ${LINENO}: failed to build 'builder'"
- veyron go build veyron.io/veyron/veyron2/vdl/vdl || shell_test::fail "line ${LINENO}: failed to build 'vdl'"
- veyron go build veyron.io/wspr/veyron/services/wsprd || shell_test::fail "line ${LINENO}: failed to build 'wsprd'"
-}
-
-# Sets up a directory with the given files, then runs builder.
-test_with_files() {
- local -r TESTDATA_DIR="$(shell::go_package_dir veyron.io/veyron/veyron/tools/playground/testdata)"
-
- # Write input files to a fresh dir, then run pgbundle.
- local -r PGBUNDLE_DIR=$(shell::tmp_dir)
- for f in $@; do
- fdir="${PGBUNDLE_DIR}/$(dirname ${f})"
- mkdir -p "${fdir}"
- cp "${TESTDATA_DIR}/${f}" "${fdir}/"
- done
-
- ./node_modules/.bin/pgbundle "${PGBUNDLE_DIR}"
-
- # Create a fresh dir to run bundler from.
- local -r ORIG_DIR=$(pwd)
- pushd $(shell::tmp_dir)
- ln -s "${ORIG_DIR}/node_modules" ./ # for veyron.js
- "${ORIG_DIR}/builder" < "${PGBUNDLE_DIR}/bundle.json" 2>&1 | tee builder.out
- # Move builder output to original dir for verification.
- mv builder.out "${ORIG_DIR}"
- popd
-}
-
-main() {
- cd $(shell::tmp_dir)
-
- export GOPATH="$(pwd):$(veyron env GOPATH)"
- export VDLPATH="$(pwd):$(veyron env VDLPATH)"
- export PATH="$(pwd):${VEYRON_ROOT}/environment/cout/node/bin:${PATH}"
-
- build_go_binaries
- install_veyron_js
- install_pgbundle
-
- echo -e "\n\n>>>>> Test without identities\n\n"
-
- test_with_files "src/pingpong/wire.vdl" "src/pong/pong.go" "src/ping/ping.go" || shell_test::fail "line ${LINENO}: basic ping (go -> go)"
- grep -q PING builder.out || shell_test::fail "line ${LINENO}: no PING"
- grep -q PONG builder.out || shell_test::fail "line ${LINENO}: no PONG"
-
- test_with_files "src/pong/pong.js" "src/ping/ping.js" || shell_test::fail "line ${LINENO}: basic ping (js -> js)"
- grep -q PING builder.out || shell_test::fail "line ${LINENO}: no PING"
- grep -q PONG builder.out || shell_test::fail "line ${LINENO}: no PONG"
-
- test_with_files "src/pong/pong.go" "src/ping/ping.js" "src/pingpong/wire.vdl" || shell_test::fail "line ${LINENO}: basic ping (js -> go)"
- grep -q PING builder.out || shell_test::fail "line ${LINENO}: no PING"
- grep -q PONG builder.out || shell_test::fail "line ${LINENO}: no PONG"
-
- test_with_files "src/pong/pong.js" "src/ping/ping.go" "src/pingpong/wire.vdl" || shell_test::fail "line ${LINENO}: basic ping (go -> js)"
- grep -q PING builder.out || shell_test::fail "line ${LINENO}: no PING"
- grep -q PONG builder.out || shell_test::fail "line ${LINENO}: no PONG"
-
- echo -e "\n\n>>>>> Test with authorized identities\n\n"
-
- test_with_files "src/pong/pong.go" "src/ping/ping.go" "src/pingpong/wire.vdl" "src/ids/authorized.id" || shell_test::fail "line ${LINENO}: authorized id (go -> go)"
- grep -q PING builder.out || shell_test::fail "line ${LINENO}: no PING"
- grep -q PONG builder.out || shell_test::fail "line ${LINENO}: no PONG"
-
- test_with_files "src/pong/pong.js" "src/ping/ping.js" "src/ids/authorized.id" || shell_test::fail "line ${LINENO}: authorized id (js -> js)"
- grep -q PING builder.out || shell_test::fail "line ${LINENO}: no PING"
- grep -q PONG builder.out || shell_test::fail "line ${LINENO}: no PONG"
-
- echo -e "\n\n>>>>> Test with expired identities\n\n"
-
- test_with_files "src/pong/pong.go" "src/ping/ping.go" "src/pingpong/wire.vdl" "src/ids/expired.id" || shell_test::fail "line ${LINENO}: failed to build with expired id (go -> go)"
- grep -q "ipc: not authorized" builder.out || shell_test::fail "line ${LINENO}: rpc with expired id succeeded"
-
- test_with_files "src/pong/pong.js" "src/ping/ping.js" "src/ids/expired.id" || shell_test::fail "line ${LINENO}: failed to build with expired id (js -> js)"
- grep -q "ipc: not authorized" builder.out || shell_test::fail "line ${LINENO}: rpc with expired id succeeded"
-
- echo -e "\n\n>>>>> Test with unauthorized identities\n\n"
-
- test_with_files "src/pong/pong.go" "src/ping/ping.go" "src/pingpong/wire.vdl" "src/ids/unauthorized.id" || shell_test::fail "line ${LINENO}: failed to build with unauthorized id (go -> go)"
- grep -q "ipc: not authorized" builder.out || shell_test::fail "line ${LINENO}: rpc with unauthorized id succeeded"
-
- # TODO(nlacasse): Write the javascript version of this test once the
- # javascript implementation is capable of checking that an identity is
- # authorized.
-
- shell_test::pass
-}
-
-main "$@"
diff --git a/tools/playground/testdata/src/ids/authorized.id b/tools/playground/testdata/src/ids/authorized.id
deleted file mode 100644
index cca29d1..0000000
--- a/tools/playground/testdata/src/ids/authorized.id
+++ /dev/null
@@ -1,15 +0,0 @@
-[
-{
- "Name": "myorg"
-},
-{
- "Name": "myserver",
- "Blesser": "myorg",
- "Files": ["pong.go", "pong.js"]
-},
-{
- "Name": "myclient",
- "Blesser": "myserver",
- "Files": ["ping.go", "ping.js"]
-}
-]
diff --git a/tools/playground/testdata/src/ids/expired.id b/tools/playground/testdata/src/ids/expired.id
deleted file mode 100644
index 2fee1f3..0000000
--- a/tools/playground/testdata/src/ids/expired.id
+++ /dev/null
@@ -1,7 +0,0 @@
-[
-{
- "Name": "expired",
- "Duration": "0s",
- "Files": ["ping.go", "pong.go", "ping.js", "pong.js"]
-}
-]
diff --git a/tools/playground/testdata/src/ids/unauthorized.id b/tools/playground/testdata/src/ids/unauthorized.id
deleted file mode 100644
index cd39f52..0000000
--- a/tools/playground/testdata/src/ids/unauthorized.id
+++ /dev/null
@@ -1,15 +0,0 @@
-[
-{
- "Name": "myorg"
-},
-{
- "Name": "myserver",
- "Blesser": "myorg",
- "Files": ["pong.go", "pong.js"]
-},
-{
- "Name": "myclient",
- "Blesser": "myorg",
- "Files": ["ping.go", "ping.js"]
-}
-]
diff --git a/tools/playground/testdata/src/ping/ping.go b/tools/playground/testdata/src/ping/ping.go
deleted file mode 100644
index 75593b8..0000000
--- a/tools/playground/testdata/src/ping/ping.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// +build OMIT
-package main
-
-import (
- "fmt"
-
- _ "veyron.io/veyron/veyron/profiles"
- "veyron.io/veyron/veyron2/rt"
-
- "pingpong"
-)
-
-func main() {
- runtime := rt.Init()
- log := runtime.Logger()
-
- s, err := pingpong.BindPingPong("pingpong")
- if err != nil {
- log.Fatal("error binding to server: ", err)
- }
-
- pong, err := s.Ping(runtime.NewContext(), "PING")
- if err != nil {
- log.Fatal("error pinging: ", err)
- }
- fmt.Println(pong)
-}
diff --git a/tools/playground/testdata/src/ping/ping.js b/tools/playground/testdata/src/ping/ping.js
deleted file mode 100644
index 1b6f2d8..0000000
--- a/tools/playground/testdata/src/ping/ping.js
+++ /dev/null
@@ -1,16 +0,0 @@
-var veyron = require('veyron');
-
-veyron.init(function(err, rt){
- if (err) throw err;
-
- rt.bindTo('pingpong', function(err, s){
- if (err) throw err;
-
- s.ping('PING', function(err, pong){
- if (err) throw err;
-
- console.log(pong);
- process.exit(0);
- });
- });
-});
diff --git a/tools/playground/testdata/src/pingpong/wire.vdl b/tools/playground/testdata/src/pingpong/wire.vdl
deleted file mode 100644
index 539231e..0000000
--- a/tools/playground/testdata/src/pingpong/wire.vdl
+++ /dev/null
@@ -1,7 +0,0 @@
-package pingpong
-
-import "veyron.io/veyron/veyron2/security"
-
-type PingPong interface {
- Ping(message string) (string, error) {security.ReadLabel}
-}
diff --git a/tools/playground/testdata/src/pingpong/wire.vdl.go b/tools/playground/testdata/src/pingpong/wire.vdl.go
deleted file mode 100644
index e1aa5db..0000000
--- a/tools/playground/testdata/src/pingpong/wire.vdl.go
+++ /dev/null
@@ -1,187 +0,0 @@
-// This file was auto-generated by the veyron vdl tool.
-// Source: wire.vdl
-
-package pingpong
-
-import (
- "veyron.io/veyron/veyron2/security"
-
- // The non-user imports are prefixed with "_gen_" to prevent collisions.
- _gen_veyron2 "veyron.io/veyron/veyron2"
- _gen_context "veyron.io/veyron/veyron2/context"
- _gen_ipc "veyron.io/veyron/veyron2/ipc"
- _gen_naming "veyron.io/veyron/veyron2/naming"
- _gen_vdlutil "veyron.io/veyron/veyron2/vdl/vdlutil"
- _gen_wiretype "veyron.io/veyron/veyron2/wiretype"
-)
-
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
-const _ = _gen_wiretype.TypeIDInvalid
-
-// PingPong is the interface the client binds and uses.
-// PingPong_ExcludingUniversal is the interface without internal framework-added methods
-// to enable embedding without method collisions. Not to be used directly by clients.
-type PingPong_ExcludingUniversal interface {
- Ping(ctx _gen_context.T, message string, opts ..._gen_ipc.CallOpt) (reply string, err error)
-}
-type PingPong interface {
- _gen_ipc.UniversalServiceMethods
- PingPong_ExcludingUniversal
-}
-
-// PingPongService is the interface the server implements.
-type PingPongService interface {
- Ping(context _gen_ipc.ServerContext, message string) (reply string, err error)
-}
-
-// BindPingPong returns the client stub implementing the PingPong
-// interface.
-//
-// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
-// global Runtime is used.
-func BindPingPong(name string, opts ..._gen_ipc.BindOpt) (PingPong, error) {
- var client _gen_ipc.Client
- switch len(opts) {
- case 0:
- // Do nothing.
- case 1:
- if clientOpt, ok := opts[0].(_gen_ipc.Client); opts[0] == nil || ok {
- client = clientOpt
- } else {
- return nil, _gen_vdlutil.ErrUnrecognizedOption
- }
- default:
- return nil, _gen_vdlutil.ErrTooManyOptionsToBind
- }
- stub := &clientStubPingPong{defaultClient: client, name: name}
-
- return stub, nil
-}
-
-// NewServerPingPong creates a new server stub.
-//
-// It takes a regular server implementing the PingPongService
-// interface, and returns a new server stub.
-func NewServerPingPong(server PingPongService) interface{} {
- return &ServerStubPingPong{
- service: server,
- }
-}
-
-// clientStubPingPong implements PingPong.
-type clientStubPingPong struct {
- defaultClient _gen_ipc.Client
- name string
-}
-
-func (__gen_c *clientStubPingPong) client(ctx _gen_context.T) _gen_ipc.Client {
- if __gen_c.defaultClient != nil {
- return __gen_c.defaultClient
- }
- return _gen_veyron2.RuntimeFromContext(ctx).Client()
-}
-
-func (__gen_c *clientStubPingPong) Ping(ctx _gen_context.T, message string, opts ..._gen_ipc.CallOpt) (reply string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Ping", []interface{}{message}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubPingPong) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubPingPong) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubPingPong) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-// ServerStubPingPong wraps a server that implements
-// PingPongService and provides an object that satisfies
-// the requirements of veyron2/ipc.ReflectInvoker.
-type ServerStubPingPong struct {
- service PingPongService
-}
-
-func (__gen_s *ServerStubPingPong) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
- // TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
- // Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
- // This will change when it is replaced with Signature().
- switch method {
- case "Ping":
- return []interface{}{security.Label(2)}, nil
- default:
- return nil, nil
- }
-}
-
-func (__gen_s *ServerStubPingPong) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
- result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
- result.Methods["Ping"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "message", Type: 3},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 3},
- {Name: "", Type: 65},
- },
- }
-
- result.TypeDefs = []_gen_vdlutil.Any{
- _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
-
- return result, nil
-}
-
-func (__gen_s *ServerStubPingPong) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
- if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
- return unresolver.UnresolveStep(call)
- }
- if call.Server() == nil {
- return
- }
- var published []string
- if published, err = call.Server().Published(); err != nil || published == nil {
- return
- }
- reply = make([]string, len(published))
- for i, p := range published {
- reply[i] = _gen_naming.Join(p, call.Name())
- }
- return
-}
-
-func (__gen_s *ServerStubPingPong) Ping(call _gen_ipc.ServerCall, message string) (reply string, err error) {
- reply, err = __gen_s.service.Ping(call, message)
- return
-}
diff --git a/tools/playground/testdata/src/pong/pong.go b/tools/playground/testdata/src/pong/pong.go
deleted file mode 100644
index 7a30485..0000000
--- a/tools/playground/testdata/src/pong/pong.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// +build OMIT
-package main
-
-import (
- "fmt"
-
- "veyron.io/veyron/veyron/lib/signals"
- _ "veyron.io/veyron/veyron/profiles"
- sflag "veyron.io/veyron/veyron/security/flag"
- "veyron.io/veyron/veyron2/ipc"
- "veyron.io/veyron/veyron2/rt"
-
- "pingpong"
-)
-
-type pongd struct{}
-
-func (f *pongd) Ping(_ ipc.ServerContext, message string) (result string, err error) {
- fmt.Println(message)
- return "PONG", nil
-}
-
-func main() {
- r := rt.Init()
- log := r.Logger()
- s, err := r.NewServer()
- if err != nil {
- log.Fatal("failure creating server: ", err)
- }
- log.Info("Waiting for ping")
-
- serverPong := pingpong.NewServerPingPong(&pongd{})
-
- if endpoint, err := s.Listen("tcp", "127.0.0.1:0"); err == nil {
- fmt.Printf("Listening at: %v\n", endpoint)
- } else {
- log.Fatal("error listening to service: ", err)
- }
-
- if err := s.Serve("pingpong", ipc.LeafDispatcher(serverPong, sflag.NewAuthorizerOrDie())); err != nil {
- log.Fatal("error serving service: ", err)
- }
-
- // Wait forever.
- <-signals.ShutdownOnSignals()
-}
diff --git a/tools/playground/testdata/src/pong/pong.js b/tools/playground/testdata/src/pong/pong.js
deleted file mode 100644
index 71d31e3..0000000
--- a/tools/playground/testdata/src/pong/pong.js
+++ /dev/null
@@ -1,17 +0,0 @@
-var veyron = require('veyron');
-var leafDispatcher = require('veyron/src/ipc/leaf_dispatcher');
-
-var pingPongService = {
- ping: function(msg){
- console.log(msg);
- return 'PONG';
- }
-};
-
-veyron.init(function(err, rt) {
- if (err) throw err;
-
- rt.serve('pingpong', leafDispatcher(pingPongService), function(err) {
- if (err) throw err;
- });
-});