Skip to content

Commit b78f654

Browse files
Preload dependencies in build docker images to reduce downloading at build/test/ci runtime
Additional fixes - upgrade ubuntu-test.docker to ubuntu 22.04 (and some small fixes brought forward from CASSANDRA-20997) - (.jenkins/k8s) changes gke's small node pool from n2-highcpu-8 to e2-highcpu-8 (gke's own pod resources reqs increased) - (.jenkins/k8s) limit one agent pod per node (when jenkins is deployed in k8s using our helm) - (.jenkins/k8s) add the cassandra-6.0 job - pass maven.repo.local sys prop, if set, into accord's gradle build - check and fail on maven dependencies checksums when downloading - when on-the-fly building docker images add `--load` (podman compatbility) - newer python versions can use venv instead of virtualenv - rename ubuntu2004_test.docker to ubuntu-test.docker (in 5.0) - (Jenkinsfile) fix retries (which was no longer working when agents/nodes died, since CASSANDRA-20833) - (Jenkinsfile) @NonCPS where (now) needed - (Jenkinsfile) fix default value for the branch parameter (after a new helm deploy) - (.build/run-ci) fix missing parameters on jobs also at helm deploy time - (.build/run-ci) .git suffixes on repo urls are optional patch by Mick Semb Wever; reviewed by Dmitry Konstantinov, Stefan Miklosovic for CASSANDRA-21403
1 parent 2a219ed commit b78f654

14 files changed

Lines changed: 303 additions & 64 deletions

.build/build-resolver.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@
5656

5757
<typedef uri="antlib:org.apache.maven.resolver.ant" resource="org/apache/maven/resolver/ant/antlib.xml" classpathref="resolver-ant-tasks.classpath" />
5858
<resolver:remoterepos id="all">
59-
<remoterepo id="resolver-central" url="${artifact.remoteRepository.central}"/>
60-
<remoterepo id="resolver-apache" url="${artifact.remoteRepository.apache}"/>
59+
<remoterepo id="resolver-central" url="${artifact.remoteRepository.central}" checksums="fail" />
60+
<remoterepo id="resolver-apache" url="${artifact.remoteRepository.apache}" checksums="fail" />
6161
<!-- Snapshot artifacts must not exist in nor be downloaded by any Cassandra release artifact.
6262
Please validate that all artifacts included in parent-pom-template.xml are release
6363
artifacts before committing.

.build/docker/_create_user.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ echo "${username} ALL=(root) NOPASSWD:ALL" > /etc/sudoers.d/${username}
5151
chmod 0440 /etc/sudoers.d/${username}
5252
mkdir -p ${BUILD_HOME}/docker ${DIST_DIR} ${BUILD_HOME}/.ssh
5353

54+
# rsync in cached maven dependencies
55+
echo "Syncing maven dependencies and gradle wrapper"
56+
rsync -a /home/image-cache/.m2/repository/ ${BUILD_HOME}/.m2/repository/
57+
cp -a /home/image-cache/.gradle ${BUILD_HOME}/
58+
chown -R ${username}:${username} ${BUILD_HOME}/.gradle ${BUILD_HOME}/.m2
59+
5460
# we need to make SSH less strict to prevent various dtests from failing when they attempt to
5561
# git clone a given commit/tag/etc
5662
echo 'Host *\n UserKnownHostsFile /dev/null\n StrictHostKeyChecking no' > ${BUILD_HOME}/.ssh/config

