Add support for Docker base images
diff --git a/buildkite/create-docker-cache.sh b/buildkite/create-docker-cache.sh new file mode 100644 index 0000000..61153f9 --- /dev/null +++ b/buildkite/create-docker-cache.sh
@@ -0,0 +1,21 @@ +#!/bin/bash + +set -euxo pipefail + +gcloud compute instances delete docker-cache --zone=europe-west1-c --quiet + +gcloud compute instances create-with-container \ + --project bazel-public \ + --zone "europe-west1-c" \ + --boot-disk-device-name "docker-cache" \ + --boot-disk-size 250GB \ + --boot-disk-type pd-ssd \ + --container-env "REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io" \ + --container-image "registry:2" \ + --container-restart-policy always \ + --image-family cos-stable \ + --image-project cos-cloud \ + --machine-type n1-standard-4 \ + --network buildkite \ + --network-tier PREMIUM \ + docker-cache
diff --git a/buildkite/create_images.py b/buildkite/create_images.py index 4b6b436..0452650 100755 --- a/buildkite/create_images.py +++ b/buildkite/create_images.py
@@ -42,6 +42,14 @@ # 'install-buildkite-agent.sh' # ] # }, + ("bk-docker",): { + "source_image_project": "ubuntu-os-cloud", + "source_image_family": "ubuntu-1804-lts", + "setup_script": "setup-docker.sh", + "licenses": [ + "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx" + ], + }, ("bk-worker-ubuntu1404-java8",): { "source_image_project": "ubuntu-os-cloud", "source_image_family": "ubuntu-1404-lts",
diff --git a/buildkite/gcloud_utils.py b/buildkite/gcloud_utils.py index a77a801..cddc3cd 100644 --- a/buildkite/gcloud_utils.py +++ b/buildkite/gcloud_utils.py
@@ -49,7 +49,7 @@ # Filter for log lines printed by our startup script, ignore the rest. # Then drop the common prefix to make the output easier to read. # For unknown platforms, we just take every line unmodified. - if "ubuntu" in instance_name: + if "ubuntu" in instance_name or "docker" in instance_name: match = re.match(r".*INFO startup-script: (.*)", line) if not match: continue
diff --git a/buildkite/setup-docker.sh b/buildkite/setup-docker.sh new file mode 100644 index 0000000..a534242 --- /dev/null +++ b/buildkite/setup-docker.sh
@@ -0,0 +1,131 @@ +#!/bin/bash +# +# Copyright 2018 The Bazel Authors. All rights reserved. +# +# 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. + +# Setup script for an Ubuntu 18.04 LTS based Docker host. + +# Fail on errors. +# Fail when using undefined variables. +# Print all executed commands. +# Fail when any command in a pipe fails. +set -euxo pipefail + +# Prevent dpkg / apt-get / debconf from trying to access stdin. +export DEBIAN_FRONTEND="noninteractive" + +### Install base packages. +{ + apt-get -qqy update + apt-get -qqy dist-upgrade > /dev/null +} + +### Increase file descriptor limits +{ +cat >> /etc/security/limits.conf <<EOF +* soft nofile 100000 +* hard nofile 100000 +EOF +} + +### Install the Buildkite Agent on production images. +{ + apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 \ + --recv-keys 32A37959C2FA5C3C99EFBC32A79206696452D198 &> /dev/null + add-apt-repository -y "deb https://apt.buildkite.com/buildkite-agent stable main" + apt-get -qqy update + apt-get -qqy install buildkite-agent > /dev/null + + # Write the Buildkite agent configuration. + cat > /etc/buildkite-agent/buildkite-agent.cfg <<EOF +token="xxx" +name="%hostname-%n" +tags="kind=docker,os=linux" +build-path="/var/lib/buildkite-agent/builds" +hooks-path="/etc/buildkite-agent/hooks" +plugins-path="/etc/buildkite-agent/plugins" +git-clone-flags="-v --reference /var/lib/bazelbuild" +disconnect-after-job=true +disconnect-after-job-timeout=86400 +EOF + + # Add the Buildkite agent hooks. + cat > /etc/buildkite-agent/hooks/environment <<'EOF' +#!/bin/bash + +set -euo pipefail + +export PATH=$PATH:/usr/lib/google-cloud-sdk/bin:/snap/bin:/snap/google-cloud-sdk/current/bin +export BUILDKITE_ARTIFACT_UPLOAD_DESTINATION="gs://bazel-buildkite-artifacts/$BUILDKITE_JOB_ID" +export BUILDKITE_GS_ACL="publicRead" + +gcloud auth configure-docker --quiet +EOF + + # This is a normal worker machine with systemd (e.g. Ubuntu 16.04 LTS). + systemctl disable buildkite-agent + mkdir /etc/systemd/system/buildkite-agent.service.d + cat > /etc/systemd/system/buildkite-agent.service.d/override.conf <<'EOF' +[Service] +Restart=always +PermissionsStartOnly=true +# Immediately force a shutdown of the system when the Buildkite agent terminates. +ExecStopPost=/sbin/poweroff --force --force +# Disable tasks accounting, because Bazel is prone to run into resource limits there. +# This fixes the "cgroup: fork rejected by pids controller" error that some CI jobs triggered. +TasksAccounting=no +EOF +} + +### Install Docker. +{ + apt-get -qqy install apt-transport-https ca-certificates > /dev/null + + curl -sSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - + add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" + + apt-get -qqy update + apt-get -qqy install docker-ce > /dev/null + + # Allow the buildkite-agent user access to Docker. + usermod -aG docker buildkite-agent + + # Use our caching Docker registry. + cat > /etc/docker/daemon.json <<'EOF' +{ + "insecure-registries" : ["docker-cache.europe-west1-c.c.bazel-public.internal:5000"] +} +EOF + + # Disable the Docker service, as the startup script has to mount + # /var/lib/docker first. + systemctl disable docker +} + +### Download a static bundle of all our Git repositories and unpack it. +{ + rm -rf /var/lib/bazelbuild + curl -sS https://storage.googleapis.com/bazel-git-mirror/bazelbuild.tar | tar x -C /var/lib + chown -R root:root /var/lib/bazelbuild + chmod -R 0755 /var/lib/bazelbuild +} + +### Clean up and trim the filesystem (potentially reduces the final image size). +{ + rm -rf /var/lib/apt/lists/* + fstrim -v / + sleep 3 +} + +poweroff
diff --git a/buildkite/startup-docker.sh b/buildkite/startup-docker.sh new file mode 100644 index 0000000..a879425 --- /dev/null +++ b/buildkite/startup-docker.sh
@@ -0,0 +1,55 @@ +#!/bin/bash +# +# Copyright 2018 The Bazel Authors. All rights reserved. +# +# 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 -euxo pipefail + +# Wait for all snaps to become available. +snap wait system seed.loaded + +# Ubuntu 18.04 installs gcloud, gsutil, etc. commands in /snap/bin +export PATH=$PATH:/snap/bin + +# If available: Use the local SSD as swap space. +if [[ -e /dev/nvme0n1 ]]; then + mkswap -f /dev/nvme0n1 + swapon /dev/nvme0n1 + + # Move fast and lose data. + mount -t tmpfs -o mode=1777,uid=root,gid=root,size=$((100 * 1024 * 1024 * 1024)) tmpfs /tmp + mount -t tmpfs -o mode=0711,uid=root,gid=root,size=$((100 * 1024 * 1024 * 1024)) tmpfs /var/lib/docker + mount -t tmpfs -o mode=0755,uid=buildkite-agent,gid=buildkite-agent,size=$((100 * 1024 * 1024 * 1024)) tmpfs /var/lib/buildkite-agent +fi + +# Start Docker. +systemctl start docker + +# Get the Buildkite Token from GCS and decrypt it using KMS. +BUILDKITE_TOKEN=$(gsutil cat "gs://bazel-encrypted-secrets/buildkite-agent-token.enc" | \ + gcloud kms decrypt --location global --keyring buildkite --key buildkite-agent-token --ciphertext-file - --plaintext-file -) + +# Insert the Buildkite Token into the agent configuration. +sed -i "s/token=\"xxx\"/token=\"${BUILDKITE_TOKEN}\"/" /etc/buildkite-agent/buildkite-agent.cfg +sed -i "s/name=.*/name=%hostname/" /etc/buildkite-agent/buildkite-agent.cfg + +# Fix permissions of the Buildkite agent configuration files and hooks. +chmod 0400 /etc/buildkite-agent/buildkite-agent.cfg +chmod 0500 /etc/buildkite-agent/hooks/* +chown -R buildkite-agent:buildkite-agent /etc/buildkite-agent + +# Start the Buildkite agent service. +systemctl start buildkite-agent + +exit 0