mirror of
https://github.com/gravitational/teleport
synced 2024-10-20 01:03:40 +00:00
d3eed17856
* build: Support ARM64 (cross)builds of fido2 et al Add support for building/cross-building the fido2 libraries (cbor, openssl and fido2), supporting ARM64 builds. This is done by adding the appropriate flags to the library builds in `build-fido2-macos.sh` based on the `C_ARCH` environment variable. If unset then the host architecture is used. The `Makefile` defined `C_ARCH` based on the `ARCH` variable, mapping it to an appropriate value for the C compiler. Building the libraries should now be done through the new `build-fido2` target, and getting the pkg-config path should be done with the `print-fido2-pkg-path`. This is instead of calling the `build-fido2-macos.sh` script directly as the `Makefile` takes care of setting the `C_ARCH` environment variable appropriately. * build: Add make target to install rust cross toolchain Add the `rustup-set-target-toolchain` target to the Makefile to ensure the right rust toolchain is installed for the version of Rust we use as well as the target architecture we wish to generate code for, based on the `ARCH` variable. This is intended to be used by CI jobs to ensure they build with the correct toolchain. * build: Support building MacOS packages for ARM64 Remove the restriction that allows only AMD64 packages to be built on MacOS for the teleport and tsh packages. This is via the existing `-a` flag to `build-package.sh` and a newly added `-a` flag to `build-pkg-tsh.sh`. This adds the architecture to the filename of the package to distinguish the packages for different architectures. Update the comments in the Makefile mentioning that `arch` is ignored. build: add architecture to package names * build: Build Teleport Connect with target architecture When packaging Teleport Connect with electron-builder, pass an architecture flag so that we can cross-build Teleport Connect. This will allow us to build MacOS ARM64 binaries on the AMD64 runners. Add the architecture to the `dmg` filename via the electron-builder config, so that the filenames for different architectures don't clash. * build: Copy Mac release artifacts to release directory Copy the Mac release artifacts to a release artifact directory so that the CI scripts do not have to. This makes it clearer what is and is not a release artifact and puts the logic in the Makefile instead of the CI yaml, so it can more easily be tested locally and to make it easier to migrate to the next CI system. This will also be useful for building universal binaries for Mac as the CI system can put the architecture-specific binaries from a previous workflow job into a common location. We should look at copying all release artifacts for the other builds (Linux tarballs and packages, etc) into this directory too. It may help with unifying the GitHub Actions release workflows. * build: Add MacOS universal builds Add support for ARCH=universal on Darwin to produce universal (fat) binaries from pre-built arm64 and amd64 binaries. Packages (pkg) and disk images (dmg) for containing universal binaries are named without an architecture in the filename, as that is the current naming for the current AMD64-only releases. These universal ones will replace those AMD64-only ones providing a single release artifact working across architectures. Co-authored-by: Grzegorz Zdunek <grzegorz.zdunek@goteleport.com> * build: Do not clean before release-darwin Remove the `clean` prerequisite from the `release-darwin-unsigned` target as it is not needed when building on GitHub Actions, as it starts with a fresh slate each run. We do not make releases manually so we don't need to ensure a clean working directory there either. Not doing a clean makes it easier to build a MacOS universal release as it depends on the architecture-specific tarballs from a previous release build. We would need to manually save the tarballs from the first architecture release build as they would get deleted by the `clean` from the second. So just stop cleaning as it is not needed. --------- Co-authored-by: Grzegorz Zdunek <grzegorz.zdunek@goteleport.com>
376 lines
13 KiB
Bash
Executable file
376 lines
13 KiB
Bash
Executable file
#!/bin/bash
|
|
set -e
|
|
|
|
usage() {
|
|
echo "Usage: $(basename $0) [-t <oss/ent>] [-v <version>] [-p <package type>] [-b <bundle id>] <-a [amd64/x86_64]|[386/i386]|arm|arm64> <-r fips> <-s tarball source dir>" 1>&2
|
|
exit 1
|
|
}
|
|
|
|
# Don't follow sourced script.
|
|
#shellcheck disable=SC1090
|
|
#shellcheck disable=SC1091
|
|
. "$(dirname "$0")/build-common.sh"
|
|
|
|
while getopts ":t:v:p:a:r:s:b:n" 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" && ${a} != "arm" && ${a} != "arm64" && ${a} != "universal" ]]; then usage; fi
|
|
;;
|
|
r)
|
|
r=${OPTARG}
|
|
if [[ ${r} != "fips" ]]; then usage; fi
|
|
;;
|
|
s)
|
|
s=${OPTARG}
|
|
;;
|
|
b)
|
|
b=${OPTARG}
|
|
;;
|
|
n)
|
|
# Dry-run mode.
|
|
# Only affects parts of the script, use at your own peril!
|
|
DRY_RUN_PREFIX='echo + '
|
|
;;
|
|
*)
|
|
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"
|
|
TARBALL_DIRECTORY="$s"
|
|
GNUPG_DIR=${GNUPG_DIR:-/tmp/gnupg}
|
|
|
|
# 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@goteleport.com"
|
|
LICENSE="Apache-2.0"
|
|
VENDOR="Gravitational"
|
|
DESCRIPTION="Teleport is a gateway for managing access to clusters of Linux servers via SSH or the Kubernetes API"
|
|
DOCS_URL="https://goteleport.com/docs"
|
|
|
|
# check that curl is installed
|
|
if [[ ! $(type curl) ]]; then
|
|
echo "curl must be installed"
|
|
exit 2
|
|
fi
|
|
|
|
# check that tar is installed
|
|
if [[ ! $(type tar) ]]; then
|
|
echo "tar must be installed"
|
|
exit 11
|
|
fi
|
|
|
|
# check that docker is installed when fpm is needed to build
|
|
if [[ "${PACKAGE_TYPE}" != "pkg" ]]; then
|
|
if [[ ! $(type 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 [[ "${RUNTIME}" != "" ]]; then
|
|
echo "runtime parameter is ignored when building for OS X"
|
|
unset RUNTIME
|
|
fi
|
|
PLATFORM="darwin"
|
|
if [[ ! $(type pkgbuild) ]]; then
|
|
echo "You need to install pkgbuild"
|
|
echo "Run: xcode-select --install"
|
|
exit 5
|
|
fi
|
|
else
|
|
PLATFORM="linux"
|
|
# if arch isn't set for other package types, throw an error
|
|
if [[ "${ARCH}" == "" ]]; then
|
|
usage
|
|
fi
|
|
|
|
if [[ -n "${b:-}" ]]; then
|
|
echo "bundle ID parameter can only be used for OS X packages"
|
|
exit 6
|
|
fi
|
|
|
|
# set docker image appropriately
|
|
if [[ "${PACKAGE_TYPE}" == "deb" ]]; then
|
|
DOCKER_IMAGE="public.ecr.aws/gravitational/fpm:debian8"
|
|
elif [[ "${PACKAGE_TYPE}" == "rpm" ]]; then
|
|
DOCKER_IMAGE="public.ecr.aws/gravitational/fpm:centos8"
|
|
fi
|
|
fi
|
|
|
|
PACKAGE_ARCH=""
|
|
# handle differences between 'gravitational' arch and system arch
|
|
if [[ "${ARCH}" == "386" || "${ARCH}" == "i386" ]]; then
|
|
TEXT_ARCH="32-bit x86"
|
|
TARBALL_ARCH="386"
|
|
DEB_PACKAGE_ARCH="i386"
|
|
DEB_OUTPUT_ARCH="i386"
|
|
RPM_PACKAGE_ARCH="i386"
|
|
RPM_OUTPUT_ARCH="i386"
|
|
elif [[ "${ARCH}" == "amd64" || "${ARCH}" == "x86_64" ]]; then
|
|
TEXT_ARCH="64-bit x86"
|
|
TARBALL_ARCH="amd64"
|
|
PACKAGE_ARCH="amd64"
|
|
DEB_PACKAGE_ARCH="amd64"
|
|
DEB_OUTPUT_ARCH="amd64"
|
|
RPM_PACKAGE_ARCH="x86_64"
|
|
RPM_OUTPUT_ARCH="x86_64"
|
|
elif [[ "${ARCH}" == "arm" ]]; then
|
|
TEXT_ARCH="32-bit ARM"
|
|
TARBALL_ARCH="arm"
|
|
# 32-bit arm can be hardfloat and softfloat, and we build for linux-gnueabihf
|
|
DEB_PACKAGE_ARCH="armhf"
|
|
DEB_OUTPUT_ARCH="arm" # backwards compatibility
|
|
RPM_PACKAGE_ARCH="armv7hl"
|
|
RPM_OUTPUT_ARCH="arm" # backwards compatibility
|
|
elif [[ "${ARCH}" == "arm64" ]]; then
|
|
TEXT_ARCH="64-bit ARM"
|
|
TARBALL_ARCH="arm64"
|
|
PACKAGE_ARCH="arm64"
|
|
DEB_PACKAGE_ARCH="arm64"
|
|
DEB_OUTPUT_ARCH="arm64"
|
|
RPM_PACKAGE_ARCH="aarch64"
|
|
RPM_OUTPUT_ARCH="arm64" # backwards compatibility
|
|
elif [[ "${ARCH}" == "universal" ]]; then
|
|
TARBALL_ARCH="universal"
|
|
PACKAGE_ARCH="universal"
|
|
fi
|
|
|
|
# amd64 RPMs should use CentOS 7 compatible artifacts
|
|
if [[ "${PACKAGE_TYPE}" == "rpm" && "${RPM_PACKAGE_ARCH}" == "x86_64" ]]; then
|
|
OPTIONAL_TARBALL_SECTION+="-centos7"
|
|
fi
|
|
|
|
# set optional runtime section for filename
|
|
if [[ "${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}-${TARBALL_ARCH}${OPTIONAL_TARBALL_SECTION}${OPTIONAL_RUNTIME_SECTION}-bin.tar.gz"
|
|
TAR_PATH="teleport-ent"
|
|
RPM_NAME="teleport-ent"
|
|
if [[ "${RUNTIME}" == "fips" ]]; then
|
|
TYPE_DESCRIPTION="[${TEXT_ARCH} Enterprise edition, built with FIPS support]"
|
|
RPM_NAME="teleport-ent-fips"
|
|
else
|
|
TYPE_DESCRIPTION="[${TEXT_ARCH} Enterprise edition]"
|
|
fi
|
|
else
|
|
TARBALL_FILENAME="teleport-v${TELEPORT_VERSION}-${PLATFORM}-${TARBALL_ARCH}${OPTIONAL_TARBALL_SECTION}${OPTIONAL_RUNTIME_SECTION}-bin.tar.gz"
|
|
TAR_PATH="teleport"
|
|
RPM_NAME="teleport"
|
|
if [[ "${RUNTIME}" == "fips" ]]; then
|
|
TYPE_DESCRIPTION="[${TEXT_ARCH} Open source edition, built with FIPS support]"
|
|
RPM_NAME="teleport-fips"
|
|
else
|
|
TYPE_DESCRIPTION="[${TEXT_ARCH} Open source edition]"
|
|
fi
|
|
fi
|
|
|
|
# set file list
|
|
if [[ "${PACKAGE_TYPE}" == "pkg" ]]; then
|
|
if [[ -z "${PACKAGE_ARCH}" ]]; then
|
|
echo "Unsupported architecture: ${ARCH}"
|
|
exit 1
|
|
fi
|
|
# No architecture tag on package filename for universal (multi-arch) binaries.
|
|
ARCH_TAG=""
|
|
if [[ "${PACKAGE_ARCH}" != "universal" ]]; then
|
|
ARCH_TAG="-${PACKAGE_ARCH}"
|
|
fi
|
|
SIGN_PKG="true"
|
|
FILE_LIST="${TAR_PATH}/tsh ${TAR_PATH}/tctl ${TAR_PATH}/teleport ${TAR_PATH}/tbot"
|
|
BUNDLE_ID="${b:-com.gravitational.teleport}"
|
|
if [[ "${TELEPORT_TYPE}" == "ent" ]]; then
|
|
PKG_FILENAME="teleport-ent-${TELEPORT_VERSION}${ARCH_TAG}.${PACKAGE_TYPE}"
|
|
else
|
|
PKG_FILENAME="teleport-${TELEPORT_VERSION}${ARCH_TAG}.${PACKAGE_TYPE}"
|
|
fi
|
|
else
|
|
FILE_LIST="${TAR_PATH}/tsh ${TAR_PATH}/tctl ${TAR_PATH}/teleport ${TAR_PATH}/tbot ${TAR_PATH}/examples/systemd/teleport.service"
|
|
LINUX_BINARY_FILE_LIST="${TAR_PATH}/tsh ${TAR_PATH}/tctl ${TAR_PATH}/tbot ${TAR_PATH}/teleport"
|
|
LINUX_SYSTEMD_FILE_LIST="${TAR_PATH}/examples/systemd/teleport.service"
|
|
EXTRA_DOCKER_OPTIONS=""
|
|
RPM_SIGN_STANZA=""
|
|
if [[ "${PACKAGE_TYPE}" == "rpm" ]]; then
|
|
PACKAGE_ARCH="${RPM_PACKAGE_ARCH}"
|
|
OUTPUT_FILENAME="${TAR_PATH}-${TELEPORT_VERSION}-1${OPTIONAL_RUNTIME_SECTION}.${RPM_OUTPUT_ARCH}.rpm"
|
|
FILE_PERMISSIONS_STANZA="--rpm-user root --rpm-group root --rpm-use-file-permissions "
|
|
# the rpm/rpmmacros file suppresses the creation of .build-id files (see https://github.com/gravitational/teleport/issues/7040)
|
|
EXTRA_DOCKER_OPTIONS="-v $(pwd)/rpm/rpmmacros:/root/.rpmmacros"
|
|
# if we set this environment variable, don't sign RPMs (can be useful for building test RPMs
|
|
# without having the signing keys)
|
|
if [ "${UNSIGNED_RPM}" == "true" ]; then
|
|
echo "RPMs will not be signed as requested"
|
|
else
|
|
# the GNUPG_DIR location here is assumed to contain a complete ~/.gnupg directory structure
|
|
# with pubring.kbx and trustdb.gpg files, plus a private-keys-v1.d directory with signing keys
|
|
# it needs to contain the "Gravitational, Inc" private key and signing key.
|
|
# we also use the rpm-sign/rpmmacros file instead which contains extra directives used for signing.
|
|
EXTRA_DOCKER_OPTIONS="-v $(pwd)/rpm-sign/rpmmacros:/root/.rpmmacros -v $(pwd)/rpm-sign/popt-override:/etc/popt.d/rpmsign-override -v ${GNUPG_DIR}:/root/.gnupg"
|
|
RPM_SIGN_STANZA="--rpm-sign"
|
|
fi
|
|
elif [[ "${PACKAGE_TYPE}" == "deb" ]]; then
|
|
PACKAGE_ARCH="${DEB_PACKAGE_ARCH}"
|
|
OUTPUT_FILENAME="${TAR_PATH}_${TELEPORT_VERSION}${OPTIONAL_RUNTIME_SECTION}_${DEB_OUTPUT_ARCH}.deb"
|
|
FILE_PERMISSIONS_STANZA="--deb-user root --deb-group root "
|
|
fi
|
|
fi
|
|
|
|
# create a temporary directory and download specified Teleport version
|
|
pushd "$(mktemp -d)"
|
|
PACKAGE_TEMPDIR=$(pwd)
|
|
# automatically clean up on exit
|
|
trap 'rm -rf ${PACKAGE_TEMPDIR}' EXIT
|
|
mkdir -p ${PACKAGE_TEMPDIR}/buildroot
|
|
|
|
# Find or download tarball to the local file cache.
|
|
tarname="$TARBALL_FILENAME"
|
|
[[ -n "$TARBALL_DIRECTORY" ]] && tarname="$TARBALL_DIRECTORY/$TARBALL_FILENAME"
|
|
tarout='' # find_or_fetch_tarball writes to this
|
|
find_or_fetch_tarball "$tarname" tarout
|
|
TARBALL_DIRECTORY="$(dirname "$tarout")"
|
|
TARBALL_FILENAME="$(basename "$tarout")" # for consistency, shouldn't change
|
|
echo "Found ${TARBALL_DIRECTORY}/${TARBALL_FILENAME} - using it"
|
|
|
|
# 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 ${PACKAGE_TEMPDIR}/buildroot${LINUX_BINARY_DIR}
|
|
mv -v ${LINUX_BINARY_FILE_LIST} ${PACKAGE_TEMPDIR}/buildroot${LINUX_BINARY_DIR}
|
|
fi
|
|
if [[ "${LINUX_SYSTEMD_FILE_LIST}" != "" ]]; then
|
|
mkdir -p ${PACKAGE_TEMPDIR}/buildroot${LINUX_SYSTEMD_DIR}
|
|
mv -v ${LINUX_SYSTEMD_FILE_LIST} ${PACKAGE_TEMPDIR}/buildroot${LINUX_SYSTEMD_DIR}
|
|
fi
|
|
if [[ "${LINUX_CONFIG_FILE}" != "" ]]; then
|
|
mkdir -p ${PACKAGE_TEMPDIR}/buildroot${LINUX_CONFIG_DIR}
|
|
mv -v ${LINUX_CONFIG_FILE} ${PACKAGE_TEMPDIR}/buildroot${LINUX_CONFIG_DIR}
|
|
CONFIG_FILE_STANZA="--config-files /src/buildroot${LINUX_CONFIG_DIR}/${LINUX_CONFIG_FILE} "
|
|
fi
|
|
# /var/lib/teleport
|
|
# shellcheck disable=SC2174
|
|
mkdir -p -m0700 ${PACKAGE_TEMPDIR}/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
|
|
$DRY_RUN_PREFIX codesign -s "${DEVELOPER_ID_APPLICATION}" \
|
|
-f \
|
|
-v \
|
|
--timestamp \
|
|
--options runtime \
|
|
${PACKAGE_TEMPDIR}/${FILE}
|
|
done
|
|
fi
|
|
|
|
# build the package for OS X
|
|
pkgbuild \
|
|
--root ${PACKAGE_TEMPDIR}/${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
|
|
$DRY_RUN_PREFIX productsign \
|
|
--sign "${DEVELOPER_ID_INSTALLER}" \
|
|
--timestamp \
|
|
${PKG_FILENAME}.unsigned \
|
|
${PKG_FILENAME}
|
|
[[ -n "$DRY_RUN_PREFIX" ]] && cp "$PKG_FILENAME.unsigned" "$PKG_FILENAME"
|
|
|
|
# remove unsigned package after successful signing
|
|
rm -f ${PKG_FILENAME}.unsigned
|
|
|
|
notarize "$PKG_FILENAME" "$TEAMID" "$BUNDLE_ID"
|
|
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 ${PACKAGE_TEMPDIR}:/src --rm ${EXTRA_DOCKER_OPTIONS} ${DOCKER_IMAGE} \
|
|
fpm \
|
|
--input-type dir \
|
|
--output-type ${PACKAGE_TYPE} \
|
|
--name ${RPM_NAME} \
|
|
--version "${TELEPORT_VERSION}" \
|
|
--maintainer "${MAINTAINER}" \
|
|
--url "${DOCS_URL}" \
|
|
--license "${LICENSE}" \
|
|
--vendor "${VENDOR}" \
|
|
--description "${DESCRIPTION} ${TYPE_DESCRIPTION}" \
|
|
--architecture ${PACKAGE_ARCH} \
|
|
--package ${OUTPUT_FILENAME} \
|
|
--chdir /src/buildroot \
|
|
--directories ${LINUX_DATA_DIR} \
|
|
--provides teleport \
|
|
--prefix / \
|
|
--verbose \
|
|
${CONFIG_FILE_STANZA} \
|
|
${FILE_PERMISSIONS_STANZA} \
|
|
${RPM_SIGN_STANZA} .
|
|
|
|
# copy created package back to current directory
|
|
cp ${PACKAGE_TEMPDIR}/*."${PACKAGE_TYPE}" .
|
|
|
|
# checksum created packages
|
|
for FILE in *."${PACKAGE_TYPE}"; do
|
|
sha256sum ${FILE} > ${FILE}.sha256
|
|
done
|
|
fi
|