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 headManaged integration
The sandbox state can be automatically managed by GDK by enabling the following setting:
gdk config set gdk.sandbox.managed trueIf 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
└── datapostgres-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
└── repositoriesFinally, 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).