Skip to content

Instantly share code, notes, and snippets.

@akbertram
Created January 5, 2024 11:33
Show Gist options
  • Save akbertram/71cca366f424899bd537c21220ef45eb to your computer and use it in GitHub Desktop.
Save akbertram/71cca366f424899bd537c21220ef45eb to your computer and use it in GitHub Desktop.

Jenkins Build Agent scripts

These scripts, using Hashicorp Packer, prepare a Google Cloud Image that can be used for a Jenkins Agent to build a Java project (which in this case also requires Node, Docker, and Google Chrome for running WebDriver tests).

I find that using Packer to create the image has several advantages over using Docker images for build steps, namely:

  1. Faster start up, and can be used together with stateful build agents.
  2. Build logic can fully live in our Gradle scripts rather .yaml build steps each with a different Docker container

However, it does make upgrading toolsets a bit more time consuming than just changing the Docker image.

#!/bin/bash
if [ ! -f packer ]
then
wget -q https://releases.hashicorp.com/packer/1.8.6/packer_1.8.6_linux_amd64.zip
unzip packer_1.8.6_linux_amd64.zip
rm packer_1.8.6_linux_amd64.zip
fi
# If we are running on Jenkins, we need to use the VM's internal IP address
# in order to make it through the firewall. Otherwise, if being run from a developer's
# laptop, then we need to use the external IP address, and the developer's IP address needs
# to be whitelisted.
if [[ -z "$BUILD_NUMBER" ]]; then
echo "Running outside of Jenkins network, using external IP address"
echo "Be sure your IP address is whitelisted."
USE_INTERNAL="false"
else
echo "Running inside of Jenkins network, using internal IP address."
USE_INTERNAL="true"
fi
export PROJECT=$(gcloud info --format='value(config.project)')
export NO_COLOR=true
cat > jenkins-agent.json <<EOF
{
"builders": [
{
"type": "googlecompute",
"project_id": "activityinfo-build",
"source_image": "debian-11-bullseye-v20231212",
"zone": "europe-west4-b",
"disk_size": "25",
"network": "jenkins-network",
"subnetwork": "europe-west4",
"use_internal_ip": $USE_INTERNAL,
"tags": "jenkins-agent",
"image_name": "jenkins-agent-$1",
"image_family": "jenkins-agent",
"ssh_username": "ubuntu",
"state_timeout": "25m"
}
],
"provisioners": [
{
"type": "shell",
"script": "provision.sh",
"timeout": "1h"
}
]
}
EOF
./packer build jenkins-agent.json
#!/bin/sh -x
# Stop on the first error
set -e
# We need the app-engine-java component, which is somehow not available
# through the configured package manager
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
sudo apt install -y apt-transport-https ca-certificates gnupg2 software-properties-common
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9
# Setup docker repo
sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get update # Sometimes needs to be run twice!!
sudo apt-get install -y openjdk-11-jdk-headless
sudo apt-get install -y google-cloud-cli google-cloud-cli-app-engine-java
sudo apt-get install -y unzip
# Install docker, needed for publishing docker image from Jenkins
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Ensure that docker can be run as non-root
sudo usermod -aG docker jenkins
# Configure for pushing to Google Cloud Registry (for the jenkins user)
gcloud auth configure-docker
# The rest of this script essentially pre-installs build dependencies
# to reduce build time.
# Install the version of gradle we are using for this build
wget -q https://services.gradle.org/distributions/gradle-6.9.1-bin.zip
sudo unzip gradle-6.9.1-bin.zip -d /opt
sudo ln -s /opt/gradle-6.9.1/bin/gradle /usr/bin/gradle
gradle -v
# Install node.
# The version number must be kept in sync with ui/app/build.gradle
export NODE_VERSION=20.10.0
wget -q https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz
sudo tar -xzf node-v${NODE_VERSION}-linux-x64.tar.gz -C /opt
sudo ln -s /opt/node-v${NODE_VERSION}-linux-x64/bin/node /usr/bin/node
sudo ln -s /opt/node-v${NODE_VERSION}-linux-x64/bin/npm /usr/bin/npm
# Install the latest version of chrome
wget -q https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install -y ./google-chrome-stable_current_amd64.deb
# Cleanup downloads
rm *
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment