sandbox: timeout runsc commands

The current mechanism for forcing a process to die ater a timeout is not
sufficient. This change fixes issues that were causing processes to run
forever on the sandbox.

- Gracefully terminate processes before we kill them inside of our
gVisor process. This helps capture valuable debug output for the user.

- Return a friendlier error when our run context times out on the
playground.

- Add a test that timeouts are handled gracefully.

- Reduce concurrent goroutines in our sandbox run handler by replacing
goroutine copy functions with a custom writer (limitedWriter) that
returns an error if too much output is returned, halting the program.

- Custom writers (limitedWriter, switchWriter) also fix timing errors
when calling Wait() too soon on a Command, before we have read all of
the data. It also fixes a different error from trying to read data after
a program has terminated.

- Remove goroutine from startContainer, and use a ticker + context
timeout for synchronization.

Updates golang/go#25224
Updates golang/go#38343

Change-Id: Ie9d65220e5c4f39272ea70b45c4b472bcd7069bb
Reviewed-on: https://go-review.googlesource.com/c/playground/+/227652
Run-TryBot: Alexander Rakoczy <alex@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
5 files changed
tree: 7f25616f7c8488f95f3d409f1aa51b3a67db32be
  1. cmd/
  2. deploy/
  3. examples/
  4. internal/
  5. sandbox/
  6. static/
  7. .gitignore
  8. AUTHORS
  9. CONTRIBUTING.md
  10. CONTRIBUTORS
  11. Dockerfile
  12. LICENSE
  13. Makefile
  14. PATENTS
  15. README.md
  16. app.yaml
  17. cache.go
  18. client.go
  19. codereview.cfg
  20. edit.go
  21. edit.html
  22. enable-fake-time.patch
  23. fake_fs.lst
  24. fmt.go
  25. fmt_test.go
  26. go.mod
  27. go.sum
  28. logger.go
  29. main.go
  30. play.go
  31. play_test.go
  32. sandbox.go
  33. server.go
  34. server_test.go
  35. share.go
  36. store.go
  37. tests.go
  38. txtar.go
  39. txtar_test.go
  40. vet.go
README.md

playground

This subrepository holds the source for the Go playground: https://play.golang.org/

Building

# build the image
docker build -t playground .

Running

docker run --name=play --rm -p 8080:8080 golang/playground &
# run some Go code
cat /path/to/code.go | go run client.go | curl -s --upload-file - localhost:8080/compile

Deployment

Deployment Triggers

Playground releases automatically triggered when new Go repository tags are pushed to GitHub, or when master is pushed on the playground repository.

For details, see deploy/go_trigger.json, deploy/playground_trigger.json, and deploy/deploy.json.

After making changes to trigger configuration, update configuration by running the following Make target:

make update-cloudbuild-trigger

Deploy via Cloud Build

The Cloud Build configuration will always build and deploy with the latest supported release of Go.

gcloud builds submit --config deploy/deploy.json .

Deploy via gcloud app deploy

Building the playground Docker container takes more than the default 10 minute time limit of cloud build, so increase its timeout first (note, app/cloud_build_timeout is a global configuration value):

gcloud config set app/cloud_build_timeout 1200  # 20 mins

Alternatively, to avoid Cloud Build and build locally:

make docker
docker tag golang/playground:latest gcr.io/golang-org/playground:latest
docker push gcr.io/golang-org/playground:latest
gcloud --project=golang-org --account=you@google.com app deploy app.yaml --image-url=gcr.io/golang-org/playground:latest

Then:

gcloud --project=golang-org --account=you@google.com app deploy app.yaml

Contributing

To submit changes to this repository, see https://golang.org/doc/contribute.html.