Skip to content

Support custom bind-mounts #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,33 @@ This works with the `--post-mortem` flag, so -- provided docker is installed --
you can even use `TryCI` to prod around in a CI job on machines which you
haven't cloned the original repo or setup to develop on.

## Using bindmounts for faster build times

Sometimes a CI build will depend on a submodule or external program which the
`.buildbot.sh` script builds from source each time. For large projects (like
`ykllvm`, which can take up to an hour to build) this can make build times
significantly slower.

Instead, you can mount arbitrarily many prebuilt programs from the host to be
used inside the docker container using `-m/--mount` flag. You can specify
multiple bind-mounts by repeating the option or by providing a comma-separated
list:

```
-m /src:/dst -m /foo:/bar:ro
-m /src:/dst,/foo:/bar:ro
```
If using this with the `--remote` flag, you must ensure the directory you wish
to bind-mount exists on the remote machine -- it does not `scp` / `rsync` it
over.

## Troubleshooting

* Docker must be installed on both the local machine and remote machine used to
compile and run the build.
* Your user account on both the local and remote machine must be a member of the
`docker` group.
* If running CI on a remote machine (`--remote server_name`) you must use ssh
* If running CI on a remote machine (`--remote <server_name>`) you must use ssh
passwordless login (using public/private key pair).


50 changes: 39 additions & 11 deletions tryci
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,34 @@ usage() {
Runs a soft-dev CI job.
Must be run from the same directory as the job's .buildbot.sh file.

usage: tryci [-p] [-r server_name] [-b <ref>] [-h]
usage: tryci [-h] [-c <ref>] [-m <mount>...] [-p] [-r <server-name>]

Options:
-p, --post-mortem
Attach a shell to the image to prod around if the build fails.

-r, --remote server_name
Specify the server \`server_name\` to run the CI job on over SSH.
Useful if you want to test on a remote CI environment.

-c, --checkout <ref>
Tryci will run a CI job from a clone of <ref> instead of the
working tree. Valid formats:
Run a CI job from a clone of <ref> instead of the working tree. Valid
formats:
- Branch name (e.g., main, feature/x)
- Commit hash (e.g., a1b2c3d)
- Tag (e.g., v1.0.0)
- Remote-tracking branch (e.g., origin/main)
- Remote URL with branch (e.g., https://github.com/user/repo#branch)
Useful for debugging the exact version of a CI job that failed on CI.

-m, --mount <mount> [<mount> ...]
Specify one or more bind-mounts. Each <mount> should be in the form:
<host-path>:<container-path>[:ro|rw]
You can specify multiple bind-mounts by repeating the option or by
providing a comma-separated list:
-m /src:/dst -m /foo:/bar:ro
-m /src:/dst,/foo:/bar:ro

-p, --post-mortem
Attach a shell to the image to prod around if the build fails.

-r, --remote <server-name>
Specify the server <server-name> to run the CI job on over SSH.
Useful if you want to test on a remote CI environment.

-h, --help
Show this help message and exit.
EOF
Expand Down Expand Up @@ -182,7 +190,7 @@ build_image() {
container_tag=$(docker create \
${CAP_ARGS} \
-u "${ci_uid}" \
-v /opt/ykllvm_cache:/opt/ykllvm_cache:ro \
${volumes}
"${image_tag}")
}

Expand Down Expand Up @@ -214,6 +222,7 @@ run_image() {
pm=0
server=""
ref=""
volumes="-v /opt/ykllvm_cache:/opt/ykllvm_cache:ro"

while [ $# -gt 0 ]; do
case $1 in
Expand All @@ -229,6 +238,25 @@ while [ $# -gt 0 ]; do
ref="$2"
shift 2
;;
-m | --mounts)
# Support both repeated and comma-separated mounts
shift
if [[ -z "$1" || "$1" =~ ^- ]]; then
error "--mounts requires an argument."
exit 1
fi

IFS=',' read -ra mounts <<< "$1"
for m in "${mounts[@]}"; do
if [[ ! "$m" =~ ^[^:]+:[^:]+(:ro|:rw)?$ ]]; then
error "Invalid bind mount: '$m'"
error "Expected format: /host/path:/container/path[:ro|rw]"
exit 1
fi
volumes+=" -v $m"
done
shift
;;
-h | --help)
usage
exit 0
Expand Down