Fiddle 3.0 Design

Fiddle is broken in to two pieces, each run as containers on kubernetes.

  1. Fiddle
  2. Handles serving the web UI.
  3. Reads/writes results to/from Google Cloud Storage.
  4. Is exposed to Ingress.
  5. Fiddler
  6. Accepts code to run via POST.
  7. Compiles and runs code.
  8. Returns results of run as JSON.
  9. The pods are never exposed as a Service.
  10. The pods are severely locked down.
  11. Fiddler pods are killed after 1 run.

A number of fiddlers are run on kubernetes and await code sent by fiddle. After a single run the container is deleted and kubernetes will schedule a replacement pod.

+-------------------+
|                   |                    +--------------------+
|                   |                    |                    |
| Fiddle            +------------------->+ Fiddler            |
|                   |                    |                    |
|                   |                    +--------------------+
+-------------------+
                                            .
                                            .
                                            .
                                         +--------------------+
                                         |                    |
                                         | Fiddler            |
                                         |                    |
                                         +--------------------+

URLs

The URL structure of fiddle is:

/c/cbb8dee39e9f1576cd97c2d504db8eee - Direct link to a fiddle.

Links to individual resources:

/i/cbb8dee39e9f1576cd97c2d504db8eee_raster.png
/i/cbb8dee39e9f1576cd97c2d504db8eee_gpu.png
/i/cbb8dee39e9f1576cd97c2d504db8eee.pdf
/i/cbb8dee39e9f1576cd97c2d504db8eee.skp

Links to individual resources for a given commit:

/ai/<runid>/cbb8dee39e9f1576cd97c2d504db8eee_raster.png
/ai/<runid>/cbb8dee39e9f1576cd97c2d504db8eee_gpu.png
/ai/<runid>/cbb8dee39e9f1576cd97c2d504db8eee.pdf
/ai/<runid>/cbb8dee39e9f1576cd97c2d504db8eee.skp

Where runid is the hash timestamp and git hash of a particular version of Skia.

To create a new fiddle, POST JSON to /_/run of the form:

{
  "code":"void draw(SkCanvas...",
  "width":256,
  "height":256,
  "source":0,
}

Embedding fiddles in iframes is done by:

/iframe/cbb8dee39e9f1576cd97c2d504db8eee

Which should really just be a version of index.html that strips out much of the surrounding elements.

Scraps can be expanded by visiting

/scrap/{typeType}/{scrapHashOrName}

A fiddle will be created from the scrap and then the user will be redirected to a direct link to the create fiddle.

Storage

Fiddles are stored in Google Storage under gs://skia-fiddle/, which is different from fiddle 1.0 where they were stored in MySql. For each fiddle we store the user's code at:

gs://skia-fiddle/fiddle/<fiddlehash>/draw.cpp

The image width, height, and source (as a 64bit int) values are stored as metadata on the draw.cpp file.

Note that the fiddlehash must match the hash generated by fiddle 1.0, so that hash is actually the hash of the user's code with line numbers added, along with the width and height added in a comment. We also store the rendered images:

gs://skia-fiddle/fiddle/<fiddlehash>/cpu.png
gs://skia-fiddle/fiddle/<fiddlehash>/gpu.png
gs://skia-fiddle/fiddle/<fiddlehash>/skp.skp
gs://skia-fiddle/fiddle/<fiddlehash>/pdf.pdf

Named Fiddles

Named fiddles are actually just like soft links from a name to the fiddleHash of a fiddle. The named fiddles are stored in:

gs://skia-fiddle/named/<fiddle name>

Where the name of the fiddle is the filename, and the contents of the file is the fiddleHash. The id of the person that created the named shortcut is attached as metadata to the file.

Named fiddles come exclusively from the Skia repo. They are currently checked in to $SKIA_ROOT/docs/examples. With the help of make_all_examples_cpp.py, they are compiled regularly to ensure freshness as a part of the fiddle_examples executable.

Source

Source images are packaged into each container.

Security

We're putting a C++ compiler on the web, and promising to run the results of user submitted code, so security is a large concern. Security is handled in a layered approach, using a combination of limits, AppArmor, and network profiles.

limits

  • Each run of the fiddle executable is restricted to 30 seconds.
  • Each request to a fiddler times out after 2 minutes.

AppArmor

  • We use the default kubernetes profile.

Network

  • Each fiddler pod is restricted to only allow ingress on ports 8000 and 20000 and is totally blocked on network egress.

Capabilities

  • Each fiddler pod drops all capabilities.

User

  • Each image runs as user skia (2000) with no extra privileges.

Lifetime

  • Each fiddler pod is deleted after it handles 1 fiddle.

RBAC

  • Fiddler pods don't load any mounts, secrets, or service accounts.

Backups

A backup of all the named fiddles from gs://skia-fiddle/named to gs://skia-fiddle-backup takes placed on a daily basis. See:

https://console.cloud.google.com/storage/transfer?project=google.com:skia-buildbots