5 export MSYS_NO_PATHCONV=1
7 script=`cd $(dirname $0) && pwd`/`basename $0`
21 echo "expected single argument for the image name"
30 script_dir="`dirname $script`"
31 docker_dir="${script_dir}/host-$(uname -m)"
32 ci_dir="`dirname $script_dir`"
33 src_dir="`dirname $ci_dir`"
34 root_dir="`dirname $src_dir`"
37 dist=$objdir/build/dist
39 source "$ci_dir/shared.sh"
41 CACHE_DOMAIN="${CACHE_DOMAIN:-ci-caches.rust-lang.org}"
43 if [ -f "$docker_dir/$image/Dockerfile" ]; then
44 if [ "$CI" != "" ]; then
45 hash_key=/tmp/.docker-hash-key.txt
47 echo $image >> $hash_key
49 cat "$docker_dir/$image/Dockerfile" >> $hash_key
50 # Look for all source files involves in the COPY command
51 copied_files=/tmp/.docker-copied-files.txt
53 for i in $(sed -n -e 's/^COPY \(.*\) .*$/\1/p' "$docker_dir/$image/Dockerfile"); do
55 find "$script_dir/$i" -type f >> $copied_files
57 # Sort the file names and cat the content into the hash key
58 sort $copied_files | xargs cat >> $hash_key
60 # Include the architecture in the hash key, since our Linux CI does not
61 # only run in x86_64 machines.
64 docker --version >> $hash_key
65 cksum=$(sha512sum $hash_key | \
68 url="https://$CACHE_DOMAIN/docker/$cksum"
70 echo "Attempting to download $url"
71 rm -f /tmp/rustci_docker_cache
73 retry curl -y 30 -Y 10 --connect-timeout 30 -f -L -C - -o /tmp/rustci_docker_cache "$url"
74 loaded_images=$(docker load -i /tmp/rustci_docker_cache | sed 's/.* sha/sha/')
76 echo "Downloaded containers:\n$loaded_images"
79 dockerfile="$docker_dir/$image/Dockerfile"
80 if [ -x /usr/bin/cygpath ]; then
81 context="`cygpath -w $script_dir`"
82 dockerfile="`cygpath -w $dockerfile`"
93 if [ "$CI" != "" ]; then
94 s3url="s3://$SCCACHE_BUCKET/docker/$cksum"
95 upload="aws s3 cp - $s3url"
96 digest=$(docker inspect rust-ci --format '{{.Id}}')
97 echo "Built container $digest"
98 if ! grep -q "$digest" <(echo "$loaded_images"); then
99 echo "Uploading finished image to $url"
101 docker history -q rust-ci | \
103 xargs docker save | \
108 echo "Looks like docker image is the same as before, not uploading"
110 # Record the container image for reuse, e.g. by rustup.rs builds
111 info="$dist/image-$image.txt"
114 echo "$digest" >>"$info"
116 elif [ -f "$docker_dir/disabled/$image/Dockerfile" ]; then
118 echo Cannot run disabled images on CI!
121 # Transform changes the context of disabled Dockerfiles to match the enabled ones
122 tar --transform 's#disabled/#./#' -C $script_dir -c . | docker \
126 -f "host-$(uname -m)/$image/Dockerfile" \
129 echo Invalid image: $image
131 # Check whether the image exists for other architectures
132 for arch_dir in "${script_dir}"/host-*; do
133 # Avoid checking non-directories and the current host architecture directory
134 if ! [[ -d "${arch_dir}" ]]; then
137 if [[ "${arch_dir}" = "${docker_dir}" ]]; then
141 arch_name="$(basename "${arch_dir}" | sed 's/^host-//')"
142 if [[ -f "${arch_dir}/${image}/Dockerfile" ]]; then
143 echo "Note: the image exists for the ${arch_name} host architecture"
144 elif [[ -f "${arch_dir}/disabled/${image}/Dockerfile" ]]; then
145 echo "Note: the disabled image exists for the ${arch_name} host architecture"
149 echo "Note: the current host architecture is $(uname -m)"
155 mkdir -p $HOME/.cargo
157 mkdir -p $objdir/cores
158 mkdir -p /tmp/toolstate
161 if [ "$SCCACHE_BUCKET" != "" ]; then
162 args="$args --env SCCACHE_BUCKET"
163 args="$args --env SCCACHE_REGION"
164 args="$args --env AWS_ACCESS_KEY_ID"
165 args="$args --env AWS_SECRET_ACCESS_KEY"
167 mkdir -p $HOME/.cache/sccache
168 args="$args --env SCCACHE_DIR=/sccache --volume $HOME/.cache/sccache:/sccache"
171 # Run containers as privileged as it should give them access to some more
172 # syscalls such as ptrace and whatnot. In the upgrade to LLVM 5.0 it was
173 # discovered that the leak sanitizer apparently needs these syscalls nowadays so
174 # we'll need `--privileged` for at least the `x86_64-gnu` builder, so this just
175 # goes ahead and sets it for all builders.
176 args="$args --privileged"
178 # Things get a little weird if this script is already running in a docker
179 # container. If we're already in a docker container then we assume it's set up
180 # to do docker-in-docker where we have access to a working `docker` command.
182 # If this is the case (we check via the presence of `/.dockerenv`)
183 # then we can't actually use the `--volume` argument. Typically we use
184 # `--volume` to efficiently share the build and source directory between this
185 # script and the container we're about to spawn. If we're inside docker already
186 # though the `--volume` argument maps the *host's* folder to the container we're
187 # about to spawn, when in fact we want the folder in this container itself. To
188 # work around this we use a recipe cribbed from
189 # https://circleci.com/docs/2.0/building-docker-images/#mounting-folders to
190 # create a temporary container with a volume. We then copy the entire source
191 # directory into this container, and then use that copy in the container we're
192 # about to spawn. Finally after the build finishes we re-extract the object
195 # Note that none of this is necessary if we're *not* in a docker-in-docker
196 # scenario. If this script is run on a bare metal host then we share a bunch of
197 # data directories to share as much data as possible. Note that we also use
198 # `LOCAL_USER_ID` (recognized in `src/ci/run.sh`) to ensure that files are all
199 # read/written as the same user as the bare-metal user.
200 if [ -f /.dockerenv ]; then
201 docker create -v /checkout --name checkout alpine:3.4 /bin/true
202 docker cp . checkout:/checkout
203 args="$args --volumes-from checkout"
205 args="$args --volume $root_dir:/checkout:ro"
206 args="$args --volume $objdir:/checkout/obj"
207 args="$args --volume $HOME/.cargo:/cargo"
208 args="$args --volume $HOME/rustsrc:$HOME/rustsrc"
209 args="$args --volume /tmp/toolstate:/tmp/toolstate"
210 args="$args --env LOCAL_USER_ID=`id -u`"
219 command="/checkout/src/ci/run.sh"
222 if [ "$CI" != "" ]; then
223 # Get some needed information for $BASE_COMMIT
225 # This command gets the last merge commit which we'll use as base to list
226 # deleted files since then.
227 BASE_COMMIT="$(git log --author=bors@rust-lang.org -n 2 --pretty=format:%H | tail -n 1)"
234 --workdir /checkout/obj \
235 --env SRC=/checkout \
237 --env CARGO_HOME=/cargo \
242 --env BUILD_SOURCEBRANCHNAME \
243 --env GITHUB_ACTIONS \
245 --env TOOLSTATE_REPO_ACCESS_TOKEN \
246 --env TOOLSTATE_REPO \
247 --env TOOLSTATE_PUBLISH \
248 --env RUST_CI_OVERRIDE_RELEASE_CHANNEL \
249 --env CI_JOB_NAME="${CI_JOB_NAME-$IMAGE}" \
250 --env BASE_COMMIT="$BASE_COMMIT" \
256 if [ -f /.dockerenv ]; then
258 docker cp checkout:/checkout/obj $objdir