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).