mirror of
https://github.com/gravitational/teleport
synced 2024-10-22 02:03:24 +00:00
389 lines
13 KiB
Bash
Executable file
389 lines
13 KiB
Bash
Executable file
#!/bin/bash
|
|
set -e
|
|
|
|
usage() { echo "Usage: $(basename $0) [-t <oss/ent>] [-v <version>] [-p <package type>] <-a [amd64/x86_64]|[386/i386]> <-r go1.9.7|fips> <-s tarball source dir> <-m tsh>" 1>&2; exit 1; }
|
|
while getopts ":t:v:p:a:r:s:m:" o; do
|
|
case "${o}" in
|
|
t)
|
|
t=${OPTARG}
|
|
if [[ ${t} != "oss" && ${t} != "ent" ]]; then usage; fi
|
|
;;
|
|
v)
|
|
v=${OPTARG}
|
|
;;
|
|
p)
|
|
p=${OPTARG}
|
|
if [[ ${p} != "rpm" && ${p} != "deb" && ${p} != "pkg" ]]; then usage; fi
|
|
;;
|
|
a)
|
|
a=${OPTARG}
|
|
if [[ ${a} != "amd64" && ${a} != "x86_64" && ${a} != "386" && ${a} != "i386" ]]; then usage; fi
|
|
;;
|
|
r)
|
|
r=${OPTARG}
|
|
if [[ ${r} != "go1.9.7" && ${r} != "fips" ]]; then usage; fi
|
|
;;
|
|
s)
|
|
s=${OPTARG}
|
|
;;
|
|
m)
|
|
m=${OPTARG}
|
|
if [[ ${m} != "tsh" ]]; then usage; fi
|
|
;;
|
|
*)
|
|
usage
|
|
;;
|
|
esac
|
|
done
|
|
shift $((OPTIND-1))
|
|
|
|
if [ -z "${t}" ] || [ -z "${v}" ] || [ -z "${p}" ]; then
|
|
usage
|
|
fi
|
|
|
|
TELEPORT_TYPE=${t}
|
|
TELEPORT_VERSION=${v}
|
|
PACKAGE_TYPE=${p}
|
|
ARCH=${a}
|
|
RUNTIME=${r}
|
|
BUILD_MODE=${m}
|
|
TARBALL_DIRECTORY=/tmp/teleport-tarballs
|
|
DOWNLOAD_IF_NEEDED=true
|
|
if [[ "${s}" != "" ]]; then
|
|
DOWNLOAD_IF_NEEDED=false
|
|
TARBALL_DIRECTORY=${s}
|
|
fi
|
|
|
|
# linux package configuration
|
|
LINUX_BINARY_DIR=/usr/local/bin
|
|
LINUX_SYSTEMD_DIR=/lib/systemd/system
|
|
LINUX_CONFIG_DIR=/etc
|
|
LINUX_DATA_DIR=/var/lib/teleport
|
|
|
|
# extra package information for linux
|
|
MAINTAINER="info@gravitational.com"
|
|
LICENSE="Apache-2.0"
|
|
VENDOR="Gravitational"
|
|
DESCRIPTION="Gravitational Teleport is a gateway for managing access to clusters of Linux servers via SSH or the Kubernetes API"
|
|
DOCS_URL="https://gravitational.com/teleport/docs"
|
|
|
|
# signing IDs to use for mac (must be pre-loaded into the keychain on the build box)
|
|
DEVELOPER_ID_APPLICATION="Developer ID Application: Gravitational Inc." # used for signing binaries
|
|
DEVELOPER_ID_INSTALLER="Developer ID Installer: Gravitational Inc." # used for signing packages
|
|
|
|
# download root for packages
|
|
DOWNLOAD_ROOT="https://get.gravitational.com"
|
|
|
|
# check that curl is installed
|
|
if [ ! $(command -v curl) ]; then
|
|
echo "curl must be installed"
|
|
exit 2
|
|
fi
|
|
|
|
# check that docker is installed when fpm is needed to build
|
|
if [[ "${PACKAGE_TYPE}" != "pkg" ]]; then
|
|
if [ ! $(command -v docker) ]; then
|
|
echo "docker must be installed to build non-OSX packages"
|
|
exit 3
|
|
fi
|
|
fi
|
|
|
|
# check that pkgbuild is installed if building for OS X and set variables appropriately
|
|
if [[ "${PACKAGE_TYPE}" == "pkg" ]]; then
|
|
if ! uname | grep -q Darwin; then
|
|
echo "You must be running on OS X to build .pkg files"
|
|
exit 4
|
|
fi
|
|
if [[ "${ARCH}" != "" ]]; then
|
|
echo "arch parameter is ignored when building for OS X"
|
|
unset ARCH
|
|
fi
|
|
if [[ "${RUNTIME}" != "" ]]; then
|
|
echo "runtime parameter is ignored when building for OS X"
|
|
unset RUNTIME
|
|
fi
|
|
PLATFORM="darwin"
|
|
ARCH="amd64"
|
|
if [ ! $(command -v pkgbuild) ]; then
|
|
echo "You need to install pkgbuild"
|
|
echo "Run: xcode-select --install"
|
|
exit 5
|
|
fi
|
|
|
|
if [[ "${BUILD_MODE}" == "tsh" ]]; then
|
|
if [ ! $(command -v codesign) ]; then
|
|
echo "You need to install codesign"
|
|
echo "Run: xcode-select --install or sudo xcode-select --reset"
|
|
exit 6
|
|
fi
|
|
|
|
if [ ! $(command -v productsign) ]; then
|
|
echo "You need to install productsign"
|
|
echo "Run: xcode-select --install or sudo xcode-select --reset"
|
|
exit 7
|
|
fi
|
|
|
|
if [ ! $(command -v gon) ]; then
|
|
echo "You need to install gon"
|
|
echo "Install a binary from https://github.com/mitchellh/gon and make sure it's present in the system PATH"
|
|
exit 8
|
|
fi
|
|
|
|
if [[ "${APPLE_USERNAME}" == "" ]]; then
|
|
echo "The APPLE_USERNAME environment variable needs to be set to the email address of the Apple user which will submit the notarization request"
|
|
exit 9
|
|
fi
|
|
|
|
if [[ "${APPLE_PASSWORD}" == "" ]]; then
|
|
echo "The APPLE_PASSWORD environment variable needs to be set to the password matching the email address of the Apple user which will submit the notarization request"
|
|
exit 10
|
|
fi
|
|
fi
|
|
else
|
|
PLATFORM="linux"
|
|
# if arch isn't set for other package types, throw an error
|
|
if [[ "${ARCH}" == "" ]]; then
|
|
usage
|
|
fi
|
|
|
|
# set docker image appropriately
|
|
if [[ "${PACKAGE_TYPE}" == "deb" ]]; then
|
|
DOCKER_IMAGE="cdrx/fpm-debian:8"
|
|
elif [[ "${PACKAGE_TYPE}" == "rpm" ]]; then
|
|
DOCKER_IMAGE="cdrx/fpm-centos:7"
|
|
fi
|
|
|
|
# if client-only build is requested for a non-Mac platform, unset it
|
|
if [[ "${BUILD_MODE}" == "tsh" ]]; then
|
|
echo "Client-only builds are only offered for Mac"
|
|
unset BUILD_MODE
|
|
fi
|
|
fi
|
|
|
|
# handle differences between 'gravitational' arch and system arch
|
|
FILENAME_ARCH=${ARCH}
|
|
if [[ "${ARCH}" == "i386" ]]; then
|
|
FILENAME_ARCH="386"
|
|
TEXT_ARCH="32-bit"
|
|
elif [[ "${ARCH}" == "386" ]]; then
|
|
ARCH="i386"
|
|
TEXT_ARCH="32-bit"
|
|
elif [[ "${ARCH}" == "x86_64" ]]; then
|
|
FILENAME_ARCH="amd64"
|
|
if [[ "${PACKAGE_TYPE}" == "rpm" ]]; then
|
|
ARCH="x86_64"
|
|
fi
|
|
TEXT_ARCH="64-bit"
|
|
elif [[ "${ARCH}" == "amd64" ]]; then
|
|
if [[ "${PACKAGE_TYPE}" == "rpm" ]]; then
|
|
ARCH="x86_64"
|
|
fi
|
|
TEXT_ARCH="64-bit"
|
|
fi
|
|
|
|
# set optional runtime section for filename
|
|
if [[ "${RUNTIME}" == "go1.9.7" ]]; then
|
|
OPTIONAL_RUNTIME_SECTION="-go1.9.7"
|
|
elif [[ "${RUNTIME}" == "fips" ]]; then
|
|
OPTIONAL_RUNTIME_SECTION="-fips"
|
|
fi
|
|
|
|
# set variables appropriately depending on type of package being built
|
|
if [[ "${TELEPORT_TYPE}" == "ent" ]]; then
|
|
TARBALL_FILENAME="teleport-ent-v${TELEPORT_VERSION}-${PLATFORM}-${FILENAME_ARCH}${OPTIONAL_RUNTIME_SECTION}-bin.tar.gz"
|
|
URL="${DOWNLOAD_ROOT}/${TARBALL_FILENAME}"
|
|
TAR_PATH="teleport-ent"
|
|
if [[ "${RUNTIME}" == "go1.9.7" ]]; then
|
|
TYPE_DESCRIPTION="[${TEXT_ARCH} Enterprise edition, built with Go 1.9.7]"
|
|
elif [[ "${RUNTIME}" == "fips" ]]; then
|
|
TYPE_DESCRIPTION="[${TEXT_ARCH} Enterprise edition, built with FIPS support]"
|
|
else
|
|
TYPE_DESCRIPTION="[${TEXT_ARCH} Enterprise edition]"
|
|
fi
|
|
else
|
|
TARBALL_FILENAME="teleport-v${TELEPORT_VERSION}-${PLATFORM}-${FILENAME_ARCH}${OPTIONAL_RUNTIME_SECTION}-bin.tar.gz"
|
|
URL="${DOWNLOAD_ROOT}/${TARBALL_FILENAME}"
|
|
TAR_PATH="teleport"
|
|
if [[ "${RUNTIME}" == "go1.9.7" ]]; then
|
|
TYPE_DESCRIPTION="[${TEXT_ARCH} Open source edition, built with Go 1.9.7]"
|
|
elif [[ "${RUNTIME}" == "fips" ]]; then
|
|
TYPE_DESCRIPTION="[${TEXT_ARCH} Open source edition, built with FIPS support]"
|
|
else
|
|
TYPE_DESCRIPTION="[${TEXT_ARCH} Open source edition]"
|
|
fi
|
|
fi
|
|
|
|
# set file list
|
|
if [[ "${PACKAGE_TYPE}" == "pkg" ]]; then
|
|
# handle mac client-only builds
|
|
if [[ "${BUILD_MODE}" == "tsh" ]]; then
|
|
FILE_LIST="${TAR_PATH}/tsh"
|
|
BUNDLE_ID="com.gravitational.teleport.tsh"
|
|
SIGN_PKG="true"
|
|
NOTARIZE_PKG="true"
|
|
PKG_FILENAME="tsh-${TELEPORT_VERSION}.${PACKAGE_TYPE}"
|
|
else
|
|
FILE_LIST="${TAR_PATH}/tsh ${TAR_PATH}/tctl ${TAR_PATH}/teleport"
|
|
BUNDLE_ID="com.gravitational.teleport"
|
|
# we can't sign/notarize full Teleport packages on Mac yet due to https://github.com/gravitational/teleport/issues/3158
|
|
# TODO(gus): uncomment/fix this when the teleport binary is fixed
|
|
SIGN_PKG="false"
|
|
NOTARIZE_PKG="false"
|
|
if [[ "${TELEPORT_TYPE}" == "ent" ]]; then
|
|
PKG_FILENAME="teleport-ent-${TELEPORT_VERSION}.${PACKAGE_TYPE}"
|
|
else
|
|
PKG_FILENAME="teleport-${TELEPORT_VERSION}.${PACKAGE_TYPE}"
|
|
fi
|
|
fi
|
|
else
|
|
FILE_LIST="${TAR_PATH}/tsh ${TAR_PATH}/tctl ${TAR_PATH}/teleport ${TAR_PATH}/examples/systemd/teleport.service"
|
|
LINUX_BINARY_FILE_LIST="${TAR_PATH}/tsh ${TAR_PATH}/tctl ${TAR_PATH}/teleport"
|
|
LINUX_SYSTEMD_FILE_LIST="${TAR_PATH}/examples/systemd/teleport.service"
|
|
LINUX_CONFIG_FILE_LIST=""
|
|
if [[ "${PACKAGE_TYPE}" == "rpm" ]]; then
|
|
OUTPUT_FILENAME="${TAR_PATH}-${TELEPORT_VERSION}-1${OPTIONAL_RUNTIME_SECTION}.${ARCH}.rpm"
|
|
elif [[ "${PACKAGE_TYPE}" == "deb" ]]; then
|
|
OUTPUT_FILENAME="${TAR_PATH}_${TELEPORT_VERSION}${OPTIONAL_RUNTIME_SECTION}_${ARCH}.deb"
|
|
fi
|
|
fi
|
|
|
|
# create a temporary directory and download specified Teleport version
|
|
pushd $(mktemp -d)
|
|
TMPDIR=$(pwd)
|
|
# automatically clean up on exit
|
|
trap "rm -rf ${TMPDIR}" EXIT
|
|
mkdir -p ${TMPDIR}/buildroot
|
|
|
|
# implement a rudimentary download cache for repeat builds on the same host
|
|
mkdir -p ${TARBALL_DIRECTORY}
|
|
if [ ! -f ${TARBALL_DIRECTORY}/${TARBALL_FILENAME} ]; then
|
|
if [[ "${DOWNLOAD_IF_NEEDED}" == "true" ]]; then
|
|
echo "Downloading ${URL} to ${TARBALL_DIRECTORY}"
|
|
curl -sL ${URL} -o ${TARBALL_DIRECTORY}/${TARBALL_FILENAME}
|
|
else
|
|
echo "Can't find ${TARBALL_DIRECTORY}/${TARBALL_FILENAME}"
|
|
echo "Downloading from ${DOWNLOAD_ROOT} is disabled when a path is provided with -s"
|
|
exit 6
|
|
fi
|
|
else
|
|
echo "Found ${TARBALL_DIRECTORY}/${TARBALL_FILENAME} - using it"
|
|
fi
|
|
|
|
# extract necessary files from tarball
|
|
tar -C $(pwd) -xvzf ${TARBALL_DIRECTORY}/${TARBALL_FILENAME} ${FILE_LIST}
|
|
|
|
# move files into correct locations before building the package
|
|
if [[ "${PACKAGE_TYPE}" != "pkg" ]]; then
|
|
if [[ "${LINUX_BINARY_FILE_LIST}" != "" ]]; then
|
|
mkdir -p ${TMPDIR}/buildroot${LINUX_BINARY_DIR}
|
|
mv -v ${LINUX_BINARY_FILE_LIST} ${TMPDIR}/buildroot${LINUX_BINARY_DIR}
|
|
fi
|
|
if [[ "${LINUX_SYSTEMD_FILE_LIST}" != "" ]]; then
|
|
mkdir -p ${TMPDIR}/buildroot${LINUX_SYSTEMD_DIR}
|
|
mv -v ${LINUX_SYSTEMD_FILE_LIST} ${TMPDIR}/buildroot${LINUX_SYSTEMD_DIR}
|
|
fi
|
|
if [[ "${LINUX_CONFIG_FILE}" != "" ]]; then
|
|
mkdir -p ${TMPDIR}/buildroot${LINUX_CONFIG_DIR}
|
|
mv -v ${LINUX_CONFIG_FILE} ${TMPDIR}/buildroot${LINUX_CONFIG_DIR}
|
|
CONFIG_FILE_STANZA="--config-files /src/buildroot${LINUX_CONFIG_DIR}/${LINUX_CONFIG_FILE} "
|
|
fi
|
|
# /var/lib/teleport
|
|
mkdir -p ${TMPDIR}/buildroot${LINUX_DATA_DIR}
|
|
fi
|
|
popd
|
|
|
|
if [[ "${PACKAGE_TYPE}" == "pkg" ]]; then
|
|
# erase any existing versions of the package in the output directory first
|
|
rm -f ${PKG_FILENAME}
|
|
|
|
if [[ "${SIGN_PKG}" == "true" ]]; then
|
|
# run codesign to sign binaries
|
|
for FILE in ${FILE_LIST}; do
|
|
codesign -s "${DEVELOPER_ID_APPLICATION}" \
|
|
-f \
|
|
-v \
|
|
--timestamp \
|
|
--options runtime \
|
|
${TMPDIR}/${FILE}
|
|
done
|
|
fi
|
|
|
|
# build the package for OS X
|
|
pkgbuild \
|
|
--root ${TMPDIR}/${TAR_PATH} \
|
|
--identifier ${BUNDLE_ID} \
|
|
--version ${TELEPORT_VERSION} \
|
|
--install-location /usr/local/bin \
|
|
${PKG_FILENAME}
|
|
|
|
if [[ "${SIGN_PKG}" == "true" ]]; then
|
|
# mark package as unsigned first
|
|
mv ${PKG_FILENAME} ${PKG_FILENAME}.unsigned
|
|
|
|
# run productsign to sign package
|
|
productsign \
|
|
--sign "${DEVELOPER_ID_INSTALLER}" \
|
|
--timestamp \
|
|
${PKG_FILENAME}.unsigned \
|
|
${PKG_FILENAME}
|
|
|
|
# remove unsigned package after successful signing
|
|
rm -f ${PKG_FILENAME}.unsigned
|
|
fi
|
|
|
|
# write gon config file
|
|
if [[ "${NOTARIZE_PKG}" == "true" ]]; then
|
|
echo " {
|
|
\"notarize\": [{
|
|
\"path\": \"${PKG_FILENAME}\",
|
|
\"bundle_id\": \"${BUNDLE_ID}\",
|
|
\"staple\": true
|
|
}],
|
|
\"apple_id\": {
|
|
\"username\": \"${APPLE_USERNAME}\",
|
|
\"password\": \"${APPLE_PASSWORD}\"
|
|
}
|
|
}" > ${TMPDIR}/gon-config.json
|
|
|
|
# notarise built package using gon
|
|
gon ${TMPDIR}/gon-config.json
|
|
fi
|
|
|
|
# checksum created packages
|
|
for PACKAGE in *.${PACKAGE_TYPE}; do
|
|
shasum -a 256 ${PACKAGE} > ${PACKAGE}.sha256
|
|
done
|
|
else
|
|
# erase any existing packages of the same type/version/arch in the output directory first
|
|
rm -vf ${OUTPUT_FILENAME}
|
|
|
|
# build for other platforms
|
|
docker run -v ${TMPDIR}:/src --rm ${DOCKER_IMAGE} \
|
|
fpm \
|
|
--input-type dir \
|
|
--output-type ${PACKAGE_TYPE} \
|
|
--name ${TAR_PATH} \
|
|
--version "${TELEPORT_VERSION}" \
|
|
--maintainer "${MAINTAINER}" \
|
|
--url "${DOCS_URL}" \
|
|
--license "${LICENSE}" \
|
|
--vendor "${VENDOR}" \
|
|
--description "${DESCRIPTION} ${TYPE_DESCRIPTION}" \
|
|
--architecture ${ARCH} \
|
|
--package ${OUTPUT_FILENAME} \
|
|
--chdir /src/buildroot \
|
|
--directories ${LINUX_DATA_DIR} \
|
|
--provides teleport \
|
|
--prefix / \
|
|
--verbose \
|
|
${CONFIG_FILE_STANZA} .
|
|
|
|
# copy created package back to current directory
|
|
cp ${TMPDIR}/*.${PACKAGE_TYPE} .
|
|
|
|
# checksum created packages
|
|
for FILE in *.${PACKAGE_TYPE}; do
|
|
sha256sum ${FILE} > ${FILE}.sha256
|
|
done
|
|
fi
|