Sandbox design

Sandbox design

gdk sandbox helps users create a sandbox data environment based on a working database (called “head”) from the default branch.

A sandbox allows working on changes with a database schema that diverges from the default branch. After work on a feature branch is complete, the sandbox can be discarded and is replaced by the head.

The head is kept in sync by gdk update, which will ensure that the sandbox is disabled before updating.

Idea

The guiding idea behind the sandbox system is to be unobtrusive and work with zero configuration. It also needs to fit in the existing directory structure, which is not made with a sandbox in mind.

Commands

gdk sandbox enable # Switch to sandbox database  disable # Switch back to head database  status # Print sandbox status  reset # Recreates sandbox from head

Managed integration

The sandbox state can be automatically managed by GDK by enabling the following setting:

gdk config set gdk.sandbox.managed true

If this setting is enabled, GDK disables the sandbox when running gdk update and reenables it when using gdk switch <branch> to ensure that work on feature branches is contained to the sandbox.

Data sources

The sandbox system tracks these paths:

. ├── repositories ├── redis │ └── dump.rdb ├── postgres │ └── data ├── postgres-replica │ └── data └── postgres-replica-2  └── data

postgres-replica and postgres-replica-2 will only be tracked if postgresql.replica.enabled and postgresql.replica2.enabled is true, respectively.

If these paths do not exist, enabling the sandbox will fail with the suggestion to run gdk reset-data (optionally with --fast).

File system design

When the sandbox is enabled for the first time, GDK creates a sandbox directory in the root directory.

For each tracked path, GDK moves it to sandbox/head/$NAME where $NAME is the internal name of the path. This acts as a backup directory when we want to disable the sandbox again. Then, GDK copies said directory over to sandbox/sandbox/$NAME.

sandbox ├── head │ ├── postgres │ ├── redis │ └── repositories └── sandbox  ├── postgres  ├── redis  └── repositories

Finally, GDK creates a symlink at each path, so GDK services don’t need to be aware about the sandbox status.

To disable the sandbox, GDK removes the symlinks and moves the head/* paths back to the original paths of the data sources. The sandbox/* paths stay around indefinitely, so the Sandbox can persist until it is reset with gdk sandbox reset.

Note

We could also use symlinks for the head/* paths but this will currently cause problems with destructive operations like gdk reset-data because it can’t deal with these symlinks.

Future proof

The namespaced design in the sandbox directory would allow us to create more than one sandbox in the future.

Known limitations

  • We can’t yet detect missing directories in a sandbox (e.g. when the postgres replica was enabled after the sandbox was created).
Last updated on