#!/usr/bin/env bash ########################################################################### # Packaging script which creates debian and RPM packages. It optionally # tags the repo with the given version. # # Requirements: GOPATH must be set. 'fpm' must be on the path, and the AWS # CLI tools must also be installed. # # https://github.com/jordansissel/fpm # http://aws.amazon.com/cli/ # # Packaging process: to package a build, simply execute: # # package.sh # # The script will automatically determined the version number from git using # `git describe --always --tags` # # AWS upload: the script will also offer to upload the packages to S3. If # this option is selected, the credentials should be present in the file # ~/aws.conf. The contents should be of the form: # # [default] # aws_access_key_id= # aws_secret_access_key= # region = us-east-1 # # Trim the leading spaces when creating the file. The script will exit if # S3 upload is requested, but this file does not exist. AWS_FILE=~/aws.conf INSTALL_ROOT_DIR=/opt/telegraf TELEGRAF_LOG_DIR=/var/log/telegraf CONFIG_ROOT_DIR=/etc/opt/telegraf LOGROTATE_DIR=/etc/logrotate.d SAMPLE_CONFIGURATION=etc/config.sample.toml LOGROTATE_CONFIGURATION=etc/logrotate.d/telegraf INITD_SCRIPT=scripts/init.sh SYSTEMD_SCRIPT=scripts/telegraf.service TMP_WORK_DIR=`mktemp -d` POST_INSTALL_PATH=`mktemp` ARCH=`uname -i` LICENSE=MIT URL=influxdb.com MAINTAINER=support@influxdb.com VENDOR=InfluxDB DESCRIPTION="InfluxDB Telegraf agent" PKG_DEPS=(coreutils) GO_VERSION="go1.5" GOPATH_INSTALL= BINS=( telegraf ) ########################################################################### # Helper functions. # usage prints simple usage information. usage() { echo -e "$0\n" cleanup_exit $1 } # make_dir_tree creates the directory structure within the packages. make_dir_tree() { work_dir=$1 version=$2 mkdir -p $work_dir/$INSTALL_ROOT_DIR/versions/$version/scripts if [ $? -ne 0 ]; then echo "Failed to create installation directory -- aborting." cleanup_exit 1 fi mkdir -p $work_dir/$CONFIG_ROOT_DIR if [ $? -ne 0 ]; then echo "Failed to create configuration directory -- aborting." cleanup_exit 1 fi mkdir -p $work_dir/$LOGROTATE_DIR if [ $? -ne 0 ]; then echo "Failed to create configuration directory -- aborting." cleanup_exit 1 fi } # cleanup_exit removes all resources created during the process and exits with # the supplied returned code. cleanup_exit() { rm -r $TMP_WORK_DIR rm $POST_INSTALL_PATH exit $1 } # check_gopath sanity checks the value of the GOPATH env variable, and determines # the path where build artifacts are installed. GOPATH may be a colon-delimited # list of directories. check_gopath() { [ -z "$GOPATH" ] && echo "GOPATH is not set." && cleanup_exit 1 GOPATH_INSTALL=`echo $GOPATH | cut -d ':' -f 1` [ ! -d "$GOPATH_INSTALL" ] && echo "GOPATH_INSTALL is not a directory." && cleanup_exit 1 echo "GOPATH ($GOPATH) looks sane, using $GOPATH_INSTALL for installation." } # check_clean_tree ensures that no source file is locally modified. check_clean_tree() { modified=$(git ls-files --modified | wc -l) if [ $modified -ne 0 ]; then echo "The source tree is not clean -- aborting." cleanup_exit 1 fi echo "Git tree is clean." } # do_build builds the code. The version and commit must be passed in. do_build() { version=$1 commit=`git rev-parse HEAD` if [ $? -ne 0 ]; then echo "Unable to retrieve current commit -- aborting" cleanup_exit 1 fi for b in ${BINS[*]}; do rm -f $GOPATH_INSTALL/bin/$b done godep go install -ldflags="-X main.Version $version" ./... if [ $? -ne 0 ]; then echo "Build failed, unable to create package -- aborting" cleanup_exit 1 fi echo "Build completed successfully." } # generate_postinstall_script creates the post-install script for the # package. It must be passed the version. generate_postinstall_script() { version=$1 cat <$POST_INSTALL_PATH #!/bin/sh rm -f $INSTALL_ROOT_DIR/telegraf rm -f $INSTALL_ROOT_DIR/init.sh ln -sfn $INSTALL_ROOT_DIR/versions/$version/telegraf $INSTALL_ROOT_DIR/telegraf if ! id telegraf >/dev/null 2>&1; then useradd --help 2>&1| grep -- --system > /dev/null 2>&1 old_useradd=\$? if [ \$old_useradd -eq 0 ] then useradd --system -U -M telegraf else groupadd telegraf && useradd -M -g telegraf telegraf fi fi # Systemd if which systemctl > /dev/null 2>&1 ; then cp $INSTALL_ROOT_DIR/versions/$version/scripts/telegraf.service \ /lib/systemd/system/telegraf.service systemctl enable telegraf # Sysv else ln -sfn $INSTALL_ROOT_DIR/versions/$version/scripts/init.sh \ $INSTALL_ROOT_DIR/init.sh rm -f /etc/init.d/telegraf ln -sfn $INSTALL_ROOT_DIR/init.sh /etc/init.d/telegraf chmod +x /etc/init.d/telegraf # update-rc.d sysv service: if which update-rc.d > /dev/null 2>&1 ; then update-rc.d -f telegraf remove update-rc.d telegraf defaults # CentOS-style sysv: else chkconfig --add telegraf fi mkdir -p $TELEGRAF_LOG_DIR chown -R -L telegraf:telegraf $TELEGRAF_LOG_DIR fi chown -R -L telegraf:telegraf $INSTALL_ROOT_DIR chmod -R a+rX $INSTALL_ROOT_DIR EOF echo "Post-install script created successfully at $POST_INSTALL_PATH" } ########################################################################### # Start the packaging process. if [ "$1" == "-h" ]; then usage 0 elif [ "$1" == "" ]; then VERSION=`git describe --always --tags | tr -d v` else VERSION="$1" fi cd `git rev-parse --show-toplevel` echo -e "\nStarting package process, version: $VERSION\n" check_gopath do_build $VERSION make_dir_tree $TMP_WORK_DIR $VERSION ########################################################################### # Copy the assets to the installation directories. for b in ${BINS[*]}; do cp $GOPATH_INSTALL/bin/$b $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/$VERSION if [ $? -ne 0 ]; then echo "Failed to copy binaries to packaging directory -- aborting." cleanup_exit 1 fi done echo "${BINS[*]} copied to $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/$VERSION" cp $INITD_SCRIPT $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/$VERSION/scripts if [ $? -ne 0 ]; then echo "Failed to copy init.d script to packaging directory -- aborting." cleanup_exit 1 fi echo "$INITD_SCRIPT copied to $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/$VERSION/scripts" cp $SYSTEMD_SCRIPT $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/$VERSION/scripts if [ $? -ne 0 ]; then echo "Failed to copy systemd file to packaging directory -- aborting." cleanup_exit 1 fi echo "$SYSTEMD_SCRIPT copied to $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/$VERSION/scripts" cp $SAMPLE_CONFIGURATION $TMP_WORK_DIR/$CONFIG_ROOT_DIR/telegraf.conf if [ $? -ne 0 ]; then echo "Failed to copy $SAMPLE_CONFIGURATION to packaging directory -- aborting." cleanup_exit 1 fi cp $LOGROTATE_CONFIGURATION $TMP_WORK_DIR/$LOGROTATE_DIR/telegraf if [ $? -ne 0 ]; then echo "Failed to copy $LOGROTATE_CONFIGURATION to packaging directory -- aborting." cleanup_exit 1 fi generate_postinstall_script $VERSION ########################################################################### # Create the actual packages. if [ "$CIRCLE_BRANCH" == "" ]; then echo -n "Commence creation of $ARCH packages, version $VERSION? [Y/n] " read response response=`echo $response | tr 'A-Z' 'a-z'` if [ "x$response" == "xn" ]; then echo "Packaging aborted." cleanup_exit 1 fi fi if [ $ARCH == "i386" ]; then rpm_package=telegraf-$VERSION-1.i686.rpm debian_package=telegraf_${VERSION}_i686.deb deb_args="-a i686" rpm_args="setarch i686" elif [ $ARCH == "arm" ]; then rpm_package=telegraf-$VERSION-1.armel.rpm debian_package=telegraf_${VERSION}_armel.deb else rpm_package=telegraf-$VERSION-1.x86_64.rpm debian_package=telegraf_${VERSION}_amd64.deb fi COMMON_FPM_ARGS="-C $TMP_WORK_DIR --vendor $VENDOR --url $URL --license $LICENSE \ --maintainer $MAINTAINER --after-install $POST_INSTALL_PATH \ --name telegraf --provides telegraf --version $VERSION --config-files $CONFIG_ROOT_DIR ." $rpm_args fpm -s dir -t rpm --description "$DESCRIPTION" $COMMON_FPM_ARGS if [ $? -ne 0 ]; then echo "Failed to create RPM package -- aborting." cleanup_exit 1 fi echo "RPM package created successfully." fpm -s dir -t deb $deb_args --description "$DESCRIPTION" $COMMON_FPM_ARGS if [ $? -ne 0 ]; then echo "Failed to create Debian package -- aborting." cleanup_exit 1 fi echo "Debian package created successfully." ########################################################################### # Offer to publish the packages. if [ "$CIRCLE_BRANCH" == "" ]; then echo -n "Publish packages to S3? [y/N] " read response response=`echo $response | tr 'A-Z' 'a-z'` if [ "x$response" == "xy" ]; then echo "Publishing packages to S3." if [ ! -e "$AWS_FILE" ]; then echo "$AWS_FILE does not exist -- aborting." cleanup_exit 1 fi # Upload .deb and .rpm packages for filepath in `ls *.{deb,rpm}`; do echo "Uploading $filepath to S3" filename=`basename $filepath` echo "Uploading $filename to s3://get.influxdb.org/telegraf/$filename" AWS_CONFIG_FILE=$AWS_FILE aws s3 cp $filepath \ s3://get.influxdb.org/telegraf/$filename \ --acl public-read --region us-east-1 if [ $? -ne 0 ]; then echo "Upload failed -- aborting". cleanup_exit 1 fi rm $filepath done # Make and upload linux amd64, 386, and arm make build-linux-bins for b in `ls telegraf_*`; do zippedbin=${b}_${VERSION}.tar.gz # Zip the binary tar -zcf $TMP_WORK_DIR/$zippedbin ./$b echo "Uploading binary: $zippedbin to S3" AWS_CONFIG_FILE=$AWS_FILE aws s3 cp $TMP_WORK_DIR/$zippedbin \ s3://get.influxdb.org/telegraf/$zippedbin \ --acl public-read --region us-east-1 if [ $? -ne 0 ]; then echo "Binary upload failed -- aborting". cleanup_exit 1 fi done else echo "Not publishing packages to S3." fi fi ########################################################################### # All done. echo -e "\nPackaging process complete." cleanup_exit 0