1*6dbdd20aSAndroid Build Coastguard Worker#!/bin/bash 2*6dbdd20aSAndroid Build Coastguard Worker# Copyright (C) 2019 The Android Open Source Project 3*6dbdd20aSAndroid Build Coastguard Worker# 4*6dbdd20aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 5*6dbdd20aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 6*6dbdd20aSAndroid Build Coastguard Worker# You may obtain a copy of the License at 7*6dbdd20aSAndroid Build Coastguard Worker# 8*6dbdd20aSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 9*6dbdd20aSAndroid Build Coastguard Worker# 10*6dbdd20aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 11*6dbdd20aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 12*6dbdd20aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*6dbdd20aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 14*6dbdd20aSAndroid Build Coastguard Worker# limitations under the License. 15*6dbdd20aSAndroid Build Coastguard Worker 16*6dbdd20aSAndroid Build Coastguard Workerset -eux -o pipefail 17*6dbdd20aSAndroid Build Coastguard Worker 18*6dbdd20aSAndroid Build Coastguard Worker# num-workers, {sandbox,worker}-img are set at VM creation time in the Makefile. 19*6dbdd20aSAndroid Build Coastguard Worker 20*6dbdd20aSAndroid Build Coastguard WorkerATTRS='http://metadata.google.internal/computeMetadata/v1/instance/attributes' 21*6dbdd20aSAndroid Build Coastguard WorkerURL="$ATTRS/num-workers" 22*6dbdd20aSAndroid Build Coastguard WorkerNUM_WORKERS=$(curl --silent --fail -H'Metadata-Flavor:Google' $URL || echo 1) 23*6dbdd20aSAndroid Build Coastguard Worker 24*6dbdd20aSAndroid Build Coastguard WorkerURL="$ATTRS/sandbox-img" 25*6dbdd20aSAndroid Build Coastguard WorkerSANDBOX_IMG=$(curl --silent --fail -H'Metadata-Flavor:Google' $URL) 26*6dbdd20aSAndroid Build Coastguard Worker 27*6dbdd20aSAndroid Build Coastguard WorkerURL="$ATTRS/worker-img" 28*6dbdd20aSAndroid Build Coastguard WorkerWORKER_IMG=$(curl --silent --fail -H'Metadata-Flavor:Google' $URL) 29*6dbdd20aSAndroid Build Coastguard Worker 30*6dbdd20aSAndroid Build Coastguard Workerfor SSD in /dev/nvme0n*; do 31*6dbdd20aSAndroid Build Coastguard Workermkswap $SSD 32*6dbdd20aSAndroid Build Coastguard Workerswapon -p -1 $SSD 33*6dbdd20aSAndroid Build Coastguard Workerdone 34*6dbdd20aSAndroid Build Coastguard Worker 35*6dbdd20aSAndroid Build Coastguard Worker# This is used by the sandbox containers, NOT needed by the workers. 36*6dbdd20aSAndroid Build Coastguard Worker# Rationale for size=500G: by default tmpfs mount are set to RAM/2, which makes 37*6dbdd20aSAndroid Build Coastguard Worker# the CI depend too much on the underlying VM. Here and below, we pick an 38*6dbdd20aSAndroid Build Coastguard Worker# arbitrary fixed size (we use local scratch NVME as a swap device). 39*6dbdd20aSAndroid Build Coastguard Workerexport SHARED_WORKER_CACHE=/mnt/disks/shared_worker_cache 40*6dbdd20aSAndroid Build Coastguard Workerrm -rf $SHARED_WORKER_CACHE 41*6dbdd20aSAndroid Build Coastguard Workermkdir -p $SHARED_WORKER_CACHE 42*6dbdd20aSAndroid Build Coastguard Workermount -t tmpfs tmpfs $SHARED_WORKER_CACHE -o mode=777,size=500G 43*6dbdd20aSAndroid Build Coastguard Worker 44*6dbdd20aSAndroid Build Coastguard Worker# This is used to queue build artifacts that are uploaded to GCS. 45*6dbdd20aSAndroid Build Coastguard Workerexport ARTIFACTS_DIR=/mnt/disks/artifacts 46*6dbdd20aSAndroid Build Coastguard Workerrm -rf $ARTIFACTS_DIR 47*6dbdd20aSAndroid Build Coastguard Workermkdir -p $ARTIFACTS_DIR 48*6dbdd20aSAndroid Build Coastguard Workermount -t tmpfs tmpfs $ARTIFACTS_DIR -o mode=777,size=500G 49*6dbdd20aSAndroid Build Coastguard Worker 50*6dbdd20aSAndroid Build Coastguard Worker# Pull the latest images from the registry. 51*6dbdd20aSAndroid Build Coastguard Workerdocker pull $WORKER_IMG 52*6dbdd20aSAndroid Build Coastguard Workerdocker pull $SANDBOX_IMG 53*6dbdd20aSAndroid Build Coastguard Worker 54*6dbdd20aSAndroid Build Coastguard Worker# Create the restricted bridge for the sandbox container. 55*6dbdd20aSAndroid Build Coastguard Worker# Prevent access to the metadata server and impersonation of service accounts. 56*6dbdd20aSAndroid Build Coastguard Workerdocker network rm sandbox 2>/dev/null || true # Handles the reboot case. 57*6dbdd20aSAndroid Build Coastguard Workerdocker network create sandbox -o com.docker.network.bridge.name=sandbox 58*6dbdd20aSAndroid Build Coastguard Workersudo iptables -I DOCKER-USER -i sandbox -d 169.254.0.0/16 -j REJECT 59*6dbdd20aSAndroid Build Coastguard Worker 60*6dbdd20aSAndroid Build Coastguard Worker# These args will be appended to the docker run invocation for the sandbox. 61*6dbdd20aSAndroid Build Coastguard Workerexport SANDBOX_NETWORK_ARGS="--network sandbox --dns 8.8.8.8" 62*6dbdd20aSAndroid Build Coastguard Worker 63*6dbdd20aSAndroid Build Coastguard Worker# The worker_main_loop.py script creates one docker sandbox container for 64*6dbdd20aSAndroid Build Coastguard Worker# each job invocation. It needs to talk back to the host docker to do so. 65*6dbdd20aSAndroid Build Coastguard Worker# This implies that the worker container is trusted and should never run code 66*6dbdd20aSAndroid Build Coastguard Worker# from the repo, as opposite to the sandbox container that is isolated. 67*6dbdd20aSAndroid Build Coastguard Workerfor i in $(seq $NUM_WORKERS); do 68*6dbdd20aSAndroid Build Coastguard Worker 69*6dbdd20aSAndroid Build Coastguard Worker# We manually mount a tmpfs mount ourselves because Docker doesn't allow to 70*6dbdd20aSAndroid Build Coastguard Worker# both override tmpfs-size AND "-o exec" (see also 71*6dbdd20aSAndroid Build Coastguard Worker# https://github.com/moby/moby/issues/32131) 72*6dbdd20aSAndroid Build Coastguard WorkerSANDBOX_TMP=/mnt/disks/sandbox-$i-tmp 73*6dbdd20aSAndroid Build Coastguard Workerrm -rf $SANDBOX_TMP 74*6dbdd20aSAndroid Build Coastguard Workermkdir -p $SANDBOX_TMP 75*6dbdd20aSAndroid Build Coastguard Workermount -t tmpfs tmpfs $SANDBOX_TMP -o mode=777,size=100G 76*6dbdd20aSAndroid Build Coastguard Worker 77*6dbdd20aSAndroid Build Coastguard Workerdocker rm -f worker-$i 2>/dev/null || true 78*6dbdd20aSAndroid Build Coastguard Workerdocker run -d \ 79*6dbdd20aSAndroid Build Coastguard Worker -v /var/run/docker.sock:/var/run/docker.sock \ 80*6dbdd20aSAndroid Build Coastguard Worker -v $ARTIFACTS_DIR:$ARTIFACTS_DIR \ 81*6dbdd20aSAndroid Build Coastguard Worker --env SHARED_WORKER_CACHE="$SHARED_WORKER_CACHE" \ 82*6dbdd20aSAndroid Build Coastguard Worker --env SANDBOX_NETWORK_ARGS="$SANDBOX_NETWORK_ARGS" \ 83*6dbdd20aSAndroid Build Coastguard Worker --env ARTIFACTS_DIR="$ARTIFACTS_DIR" \ 84*6dbdd20aSAndroid Build Coastguard Worker --env SANDBOX_TMP="$SANDBOX_TMP" \ 85*6dbdd20aSAndroid Build Coastguard Worker --env WORKER_HOST="$(hostname)" \ 86*6dbdd20aSAndroid Build Coastguard Worker --name worker-$i \ 87*6dbdd20aSAndroid Build Coastguard Worker --hostname worker-$i \ 88*6dbdd20aSAndroid Build Coastguard Worker --log-driver gcplogs \ 89*6dbdd20aSAndroid Build Coastguard Worker $WORKER_IMG 90*6dbdd20aSAndroid Build Coastguard Workerdone 91*6dbdd20aSAndroid Build Coastguard Worker 92*6dbdd20aSAndroid Build Coastguard Worker 93*6dbdd20aSAndroid Build Coastguard Worker# Register a systemd service to stop worker containers gracefully on shutdown. 94*6dbdd20aSAndroid Build Coastguard Workercat > /etc/systemd/system/graceful_shutdown.sh <<EOF 95*6dbdd20aSAndroid Build Coastguard Worker#!/bin/sh 96*6dbdd20aSAndroid Build Coastguard Workerlogger 'Shutting down worker containers' 97*6dbdd20aSAndroid Build Coastguard Workerdocker ps -q -f 'name=worker-\d+$' | xargs docker stop -t 120 98*6dbdd20aSAndroid Build Coastguard Workerexit 0 99*6dbdd20aSAndroid Build Coastguard WorkerEOF 100*6dbdd20aSAndroid Build Coastguard Worker 101*6dbdd20aSAndroid Build Coastguard Workerchmod 755 /etc/systemd/system/graceful_shutdown.sh 102*6dbdd20aSAndroid Build Coastguard Worker 103*6dbdd20aSAndroid Build Coastguard Worker# This service will cause the graceful_shutdown.sh to be invoked before stopping 104*6dbdd20aSAndroid Build Coastguard Worker# docker, hence before tearing down any other container. 105*6dbdd20aSAndroid Build Coastguard Workercat > /etc/systemd/system/graceful_shutdown.service <<EOF 106*6dbdd20aSAndroid Build Coastguard Worker[Unit] 107*6dbdd20aSAndroid Build Coastguard WorkerDescription=Worker container lifecycle 108*6dbdd20aSAndroid Build Coastguard WorkerWants=gcr-online.target docker.service 109*6dbdd20aSAndroid Build Coastguard WorkerAfter=gcr-online.target docker.service 110*6dbdd20aSAndroid Build Coastguard WorkerRequires=docker.service 111*6dbdd20aSAndroid Build Coastguard Worker 112*6dbdd20aSAndroid Build Coastguard Worker[Service] 113*6dbdd20aSAndroid Build Coastguard WorkerType=oneshot 114*6dbdd20aSAndroid Build Coastguard WorkerRemainAfterExit=yes 115*6dbdd20aSAndroid Build Coastguard WorkerExecStop=/etc/systemd/system/graceful_shutdown.sh 116*6dbdd20aSAndroid Build Coastguard WorkerEOF 117*6dbdd20aSAndroid Build Coastguard Worker 118*6dbdd20aSAndroid Build Coastguard Workersystemctl daemon-reload 119*6dbdd20aSAndroid Build Coastguard Workersystemctl start graceful_shutdown.service