.build/docker/_docker_run.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
# variables, with defaults
3232
[ "x${cassandra_dir}" != "x" ] || cassandra_dir="$(readlink -f $(dirname -- "$0")/../..)"
3333
[ "x${build_dir}" != "x" ] || build_dir="${cassandra_dir}/build"
34+
# parameterise the maven repository host directory, as it cannot be shared across containers
35+
# m2_dir fails under /tmp on macos
3436
[ "x${m2_dir}" != "x" ] || m2_dir="${HOME}/.m2/repository"
3537
[ -d "${build_dir}" ] || { mkdir -p "${build_dir}" ; }
3638
[ -d "${m2_dir}" ] || { mkdir -p "${m2_dir}" ; }
@@ -99,7 +101,7 @@ if ! ( [[ "$(docker images -q ${image_name} 2>/dev/null)" != "" ]] ) ; then
99101
if ! ( docker pull -q ${image_name} >/dev/null 2>/dev/null ) ; then
100102
# Create build images containing the build tool-chain, Java and an Apache Cassandra git working directory, with retry
101103
echo "Building docker image..."
102-
until docker build -t ${image_name} -f docker/${dockerfile} . ; do
104+
until docker build -t ${image_name} -f docker/${dockerfile} --load . ; do
103105
echo "docker build failed… trying again in 10s… "
104106
sleep 10
105107
done
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#!/bin/bash
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
set -e
16+
17+
# Script to prepopulate Maven repository with dependencies from multiple Cassandra branches
18+
# This will download all dependencies to a custom Maven repository directory
19+
20+
# pre-conditions
21+
command -v ant >/dev/null 2>&1 || { error 1 "ant needs to be installed"; }
22+
command -v git >/dev/null 2>&1 || { error 1 "git needs to be installed"; }
23+
24+
25+
error() {
26+
echo >&2 $2;
27+
set -x
28+
exit $1
29+
}
30+
31+
# Function to download dependencies for a branch
32+
download_deps_for_branch() {
33+
local branch=$1
34+
local branch_name=$(echo "$branch" | sed 's|origin/||')
35+
36+
# Check if branch exists
37+
if ! git rev-parse --verify "$branch" >/dev/null 2>&1; then
38+
echo "WARNING: Branch $branch does not exist, skipping..."
39+
return
40+
fi
41+
42+
git checkout "$branch"
43+
44+
echo ""
45+
echo "Downloading dependencies for $branch to $CUSTOM_M2_REPO..."
46+
echo ""
47+
48+
# ensure git modules are initialised
49+
ant init
50+
# download all dependencies
51+
ant -Dmaven.repo.local="$CUSTOM_M2_REPO" -Dlocal.repository="$CUSTOM_M2_REPO" resolver-dist-lib
52+
}
53+
54+
CUSTOM_M2_REPO="${1:-$HOME/.m2/repository}"
55+
TMP_DIR=${TMP_DIR:-/tmp}
56+
57+
cd $TMP_DIR
58+
git clone https://github.com/apache/cassandra.git
59+
cd cassandra
60+
git config advice.detachedHead false
61+
62+
# Automatically detect branches from cassandra-5.0 onwards to trunk
63+
echo "Detecting branches..."
64+
BRANCHES=()
65+
66+
# Get all origin branches matching cassandra-5.x+, cassandra-6.x+, etc., and trunk
67+
# Pattern matches: cassandra-5.0, cassandra-5.0.0, cassandra-10.0, cassandra-10.0.1, trunk
68+
while IFS= read -r branch; do
69+
BRANCHES+=("$branch")
70+
done < <(git branch -r | grep -E "^\s*origin/(cassandra-[5-9][0-9]*\.[0-9]+(\.[0-9]+)?|trunk)$" | sed 's/^[[:space:]]*//' | sort -V)
71+
72+
# If no branches found, fail
73+
if [ ${#BRANCHES[@]} -eq 0 ]; then
74+
echo "ERROR: No branches auto-detected matching pattern origin/cassandra-[5+].x or origin/trunk"
75+
echo "Please ensure you have fetched remote branches: git fetch origin"
76+
exit 1
77+
fi
78+
79+
echo "Branches to process:"
80+
for branch in "${BRANCHES[@]}"; do
81+
echo " - $branch"
82+
done
83+
echo "=========================================="
84+
echo ""
85+
86+
# Create custom Maven repository directory
87+
mkdir -p "$CUSTOM_M2_REPO"
88+
89+
# Process each branch
90+
for branch in "${BRANCHES[@]}"; do
91+
download_deps_for_branch "$branch"
92+
done
93+
94+
cd -
95+
rm -rf $TMP_DIR/cassandra

.build/docker/almalinux-build.docker

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ ENV CASSANDRA_DIR=$BUILD_HOME/cassandra
2626
ARG UID_ARG=1000
2727
ARG GID_ARG=1000
2828

29-
LABEL org.cassandra.buildenv=almalinux
29+
LABEL org.cassandra.buildenv=almalinux_build
3030

3131
RUN echo "Building with arguments:" \
3232
&& echo " - DIST_DIR=${DIST_DIR}" \
@@ -55,3 +55,12 @@ RUN rpm -i --nodeps ant-junit-1.9.4-2.el7.noarch.rpm
5555

5656
# python3 is needed for the gen-doc target
5757
RUN pip3 install --upgrade pip
58+
59+
# Prepopulate Maven repository with dependencies from all branches. see _create_user.sh
60+
COPY docker/_prepopulate_maven_deps.sh /tmp/_prepopulate_maven_deps.sh
61+
RUN alternatives --set java $(alternatives --display java | grep "family java-11-openjdk" | cut -d' ' -f1)
62+
RUN alternatives --set javac $(alternatives --display javac | grep "family java-11-openjdk" | cut -d' ' -f1)
63+
RUN mkdir -p /home/image-cache && chmod -R a+rwx /home/image-cache
64+
RUN JAVA_HOME=$(readlink -f /usr/bin/javac | sed "s:/bin/javac::") \
65+
bash /tmp/_prepopulate_maven_deps.sh /home/image-cache/.m2/repository && rm /tmp/_prepopulate_maven_deps.sh
66+
RUN cp -a /root/.gradle /home/image-cache/.gradle

.build/docker/bullseye-build.docker

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ ENV DIST_DIR=/dist
2323
ENV BUILD_HOME=/home/build
2424
ENV CASSANDRA_DIR=$BUILD_HOME/cassandra
2525

26-
LABEL org.cassandra.buildenv=bullseye
26+
LABEL org.cassandra.buildenv=debian_build
2727

2828
RUN echo "Building with arguments:" \
2929
&& echo " - DIST_DIR=${DIST_DIR}" \
@@ -70,4 +70,10 @@ RUN sh -c '\
7070

7171
ENV GOROOT="/usr/local/go"
7272
ENV GOPATH="$BUILD_HOME/go"
73-
ENV PATH="$PATH:/usr/local/go/bin"
73+
ENV PATH="$PATH:/usr/local/go/bin"
74+
75+
# Prepopulate Maven repository with dependencies from all branches. see _create_user.sh
76+
COPY docker/_prepopulate_maven_deps.sh /tmp/_prepopulate_maven_deps.sh
77+
RUN mkdir -p /home/image-cache && chmod -R a+rwx /home/image-cache
78+
RUN bash /tmp/_prepopulate_maven_deps.sh /home/image-cache/.m2/repository && rm /tmp/_prepopulate_maven_deps.sh
79+
RUN cp -a /root/.gradle /home/image-cache/.gradle

.build/docker/run-tests.sh

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
[ "x${cassandra_dir}" != "x" ] || cassandra_dir="$(readlink -f $(dirname -- "$0")/../..)"
2626
[ "x${cassandra_dtest_dir}" != "x" ] || cassandra_dtest_dir="${cassandra_dir}/../cassandra-dtest"
2727
[ "x${build_dir}" != "x" ] || build_dir="${cassandra_dir}/build"
28+
# parameterise the maven repository host directory, as it cannot be shared across containers.
29+
# m2_dir fails under /tmp on macos
2830
[ "x${m2_dir}" != "x" ] || m2_dir="${HOME}/.m2/repository"
2931
[ "x${docker_timeout_hours}" != "x" ] || docker_timeout_hours="1"
3032
[ -d "${build_dir}" ] || { mkdir -p "${build_dir}" ; }
@@ -134,7 +136,7 @@ docker --version
134136
pushd ${cassandra_dir}/.build >/dev/null
135137

136138
# build test image
137-
dockerfile="ubuntu2004_test.docker"
139+
dockerfile="ubuntu-test.docker"
138140
image_tag="$(md5sum docker/${dockerfile} | cut -d' ' -f1)"
139141
image_name="apache/cassandra-${dockerfile/.docker/}:${image_tag}"
140142
docker_mounts="-v ${cassandra_dir}:/home/cassandra/cassandra -v "${build_dir}":/home/cassandra/cassandra/build -v ${m2_dir}:/home/cassandra/.m2/repository"
@@ -147,7 +149,7 @@ if ! ( [[ "$(docker images -q ${image_name} 2>/dev/null)" != "" ]] ) ; then
147149
if ! ( docker pull -q ${image_name} >/dev/null 2>/dev/null ) ; then
148150
# Create build images containing the build tool-chain, Java and an Apache Cassandra git working directory, with retry
149151
echo "Building docker image..."
150-
until docker build -t ${image_name} -f docker/${dockerfile} . ; do
152+
until docker build -t ${image_name} -f docker/${dockerfile} --load . ; do
151153
echo "docker build failed… trying again in 10s… "
152154
sleep 10
153155
done
@@ -294,7 +296,7 @@ docker_command="source \${CASSANDRA_DIR}/.build/docker/_set_java.sh ${java_versi
294296
# start the container, timeout after 4 hours
295297
docker_id=$(docker run --name ${container_name} ${docker_flags} ${docker_envs} ${docker_mounts} ${docker_volume_opt} ${image_name} sleep ${docker_timeout_hours}h)
296298

297-
echo "Running container ${container_name} ${docker_id}"
299+
echo "Running container ${container_name} ${docker_id} using image ${image_name}"
298300

299301
docker exec --user root ${container_name} bash -c "\${CASSANDRA_DIR}/.build/docker/_create_user.sh cassandra $(id -u) $(id -g)" | tee -a ${logfile}
300302
docker exec --user root ${container_name} update-alternatives --set python /usr/bin/python${python_version} | tee -a ${logfile}
Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
# See the License for the specific language governing permissions and
1111
# limitations under the License.
1212

13-
FROM ubuntu:20.04
14-
MAINTAINER Apache Cassandra <dev@cassandra.apache.org>
13+
FROM ubuntu:22.04
14+
LABEL org.opencontainers.image.authors="Apache Cassandra <dev@cassandra.apache.org>"
1515

1616
# CONTEXT is expected to be cassandra/.build
1717

@@ -23,7 +23,7 @@ ENV LC_CTYPE=en_US.UTF-8
2323
ENV PYTHONIOENCODING=utf-8
2424
ENV PYTHONUNBUFFERED=true
2525

26-
LABEL org.cassandra.buildenv=ubuntu_2004
26+
LABEL org.cassandra.buildenv=ubuntu_test
2727

2828
RUN echo "Building with arguments:" \
2929
&& echo " - DIST_DIR=${DIST_DIR}" \
@@ -42,7 +42,7 @@ RUN echo 'Acquire::ftp::Timeout "60";' >> /etc/apt/apt.conf.d/80proxy.conf
4242

4343
RUN export DEBIAN_FRONTEND=noninteractive && \
4444
apt-get update && \
45-
apt-get install -y --no-install-recommends software-properties-common apt-utils
45+
apt-get install -y --no-install-recommends software-properties-common apt-utils gnupg
4646

4747
RUN export DEBIAN_FRONTEND=noninteractive && \
4848
add-apt-repository -y ppa:deadsnakes/ppa && \
@@ -54,7 +54,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
5454
vim lsof sudo libjemalloc2 dumb-init locales rsync \
5555
openjdk-8-jdk openjdk-11-jdk openjdk-17-jdk ant ant-optional
5656

57-
57+
RUN update-alternatives --remove java /usr/lib/jvm/java-8-openjdk-$(dpkg --print-architecture)/jre/bin/java
58+
RUN update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-8-openjdk-$(dpkg --print-architecture)/bin/java 1081
5859
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.8 2
5960
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.11 3
6061
RUN python3.8 -m pip install --upgrade pip
@@ -79,6 +80,7 @@ RUN find /etc -type f -name java.security -exec sed -i 's/TLSv1, TLSv1.1//' {} \
7980
RUN find /etc -type f -name java.security -exec sed -i 's/3DES_EDE_CBC$/3DES_EDE_CBC, TLSv1, TLSv1.1/' {} \;
8081

8182
# create and change to cassandra-tmp user, use an rare uid to avoid collision later on
83+
RUN mkdir -p /home/image-cache && chmod -R a+rwx /home/image-cache
8284
RUN adduser --disabled-login --uid 901743 --lastuid 901743 --gecos cassandra cassandra-tmp
8385
RUN gpasswd -a cassandra-tmp sudo
8486
RUN echo "cassandra-tmp ALL=(root) NOPASSWD:ALL" > /etc/sudoers.d/build
@@ -87,11 +89,16 @@ RUN chmod 0440 /etc/sudoers.d/build
8789
# switch to the cassandra user
8890
RUN mkdir -p ${BUILD_HOME} && chmod a+rwx ${BUILD_HOME}
8991
USER cassandra-tmp
90-
ENV HOME ${BUILD_HOME}
92+
ENV HOME=${BUILD_HOME}
9193
WORKDIR ${BUILD_HOME}
9294

9395
ENV ANT_HOME=/usr/share/ant
9496

97+
# Prepopulate Maven repository with dependencies from all branches. see _create_user.sh
98+
COPY docker/_prepopulate_maven_deps.sh /tmp/_prepopulate_maven_deps.sh
99+
RUN bash /tmp/_prepopulate_maven_deps.sh /home/image-cache/.m2/repository
100+
RUN cp -a /home/cassandra-tmp/.gradle /home/image-cache/.gradle
101+
95102
# run pip commands and setup virtualenv (note we do this after we switch to cassandra user so we
96103
# setup the virtualenv for the cassandra user and not the root user by accident) for Python 3.8/3.11
97104
# Don't build cython extensions when installing cassandra-driver. During test execution the driver
@@ -110,15 +117,22 @@ RUN /bin/bash -c "export CASS_DRIVER_NO_CYTHON=1 CASS_DRIVER_NO_EXTENSIONS=1 \
110117
&& pip3 install -r /opt/requirements.txt \
111118
&& pip3 freeze --user"
112119

113-
RUN virtualenv --python=python3.11 ${BUILD_HOME}/env3.11
120+
RUN python3.11 -m venv ${BUILD_HOME}/env3.11
114121
RUN chmod +x ${BUILD_HOME}/env3.11/bin/activate
115122

116123
RUN /bin/bash -c "export CASS_DRIVER_NO_CYTHON=1 CASS_DRIVER_NO_EXTENSIONS=1 \
117124
&& source ${BUILD_HOME}/env3.11/bin/activate \
118125
&& curl -sS https://bootstrap.pypa.io/get-pip.py | python3.11 \
119-
&& pip3 install -r /opt/requirements.txt \
126+
&& pip3 install --upgrade \"pip<25.0\" \"setuptools==60.8.2\" wheel \
127+
&& pip3 install --no-build-isolation -r /opt/requirements.txt \
120128
&& pip3 freeze --user"
121129

130+
# 4* requires java8, sudo doesn't work on cross-platform builds
131+
USER root
132+
RUN update-alternatives --set java /usr/lib/jvm/java-8-openjdk-$(dpkg --print-architecture)/bin/java
133+
RUN update-alternatives --set javac /usr/lib/jvm/java-8-openjdk-$(dpkg --print-architecture)/bin/javac
134+
USER cassandra-tmp
135+
122136
# Initialize the CCM git repo as well as this also can fail to clone
123137
RUN /bin/bash -c "source ${BUILD_HOME}/env3.8/bin/activate && \
124138
ccm create -n 1 -v git:cassandra-4.1 test && ccm remove test && \
@@ -131,16 +145,23 @@ RUN bash -c 'source ${BUILD_HOME}/env3.8/bin/activate && \
131145
latest_4_1=$(curl -s https://downloads.apache.org/cassandra/ | grep -oP "(?<=href=\")4\.1\.[0-9]+(?=\")" | sort -V | tail -1 | cut -d"." -f3) && \
132146
for i in $(seq 1 $latest_4_1); do echo $i ; ccm create --quiet -n 1 -v binary:4.1.$i test && ccm remove test ; done'
133147

134-
# 5+ requires java11
135-
RUN sudo update-java-alternatives --set java-1.11.0-openjdk-$(dpkg --print-architecture)
148+
# 5+ requires java11, sudo doesn't work on cross-platform builds
149+
USER root
150+
RUN update-alternatives --set java /usr/lib/jvm/java-11-openjdk-$(dpkg --print-architecture)/bin/java
151+
RUN update-alternatives --set javac /usr/lib/jvm/java-11-openjdk-$(dpkg --print-architecture)/bin/javac
152+
USER cassandra-tmp
136153

137154
# Initialize ccm versions. branch heads and all versions iterating through to the latest version found on downloads.apache.org/cassandra
138155
RUN rm -fr ${BUILD_HOME}/.ccm/repository/_git_cache_apache
139156
RUN /bin/bash -c 'source ${BUILD_HOME}/env3.8/bin/activate && \
140157
ccm create --quiet -n 1 -v git:cassandra-5.0 test && ccm remove test && \
158+
ccm create --quiet -n 1 -v git:cassandra-6.0 test && ccm remove test && \
141159
ccm create --quiet -n 1 -v git:trunk test && ccm remove test && \
142160
latest_5_0=$(curl -s https://downloads.apache.org/cassandra/ | grep -oP "(?<=href=\")5\.0\.[0-9]+(?=\")" | sort -V | tail -1 | cut -d"." -f3) && \
143161
for i in $(seq 1 $latest_5_0); do echo $i ; ccm create --quiet -n 1 -v binary:5.0.$i test && ccm remove test ; done'
162+
# TODO uncomment when 6.0.0 is released
163+
#latest_6_0=$(curl -s https://downloads.apache.org/cassandra/ | grep -oP "(?<=href=\")6\.0\.[0-9]+(?=\")" | sort -V | tail -1 | cut -d"." -f3) && \
164+
#for i in $(seq 1 $latest_6_0); do echo $i ; ccm create --quiet -n 1 -v binary:6.0.$i test && ccm remove test ; done'
144165

145166
# the .git subdirectories to pip installed cassandra-driver breaks virtualenv-clone, so just remove them
146167
# and other directories we don't need in image

0 commit comments

Comments
 (0)