|
3 | 3 | # Synopsis:
|
4 | 4 | # Build a Docker image containing a CraC checkpoint to restart from.
|
5 | 5 | # An initial image is built. A container is created from that image
|
6 |
| -# and tests are run to warm up the JVM. Then a checkpoint is created. |
7 |
| -# The final image is created by committing the containiner |
8 |
| -# containing the checkpoint. |
| 6 | +# and tests are run to warm up the JVM. Once the runner has finished running |
| 7 | +# all the tests it creates a checkpoint of the VM process before exiting. |
| 8 | +# This checkpoint is written to the host file system, so it can be copied |
| 9 | +# into the final image. |
| 10 | +# Then the final image is created, which restores from the checkpoint |
| 11 | +# instead of starting a new JVM |
| 12 | +# This avoids slow JVM start up and JVM warm up costs. |
| 13 | +# |
| 14 | +# Example: |
| 15 | +# ./bin/build-crac-checkpoint-image.sh |
9 | 16 |
|
10 |
| -# build outside of Docker container, so we can copy jar into both images |
| 17 | +create_checkpoint() { |
| 18 | + # Copy all tests into one merged project, so we can warm up the JVM |
| 19 | + # TODO(FAP): this is missing some tests as most tests use the same filenames |
| 20 | + mkdir -p tests/merged |
| 21 | + for dir in tests/*; do |
| 22 | + if [ -d "$dir" ] && [ "$dir" != "tests/merged/" ]; then |
| 23 | + rsync -a "$dir"/ tests/merged/ |
| 24 | + fi |
| 25 | + done |
| 26 | + |
| 27 | + real_path() { |
| 28 | + echo "$(cd "$(dirname -- "$1")" >/dev/null; pwd -P)/$(basename -- "$1")"; |
| 29 | + } |
| 30 | + |
| 31 | + mkdir -p build/cr |
| 32 | + |
| 33 | + image_tag="$1" |
| 34 | + slug="merged" |
| 35 | + solution_dir=$(realpath "tests/merged/") |
| 36 | + output_dir=$(realpath "tests/merged/") |
| 37 | + |
| 38 | + docker run --cap-add CHECKPOINT_RESTORE \ |
| 39 | + --cap-add SYS_PTRACE \ |
| 40 | + --name java-test-runner-crac \ |
| 41 | + --network none \ |
| 42 | + --mount type=bind,src="${solution_dir}",dst=/solution \ |
| 43 | + --mount type=bind,src="${output_dir}",dst=/output \ |
| 44 | + --mount type=bind,src="$(real_path build/cr)",dst=/opt/test-runner/crac-checkpoint \ |
| 45 | + --mount type=tmpfs,dst=/tmp \ |
| 46 | + "${image_tag}" "${slug}" /solution /output |
| 47 | + |
| 48 | + docker rm -f java-test-runner-crac |
| 49 | + rm -rf tests/merged/ |
| 50 | +} |
| 51 | + |
| 52 | +# 1. Build jar outside of Docker, so we can copy the jar into both images |
| 53 | +echo "build-crac-checkpoint-image.sh: Building jar with Gradle" |
11 | 54 | ./gradlew build
|
12 | 55 |
|
13 |
| -docker build -t exercism/java-test-runner-crac-checkpoint -f Dockerfile.createCheckpoint . |
| 56 | +image_tag="exercism/java-test-runner-crac-checkpoint" |
| 57 | + |
| 58 | +# 2. Build first image with an entrypoint that will create a CraC checkpoint |
| 59 | +echo "build-crac-checkpoint-image.sh: Building image that creates CraC checkpoint" |
| 60 | +docker build -t "$image_tag" -f Dockerfile.createCheckpoint . |
14 | 61 |
|
15 |
| -bin/create-checkpoint.sh |
| 62 | +# 3. Run a container from image created in step 2 and create CraC checkpoint |
| 63 | +echo "build-crac-checkpoint-image.sh: Creating CraC checkpoint" |
| 64 | +create_checkpoint "$image_tag" |
16 | 65 |
|
| 66 | +# Build final test runner image, includes the jar and the checkpoint created in step 1 and 3 |
| 67 | +echo "build-crac-checkpoint-image.sh: Building final test runner image" |
17 | 68 | docker build -t exercism/java-test-runner -f Dockerfile .
|
0 commit comments