Merge sandbox and frontend into one service
Since frontend was moved to the flex runtime, there is no longer
a reason to keep the two separate. Consolidate the two into one
service to reduce deployment complexity.
Change-Id: Ie64c17e1833ed94ac8bff7381963f683d824ca5d
Reviewed-on: https://go-review.googlesource.com/85456
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 88dff59..b252820 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -24,7 +24,7 @@
before sending patches.
**We do not accept GitHub pull requests**
-(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review).
+(we use [Gerrit](https://www.gerritcodereview.com/) instead for code review).
Unless otherwise noted, the Go source files are distributed under
the BSD-style license found in the LICENSE file.
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..a99db1e
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,181 @@
+# Copyright 2017 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+FROM debian:jessie
+LABEL maintainer "golang-dev@googlegroups.com"
+
+ENV GOPATH /go
+ENV PATH /usr/local/go/bin:$GOPATH/bin:$PATH
+ENV GOROOT_BOOTSTRAP /usr/local/gobootstrap
+ENV GO_VERSION 1.9.2
+ENV BUILD_DEPS 'curl bzip2 git ca-certificates gcc patch libc6-dev'
+
+# Fake time
+COPY enable-fake-time.patch /usr/local/playground/
+# Fake file system
+COPY fake_fs.lst /usr/local/playground/
+
+RUN set -x && \
+ apt-get update && apt-get install -y ${BUILD_DEPS} --no-install-recommends && rm -rf /var/lib/apt/lists/*
+
+RUN curl -s https://storage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/49.0.2623.87/naclsdk_linux.tar.bz2 | tar -xj -C /usr/local/bin --strip-components=2 pepper_49/tools/sel_ldr_x86_64
+
+# Get the Go binary.
+RUN curl -sSL https://dl.google.com/go/go$GO_VERSION.linux-amd64.tar.gz -o /tmp/go.tar.gz && \
+ curl -sSL https://dl.google.com/go/go$GO_VERSION.linux-amd64.tar.gz.sha256 -o /tmp/go.tar.gz.sha256 && \
+ echo "$(cat /tmp/go.tar.gz.sha256) /tmp/go.tar.gz" | sha256sum -c - && \
+ tar -C /usr/local/ -vxzf /tmp/go.tar.gz && \
+ rm /tmp/go.tar.gz /tmp/go.tar.gz.sha256 && \
+ # Make a copy for GOROOT_BOOTSTRAP, because we rebuild the toolchain and make.bash removes bin/go as its first step.
+ cp -R /usr/local/go $GOROOT_BOOTSTRAP && \
+ # Apply the fake time and fake filesystem patches.
+ patch /usr/local/go/src/runtime/rt0_nacl_amd64p32.s /usr/local/playground/enable-fake-time.patch && \
+ cd /usr/local/go && go run misc/nacl/mkzip.go -p syscall /usr/local/playground/fake_fs.lst src/syscall/fstest_nacl.go && \
+ # Re-build the Go toolchain.
+ cd /usr/local/go/src && GOOS=nacl GOARCH=amd64p32 ./make.bash --no-clean && \
+ # Clean up.
+ rm -rf $GOROOT_BOOTSTRAP
+
+# Add and compile tour packages
+RUN GOOS=nacl GOARCH=amd64p32 go get \
+ golang.org/x/tour/pic \
+ golang.org/x/tour/reader \
+ golang.org/x/tour/tree \
+ golang.org/x/tour/wc \
+ golang.org/x/talks/2016/applicative/google && \
+ rm -rf $GOPATH/src/golang.org/x/tour/.git && \
+ rm -rf $GOPATH/src/golang.org/x/talks/.git
+
+# Add tour packages under their old import paths (so old snippets still work)
+RUN mkdir -p $GOPATH/src/code.google.com/p/go-tour && \
+ cp -R $GOPATH/src/golang.org/x/tour/* $GOPATH/src/code.google.com/p/go-tour/ && \
+ sed -i 's_// import_// public import_' $(find $GOPATH/src/code.google.com/p/go-tour/ -name *.go) && \
+ go install \
+ code.google.com/p/go-tour/pic \
+ code.google.com/p/go-tour/reader \
+ code.google.com/p/go-tour/tree \
+ code.google.com/p/go-tour/wc
+
+# BEGIN deps (run `make update-deps` to update)
+
+# Repo cloud.google.com/go at 558b56d (2017-07-03)
+ENV REV=558b56dfa3c56acc26fef35cb07f97df0bb18b39
+RUN go get -d cloud.google.com/go/compute/metadata `#and 5 other pkgs` &&\
+ (cd /go/src/cloud.google.com/go && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Repo github.com/golang/protobuf at 748d386 (2017-07-26)
+ENV REV=748d386b5c1ea99658fd69fe9f03991ce86a90c1
+RUN go get -d github.com/golang/protobuf/proto `#and 6 other pkgs` &&\
+ (cd /go/src/github.com/golang/protobuf && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Repo golang.org/x/net at 66aacef (2017-08-28)
+ENV REV=66aacef3dd8a676686c7ae3716979581e8b03c47
+RUN go get -d golang.org/x/net/context `#and 8 other pkgs` &&\
+ (cd /go/src/golang.org/x/net && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Repo golang.org/x/oauth2 at cce311a (2017-06-29)
+ENV REV=cce311a261e6fcf29de72ca96827bdb0b7d9c9e6
+RUN go get -d golang.org/x/oauth2 `#and 5 other pkgs` &&\
+ (cd /go/src/golang.org/x/oauth2 && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Repo golang.org/x/text at 2bf8f2a (2017-06-30)
+ENV REV=2bf8f2a19ec09c670e931282edfe6567f6be21c9
+RUN go get -d golang.org/x/text/secure/bidirule `#and 4 other pkgs` &&\
+ (cd /go/src/golang.org/x/text && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Repo golang.org/x/tools at 89c69fd (2017-09-01)
+ENV REV=89c69fd3045b723bb4d9f75d73b881c50ab481c0
+RUN go get -d golang.org/x/tools/go/ast/astutil `#and 3 other pkgs` &&\
+ (cd /go/src/golang.org/x/tools && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Repo google.golang.org/api at e6586c9 (2017-06-27)
+ENV REV=e6586c9293b9d514c7f5d5076731ec977cff1be6
+RUN go get -d google.golang.org/api/googleapi/transport `#and 5 other pkgs` &&\
+ (cd /go/src/google.golang.org/api && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Repo google.golang.org/genproto at aa2eb68 (2017-06-01)
+ENV REV=aa2eb687b4d3e17154372564ad8d6bf11c3cf21f
+RUN go get -d google.golang.org/genproto/googleapis/api/annotations `#and 4 other pkgs` &&\
+ (cd /go/src/google.golang.org/genproto && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Repo google.golang.org/grpc at 3c33c26 (2017-06-27)
+ENV REV=3c33c26290b747350f8650c7d38bcc51b42dc785
+RUN go get -d google.golang.org/grpc `#and 15 other pkgs` &&\
+ (cd /go/src/google.golang.org/grpc && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Optimization to speed up iterative development, not necessary for correctness:
+RUN go install cloud.google.com/go/compute/metadata \
+ cloud.google.com/go/datastore \
+ cloud.google.com/go/internal/atomiccache \
+ cloud.google.com/go/internal/fields \
+ cloud.google.com/go/internal/version \
+ github.com/golang/protobuf/proto \
+ github.com/golang/protobuf/protoc-gen-go/descriptor \
+ github.com/golang/protobuf/ptypes/any \
+ github.com/golang/protobuf/ptypes/struct \
+ github.com/golang/protobuf/ptypes/timestamp \
+ github.com/golang/protobuf/ptypes/wrappers \
+ golang.org/x/net/context \
+ golang.org/x/net/context/ctxhttp \
+ golang.org/x/net/http2 \
+ golang.org/x/net/http2/hpack \
+ golang.org/x/net/idna \
+ golang.org/x/net/internal/timeseries \
+ golang.org/x/net/lex/httplex \
+ golang.org/x/net/trace \
+ golang.org/x/oauth2 \
+ golang.org/x/oauth2/google \
+ golang.org/x/oauth2/internal \
+ golang.org/x/oauth2/jws \
+ golang.org/x/oauth2/jwt \
+ golang.org/x/text/secure/bidirule \
+ golang.org/x/text/transform \
+ golang.org/x/text/unicode/bidi \
+ golang.org/x/text/unicode/norm \
+ golang.org/x/tools/go/ast/astutil \
+ golang.org/x/tools/godoc/static \
+ golang.org/x/tools/imports \
+ google.golang.org/api/googleapi/transport \
+ google.golang.org/api/internal \
+ google.golang.org/api/iterator \
+ google.golang.org/api/option \
+ google.golang.org/api/transport \
+ google.golang.org/genproto/googleapis/api/annotations \
+ google.golang.org/genproto/googleapis/datastore/v1 \
+ google.golang.org/genproto/googleapis/rpc/status \
+ google.golang.org/genproto/googleapis/type/latlng \
+ google.golang.org/grpc \
+ google.golang.org/grpc/codes \
+ google.golang.org/grpc/credentials \
+ google.golang.org/grpc/credentials/oauth \
+ google.golang.org/grpc/grpclb/grpc_lb_v1 \
+ google.golang.org/grpc/grpclog \
+ google.golang.org/grpc/internal \
+ google.golang.org/grpc/keepalive \
+ google.golang.org/grpc/metadata \
+ google.golang.org/grpc/naming \
+ google.golang.org/grpc/peer \
+ google.golang.org/grpc/stats \
+ google.golang.org/grpc/status \
+ google.golang.org/grpc/tap \
+ google.golang.org/grpc/transport
+# END deps
+
+RUN apt-get purge -y --auto-remove ${BUILD_DEPS}
+
+# Add and compile playground daemon
+COPY . /go/src/playground/
+RUN go install playground
+
+RUN mkdir /app
+
+COPY edit.html /app
+COPY static /app/static
+
+WORKDIR /app
+
+# Run tests
+RUN /go/bin/playground test
+
+EXPOSE 8080
+ENTRYPOINT ["/go/bin/playground"]
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..0854a90
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,12 @@
+.PHONY: update-deps docker test
+
+update-deps:
+ go install golang.org/x/build/cmd/gitlock
+ gitlock --update=Dockerfile golang.org/x/playground/frontend
+
+docker: Dockerfile
+ docker build -t playground .
+
+test: docker
+ go test
+ docker run --rm playground test
diff --git a/README.md b/README.md
index 2fd7edc..ec92d82 100644
--- a/README.md
+++ b/README.md
@@ -1,78 +1,31 @@
# playground
-This subrepository holds the source for various packages and tools that support
-the Go playground: https://play.golang.org/
+This subrepository holds the source for the Go playground:
+https://play.golang.org/
To submit changes to this repository, see http://golang.org/doc/contribute.html.
-## Frontend
-
-### Building
+## Building
```
-# build the frontend image
-docker build -t frontend frontend/
+# build the image
+docker build -t playground .
```
-### Running with an in-memory store
+## Running
```
-docker run --rm -d -p 8080:8080 frontend
-```
-
-### Running with the Cloud Datastore Emulator
-
-```
-# install it if needed
-gcloud components install cloud-datastore-emulator
-# run the datastore emulator
-gcloud --project=golang-org beta emulators datastore start
-# set env vars
-$(gcloud beta emulators datastore env-init)
-# run the frontend
-cd frontend && go install && frontend
-```
-
-Now visit localhost:8080 to ensure it worked.
-
-```
-# unset any env vars once finished
-$(gcloud beta emulators datastore env-unset)
-```
-
-## Sandbox
-
-### Building
-
-```
-# build the sandbox image
-docker build -t sandbox sandbox/
-```
-
-### Running
-
-```
-# run the sandbox
-docker run -d -p 8080:8080 sandbox
-# get docker host ip, try boot2docker fallback on localhost.
-DOCKER_HOST_IP=$(boot2docker ip || echo localhost)
+docker run --rm -d -p 8080:8080 playground
# run go some code
-cat /path/to/code.go | go run ./sandbox/client.go | curl --data @- $DOCKER_HOST_IP:8080/compile
+cat /path/to/code.go | go run client.go | curl --data @- localhost:8080/compile
```
-To submit changes to this repository, see http://golang.org/doc/contribute.html.
-
# Deployment
```
-gcloud --project=golang-org --account=person@example.com app deploy frontend/app.yaml
+gcloud --project=golang-org --account=person@example.com app deploy app.yaml
```
-```
-gcloud --project=golang-org --account=person@example.com app deploy sandbox/app-flex.yaml --no-promote
-```
+# Contributing
-Use the Cloud Console's to set the new version as the default:
-https://cloud.google.com/console/appengine/versions?project=golang-org&moduleId=sandbox-flex
-Then test that play.golang.org and tour.golang.org are working before deleting
-the old version.
+To submit changes to this repository, see http://golang.org/doc/contribute.html.
\ No newline at end of file
diff --git a/frontend/app.yaml b/app.yaml
similarity index 100%
rename from frontend/app.yaml
rename to app.yaml
diff --git a/sandbox/client.go b/client.go
similarity index 87%
rename from sandbox/client.go
rename to client.go
index eee62f9..c168c3c 100644
--- a/sandbox/client.go
+++ b/client.go
@@ -1,6 +1,6 @@
// +build ignore
-// Copyright 2014 The Go Authors. All rights reserved.
+// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/frontend/edit.go b/edit.go
similarity index 100%
rename from frontend/edit.go
rename to edit.go
diff --git a/frontend/edit.html b/edit.html
similarity index 100%
rename from frontend/edit.html
rename to edit.html
diff --git a/sandbox/enable-fake-time.patch b/enable-fake-time.patch
similarity index 100%
rename from sandbox/enable-fake-time.patch
rename to enable-fake-time.patch
diff --git a/sandbox/fake_fs.lst b/fake_fs.lst
similarity index 100%
rename from sandbox/fake_fs.lst
rename to fake_fs.lst
diff --git a/frontend/fmt.go b/fmt.go
similarity index 100%
rename from frontend/fmt.go
rename to fmt.go
diff --git a/frontend/Dockerfile b/frontend/Dockerfile
deleted file mode 100644
index 1594a89..0000000
--- a/frontend/Dockerfile
+++ /dev/null
@@ -1,143 +0,0 @@
-# Copyright 2017 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-FROM golang:1.9.2
-LABEL maintainer "golang-dev@googlegroups.com"
-
-# BEGIN deps (run `make update-deps` to update)
-
-# Repo cloud.google.com/go at 3051b91 (2017-12-06)
-ENV REV=3051b919da3b8d62bc3a57ab4b353ca1c72402d5
-RUN go get -d cloud.google.com/go/compute/metadata `#and 6 other pkgs` &&\
- (cd /go/src/cloud.google.com/go && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
-
-# Repo github.com/golang/protobuf at 1e59b77 (2017-11-13)
-ENV REV=1e59b77b52bf8e4b449a57e6f79f21226d571845
-RUN go get -d github.com/golang/protobuf/proto `#and 8 other pkgs` &&\
- (cd /go/src/github.com/golang/protobuf && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
-
-# Repo github.com/googleapis/gax-go at 317e000 (2017-09-15)
-ENV REV=317e0006254c44a0ac427cc52a0e083ff0b9622f
-RUN go get -d github.com/googleapis/gax-go &&\
- (cd /go/src/github.com/googleapis/gax-go && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
-
-# Repo golang.org/x/net at faacc1b (2017-12-07)
-ENV REV=faacc1b5e36e3ff02cbec9661c69ac63dd5a83ad
-RUN go get -d golang.org/x/net/context `#and 8 other pkgs` &&\
- (cd /go/src/golang.org/x/net && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
-
-# Repo golang.org/x/oauth2 at 6a2004c (2017-12-06)
-ENV REV=6a2004c8907a86949d71c664c81574897a4e55a6
-RUN go get -d golang.org/x/oauth2 `#and 5 other pkgs` &&\
- (cd /go/src/golang.org/x/oauth2 && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
-
-# Repo golang.org/x/text at be25de4 (2017-12-07)
-ENV REV=be25de41fadfae372d6470bda81ca6beb55ef551
-RUN go get -d golang.org/x/text/secure/bidirule `#and 4 other pkgs` &&\
- (cd /go/src/golang.org/x/text && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
-
-# Repo golang.org/x/tools at 5d8e38b (2017-12-10)
-ENV REV=5d8e38b9550d35d893ff8276756b4118ec1bf360
-RUN go get -d golang.org/x/tools/go/ast/astutil `#and 3 other pkgs` &&\
- (cd /go/src/golang.org/x/tools && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
-
-# Repo google.golang.org/api at 9a048ca (2017-12-07)
-ENV REV=9a048cac3675aa589c62a35d7d42b25451dd15f1
-RUN go get -d google.golang.org/api/googleapi `#and 6 other pkgs` &&\
- (cd /go/src/google.golang.org/api && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
-
-# Repo google.golang.org/genproto at 7f0da29 (2017-11-23)
-ENV REV=7f0da29060c682909f650ad8ed4e515bd74fa12a
-RUN go get -d google.golang.org/genproto/googleapis/api/annotations `#and 4 other pkgs` &&\
- (cd /go/src/google.golang.org/genproto && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
-
-# Repo google.golang.org/grpc at b8191e5 (2017-12-06)
-ENV REV=b8191e57b23de650278db4d23bf596219e5f3665
-RUN go get -d google.golang.org/grpc `#and 24 other pkgs` &&\
- (cd /go/src/google.golang.org/grpc && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
-
-# Optimization to speed up iterative development, not necessary for correctness:
-RUN go install cloud.google.com/go/compute/metadata \
- cloud.google.com/go/datastore \
- cloud.google.com/go/internal \
- cloud.google.com/go/internal/atomiccache \
- cloud.google.com/go/internal/fields \
- cloud.google.com/go/internal/version \
- github.com/golang/protobuf/proto \
- github.com/golang/protobuf/protoc-gen-go/descriptor \
- github.com/golang/protobuf/ptypes \
- github.com/golang/protobuf/ptypes/any \
- github.com/golang/protobuf/ptypes/duration \
- github.com/golang/protobuf/ptypes/struct \
- github.com/golang/protobuf/ptypes/timestamp \
- github.com/golang/protobuf/ptypes/wrappers \
- github.com/googleapis/gax-go \
- golang.org/x/net/context \
- golang.org/x/net/context/ctxhttp \
- golang.org/x/net/http2 \
- golang.org/x/net/http2/hpack \
- golang.org/x/net/idna \
- golang.org/x/net/internal/timeseries \
- golang.org/x/net/lex/httplex \
- golang.org/x/net/trace \
- golang.org/x/oauth2 \
- golang.org/x/oauth2/google \
- golang.org/x/oauth2/internal \
- golang.org/x/oauth2/jws \
- golang.org/x/oauth2/jwt \
- golang.org/x/text/secure/bidirule \
- golang.org/x/text/transform \
- golang.org/x/text/unicode/bidi \
- golang.org/x/text/unicode/norm \
- golang.org/x/tools/go/ast/astutil \
- golang.org/x/tools/godoc/static \
- golang.org/x/tools/imports \
- google.golang.org/api/googleapi \
- google.golang.org/api/googleapi/internal/uritemplates \
- google.golang.org/api/internal \
- google.golang.org/api/iterator \
- google.golang.org/api/option \
- google.golang.org/api/transport/grpc \
- google.golang.org/genproto/googleapis/api/annotations \
- google.golang.org/genproto/googleapis/datastore/v1 \
- google.golang.org/genproto/googleapis/rpc/status \
- google.golang.org/genproto/googleapis/type/latlng \
- google.golang.org/grpc \
- google.golang.org/grpc/balancer \
- google.golang.org/grpc/balancer/base \
- google.golang.org/grpc/balancer/roundrobin \
- google.golang.org/grpc/codes \
- google.golang.org/grpc/connectivity \
- google.golang.org/grpc/credentials \
- google.golang.org/grpc/credentials/oauth \
- google.golang.org/grpc/encoding \
- google.golang.org/grpc/grpclb/grpc_lb_v1/messages \
- google.golang.org/grpc/grpclog \
- google.golang.org/grpc/internal \
- google.golang.org/grpc/keepalive \
- google.golang.org/grpc/metadata \
- google.golang.org/grpc/naming \
- google.golang.org/grpc/peer \
- google.golang.org/grpc/resolver \
- google.golang.org/grpc/resolver/dns \
- google.golang.org/grpc/resolver/manual \
- google.golang.org/grpc/resolver/passthrough \
- google.golang.org/grpc/stats \
- google.golang.org/grpc/status \
- google.golang.org/grpc/tap \
- google.golang.org/grpc/transport
-# END deps
-
-# Add and compile frontend daemon
-COPY . /go/src/frontend/
-RUN go install frontend
-
-RUN mkdir /app
-
-COPY edit.html /app
-COPY static /app/static
-
-WORKDIR /app
-
-EXPOSE 8080
-ENTRYPOINT ["/go/bin/frontend"]
diff --git a/frontend/Makefile b/frontend/Makefile
deleted file mode 100644
index 2b5f1b5..0000000
--- a/frontend/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-update-deps:
- go install golang.org/x/build/cmd/gitlock
- gitlock --update=Dockerfile golang.org/x/playground/frontend
\ No newline at end of file
diff --git a/frontend/compile.go b/frontend/compile.go
deleted file mode 100644
index 0c4deb5..0000000
--- a/frontend/compile.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "io"
- "net/http"
-)
-
-const runURL = "https://golang.org/compile?output=json"
-
-func (s *server) handleCompile(w http.ResponseWriter, r *http.Request) {
- if r.Method != "POST" {
- http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
- return
- }
- if err := s.passThru(w, r); err != nil {
- http.Error(w, "Compile server error.", http.StatusInternalServerError)
- return
- }
-}
-
-func (s *server) passThru(w io.Writer, req *http.Request) error {
- defer req.Body.Close()
- r, err := http.Post(runURL, req.Header.Get("Content-type"), req.Body)
- if err != nil {
- s.log.Errorf("error making POST request: %v", err)
- return err
- }
- defer r.Body.Close()
- if _, err := io.Copy(w, r.Body); err != nil {
- s.log.Errorf("error copying response Body: %v", err)
- return err
- }
- return nil
-}
diff --git a/frontend/logger.go b/logger.go
similarity index 100%
rename from frontend/logger.go
rename to logger.go
diff --git a/frontend/main.go b/main.go
similarity index 94%
rename from frontend/main.go
rename to main.go
index 497f49c..acef3f6 100644
--- a/frontend/main.go
+++ b/main.go
@@ -17,6 +17,11 @@
var log = newStdLogger()
func main() {
+ if len(os.Args) > 1 && os.Args[1] == "test" {
+ test()
+ return
+ }
+
s, err := newServer(func(s *server) error {
pid := projectID()
if pid == "" {
diff --git a/sandbox/play.go b/play.go
similarity index 98%
rename from sandbox/play.go
rename to play.go
index 601666f..fd56676 100644
--- a/sandbox/play.go
+++ b/play.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The Go Authors. All rights reserved.
+// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/sandbox/play_test.go b/play_test.go
similarity index 95%
rename from sandbox/play_test.go
rename to play_test.go
index bdf2a0b..69f9dd4 100644
--- a/sandbox/play_test.go
+++ b/play_test.go
@@ -1,4 +1,4 @@
-// Copyright 2015 The Go Authors. All rights reserved.
+// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/sandbox/sandbox.go b/sandbox.go
similarity index 69%
rename from sandbox/sandbox.go
rename to sandbox.go
index 69ca24f..97ba0ba 100644
--- a/sandbox/sandbox.go
+++ b/sandbox.go
@@ -1,23 +1,21 @@
-// Copyright 2014 The Go Authors. All rights reserved.
+// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// TODO(adg): add logging
-// TODO(proppy): restrict memory use
-// TODO(adg): send exit code to user
+// TODO(andybons): add logging
+// TODO(andybons): restrict memory use
+// TODO(andybons): send exit code to user
-// Command sandbox is an HTTP server that takes requests containing go
-// source files, and builds and executes them in a NaCl sanbox.
package main
import (
+ "context"
"encoding/json"
- "errors"
"fmt"
"go/parser"
"go/token"
"io/ioutil"
- "log"
+ stdlog "log"
"net/http"
"os"
"os/exec"
@@ -28,28 +26,22 @@
const maxRunTime = 2 * time.Second
-type Request struct {
+type request struct {
Body string
}
-type Response struct {
+type response struct {
Errors string
Events []Event
}
-func main() {
- if len(os.Args) > 1 && os.Args[1] == "test" {
- test()
- return
- }
- http.HandleFunc("/compile", compileHandler)
- http.HandleFunc("/_ah/health", healthHandler)
- log.Fatal(http.ListenAndServe(":8080", nil))
-}
-
-func compileHandler(w http.ResponseWriter, r *http.Request) {
- var req Request
- if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
+func handleCompile(w http.ResponseWriter, r *http.Request) {
+ var req request
+ // Until programs that depend on golang.org/x/tools/godoc/static/playground.js
+ // are updated to always send JSON, this check is in place.
+ if b := r.FormValue("body"); b != "" {
+ req.Body = b
+ } else if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, fmt.Sprintf("error decoding request: %v", err), http.StatusBadRequest)
return
}
@@ -64,7 +56,8 @@
}
}
-func compileAndRun(req *Request) (*Response, error) {
+func compileAndRun(req *request) (*response, error) {
+ // TODO(andybons): Add semaphore to limit number of running programs at once.
tmpDir, err := ioutil.TempDir("", "sandbox")
if err != nil {
return nil, fmt.Errorf("error creating temp directory: %v", err)
@@ -80,7 +73,7 @@
f, err := parser.ParseFile(fset, in, nil, parser.PackageClauseOnly)
if err == nil && f.Name.Name != "main" {
- return &Response{Errors: "package name must be main"}, nil
+ return &response{Errors: "package name must be main"}, nil
}
exe := filepath.Join(tmpDir, "a.out")
@@ -98,17 +91,19 @@
// message before any compile errors; strip it.
errs = strings.Replace(errs, "# command-line-arguments\n", "", 1)
- return &Response{Errors: errs}, nil
+ return &response{Errors: errs}, nil
}
return nil, fmt.Errorf("error building go source: %v", err)
}
- cmd = exec.Command("sel_ldr_x86_64", "-l", "/dev/null", "-S", "-e", exe)
+ ctx, cancel := context.WithTimeout(context.Background(), maxRunTime)
+ defer cancel()
+ cmd = exec.CommandContext(ctx, "sel_ldr_x86_64", "-l", "/dev/null", "-S", "-e", exe)
rec := new(Recorder)
cmd.Stdout = rec.Stdout()
cmd.Stderr = rec.Stderr()
- if err := runTimeout(cmd, maxRunTime); err != nil {
- if err == timeoutErr {
- return &Response{Errors: "process took too long"}, nil
+ if err := cmd.Run(); err != nil {
+ if ctx.Err() == context.DeadlineExceeded {
+ return &response{Errors: "process took too long"}, nil
}
if _, ok := err.(*exec.ExitError); !ok {
return nil, fmt.Errorf("error running sandbox: %v", err)
@@ -118,40 +113,11 @@
if err != nil {
return nil, fmt.Errorf("error decoding events: %v", err)
}
- return &Response{Events: events}, nil
-}
-
-var timeoutErr = errors.New("process timed out")
-
-func runTimeout(cmd *exec.Cmd, d time.Duration) error {
- if err := cmd.Start(); err != nil {
- return err
- }
- errc := make(chan error, 1)
- go func() {
- errc <- cmd.Wait()
- }()
- t := time.NewTimer(d)
- select {
- case err := <-errc:
- t.Stop()
- return err
- case <-t.C:
- cmd.Process.Kill()
- return timeoutErr
- }
-}
-
-func healthHandler(w http.ResponseWriter, r *http.Request) {
- if err := healthCheck(); err != nil {
- http.Error(w, "Health check failed: "+err.Error(), http.StatusInternalServerError)
- return
- }
- fmt.Fprint(w, "ok")
+ return &response{Events: events}, nil
}
func healthCheck() error {
- resp, err := compileAndRun(&Request{Body: healthProg})
+ resp, err := compileAndRun(&request{Body: healthProg})
if err != nil {
return err
}
@@ -174,24 +140,24 @@
func test() {
if err := healthCheck(); err != nil {
- log.Fatal(err)
+ stdlog.Fatal(err)
}
for _, t := range tests {
- resp, err := compileAndRun(&Request{Body: t.prog})
+ resp, err := compileAndRun(&request{Body: t.prog})
if err != nil {
- log.Fatal(err)
+ stdlog.Fatal(err)
}
if t.errors != "" {
if resp.Errors != t.errors {
- log.Fatalf("resp.Errors = %q, want %q", resp.Errors, t.errors)
+ stdlog.Fatalf("resp.Errors = %q, want %q", resp.Errors, t.errors)
}
continue
}
if resp.Errors != "" {
- log.Fatal(resp.Errors)
+ stdlog.Fatal(resp.Errors)
}
if len(resp.Events) != 1 || !strings.Contains(resp.Events[0].Message, t.want) {
- log.Fatalf("unexpected output: %v, want %q", resp.Events, t.want)
+ stdlog.Fatalf("unexpected output: %v, want %q", resp.Events, t.want)
}
}
fmt.Println("OK")
diff --git a/sandbox/Dockerfile b/sandbox/Dockerfile
deleted file mode 100644
index b20cbc4..0000000
--- a/sandbox/Dockerfile
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright 2014 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-FROM debian:jessie
-
-ENV GOPATH /go
-ENV PATH /usr/local/go/bin:$GOPATH/bin:$PATH
-ENV GOROOT_BOOTSTRAP /usr/local/gobootstrap
-ENV GO_VERSION 1.9.2
-
-# Fake time
-COPY enable-fake-time.patch /usr/local/sandbox/
-# Fake file system
-COPY fake_fs.lst /usr/local/sandbox/
-
-RUN set -x && buildDeps='curl ca-certificates bzip2'; \
- apt-get update && apt-get install -y $buildDeps --no-install-recommends && rm -rf /var/lib/apt/lists/* && \
- curl -s https://storage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/44.0.2403.157/naclsdk_linux.tar.bz2 | tar -xj -C /usr/local/bin --strip-components=2 pepper_44/tools/sel_ldr_x86_64 && \
- apt-get purge -y --auto-remove $buildDeps
-
-RUN set -x && buildDeps='curl ca-certificates gcc patch libc6-dev'; \
- apt-get update && apt-get install -y $buildDeps --no-install-recommends && rm -rf /var/lib/apt/lists/* && \
- # Get the Go binary.
- curl -sSL https://dl.google.com/go/go$GO_VERSION.linux-amd64.tar.gz -o /tmp/go.tar.gz && \
- curl -sSL https://dl.google.com/go/go$GO_VERSION.linux-amd64.tar.gz.sha256 -o /tmp/go.tar.gz.sha256 && \
- echo "$(cat /tmp/go.tar.gz.sha256) /tmp/go.tar.gz" | sha256sum -c - && \
- tar -C /usr/local/ -vxzf /tmp/go.tar.gz && \
- rm /tmp/go.tar.gz /tmp/go.tar.gz.sha256 && \
- # Make a copy for GOROOT_BOOTSTRAP, because we rebuild the toolchain and make.bash removes bin/go as its first step.
- cp -R /usr/local/go $GOROOT_BOOTSTRAP && \
- # Apply the fake time and fake filesystem patches.
- patch /usr/local/go/src/runtime/rt0_nacl_amd64p32.s /usr/local/sandbox/enable-fake-time.patch && \
- cd /usr/local/go && go run misc/nacl/mkzip.go -p syscall /usr/local/sandbox/fake_fs.lst src/syscall/fstest_nacl.go && \
- # Re-build the Go toolchain.
- cd /usr/local/go/src && GOOS=nacl GOARCH=amd64p32 ./make.bash --no-clean && \
- # Clean up.
- rm -rf $GOROOT_BOOTSTRAP && \
- apt-get purge -y --auto-remove $buildDeps
-
-# Add and compile tour packages
-RUN set -x && buildDeps='git ca-certificates'; \
- apt-get update && apt-get install -y $buildDeps --no-install-recommends && rm -rf /var/lib/apt/lists/* && \
- GOOS=nacl GOARCH=amd64p32 go get \
- golang.org/x/tour/pic \
- golang.org/x/tour/reader \
- golang.org/x/tour/tree \
- golang.org/x/tour/wc \
- golang.org/x/talks/2016/applicative/google && \
- rm -rf $GOPATH/src/golang.org/x/tour/.git && \
- rm -rf $GOPATH/src/golang.org/x/talks/.git && \
- apt-get purge -y --auto-remove $buildDeps
-
-# Add tour packages under their old import paths (so old snippets still work)
-RUN mkdir -p $GOPATH/src/code.google.com/p/go-tour && \
- cp -R $GOPATH/src/golang.org/x/tour/* $GOPATH/src/code.google.com/p/go-tour/ && \
- sed -i 's_// import_// public import_' $(find $GOPATH/src/code.google.com/p/go-tour/ -name *.go) && \
- go install \
- code.google.com/p/go-tour/pic \
- code.google.com/p/go-tour/reader \
- code.google.com/p/go-tour/tree \
- code.google.com/p/go-tour/wc
-
-# Add and compile sandbox daemon
-COPY . /go/src/sandbox/
-RUN go install sandbox
-
-# Run tests
-RUN /go/bin/sandbox test
-
-EXPOSE 8080
-ENTRYPOINT ["/go/bin/sandbox"]
diff --git a/sandbox/Makefile b/sandbox/Makefile
deleted file mode 100644
index 72cdfc2..0000000
--- a/sandbox/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-docker: Dockerfile
- docker build -t playground/sandbox .
-
-test: docker
- go test
- docker run --rm playground/sandbox test
diff --git a/sandbox/app-flex.yaml b/sandbox/app-flex.yaml
deleted file mode 100644
index fad29f8..0000000
--- a/sandbox/app-flex.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-service: sandbox-flex
-runtime: custom
-env: flex
-
-automatic_scaling:
- min_num_instances: 5
- max_num_instances: 20
-
-health_check:
- check_interval_sec: 20
- restart_threshold: 10
diff --git a/sandbox/app.yaml b/sandbox/app.yaml
deleted file mode 100644
index 8e6a30d..0000000
--- a/sandbox/app.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-service: sandbox
-runtime: custom
-vm: true
-
-automatic_scaling:
- min_num_instances: 5
- max_num_instances: 20
-
-health_check:
- check_interval_sec: 20
- restart_threshold: 10
-
-handlers:
-- url: /.*
- script: _go_app
-
diff --git a/sandbox/container-vm.yaml b/sandbox/container-vm.yaml
deleted file mode 100644
index 3bd498f..0000000
--- a/sandbox/container-vm.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-version: v1beta2
-containers:
- - name: sandbox
- # TODO(proppy): publish the sandbox image to the hub
- image: golang/playground-sandbox
- ports:
- - containerPort: 8080
- hostPort: 80
diff --git a/frontend/server.go b/server.go
similarity index 91%
rename from frontend/server.go
rename to server.go
index 136124c..350b384 100644
--- a/frontend/server.go
+++ b/server.go
@@ -48,9 +48,9 @@
func (s *server) init() {
s.mux.HandleFunc("/", s.handleEdit)
- s.mux.HandleFunc("/compile", s.handleCompile)
s.mux.HandleFunc("/fmt", handleFmt)
s.mux.HandleFunc("/share", s.handleShare)
+ s.mux.HandleFunc("/compile", handleCompile)
s.mux.HandleFunc("/playground.js", s.handlePlaygroundJS)
s.mux.HandleFunc("/favicon.ico", handleFavicon)
s.mux.HandleFunc("/_ah/health", handleHealthCheck)
@@ -70,7 +70,11 @@
}
func handleHealthCheck(w http.ResponseWriter, r *http.Request) {
- fmt.Fprintf(w, "ok")
+ if err := healthCheck(); err != nil {
+ http.Error(w, "Health check failed: "+err.Error(), http.StatusInternalServerError)
+ return
+ }
+ fmt.Fprint(w, "ok")
}
func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
diff --git a/frontend/server_test.go b/server_test.go
similarity index 100%
rename from frontend/server_test.go
rename to server_test.go
diff --git a/frontend/share.go b/share.go
similarity index 100%
rename from frontend/share.go
rename to share.go
diff --git a/frontend/static/favicon.ico b/static/favicon.ico
similarity index 100%
rename from frontend/static/favicon.ico
rename to static/favicon.ico
Binary files differ
diff --git a/frontend/static/godoc.css b/static/godoc.css
similarity index 100%
rename from frontend/static/godoc.css
rename to static/godoc.css
diff --git a/frontend/static/gopher.png b/static/gopher.png
similarity index 100%
rename from frontend/static/gopher.png
rename to static/gopher.png
Binary files differ
diff --git a/frontend/static/jquery-linedtextarea.js b/static/jquery-linedtextarea.js
similarity index 100%
rename from frontend/static/jquery-linedtextarea.js
rename to static/jquery-linedtextarea.js
diff --git a/frontend/static/playground-embed.js b/static/playground-embed.js
similarity index 100%
rename from frontend/static/playground-embed.js
rename to static/playground-embed.js
diff --git a/frontend/static/style.css b/static/style.css
similarity index 100%
rename from frontend/static/style.css
rename to static/style.css
diff --git a/frontend/store.go b/store.go
similarity index 100%
rename from frontend/store.go
rename to store.go