Also build a package for python-six.
[arvados-dev.git] / jenkins / run-build-packages.sh
index 9ff93a233d0b5e8776c6835a18759036fe4b9f40..621df9676c5d4453eca9c8bdac263ac72c90e041 100755 (executable)
 #!/bin/bash
 
-EXITCODE=0
-CALL_PRM=0
 
-APTUSER=$1
-APTSERVER=$2
+read -rd "\000" helpmessage <<EOF
+$(basename $0): Build Arvados packages and (optionally) upload them.
 
-if [[ "$APTUSER" == '' ]]; then
-  echo "Syntax: $0 <aptuser> <aptserver>"
-  exit 1
-fi
+Syntax:
+        WORKSPACE=/path/to/arvados $(basename $0) [options]
 
-if [[ "$APTSERVER" == '' ]]; then
-  echo "Syntax: $0 <aptuser> <aptserver>"
-  exit 1
-fi
+Options:
 
-source /etc/profile.d/rvm.sh
-echo $WORKSPACE
+--upload               Upload packages (default: false)
+--scp-user USERNAME    Scp user for apt server (only required when --upload is specified)
+--apt-server HOSTNAME  Apt server hostname (only required when --upload is specified)
+--debug                Output debug information (default: false)
 
-# Build arvados GEM
-echo "Build and publish ruby gem"
-cd "$WORKSPACE"
-cd sdk/ruby
-# clean up old gems
-rm -f arvados-*gem
-gem build arvados.gemspec
-# publish new gem
-gem push arvados-*gem
+WORKSPACE=path         Path to the Arvados source tree to build packages from
 
-# Build arvados-cli GEM
-echo "Build and publish ruby gem"
-cd "$WORKSPACE"
-cd sdk/cli
-# clean up old gems
-rm -f arvados-cli*gem
-gem build arvados-cli.gemspec
-# publish new gem
-gem push arvados-cli*gem
+EOF
 
-# Build arvados-python-client Python package
-echo "Build and publish arvados-python-client package"
-cd "$WORKSPACE"
-
-GIT_HASH=`git log --format=format:%ct.%h -n1 .`
-
-cd sdk/python
+EXITCODE=0
+CALL_FREIGHT=0
+
+DEBUG=0
+UPLOAD=0
+
+while [[ -n "$1" ]]
+do
+    arg="$1"; shift
+    case "$arg" in
+        --help)
+            echo >&2 "$helpmessage"
+            echo >&2
+            exit 1
+            ;;
+        --scp-user)
+            APTUSER="$1"; shift
+            ;;
+        --apt-server)
+            APTSERVER="$1"; shift
+            ;;
+        --debug)
+            DEBUG=1
+            ;;
+        --upload)
+            UPLOAD=1
+            ;;
+        *)
+            echo >&2 "$0: Unrecognized option: '$arg'. Try: $0 --help"
+            exit 1
+            ;;
+    esac
+done
+
+# Sanity checks
+if [[ "$UPLOAD" != '0' && ("$APTUSER" == '' || "$APTSERVER" == '') ]]; then
+  echo >&2 "$helpmessage"
+  echo >&2
+  echo >&2 "Error: please specify --scp-user and --apt-server if --upload is set"
+  echo >&2
+  exit 1
+fi
 
-# We mess with this file below, reset it here
-git checkout setup.py
+# Sanity check
+if ! [[ -n "$WORKSPACE" ]]; then
+  echo >&2 "$helpmessage"
+  echo >&2
+  echo >&2 "Error: WORKSPACE environment variable not set"
+  echo >&2
+  exit 1
+fi
 
-# Make sure only to use sdist - that's the only format pip can deal with (sigh)
-python setup.py egg_info -b ".$GIT_HASH" sdist upload
+# Test for fpm
+fpm --version >/dev/null 2>&1
 
-cd ../../services/fuse
+if [[ "$?" != 0 ]]; then
+  echo >&2 "$helpmessage"
+  echo >&2
+  echo >&2 "Error: fpm not found"
+  echo >&2
+  exit 1
+fi
 
