blob: 5914f8baebc20fefad9f15a4020dffdcc9ac4437 [file] [log] [blame]
#!/bin/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.
################################################################################
#
# Mini cluster test binaries
# -------------------------
#
# This script generates optimized, dynamically-linked, stripped, fully
# relocatable Kudu server binaries for easy use by integration tests using a
# mini cluster. The resulting binaries should never be deployed to run an
# actual Kudu service, whether in production or development, because all
# security dependencies are copied from the build system and will not be
# updated if the operating system on the runtime host is patched.
#
# Properties file
# ---------------
#
# The JAR that is generated contains a properties file in META-INF that allows
# it to be located by Java code at runtime if the JAR is on the classpath.
# The location of that file in the archive is:
#
# META-INF/apache-kudu-test-binary.properties
#
# The following properties are supported:
#
# * format.version: The format of the artifact, in case we need to extend it
# later and be able to tell the difference between the archive formats.
# * artifact.version: The version of the release (or snapshot, i.e.
# 1.9.0-SNAPSHOT) in order for the format to support support multiple
# versions on the classpath or to allow a client to be able to request a
# specific release version.
# * artifact.prefix: The directory name at the root of the JAR under which the
# binary files can be found (similar to ./configure --prefix in autoconf).
# * artifact.os: The operating system name using the same convention as
# https://github.com/trustin/os-maven-plugin for ${os.detected.name}.
# Practically speaking for Kudu at the time of writing, that is either
# 'linux' or 'osx'.
# * artifact.arch: The target system architecture using the same convention as
# os-maven-plugin for ${os.detected.arch}. Practically speaking for Kudu, at
# the time of writing this will always be set to x86_64.
#
# Example:
#
# $ cat META-INF/apache-kudu-test-binary.properties
# format.version=1
# artifact.version=1.8.0
# artifact.prefix=kudu-binary-1.8.0-linux-x86_64
# artifact.os=linux
# artifact.arch=x86_64
#
################################################################################
set -e
SOURCE_ROOT=$(cd $(dirname $0)/../..; pwd)
BUILD_ROOT=$SOURCE_ROOT/build/mini-cluster
MINI_CLUSTER_SRCDIR=$SOURCE_ROOT/build-support/mini-cluster
TARGETS="kudu kudu-tserver kudu-master"
# Remove leftovers from previous releases/builds: rename the existing directory.
# To skip this step, set the MINI_CLUSTER_NO_FRESH_BUILD environment variable.
if [ -d "$BUILD_ROOT" ]; then
if [ -n "$MINI_CLUSTER_NO_FRESH_BUILD" ]; then
echo "WARNING: using existing build directory"
else
suffix=$(date "+%Y%m%d.%H%M%S")
echo "Moving existing $BUILD_ROOT into $BUILD_ROOT.$suffix"
mv $BUILD_ROOT $BUILD_ROOT.$suffix
fi
fi
THIRDPARTY_DIR=${THIRDPARTY_DIR:-$SOURCE_ROOT/thirdparty}
cd $SOURCE_ROOT
if [ -n "$NO_REBUILD_THIRDPARTY" ]; then
echo Skipping thirdparty because NO_REBUILD_THIRDPARTY is not empty
else
echo Building thirdparty... >&2
$SOURCE_ROOT/build-support/enable_devtoolset.sh \
$THIRDPARTY_DIR/build-if-necessary.sh
fi
mkdir -p $BUILD_ROOT
cd $BUILD_ROOT
MACOS=""
# TODO(mpercy): What's a better way to detect macOS?
if [ $(uname) == "Darwin" ]; then
MACOS=1
fi
EXTRA_CMAKE_FLAGS=""
if [ -n "$MACOS" ]; then
# TODO(mpercy): Consider using pkg-config to support building with MacPorts.
EXTRA_CMAKE_FLAGS="$EXTRA_CMAKE_FLAGS -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl"
# TODO(mpercy): Is it even possible to build Kudu with gcc/g++ on macOS?
export CC=clang
export CXX=clang++
fi
rm -rf CMakeCache.txt CMakeFiles
# We want a fast build with a small total output size, so we need to build in
# release mode with dynamic linking so that all of the target executables can
# use the same shared objects for their dependencies. Since we may not
# distribute chronyc/chronyd in kudu-binaries JAR due to licensing restrictions,
# the test harness is built to not rely on chronyd as NTP server for tests run
# with the mini-cluster.
echo Configuring Kudu... >&2
$SOURCE_ROOT/build-support/enable_devtoolset.sh \
$THIRDPARTY_DIR/installed/common/bin/cmake ../.. \
-DNO_TESTS=1 -DNO_CHRONY=1 \
-DCMAKE_BUILD_TYPE=RELEASE -DKUDU_LINK=dynamic $EXTRA_CMAKE_FLAGS
echo Building Kudu... >&2
NUM_PROCS=$(getconf _NPROCESSORS_ONLN)
make -j$NUM_PROCS $TARGETS
# Relocate the binaries.
$MINI_CLUSTER_SRCDIR/relocate_binaries_for_mini_cluster.py $BUILD_ROOT $TARGETS
ARTIFACT_NAME="$(ls -dF kudu-binary-* | egrep '.*/$' | sed 's#/##')"
if [ $(echo $ARTIFACT_NAME | wc -w) -ne 1 ]; then
echo "ERROR: this script can handle only single kudu-binary artifact, but"
echo " multiple kudu-binary-* directories found under $BUILD_ROOT:"
echo " $ARTIFACT_NAME"
echo " Remove extra kudu-binary-* directories"
exit 1
fi
# Strip everything to minimize the size of the tarball we generate.
echo Stripping symbols...
for file in $ARTIFACT_NAME/bin/*; do
strip $file
done
# Stripping libraries on macOS is tricky, so skip it for now.
# TODO(mpercy): Deal with detecting signed libraries and indirect symbol table
# entries on macOS.
if [ -z "$MACOS" ]; then
find $ARTIFACT_NAME/lib -type f -exec strip {} \;
fi
# Generate the properties file that allows us to find this archive on the
# classpath at runtime. See above for the specification.
PROP_DIR="META-INF"
PROP_FILE="$PROP_DIR/apache-kudu-test-binary.properties"
FORMAT_VERSION=1
ARTIFACT_VERSION=$(cat $SOURCE_ROOT/version.txt)
ARTIFACT_OS="linux"
if [ $MACOS ]; then
ARTIFACT_OS="osx"
fi
ARTIFACT_ARCH=$(uname -m)
rm -rf $PROP_DIR
mkdir -p $PROP_DIR
cat <<EOF > $PROP_FILE
format.version=$FORMAT_VERSION
artifact.os=$ARTIFACT_OS
artifact.arch=$ARTIFACT_ARCH
artifact.prefix=$ARTIFACT_NAME
artifact.version=$ARTIFACT_VERSION
EOF
# Include the basic legal files.
# Create a platform-specific NOTICE file.
JAR_NOTICE=$MINI_CLUSTER_SRCDIR/NOTICE-BINARY-JAR-LINUX.txt
if [ $MACOS ]; then
JAR_NOTICE=$MINI_CLUSTER_SRCDIR/NOTICE-BINARY-JAR-OSX.txt
fi
cat $SOURCE_ROOT/NOTICE.txt \
$JAR_NOTICE \
> $ARTIFACT_NAME/NOTICE.txt
# Create a platform-specific LICENSE file.
JAR_LICENSE=$MINI_CLUSTER_SRCDIR/LICENSE-BINARY-JAR-LINUX.txt
if [ $MACOS ]; then
JAR_LICENSE=$MINI_CLUSTER_SRCDIR/LICENSE-BINARY-JAR-OSX.txt
fi
cat $SOURCE_ROOT/LICENSE.txt \
$THIRDPARTY_DIR/LICENSE.txt \
$JAR_LICENSE \
> $ARTIFACT_NAME/LICENSE.txt
# Include the web UI template files.
cp -Rp $SOURCE_ROOT/www $ARTIFACT_NAME/
# Include a basic warning.
cat <<EOF > $ARTIFACT_NAME/README.txt
This archive contains Kudu binaries for use in a "mini cluster" environment for
TESTING ONLY.
The binaries in this archive should never be deployed to run an actual Kudu
service, whether in production or development, because many security-related
dependencies are copied from the build system and will not be patched when the
operating system on the runtime host is patched.
EOF
echo "Running license check on artifact..."
$SOURCE_ROOT/build-support/mini-cluster/check-license.pl $ARTIFACT_NAME
echo Creating archive...
ARTIFACT_FILE=$ARTIFACT_NAME.jar
jar cf $ARTIFACT_FILE $PROP_DIR/ $ARTIFACT_NAME/
echo "Binary test artifact: $(pwd)/$ARTIFACT_FILE"