Leopold Schabel | dca59d9 | 2021-04-01 19:02:53 +0200 | [diff] [blame] | 1 | #!/usr/bin/env bash |
Leopold Schabel | 2983d72 | 2019-10-23 12:16:42 +0200 | [diff] [blame] | 2 | set -euo pipefail |
Serge Bazanski | bd0d24e | 2021-05-19 14:27:36 +0200 | [diff] [blame] | 3 | shopt -s nullglob |
Leopold Schabel | 2983d72 | 2019-10-23 12:16:42 +0200 | [diff] [blame] | 4 | |
Serge Bazanski | bd0d24e | 2021-05-19 14:27:36 +0200 | [diff] [blame] | 5 | main() { |
| 6 | # Our local user needs write access to /dev/kvm (best accomplished by |
| 7 | # adding your user to the kvm group). |
| 8 | if ! touch /dev/kvm; then |
| 9 | echo "Cannot write to /dev/kvm - please verify permissions." >&2 |
| 10 | exit 1 |
| 11 | fi |
| 12 | |
| 13 | # The KVM module needs to be loaded, since our container is unprivileged |
| 14 | # and won't be able to do it itself. |
| 15 | if ! [[ -d /sys/module/kvm ]]; then |
| 16 | echo "kvm module not loaded - please modprobe kvm" >&2 |
| 17 | exit 1 |
| 18 | fi |
Leopold Schabel | 2983d72 | 2019-10-23 12:16:42 +0200 | [diff] [blame] | 19 | |
Serge Bazanski | bd0d24e | 2021-05-19 14:27:36 +0200 | [diff] [blame] | 20 | local dockerfile="build/ci/Dockerfile" |
| 21 | if ! [[ -f "${dockerfile}" ]]; then |
| 22 | echo "Dockerfile not found at path ${dockerfile}. Make sure to run this script from the root of the Monogon checkout." >&2 |
| 23 | exit 1 |
| 24 | fi |
| 25 | |
| 26 | # Rebuild base image purely with no build context (-) ensuring that the |
| 27 | # builder image does not contain any other data from the repository. |
Serge Bazanski | ed86976 | 2021-11-18 13:30:58 +0100 | [diff] [blame^] | 28 | podman build -t gcr.io/monogon-infra/monogon-builder - < "${dockerfile}" |
Leopold Schabel | 2983d72 | 2019-10-23 12:16:42 +0200 | [diff] [blame] | 29 | |
Serge Bazanski | bd0d24e | 2021-05-19 14:27:36 +0200 | [diff] [blame] | 30 | # TODO(serge): stop using pods for the builder, this is a historical artifact. |
| 31 | podman pod create --name monogon |
| 32 | |
| 33 | # Mount bazel root to identical paths inside and outside the container. |
| 34 | # This caches build state even if the container is destroyed. |
| 35 | # |
| 36 | # TODO(serge): do not hardcode this path? This breaks if attempting to use |
| 37 | # the build container from multiple Monogon checkouts on disk. |
| 38 | local bazel_root="${HOME}/.cache/bazel-monogon" |
| 39 | mkdir -p "${bazel_root}" |
| 40 | |
| 41 | # When IntelliJ's Bazel plugin uses //scripts/bin/bazel to either build targets |
| 42 | # or run syncs, it adds a --override_repository flag to the bazel command |
| 43 | # line that points @intellij_aspect into a path on the filesystem. This |
| 44 | # external repository contains a Bazel Aspect definition which Bazel |
| 45 | # executes to provide the IntelliJ Bazel plugin with information about the |
| 46 | # workspace / build targets / etc... |
| 47 | # |
| 48 | # We need to make this path available within the build container. However, |
| 49 | # instead of directly pointing into that path on the host, we redirect through |
| 50 | # a patched copy of this repository. That patch applies fixes related to the |
| 51 | # Monogon codebase in general, not specific to the fact that we're running in a |
| 52 | # container. |
| 53 | # |
| 54 | # What this ends up doing is that the path mounted within the container |
| 55 | # looks as if it's a path straight from the host IntelliJ config directory, |
| 56 | # but in fact points into a patched copy. It looks weird, but this setup |
| 57 | # allows us to let IntelliJ's Bazel integration to trigger Bazel without us |
| 58 | # having to replace the override_repository flag that it passes to Bazel. |
| 59 | # We at some point used to do that, but parsing and replacing Bazel flags |
| 60 | # in the scripts/bin/bazel wrapper script is error prone and fragile. |
Leopold Schabel | 2983d72 | 2019-10-23 12:16:42 +0200 | [diff] [blame] | 61 | |
Serge Bazanski | bd0d24e | 2021-05-19 14:27:36 +0200 | [diff] [blame] | 62 | # Find all IntelliJ installation/config directories. |
| 63 | local ij_home_paths=("${HOME}/.local/share/JetBrains/IntelliJIdea"*) |
| 64 | # Get the newest one, if any. |
| 65 | local ij_home="" |
| 66 | if ! [[ ${#ij_home_paths[@]} -eq 0 ]]; then |
| 67 | # Reverse sort paths by name, with the first being the newest IntelliJ |
| 68 | # installation. |
| 69 | IFS=$'\n' |
| 70 | local sorted=($(sort -r <<<"${ij_home_paths[*]}")) |
| 71 | unset IFS |
| 72 | ij_home="${sorted[0]}" |
| 73 | fi |
Leopold Schabel | 052af2d | 2019-11-06 02:21:53 +0000 | [diff] [blame] | 74 | |
Serge Bazanski | bd0d24e | 2021-05-19 14:27:36 +0200 | [diff] [blame] | 75 | # If we don't have or can't find ij_home, don't bother with attempting to patch anything. |
| 76 | # If we do, podman_flags will get populated with extra flags that it will |
| 77 | # run with to support IntelliJ/Bazel integration. |
| 78 | declare -a podman_flags |
| 79 | if [[ -d "${ij_home}" ]]; then |
| 80 | echo "IntelliJ found at ${ij_home}, patching and mounting aspect repository." |
| 81 | # aspect_orig is the path to the aspect external repository that IntelliJ will |
| 82 | # inject into bazel via --override_repository. It is the path that it expects |
| 83 | # to be available to Bazel within the container, and also the path that is |
| 84 | # directly visible in the host. |
| 85 | local aspect_orig="${ij_home}/ijwb/aspect" |
| 86 | # aspect_patched is the path to our patched copy of the aspect |
| 87 | # repository. We keep this in bazel_root for convenience, as that's a |
| 88 | # path that we control on the host anyway, so we can be sure we're not |
| 89 | # trampling some other process. |
| 90 | local aspect_patched="${bazel_root}/ijwb_aspect" |
Hendrik Hofstadt | 3e6018f | 2019-10-28 21:29:42 +0100 | [diff] [blame] | 91 | |
Serge Bazanski | bd0d24e | 2021-05-19 14:27:36 +0200 | [diff] [blame] | 92 | # If we already have a patched version of the aspect, remove it. |
| 93 | if [[ -d "${aspect_patched}" ]]; then |
| 94 | rm -rf "${aspect_patched}" |
| 95 | fi |
Leopold Schabel | 8b9c055 | 2019-11-15 14:07:45 +0100 | [diff] [blame] | 96 | |
Serge Bazanski | bd0d24e | 2021-05-19 14:27:36 +0200 | [diff] [blame] | 97 | # Copy and patch the aspect. |
| 98 | cp -r "${aspect_orig}" "${aspect_patched}" |
| 99 | patch -d "${aspect_patched}" -p1 < scripts/patches/bazel_intellij_aspect_filter.patch |
Leopold Schabel | 58ec09e | 2021-04-01 18:34:19 +0200 | [diff] [blame] | 100 | |
Serge Bazanski | bd0d24e | 2021-05-19 14:27:36 +0200 | [diff] [blame] | 101 | # Make podman mount the patched aspect into the original aspect path in the build container. |
| 102 | podman_flags+=(-v "${aspect_patched}:${aspect_orig}") |
| 103 | else |
| 104 | echo "No IntelliJ found, not patching/mounting aspect repository." |
| 105 | fi |
Leopold Schabel | 58ec09e | 2021-04-01 18:34:19 +0200 | [diff] [blame] | 106 | |
Serge Bazanski | bd0d24e | 2021-05-19 14:27:36 +0200 | [diff] [blame] | 107 | podman run -it -d \ |
| 108 | -v $(pwd):$(pwd):z \ |
| 109 | -w $(pwd) \ |
| 110 | --volume="${bazel_root}:${bazel_root}" \ |
| 111 | --device /dev/kvm \ |
| 112 | --privileged \ |
| 113 | --pod monogon \ |
| 114 | --name=monogon-dev \ |
| 115 | --net=host \ |
| 116 | "${podman_flags[@]}" \ |
Serge Bazanski | ed86976 | 2021-11-18 13:30:58 +0100 | [diff] [blame^] | 117 | gcr.io/monogon-infra/monogon-builder |
Serge Bazanski | bd0d24e | 2021-05-19 14:27:36 +0200 | [diff] [blame] | 118 | } |
Leopold Schabel | 58ec09e | 2021-04-01 18:34:19 +0200 | [diff] [blame] | 119 | |
Serge Bazanski | bd0d24e | 2021-05-19 14:27:36 +0200 | [diff] [blame] | 120 | main |