-# We mess with this file below, reset it here
-git checkout setup.py
+if [[ "$DEBUG" != 0 ]]; then
+  echo "Workspace is $WORKSPACE"
+fi
 
-# Make sure only to use sdist - that's the only format pip can deal with (sigh)
-python setup.py egg_info -b ".$GIT_HASH" sdist upload
+handle_python_package () {
+  # This function assumes the current working directory is the python package directory
+  if [[ "$UPLOAD" != 0 ]]; then
+    # Make sure only to use sdist - that's the only format pip can deal with (sigh)
+    if [[ "$DEBUG" != 0 ]]; then
+      python setup.py sdist upload
+    else
+      python setup.py -q sdist upload
+    fi
+  else
+    # Make sure only to use sdist - that's the only format pip can deal with (sigh)
+    if [[ "$DEBUG" != 0 ]]; then
+      python setup.py sdist
+    else
+      python setup.py -q sdist
+    fi
+  fi
+}
 
 # Build debs for everything
-
-# Build arvados src deb package
-
 build_and_scp_deb () {
   PACKAGE=$1
-  PACKAGE_NAME=$2
-  # Put spaces in $3 and you will regret it. Despite the use of arrays below.
-  # Because, bash sucks.
-  VENDOR=${3// /_}
-  PACKAGE_TYPE=$4
-  EXTRA_ARGUMENTS=$5
+  shift
+  PACKAGE_NAME=$1
+  shift
+  VENDOR=$1
+  shift
+  PACKAGE_TYPE=$1
+  shift
+  VERSION=$1
+  shift
 
   if [[ "$PACKAGE_NAME" == "" ]]; then
     PACKAGE_NAME=$PACKAGE
@@ -82,7 +125,7 @@ build_and_scp_deb () {
     PACKAGE_TYPE='python'
   fi
 
-  COMMAND_ARR=("fpm" "-s" "$PACKAGE_TYPE" "-t" "deb")
+  declare -a COMMAND_ARR=("fpm" "--maintainer=Ward Vandewege <ward@curoverse.com>" "-s" "$PACKAGE_TYPE" "-t" "deb" "-x" "usr/local/lib/python2.7/dist-packages/tests")
 
   if [[ "$PACKAGE_NAME" != "$PACKAGE" ]]; then
     COMMAND_ARR+=('-n' "$PACKAGE_NAME")
@@ -91,111 +134,233 @@ build_and_scp_deb () {
   if [[ "$VENDOR" != "" ]]; then
     COMMAND_ARR+=('--vendor' "$VENDOR")
   fi
-  for a in $EXTRA_ARGUMENTS; do
-    COMMAND_ARR+=("$a")
+
+  if [[ "$VERSION" != "" ]]; then
+    COMMAND_ARR+=('-v' "$VERSION")
+  fi
+
+  for i; do
+    COMMAND_ARR+=("$i")
   done
 
   COMMAND_ARR+=("$PACKAGE")
 
-  FPM_RESULTS=$(${COMMAND_ARR[@]})
+  if [[ "$DEBUG" != 0 ]]; then
+    echo
+    echo "${COMMAND_ARR[@]}"
+    echo
+  fi
+
+  FPM_RESULTS=$("${COMMAND_ARR[@]}")
   FPM_EXIT_CODE=$?
-  echo ${COMMAND_ARR[@]}
-  if [[ ! $FPM_RESULTS =~ "File already exists" ]]; then
-    if [[ "$FPM_EXIT_CODE" != "0" ]]; then
-      echo "Error building debian package for $1:\n $FPM_RESULTS"
+
+  FPM_PACKAGE_NAME=''
+  if [[ $FPM_RESULTS =~ ([A-Za-z0-9_\-.]*\.deb) ]]; then
+    FPM_PACKAGE_NAME=${BASH_REMATCH[1]}
+  fi
+
+  if [[ "$FPM_PACKAGE_NAME" == "" ]]; then
+    EXITCODE=1
+    echo "Error: $PACKAGE: Unable to figure out package name from fpm results:"
+    echo
+    echo $FPM_RESULTS
+    echo
+  else
+    if [[ ! $FPM_RESULTS =~ "File already exists" ]]; then
+      if [[ "$FPM_EXIT_CODE" != "0" ]]; then
+        echo "Error building debian package for $1:\n $FPM_RESULTS"
+      else
+        if [[ "$UPLOAD" != 0 ]]; then
+          scp -P2222 $FPM_PACKAGE_NAME $APTUSER@$APTSERVER:tmp/
+          CALL_FREIGHT=1
+        fi
+      fi
     else
-      scp -P2222 $PACKAGE_NAME*.deb $APTUSER@$APTSERVER:tmp/
-      CALL_PRM=1
+      echo "Debian package $FPM_PACKAGE_NAME exists, not rebuilding"
     fi
-  else
-    echo "Debian package for $1 exists, not rebuilding"
   fi
 }
 
+source /etc/profile.d/rvm.sh
+
+# Make all files world-readable -- jenkins runs with umask 027, and has checked
+# out our git tree here
+chmod o+r "$WORKSPACE" -R
+
+# More cleanup - make sure all executables that we'll package are 755
+find -type d -name 'bin' |xargs -I {} find {} -type f |xargs -I {} chmod 755 {}
+
+# Now fix our umask to something better suited to building and publishing
+# gems and packages
+umask 0022
+
+if [[ "$DEBUG" != 0 ]]; then
+  echo "umask is" `umask`
+fi
+
+# Ruby gems
+if [[ "$DEBUG" != 0 ]]; then
+  echo
+  echo "Ruby gems"
+  echo
+fi
+
+cd "$WORKSPACE"
+cd sdk/ruby
+# clean up old gems
+rm -f arvados-*gem
+
+if [[ "$DEBUG" != 0 ]]; then
+  gem build arvados.gemspec
+else
+  # -q appears to be broken in gem version 2.2.2
+  gem build arvados.gemspec -q >/dev/null
+fi
+
+if [[ "$UPLOAD" != 0 ]]; then
+  # publish new gem
+  gem push arvados-*gem
+fi
+
+# Build arvados-cli GEM
+cd "$WORKSPACE"
+cd sdk/cli
+# clean up old gems
+rm -f arvados-cli*gem
+
+if [[ "$DEBUG" != 0 ]]; then
+  gem build arvados-cli.gemspec
+else
+  # -q appears to be broken in gem version 2.2.2
+  gem build arvados-cli.gemspec -q >/dev/null
+fi
+
+if [[ "$UPLOAD" != 0 ]]; then
+  # publish new gem
+  gem push arvados-cli*gem
+fi
+
+# Python packages
+if [[ "$DEBUG" != 0 ]]; then
+  echo
+  echo "Python packages"
+  echo
+fi
+
+cd "$WORKSPACE"
+
+GIT_TIMESTAMP=`git log --first-parent --max-count=1 --format=format:%ct -n1 .`
+HUMAN_READABLE_TIMESTAMP=`TZ=UTC date -d @$GIT_TIMESTAMP +%Y%m%d%H%M%S`
+GIT_HASH=`git log --first-parent --max-count=1 --format=format:$HUMAN_READABLE_TIMESTAMP.%h -n1 .`
+
+cd sdk/python
+handle_python_package
+
+cd ../../services/fuse
+handle_python_package
+
+cd ../../services/nodemanager
+handle_python_package
+
 if [[ ! -d "$WORKSPACE/debs" ]]; then
   mkdir -p $WORKSPACE/debs
 fi
 
-# Make sure our destination directory on $APTSERVER exists - prm can delete it when invoked improperly
-ssh -p2222 $APTUSER@$APTSERVER mkdir tmp
-
 # Arvados-src
 # We use $WORKSPACE/src-build-dir as the clean directory from which to build the src package
 if [[ ! -d "$WORKSPACE/src-build-dir" ]]; then
   mkdir "$WORKSPACE/src-build-dir"
-  cd "$WORKSPACE/src-build-dir"
-  git clone https://github.com/curoverse/arvados.git
-fi  
+  cd "$WORKSPACE"
+  if [[ "$DEBUG" != 0 ]]; then
+    git clone https://github.com/curoverse/arvados.git src-build-dir
+  else
+    git clone -q https://github.com/curoverse/arvados.git src-build-dir
+  fi
+fi
 
 cd "$WORKSPACE/src-build-dir"
-git fetch -a
-git checkout $GIT_REV
-cd $WORKSPACE
-
-cd $WORKSPACE/debs
-build_and_scp_deb $WORKSPACE/src-build-dir/=/usr/local/arvados/src arvados-src 'Curoverse, Inc.' 'dir' "-v 0.1.$GIT_HASH -x 'usr/local/arvados/src/.git*'"
+# just in case, check out master
+if [[ "$DEBUG" != 0 ]]; then
+  git checkout master
+  git pull
+  # go into detached-head state
+  git checkout `git log --format=format:%h -n1 .`
+else
+  git checkout -q master
+  git pull -q
+  # go into detached-head state
+  git checkout -q `git log --format=format:%h -n1 .`
+fi
 
-# Keep
-cd $WORKSPACE/services/keep
-./go.sh install keep
+# Build arvados src deb package
 cd $WORKSPACE/debs
-build_and_scp_deb $WORKSPACE/services/keep/bin/keep=/usr/bin/keep keep 'Curoverse, Inc.' 'dir' "-v 0.1.$GIT_HASH"
+build_and_scp_deb $WORKSPACE/src-build-dir/=/usr/local/arvados/src arvados-src 'Curoverse, Inc.' 'dir' "0.1.$GIT_HASH" "--exclude=usr/local/arvados/src/.git" "--url=https://arvados.org" "--license=GNU Affero General Public License, version 3.0" "--description=The Arvados source code" "--architecture=all"
 
-# Keep proxy
+# clean up, check out master and step away from detached-head state
+cd "$WORKSPACE/src-build-dir"
+if [[ "$DEBUG" != 0 ]]; then
+  git checkout master
+else
+  git checkout -q master
+fi
 
-# First build the keepclient library
-cd $WORKSPACE/sdk/go
-./go.sh install arvados.org/keepclient
+# Keep
+export GOPATH=$(mktemp -d)
+mkdir -p "$GOPATH/src/git.curoverse.com"
+ln -sfn "$WORKSPACE" "$GOPATH/src/git.curoverse.com/arvados.git"
 
-# Then keepproxy
-cd $WORKSPACE/services/keep
-./go.sh install arvados.org/keepproxy
+# keepstore
+go get "git.curoverse.com/arvados.git/services/keepstore"
 cd $WORKSPACE/debs
-build_and_scp_deb $WORKSPACE/services/keep/bin/keepproxy=/usr/bin/keepproxy keepproxy 'Curoverse, Inc.' 'dir' "-v 0.1.$GIT_HASH"
+build_and_scp_deb $GOPATH/bin/keepstore=/usr/bin/keepstore keepstore 'Curoverse, Inc.' 'dir' "0.1.$GIT_HASH" "--url=https://arvados.org" "--license=GNU Affero General Public License, version 3.0" "--description=Keepstore is the Keep storage daemon, accessible to clients on the LAN"
 
-# The crunchstat wrapper
-cd $WORKSPACE/services/crunch/crunchstat
-./go.sh install arvados.org/crunchstat
+# keepproxy
+go get "git.curoverse.com/arvados.git/services/keepproxy"
 cd $WORKSPACE/debs
-build_and_scp_deb $WORKSPACE/services/crunch/crunchstat/bin/crunchstat=/usr/bin/crunchstat crunchstat 'Curoverse, Inc.' 'dir' "-v 0.1.$GIT_HASH"
-
-# The Python SDK
-cd $WORKSPACE/sdk/python
-sed -i'' -e "s:version='0.1':version='0.1.$GIT_HASH':" setup.py
+build_and_scp_deb $GOPATH/bin/keepproxy=/usr/bin/keepproxy keepproxy 'Curoverse, Inc.' 'dir' "0.1.$GIT_HASH" "--url=https://arvados.org" "--license=GNU Affero General Public License, version 3.0" "--description=Keepproxy makes a Keep cluster accessible to clients that are not on the LAN"
 
+# crunchstat
+go get "git.curoverse.com/arvados.git/services/crunchstat"
 cd $WORKSPACE/debs
+build_and_scp_deb $GOPATH/bin/crunchstat=/usr/bin/crunchstat crunchstat 'Curoverse, Inc.' 'dir' "0.1.$GIT_HASH" "--url=https://arvados.org" "--license=GNU Affero General Public License, version 3.0" "--description=Crunchstat gathers cpu/memory/network statistics of running Crunch jobs"
 
+# The Python SDK
 # Please resist the temptation to add --no-python-fix-name to the fpm call here
 # (which would remove the python- prefix from the package name), because this
 # package is a dependency of arvados-fuse, and fpm can not omit the python-
 # prefix from only one of the dependencies of a package...  Maybe I could
 # whip up a patch and send it upstream, but that will be for another day. Ward,
 # 2014-05-15
-build_and_scp_deb $WORKSPACE/sdk/python python-arvados-python-client 'Curoverse, Inc.' 'python' "-v 0.1.${GIT_HASH}"
-
-# The FUSE driver
-cd $WORKSPACE/services/fuse
-sed -i'' -e "s:version='0.1':version='0.1.$GIT_HASH':" setup.py
-
-
 cd $WORKSPACE/debs
+build_and_scp_deb $WORKSPACE/sdk/python python-arvados-python-client 'Curoverse, Inc.' 'python' "$(awk '($1 == "Version:"){print $2}' $WORKSPACE/sdk/python/arvados_python_client.egg-info/PKG-INFO)" "--url=https://arvados.org" "--description=The Arvados Python SDK"
 
+# The FUSE driver
 # Please seem comment about --no-python-fix-name above; we stay consistent and do
 # not omit the python- prefix first.
-build_and_scp_deb $WORKSPACE/services/fuse python-arvados-fuse 'Curoverse, Inc.' 'python' "-v 0.1.${GIT_HASH}"
+cd $WORKSPACE/debs
+build_and_scp_deb $WORKSPACE/services/fuse python-arvados-fuse 'Curoverse, Inc.' 'python' "$(awk '($1 == "Version:"){print $2}' $WORKSPACE/services/fuse/arvados_fuse.egg-info/PKG-INFO)" "--url=https://arvados.org" "--description=The Keep FUSE driver"
+
+# The node manager
+cd $WORKSPACE/debs
+build_and_scp_deb $WORKSPACE/services/nodemanager arvados-node-manager 'Curoverse, Inc.' 'python' "$(awk '($1 == "Version:"){print $2}' $WORKSPACE/services/nodemanager/arvados_node_manager.egg-info/PKG-INFO)" "--url=https://arvados.org" "--description=The Arvados node manager"
 
 # A few dependencies
-build_and_scp_deb python-gflags
-build_and_scp_deb pyvcf
-build_and_scp_deb google-api-python-client
-build_and_scp_deb httplib2
-build_and_scp_deb ws4py
-build_and_scp_deb virtualenv
+for deppkg in python-gflags pyvcf google-api-python-client oauth2client \
+      pyasn1 pyasn1-modules rsa uritemplate httplib2 ws4py virtualenv \
+      pykka apache-libcloud requests six; do
+    build_and_scp_deb "$deppkg"
+done
 
 # Finally, publish the packages, if necessary
-if [[ "$CALL_PRM" != "0" ]]; then
-  ssh -p2222 $APTUSER@$APTSERVER -t "cd /var/www/$APTSERVER; /usr/local/rvm/bin/rvm default do prm --type deb -p . --component main --release wheezy --arch amd64  -d /home/$APTUSER/tmp/ --gpg 1078ECD7"
+if [[ "$UPLOAD" != 0 && "$CALL_FREIGHT" != 0 ]]; then
+  ssh -p2222 $APTUSER@$APTSERVER -t "cd tmp && ls -laF *deb && freight add *deb apt/wheezy && freight cache && rm -f *deb"
 else
-  echo "No new packages generated. No PRM run necessary."
+  if [[ "$UPLOAD" != 0 ]]; then
+    echo "No new packages generated. No freight run necessary."
+  fi
 fi
 
+# clean up temporary GOPATH
+rm -rf "$GOPATH"
+
+exit $EXITCODE