#!/bin/bash # Copyright (C) 2019 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -eux -o pipefail # num-workers is set at VM creation time in the Makefile. URL='http://metadata.google.internal/computeMetadata/v1/instance/attributes/num-workers' NUM_WORKERS=$(curl --silent --fail -H'Metadata-Flavor:Google' $URL || echo 1) for SSD in /dev/nvme0n*; do mkswap $SSD swapon -p -1 $SSD done # This is used by the sandbox containers, NOT needed by the workers. # Rationale for size=100G: by default tmpfs mount are set to RAM/2, which makes # the CI depend too much on the underlying VM. Here and below, we pick an # arbitrary fixed size (we use local scratch NVME as a swap device). export SHARED_WORKER_CACHE=/mnt/disks/shared_worker_cache rm -rf $SHARED_WORKER_CACHE mkdir -p $SHARED_WORKER_CACHE mount -t tmpfs tmpfs $SHARED_WORKER_CACHE -o mode=777,size=100G # This is used to queue build artifacts that are uploaded to GCS. export ARTIFACTS_DIR=/mnt/disks/artifacts rm -rf $ARTIFACTS_DIR mkdir -p $ARTIFACTS_DIR mount -t tmpfs tmpfs $ARTIFACTS_DIR -o mode=777,size=100G # Pull the latest images from the registry. docker pull eu.gcr.io/perfetto-ci/worker docker pull eu.gcr.io/perfetto-ci/sandbox # Create the restricted bridge for the sandbox container. # Prevent access to the metadata server and impersonation of service accounts. docker network rm sandbox 2>/dev/null || true # Handles the reboot case. docker network create sandbox -o com.docker.network.bridge.name=sandbox sudo iptables -I DOCKER-USER -i sandbox -d 169.254.0.0/16 -j REJECT # These args will be appended to the docker run invocation for the sandbox. export SANDBOX_NETWORK_ARGS="--network sandbox --dns 8.8.8.8" # The worker_main_loop.py script creates one docker sandbox container for # each job invocation. It needs to talk back to the host docker to do so. # This implies that the worker container is trusted and should never run code # from the repo, as opposite to the sandbox container that is isolated. for i in $(seq $NUM_WORKERS); do # We manually mount a tmpfs mount ourselves because Docker doesn't allow to # both override tmpfs-size AND "-o exec" (see also # https://github.com/moby/moby/issues/32131) SANDBOX_TMP=/mnt/disks/sandbox-$i-tmp rm -rf $SANDBOX_TMP mkdir -p $SANDBOX_TMP mount -t tmpfs tmpfs $SANDBOX_TMP -o mode=777,size=100G docker rm -f worker-$i 2>/dev/null || true docker run -d \ -v /var/run/docker.sock:/var/run/docker.sock \ -v $ARTIFACTS_DIR:$ARTIFACTS_DIR \ --env SHARED_WORKER_CACHE="$SHARED_WORKER_CACHE" \ --env SANDBOX_NETWORK_ARGS="$SANDBOX_NETWORK_ARGS" \ --env ARTIFACTS_DIR="$ARTIFACTS_DIR" \ --env SANDBOX_TMP="$SANDBOX_TMP" \ --env WORKER_HOST="$(hostname)" \ --name worker-$i \ --hostname worker-$i \ --log-driver gcplogs \ eu.gcr.io/perfetto-ci/worker done # Register a systemd service to stop worker containers gracefully on shutdown. cat > /etc/systemd/system/graceful_shutdown.sh < /etc/systemd/system/graceful_shutdown.service <