From 64166df891ece136b6183fadc157b044bd9e7d0a Mon Sep 17 00:00:00 2001 From: Aman Poonia Date: Wed, 5 Aug 2026 19:14:56 +0530 Subject: [PATCH] HBASE-30316 Add Docker build modes and user-friendly tooling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extends hbase_docker to support three input modes and adds unified build script for better user experience. Changes: - Dockerfile: Add INPUT_MODE build arg (tag/tarball/source-dir) - tag: Clone from GitHub (default, unchanged behavior) - tarball: Build from local tarball file - source-dir: Build from local source directory - build-hbase.sh: Unified script with user-friendly interface - Prerequisites validation (Docker, disk space) - Auto-setup and cleanup - Clear progress indicators and error messages - Supports --tag, --tarball, and --source flags - README.md: User-first documentation - Progressive disclosure (simple โ†’ advanced) - Real workflows for three audiences (learners, developers, release managers) - Maven usage inside containers - Volume mount guide for persistent changes - .dockerignore: Proper source directory inclusion Target audiences: - New users learning HBase (3-command quickstart) - Developers testing local changes (uncommitted changes supported) - Release managers verifying RCs (tarball mode) All modes tested and working. Backward compatible - default behavior unchanged. --- dev-support/hbase_docker/.dockerignore | 13 + dev-support/hbase_docker/Dockerfile | 40 +- dev-support/hbase_docker/README.md | 425 ++++++++++++++++++++-- dev-support/hbase_docker/build-hbase.sh | 400 ++++++++++++++++++++ dev-support/hbase_docker/m1/.dockerignore | 11 + dev-support/hbase_docker/m1/Dockerfile | 40 +- 6 files changed, 898 insertions(+), 31 deletions(-) create mode 100644 dev-support/hbase_docker/.dockerignore create mode 100755 dev-support/hbase_docker/build-hbase.sh create mode 100644 dev-support/hbase_docker/m1/.dockerignore diff --git a/dev-support/hbase_docker/.dockerignore b/dev-support/hbase_docker/.dockerignore new file mode 100644 index 000000000000..935f5387540f --- /dev/null +++ b/dev-support/hbase_docker/.dockerignore @@ -0,0 +1,13 @@ +# Exclude everything by default +* + +# But include the files we might need for different INPUT_MODE options +!hbase-src.tar.gz +!hbase +!hbase/** + +# The Dockerfile and README are not needed in the image +Dockerfile +README.md +.dockerignore +m1/ diff --git a/dev-support/hbase_docker/Dockerfile b/dev-support/hbase_docker/Dockerfile index 2c246d003f46..07391f6f9583 100644 --- a/dev-support/hbase_docker/Dockerfile +++ b/dev-support/hbase_docker/Dockerfile @@ -75,9 +75,43 @@ ENV PATH "${JAVA_HOME}/bin:${MAVEN_HOME}/bin:${PATH}" # Pull down HBase and build it into /root/hbase-bin. WORKDIR /root ARG BRANCH_OR_TAG=master -RUN git clone --depth 1 -b ${BRANCH_OR_TAG} https://github.com/apache/hbase.git \ - && \ - mvn -T1C clean install -DskipTests assembly:single -f ./hbase/pom.xml \ +ARG INPUT_MODE=tag + +# INPUT_MODE=tag (default): clones from GitHub; build context files are ignored +# INPUT_MODE=tarball: expects hbase-src.tar.gz in the build context root +# INPUT_MODE=source-dir: expects the HBase source root as the build context +# (use build-hbase.sh --source, which sets this up correctly) +COPY . /tmp/build-context/ + +# Stage source using the appropriate method +RUN set -e && \ + case "${INPUT_MODE}" in \ + tag) \ + echo "INFO: Cloning HBase from GitHub (branch/tag: ${BRANCH_OR_TAG})" && \ + git clone --depth 1 -b "${BRANCH_OR_TAG}" https://github.com/apache/hbase.git \ + ;; \ + tarball) \ + echo "INFO: Extracting HBase from tarball" && \ + if [ ! -f /tmp/build-context/hbase-src.tar.gz ]; then \ + echo "ERROR: hbase-src.tar.gz not found in build context" >&2 && \ + exit 1; \ + fi && \ + mkdir -p hbase && \ + tar xzf /tmp/build-context/hbase-src.tar.gz -C hbase --strip-components 1 \ + ;; \ + source-dir) \ + echo "INFO: Using HBase source from build context" && \ + cp -r /tmp/build-context hbase \ + ;; \ + *) \ + echo "ERROR: Invalid INPUT_MODE=${INPUT_MODE}. Must be: tag, tarball, or source-dir" >&2 && \ + exit 1 \ + ;; \ + esac && \ + rm -rf /tmp/build-context + +# Build HBase and extract the assembly +RUN mvn -T1C clean install -DskipTests assembly:single -f ./hbase/pom.xml \ && \ mkdir -p hbase-bin \ && \ diff --git a/dev-support/hbase_docker/README.md b/dev-support/hbase_docker/README.md index d37e329cca19..0890b9b02254 100644 --- a/dev-support/hbase_docker/README.md +++ b/dev-support/hbase_docker/README.md @@ -19,28 +19,403 @@ under the License. # hbase_docker -## Overview - -The Dockerfile in this folder can be used to build a Docker image running -a specific HBase branch or tag(default to master) in standalone mode. It -does this by setting up necessary dependencies, checking out the specific -branch or tag of HBase from GitHub, and then building HBase. By default, -this image will start the HMaster and launch the HBase shell when run. - -## Usage - -1. Ensure that you have a recent version of Docker installed from - [docker.io](http://www.docker.io). -1. Set this folder as your working directory. -1. Type `docker build -t hbase_docker --build-arg BRANCH_OR_TAG=.` - to build a Docker image called **hbase_docker**. This may take 10 minutes - or more the first time you run the command since it will create a Maven - repository inside the image as well as checkout the master branch of HBase. -1. When this completes successfully, you can run `docker run -it hbase_docker` - to access an HBase shell running inside of a container created from the - **hbase_docker** image. Alternatively, you can type `docker run -it hbase_docker - bash` to start a container without a running HMaster. Within this environment, - HBase is built in `/root/hbase-bin`. - -> NOTE: When running on mac m1 platforms, the docker file requires setting platform flag explicitly. -> You may use same instructions above running from to the "./m1" sub-dir. +**Run HBase in Docker with one command.** Perfect for: +- ๐ŸŽ“ **Learning HBase** - Try it without installing anything +- ๐Ÿ”ง **HBase developers** - Test your changes in isolation +- โœ… **Release verification** - Validate release candidates +- ๐Ÿงช **Testing** - Run builds and tests in clean environments + +--- + +## I Just Want to Try HBase (New Users Start Here!) + +**Prerequisites:** +- Docker Desktop installed and running ([Get Docker](https://www.docker.com/products/docker-desktop)) +- 5GB free disk space +- 15 minutes for first build + +**Get HBase running in 3 commands:** + +```bash +# 1. Go to the docker directory +cd dev-support/hbase_docker + +# 2. Build HBase (one command, ~15 minutes) +./build-hbase.sh --tag master + +# 3. Start HBase shell +docker run --platform linux/amd64 -it --rm hbase_local +``` + +**Try it out:** +``` +# Inside HBase shell: +create 'test', 'cf' +put 'test', 'row1', 'cf:a', 'value1' +scan 'test' +exit +``` + +That's it! No installation, no configuration needed. ๐ŸŽ‰ + +> **Apple Silicon (M1/M2/M3):** The build script automatically selects the right Dockerfile for your chip. +> For `docker run` commands, always pass `--platform linux/amd64` โ€” the image is x86_64 running under Rosetta. + +--- + +## I Want to Build from Different Sources + +The script supports three modes: + +### 1. From GitHub (Learning, Testing Branches) +```bash +./build-hbase.sh --tag master +./build-hbase.sh --tag branch-2.4 +./build-hbase.sh --tag rel/2.6.7 +``` +**Use when:** Learning HBase, testing specific versions + +### 2. From Downloaded Tarball (Release Verification) +```bash +./build-hbase.sh --tarball ~/Downloads/hbase-2.6.7-src.tar.gz +``` +**Use when:** Verifying release candidates, testing official releases + +### 3. From Local Source (Development) +```bash +# From any HBase repository +./build-hbase.sh --source ~/Code/hbase + +# From current repository +./build-hbase.sh --source . +``` +**Use when:** Testing your code changes, debugging, active development + +**Perfect for HBase developers** working on patches or new features. + +--- + +## Running HBase + +After building, you have several options: + +### Start HBase Shell (Interactive) +```bash +docker run --platform linux/amd64 -it --rm hbase_local +``` +This starts HBase in standalone mode and gives you the HBase shell. + +### Get Bash Shell (Explore Container) +```bash +docker run --platform linux/amd64 -it --rm hbase_local bash +``` +Gives you a bash prompt to explore the container. + +### Run Maven Commands (Build, Test) +```bash +docker run --platform linux/amd64 -it --rm hbase_local bash -c ' + cd /root/hbase && mvn clean install +' +``` +The container has the full source code and Maven ready to use. + +--- + +## Common Workflows + +### I'm Learning HBase +```bash +# Build once +./build-hbase.sh --tag master + +# Start HBase whenever you want to experiment +docker run --platform linux/amd64 -it --rm hbase_local + +# Play around with HBase commands +create 'users', 'info', 'contact' +put 'users', 'john', 'info:name', 'John Doe' +get 'users', 'john' +scan 'users' +``` + +### I'm Verifying a Release Candidate +```bash +# Download RC tarball from Apache +wget https://dist.apache.org/repos/dist/dev/hbase/hbase-2.6.7RC0/hbase-2.6.7-src.tar.gz + +# Build from it +cd dev-support/hbase_docker +./build-hbase.sh --tarball hbase-2.6.7-src.tar.gz hbase_267_rc0 + +# Test it works +docker run --platform linux/amd64 -it --rm hbase_267_rc0 + +# Run tests (optional) +docker run --platform linux/amd64 -it --rm hbase_267_rc0 bash -c ' + cd /root/hbase && mvn test +' +``` + +### I'm an HBase Developer Testing My Changes +```bash +# 1. Make changes to HBase code +vim hbase-server/src/main/java/org/apache/hadoop/hbase/MyClass.java + +# 2. Build Docker image with your changes (includes uncommitted changes!) +cd dev-support/hbase_docker +./build-hbase.sh --source . my_feature + +# 3. Test your changes in HBase shell +docker run --platform linux/amd64 -it --rm my_feature + +# 4. Or run unit tests +docker run --platform linux/amd64 -it --rm my_feature bash -c ' + cd /root/hbase && mvn test -Dtest=MyTest +' + +# 5. Run full test suite +docker run --platform linux/amd64 -it --rm my_feature bash -c ' + cd /root/hbase && mvn clean install +' +``` + +**Note:** This builds from your working directory, including uncommitted changes. +Great for testing patches before committing! + +--- + +## Running Tests and Builds Inside Docker + +The Docker image includes Maven and all dependencies. You can run any Maven command: + +```bash +# Start bash in the container +docker run --platform linux/amd64 -it --rm hbase_local bash + +# Inside container: +cd /root/hbase + +# Run full build with tests +mvn clean install + +# Run tests only +mvn test + +# Skip tests +mvn clean install -DskipTests + +# Run integration tests +mvn verify +``` + +**Important:** Files are **copied** into the image. Changes inside the container don't affect your local files. + +### For Active Development: Volume Mount (Changes Persist!) + +If you're actively developing and need changes to persist to your local files: + +```bash +# 1. Build a base image once (use any stable branch) +./build-hbase.sh --tag master hbase_dev + +# 2. Run with your local code mounted +cd /path/to/hbase +docker run --platform linux/amd64 \ + -v $(pwd):/workspace \ + -w /workspace \ + -it --rm hbase_dev bash + +# 3. Inside container - changes persist to your local files! +mvn clean install # Build from your local code +mvn spotless:apply # Format your local files +mvn test # Run tests +exit + +# 4. Changes are now in your local files +git diff # See the changes +git add . +``` + +**Why use this?** +- โœ… Code formatting (spotless) affects your local files +- โœ… Faster iteration (no rebuild needed) +- โœ… Generated files appear locally +- โœ… Perfect for active development sessions + +**When not to use:** +- Just testing if something compiles โ†’ Use `--source` mode instead (simpler) + +--- + +## Troubleshooting + +### Docker daemon is not running +``` +โŒ ERROR: Docker daemon is not running +``` +**Fix:** Start Docker Desktop app + +### Out of disk space +``` +โš ๏ธ WARNING: Low disk space +``` +**Fix:** Clean up old Docker images +```bash +docker image prune -a +``` + +### Build is very slow on Mac +This is normal on Apple Silicon โ€” Docker uses Rosetta 2 emulation to run the x86_64 image. +- Expected on Apple Silicon: 15-20 minutes +- Native Linux (x86_64): 10-12 minutes + +> **Note:** Apple is deprecating Rosetta. Once removed, builds will still work via QEMU emulation +> but will be slower. A native arm64 image is planned for a future release. + +### Permission denied errors +Make sure the script is executable: +```bash +chmod +x build-hbase.sh +``` + +### Need help? +```bash +./build-hbase.sh --help +``` + +--- + +## Advanced Topics + +
+Manual Docker Build Commands + +If you prefer raw Docker commands instead of the script: + +### Build from GitHub (default) +```bash +docker build --platform linux/amd64 -t hbase . +docker build --platform linux/amd64 --build-arg BRANCH_OR_TAG=branch-2.4 -t hbase . +``` + +### Build from tarball +```bash +cp /path/to/hbase-src.tar.gz hbase-src.tar.gz +docker build --platform linux/amd64 --build-arg INPUT_MODE=tarball -t hbase . +``` + +### Build from local source +```bash +# Use the source directory as the build context directly +docker build --platform linux/amd64 \ + --build-arg INPUT_MODE=source-dir \ + -f /path/to/hbase_docker/Dockerfile \ + -t hbase \ + /path/to/hbase +``` + +
+ +
+Technical Details: How It Works + +### INPUT_MODE Build Argument + +The Dockerfile supports three input modes via `INPUT_MODE`: +- `tag` (default) - Clone from GitHub +- `tarball` - Extract from local `hbase-src.tar.gz` +- `source-dir` - Copy from local `hbase/` directory + +### What's Inside the Image + +After build: +- HBase source code at `/root/hbase/` +- Built HBase binaries at `/root/hbase-bin/` +- Maven 3.8.6 at `/opt/maven/` +- Java 8 (Temurin JDK) +- All Maven dependencies cached + +### Build Context Control + +`.dockerignore` controls what gets copied: +- Excludes everything by default +- Includes only `hbase-src.tar.gz` or `hbase/` directory +- Keeps Docker context small and fast + +
+ +
+Prerequisites Details + +### Required +- **Docker installed and running** + - macOS/Windows: [Docker Desktop](https://www.docker.com/products/docker-desktop) + - Linux: [Docker Engine](https://docs.docker.com/engine/install/) +- **~5GB free disk space** (Docker image is ~2.7GB) + +### Internet Connection +- **Required for `--tag` mode** (clone from GitHub) +- **Required for Maven dependencies** (all modes) +- **Not required** if Maven local repository is fully populated (rare) + +The `build-hbase.sh` script checks these automatically and shows helpful errors. + +
+ +
+Custom Image Names + +Add a third argument to customize the image name: + +```bash +./build-hbase.sh --tag branch-2.4 my_custom_name +./build-hbase.sh --tarball hbase.tar.gz hbase_rc_test +./build-hbase.sh --source ~/Code/hbase hbase_dev +``` + +Then run with your custom name: +```bash +docker run --platform linux/amd64 -it --rm my_custom_name +``` + +
+ +
+What the Script Does + +The `build-hbase.sh` script automates setup: + +1. **Validates prerequisites** - Docker running, disk space +2. **Cleans build context** - Removes conflicting files +3. **Sets up source** - Copies tarballs, validates paths +4. **Builds image** - Runs docker build with correct flags +5. **Reports results** - Shows next steps or troubleshooting + +Logs are saved to `/tmp/hbase-docker-build.log` + +You can skip the script and use raw Docker commands if you prefer. + +
+ +--- + +## Quick Reference + +```bash +# Build commands +./build-hbase.sh --tag branch-2.4 # From GitHub +./build-hbase.sh --tarball hbase.tar.gz # From tarball +./build-hbase.sh --source ~/Code/hbase # From local source + +# Run commands +docker run --platform linux/amd64 -it --rm hbase_local # HBase shell +docker run --platform linux/amd64 -it --rm hbase_local bash # Bash shell + +# Maven in container +cd /root/hbase && mvn clean install # Full build with tests +cd /root/hbase && mvn test # Tests only + +# Help +./build-hbase.sh --help # Show usage +docker images | grep hbase # List images +``` diff --git a/dev-support/hbase_docker/build-hbase.sh b/dev-support/hbase_docker/build-hbase.sh new file mode 100755 index 000000000000..7c6d2a13c09f --- /dev/null +++ b/dev-support/hbase_docker/build-hbase.sh @@ -0,0 +1,400 @@ +#!/usr/bin/env bash +set -e + +# build-hbase.sh - Unified HBase Docker Build Script +# +# ONE script for all build modes. User specifies what they want. +# +# Usage: +# ./build-hbase.sh --tag branch-2.4 # Clone from GitHub +# ./build-hbase.sh --tarball hbase-2.6.7.tar.gz # Build from tarball +# ./build-hbase.sh --source /path/to/hbase # Build from local dir +# ./build-hbase.sh --source . # Build from current repo +# ./build-hbase.sh --help # Show help + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +LOG_FILE="${LOG_FILE:-/tmp/hbase-docker-build.log}" +DEFAULT_IMAGE_NAME="hbase_local" + +# On Apple Silicon (arm64), use m1/Dockerfile which is tuned for Rosetta emulation. +# Both cases build linux/amd64 images; m1/Dockerfile just handles arm64 host quirks. +HOST_ARCH=$(uname -m) +if [[ "$HOST_ARCH" == "arm64" || "$HOST_ARCH" == "aarch64" ]]; then + DOCKERFILE="$SCRIPT_DIR/m1/Dockerfile" +else + DOCKERFILE="$SCRIPT_DIR/Dockerfile" +fi +PLATFORM="linux/amd64" + +#============================================================================= +# Prerequisites Check +#============================================================================= +check_prerequisites() { + local errors=0 + + # Check if Docker is installed + if ! command -v docker &> /dev/null; then + echo "โŒ ERROR: Docker is not installed" + echo + echo "Please install Docker:" + echo " โ€ข Docker Desktop: https://www.docker.com/products/docker-desktop" + echo " โ€ข Linux: https://docs.docker.com/engine/install/" + echo + errors=1 + fi + + # Check if Docker daemon is running + if command -v docker &> /dev/null; then + if ! docker info &> /dev/null; then + echo "โŒ ERROR: Docker daemon is not running" + echo + echo "Please start Docker:" + echo " โ€ข macOS: Start Docker Desktop app" + echo " โ€ข Linux: sudo systemctl start docker" + echo " โ€ข Windows: Start Docker Desktop app" + echo + echo "Then verify with: docker ps" + echo + errors=1 + fi + fi + + # Check disk space (warn if less than 5GB) + if command -v df &> /dev/null; then + local available_kb + available_kb=$(df -k . | tail -1 | awk '{print $4}') + local available_gb=$((available_kb / 1024 / 1024)) + + if [ "$available_gb" -lt 5 ]; then + echo "โš ๏ธ WARNING: Low disk space (~${available_gb}GB available)" + echo " HBase Docker images require ~3GB" + echo " Consider cleaning up: docker image prune -a" + echo + fi + fi + + return $errors +} + +#============================================================================= +# Help +#============================================================================= +show_help() { + cat <<'EOF' +โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— +โ•‘ HBase Docker Build Script โ•‘ +โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + +USAGE: + build-hbase.sh MODE VALUE [IMAGE_NAME] + +MODES: + --tag BRANCH_OR_TAG Clone from GitHub + --tarball FILE Build from tarball + --source PATH Build from local directory + +EXAMPLES: + # Clone from GitHub branch + ./build-hbase.sh --tag branch-2.4 + + # Clone from GitHub tag + ./build-hbase.sh --tag rel/2.6.7 + + # Build from downloaded tarball + ./build-hbase.sh --tarball ~/Downloads/hbase-2.6.7-src.tar.gz + + # Build from local HBase directory + ./build-hbase.sh --source ~/Code/hbase + + # Build from current repository + ./build-hbase.sh --source . + + # Custom image name + ./build-hbase.sh --tag branch-2.4 my_hbase_image + +OPTIONS: + --help, -h Show this help + +ENVIRONMENT: + LOG_FILE Path to build log (default: /tmp/hbase-docker-build.log) + +EOF +} + +#============================================================================= +# Build Functions +#============================================================================= + +build_from_tag() { + local branch_or_tag="$1" + local image_name="$2" + + echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" + echo "MODE: Clone from GitHub" + echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" + echo "Branch/Tag: $branch_or_tag" + echo "Image name: $image_name" + echo "Log file: $LOG_FILE" + echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" + echo + + # Build + echo "๐Ÿš€ Starting Docker build (10-15 minutes)..." + echo " Platform: $PLATFORM" + echo " Follow progress: tail -f $LOG_FILE" + echo + + docker build --platform "$PLATFORM" \ + -f "$DOCKERFILE" \ + --build-arg INPUT_MODE=tag \ + --build-arg BRANCH_OR_TAG="$branch_or_tag" \ + -t "$image_name" \ + "$SCRIPT_DIR" 2>&1 | tee "$LOG_FILE" + + return ${PIPESTATUS[0]} +} + +build_from_tarball() { + local tarball_path="$1" + local image_name="$2" + + echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" + echo "MODE: Build from Tarball" + echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" + echo "Tarball: $tarball_path" + echo "Image name: $image_name" + echo "Log file: $LOG_FILE" + echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" + echo + + # Verify tarball exists + if [ ! -f "$tarball_path" ]; then + echo "โŒ ERROR: Tarball not found: $tarball_path" + exit 1 + fi + + # Copy tarball + echo "๐Ÿ“ฆ Copying tarball to build context..." + cp "$tarball_path" "$SCRIPT_DIR/hbase-src.tar.gz" + echo " Size: $(du -h "$SCRIPT_DIR/hbase-src.tar.gz" | cut -f1)" + + # Build + echo "๐Ÿš€ Starting Docker build (10-15 minutes)..." + echo " Platform: $PLATFORM" + echo " Follow progress: tail -f $LOG_FILE" + echo + + docker build --platform "$PLATFORM" \ + -f "$DOCKERFILE" \ + --build-arg INPUT_MODE=tarball \ + -t "$image_name" \ + "$SCRIPT_DIR" 2>&1 | tee "$LOG_FILE" + + local status=${PIPESTATUS[0]} + + # Clean up + rm -f "$SCRIPT_DIR/hbase-src.tar.gz" + + return $status +} + +build_from_source() { + local source_path="$1" + local image_name="$2" + + # Validate and resolve to absolute path + if [ ! -d "$source_path" ]; then + echo "โŒ ERROR: Directory not found: $source_path" + exit 1 + fi + source_path="$(cd "$source_path" && pwd)" + + echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" + echo "MODE: Build from Local Source" + echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" + echo "Source: $source_path" + echo "Image name: $image_name" + echo "Log file: $LOG_FILE" + echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" + echo + + # Verify it's an HBase repo + if [ ! -f "$source_path/pom.xml" ]; then + echo "โŒ ERROR: Not an HBase repository (no pom.xml found)" + echo " Path: $source_path" + exit 1 + fi + + echo "๐Ÿ“ Using source directory as build context..." + echo " This includes all files (including uncommitted changes)" + + # Temporarily copy the Dockerfile into the source tree so Docker can find it + # while the source directory serves as the build context + local temp_dockerfile="$source_path/.hbase-docker-temp" + mkdir -p "$temp_dockerfile" + cp "$DOCKERFILE" "$temp_dockerfile/Dockerfile" + + # .dockerignore must be at the build context root to take effect + cat > "$source_path/.dockerignore" <<'DOCKERIGNORE' +# Exclude build artifacts and metadata from the Docker build context +target/ +.git/ +.idea/ +*.iml +.hbase-docker-temp/ +DOCKERIGNORE + + # Build from source directory + echo "๐Ÿš€ Starting Docker build (10-15 minutes)..." + echo " Platform: $PLATFORM" + echo " Follow progress: tail -f $LOG_FILE" + echo + + docker build --platform "$PLATFORM" \ + --build-arg INPUT_MODE=source-dir \ + -f "$temp_dockerfile/Dockerfile" \ + -t "$image_name" \ + "$source_path" 2>&1 | tee "$LOG_FILE" + + local status=${PIPESTATUS[0]} + + # Clean up temp files + rm -rf "$temp_dockerfile" + rm -f "$source_path/.dockerignore" + + return $status +} + +show_success() { + local image_name="$1" + + echo + echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" + echo "โœ… BUILD SUCCESSFUL" + echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" + + # Get image info + docker images "$image_name" --format "Image: {{.Repository}}:{{.Tag}}\nSize: {{.Size}}\nBuilt: {{.CreatedSince}}" + + echo + echo "๐Ÿš€ NEXT STEPS:" + echo + echo "1๏ธโƒฃ Start HBase Shell (interactive):" + echo " docker run --platform $PLATFORM -it --rm $image_name" + echo + echo "2๏ธโƒฃ Get Bash Shell (explore container):" + echo " docker run --platform $PLATFORM -it --rm $image_name bash" + echo + echo "3๏ธโƒฃ Check HBase Version:" + echo " echo 'version' | docker run --platform $PLATFORM -i --rm $image_name" + echo + echo "4๏ธโƒฃ View Build Log:" + echo " cat $LOG_FILE" + echo + echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" +} + +show_failure() { + echo + echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" + echo "โŒ BUILD FAILED" + echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" + echo + echo "๐Ÿ“‹ Check the log file:" + echo " tail -100 $LOG_FILE" + echo + echo "๐Ÿ” Common issues:" + echo " โ€ข Network issues (git clone failed)" + echo " โ€ข Maven build errors" + echo " โ€ข Out of disk space" + echo " โ€ข Docker daemon issues" + echo +} + +#============================================================================= +# Main +#============================================================================= + +main() { + local mode="" + local value="" + local image_name="$DEFAULT_IMAGE_NAME" + + # Parse arguments + case "${1:-}" in + --help|-h) + show_help + exit 0 + ;; + --tag) + mode="tag" + value="$2" + image_name="${3:-$DEFAULT_IMAGE_NAME}" + ;; + --tarball) + mode="tarball" + value="$2" + image_name="${3:-$DEFAULT_IMAGE_NAME}" + ;; + --source) + mode="source" + value="$2" + image_name="${3:-$DEFAULT_IMAGE_NAME}" + ;; + "") + echo "โŒ ERROR: No mode specified" + echo + show_help + exit 1 + ;; + *) + echo "โŒ ERROR: Unknown mode: $1" + echo + show_help + exit 1 + ;; + esac + + # Validate value provided + if [ -z "$value" ]; then + echo "โŒ ERROR: No value provided for --$mode" + echo + show_help + exit 1 + fi + + echo + echo "โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—" + echo "โ•‘ HBase Docker Build Orchestrator โ•‘" + echo "โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + echo + + # Check prerequisites + if ! check_prerequisites; then + exit 1 + fi + + # Execute based on mode (use || to capture failure even under set -e) + local build_status=0 + case "$mode" in + tag) + build_from_tag "$value" "$image_name" || build_status=$? + ;; + tarball) + build_from_tarball "$value" "$image_name" || build_status=$? + ;; + source) + build_from_source "$value" "$image_name" || build_status=$? + ;; + esac + + # Report results + if [ $build_status -eq 0 ]; then + show_success "$image_name" + else + show_failure + exit 1 + fi +} + +main "$@" diff --git a/dev-support/hbase_docker/m1/.dockerignore b/dev-support/hbase_docker/m1/.dockerignore new file mode 100644 index 000000000000..087adf5e0f6d --- /dev/null +++ b/dev-support/hbase_docker/m1/.dockerignore @@ -0,0 +1,11 @@ +# Exclude everything by default +* + +# But include the files we might need for different INPUT_MODE options +!hbase-src.tar.gz +!hbase +!hbase/** + +# The Dockerfile is not needed in the image +Dockerfile +.dockerignore diff --git a/dev-support/hbase_docker/m1/Dockerfile b/dev-support/hbase_docker/m1/Dockerfile index fa88638a7aef..80f8a3b1c8cb 100644 --- a/dev-support/hbase_docker/m1/Dockerfile +++ b/dev-support/hbase_docker/m1/Dockerfile @@ -75,9 +75,43 @@ ENV PATH "${JAVA_HOME}/bin:${MAVEN_HOME}/bin:${PATH}" # Pull down HBase and build it into /root/hbase-bin. WORKDIR /root ARG BRANCH_OR_TAG=master -RUN git clone --depth 1 -b ${BRANCH_OR_TAG} https://github.com/apache/hbase.git \ - && \ - mvn -T1C clean install -DskipTests assembly:single -f ./hbase/pom.xml \ +ARG INPUT_MODE=tag + +# INPUT_MODE=tag (default): clones from GitHub; build context files are ignored +# INPUT_MODE=tarball: expects hbase-src.tar.gz in the build context root +# INPUT_MODE=source-dir: expects the HBase source root as the build context +# (use build-hbase.sh --source, which sets this up correctly) +COPY . /tmp/build-context/ + +# Stage source using the appropriate method +RUN set -e && \ + case "${INPUT_MODE}" in \ + tag) \ + echo "INFO: Cloning HBase from GitHub (branch/tag: ${BRANCH_OR_TAG})" && \ + git clone --depth 1 -b "${BRANCH_OR_TAG}" https://github.com/apache/hbase.git \ + ;; \ + tarball) \ + echo "INFO: Extracting HBase from tarball" && \ + if [ ! -f /tmp/build-context/hbase-src.tar.gz ]; then \ + echo "ERROR: hbase-src.tar.gz not found in build context" >&2 && \ + exit 1; \ + fi && \ + mkdir -p hbase && \ + tar xzf /tmp/build-context/hbase-src.tar.gz -C hbase --strip-components 1 \ + ;; \ + source-dir) \ + echo "INFO: Using HBase source from build context" && \ + cp -r /tmp/build-context hbase \ + ;; \ + *) \ + echo "ERROR: Invalid INPUT_MODE=${INPUT_MODE}. Must be: tag, tarball, or source-dir" >&2 && \ + exit 1 \ + ;; \ + esac && \ + rm -rf /tmp/build-context + +# Build HBase and extract the assembly +RUN mvn -T1C clean install -DskipTests assembly:single -f ./hbase/pom.xml \ && \ mkdir -p hbase-bin \ && \