Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 74 additions & 6 deletions dev-support/Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pipeline {
OUTPUT_DIR_RELATIVE_JDK8_HADOOP3 = 'output-jdk8-hadoop3'
OUTPUT_DIR_RELATIVE_JDK11_HADOOP3 = 'output-jdk11-hadoop3'
OUTPUT_DIR_RELATIVE_JDK17_HADOOP3 = 'output-jdk17-hadoop3'
OUTPUT_DIR_RELATIVE_READ_REPLICA = 'output-read-replica'

PROJECT = 'hbase'
PROJECT_PERSONALITY = 'https://raw.githubusercontent.com/apache/hbase/master/dev-support/hbase-personality.sh'
Expand Down Expand Up @@ -135,6 +136,7 @@ pipeline {
stash name: 'jdk8-hadoop3-result', allowEmpty: true, includes: "${OUTPUT_DIR_RELATIVE_JDK8_HADOOP3}/doesn't-match"
stash name: 'jdk11-hadoop3-result', allowEmpty: true, includes: "${OUTPUT_DIR_RELATIVE_JDK11_HADOOP3}/doesn't-match"
stash name: 'jdk17-hadoop3-result', allowEmpty: true, includes: "${OUTPUT_DIR_RELATIVE_JDK17_HADOOP3}/doesn't-match"
stash name: 'read-replica-result', allowEmpty: true, includes: "${OUTPUT_DIR_RELATIVE_READ_REPLICA}/doesn't-match"
}
}
stage ('health checks') {
Expand Down Expand Up @@ -319,7 +321,7 @@ pipeline {
else
echo "No archiver directory, skipping compressing."
fi
'''
'''
sshPublisher(publishers: [
sshPublisherDesc(configName: 'Nightlies',
transfers: [
Expand All @@ -338,7 +340,7 @@ pipeline {
else
echo "No test_logs.zip, skipping"
fi
'''
'''
// Has to be relative to WORKSPACE.
archiveArtifacts artifacts: "${env.OUTPUT_DIR_RELATIVE}/*"
archiveArtifacts artifacts: "${env.OUTPUT_DIR_RELATIVE}/**/*"
Expand Down Expand Up @@ -432,7 +434,7 @@ pipeline {
else
echo "No archiver directory, skipping compressing."
fi
'''
'''
sshPublisher(publishers: [
sshPublisherDesc(configName: 'Nightlies',
transfers: [
Expand All @@ -451,7 +453,7 @@ pipeline {
else
echo "No test_logs.zip, skipping"
fi
'''
'''
// Has to be relative to WORKSPACE.
archiveArtifacts artifacts: "${env.OUTPUT_DIR_RELATIVE}/*"
archiveArtifacts artifacts: "${env.OUTPUT_DIR_RELATIVE}/**/*"
Expand Down Expand Up @@ -580,7 +582,6 @@ pipeline {
}
}
}

stage ('yetus jdk17 hadoop3 checks') {
agent {
node {
Expand Down Expand Up @@ -691,6 +692,70 @@ pipeline {
}
}
}
stage ('hbase read-replica feature checks') {
agent {
node {
label 'hbase'
}
}
when {
anyOf {
branch 'master'
branch 'branch-3'
}
}
environment {
BASEDIR = "${env.WORKSPACE}/component"
OUTPUT_DIR_RELATIVE = "${env.OUTPUT_DIR_RELATIVE_READ_REPLICA}"
OUTPUT_DIR = "${env.WORKSPACE}/${env.OUTPUT_DIR_RELATIVE_READ_REPLICA}"
}
steps {
sh '''#!/usr/bin/env bash
set -e
rm -rf "${OUTPUT_DIR}" && mkdir "${OUTPUT_DIR}"
echo '(x) {color:red}-1 read-replica checks{color}' >"${OUTPUT_DIR}/commentfile"
echo "-- Something went wrong running this stage, please [check relevant console output|${BUILD_URL}/console]." >> "${OUTPUT_DIR}/commentfile"
'''
dir('component') {
checkout scm
}
sh '''#!/usr/bin/env bash
set -e
rm -rf "${OUTPUT_DIR}/machine" && mkdir "${OUTPUT_DIR}/machine"
"${BASEDIR}/dev-support/gather_machine_environment.sh" "${OUTPUT_DIR_RELATIVE}/machine"
echo "got the following saved stats in '${OUTPUT_DIR_RELATIVE}/machine'"
ls -lh "${OUTPUT_DIR_RELATIVE}/machine"
'''
script {
def ret = sh(
returnStatus: true,
script: '''#!/usr/bin/env bash
set -e
declare -i status=0
if "${BASEDIR}/dev-support/hbase_nightly_read_replica_test.sh" ; then
echo '(/) {color:green}+1 read-replica checks{color}' > "${OUTPUT_DIR}/commentfile"
else
echo '(x) {color:red}-1 read-replica checks{color}' > "${OUTPUT_DIR}/commentfile"
status=1
fi
echo "-- For more information [see console output|${BUILD_URL}/console]" >> "${OUTPUT_DIR}/commentfile"
exit "${status}"
'''
)
if (ret != 0) {
// mark the build as UNSTABLE instead of FAILURE, to avoid skipping the later publish of
// test output. See HBASE-26339 for more details.
currentBuild.result = 'UNSTABLE'
}
}
}
post {
always {
stash name: 'read-replica-result', includes: "${OUTPUT_DIR_RELATIVE}/commentfile"
archiveArtifacts artifacts: "${env.OUTPUT_DIR_RELATIVE}/**/*", allowEmptyArchive: true
}
}
}
} // parallel
} //stage:_health checks
} //stages
Expand All @@ -707,18 +772,21 @@ pipeline {
rm -rf ${OUTPUT_DIR_RELATIVE_JDK8_HADOOP3}
rm -rf ${OUTPUT_DIR_RELATIVE_JDK11_HADOOP3}
rm -rf ${OUTPUT_DIR_RELATIVE_JDK17_HADOOP3}
rm -rf ${OUTPUT_DIR_RELATIVE_READ_REPLICA}
'''
unstash 'general-result'
unstash 'jdk8-hadoop2-result'
unstash 'jdk8-hadoop3-result'
unstash 'jdk11-hadoop3-result'
unstash 'jdk17-hadoop3-result'
unstash 'read-replica-result'

def results = ["${env.OUTPUT_DIR_RELATIVE_GENERAL}/commentfile",
"${env.OUTPUT_DIR_RELATIVE_JDK8_HADOOP2}/commentfile",
"${env.OUTPUT_DIR_RELATIVE_JDK8_HADOOP3}/commentfile",
"${env.OUTPUT_DIR_RELATIVE_JDK11_HADOOP3}/commentfile",
"${env.OUTPUT_DIR_RELATIVE_JDK17_HADOOP3}/commentfile"]
"${env.OUTPUT_DIR_RELATIVE_JDK17_HADOOP3}/commentfile",
"${env.OUTPUT_DIR_RELATIVE_READ_REPLICA}/commentfile"]
echo env.BRANCH_NAME
echo env.BUILD_URL
echo currentBuild.result
Expand Down
104 changes: 104 additions & 0 deletions dev-support/hbase_nightly_read_replica_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/usr/bin/env bash
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
#
# Run the read-replica Docker integration test suite.

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPLICA_DIR="${SCRIPT_DIR}/read-replica"
export HBASE_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"

export HBASE_IMAGE="hbase-read-replica:${BUILD_NUMBER:-local}"

echo "Script dir: ${SCRIPT_DIR}"
echo "Replica dir: ${REPLICA_DIR}"
echo "HBase root: ${HBASE_ROOT}"

echo "Changing to replica dir: REPLICA_DIR"
cd "${REPLICA_DIR}"

echo "Sourcing environment file: $(pwd)/.env"
set -a
source .env
set +a

export PYTHONPATH="$(pwd)"
echo "Set PYTHONPATH=${PYTHONPATH}"

echo "HBASE_IMAGE=${HBASE_IMAGE}"
echo "ACTIVE_CLUSTER_CONF_DIR=${ACTIVE_CLUSTER_CONF_DIR}"
echo "REPLICA_CLUSTER_CONF_DIR=${REPLICA_CLUSTER_CONF_DIR}"
echo "DOCKER_COMPOSE_FILE=${DOCKER_COMPOSE_FILE}"
echo "HBASE_DATA_STORE_ROOT=${HBASE_DATA_STORE_ROOT}"

# Clone HBase source for Docker build context (Docker COPY doesn't follow symlinks)
echo "Cloning HBase source into ${REPLICA_DIR}/hbase for Docker build context..."
rm -rf "${REPLICA_DIR}/hbase"
git clone --local "${HBASE_ROOT}" "${REPLICA_DIR}/hbase"
rm -rf "${REPLICA_DIR}/hbase/.git"

cleanup() {
local exit_code=$?
if [ ${exit_code} -ne 0 ]; then
echo "=== FAILURE: Dumping Docker container logs ==="
if [ -n "${OUTPUT_DIR}" ] && [ -d "${OUTPUT_DIR}" ]; then
docker logs "${HBASE_CONTAINER_NAME}" 2>&1 | tee "${OUTPUT_DIR}/hbase-docker.log" || true
docker logs "${HBASE_CONTAINER_NAME}-2" 2>&1 | tee "${OUTPUT_DIR}/hbase-docker-2.log" || true
else
docker logs "${HBASE_CONTAINER_NAME}" 2>&1 || true
docker logs "${HBASE_CONTAINER_NAME}-2" 2>&1 || true
fi
fi
echo "=== Cleanup: Stopping Docker containers ==="
docker compose -f "${DOCKER_COMPOSE_FILE}" down 2>/dev/null || true
echo "=== Cleanup: Removing Docker image: ${HBASE_IMAGE} ==="
docker rmi --force "${HBASE_IMAGE}" 2>/dev/null || true
rm -rf "${REPLICA_DIR}/hbase"
exit "${exit_code}"
}
trap cleanup EXIT

# Copy latest proto file from source
echo "Copying latest version of ActiveClusterSuffix.proto to $(pwd)/python/proto/"
cp "${HBASE_ROOT}/hbase-protocol-shaded/src/main/protobuf/server/ActiveClusterSuffix.proto" \
python/proto/

# Install Python dependencies
echo "Installing Python libraries"
python3 -m pip install --user -q -r requirements.txt

# Compile protobuf
echo "Compiling Protobuf"
python3 python/proto/proto_compiler.py

# Build Docker images
echo "Building hbase-docker image"
./build-images.sh

# Run read-replica integration test suite
echo "Starting read-replica integration test scripts"
python3 python/scripts/test_dual_active_cluster_startup.py --clean-up-containers
python3 python/scripts/verify_hbase_start.py
python3 python/scripts/test_create_drop_behavior.py --skip-table-cleanup-on-start
python3 python/scripts/test_put_get_delete_behavior.py --skip-table-cleanup-on-start
python3 python/scripts/test_read_only_flag_flipping.py --skip-container-start-or-restart
python3 python/scripts/test_cannot_promote_second_active_cluster.py --skip-container-start-or-restart
python3 python/scripts/test_bulkloaded_data_and_region_splits.py --skip-container-start-or-restart

echo "All read-replica integration tests passed."
25 changes: 25 additions & 0 deletions dev-support/read-replica/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# The name of the HBase Docker image
HBASE_IMAGE=${HBASE_IMAGE:-kgeisz/hbase-docker:read-replica-gha}
# The name of the HBase docker container
HBASE_CONTAINER_NAME=hbase-docker
# The directory within the docker container that contains the config files
HBASE_CONF_DIR=/opt/hbase/conf
# The directory containing the 'data-store/<hbase.rootdir>' directory.
# This directory is mounted with the HBase Docker container.
HBASE_DATA_STORE_ROOT=${HBASE_DATA_STORE_ROOT:-/tmp/hbase-read-replica}
# The port for the active cluster's HBase UI (used for cluster readiness)
ACTIVE_CLUSTER_PORT=16010
# The port for the replica cluster's HBase UI (used for cluster readiness)
REPLICA_CLUSTER_PORT=26010
# Local path to the active cluster's HBase config file.
# This file is part of a mounted volume, so modifying it
# locally also modifies it within the container (and vise-versa).
ACTIVE_CLUSTER_CONF_DIR=${HBASE_ROOT}/dev-support/read-replica/conf1
# Same as above, except for the replica cluster
REPLICA_CLUSTER_CONF_DIR=${HBASE_ROOT}/dev-support/read-replica/conf2
# The path to the docker-compose file
DOCKER_COMPOSE_FILE=${HBASE_ROOT}/dev-support/read-replica/docker-compose.yml
# The location of the utils directory within the docker container
CONTAINER_UTILS_DIR=/opt/utils
# The log level for the Python scripts
LOG_LEVEL=DEBUG
100 changes: 100 additions & 0 deletions dev-support/read-replica/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Stage 0: Cache Maven dependencies
ARG BASE_IMAGE=registry.access.redhat.com/ubi8/openjdk-17
FROM ${BASE_IMAGE} AS cache-stage

Check failure on line 3 in dev-support/read-replica/Dockerfile

View workflow job for this annotation

GitHub Actions / general-check

hadolint: DL3006 warning: Always tag the version of an image explicitly

USER root

Check failure on line 5 in dev-support/read-replica/Dockerfile

View workflow job for this annotation

GitHub Actions / general-check

hadolint: DL3002 warning: Last USER should not be root

# Install necessary packages for building Maven dependencies
RUN INITRD=no DEBIAN_FRONTEND=noninteractive microdnf update -y && microdnf install -y maven git hostname diffutils

# Copy the entire source code to cache dependencies
COPY ./hbase /opt/hbase-src

WORKDIR /opt/hbase-src

# Download and cache all dependencies
RUN mvn clean install -DskipTests -Dskip.license.check=true

# Stage 1: Build the HBase source code
FROM ${BASE_IMAGE} AS build-stage

Check failure on line 19 in dev-support/read-replica/Dockerfile

View workflow job for this annotation

GitHub Actions / general-check

hadolint: DL3006 warning: Always tag the version of an image explicitly

USER root

Check failure on line 21 in dev-support/read-replica/Dockerfile

View workflow job for this annotation

GitHub Actions / general-check

hadolint: DL3002 warning: Last USER should not be root

# Install necessary build packages
RUN INITRD=no DEBIAN_FRONTEND=noninteractive microdnf update -y && microdnf install -y maven git hostname diffutils

Check failure on line 24 in dev-support/read-replica/Dockerfile

View workflow job for this annotation

GitHub Actions / general-check

hadolint: DL3041 warning: Specify version with `dnf install -y <package>-<version>`.

Check failure on line 24 in dev-support/read-replica/Dockerfile

View workflow job for this annotation

GitHub Actions / general-check

hadolint: DL3040 warning: `dnf clean all` missing after dnf command.

# Copy the cached Maven dependencies
COPY --from=cache-stage /root/.m2 /root/.m2

# Copy the HBase source code
COPY ./hbase /opt/hbase-src

WORKDIR /opt/hbase-src

# Build HBase source code using cached dependencies and enable parallel build
RUN mvn clean package -DskipTests -Dskip.license.check=true assembly:single -T 1C

# Stage 2: Create the final Docker image
FROM ${BASE_IMAGE}

Check failure on line 38 in dev-support/read-replica/Dockerfile

View workflow job for this annotation

GitHub Actions / general-check

hadolint: DL3006 warning: Always tag the version of an image explicitly

USER root

# Set environment variables
ENV HBASE_HOME=/opt/hbase
ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk \
HBASE_USER=hbase \
HBASE_CONF_DIR=${HBASE_HOME}/conf \
HBASE_LIB_DIR=${HBASE_HOME}/lib \
HBASE_LOGS_DIR=${HBASE_HOME}/logs \
DATA_DIR=/data-store

# Install necessary runtime packages
RUN INITRD=no DEBIAN_FRONTEND=noninteractive microdnf update -y && microdnf install -y unzip gzip wget hostname maven git diffutils vim openssh-clients python3 procps

Check failure on line 52 in dev-support/read-replica/Dockerfile

View workflow job for this annotation

GitHub Actions / general-check

hadolint: DL3040 warning: `dnf clean all` missing after dnf command.

# Copy the built HBase binaries from the build-stage
COPY --from=build-stage /opt/hbase-src/hbase-assembly/target/hbase-4.0.0-alpha-1-SNAPSHOT-bin.tar.gz /opt/

# Extract HBase binaries
RUN tar -xzf /opt/hbase-4.0.0-alpha-1-SNAPSHOT-bin.tar.gz -C /opt \
&& ln -s /opt/hbase-4.0.0-alpha-1-SNAPSHOT /opt/hbase \
&& rm /opt/hbase-4.0.0-alpha-1-SNAPSHOT-bin.tar.gz

COPY --from=build-stage /root/.m2/repository/org/apache/hadoop/hadoop-mapreduce-client-common/*/hadoop-mapreduce-client-common-*.jar \
${HBASE_HOME}/lib/

# Apply custom HBase build steps
RUN sed -i "s,^. export JAVA_HOME.*,export JAVA_HOME=$JAVA_HOME," ${HBASE_CONF_DIR}/hbase-env.sh \
&& sed -E -i 's/(.*)hbase\-daemons\.sh(.*zookeeper)/\1hbase-daemon.sh\2/g' ${HBASE_HOME}/bin/start-hbase.sh \
&& echo -e "JAVA_HOME=$JAVA_HOME\nexport JAVA_HOME\nexport PATH=$JAVA_HOME/jre/bin:$PATH" > /etc/profile.d/defaults.sh \
&& ln -sf ${HBASE_HOME}/bin/* /usr/bin

# Create HBase user and home directory
RUN useradd -u 1000 -m ${HBASE_USER} \
&& mkdir -p /home/${HBASE_USER} \
&& chown -R ${HBASE_USER}:${HBASE_USER} /opt /home/${HBASE_USER} \
&& mkdir "$DATA_DIR" && chown -R ${HBASE_USER}:${HBASE_USER} "$DATA_DIR"

# Set permissions for jboss home directory
RUN chown -R ${HBASE_USER}:${HBASE_USER} /home/jboss

# Copy configuration files - Removed in order to mount config files individually #

# Expose required ports for HBase and related services
EXPOSE 8000 8080 8085 9090 9095 2181 16000 16010 16020 16030

# Set up the utils directory as a volume
VOLUME ["/opt/utils"]

# Switch to the HBase user
USER ${HBASE_USER}

# Create necessary directories for HBase to run
RUN mkdir -p "$DATA_DIR"/hbase "$DATA_DIR"/run "$DATA_DIR"/logs
RUN chmod -R 777 "$DATA_DIR"

# Add the 'ls -l' alias
RUN echo 'alias ll="ls -l"' >> /home/hbase/.bashrc
RUN echo 'alias ll="ls -l"' >> /home/jboss/.bashrc

# Start HBase and keep it running
ENTRYPOINT ["/bin/bash", "-c", "${HBASE_HOME}/bin/start-hbase.sh && tail -f ${HBASE_LOGS_DIR}/*.log"]
Loading
Loading