diff --git a/5.0/Dockerfile b/5.0/Dockerfile index 3b2134f..0002f19 100644 --- a/5.0/Dockerfile +++ b/5.0/Dockerfile @@ -4,7 +4,7 @@ # PLEASE DO NOT EDIT IT DIRECTLY. # -FROM debian:bookworm-slim +FROM debian:trixie-slim # explicitly set user/group IDs RUN set -eux; \ diff --git a/6.0/Dockerfile b/6.0/Dockerfile new file mode 100644 index 0000000..ea27f10 --- /dev/null +++ b/6.0/Dockerfile @@ -0,0 +1,181 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM debian:trixie-slim + +# explicitly set user/group IDs +RUN set -eux; \ + groupadd -r cassandra --gid=999; \ + useradd -r -g cassandra --uid=999 cassandra + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ +# solves warning: "jemalloc shared library could not be preloaded to speed up memory allocations" + libjemalloc2 \ +# "free" is used by cassandra-env.sh + procps \ +# "cqlsh" needs a python interpreter + python3 \ +# "ip" is not required by Cassandra itself, but is commonly used in scripting Cassandra's configuration (since it is so fixated on explicit IP addresses) + iproute2 \ +# Cassandra will automatically use numactl if available +# https://github.com/apache/cassandra/blob/18bcda2d4c2eba7370a0b21f33eed37cb730bbb3/bin/cassandra#L90-L100 +# https://github.com/apache/cassandra/commit/604c0e87dc67fa65f6904ef9a98a029c9f2f865a + numactl \ + ; \ + rm -rf /var/lib/apt/lists/*; \ +# https://issues.apache.org/jira/browse/CASSANDRA-15767 ("bin/cassandra" only looks for "libjemalloc.so" or "libjemalloc.so.1" which doesn't match our "libjemalloc.so.2") + libjemalloc="$(readlink -e /usr/lib/*/libjemalloc.so.2)"; \ + ln -sT "$libjemalloc" /usr/local/lib/libjemalloc.so; \ + ldconfig + +# grab gosu for easy step-down from root +# https://github.com/tianon/gosu/releases +ENV GOSU_VERSION 1.19 +RUN set -eux; \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends ca-certificates gnupg wget; \ + rm -rf /var/lib/apt/lists/*; \ + dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \ + wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \ + wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \ + export GNUPGHOME="$(mktemp -d)"; \ + gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \ + gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \ + gpgconf --kill all; \ + rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \ + apt-mark auto '.*' > /dev/null; \ + [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + chmod +x /usr/local/bin/gosu; \ + gosu --version; \ + gosu nobody true + +ENV JAVA_HOME /opt/java/openjdk +COPY --from=eclipse-temurin:21-jre $JAVA_HOME $JAVA_HOME +ENV PATH $JAVA_HOME/bin:$PATH +RUN java --version + +ENV CASSANDRA_HOME /opt/cassandra +ENV CASSANDRA_CONF /etc/cassandra +ENV PATH $CASSANDRA_HOME/bin:$PATH + +# https://cwiki.apache.org/confluence/display/CASSANDRA2/DebianPackaging#DebianPackaging-AddingRepositoryKeys +# $ docker run --rm buildpack-deps:bullseye-curl bash -c 'wget -qO- https://downloads.apache.org/cassandra/KEYS | gpg --batch --import &> /dev/null && gpg --batch --list-keys --with-fingerprint --with-colons' | awk -F: '$1 == "pub" && $2 == "-" { pub = 1 } pub && $1 == "fpr" { fpr = $10 } $1 == "sub" { pub = 0 } pub && fpr && $1 == "uid" && $2 == "-" { print "#", $10; print "\t" fpr " \\"; pub = 0 }' +ENV GPG_KEYS \ +# Eric Evans + CEC86BB4A0BA9D0F90397CAEF8358FA2F2833C93 \ +# Eric Evans + C4965EE9E3015D192CCCF2B6F758CE318D77295D \ +# Sylvain Lebresne (pcmanus) + 5AED1BF378E9A19DADE1BCB34BD736A82B5C1B00 \ +# T Jake Luciani + 514A2AD631A57A16DD0047EC749D6EEC0353B12C \ +# Michael Shuler + A26E528B271F19B9E5D8E19EA278B781FE4B2BDA \ +# Michael Semb Wever + A4C465FEA0C552561A392A61E91335D77E3E87CB \ +# Alex Petrov + 9E66CEC6106D578D0B1EB9BFF1000962B7F6840C \ +# Jordan West + C4009872C59B49561310D966D0062876AF30F054 \ +# Brandon Williams + B7842CDAF36E6A3214FAE35D5E85B9AE0B84C041 \ +# Ekaterina Buryanova Dimitrova (CODE SIGNING KEY) + 3E9C876907A560ACA00964F363E9BAD215BBF5F0 \ +# Sam Tunnicliffe (CODE SIGNING KEY) + F8B7FD00E05C932991A2CD6150EE103D162C5A55 \ +# Stefan Miklosovic + 7464AAD9068241C50BA6A26232F35CB2F546D93E \ +# Berenguer Blasi (Code Signing Key) + CEC5C50B9C629EF0F5AB2706650B72EB14CCD622 + +ENV CASSANDRA_VERSION 6.0-alpha2 +ENV CASSANDRA_SHA512 64577a7e48068f6602396370765898364712cf22c95632c11e216b729c3db3e1eefe5d74ba173dd18a995b9c3964af455c0ca8bdecd3975120f3521754985734 + +RUN set -eux; \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends ca-certificates gnupg wget; \ + rm -rf /var/lib/apt/lists/*; \ + \ + ddist() { \ + local f="$1"; shift; \ + local distFile="$1"; shift; \ + local success=; \ + local distUrl=; \ + for distUrl in \ +# https://github.com/docker-library/tomcat/pull/308 + https://dlcdn.apache.org/ \ +# if the version is outdated, we have to pull from the archive + https://archive.apache.org/dist/ \ + ; do \ + if wget --progress=dot:giga -O "$f" "$distUrl$distFile" && [ -s "$f" ]; then \ + success=1; \ + break; \ + fi; \ + done; \ + [ -n "$success" ]; \ + }; \ + \ + ddist 'cassandra-bin.tgz' "cassandra/$CASSANDRA_VERSION/apache-cassandra-$CASSANDRA_VERSION-bin.tar.gz"; \ + echo "$CASSANDRA_SHA512 *cassandra-bin.tgz" | sha512sum --check --strict -; \ + \ + ddist 'cassandra-bin.tgz.asc' "cassandra/$CASSANDRA_VERSION/apache-cassandra-$CASSANDRA_VERSION-bin.tar.gz.asc"; \ + export GNUPGHOME="$(mktemp -d)"; \ + for key in $GPG_KEYS; do \ + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ + done; \ + gpg --batch --verify cassandra-bin.tgz.asc cassandra-bin.tgz; \ + rm -rf "$GNUPGHOME"; \ + \ + apt-mark auto '.*' > /dev/null; \ + [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + \ + mkdir -p "$CASSANDRA_HOME"; \ + tar --extract --file cassandra-bin.tgz --directory "$CASSANDRA_HOME" --strip-components 1; \ + rm cassandra-bin.tgz*; \ + \ + [ ! -e "$CASSANDRA_CONF" ]; \ + mv "$CASSANDRA_HOME/conf" "$CASSANDRA_CONF"; \ + ln -sT "$CASSANDRA_CONF" "$CASSANDRA_HOME/conf"; \ + \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + ppc64el) \ +# https://issues.apache.org/jira/browse/CASSANDRA-13345 +# "The stack size specified is too small, Specify at least 328k" + grep -- '^-Xss256k$' "$CASSANDRA_CONF/jvm-server.options"; \ + sed -ri 's/^-Xss256k$/-Xss512k/' "$CASSANDRA_CONF/jvm-server.options"; \ + grep -- '^-Xss512k$' "$CASSANDRA_CONF/jvm-server.options"; \ + ;; \ + esac; \ + \ + mkdir -p "$CASSANDRA_CONF" /var/lib/cassandra /var/log/cassandra; \ + chown -R cassandra:cassandra "$CASSANDRA_CONF" /var/lib/cassandra /var/log/cassandra; \ + chmod 1777 "$CASSANDRA_CONF" /var/lib/cassandra /var/log/cassandra; \ + chmod -R a+rwX "$CASSANDRA_CONF"; \ + ln -sT /var/lib/cassandra "$CASSANDRA_HOME/data"; \ + ln -sT /var/log/cassandra "$CASSANDRA_HOME/logs"; \ + \ +# smoke test + cassandra -v + +VOLUME /var/lib/cassandra + +COPY docker-entrypoint.sh /usr/local/bin/ +ENTRYPOINT ["docker-entrypoint.sh"] + +# 7000: intra-node communication +# 7001: TLS intra-node communication +# 7199: JMX +# 9042: CQL +# 9160: thrift service +EXPOSE 7000 7001 7199 9042 9160 +CMD ["cassandra", "-f"] diff --git a/6.0/docker-entrypoint.sh b/6.0/docker-entrypoint.sh new file mode 100755 index 0000000..f39af13 --- /dev/null +++ b/6.0/docker-entrypoint.sh @@ -0,0 +1,94 @@ +#!/usr/bin/env bash +set -e + +# first arg is `-f` or `--some-option` +# or there are no args +if [ "$#" -eq 0 ] || [ "${1#-}" != "$1" ]; then + set -- cassandra -f "$@" +fi + +# allow the container to be started with `--user` +if [ "$1" = 'cassandra' -a "$(id -u)" = '0' ]; then + find "$CASSANDRA_CONF" /var/lib/cassandra /var/log/cassandra \ + \! -user cassandra -exec chown cassandra '{}' + + exec gosu cassandra "$BASH_SOURCE" "$@" +fi + +_ip_address() { + # scrape the first non-localhost IP address of the container + # in Swarm Mode, we often get two IPs -- the container IP, and the (shared) VIP, and the container IP should always be first + ip address | awk ' + $1 != "inet" { next } # only lines with ip addresses + $NF == "lo" { next } # skip loopback devices + $2 ~ /^127[.]/ { next } # skip loopback addresses + $2 ~ /^169[.]254[.]/ { next } # skip link-local addresses + { + gsub(/\/.+$/, "", $2) + print $2 + exit + } + ' +} + +# "sed -i", but without "mv" (which doesn't work on a bind-mounted file, for example) +_sed-in-place() { + local filename="$1"; shift + local tempFile + tempFile="$(mktemp)" + sed "$@" "$filename" > "$tempFile" + cat "$tempFile" > "$filename" + rm "$tempFile" +} + +if [ "$1" = 'cassandra' ]; then + : ${CASSANDRA_RPC_ADDRESS='0.0.0.0'} + + : ${CASSANDRA_LISTEN_ADDRESS='auto'} + if [ "$CASSANDRA_LISTEN_ADDRESS" = 'auto' ]; then + CASSANDRA_LISTEN_ADDRESS="$(_ip_address)" + fi + + : ${CASSANDRA_BROADCAST_ADDRESS="$CASSANDRA_LISTEN_ADDRESS"} + + if [ "$CASSANDRA_BROADCAST_ADDRESS" = 'auto' ]; then + CASSANDRA_BROADCAST_ADDRESS="$(_ip_address)" + fi + : ${CASSANDRA_BROADCAST_RPC_ADDRESS:=$CASSANDRA_BROADCAST_ADDRESS} + + if [ -n "${CASSANDRA_NAME:+1}" ]; then + : ${CASSANDRA_SEEDS:="cassandra"} + fi + : ${CASSANDRA_SEEDS:="$CASSANDRA_BROADCAST_ADDRESS"} + + _sed-in-place "$CASSANDRA_CONF/cassandra.yaml" \ + -r 's/(- seeds:).*/\1 "'"$CASSANDRA_SEEDS"'"/' + + for yaml in \ + broadcast_address \ + broadcast_rpc_address \ + cluster_name \ + endpoint_snitch \ + listen_address \ + num_tokens \ + rpc_address \ + start_rpc \ + ; do + var="CASSANDRA_${yaml^^}" + val="${!var}" + if [ "$val" ]; then + _sed-in-place "$CASSANDRA_CONF/cassandra.yaml" \ + -r 's/^(# )?('"$yaml"':).*/\2 '"$val"'/' + fi + done + + for rackdc in dc rack; do + var="CASSANDRA_${rackdc^^}" + val="${!var}" + if [ "$val" ]; then + _sed-in-place "$CASSANDRA_CONF/cassandra-rackdc.properties" \ + -r 's/^('"$rackdc"'=).*/\1 '"$val"'/' + fi + done +fi + +exec "$@" diff --git a/versions.json b/versions.json index 73664e9..9936b00 100644 --- a/versions.json +++ b/versions.json @@ -26,7 +26,17 @@ "version": "17" }, "debian": { - "version": "bookworm" + "version": "trixie" + } + }, + "6.0": { + "version": "6.0-alpha2", + "sha512": "64577a7e48068f6602396370765898364712cf22c95632c11e216b729c3db3e1eefe5d74ba173dd18a995b9c3964af455c0ca8bdecd3975120f3521754985734", + "java": { + "version": "21" + }, + "debian": { + "version": "trixie" } } } diff --git a/versions.sh b/versions.sh index eefe79c..d458306 100755 --- a/versions.sh +++ b/versions.sh @@ -1,24 +1,24 @@ #!/usr/bin/env bash set -Eeuo pipefail +# https://cassandra.apache.org/doc/6.0/cassandra/installing/installing.html#prerequisites +# https://github.com/apache/cassandra/commit/940739a4889794a5f198731b152c70e86bc95976 (add jdk21 support in 6.0) # https://cassandra.apache.org/doc/5.0/cassandra/installing/installing.html#prerequisites # https://cassandra.apache.org/doc/4.1/cassandra/getting_started/installing.html#prerequisites -# https://github.com/apache/cassandra/blob/cassandra-5.0.6/build.xml#L48 -defaultJavaVersion='17' +defaultJavaVersion='21' declare -A javaVersions=( [4.0]='11' # https://github.com/apache/cassandra/blob/cassandra-4.0.19/build.xml#L212-L221 [4.1]='11' # https://github.com/apache/cassandra/blob/cassandra-4.1.10/build.xml#L227-L236 + [5.0]='17' # https://github.com/apache/cassandra/blob/cassandra-5.0.9/build.xml#L48 ) +# 5.0.9+ supports up to python 3.13: https://issues.apache.org/jira/browse/CASSANDRA-20997 +# https://github.com/apache/cassandra/blob/cassandra-5.0.9/bin/cqlsh#L66 +# https://github.com/apache/cassandra/blob/cassandra-6.0-alpha2/bin/cqlsh#L66 defaultSuite='trixie' declare -A suites=( # https://issues.apache.org/jira/browse/CASSANDRA-19206: "cqlsh breaks with Python 3.12" ("ModuleNotFoundError: No module named 'six.moves'") [4.0]='bookworm' [4.1]='bookworm' - # "Warning: unsupported version of Python, required 3.6-3.11 but found 3.12" - # https://github.com/apache/cassandra/commit/8fd44ca8fc9e0b0e94932bcd855e2833bf6ca3cb#diff-8d8ae48aaf489a8a0e726d3e4a6230a26dcc76e7c739e8e3968e3f65c995d148 - # https://issues.apache.org/jira/browse/CASSANDRA-19245?focusedCommentId=17803539#comment-17803539 - # https://github.com/apache/cassandra/blob/cassandra-5.0.6/bin/cqlsh#L65 - [5.0]='bookworm' ) cd "$(dirname "$(readlink -f "$BASH_SOURCE")")"