Skip to content

Setups and images

Give a box the same packages, Chrome version, repos and fonts every time with a setup, and save a finished box as an image to start copies of it.

A new box has the standard tools and nothing of yours. Two things make it yours without doing the work again each time:

  • A setup is a recipe: packages, a Chrome version, repos, fonts, environment variables and commands. Your agent applies it to a box.
  • An image is a saved copy of a box that is already set up. New boxes start as a copy of it.

Use a setup for anything quick to install. Save an image when getting a box ready takes minutes, or when several boxes have to be exactly alike.

Setups

Your agent applies a setup with box_setup, or passes it as setup to box_create so the box is ready before it's handed over. You can ask for it in plain words ("set this box up with Chrome 153 and our app repo"), and the agent writes the recipe:

{
  "packages": ["jq"],
  "chrome": "153.0.8010.52",
  "repos": [{ "url": "https://github.com/acme/app", "ref": "main" }],
  "fonts": { "packs": ["inter", "noto-emoji"], "dirs": ["/root/app/test/fonts"] },
  "env": { "NODE_OPTIONS": "--max-old-space-size=8192" },
  "run": ["cd /root/app && npm ci"]
}

Every field is optional. The steps run in this order:

Step What it does
packages Installs apt packages by name, up to 50.
chrome Installs a Chrome for Testing build: an exact version, or a milestone such as "153" for its latest build. chrome runs it, and $CHROME_PATH points to it in every later command.
repos Clones up to 10 repos over HTTPS, each to /root/<repo name> unless it has a path. ref picks a branch, tag or commit. Running the setup again fetches instead of cloning again.
fonts Installs fonts from packs (noto-cjk, noto-emoji, ms-core, inter), from urls (.ttf, .otf, .woff2 or .zip files) and from dirs (folders in the box, such as a cloned repo's), then rebuilds the font cache.
run Runs up to 20 shell commands in order and stops at the first one that fails.

env isn't a step. Its variables are set for every command that runs in the box afterwards.

Each step gets up to 15 minutes and is reported on its own. A step that fails doesn't undo the ones that worked, and only the steps that worked become part of the box's setup. Fix the failed one and apply the setup again: that's safe to repeat.

Private repos

Private GitHub repos are cloned with the GitHub token you add under Toolhouse → Accounts. The token is only sent to github.com, and it sits in the box in a file only root can read, only while the clone runs. When no token is saved, the step says so.

Environment variables

env is for settings, not secrets: it is stored in plain text. Names are upper-case letters, digits and underscores. Variables wack sets itself can't be changed (PATH, HOME, DISPLAY, CHROME_PATH, PWD, OLDPWD, TERM and anything starting with WACK_).

What a box has

The box's Settings tab shows its setup under Installed: the Chrome version, repos, fonts and packages. Setups add up: applying another one later merges into what's there.

Images

Save as image (in the box's Settings) keeps a copy of the box: its disk, its setup and its size. Agents do the same with box_image_save. Saving takes about a minute for most boxes.

To start a box from an image, pick it under Start from in the New box dialog, or have your agent pass image to box_create. The new box has the image's files, setup and size, and is usually ready within a minute. The first box from a new image can take longer.

  • Your images are listed in Settings, where you can delete them. Agents see them in box_list and delete them with box_image_delete.
  • Deleting an image doesn't touch boxes that started from it.
  • Your plan sets how many images you can keep: 1 on Hobby, 5 on Pro and 20 on Power.
  • If an agent asks for an image that is gone, the box starts from the standard tools with the image's setup applied again, and the agent is told. That box may differ from older copies, so save a new image.

Images of GPU boxes

Save as image works on a GPU box without stopping it. It takes from under a minute to about 10 minutes, depending on how much is on its disk. Programs running in the box can end while it saves, so check them afterwards. Boxes started from a GPU image are GPU boxes.

Pixel tests

Screenshots compare well between two runs in the same setup: the same image, the same Chrome build, the same fonts, the same screen size, and the same kind of box. So:

  • Use one image for every box you compare. Build one box with a setup, save it as an image, and start each test box from it.
  • Record reference images in a box, never on another machine. A box's pixels won't match a Mac's exactly.
  • Bring your own fonts. Apple's fonts can't be installed on a box. Have test pages load their own fonts, or ship them in a repo and list the folder in the setup's fonts.dirs.
  • Compare like with like. Timings and pixels from a box without a GPU say nothing about a machine with one, and the other way round.

On the CPU

Standard, Large and XL boxes draw with SwiftShader, which is very repeatable. Launch Chrome with:

--use-angle=swiftshader --enable-unsafe-swiftshader --force-device-scale-factor=1 --font-render-hinting=none --test-type --disable-infobars

On a GPU box

For hardware rendering and real performance numbers, use a GPU box. Launch $CHROME_PATH with:

--no-sandbox $WACK_CHROME_GPU_FLAGS --force-device-scale-factor=1 --font-render-hinting=none --test-type --disable-infobars

Add --headless=new for headless, or run it on the screen for a window you can watch. Both draw on the GPU; compare pixels only between runs launched the same way, and only GPU box to GPU box. Chrome on the GPU lists the checks to make on every run.

Last updated