14325: Merge branch 'master'
authorTom Clegg <tclegg@veritasgenetics.com>
Wed, 6 Feb 2019 21:27:57 +0000 (16:27 -0500)
committerTom Clegg <tclegg@veritasgenetics.com>
Wed, 6 Feb 2019 21:27:57 +0000 (16:27 -0500)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg@veritasgenetics.com>

89 files changed:
.gitignore
backports/deb-libfuse-dev/fpm-info.sh [deleted file]
backports/python-apache-libcloud/fpm-info.sh [deleted file]
backports/python-ciso8601/fpm-info.sh [deleted file]
backports/python-llfuse/fpm-info.sh [deleted file]
backports/python-pycurl/fpm-info.sh [deleted file]
build/build-dev-docker-jobs-image.sh
build/build.list [deleted file]
build/check-copyright-notices
build/package-build-dockerfiles/Makefile
build/package-build-dockerfiles/centos7/Dockerfile
build/package-build-dockerfiles/debian8/Dockerfile
build/package-build-dockerfiles/debian9/Dockerfile
build/package-build-dockerfiles/ubuntu1404/Dockerfile
build/package-build-dockerfiles/ubuntu1604/Dockerfile
build/package-build-dockerfiles/ubuntu1804/Dockerfile
build/package-test-dockerfiles/Makefile
build/package-test-dockerfiles/centos7/Dockerfile
build/package-test-dockerfiles/debian8/Dockerfile
build/package-test-dockerfiles/debian9/Dockerfile
build/package-test-dockerfiles/ubuntu1404/Dockerfile
build/package-test-dockerfiles/ubuntu1604/Dockerfile
build/package-test-dockerfiles/ubuntu1804/Dockerfile
build/package-testing/deb-common-test-packages.sh
build/package-testing/rpm-common-test-packages.sh
build/package-testing/test-package-arvados-node-manager.sh
build/package-testing/test-package-python27-python-arvados-cwl-runner.sh
build/package-testing/test-package-python27-python-arvados-fuse.sh
build/package-testing/test-package-python27-python-arvados-python-client.sh
build/run-build-docker-jobs-image.sh
build/run-build-packages-one-target.sh
build/run-build-packages.sh
build/run-library.sh
build/run-tests.sh
doc/admin/upgrading.html.textile.liquid
doc/sdk/python/sdk-python.html.textile.liquid
sdk/cli/bin/crunch-job
sdk/cwl/arvados_cwl/__init__.py
sdk/cwl/arvados_cwl/arvcontainer.py
sdk/cwl/arvados_cwl/arvjob.py
sdk/cwl/arvados_cwl/arvtool.py
sdk/cwl/arvados_cwl/arvworkflow.py
sdk/cwl/arvados_cwl/crunch_script.py
sdk/cwl/arvados_cwl/done.py
sdk/cwl/arvados_cwl/executor.py
sdk/cwl/arvados_cwl/fsaccess.py
sdk/cwl/arvados_cwl/http.py
sdk/cwl/arvados_cwl/pathmapper.py
sdk/cwl/arvados_cwl/perf.py
sdk/cwl/arvados_cwl/runner.py
sdk/cwl/arvados_cwl/task_queue.py
sdk/cwl/arvados_cwl/util.py
sdk/cwl/arvados_version.py
sdk/cwl/fpm-info.sh [moved from backports/python-pycrypto/fpm-info.sh with 51% similarity]
sdk/cwl/gittaggers.py
sdk/cwl/setup.py
sdk/cwl/test_with_arvbox.sh
sdk/cwl/tests/12213-keepref-expr.cwl
sdk/cwl/tests/arvados-tests.yml
sdk/cwl/tests/federation/framework/check_exist.py
sdk/cwl/tests/federation/framework/prepare.py
sdk/cwl/tests/hw.py
sdk/cwl/tests/matcher.py
sdk/cwl/tests/test_container.py
sdk/cwl/tests/test_http.py
sdk/cwl/tests/test_job.py
sdk/cwl/tests/test_make_output.py
sdk/cwl/tests/test_submit.py
sdk/cwl/tests/test_urljoin.py
sdk/cwl/tests/test_util.py
sdk/cwl/tests/wf/check_mem.py
sdk/dev-jobs.dockerfile
sdk/pam/fpm-info.sh
sdk/pam/lib/libpam_arvados.py
sdk/python/arvados/commands/keepdocker.py
sdk/python/fpm-info.sh [moved from backports/deb-fuse/fpm-info.sh with 68% similarity]
sdk/python/setup.py
services/dockercleaner/README.rst [new file with mode: 0644]
services/dockercleaner/arvados-docker-cleaner.service
services/dockercleaner/bin/arvados-docker-cleaner [new file with mode: 0755]
services/fuse/fpm-info.sh
services/nodemanager/fpm-info.sh [new file with mode: 0644]
tools/arvbox/bin/arvbox
tools/arvbox/lib/arvbox/docker/Dockerfile.base
tools/arvbox/lib/arvbox/docker/common.sh
tools/arvbox/lib/arvbox/docker/service/certificate/run
tools/crunchstat-summary/README.rst [new file with mode: 0644]
tools/crunchstat-summary/fpm-info.sh [new file with mode: 0644]
tools/crunchstat-summary/setup.py

index 517166c3fbd2043bff880db2b11b97238e4eb5f2..db3020ae82d13231817872355b04dd09849f87a0 100644 (file)
@@ -29,4 +29,5 @@ services/api/config/arvados-clients.yml
 .DS_Store
 .vscode
 .Rproj.user
-_version.py
\ No newline at end of file
+_version.py
+*.bak
diff --git a/backports/deb-libfuse-dev/fpm-info.sh b/backports/deb-libfuse-dev/fpm-info.sh
deleted file mode 100644 (file)
index 46088c0..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (C) The Arvados Authors. All rights reserved.
-#
-# SPDX-License-Identifier: Apache-2.0
-
-case "$TARGET" in
-    ubuntu1204)
-        fpm_depends+=('libfuse2 = 2.9.2-5')
-        ;;
-esac
diff --git a/backports/python-apache-libcloud/fpm-info.sh b/backports/python-apache-libcloud/fpm-info.sh
deleted file mode 100644 (file)
index c866168..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-# Copyright (C) The Arvados Authors. All rights reserved.
-#
-# SPDX-License-Identifier: Apache-2.0
-
-case $TARGET in
-     centos7)
-         # fpm incorrectly transforms the dependency name in this case.
-         fpm_depends+=(python-backports-ssl_match_hostname)
-         fpm_args+=(--python-disable-dependency backports.ssl-match-hostname)
-     ;;
-esac
diff --git a/backports/python-ciso8601/fpm-info.sh b/backports/python-ciso8601/fpm-info.sh
deleted file mode 100644 (file)
index 7e24f5d..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (C) The Arvados Authors. All rights reserved.
-#
-# SPDX-License-Identifier: Apache-2.0
-
-case "$TARGET" in
-    centos*)
-        fpm_depends+=(glibc)
-        ;;
-    debian* | ubuntu*)
-        fpm_depends+=(libc6)
-        ;;
-esac
diff --git a/backports/python-llfuse/fpm-info.sh b/backports/python-llfuse/fpm-info.sh
deleted file mode 100644 (file)
index ef0b446..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) The Arvados Authors. All rights reserved.
-#
-# SPDX-License-Identifier: Apache-2.0
-
-case "$TARGET" in
-    centos*)
-        build_depends+=('fuse-devel')
-        fpm_depends+=(glibc fuse-libs)
-        ;;
-    ubuntu1204)
-        build_depends+=(libfuse2 libfuse-dev)
-        fpm_depends+=(libc6 python-contextlib2 'libfuse2 = 2.9.2-5' 'fuse = 2.9.2-5')
-        ;;
-    debian* | ubuntu*)
-        build_depends+=('libfuse-dev')
-        fpm_depends+=(libc6 'libfuse2 > 2.9.0' 'fuse > 2.9.0')
-        ;;
-esac
diff --git a/backports/python-pycurl/fpm-info.sh b/backports/python-pycurl/fpm-info.sh
deleted file mode 100644 (file)
index 8ec9c79..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-# Copyright (C) The Arvados Authors. All rights reserved.
-#
-# SPDX-License-Identifier: Apache-2.0
-
-case "$TARGET" in
-    debian8)
-            fpm_depends+=(
-                libc6
-                libcomerr2
-                libcurl3-gnutls
-                libffi6
-                libgcrypt20
-                libgmp10
-                libgnutls-deb0-28
-                libgpg-error0
-                libgssapi-krb5-2
-                libhogweed2
-                libidn11
-                libk5crypto3
-                libkeyutils1
-                libkrb5-3
-                libkrb5support0
-                libldap-2.4-2
-                libnettle4
-                libp11-kit0
-                librtmp1
-                libsasl2-2
-                libssh2-1
-                libtasn1-6
-                zlib1g
-            ) ;;
-    ubuntu1204)
-            fpm_depends+=(
-                libasn1-8-heimdal
-                libc6
-                libcomerr2
-                libcurl3-gnutls
-                libgcrypt11
-                libgnutls26
-                libgpg-error0
-                libgssapi-krb5-2
-                libgssapi3-heimdal
-                libhcrypto4-heimdal
-                libheimbase1-heimdal
-                libheimntlm0-heimdal
-                libhx509-5-heimdal
-                libidn11
-                libk5crypto3
-                libkeyutils1
-                libkrb5-26-heimdal
-                libkrb5-3
-                libkrb5support0
-                libldap-2.4-2
-                libp11-kit0
-                libroken18-heimdal
-                librtmp0
-                libsasl2-2
-                libsqlite3-0
-                libtasn1-3
-                libwind0-heimdal
-                zlib1g
-            ) ;;
-    ubuntu1404)
-            fpm_depends+=(
-                libasn1-8-heimdal
-                libc6
-                libcomerr2
-                libcurl3-gnutls
-                libffi6
-                libgcrypt11
-                libgnutls26
-                libgpg-error0
-                libgssapi-krb5-2
-                libgssapi3-heimdal
-                libhcrypto4-heimdal
-                libheimbase1-heimdal
-                libheimntlm0-heimdal
-                libhx509-5-heimdal
-                libidn11
-                libk5crypto3
-                libkeyutils1
-                libkrb5-26-heimdal
-                libkrb5-3
-                libkrb5support0
-                libldap-2.4-2
-                libp11-kit0
-                libroken18-heimdal
-                librtmp0
-                libsasl2-2
-                libsqlite3-0
-                libtasn1-6
-                libwind0-heimdal
-                zlib1g
-            ) ;;
-esac
index 9393c1accec46a4e6e3bb6cb35df3cd4bef54bf6..2e4c4573823e4d67efc84ad22b70c4ec915aff95 100755 (executable)
@@ -16,6 +16,7 @@ Syntax:
 WORKSPACE=path         Path to the Arvados source tree to build packages from
 CWLTOOL=path           (optional) Path to cwltool git repository.
 SALAD=path             (optional) Path to schema_salad git repository.
+PYCMD=pythonexec       (optional) Specify the python executable to use in the docker image. Defaults to "python".
 
 EOF
 
@@ -35,6 +36,11 @@ fi
 
 cd "$WORKSPACE"
 
+py=python
+if [[ -n "$PYCMD" ]] ; then
+    py="$PYCMD" ;
+fi
+
 (cd sdk/python && python setup.py sdist)
 sdk=$(cd sdk/python/dist && ls -t arvados-python-client-*.tar.gz | head -n1)
 
@@ -69,6 +75,6 @@ if [[ $python_sdk_ts -gt $cwl_runner_ts ]]; then
     cwl_runner_version=$(cd sdk/python && nohash_version_from_git 1.0)
 fi
 
-docker build --build-arg sdk=$sdk --build-arg runner=$runner --build-arg salad=$salad --build-arg cwltool=$cwltool -f "$WORKSPACE/sdk/dev-jobs.dockerfile" -t arvados/jobs:$cwl_runner_version "$WORKSPACE/sdk"
+docker build --build-arg sdk=$sdk --build-arg runner=$runner --build-arg salad=$salad --build-arg cwltool=$cwltool --build-arg pythoncmd=$py -f "$WORKSPACE/sdk/dev-jobs.dockerfile" -t arvados/jobs:$cwl_runner_version "$WORKSPACE/sdk"
 echo arv-keepdocker arvados/jobs $cwl_runner_version
 arv-keepdocker arvados/jobs $cwl_runner_version
diff --git a/build/build.list b/build/build.list
deleted file mode 100644 (file)
index 502460b..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (C) The Arvados Authors. All rights reserved.
-#
-# SPDX-License-Identifier: AGPL-3.0
-
-#distribution(s)|name|version|iteration|type|architecture|extra fpm arguments
-debian8,debian9,centos7|python-gflags|2.0|2|python|all
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804,centos7|google-api-python-client|1.6.2|2|python|all
-debian8,debian9,ubuntu1404,centos7|oauth2client|1.5.2|2|python|all
-debian8,debian9,ubuntu1404,centos7|pyasn1|0.1.7|2|python|all
-debian8,debian9,ubuntu1404,centos7|pyasn1-modules|0.0.5|2|python|all
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804,centos7|rsa|3.4.2|2|python|all
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804,centos7|uritemplate|3.0.0|2|python|all
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804,centos7|httplib2|0.9.2|3|python|all
-debian8,debian9,centos7,ubuntu1404,ubuntu1604|ws4py|0.4.2|2|python|all
-debian8,debian9,centos7|pykka|1.2.1|2|python|all
-debian8,debian9,ubuntu1404,centos7|six|1.10.0|2|python|all
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804,centos7|ciso8601|1.0.6|3|python|amd64
-debian8,debian9,centos7|pycrypto|2.6.1|3|python|amd64
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804|backports.ssl_match_hostname|3.5.0.1|2|python|all
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804,centos7|llfuse|1.2|3|python|amd64
-debian8,debian9,ubuntu1404,centos7|pycurl|7.19.5.3|3|python|amd64
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804,centos7|pyyaml|3.12|2|python|amd64
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804,centos7|rdflib|4.2.2|2|python|all
-debian8,debian9,ubuntu1404,centos7|shellescape|3.4.1|2|python|all
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804,centos7|mistune|0.8.1|2|python|all
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804,centos7|typing|3.6.4|2|python|all
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804,centos7|avro|1.8.1|2|python|all
-debian8,debian9,ubuntu1404,centos7|ruamel.ordereddict|0.4.9|2|python|amd64
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804,centos7|cachecontrol|0.11.7|2|python|all
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804,centos7|pathlib2|2.3.2|2|python|all
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804,centos7|scandir|1.7|2|python|all
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804,centos7|docker-py|1.7.2|2|python3|all
-debian8,debian9,centos7|six|1.10.0|2|python3|all
-debian8,debian9,ubuntu1404,centos7|requests|2.12.4|2|python3|all
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804,centos7|websocket-client|0.37.0|2|python3|all
-debian8,ubuntu1404,centos7|requests|2.6.1|2|python|all
-centos7|contextlib2|0.5.4|2|python|all
-centos7|isodate|0.5.4|2|python|all
-centos7|python-daemon|2.1.2|1|python|all
-centos7|pbr|0.11.1|2|python|all
-centos7|pyparsing|2.1.10|2|python|all
-centos7|keepalive|0.5|2|python|all
-centos7|networkx|1.11|0|python|all
-centos7|psutil|5.0.1|0|python|all
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804,centos7|lockfile|0.12.2|2|python|all|--epoch 1
-debian8,debian9,ubuntu1404,ubuntu1604,ubuntu1804,centos7|subprocess32|3.5.1|2|python|all
-all|ruamel.yaml|0.15.77|1|python|amd64|--python-setup-py-arguments --single-version-externally-managed --depends 'python-ruamel.ordereddict >= 0.4.9'
-all|cwltest|1.0.20180518074130|4|python|all|--depends 'python-futures >= 3.0.5' --depends 'python-subprocess32 >= 3.5.0'
-all|junit-xml|1.8|3|python|all
-all|rdflib-jsonld|0.4.0|2|python|all
-all|futures|3.0.5|2|python|all
-all|future|0.16.0|2|python|all
-all|future|0.16.0|2|python3|all
-all|mypy-extensions|0.3.0|1|python|all
-all|prov|1.5.1|0|python|all
-all|bagit|1.6.4|0|python|all
-all|typing-extensions|3.6.5|0|python|all
index 2a40b50ec1f5b94c2523e293871d04005d962973..ba08f34bcd46ebffd64adb7d387714f4b97d189b 100755 (executable)
@@ -180,7 +180,7 @@ ${cc}${cc:+ }SPDX-License-Identifier: CC-BY-SA-3.0${ce}"
         Makefile | build/* | lib/* | tools/* | apps/* | services/* | sdk/cli/bin/crunch-job)
             want=${wantGPL}
             ;;
-        crunch_scripts/* | backports/* | docker/* | sdk/*)
+        crunch_scripts/* | docker/* | sdk/*)
             want=${wantApache}
             ;;
         doc/*)
index 6591319029f131dd81a32665c2bc35fe5ef9a9d8..523205021304cb1462c4da66d966072293972e4a 100644 (file)
@@ -30,9 +30,10 @@ ubuntu1804/generated: common-generated-all
 
 GOTARBALL=go1.10.1.linux-amd64.tar.gz
 NODETARBALL=node-v6.11.2-linux-x64.tar.xz
-RVMKEY=rvm.asc
+RVMKEY1=mpapis.asc
+RVMKEY2=pkuczynski.asc
 
-common-generated-all: common-generated/$(GOTARBALL) common-generated/$(NODETARBALL) common-generated/$(RVMKEY)
+common-generated-all: common-generated/$(GOTARBALL) common-generated/$(NODETARBALL) common-generated/$(RVMKEY1) common-generated/$(RVMKEY2)
 
 common-generated/$(GOTARBALL): common-generated
        wget -cqO common-generated/$(GOTARBALL) http://storage.googleapis.com/golang/$(GOTARBALL)
@@ -40,8 +41,11 @@ common-generated/$(GOTARBALL): common-generated
 common-generated/$(NODETARBALL): common-generated
        wget -cqO common-generated/$(NODETARBALL) https://nodejs.org/dist/v6.11.2/$(NODETARBALL)
 
-common-generated/$(RVMKEY): common-generated
-       wget -cqO common-generated/$(RVMKEY) https://rvm.io/pkuczynski.asc
+common-generated/$(RVMKEY1): common-generated
+       wget -cqO common-generated/$(RVMKEY1) https://rvm.io/mpapis.asc
+
+common-generated/$(RVMKEY2): common-generated
+       wget -cqO common-generated/$(RVMKEY2) https://rvm.io/pkuczynski.asc
 
 common-generated:
        mkdir common-generated
index ba616eef1aeefcf36c67edfaa6cc62dc6226f008..522189a20cd92625652a4ee38d9c2f02222135b4 100644 (file)
@@ -6,11 +6,13 @@ FROM centos:7
 MAINTAINER Ward Vandewege <ward@curoverse.com>
 
 # Install dependencies.
-RUN yum -q -y install make automake gcc gcc-c++ libyaml-devel patch readline-devel zlib-devel libffi-devel openssl-devel bzip2 libtool bison sqlite-devel rpm-build git perl-ExtUtils-MakeMaker libattr-devel nss-devel libcurl-devel which tar unzip scl-utils centos-release-scl postgresql-devel python-devel python-setuptools fuse-devel xz-libs git
+RUN yum -q -y install make automake gcc gcc-c++ libyaml-devel patch readline-devel zlib-devel libffi-devel openssl-devel bzip2 libtool bison sqlite-devel rpm-build git perl-ExtUtils-MakeMaker libattr-devel nss-devel libcurl-devel which tar unzip scl-utils centos-release-scl postgresql-devel python-devel python-setuptools fuse-devel xz-libs git python-virtualenv wget
 
 # Install RVM
-ADD generated/rvm.asc /tmp/
-RUN gpg --import /tmp/rvm.asc && \
+ADD generated/mpapis.asc /tmp/
+ADD generated/pkuczynski.asc /tmp/
+RUN gpg --import --no-tty /tmp/mpapis.asc && \
+    gpg --import --no-tty /tmp/pkuczynski.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.3 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.3 && \
@@ -27,13 +29,17 @@ RUN ln -s /usr/local/node-v6.11.2-linux-x64/bin/* /usr/local/bin/
 
 # Need to "touch" RPM database to workaround bug in interaction between
 # overlayfs and yum (https://bugzilla.redhat.com/show_bug.cgi?id=1213602)
-RUN touch /var/lib/rpm/* && yum -q -y install python33
-RUN scl enable python33 "easy_install-3.3 pip" && easy_install-2.7 pip
+RUN touch /var/lib/rpm/* && yum -q -y install rh-python35
+RUN scl enable rh-python35 "easy_install-3.5 pip" && easy_install-2.7 pip
 
 # Old versions of setuptools cannot build a schema-salad package.
 RUN pip install --upgrade setuptools
 
+# Add epel, we need it for the python-pam dependency
+RUN wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
+RUN rpm -ivh epel-release-latest-7.noarch.rpm
+
 RUN git clone --depth 1 git://git.curoverse.com/arvados.git /tmp/arvados && cd /tmp/arvados/services/api && /usr/local/rvm/bin/rvm-exec default bundle && cd /tmp/arvados/apps/workbench && /usr/local/rvm/bin/rvm-exec default bundle && rm -rf /tmp/arvados
 
 ENV WORKSPACE /arvados
-CMD ["scl", "enable", "python33", "/usr/local/rvm/bin/rvm-exec default bash /jenkins/run-build-packages.sh --target centos7"]
+CMD ["scl", "enable", "rh-python35", "/usr/local/rvm/bin/rvm-exec default bash /jenkins/run-build-packages.sh --target centos7"]
index 1244e3f55d4ac244742f9a3bfb803dde9b7aca2d..1e6c62ce7ea72fba1380260bb2c7c07dbc19c87c 100644 (file)
@@ -8,11 +8,16 @@ MAINTAINER Ward Vandewege <ward@curoverse.com>
 ENV DEBIAN_FRONTEND noninteractive
 
 # Install dependencies.
-RUN /usr/bin/apt-get update && /usr/bin/apt-get install -q -y python2.7-dev python3 python-setuptools python3-setuptools libcurl4-gnutls-dev curl git procps libattr1-dev libfuse-dev libgnutls28-dev libpq-dev python-pip unzip
+RUN /usr/bin/apt-get update && /usr/bin/apt-get install -q -y python2.7-dev python3 python-setuptools python3-setuptools libcurl4-gnutls-dev curl git procps libattr1-dev libfuse-dev libgnutls28-dev libpq-dev python-pip unzip python3-venv python3-dev
+
+# Install virtualenv
+RUN /usr/bin/pip install virtualenv
 
 # Install RVM
-ADD generated/rvm.asc /tmp/
-RUN gpg --import /tmp/rvm.asc && \
+ADD generated/mpapis.asc /tmp/
+ADD generated/pkuczynski.asc /tmp/
+RUN gpg --import --no-tty /tmp/mpapis.asc && \
+    gpg --import --no-tty /tmp/pkuczynski.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.3 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.3 && \
index 42094d53bb8a4d982afce90b5a65bd28dd3fd763..fcaf0bc0a1bb74cb134847eed3cbde9fc14f0c80 100644 (file)
@@ -9,11 +9,16 @@ MAINTAINER Nico Cesar <nico@curoverse.com>
 ENV DEBIAN_FRONTEND noninteractive
 
 # Install dependencies.
-RUN /usr/bin/apt-get update && /usr/bin/apt-get install -q -y python2.7-dev python3 python-setuptools python3-setuptools libcurl4-gnutls-dev curl git procps libattr1-dev libfuse-dev libgnutls28-dev libpq-dev python-pip unzip
+RUN /usr/bin/apt-get update && /usr/bin/apt-get install -q -y python2.7-dev python3 python-setuptools python3-setuptools libcurl4-gnutls-dev curl git procps libattr1-dev libfuse-dev libgnutls28-dev libpq-dev python-pip unzip python3-venv python3-dev
+
+# Install virtualenv
+RUN /usr/bin/pip install virtualenv
 
 # Install RVM
-ADD generated/rvm.asc /tmp/
-RUN gpg --no-tty --import /tmp/rvm.asc && \
+ADD generated/mpapis.asc /tmp/
+ADD generated/pkuczynski.asc /tmp/
+RUN gpg --import --no-tty /tmp/mpapis.asc && \
+    gpg --import --no-tty /tmp/pkuczynski.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.3 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.3 && \
index a6bf65bc11a84c12b32c3231c33257ff28be9c65..a88435a5b4bb0e98fd646f7ede5e03a45c5490bd 100644 (file)
@@ -8,11 +8,16 @@ MAINTAINER Ward Vandewege <ward@curoverse.com>
 ENV DEBIAN_FRONTEND noninteractive
 
 # Install dependencies.
-RUN /usr/bin/apt-get update && /usr/bin/apt-get install -q -y python2.7-dev python3 python-setuptools python3-setuptools libcurl4-gnutls-dev curl git libattr1-dev libfuse-dev libpq-dev python-pip unzip 
+RUN /usr/bin/apt-get update && /usr/bin/apt-get install -q -y python2.7-dev python3 python-setuptools python3-setuptools libcurl4-gnutls-dev curl git libattr1-dev libfuse-dev libpq-dev python-pip unzip python3.4-venv python3.4-dev
+
+# Install virtualenv
+RUN /usr/bin/pip install virtualenv
 
 # Install RVM
-ADD generated/rvm.asc /tmp/
-RUN gpg --import /tmp/rvm.asc && \
+ADD generated/mpapis.asc /tmp/
+ADD generated/pkuczynski.asc /tmp/
+RUN gpg --import --no-tty /tmp/mpapis.asc && \
+    gpg --import --no-tty /tmp/pkuczynski.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.3 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.3 && \
index 17bf89f3b64a253a0421846974801f2ebc6ffbf0..be3911eff3e94ee6907efc883a8da047a4622ae4 100644 (file)
@@ -8,11 +8,16 @@ MAINTAINER Ward Vandewege <ward@curoverse.com>
 ENV DEBIAN_FRONTEND noninteractive
 
 # Install dependencies.
-RUN /usr/bin/apt-get update && /usr/bin/apt-get install -q -y python2.7-dev python3 python-setuptools python3-setuptools libcurl4-gnutls-dev libgnutls-dev curl git libattr1-dev libfuse-dev libpq-dev python-pip unzip tzdata
+RUN /usr/bin/apt-get update && /usr/bin/apt-get install -q -y python2.7-dev python3 python-setuptools python3-setuptools libcurl4-gnutls-dev libgnutls-dev curl git libattr1-dev libfuse-dev libpq-dev python-pip unzip tzdata python3-venv python3-dev
+
+# Install virtualenv
+RUN /usr/bin/pip install virtualenv
 
 # Install RVM
-ADD generated/rvm.asc /tmp/
-RUN gpg --import /tmp/rvm.asc && \
+ADD generated/mpapis.asc /tmp/
+ADD generated/pkuczynski.asc /tmp/
+RUN gpg --import --no-tty /tmp/mpapis.asc && \
+    gpg --import --no-tty /tmp/pkuczynski.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.3 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.3 && \
index c66de46908daef3de6700c9b790917fde6c08e85..8995d14be0bdc55cbdeb47c005c2323f648b6bc4 100644 (file)
@@ -8,11 +8,16 @@ MAINTAINER Ward Vandewege <ward@curoverse.com>
 ENV DEBIAN_FRONTEND noninteractive
 
 # Install dependencies.
-RUN /usr/bin/apt-get update && /usr/bin/apt-get install -q -y python2.7-dev python3 python-setuptools python3-pip libcurl4-gnutls-dev libgnutls28-dev curl git libattr1-dev libfuse-dev libpq-dev python-pip unzip tzdata
+RUN /usr/bin/apt-get update && /usr/bin/apt-get install -q -y python2.7-dev python3 python-setuptools python3-pip libcurl4-gnutls-dev libgnutls28-dev curl git libattr1-dev libfuse-dev libpq-dev python-pip unzip tzdata python3-venv python3-dev
+
+# Install virtualenv
+RUN /usr/bin/pip install virtualenv
 
 # Install RVM
-ADD generated/rvm.asc /tmp/
-RUN gpg --import /tmp/rvm.asc && \
+ADD generated/mpapis.asc /tmp/
+ADD generated/pkuczynski.asc /tmp/
+RUN gpg --import --no-tty /tmp/mpapis.asc && \
+    gpg --import --no-tty /tmp/pkuczynski.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.3 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.3 && \
index 7b52511396fbe1b61ef1a87ec8b27893c43eb5f8..c6d5a15fbab5915f0854b300a72d522aa90b5b29 100644 (file)
@@ -28,12 +28,16 @@ ubuntu1804/generated: common-generated-all
        test -d ubuntu1804/generated || mkdir ubuntu1804/generated
        cp -rlt ubuntu1804/generated common-generated/*
 
-RVMKEY=rvm.asc
+RVMKEY1=mpapis.asc
+RVMKEY2=pkuczynski.asc
 
-common-generated-all: common-generated/$(RVMKEY)
+common-generated-all: common-generated/$(RVMKEY1) common-generated/$(RVMKEY2)
 
-common-generated/$(RVMKEY): common-generated
-       wget -cqO common-generated/$(RVMKEY) https://rvm.io/pkuczynski.asc
+common-generated/$(RVMKEY1): common-generated
+       wget -cqO common-generated/$(RVMKEY1) https://rvm.io/mpapis.asc
+
+common-generated/$(RVMKEY2): common-generated
+       wget -cqO common-generated/$(RVMKEY2) https://rvm.io/pkuczynski.asc
 
 common-generated:
        mkdir common-generated
index 36be0ba32b0ac0cb11ee30a416e6d8c380a96989..0bfe80b70d87178619d0e9a8049cfa23f61a0acd 100644 (file)
@@ -6,16 +6,20 @@ FROM centos:7
 MAINTAINER Ward Vandewege <wvandewege@veritasgenetics.com>
 
 # Install dependencies.
-RUN yum -q -y install scl-utils centos-release-scl which tar
+RUN yum -q -y install scl-utils centos-release-scl which tar wget
 
 # Install RVM
-ADD generated/rvm.asc /tmp/
+ADD generated/mpapis.asc /tmp/
+ADD generated/pkuczynski.asc /tmp/
 RUN touch /var/lib/rpm/* && \
-    gpg --import /tmp/rvm.asc && \
+    gpg --import --no-tty /tmp/mpapis.asc && \
+    gpg --import --no-tty /tmp/pkuczynski.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.3 && \
-    /usr/local/rvm/bin/rvm alias create default ruby-2.3 && \
-    /usr/local/rvm/bin/rvm-exec default gem install bundle && \
-    /usr/local/rvm/bin/rvm-exec default gem install cure-fpm --version 1.6.0b
+    /usr/local/rvm/bin/rvm alias create default ruby-2.3
+
+# Add epel, we need it for the python-pam dependency
+RUN wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
+RUN rpm -ivh epel-release-latest-7.noarch.rpm
 
 COPY localrepo.repo /etc/yum.repos.d/localrepo.repo
index fdefadea5080e4cacbd2ecbba04b7c5db1fd9b90..2168f725a1a5a3d9cf7fcbfafb50b28733870f79 100644 (file)
@@ -12,8 +12,10 @@ RUN apt-get update && \
     apt-get -y install --no-install-recommends curl ca-certificates
 
 # Install RVM
-ADD generated/rvm.asc /tmp/
-RUN gpg --import /tmp/rvm.asc && \
+ADD generated/mpapis.asc /tmp/
+ADD generated/pkuczynski.asc /tmp/
+RUN gpg --import --no-tty /tmp/mpapis.asc && \
+    gpg --import --no-tty /tmp/pkuczynski.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.3 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.3
index c682ccc7cb05f84fbe68d56c60a4846c3448fe69..9c46ef601313939d38549fbd44fa32bee44bfbfb 100644 (file)
@@ -12,8 +12,10 @@ RUN apt-get update && \
     apt-get -y install --no-install-recommends curl ca-certificates gpg procps
 
 # Install RVM
-ADD generated/rvm.asc /tmp/
-RUN gpg --no-tty --import /tmp/rvm.asc && \
+ADD generated/mpapis.asc /tmp/
+ADD generated/pkuczynski.asc /tmp/
+RUN gpg --import --no-tty /tmp/mpapis.asc && \
+    gpg --import --no-tty /tmp/pkuczynski.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.3 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.3
index 5f5b1d88191b0ddf3019594094a505b0fac13ba5..c05dbee0f3b88bc4bb12964ce72d04efc5a66869 100644 (file)
@@ -12,8 +12,10 @@ RUN apt-get update && \
     apt-get -y install --no-install-recommends curl ca-certificates python2.7-dev python3 python-setuptools python3-setuptools libcurl4-gnutls-dev curl git libattr1-dev libfuse-dev libpq-dev python-pip unzip binutils build-essential ca-certificates
 
 # Install RVM
-ADD generated/rvm.asc /tmp/
-RUN gpg --import /tmp/rvm.asc && \
+ADD generated/mpapis.asc /tmp/
+ADD generated/pkuczynski.asc /tmp/
+RUN gpg --import --no-tty /tmp/mpapis.asc && \
+    gpg --import --no-tty /tmp/pkuczynski.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.3 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.3
index 1f65c7a474c3226976f1516850b1059094a493c0..615ab1c00e9a48ba598f88c323b0fbc69e084d46 100644 (file)
@@ -12,8 +12,10 @@ RUN apt-get update && \
     apt-get -y install --no-install-recommends curl ca-certificates
 
 # Install RVM
-ADD generated/rvm.asc /tmp/
-RUN gpg --import /tmp/rvm.asc && \
+ADD generated/mpapis.asc /tmp/
+ADD generated/pkuczynski.asc /tmp/
+RUN gpg --import --no-tty /tmp/mpapis.asc && \
+    gpg --import --no-tty /tmp/pkuczynski.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.3 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.3
index 9d326c72946bb645900637ebc852b87c2d253743..d530d22a292545873331b65e8d27201e1d5ab747 100644 (file)
@@ -12,8 +12,10 @@ RUN apt-get update && \
     apt-get -y install --no-install-recommends curl ca-certificates gnupg2
 
 # Install RVM
-ADD generated/rvm.asc /tmp/
-RUN gpg --import /tmp/rvm.asc && \
+ADD generated/mpapis.asc /tmp/
+ADD generated/pkuczynski.asc /tmp/
+RUN gpg --import --no-tty /tmp/mpapis.asc && \
+    gpg --import --no-tty /tmp/pkuczynski.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.3 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.3
index b5325224ee170bbc6170babfa8c2b95665d2057a..77017ba9702cb870ed83cb982fe3b135a779e6e6 100755 (executable)
@@ -2,9 +2,19 @@
 # Copyright (C) The Arvados Authors. All rights reserved.
 #
 # SPDX-License-Identifier: AGPL-3.0
-
 set -eu
 
+# Set up
+DEBUG=${ARVADOS_DEBUG:-0}
+STDOUT_IF_DEBUG=/dev/null
+STDERR_IF_DEBUG=/dev/null
+DASHQQ_UNLESS_DEBUG=-qq
+if [[ "$DEBUG" != "0" ]]; then
+  STDOUT_IF_DEBUG=/dev/stdout
+  STDERR_IF_DEBUG=/dev/stderr
+  DASHQQ_UNLESS_DEBUG=
+fi
+
 # Multiple .deb based distros symlink to this script, so extract the target
 # from the invocation path.
 target=$(echo $0 | sed 's/.*test-packages-\([^.]*\)\.sh.*/\1/')
@@ -13,8 +23,9 @@ export ARV_PACKAGES_DIR="/arvados/packages/$target"
 
 dpkg-query --show > "$ARV_PACKAGES_DIR/$1.before"
 
-apt-get -qq update
-apt-get --assume-yes --allow-unauthenticated install "$1"
+apt-get $DASHQQ_UNLESS_DEBUG update
+
+apt-get $DASHQQ_UNLESS_DEBUG -y --allow-unauthenticated install "$1" >"$STDOUT_IF_DEBUG" 2>"$STDERR_IF_DEBUG"
 
 dpkg-query --show > "$ARV_PACKAGES_DIR/$1.after"
 
@@ -35,12 +46,14 @@ fi
 
 dpkg-deb -x $debpkg .
 
-while read so && [ -n "$so" ]; do
-    echo
-    echo "== Packages dependencies for $so =="
-    ldd "$so" | awk '($3 ~ /^\//){print $3}' | sort -u | xargs dpkg -S | cut -d: -f1 | sort -u
-done <<EOF
+if [[ "$DEBUG" != "0" ]]; then
+  while read so && [ -n "$so" ]; do
+      echo
+      echo "== Packages dependencies for $so =="
+      ldd "$so" | awk '($3 ~ /^\//){print $3}' | sort -u | xargs dpkg -S | cut -d: -f1 | sort -u
+  done <<EOF
 $(find -name '*.so')
 EOF
+fi
 
 exec /jenkins/package-testing/common-test-packages.sh "$1"
index 268611cb7f50eba879e84c2e10f766b8ea4b6ff5..12450dd4f954acf65a58fe637880697be5918861 100755 (executable)
@@ -5,6 +5,15 @@
 
 set -eu
 
+# Set up
+DEBUG=${ARVADOS_DEBUG:-0}
+STDOUT_IF_DEBUG=/dev/null
+STDERR_IF_DEBUG=/dev/null
+if [[ "$DEBUG" != "0" ]]; then
+  STDOUT_IF_DEBUG=/dev/stdout
+  STDERR_IF_DEBUG=/dev/stderr
+fi
+
 target=$(basename "$0" | grep -Eo '\bcentos[[:digit:]]+\b')
 
 yum -q clean all
@@ -14,7 +23,7 @@ export ARV_PACKAGES_DIR="/arvados/packages/$target"
 
 rpm -qa | sort > "$ARV_PACKAGES_DIR/$1.before"
 
-yum install --assumeyes $1
+yum install --assumeyes -e 0 $1
 
 rpm -qa | sort > "$ARV_PACKAGES_DIR/$1.after"
 
@@ -41,10 +50,12 @@ cd /tmp/opts
 
 rpm2cpio $(ls -t "$ARV_PACKAGES_DIR/$1"-*.rpm | head -n1) | cpio -idm 2>/dev/null
 
-find -name '*.so' | while read so; do
-    echo -e "\n== Packages dependencies for $so =="
-    ldd "$so" \
-        | awk '($3 ~ /^\//){print $3}' | sort -u | xargs rpm -qf | sort -u
-done
+if [[ "$DEBUG" != "0" ]]; then
+  find -name '*.so' | while read so; do
+      echo -e "\n== Packages dependencies for $so =="
+      ldd "$so" \
+          | awk '($3 ~ /^\//){print $3}' | sort -u | xargs rpm -qf | sort -u
+  done
+fi
 
 exec /jenkins/package-testing/common-test-packages.sh "$1"
index c699fb45b54ae7ff7f89a8567aa4536147ef0bd8..9300f4cc6901af136fc0f93384ca5be8e45aa9d5 100755 (executable)
@@ -3,7 +3,11 @@
 #
 # SPDX-License-Identifier: AGPL-3.0
 
-exec python <<EOF
+set -e
+
+arvados-node-manager --version
+
+exec /usr/share/python2.7/dist/arvados-node-manager/bin/python2.7 <<EOF
 import libcloud.compute.types
 import libcloud.compute.providers
 libcloud.compute.providers.get_driver(libcloud.compute.types.Provider.AZURE_ARM)
index e499238d89eb2572af6beb6f9d9a05bce1dd8b31..99327c016ad618dbf69971a0960e19def60469e9 100755 (executable)
@@ -6,8 +6,3 @@
 set -e
 
 arvados-cwl-runner --version
-
-exec python <<EOF
-import arvados_cwl
-print "arvados-cwl-runner version", arvados_cwl.__version__
-EOF
index 152d1eb6979a520eb56fcb60f498752cd4847eb9..81929857b8eaa6791a3e47e196f578de6f17b9a0 100755 (executable)
@@ -3,7 +3,6 @@
 #
 # SPDX-License-Identifier: AGPL-3.0
 
-exec python <<EOF
-import arvados_fuse
-print "Successfully imported arvados_fuse"
-EOF
+set -e
+
+arv-mount --version
index 2603e034aad3cd35b79c54ee3e53d4eedb569df6..2c92a3efb354f5f0914e74363852ed315091d475 100755 (executable)
@@ -3,7 +3,11 @@
 #
 # SPDX-License-Identifier: AGPL-3.0
 
-exec python2.7 <<EOF
+set -e
+
+arv-put --version
+
+/usr/share/python2.7/dist/python-arvados-python-client/bin/python2.7 << EOF
 import arvados
 print "Successfully imported arvados"
 EOF
index 83bb5ae7165cb2cfd11879e85411253472887b26..7186a2209129a08c9c6fbd6a094ce6f0a9dac3c0 100755 (executable)
@@ -136,7 +136,7 @@ fi
 echo cwl_runner_version $cwl_runner_version python_sdk_version $python_sdk_version
 
 if [[ "${python_sdk_version}" != "${ARVADOS_BUILDING_VERSION}" ]]; then
-       python_sdk_version="${python_sdk_version}-2"
+       python_sdk_version="${python_sdk_version}-1"
 else
        python_sdk_version="${ARVADOS_BUILDING_VERSION}-${ARVADOS_BUILDING_ITERATION}"
 fi
@@ -144,7 +144,7 @@ fi
 cwl_runner_version_orig=$cwl_runner_version
 
 if [[ "${cwl_runner_version}" != "${ARVADOS_BUILDING_VERSION}" ]]; then
-       cwl_runner_version="${cwl_runner_version}-4"
+       cwl_runner_version="${cwl_runner_version}-1"
 else
        cwl_runner_version="${ARVADOS_BUILDING_VERSION}-${ARVADOS_BUILDING_ITERATION}"
 fi
index 46379e7b9ad0c5b29d1cd85797ad4cdbeb7e2e99..9b21b58e2af75d8968c68f7280adb707c8c444ba 100755 (executable)
@@ -74,6 +74,7 @@ while [ $# -gt 0 ]; do
             ;;
         --only-test)
             test_packages=1
+            testing_one_package=1
             packages="$2"; shift
             ;;
         --force-test)
@@ -121,33 +122,33 @@ if [[ -n "$ARVADOS_BUILDING_VERSION" ]]; then
 fi
 
 if [[ -n "$test_packages" ]]; then
-    if [[ -n "$(find $WORKSPACE/packages/$TARGET -name '*.rpm')" ]] ; then
-       set +e
-       /usr/bin/which createrepo >/dev/null
-       if [[ "$?" != "0" ]]; then
-               echo >&2
-               echo >&2 "Error: please install createrepo. E.g. sudo apt-get install createrepo"
-               echo >&2
-               exit 1
-       fi
-       set -e
-        createrepo $WORKSPACE/packages/$TARGET
+  if [[ -n "$(find $WORKSPACE/packages/$TARGET -name '*.rpm')" ]] ; then
+    set +e
+    /usr/bin/which createrepo >/dev/null
+    if [[ "$?" != "0" ]]; then
+      echo >&2
+      echo >&2 "Error: please install createrepo. E.g. sudo apt-get install createrepo"
+      echo >&2
+      exit 1
     fi
+    set -e
+    createrepo $WORKSPACE/packages/$TARGET
+  fi
 
-    if [[ -n "$(find $WORKSPACE/packages/$TARGET -name '*.deb')" ]] ; then
-        (cd $WORKSPACE/packages/$TARGET
-          dpkg-scanpackages .  2> >(grep -v 'warning' 1>&2) | tee Packages | gzip -c > Packages.gz
-          apt-ftparchive -o APT::FTPArchive::Release::Origin=Arvados release . > Release
-        )
-    fi
+  if [[ -n "$(find $WORKSPACE/packages/$TARGET -name '*.deb')" ]] ; then
+    (cd $WORKSPACE/packages/$TARGET
+      dpkg-scanpackages .  2> >(grep -v 'warning' 1>&2) | tee Packages | gzip -c > Packages.gz
+      apt-ftparchive -o APT::FTPArchive::Release::Origin=Arvados release . > Release
+    )
+  fi
 
-    COMMAND="/jenkins/package-testing/test-packages-$TARGET.sh"
-    IMAGE="arvados/package-test:$TARGET"
+  COMMAND="/jenkins/package-testing/test-packages-$TARGET.sh"
+  IMAGE="arvados/package-test:$TARGET"
 else
-    IMAGE="arvados/build:$TARGET"
-    if [[ "$COMMAND" != "" ]]; then
-        COMMAND="/usr/local/rvm/bin/rvm-exec default bash /jenkins/$COMMAND --target $TARGET$DEBUG"
-    fi
+  IMAGE="arvados/build:$TARGET"
+  if [[ "$COMMAND" != "" ]]; then
+    COMMAND="/usr/local/rvm/bin/rvm-exec default bash /jenkins/$COMMAND --target $TARGET$DEBUG"
+  fi
 fi
 
 JENKINS_DIR=$(dirname "$(readlink -e "$0")")
@@ -218,6 +219,17 @@ if [[ -n "$test_packages" ]]; then
             continue
           fi
         fi
+        # If we're testing all packages, we should not error out on packages that don't exist.
+        # If we are testing one specific package only (i.e. --only-test was given), we should
+        # error out if that package does not exist.
+        if [[ -z "$testing_one_package" ]]; then
+          MATCH=`find ${WORKSPACE}/packages/ -regextype posix-extended -regex .*${TARGET}/$p.*\\(deb\\|rpm\\)`
+          if [[ "$MATCH" == "" ]]; then
+            # No new package has been built that needs testing
+            echo "Skipping $p test because no package file is available to test."
+            continue
+          fi
+        fi
         echo
         echo "START: $p test on $IMAGE" >&2
         # ulimit option can be removed when debian8 and ubuntu1404 are retired
@@ -237,7 +249,9 @@ if [[ -n "$test_packages" ]]; then
         fi
     done
 
-    touch ${WORKSPACE}/packages/.last_test_${TARGET}
+    if [[ "$FINAL_EXITCODE" == "0" ]]; then
+      touch ${WORKSPACE}/packages/.last_test_${TARGET}
+    fi
 else
     echo
     echo "START: build packages on $IMAGE" >&2
index d81f2de39d40b29c3825e3d4785e3df2650489fc..b0199aed9767700a9e891e529a1b6fdc84415c25 100755 (executable)
@@ -30,8 +30,18 @@ WORKSPACE=path         Path to the Arvados source tree to build packages from
 
 EOF
 
-EXITCODE=0
+# Begin of user configuration
+
+# set to --no-cache-dir to disable pip caching
+CACHE_FLAG=
+
+MAINTAINER="Ward Vandewege <wvandewege@veritasgenetics.com>"
+VENDOR="Veritas Genetics, Inc."
+
+# End of user configuration
+
 DEBUG=${ARVADOS_DEBUG:-0}
+EXITCODE=0
 TARGET=debian8
 COMMAND=
 
@@ -117,7 +127,7 @@ case "$TARGET" in
         PYTHON2_INSTALL_LIB=lib/python$PYTHON2_VERSION/site-packages
         PYTHON3_PACKAGE=$(rpm -qf "$(which python$PYTHON3_VERSION)" --queryformat '%{NAME}\n')
         PYTHON3_PKG_PREFIX=$PYTHON3_PACKAGE
-        PYTHON3_PREFIX=/opt/rh/python33/root/usr
+        PYTHON3_PREFIX=/opt/rh/rh-python35/root/usr
         PYTHON3_INSTALL_LIB=lib/python$PYTHON3_VERSION/site-packages
         export PYCURL_SSL_LIBRARY=nss
         ;;
@@ -215,7 +225,7 @@ if [[ -z "$ONLY_BUILD" ]] || [[ "libarvados-perl" = "$ONLY_BUILD" ]] ; then
     perl Makefile.PL INSTALL_BASE=install >"$STDOUT_IF_DEBUG" && \
         make install INSTALLDIRS=perl >"$STDOUT_IF_DEBUG" && \
         fpm_build install/lib/=/usr/share libarvados-perl \
-        "Curoverse, Inc." dir "$(version_from_git)" install/man/=/usr/share/man \
+        dir "$(version_from_git)" install/man/=/usr/share/man \
         "$WORKSPACE/apache-2.0.txt=/usr/share/doc/libarvados-perl/apache-2.0.txt" && \
         mv --no-clobber libarvados-perl*.$FORMAT "$WORKSPACE/packages/$TARGET/"
   fi
@@ -277,10 +287,9 @@ handle_python_package
       cd "$SRC_BUILD_DIR"
       PKG_VERSION=$(version_from_git)
       cd $WORKSPACE/packages/$TARGET
-      fpm_build $SRC_BUILD_DIR/=/usr/local/arvados/src arvados-src 'Curoverse, Inc.' 'dir' "$PKG_VERSION" "--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"
+      fpm_build $SRC_BUILD_DIR/=/usr/local/arvados/src arvados-src 'dir' "$PKG_VERSION" "--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"
 
       rm -rf "$SRC_BUILD_DIR"
-
     fi
 )
 
@@ -329,270 +338,27 @@ package_go_binary tools/keep-rsync keep-rsync \
 package_go_binary tools/keep-exercise keep-exercise \
     "Performance testing tool for Arvados Keep"
 
-
-# we need explicit debian_revision values in the dependencies for ruamel.yaml, because we have a package iteration
-# greater than zero. So we parse setup.py, get the ruamel.yaml dependencies, tell fpm not to automatically include
-# them in the package being built, and re-add them manually with an appropriate debian_revision value.
-# See #14552 for the reason for this (nasty) workaround. We use ${ruamel_depends[@]} in a few places further down
-# in this script.
-# Ward, 2018-11-28
-IFS=', ' read -r -a deps <<< `grep ruamel.yaml $WORKSPACE/sdk/python/setup.py |cut -f 3 -dl |sed -e "s/'//g"`
-declare -a ruamel_depends=()
-for i in ${deps[@]}; do
-  i=`echo "$i" | sed -e 's!\([0-9]\)! \1!'`
-  if [[ $i =~ .*\>.* ]]; then
-    ruamel_depends+=(--depends "python-ruamel.yaml $i-1")
-  elif [[ $i =~ .*\<.* ]]; then
-    ruamel_depends+=(--depends "python-ruamel.yaml $i-9")
-  else
-    echo "Encountered ruamel dependency that I can't parse. Aborting..."
-    exit 1
-  fi
-done
-
-
 # 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
-cd $WORKSPACE/packages/$TARGET
-rm -rf "$WORKSPACE/sdk/python/build"
-arvados_python_client_version=${ARVADOS_BUILDING_VERSION:-$(awk '($1 == "Version:"){print $2}' $WORKSPACE/sdk/python/arvados_python_client.egg-info/PKG-INFO)}
-test_package_presence ${PYTHON2_PKG_PREFIX}-arvados-python-client "$arvados_python_client_version" python
-if [[ "$?" == "0" ]]; then
+fpm_build_virtualenv "arvados-python-client" "sdk/python"
+fpm_build_virtualenv "arvados-python-client" "sdk/python" "python3"
 
-  fpm_build $WORKSPACE/sdk/python "${PYTHON2_PKG_PREFIX}-arvados-python-client" 'Curoverse, Inc.' 'python' "$arvados_python_client_version" "--url=https://arvados.org" "--description=The Arvados Python SDK" --depends "${PYTHON2_PKG_PREFIX}-setuptools" --deb-recommends=git  --python-disable-dependency ruamel.yaml "${ruamel_depends[@]}"
-fi
-
-# cwl-runner
-cd $WORKSPACE/packages/$TARGET
-rm -rf "$WORKSPACE/sdk/cwl/build"
-arvados_cwl_runner_version=${ARVADOS_BUILDING_VERSION:-$(awk '($1 == "Version:"){print $2}' $WORKSPACE/sdk/cwl/arvados_cwl_runner.egg-info/PKG-INFO)}
-declare -a iterargs=()
-if [[ -z "$ARVADOS_BUILDING_VERSION" ]]; then
-    arvados_cwl_runner_iteration=4
-    iterargs+=(--iteration $arvados_cwl_runner_iteration)
-else
-    arvados_cwl_runner_iteration=
-fi
-test_package_presence ${PYTHON2_PKG_PREFIX}-arvados-cwl-runner "$arvados_cwl_runner_version" python "$arvados_cwl_runner_iteration"
-if [[ "$?" == "0" ]]; then
-  fpm_build $WORKSPACE/sdk/cwl "${PYTHON2_PKG_PREFIX}-arvados-cwl-runner" 'Curoverse, Inc.' 'python' "$arvados_cwl_runner_version" "--url=https://arvados.org" "--description=The Arvados CWL runner" --depends "${PYTHON2_PKG_PREFIX}-setuptools" --depends "${PYTHON2_PKG_PREFIX}-subprocess32 >= 3.5.0" --depends "${PYTHON2_PKG_PREFIX}-pathlib2" --depends "${PYTHON2_PKG_PREFIX}-scandir" --python-disable-dependency ruamel.yaml "${ruamel_depends[@]}" "${iterargs[@]}"
-fi
-
-# schema_salad. This is a python dependency of arvados-cwl-runner,
-# but we can't use the usual PYTHONPACKAGES way to build this package due to the
-# intricacies of how version numbers get generated in setup.py: we need a specific version,
-# e.g. 1.7.20160316203940. If we don't explicitly list that version with the -v
-# argument to fpm, and instead specify it as schema_salad==1.7.20160316203940, we get
-# a package with version 1.7. That's because our gittagger hack is not being
-# picked up by self.distribution.get_version(), which is called from
-# https://github.com/jordansissel/fpm/blob/master/lib/fpm/package/pyfpm/get_metadata.py
-# by means of this command:
-#
-# python2.7 setup.py --command-packages=pyfpm get_metadata --output=metadata.json
-#
-# So we build this thing separately.
-#
-# Ward, 2016-03-17
-saladversion=$(cat "$WORKSPACE/sdk/cwl/setup.py" | grep schema-salad== | sed "s/.*==\(.*\)'.*/\1/")
-test_package_presence python-schema-salad "$saladversion" python 2
-if [[ "$?" == "0" ]]; then
-  fpm_build schema_salad "" "" python $saladversion --depends "${PYTHON2_PKG_PREFIX}-lockfile >= 1:0.12.2-2" --depends "${PYTHON2_PKG_PREFIX}-avro = 1.8.1-2" --iteration 2
-fi
-
-# And for cwltool we have the same problem as for schema_salad. Ward, 2016-03-17
-cwltoolversion=$(cat "$WORKSPACE/sdk/cwl/setup.py" | grep cwltool== | sed "s/.*==\(.*\)'.*/\1/")
-test_package_presence python-cwltool "$cwltoolversion" python 3
-if [[ "$?" == "0" ]]; then
-  fpm_build cwltool "" "" python $cwltoolversion --iteration 3 --python-disable-dependency ruamel.yaml "${ruamel_depends[@]}"
-fi
+# Arvados cwl runner
+fpm_build_virtualenv "arvados-cwl-runner" "sdk/cwl"
 
 # The PAM module
-if [[ $TARGET =~ debian|ubuntu ]]; then
-    cd $WORKSPACE/packages/$TARGET
-    rm -rf "$WORKSPACE/sdk/pam/build"
-    libpam_arvados_version=$(awk '($1 == "Version:"){print $2}' $WORKSPACE/sdk/pam/arvados_pam.egg-info/PKG-INFO)
-    test_package_presence libpam-arvados "$libpam_arvados_version" python
-    if [[ "$?" == "0" ]]; then
-      fpm_build $WORKSPACE/sdk/pam libpam-arvados 'Curoverse, Inc.' 'python' "$libpam_arvados_version" "--url=https://arvados.org" "--description=PAM module for authenticating shell logins using Arvados API tokens" --depends libpam-python
-    fi
-fi
+fpm_build_virtualenv "libpam-arvados" "sdk/pam"
 
 # The FUSE driver
-# Please see comment about --no-python-fix-name above; we stay consistent and do
-# not omit the python- prefix first.
-cd $WORKSPACE/packages/$TARGET
-rm -rf "$WORKSPACE/services/fuse/build"
-arvados_fuse_version=${ARVADOS_BUILDING_VERSION:-$(awk '($1 == "Version:"){print $2}' $WORKSPACE/services/fuse/arvados_fuse.egg-info/PKG-INFO)}
-test_package_presence "${PYTHON2_PKG_PREFIX}-arvados-fuse" "$arvados_fuse_version" python
-if [[ "$?" == "0" ]]; then
-  fpm_build $WORKSPACE/services/fuse "${PYTHON2_PKG_PREFIX}-arvados-fuse" 'Curoverse, Inc.' 'python' "$arvados_fuse_version" "--url=https://arvados.org" "--description=The Keep FUSE driver" --depends "${PYTHON2_PKG_PREFIX}-setuptools"
-fi
+fpm_build_virtualenv "arvados-fuse" "services/fuse"
 
 # The node manager
-cd $WORKSPACE/packages/$TARGET
-rm -rf "$WORKSPACE/services/nodemanager/build"
-nodemanager_version=${ARVADOS_BUILDING_VERSION:-$(awk '($1 == "Version:"){print $2}' $WORKSPACE/services/nodemanager/arvados_node_manager.egg-info/PKG-INFO)}
-iteration="${ARVADOS_BUILDING_ITERATION:-1}"
-test_package_presence arvados-node-manager "$nodemanager_version" python "$iteration"
-if [[ "$?" == "0" ]]; then
-  fpm_build $WORKSPACE/services/nodemanager arvados-node-manager 'Curoverse, Inc.' 'python' "$nodemanager_version" "--url=https://arvados.org" "--description=The Arvados node manager" --depends "${PYTHON2_PKG_PREFIX}-setuptools" --iteration "$iteration"
-fi
+fpm_build_virtualenv "arvados-node-manager" "services/nodemanager"
 
 # The Docker image cleaner
-cd $WORKSPACE/packages/$TARGET
-rm -rf "$WORKSPACE/services/dockercleaner/build"
-dockercleaner_version=${ARVADOS_BUILDING_VERSION:-$(awk '($1 == "Version:"){print $2}' $WORKSPACE/services/dockercleaner/arvados_docker_cleaner.egg-info/PKG-INFO)}
-iteration="${ARVADOS_BUILDING_ITERATION:-4}"
-test_package_presence arvados-docker-cleaner "$dockercleaner_version" python "$iteration"
-if [[ "$?" == "0" ]]; then
-  fpm_build $WORKSPACE/services/dockercleaner arvados-docker-cleaner 'Curoverse, Inc.' 'python3' "$dockercleaner_version" "--url=https://arvados.org" "--description=The Arvados Docker image cleaner" --depends "${PYTHON3_PKG_PREFIX}-websocket-client = 0.37.0" --iteration "$iteration"
-fi
+fpm_build_virtualenv "arvados-docker-cleaner" "services/dockercleaner" "python3"
 
 # The Arvados crunchstat-summary tool
-cd $WORKSPACE/packages/$TARGET
-crunchstat_summary_version=${ARVADOS_BUILDING_VERSION:-$(awk '($1 == "Version:"){print $2}' $WORKSPACE/tools/crunchstat-summary/crunchstat_summary.egg-info/PKG-INFO)}
-iteration="${ARVADOS_BUILDING_ITERATION:-2}"
-test_package_presence "$PYTHON2_PKG_PREFIX"-crunchstat-summary "$crunchstat_summary_version" python "$iteration"
-if [[ "$?" == "0" ]]; then
-  rm -rf "$WORKSPACE/tools/crunchstat-summary/build"
-  fpm_build $WORKSPACE/tools/crunchstat-summary ${PYTHON2_PKG_PREFIX}-crunchstat-summary 'Curoverse, Inc.' 'python' "$crunchstat_summary_version" "--url=https://arvados.org" "--description=Crunchstat-summary reads Arvados Crunch log files and summarize resource usage" --iteration "$iteration"
-fi
-
-# Forked libcloud
-if test_package_presence "$PYTHON2_PKG_PREFIX"-apache-libcloud "$LIBCLOUD_PIN" python 2
-then
-  LIBCLOUD_DIR=$(mktemp -d)
-  (
-      cd $LIBCLOUD_DIR
-      git clone $DASHQ_UNLESS_DEBUG https://github.com/curoverse/libcloud.git .
-      git checkout $DASHQ_UNLESS_DEBUG apache-libcloud-$LIBCLOUD_PIN
-      # libcloud is absurdly noisy without -q, so force -q here
-      OLD_DASHQ_UNLESS_DEBUG=$DASHQ_UNLESS_DEBUG
-      DASHQ_UNLESS_DEBUG=-q
-      handle_python_package
-      DASHQ_UNLESS_DEBUG=$OLD_DASHQ_UNLESS_DEBUG
-  )
-
-  # libcloud >= 2.3.0 now requires python-requests 2.4.3 or higher, otherwise
-  # it throws
-  #   ImportError: No module named packages.urllib3.poolmanager
-  # when loaded. We only see this problem on ubuntu1404, because that is our
-  # only supported distribution that ships with a python-requests older than
-  # 2.4.3.
-  fpm_build $LIBCLOUD_DIR "$PYTHON2_PKG_PREFIX"-apache-libcloud "" python "" --iteration 2 --depends 'python-requests >= 2.4.3'
-  rm -rf $LIBCLOUD_DIR
-fi
-
-# Python 2 dependencies
-declare -a PIP_DOWNLOAD_SWITCHES=(--no-deps)
-# Add --no-use-wheel if this pip knows it.
-pip install --no-use-wheel >/dev/null 2>&1
-case "$?" in
-    0) PIP_DOWNLOAD_SWITCHES+=(--no-use-wheel) ;;
-    1) ;;
-    2) ;;
-    *) echo "WARNING: 'pip install --no-use-wheel' test returned unknown exit code $?" ;;
-esac
-
-while read -r line || [[ -n "$line" ]]; do
-#  echo "Text read from file: $line"
-  if [[ "$line" =~ ^# ]]; then
-    continue
-  fi
-  IFS='|'; arr=($line); unset IFS
-
-  dist=${arr[0]}
-
-  IFS=',';dists=($dist); unset IFS
-
-  MATCH=0
-  for d in "${dists[@]}"; do
-    if [[ "$d" == "$TARGET" ]] || [[ "$d" == "all" ]]; then
-      MATCH=1
-    fi
-  done
-
-  if [[ "$MATCH" != "1" ]]; then
-    continue
-  fi
-  name=${arr[1]}
-  version=${arr[2]}
-  iteration=${arr[3]}
-  pkgtype=${arr[4]}
-  arch=${arr[5]}
-  extra=${arr[6]}
-  declare -a 'extra_arr=('"$extra"')'
-
-  if [[ "$FORMAT" == "rpm" ]]; then
-    if [[ "$arch" == "all" ]]; then
-      arch="noarch"
-    fi
-    if [[ "$arch" == "amd64" ]]; then
-      arch="x86_64"
-    fi
-  fi
-
-  if [[ "$pkgtype" == "python" ]]; then
-    outname=$(echo "$name" | sed -e 's/^python-//' -e 's/_/-/g' -e "s/^/${PYTHON2_PKG_PREFIX}-/")
-  else
-    outname=$(echo "$name" | sed -e 's/^python-//' -e 's/_/-/g' -e "s/^/${PYTHON3_PKG_PREFIX}-/")
-  fi
-
-  if [[ -n "$ONLY_BUILD" ]] && [[ "$outname" != "$ONLY_BUILD" ]] ; then
-      continue
-  fi
-
-  case "$name" in
-      httplib2|google-api-python-client)
-          test_package_presence $outname $version $pkgtype $iteration $arch
-          if [[ "$?" == "0" ]]; then
-            # Work around 0640 permissions on some package files.
-            # See #7591 and #7991.
-            pyfpm_workdir=$(mktemp --tmpdir -d pyfpm-XXXXXX) && (
-                set -e
-                cd "$pyfpm_workdir"
-                PIP_VERSION=`python$PYTHON2_VERSION -c "import pip; print(pip.__version__)" |cut -f1 -d.`
-                if (( $PIP_VERSION < 8 )); then
-                  pip install "${PIP_DOWNLOAD_SWITCHES[@]}" --download . "$name==$version"
-                else
-                  pip download --no-deps --no-binary :all: "$name==$version"
-                fi
-                # Sometimes pip gives us a tarball, sometimes a zip file...
-                DOWNLOADED=`ls $name-*`
-                [[ "$DOWNLOADED" =~ ".tar" ]] && tar -xf $DOWNLOADED
-                [[ "$DOWNLOADED" =~ ".zip" ]] && unzip $DOWNLOADED
-                cd "$name"-*/
-                "python$PYTHON2_VERSION" setup.py $DASHQ_UNLESS_DEBUG egg_info build
-                chmod -R go+rX .
-                set +e
-                fpm_build . "$outname" "" "$pkgtype" "$version" --iteration "$iteration" "${extra_arr[@]}"
-                # The upload step uses the package timestamp to determine
-                # if it is new.  --no-clobber plays nice with that.
-                mv --no-clobber "$outname"*.$FORMAT "$WORKSPACE/packages/$TARGET"
-            )
-            if [ 0 != "$?" ]; then
-                echo "ERROR: $name build process failed"
-                EXITCODE=1
-            fi
-            if [ -n "$pyfpm_workdir" ]; then
-                rm -rf "$pyfpm_workdir"
-            fi
-          fi
-          ;;
-      *)
-          test_package_presence $outname $version $pkgtype $iteration $arch
-          if [[ "$?" == "0" ]]; then
-            fpm_build "$name" "$outname" "" "$pkgtype" "$version" --iteration "$iteration" "${extra_arr[@]}"
-          fi
-          ;;
-  esac
-
-done <`dirname "$(readlink -f "$0")"`"/build.list"
+fpm_build_virtualenv "crunchstat-summary" "tools/crunchstat-summary"
 
 # Build the API server package
 test_rails_package_presence arvados-api-server "$WORKSPACE/services/api"
index b595cc8a06ee1ff8563289e7f197c00bd0fa963e..e6b086a5a3b5c2965a4f108e1c3c6a58dc63d2ab 100755 (executable)
@@ -161,7 +161,7 @@ package_go_binary() {
     fi
     switches+=("$WORKSPACE/${license_file}=/usr/share/doc/$prog/${license_file}")
 
-    fpm_build "$GOPATH/bin/${basename}=/usr/bin/${prog}" "${prog}" 'Curoverse, Inc.' dir "${version}" "--url=https://arvados.org" "--license=GNU Affero General Public License, version 3.0" "--description=${description}" "${switches[@]}"
+    fpm_build "$GOPATH/bin/${basename}=/usr/bin/${prog}" "${prog}" dir "${version}" "--url=https://arvados.org" "--license=GNU Affero General Public License, version 3.0" "--description=${description}" "${switches[@]}"
 }
 
 default_iteration() {
@@ -232,11 +232,6 @@ test_package_presence() {
       rpm_architecture="x86_64"
       deb_architecture="amd64"
 
-      if [[ "$pkgtype" =~ ^(python|python3)$ ]]; then
-        rpm_architecture="noarch"
-        deb_architecture="all"
-      fi
-
       if [[ "$pkgtype" =~ ^(src)$ ]]; then
         rpm_architecture="noarch"
         deb_architecture="all"
@@ -281,7 +276,7 @@ test_package_presence() {
           echo "Package $complete_pkgname exists, not rebuilding!"
           curl -o ./${complete_pkgname} http://apt.arvados.org/pool/${D}/main/${repo_subdir}/${complete_pkgname}
           return 1
-       elif test -f "$WORKSPACE/packages/$TARGET/processed/${complete_pkgname}" ; then
+        elif test -f "$WORKSPACE/packages/$TARGET/processed/${complete_pkgname}" ; then
           echo "Package $complete_pkgname exists, not rebuilding!"
           return 1
         else
@@ -298,6 +293,9 @@ test_package_presence() {
         echo "Package $complete_pkgname exists, not rebuilding!"
         curl -o ./${complete_pkgname} ${centos_repo}${complete_pkgname}
         return 1
+      elif test -f "$WORKSPACE/packages/$TARGET/processed/${complete_pkgname}" ; then
+        echo "Package $complete_pkgname exists, not rebuilding!"
+        return 1
       else
         echo "Package $complete_pkgname not found, building"
         return 0
@@ -332,7 +330,7 @@ handle_rails_package() {
         return 1
     fi
     local railsdir="/var/www/${pkgname%-server}/current"
-    local -a pos_args=("$srcdir/=$railsdir" "$pkgname" "Curoverse, Inc." dir "$version")
+    local -a pos_args=("$srcdir/=$railsdir" "$pkgname" dir "$version")
     local license_arg="$license_path=$railsdir/$(basename "$license_path")"
     local -a switches=(--after-install "$scripts_dir/postinst"
                        --before-remove "$scripts_dir/prerm"
@@ -359,6 +357,273 @@ handle_rails_package() {
     rm -rf "$scripts_dir"
 }
 
+# Build python packages with a virtualenv built-in
+fpm_build_virtualenv () {
+  PKG=$1
+  shift
+  PKG_DIR=$1
+  shift
+  PACKAGE_TYPE=${1:-python}
+  shift
+
+  # Set up
+  STDOUT_IF_DEBUG=/dev/null
+  STDERR_IF_DEBUG=/dev/null
+  DASHQ_UNLESS_DEBUG=-q
+  if [[ "$DEBUG" != "0" ]]; then
+      STDOUT_IF_DEBUG=/dev/stdout
+      STDERR_IF_DEBUG=/dev/stderr
+      DASHQ_UNLESS_DEBUG=
+  fi
+  if [[ "$ARVADOS_BUILDING_ITERATION" == "" ]]; then
+    ARVADOS_BUILDING_ITERATION=1
+  fi
+
+  local python=""
+  case "$PACKAGE_TYPE" in
+    python)
+        # All Arvados Python2 packages depend on Python 2.7.
+        # Make sure we build with that for consistency.
+        python=python2.7
+        PACKAGE_PREFIX=$PYTHON2_PKG_PREFIX
+        ;;
+    python3)
+        PACKAGE_PREFIX=$PYTHON3_PKG_PREFIX
+        python=python3
+        ;;
+  esac
+
+  if [[ "$PKG" != "libpam-arvados" ]] &&
+     [[ "$PKG" != "arvados-node-manager" ]] &&
+     [[ "$PKG" != "arvados-docker-cleaner" ]]; then
+    PYTHON_PKG=$PACKAGE_PREFIX-$PKG
+  else
+    # Exception to our package naming convention
+    PYTHON_PKG=$PKG
+  fi
+
+  if [[ -n "$ONLY_BUILD" ]] && [[ "$PYTHON_PKG" != "$ONLY_BUILD" ]] && [[ "$PKG" != "$ONLY_BUILD" ]]; then
+    return 0
+  fi
+
+  cd $WORKSPACE/$PKG_DIR
+
+  rm -rf dist/*
+
+  if ! $python setup.py $DASHQ_UNLESS_DEBUG sdist; then
+    echo "Error, unable to run python setup.py sdist for $PKG"
+    exit 1
+  fi
+
+  PACKAGE_PATH=`(cd dist; ls *tar.gz)`
+
+  # Determine the package version from the generated sdist archive
+  PYTHON_VERSION=${ARVADOS_BUILDING_VERSION:-$(awk '($1 == "Version:"){print $2}' *.egg-info/PKG-INFO)}
+
+  # See if we actually need to build this package; does it exist already?
+  # We can't do this earlier than here, because we need PYTHON_VERSION...
+  # This isn't so bad; the sdist call above is pretty quick compared to
+  # the invocation of virtualenv and fpm, below.
+  if ! test_package_presence "$PYTHON_PKG" $PYTHON_VERSION $PACKAGE_TYPE $ARVADOS_BUILDING_ITERATION; then
+    return 0
+  fi
+
+  echo "Building $FORMAT package for $PKG from $PKG_DIR"
+
+  # Package the sdist in a virtualenv
+  echo "Creating virtualenv..."
+
+  cd dist
+
+  rm -rf build
+  rm -f $PYTHON_PKG*deb
+
+  virtualenv_command="virtualenv --python `which $python` $DASHQ_UNLESS_DEBUG build/usr/share/$python/dist/$PYTHON_PKG"
+
+  if ! $virtualenv_command; then
+    echo "Error, unable to run"
+    echo "  $virtualenv_command"
+    exit 1
+  fi
+
+  if ! build/usr/share/$python/dist/$PYTHON_PKG/bin/pip install $DASHQ_UNLESS_DEBUG $CACHE_FLAG -U pip; then
+    echo "Error, unable to upgrade pip with"
+    echo "  build/usr/share/$python/dist/$PYTHON_PKG/bin/pip install $DASHQ_UNLESS_DEBUG $CACHE_FLAG -U pip"
+    exit 1
+  fi
+  if ! build/usr/share/$python/dist/$PYTHON_PKG/bin/pip install $DASHQ_UNLESS_DEBUG $CACHE_FLAG -U wheel; then
+    echo "Error, unable to upgrade wheel with"
+    echo "  build/usr/share/$python/dist/$PYTHON_PKG/bin/pip install $DASHQ_UNLESS_DEBUG $CACHE_FLAG -U wheel"
+    exit 1
+  fi
+
+  if [[ "$TARGET" != "centos7" ]] || [[ "$PYTHON_PKG" != "python-arvados-fuse" ]]; then
+    build/usr/share/$python/dist/$PYTHON_PKG/bin/pip install $DASHQ_UNLESS_DEBUG $CACHE_FLAG $PACKAGE_PATH
+  else
+    # centos7 needs these special tweaks to install python-arvados-fuse
+    build/usr/share/$python/dist/$PYTHON_PKG/bin/pip install $DASHQ_UNLESS_DEBUG $CACHE_FLAG docutils
+    PYCURL_SSL_LIBRARY=nss build/usr/share/$python/dist/$PYTHON_PKG/bin/pip install $DASHQ_UNLESS_DEBUG $CACHE_FLAG $PACKAGE_PATH
+  fi
+
+  if [[ "$?" != "0" ]]; then
+    echo "Error, unable to run"
+    echo "  build/usr/share/$python/dist/$PYTHON_PKG/bin/pip install $DASHQ_UNLESS_DEBUG $CACHE_FLAG $PACKAGE_PATH"
+    exit 1
+  fi
+
+  cd build/usr/share/$python/dist/$PYTHON_PKG/
+
+  # Replace the shebang lines in all python scripts, and handle the activate
+  # scripts too This is a functional replacement of the 237 line
+  # virtualenv_tools.py script that doesn't work in python3 without serious
+  # patching, minus the parts we don't need (modifying pyc files, etc).
+  for binfile in `ls bin/`; do
+    if ! file --mime bin/$binfile |grep -q binary; then
+      # Not a binary file
+      if [[ "$binfile" =~ ^activate(.csh|.fish|)$ ]]; then
+        # these 'activate' scripts need special treatment
+        sed -i "s/VIRTUAL_ENV=\".*\"/VIRTUAL_ENV=\"\/usr\/share\/$python\/dist\/$PYTHON_PKG\"/" bin/$binfile
+        sed -i "s/VIRTUAL_ENV \".*\"/VIRTUAL_ENV \"\/usr\/share\/$python\/dist\/$PYTHON_PKG\"/" bin/$binfile
+      else
+        if grep -q -E '^#!.*/bin/python\d?' bin/$binfile; then
+          # Replace shebang line
+          sed -i "1 s/^.*$/#!\/usr\/share\/$python\/dist\/$PYTHON_PKG\/bin\/python/" bin/$binfile
+        fi
+      fi
+    fi
+  done
+
+  cd - >$STDOUT_IF_DEBUG
+
+  find build -iname '*.pyc' -exec rm {} \;
+  find build -iname '*.pyo' -exec rm {} \;
+
+  # Finally, generate the package
+  echo "Creating package..."
+
+  declare -a COMMAND_ARR=("fpm" "-s" "dir" "-t" "$FORMAT")
+
+  if [[ "$MAINTAINER" != "" ]]; then
+    COMMAND_ARR+=('--maintainer' "$MAINTAINER")
+  fi
+
+  if [[ "$VENDOR" != "" ]]; then
+    COMMAND_ARR+=('--vendor' "$VENDOR")
+  fi
+
+  COMMAND_ARR+=('--url' 'https://arvados.org')
+
+  # Get description
+  DESCRIPTION=`grep '\sdescription' $WORKSPACE/$PKG_DIR/setup.py|cut -f2 -d=|sed -e "s/[',\\"]//g"`
+  COMMAND_ARR+=('--description' "$DESCRIPTION")
+
+  # Get license string
+  LICENSE_STRING=`grep license $WORKSPACE/$PKG_DIR/setup.py|cut -f2 -d=|sed -e "s/[',\\"]//g"`
+  COMMAND_ARR+=('--license' "$LICENSE_STRING")
+
+  # 12271 - As FPM-generated packages don't include scripts by default, the
+  # packages cleanup on upgrade depends on files being listed on the %files
+  # section in the generated SPEC files. To remove DIRECTORIES, they need to
+  # be listed in that sectiontoo, so we need to add this parameter to properly
+  # remove lingering dirs. But this only works for python2: if used on
+  # python33, it includes dirs like /opt/rh/python33 that belong to
+  # other packages.
+  if [[ "$FORMAT" == "rpm" ]] && [[ "$python" == "python2.7" ]]; then
+    COMMAND_ARR+=('--rpm-auto-add-directories')
+  fi
+
+  if [[ "$PKG" == "arvados-python-client" ]]; then
+    if [[ "$python" == "python2.7" ]]; then
+      COMMAND_ARR+=('--conflicts' "$PYTHON3_PKG_PREFIX-$PKG")
+    else
+      COMMAND_ARR+=('--conflicts' "$PYTHON2_PKG_PREFIX-$PKG")
+    fi
+  fi
+
+  if [[ "$DEBUG" != "0" ]]; then
+    COMMAND_ARR+=('--verbose' '--log' 'info')
+  fi
+
+  COMMAND_ARR+=('-v' "$PYTHON_VERSION")
+  COMMAND_ARR+=('--iteration' "$ARVADOS_BUILDING_ITERATION")
+  COMMAND_ARR+=('-n' "$PYTHON_PKG")
+  COMMAND_ARR+=('-C' "build")
+
+  if [[ -e "$WORKSPACE/$PKG_DIR/$PKG.service" ]]; then
+    COMMAND_ARR+=('--after-install' "${WORKSPACE}/build/go-python-package-scripts/postinst")
+    COMMAND_ARR+=('--before-remove' "${WORKSPACE}/build/go-python-package-scripts/prerm")
+  fi
+
+  if [[ "$python" == "python2.7" ]]; then
+    COMMAND_ARR+=('--depends' "$PYTHON2_PACKAGE")
+  else
+    COMMAND_ARR+=('--depends' "$PYTHON3_PACKAGE")
+  fi
+
+  # avoid warning
+  COMMAND_ARR+=('--deb-no-default-config-files')
+
+  # Append --depends X and other arguments specified by fpm-info.sh in
+  # the package source dir. These are added last so they can override
+  # the arguments added by this script.
+  declare -a fpm_args=()
+  declare -a fpm_depends=()
+
+  fpminfo="$WORKSPACE/$PKG_DIR/fpm-info.sh"
+  if [[ -e "$fpminfo" ]]; then
+    echo "Loading fpm overrides from $fpminfo"
+    if ! source "$fpminfo"; then
+      echo "Error, unable to source $WORKSPACE/$PKG_DIR/fpm-info.sh for $PKG"
+      exit 1
+    fi
+  fi
+
+  for i in "${fpm_depends[@]}"; do
+    COMMAND_ARR+=('--depends' "$i")
+  done
+
+  COMMAND_ARR+=("${fpm_args[@]}")
+
+  # Make sure to install all our package binaries in /usr/bin.
+  # We have to walk $WORKSPACE/$PKG_DIR/bin rather than
+  # $WORKSPACE/build/usr/share/$python/dist/$PYTHON_PKG/bin/ to get the list
+  # because the latter also includes all the python binaries for the virtualenv.
+  # We have to take the copies of our binaries from the latter directory, though,
+  # because those are the ones we rewrote the shebang line of, above.
+  if [[ -e "$WORKSPACE/$PKG_DIR/bin" ]]; then
+    for binary in `ls $WORKSPACE/$PKG_DIR/bin`; do
+      COMMAND_ARR+=("usr/share/$python/dist/$PYTHON_PKG/bin/$binary=/usr/bin/")
+    done
+  fi
+
+  # the libpam module should place this file in the historically correct place
+  # so as not to break backwards compatibility
+  if [[ -e "$WORKSPACE/$PKG_DIR/dist/build/usr/share/python2.7/dist/libpam-arvados/lib/security/libpam_arvados.py" ]]; then
+    COMMAND_ARR+=("usr/share/$python/dist/$PYTHON_PKG/data/lib/security/libpam_arvados.py=/usr/data/lib/security/")
+  fi
+
+  # the python-arvados-cwl-runner package comes with cwltool, expose that version
+  if [[ -e "$WORKSPACE/$PKG_DIR/dist/build/usr/share/python2.7/dist/python-arvados-cwl-runner/bin/cwltool" ]]; then
+    COMMAND_ARR+=("usr/share/python2.7/dist/python-arvados-cwl-runner/bin/cwltool=/usr/bin/")
+  fi
+
+  COMMAND_ARR+=(".")
+
+  FPM_RESULTS=$("${COMMAND_ARR[@]}")
+  FPM_EXIT_CODE=$?
+
+  # if something went wrong and debug is off, print out the fpm command that errored
+  if ! fpm_verify $FPM_EXIT_CODE $FPM_RESULTS && [[ "$STDOUT_IF_DEBUG" == "/dev/null" ]]; then
+    echo "fpm returned an error executing the command:"
+    echo
+    echo -e "\n${COMMAND_ARR[@]}\n"
+  else
+    echo `ls *$FORMAT`
+    mv $WORKSPACE/$PKG_DIR/dist/*$FORMAT $WORKSPACE/packages/$TARGET/
+  fi
+  echo
+}
+
 # Build packages for everything
 fpm_build () {
   # The package source.  Depending on the source type, this can be a
@@ -369,12 +634,8 @@ fpm_build () {
   # The name of the package to build.
   PACKAGE_NAME=$1
   shift
-  # Optional: the vendor of the package.  Should be "Curoverse, Inc." for
-  # packages of our own software.  Passed to fpm --vendor.
-  VENDOR=$1
-  shift
-  # The type of source package.  Passed to fpm -s.  Default "python".
-  PACKAGE_TYPE=${1:-python}
+  # The type of source package.  Passed to fpm -s.  Default "dir".
+  PACKAGE_TYPE=${1:-dir}
   shift
   # Optional: the package version number.  Passed to fpm -v.
   VERSION=$1
@@ -385,41 +646,8 @@ fpm_build () {
   fi
 
   local default_iteration_value="$(default_iteration "$PACKAGE" "$VERSION" "$PACKAGE_TYPE")"
-  local python=""
 
-  case "$PACKAGE_TYPE" in
-      python)
-          # All Arvados Python2 packages depend on Python 2.7.
-          # Make sure we build with that for consistency.
-          python=python2.7
-          set -- "$@" --python-bin python2.7 \
-              "${PYTHON_FPM_INSTALLER[@]}" \
-              --python-package-name-prefix "$PYTHON2_PKG_PREFIX" \
-              --prefix "$PYTHON2_PREFIX" \
-              --python-install-lib "$PYTHON2_INSTALL_LIB" \
-              --python-install-data . \
-              --exclude "${PYTHON2_INSTALL_LIB#/}/tests" \
-              --depends "$PYTHON2_PACKAGE"
-          ;;
-      python3)
-          # fpm does not actually support a python3 package type.  Instead
-          # we recognize it as a convenience shortcut to add several
-          # necessary arguments to fpm's command line later, after we're
-          # done handling positional arguments.
-          PACKAGE_TYPE=python
-          python=python3
-          set -- "$@" --python-bin python3 \
-              "${PYTHON3_FPM_INSTALLER[@]}" \
-              --python-package-name-prefix "$PYTHON3_PKG_PREFIX" \
-              --prefix "$PYTHON3_PREFIX" \
-              --python-install-lib "$PYTHON3_INSTALL_LIB" \
-              --python-install-data . \
-              --exclude "${PYTHON3_INSTALL_LIB#/}/tests" \
-              --depends "$PYTHON3_PACKAGE"
-          ;;
-  esac
-
-  declare -a COMMAND_ARR=("fpm" "--maintainer=Ward Vandewege <ward@curoverse.com>" "-s" "$PACKAGE_TYPE" "-t" "$FORMAT")
+  declare -a COMMAND_ARR=("fpm" "-s" "$PACKAGE_TYPE" "-t" "$FORMAT")
   if [ python = "$PACKAGE_TYPE" ] && [ deb = "$FORMAT" ]; then
       # Dependencies are built from setup.py.  Since setup.py will never
       # refer to Debian package iterations, it doesn't make sense to
@@ -430,7 +658,7 @@ fpm_build () {
   # 12271 - As FPM-generated packages don't include scripts by default, the
   # packages cleanup on upgrade depends on files being listed on the %files
   # section in the generated SPEC files. To remove DIRECTORIES, they need to
-  # be listed in that sectiontoo, so we need to add this parameter to properly
+  # be listed in that section too, so we need to add this parameter to properly
   # remove lingering dirs. But this only works for python2: if used on
   # python33, it includes dirs like /opt/rh/python33 that belong to
   # other packages.
@@ -438,7 +666,7 @@ fpm_build () {
     COMMAND_ARR+=('--rpm-auto-add-directories')
   fi
 
-  if [[ "${DEBUG:-0}" != "0" ]]; then
+  if [[ "$DEBUG" != "0" ]]; then
     COMMAND_ARR+=('--verbose' '--log' 'info')
   fi
 
@@ -446,6 +674,10 @@ fpm_build () {
     COMMAND_ARR+=('-n' "$PACKAGE_NAME")
   fi
 
+  if [[ "$MAINTAINER" != "" ]]; then
+    COMMAND_ARR+=('--maintainer' "$MAINTAINER")
+  fi
+
   if [[ "$VENDOR" != "" ]]; then
     COMMAND_ARR+=('--vendor' "$VENDOR")
   fi
@@ -459,14 +691,6 @@ fpm_build () {
       COMMAND_ARR+=(--iteration "$default_iteration_value")
   fi
 
-  if [[ python = "$PACKAGE_TYPE" ]] && [[ -e "${PACKAGE}/${PACKAGE_NAME}.service" ]]
-  then
-      COMMAND_ARR+=(
-          --after-install "${WORKSPACE}/build/go-python-package-scripts/postinst"
-          --before-remove "${WORKSPACE}/build/go-python-package-scripts/prerm"
-      )
-  fi
-
   # Append --depends X and other arguments specified by fpm-info.sh in
   # the package source dir. These are added last so they can override
   # the arguments added by this script.
@@ -476,12 +700,7 @@ fpm_build () {
   declare -a fpm_exclude=()
   declare -a fpm_dirs=(
       # source dir part of 'dir' package ("/source=/dest" => "/source"):
-      "${PACKAGE%%=/*}"
-      # backports ("llfuse>=1.0" => "backports/python-llfuse")
-      "${WORKSPACE}/backports/${PACKAGE_TYPE}-${PACKAGE%%[<=>]*}")
-  if [[ -n "$PACKAGE_NAME" ]]; then
-      fpm_dirs+=("${WORKSPACE}/backports/${PACKAGE_NAME}")
-  fi
+      "${PACKAGE%%=/*}")
   for pkgdir in "${fpm_dirs[@]}"; do
       fpminfo="$pkgdir/fpm-info.sh"
       if [[ -e "$fpminfo" ]]; then
index 749075d81576242a29db0d1b075414dc5f1d0270..96e6aea72ca10615c56d9734090dc7b716e024ec 100755 (executable)
@@ -528,7 +528,7 @@ setup_virtualenv() {
 }
 
 export PERLINSTALLBASE
-export PERLLIB="$PERLINSTALLBASE/lib/perl5:${PERLLIB:+$PERLLIB}"
+export PERL5LIB="$PERLINSTALLBASE/lib/perl5${PERL5LIB:+:$PERL5LIB}"
 
 export R_LIBS
 
@@ -596,6 +596,7 @@ pythonstuff=(
     sdk/python
     sdk/python:py3
     sdk/cwl
+    sdk/cwl:py3
     services/dockercleaner:py3
     services/fuse
     services/nodemanager
index 6a3e000ca0165649b0418dba566a43999be1be09..eda25d5cc6678524ea1cd44b0500201f49e56e65 100644 (file)
@@ -30,6 +30,44 @@ Note to developers: Add new items at the top. Include the date, issue number, co
 TODO: extract this information based on git commit messages and generate changelogs / release notes automatically.
 {% endcomment %}
 
+h3. current master branch
+
+h4. Python packaging change
+
+As part of story "#9945":https://dev.arvados.org/issues/9945, the distribution packaging (deb/rpm) of our Python packages has changed. These packages now include a built-in virtualenv to reduce dependencies on system packages. We have also stopped packaging and publishing backports for all the Python dependencies of our packages, as they are no longer needed.
+
+One practical consequence of this change is that the use of the Arvados Python SDK (aka "import arvados") will require a tweak if the SDK was installed from a distribution package. It now requires the loading of the virtualenv environment from our packages. The "Install documentation for the Arvados Python SDK":/sdk/python/sdk-python.html reflects this change. This does not affect the use of the command line tools (e.g. arv-get, etc.).
+
+Python scripts that rely on the distribution Arvados Python SDK packages to import the Arvados SDK will need to be tweaked to load the correct Python environment.
+
+This can be done by activating the virtualenv outside of the script:
+
+<notextile>
+<pre>~$ <code class="userinput">source /usr/share/python2.7/dist/python-arvados-python-client/bin/activate</code>
+(python-arvados-python-client) ~$ <code class="userinput">path-to-the-python-script</code>
+</pre>
+</notextile>
+
+Or alternatively, by updating the shebang line at the start of the script to:
+
+<notextile>
+<pre>
+#!/usr/share/python2.7/dist/python-arvados-python-client/bin/python
+</pre>
+</notextile>
+
+h4. python-arvados-cwl-runner deb/rpm package now conflicts with python-cwltool deb/rpm package
+
+As part of story "#9945":https://dev.arvados.org/issues/9945, the distribution packaging (deb/rpm) of our Python packages has changed. The python-arvados-cwl-runner package now includes a version of cwltool. If present, the python-cwltool and cwltool distribution packages will need to be uninstalled before the python-arvados-cwl-runner deb or rpm package can be installed.
+
+h4. Centos7 Python 3 dependency upgraded to rh-python35
+
+As part of story "#9945":https://dev.arvados.org/issues/9945, the Python 3 dependency for Centos7 Arvados packages was upgraded from SCL python33 to rh-python35.
+
+h4. Centos7 package for libpam-arvados depends on the python-pam package, which is available from EPEL
+
+As part of story "#9945":https://dev.arvados.org/issues/9945, it was discovered that the Centos7 package for libpam-arvados was missing a dependency on the python-pam package, which is available from the EPEL repository. The dependency has been added to the libpam-arvados package. This means that going forward, the EPEL repository will need to be enabled to install libpam-arvados on Centos7.
+
 h3. v1.3.0 (2018-12-05)
 
 This release includes several database migrations, which will be executed automatically as part of the API server upgrade. On large Arvados installations, these migrations will take a while. We've seen the upgrade take 30 minutes or more on installations with a lot of collections.
index 2b86261ccc06cdd9dacd268b6b4bc21cc06d74f0..be824399a4c94def5b64af218fa0b93d154d739b 100644 (file)
@@ -12,22 +12,29 @@ SPDX-License-Identifier: CC-BY-SA-3.0
 
 The Python SDK provides access from Python to the Arvados API and Keep.  It also includes a number of command line tools for using and administering Arvados and Keep, and some conveniences for use in Crunch scripts; see "Crunch utility libraries":crunch-utility-libraries.html for details.
 
-h3. Installation
+h2. Installation
 
 If you are logged in to an Arvados VM, the Python SDK should be installed.
 
-To use the Python SDK elsewhere, you can install from a distribution package, PyPI, or source.
+To use the Python SDK elsewhere, you can install from PyPI or a distribution package.
 
 {% include 'notebox_begin' %}
 The Python SDK requires Python 2.7.
 {% include 'notebox_end' %}
 
-h4. Option 1: Install from distribution packages
+h3. Option 1: Install with pip
 
-First, "add the appropriate package repository for your distribution":{{ site.baseurl }}/install/install-manual-prerequisites.html#repos.
+This installation method is recommended to make the SDK available for use in your own Python programs. It can coexist with the system-wide installation method from a distribution package (option 2, below).
+
+Run @pip-2.7 install arvados-python-client@ in an appropriate installation environment, such as a virtualenv.
+
+If your version of @pip@ is 1.4 or newer, the @pip install@ command might give an error: "Could not find a version that satisfies the requirement arvados-python-client". If this happens, try @pip-2.7 install --pre arvados-python-client@.
+
+h3. Option 2: Install from a distribution package
 
-{% assign rh_version = "6" %}
-{% include 'note_python_sc' %}
+This installation method is recommended to make the CLI tools available system-wide. It can coexist with the installation method described in option 1, above.
+
+First, "add the appropriate package repository for your distribution":{{ site.baseurl }}/install/install-manual-prerequisites.html#repos.
 
 On Red Hat-based systems:
 
@@ -43,31 +50,41 @@ On Debian-based systems:
 </code></pre>
 </notextile>
 
-h4. Option 2: Install with pip
+h3. Test installation
 
-Run @pip-2.7 install arvados-python-client@ in an appropriate installation environment, such as a virtualenv.
-
-If your version of @pip@ is 1.4 or newer, the @pip install@ command might give an error: "Could not find a version that satisfies the requirement arvados-python-client". If this happens, try @pip-2.7 install --pre arvados-python-client@.
-
-h4. Option 3: Install from source
+If the SDK is installed and your @ARVADOS_API_HOST@ and @ARVADOS_API_TOKEN@ environment variables are set up correctly (see "api-tokens":{{site.baseurl}}/user/reference/api-tokens.html for details), @import arvados@ should produce no errors.
 
-Install the @python-setuptools@ package from your distribution.  Then run the following:
+If you installed with pip (option 1, above):
 
 <notextile>
-<pre><code>~$ <span class="userinput">git clone https://github.com/curoverse/arvados.git</span>
-~$ <span class="userinput">cd arvados/sdk/python</span>
-~/arvados/sdk/python$ <span class="userinput">python2.7 setup.py install</span>
-</code></pre>
+<pre>~$ <code class="userinput">python</code>
+Python 2.7.4 (default, Sep 26 2013, 03:20:26)
+[GCC 4.7.3] on linux2
+Type "help", "copyright", "credits" or "license" for more information.
+>>> <code class="userinput">import arvados</code>
+>>> <code class="userinput">arvados.api('v1')</code>
+&lt;apiclient.discovery.Resource object at 0x233bb50&gt;
+</pre>
 </notextile>
 
-You may optionally run the final installation command in a virtualenv, or with the @--user@ option.
+If you installed from a distribution package (option 2): the package includes a virtualenv, which means the correct Python environment needs to be loaded before the Arvados SDK can be imported. This can be done by activating the virtualenv first:
 
-h4. Test installation
+<notextile>
+<pre>~$ <code class="userinput">source /usr/share/python2.7/dist/python-arvados-python-client/bin/activate</code>
+(python-arvados-python-client) ~$ <code class="userinput">python</code>
+Python 2.7.4 (default, Sep 26 2013, 03:20:26)
+[GCC 4.7.3] on linux2
+Type "help", "copyright", "credits" or "license" for more information.
+>>> <code class="userinput">import arvados</code>
+>>> <code class="userinput">arvados.api('v1')</code>
+&lt;apiclient.discovery.Resource object at 0x233bb50&gt;
+</pre>
+</notextile>
 
-If the SDK is installed and your @ARVADOS_API_HOST@ and @ARVADOS_API_TOKEN@ environment variables are set up correctly (see "api-tokens":{{site.baseurl}}/user/reference/api-tokens.html for details), @import arvados@ should produce no errors:
+Or alternatively, by using the Python executable from the virtualenv directly:
 
 <notextile>
-<pre>~$ <code class="userinput">python2.7</code>
+<pre>~$ <code class="userinput">/usr/share/python2.7/dist/python-arvados-python-client/bin/python</code>
 Python 2.7.4 (default, Sep 26 2013, 03:20:26)
 [GCC 4.7.3] on linux2
 Type "help", "copyright", "credits" or "license" for more information.
index b8afe638ac3c6a517058fd3e85a49b90607f150c..b98df8a66faf66afd479647bb9ebb210c2a022ed 100755 (executable)
@@ -2156,6 +2156,7 @@ sub find_docker_image {
           return (undef, undef);  # More than one file in the Collection.
         } else {
           $filename = (split(/:/, $filedata, 3))[2];
+          $filename =~ s/\\([0-3][0-7][0-7])/chr(oct($1))/ge;
         }
       }
     }
index 7e149528308fc9c6e38e0021af858da5450b58f8..52fd4d21a115f29ee7fb388c11ebeb0564b40ae2 100644 (file)
@@ -6,6 +6,9 @@
 # Implement cwl-runner interface for submitting and running work on Arvados, using
 # either the Crunch jobs API or Crunch containers API.
 
+from future.utils import viewitems
+from builtins import str
+
 import argparse
 import logging
 import os
@@ -66,9 +69,9 @@ def versionstring():
 def arg_parser():  # type: () -> argparse.ArgumentParser
     parser = argparse.ArgumentParser(description='Arvados executor for Common Workflow Language')
 
-    parser.add_argument("--basedir", type=str,
+    parser.add_argument("--basedir",
                         help="Base directory used to resolve relative references in the input, default to directory of input object file or current directory (if inputs piped/provided on command line).")
-    parser.add_argument("--outdir", type=str, default=os.path.abspath('.'),
+    parser.add_argument("--outdir", default=os.path.abspath('.'),
                         help="Output directory, default current directory")
 
     parser.add_argument("--eval-timeout",
@@ -99,9 +102,9 @@ def arg_parser():  # type: () -> argparse.ArgumentParser
                         default=True, dest="enable_reuse",
                         help="Disable job or container reuse")
 
-    parser.add_argument("--project-uuid", type=str, metavar="UUID", help="Project that will own the workflow jobs, if not provided, will go to home project.")
-    parser.add_argument("--output-name", type=str, help="Name to use for collection that stores the final output.", default=None)
-    parser.add_argument("--output-tags", type=str, help="Tags for the final output collection separated by commas, e.g., '--output-tags tag0,tag1,tag2'.", default=None)
+    parser.add_argument("--project-uuid", metavar="UUID", help="Project that will own the workflow jobs, if not provided, will go to home project.")
+    parser.add_argument("--output-name", help="Name to use for collection that stores the final output.", default=None)
+    parser.add_argument("--output-tags", help="Tags for the final output collection separated by commas, e.g., '--output-tags tag0,tag1,tag2'.", default=None)
     parser.add_argument("--ignore-docker-for-reuse", action="store_true",
                         help="Ignore Docker image version when deciding whether to reuse past jobs.",
                         default=False)
@@ -114,7 +117,7 @@ def arg_parser():  # type: () -> argparse.ArgumentParser
     exgroup.add_argument("--create-template", action="store_true", help="(Deprecated) synonym for --create-workflow.",
                          dest="create_workflow")
     exgroup.add_argument("--create-workflow", action="store_true", help="Create an Arvados workflow (if using the 'containers' API) or pipeline template (if using the 'jobs' API). See --api.")
-    exgroup.add_argument("--update-workflow", type=str, metavar="UUID", help="Update an existing Arvados workflow or pipeline template with the given UUID.")
+    exgroup.add_argument("--update-workflow", metavar="UUID", help="Update an existing Arvados workflow or pipeline template with the given UUID.")
 
     exgroup = parser.add_mutually_exclusive_group()
     exgroup.add_argument("--wait", action="store_true", help="After submitting workflow runner job, wait for completion.",
@@ -128,7 +131,7 @@ def arg_parser():  # type: () -> argparse.ArgumentParser
     exgroup.add_argument("--no-log-timestamps", action="store_false", help="No timestamp on logging lines",
                         default=True, dest="log_timestamps")
 
-    parser.add_argument("--api", type=str,
+    parser.add_argument("--api",
                         default=None, dest="work_api",
                         choices=("jobs", "containers"),
                         help="Select work submission API.  Default is 'jobs' if that API is available, otherwise 'containers'.")
@@ -141,7 +144,7 @@ def arg_parser():  # type: () -> argparse.ArgumentParser
                         help="RAM (in MiB) required for the workflow runner job (default 1024)",
                         default=None)
 
-    parser.add_argument("--submit-runner-image", type=str,
+    parser.add_argument("--submit-runner-image",
                         help="Docker image for workflow runner job, default arvados/jobs:%s" % __version__,
                         default=None)
 
@@ -150,11 +153,11 @@ def arg_parser():  # type: () -> argparse.ArgumentParser
                         default=False)
 
     exgroup = parser.add_mutually_exclusive_group()
-    exgroup.add_argument("--submit-request-uuid", type=str,
+    exgroup.add_argument("--submit-request-uuid",
                          default=None,
                          help="Update and commit to supplied container request instead of creating a new one (containers API only).",
                          metavar="UUID")
-    exgroup.add_argument("--submit-runner-cluster", type=str,
+    exgroup.add_argument("--submit-runner-cluster",
                          help="Submit workflow runner to a remote cluster (containers API only)",
                          default=None,
                          metavar="CLUSTER_ID")
@@ -163,7 +166,7 @@ def arg_parser():  # type: () -> argparse.ArgumentParser
                         default=None,
                         help="Collection cache size (in MiB, default 256).")
 
-    parser.add_argument("--name", type=str,
+    parser.add_argument("--name",
                         help="Name to use for workflow execution instance.",
                         default=None)
 
@@ -175,7 +178,7 @@ def arg_parser():  # type: () -> argparse.ArgumentParser
     parser.add_argument("--enable-dev", action="store_true",
                         help="Enable loading and running development versions "
                              "of CWL spec.", default=False)
-    parser.add_argument('--storage-classes', default="default", type=str,
+    parser.add_argument('--storage-classes', default="default",
                         help="Specify comma separated list of storage classes to be used when saving workflow output to Keep.")
 
     parser.add_argument("--intermediate-output-ttl", type=int, metavar="N",
@@ -208,7 +211,7 @@ def arg_parser():  # type: () -> argparse.ArgumentParser
                         default=False, dest="trash_intermediate",
                         help="Do not trash intermediate outputs (default).")
 
-    parser.add_argument("workflow", type=str, default=None, help="The workflow to execute")
+    parser.add_argument("workflow", default=None, help="The workflow to execute")
     parser.add_argument("job_order", nargs=argparse.REMAINDER, help="The input object to the workflow.")
 
     return parser
@@ -232,7 +235,7 @@ def add_arv_hints():
     ])
 
 def exit_signal_handler(sigcode, frame):
-    logger.error("Caught signal {}, exiting.".format(sigcode))
+    logger.error(str(u"Caught signal {}, exiting.").format(sigcode))
     sys.exit(-sigcode)
 
 def main(args, stdout, stderr, api_client=None, keep_client=None,
@@ -243,7 +246,7 @@ def main(args, stdout, stderr, api_client=None, keep_client=None,
     arvargs = parser.parse_args(args)
 
     if len(arvargs.storage_classes.strip().split(',')) > 1:
-        logger.error("Multiple storage classes are not supported currently.")
+        logger.error(str(u"Multiple storage classes are not supported currently."))
         return 1
 
     arvargs.use_container = True
@@ -261,7 +264,7 @@ def main(args, stdout, stderr, api_client=None, keep_client=None,
         else:
             want_api = None
         if want_api and arvargs.work_api and want_api != arvargs.work_api:
-            logger.error('--update-workflow arg {!r} uses {!r} API, but --api={!r} specified'.format(
+            logger.error(str(u'--update-workflow arg {!r} uses {!r} API, but --api={!r} specified').format(
                 arvargs.update_workflow, want_api, arvargs.work_api))
             return 1
         arvargs.work_api = want_api
@@ -271,7 +274,7 @@ def main(args, stdout, stderr, api_client=None, keep_client=None,
 
     add_arv_hints()
 
-    for key, val in cwltool.argparser.get_default_args().items():
+    for key, val in viewitems(cwltool.argparser.get_default_args()):
         if not hasattr(arvargs, key):
             setattr(arvargs, key, val)
 
index 6a91d6ff3c5076a28e06a685ed8c73bf45a84218..e921b26dfe78279c1ee22fb6a19c5e93569ed542 100644 (file)
@@ -2,10 +2,14 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from future import standard_library
+standard_library.install_aliases()
+from builtins import str
+
 import logging
 import json
 import os
-import urllib
+import urllib.request, urllib.parse, urllib.error
 import time
 import datetime
 import ciso8601
@@ -136,7 +140,7 @@ class ArvadosContainer(JobBase):
                 generatemapper = NoFollowPathMapper(self.generatefiles["listing"], "", "",
                                                     separateDirs=False)
 
-                sorteditems = sorted(generatemapper.items(), None, key=lambda n: n[1].target)
+                sorteditems = sorted(generatemapper.items(), key=lambda n: n[1].target)
 
                 logger.debug("generatemapper is %s", sorteditems)
 
@@ -158,7 +162,7 @@ class ArvadosContainer(JobBase):
                                 }
                             else:
                                 with vwd.open(p.target, "w") as n:
-                                    n.write(p.resolved.encode("utf-8"))
+                                    n.write(p.resolved)
 
                 def keepemptydirs(p):
                     if isinstance(p, arvados.collection.RichCollectionBase):
index 87d6d1049a08d349d8d45b41b47a5fccb99f237c..69fe7e2a8f1b632675b16eeb3f6ad07ee76c00e8 100644 (file)
@@ -2,6 +2,10 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from past.builtins import basestring
+from builtins import object
+from future.utils import viewitems
+
 import logging
 import re
 import copy
@@ -243,7 +247,7 @@ class ArvadosJob(JobBase):
                                                                    api_client=self.arvrunner.api,
                                                                    keep_client=self.arvrunner.keep_client,
                                                                    num_retries=self.arvrunner.num_retries)
-                        log = logc.open(logc.keys()[0])
+                        log = logc.open(list(logc.keys())[0])
                         dirs = {
                             "tmpdir": "/tmpdir",
                             "outdir": "/outdir",
@@ -343,7 +347,7 @@ class RunnerJob(Runner):
             find_or_create=self.enable_reuse
         ).execute(num_retries=self.arvrunner.num_retries)
 
-        for k,v in job_spec["script_parameters"].items():
+        for k,v in viewitems(job_spec["script_parameters"]):
             if v is False or v is None or isinstance(v, dict):
                 job_spec["script_parameters"][k] = {"value": v}
 
index c4e9f44abb0b20ecb66a7bdc13c5240beaaeeccb..31e6be12b533cb9d96c65f74189935fad8c3fcbe 100644 (file)
@@ -16,7 +16,7 @@ def validate_cluster_target(arvrunner, runtimeContext):
         runtimeContext.submit_runner_cluster not in arvrunner.api._rootDesc["remoteHosts"] and
         runtimeContext.submit_runner_cluster != arvrunner.api._rootDesc["uuidPrefix"]):
         raise WorkflowException("Unknown or invalid cluster id '%s' known remote clusters are %s" % (runtimeContext.submit_runner_cluster,
-                                                                                                  ", ".join(arvrunner.api._rootDesc["remoteHosts"].keys())))
+                                                                                                  ", ".join(list(arvrunner.api._rootDesc["remoteHosts"].keys()))))
 def set_cluster_target(tool, arvrunner, builder, runtimeContext):
     cluster_target_req = None
     for field in ("hints", "requirements"):
index ea167d4044d76fa91953eb401962107afd6b878e..8e6bff4f04cb525106ee18a62cfb6146542f3c18 100644 (file)
@@ -2,6 +2,9 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from past.builtins import basestring
+from future.utils import viewitems
+
 import os
 import json
 import copy
@@ -135,7 +138,7 @@ class ArvadosWorkflowStep(WorkflowStep):
         runtimeContext = runtimeContext.copy()
         runtimeContext.toplevel = True  # Preserve behavior for #13365
 
-        builder = make_builder({shortname(k): v for k,v in joborder.items()}, self.hints, self.requirements, runtimeContext)
+        builder = make_builder({shortname(k): v for k,v in viewitems(joborder)}, self.hints, self.requirements, runtimeContext)
         runtimeContext = set_cluster_target(self.tool, self.arvrunner, builder, runtimeContext)
         return super(ArvadosWorkflowStep, self).job(joborder, output_callback, runtimeContext)
 
index 61f9cbbe0dc80a7ce7c4894ccb2697c0b0310652..c886550d41606e60e04f0142e55519e5ea33c89a 100644 (file)
@@ -10,6 +10,9 @@
 # tool.  When the workflow completes, record the output object in an output
 # collection for this runner job.
 
+from past.builtins import basestring
+from future.utils import viewitems
+
 import arvados
 import arvados_cwl
 import arvados.collection
@@ -61,7 +64,7 @@ def run():
             if "location" in v:
                 v["location"] = keeppath(v["location"])
 
-        for k,v in job_order_object.items():
+        for k,v in viewitems(job_order_object):
             if isinstance(v, basestring) and arvados.util.keep_locator_pattern.match(v):
                 job_order_object[k] = {
                     "class": "File",
index 6d46e79cb84b33bee3af508c86498201aa37acd1..9b26ad7064207e8e76e4f819604833ab7b7a1dd7 100644 (file)
@@ -2,6 +2,8 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from future.utils import viewvalues
+
 import re
 from cwltool.errors import WorkflowException
 from collections import deque
@@ -63,7 +65,7 @@ def logtail(logcollection, logfunc, header, maxlen=25):
     containersapi = ("crunch-run.txt" in logcollection)
     mergelogs = {}
 
-    for log in logcollection.keys():
+    for log in list(logcollection):
         if not containersapi or log in ("crunch-run.txt", "stdout.txt", "stderr.txt"):
             logname = log[:-4]
             logt = deque([], maxlen)
@@ -77,7 +79,7 @@ def logtail(logcollection, logfunc, header, maxlen=25):
                         logt.append(l)
 
     if containersapi:
-        keys = mergelogs.keys()
+        keys = list(mergelogs)
         loglines = []
         while True:
             earliest = None
@@ -91,7 +93,7 @@ def logtail(logcollection, logfunc, header, maxlen=25):
             loglines.append("%s %s %s" % (ts, earliest, msg))
         loglines = loglines[-maxlen:]
     else:
-        loglines = mergelogs.values()[0]
+        loglines = mergelogs[list(mergelogs)[0]]
 
     logtxt = "\n  ".join(l.strip() for l in loglines)
     logfunc("%s\n\n  %s", header, logtxt)
index 27774b2f7cf6bd1fbb9bd8474f5dde4e7e4d6d51..535cfd7582b985ad806d659f518f9da9ce0e6fbc 100644 (file)
@@ -2,6 +2,12 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from __future__ import division
+from builtins import next
+from builtins import object
+from builtins import str
+from future.utils import viewvalues
+
 import argparse
 import logging
 import os
@@ -157,7 +163,7 @@ class ArvCwlExecutor(object):
                 raise Exception("Unsupported API '%s', expected one of %s" % (arvargs.work_api, expected_api))
 
         if self.work_api == "jobs":
-            logger.warn("""
+            logger.warning("""
 *******************************
 Using the deprecated 'jobs' API.
 
@@ -180,6 +186,11 @@ http://doc.arvados.org/install/install-api-server.html#disable_api_methods
         # if running inside a container
         if arvados_cwl.util.get_current_container(self.api, self.num_retries, logger):
             root_logger = logging.getLogger('')
+
+            # Remove existing RuntimeStatusLoggingHandlers if they exist
+            handlers = [h for h in root_logger.handlers if not isinstance(h, RuntimeStatusLoggingHandler)]
+            root_logger.handlers = handlers
+
             handler = RuntimeStatusLoggingHandler(self.runtime_status_update)
             root_logger.addHandler(handler)
 
@@ -332,7 +343,7 @@ http://doc.arvados.org/install/install-api-server.html#disable_api_methods
                 if self.stop_polling.is_set():
                     break
                 with self.workflow_eval_lock:
-                    keys = list(self.processes.keys())
+                    keys = list(self.processes)
                 if not keys:
                     remain_wait = self.poll_interval
                     continue
@@ -351,7 +362,7 @@ http://doc.arvados.org/install/install-api-server.html#disable_api_methods
                     try:
                         proc_states = table.list(filters=[["uuid", "in", page]]).execute(num_retries=self.num_retries)
                     except Exception as e:
-                        logger.warn("Error checking states on API server: %s", e)
+                        logger.warning("Error checking states on API server: %s", e)
                         remain_wait = self.poll_interval
                         continue
 
@@ -383,7 +394,7 @@ http://doc.arvados.org/install/install-api-server.html#disable_api_methods
             try:
                 self.api.collections().delete(uuid=i).execute(num_retries=self.num_retries)
             except:
-                logger.warn("Failed to delete intermediate output: %s", sys.exc_info()[1], exc_info=(sys.exc_info()[1] if self.debug else False))
+                logger.warning("Failed to delete intermediate output: %s", sys.exc_info()[1], exc_info=(sys.exc_info()[1] if self.debug else False))
             if sys.exc_info()[0] is KeyboardInterrupt or sys.exc_info()[0] is SystemExit:
                 break
 
@@ -401,7 +412,7 @@ http://doc.arvados.org/install/install-api-server.html#disable_api_methods
                             "Option 'dockerOutputDirectory' must be an absolute path.")
             if obj.get("class") == "http://commonwl.org/cwltool#Secrets" and self.work_api != "containers":
                 raise SourceLine(obj, "class", UnsupportedRequirement).makeError("Secrets not supported with --api=jobs")
-            for v in obj.itervalues():
+            for v in viewvalues(obj):
                 self.check_features(v)
         elif isinstance(obj, list):
             for i,v in enumerate(obj):
@@ -445,7 +456,7 @@ http://doc.arvados.org/install/install-api-server.html#disable_api_methods
                 logger.error("Creating CollectionReader for '%s' '%s': %s", k, v, e)
                 raise
             except IOError as e:
-                logger.warn("While preparing output collection: %s", e)
+                logger.warning("While preparing output collection: %s", e)
 
         def rewrite(fileobj):
             fileobj["location"] = generatemapper.mapper(fileobj["location"]).target
@@ -457,7 +468,8 @@ http://doc.arvados.org/install/install-api-server.html#disable_api_methods
         adjustFileObjs(outputObj, rewrite)
 
         with final.open("cwl.output.json", "w") as f:
-            json.dump(outputObj, f, sort_keys=True, indent=4, separators=(',',': '))
+            res = str(json.dumps(outputObj, sort_keys=True, indent=4, separators=(',',': '), ensure_ascii=False))
+            f.write(res)           
 
         final.save_new(name=name, owner_uuid=self.project_uuid, storage_classes=storage_classes, ensure_unique_name=True)
 
@@ -608,7 +620,7 @@ http://doc.arvados.org/install/install-api-server.html#disable_api_methods
                         visited.add(m.group(1))
                         estimated_size[0] += int(m.group(2))
             visit_class(job_order, ("File", "Directory"), estimate_collection_cache)
-            runtimeContext.collection_cache_size = max(((estimated_size[0]*192) / (1024*1024))+1, 256)
+            runtimeContext.collection_cache_size = max(((estimated_size[0]*192) // (1024*1024))+1, 256)
             self.collection_cache.set_cap(runtimeContext.collection_cache_size*1024*1024)
 
         logger.info("Using collection cache size %s MiB", runtimeContext.collection_cache_size)
@@ -660,7 +672,7 @@ http://doc.arvados.org/install/install-api-server.html#disable_api_methods
                            runtimeContext)
 
         if runtimeContext.submit and not runtimeContext.wait:
-            runnerjob = jobiter.next()
+            runnerjob = next(jobiter)
             runnerjob.run(runtimeContext)
             return (runnerjob.uuid, "success")
 
index 0816ee8fc05b74198ae9abad69887905bf8113ee..fc7cc42d15c61f19021f006cb1eec18ab94178cd 100644 (file)
@@ -2,10 +2,16 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from future import standard_library
+standard_library.install_aliases()
+from builtins import object
+from builtins import str
+from future.utils import viewvalues
+
 import fnmatch
 import os
 import errno
-import urlparse
+import urllib.parse
 import re
 import logging
 import threading
@@ -48,7 +54,7 @@ class CollectionCache(object):
 
     def cap_cache(self, required):
         # ordered dict iterates from oldest to newest
-        for pdh, v in self.collections.items():
+        for pdh, v in list(self.collections.items()):
             available = self.cap - self.total
             if available >= required or len(self.collections) < self.min_entries:
                 return
@@ -90,7 +96,7 @@ class CollectionFsAccess(cwltool.stdfsaccess.StdFsAccess):
         p = sp[0]
         if p.startswith("keep:") and arvados.util.keep_locator_pattern.match(p[5:]):
             pdh = p[5:]
-            return (self.collection_cache.get(pdh), urlparse.unquote(sp[1]) if len(sp) == 2 else None)
+            return (self.collection_cache.get(pdh), urllib.parse.unquote(sp[1]) if len(sp) == 2 else None)
         else:
             return (None, path)
 
@@ -188,7 +194,7 @@ class CollectionFsAccess(cwltool.stdfsaccess.StdFsAccess):
                 raise IOError(errno.ENOENT, "Directory '%s' in '%s' not found" % (rest, collection.portable_data_hash()))
             if not isinstance(dir, arvados.collection.RichCollectionBase):
                 raise IOError(errno.ENOENT, "Path '%s' in '%s' is not a Directory" % (rest, collection.portable_data_hash()))
-            return [abspath(l, fn) for l in dir.keys()]
+            return [abspath(l, fn) for l in list(dir.keys())]
         else:
             return super(CollectionFsAccess, self).listdir(fn)
 
@@ -243,11 +249,11 @@ class CollectionFetcher(DefaultFetcher):
         if not url:
             return base_url
 
-        urlsp = urlparse.urlsplit(url)
+        urlsp = urllib.parse.urlsplit(url)
         if urlsp.scheme or not base_url:
             return url
 
-        basesp = urlparse.urlsplit(base_url)
+        basesp = urllib.parse.urlsplit(base_url)
         if basesp.scheme in ("keep", "arvwf"):
             if not basesp.path:
                 raise IOError(errno.EINVAL, "Invalid Keep locator", base_url)
@@ -268,7 +274,7 @@ class CollectionFetcher(DefaultFetcher):
                 baseparts.pop()
 
             path = "/".join([pdh] + baseparts + urlparts)
-            return urlparse.urlunsplit((basesp.scheme, "", path, "", urlsp.fragment))
+            return urllib.parse.urlunsplit((basesp.scheme, "", path, "", urlsp.fragment))
 
         return super(CollectionFetcher, self).urljoin(base_url, url)
 
@@ -283,21 +289,21 @@ pipeline_template_uuid_pattern = re.compile(r'[a-z0-9]{5}-p5p6p-[a-z0-9]{15}')
 
 def collectionResolver(api_client, document_loader, uri, num_retries=4):
     if uri.startswith("keep:") or uri.startswith("arvwf:"):
-        return uri
+        return str(uri)
 
     if workflow_uuid_pattern.match(uri):
-        return "arvwf:%s#main" % (uri)
+        return u"arvwf:%s#main" % (uri)
 
     if pipeline_template_uuid_pattern.match(uri):
         pt = api_client.pipeline_templates().get(uuid=uri).execute(num_retries=num_retries)
-        return "keep:" + pt["components"].values()[0]["script_parameters"]["cwl:tool"]
+        return u"keep:" + viewvalues(pt["components"])[0]["script_parameters"]["cwl:tool"]
 
     p = uri.split("/")
     if arvados.util.keep_locator_pattern.match(p[0]):
-        return "keep:%s" % (uri)
+        return u"keep:%s" % (uri)
 
     if arvados.util.collection_uuid_pattern.match(p[0]):
-        return "keep:%s%s" % (api_client.collections().
+        return u"keep:%s%s" % (api_client.collections().
                               get(uuid=p[0]).execute()["portable_data_hash"],
                               uri[len(p[0]):])
 
index 4516de021b8522f25990cf2988b7b4345f13849d..ccc2e793b067f4e0853da275947a08d3630723a3 100644 (file)
@@ -2,6 +2,10 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from __future__ import division
+from future import standard_library
+standard_library.install_aliases()
+
 import requests
 import email.utils
 import time
@@ -9,7 +13,7 @@ import datetime
 import re
 import arvados
 import arvados.collection
-import urlparse
+import urllib.parse
 import logging
 import calendar
 
@@ -91,13 +95,13 @@ def http_to_keep(api, project_uuid, url, utcnow=datetime.datetime.utcnow):
         if fresh_cache(url, properties, now):
             # Do nothing
             cr = arvados.collection.CollectionReader(item["portable_data_hash"], api_client=api)
-            return "keep:%s/%s" % (item["portable_data_hash"], cr.keys()[0])
+            return "keep:%s/%s" % (item["portable_data_hash"], list(cr.keys())[0])
 
         if not changed(url, properties, now):
             # ETag didn't change, same content, just update headers
             api.collections().update(uuid=item["uuid"], body={"collection":{"properties": properties}}).execute()
             cr = arvados.collection.CollectionReader(item["portable_data_hash"], api_client=api)
-            return "keep:%s/%s" % (item["portable_data_hash"], cr.keys()[0])
+            return "keep:%s/%s" % (item["portable_data_hash"], list(cr.keys())[0])
 
     properties = {}
     req = requests.get(url, stream=True, allow_redirects=True)
@@ -123,7 +127,7 @@ def http_to_keep(api, project_uuid, url, utcnow=datetime.datetime.utcnow):
         else:
             name = grp.group(4)
     else:
-        name = urlparse.urlparse(url).path.split("/")[-1]
+        name = urllib.parse.urlparse(url).path.split("/")[-1]
 
     count = 0
     start = time.time()
@@ -134,14 +138,14 @@ def http_to_keep(api, project_uuid, url, utcnow=datetime.datetime.utcnow):
             f.write(chunk)
             loopnow = time.time()
             if (loopnow - checkpoint) > 20:
-                bps = (float(count)/float(loopnow - start))
+                bps = count / (loopnow - start)
                 if cl is not None:
                     logger.info("%2.1f%% complete, %3.2f MiB/s, %1.0f seconds left",
-                                float(count * 100) / float(cl),
-                                bps/(1024*1024),
-                                (cl-count)/bps)
+                                ((count * 100) / cl),
+                                (bps // (1024*1024)),
+                                ((cl-count) // bps))
                 else:
-                    logger.info("%d downloaded, %3.2f MiB/s", count, bps/(1024*1024))
+                    logger.info("%d downloaded, %3.2f MiB/s", count, (bps / (1024*1024)))
                 checkpoint = loopnow
 
     c.save_new(name="Downloaded from %s" % url, owner_uuid=project_uuid, ensure_unique_name=True)
index 0b2a22788e6f98537b0f5a3437a2d540a57d47ee..e0445febdc9a0731314607417739747c8f0e632c 100644 (file)
@@ -2,11 +2,17 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from future import standard_library
+standard_library.install_aliases()
+from builtins import str
+from past.builtins import basestring
+from future.utils import viewitems
+
 import re
 import logging
 import uuid
 import os
-import urllib
+import urllib.request, urllib.parse, urllib.error
 
 import arvados_cwl.util
 import arvados.commands.run
@@ -60,7 +66,7 @@ class ArvPathMapper(PathMapper):
             src = src[:src.index("#")]
 
         if isinstance(src, basestring) and ArvPathMapper.pdh_dirpath.match(src):
-            self._pathmap[src] = MapperEnt(src, self.collection_pattern % urllib.unquote(src[5:]), srcobj["class"], True)
+            self._pathmap[src] = MapperEnt(src, self.collection_pattern % urllib.parse.unquote(src[5:]), srcobj["class"], True)
 
         debug = logger.isEnabledFor(logging.DEBUG)
 
@@ -77,7 +83,7 @@ class ArvPathMapper(PathMapper):
                     if isinstance(st, arvados.commands.run.UploadFile):
                         uploadfiles.add((src, ab, st))
                     elif isinstance(st, arvados.commands.run.ArvFile):
-                        self._pathmap[src] = MapperEnt(st.fn, self.collection_pattern % urllib.unquote(st.fn[5:]), "File", True)
+                        self._pathmap[src] = MapperEnt(st.fn, self.collection_pattern % urllib.parse.unquote(st.fn[5:]), "File", True)
                     else:
                         raise WorkflowException("Input file path '%s' is invalid" % st)
             elif src.startswith("_:"):
@@ -114,7 +120,7 @@ class ArvPathMapper(PathMapper):
             remap.append((obj["location"], path + "/" + obj["basename"]))
         elif obj["location"].startswith("_:") and "contents" in obj:
             with c.open(path + "/" + obj["basename"], "w") as f:
-                f.write(obj["contents"].encode("utf-8"))
+                f.write(obj["contents"])
             remap.append((obj["location"], path + "/" + obj["basename"]))
         else:
             raise SourceLine(obj, "location", WorkflowException).makeError("Don't know what to do with '%s'" % obj["location"])
@@ -176,7 +182,7 @@ class ArvPathMapper(PathMapper):
                                          packed=False)
 
         for src, ab, st in uploadfiles:
-            self._pathmap[src] = MapperEnt(urllib.quote(st.fn, "/:+@"), self.collection_pattern % st.fn[5:],
+            self._pathmap[src] = MapperEnt(urllib.parse.quote(st.fn, "/:+@"), self.collection_pattern % st.fn[5:],
                                            "Directory" if os.path.isdir(ab) else "File", True)
 
         for srcobj in referenced_files:
@@ -228,7 +234,7 @@ class ArvPathMapper(PathMapper):
                                                               ab, "File", True)
                 if srcobj.get("secondaryFiles"):
                     ab = self.collection_pattern % c.portable_data_hash()
-                    self._pathmap["_:" + unicode(uuid.uuid4())] = MapperEnt("keep:"+c.portable_data_hash(), ab, "Directory", True)
+                    self._pathmap["_:" + str(uuid.uuid4())] = MapperEnt("keep:"+c.portable_data_hash(), ab, "Directory", True)
 
             if remap:
                 for loc, sub in remap:
@@ -301,7 +307,7 @@ class VwdPathMapper(StagingPathMapper):
         # with any secondary files.
         self.visitlisting(referenced_files, self.stagedir, basedir)
 
-        for path, (ab, tgt, type, staged) in self._pathmap.items():
+        for path, (ab, tgt, type, staged) in viewitems(self._pathmap):
             if type in ("File", "Directory") and ab.startswith("keep:"):
                 self._pathmap[path] = MapperEnt("$(task.keep)/%s" % ab[5:], tgt, type, staged)
 
index 39f475fe8d30e6fda700e2f3c965577745b0638f..cc3ea969df99cb000119cc60ffd5c29c28656d01 100644 (file)
@@ -2,6 +2,8 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from builtins import object
+
 import time
 import uuid
 
index 4b3275fa36b4ee497ec83c3de2b3e8a0c938fb62..ad8e903ba65f28bec56710a3ed15915482362d72 100644 (file)
@@ -2,15 +2,19 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from future import standard_library
+standard_library.install_aliases()
+from future.utils import  viewvalues, viewitems
+
 import os
-import urlparse
+import urllib.parse
 from functools import partial
 import logging
 import json
 import subprocess32 as subprocess
 from collections import namedtuple
 
-from StringIO import StringIO
+from io import StringIO
 
 from schema_salad.sourceline import SourceLine, cmap
 
@@ -61,7 +65,7 @@ def find_defaults(d, op):
         if "default" in d:
             op(d)
         else:
-            for i in d.itervalues():
+            for i in viewvalues(d):
                 find_defaults(i, op)
 
 def setSecondary(t, fileobj, discovered):
@@ -98,7 +102,7 @@ def upload_dependencies(arvrunner, name, document_loader,
     loaded = set()
     def loadref(b, u):
         joined = document_loader.fetcher.urljoin(b, u)
-        defrg, _ = urlparse.urldefrag(joined)
+        defrg, _ = urllib.parse.urldefrag(joined)
         if defrg not in loaded:
             loaded.add(defrg)
             # Use fetch_text to get raw file (before preprocessing).
@@ -171,7 +175,7 @@ def upload_dependencies(arvrunner, name, document_loader,
 
     visit_class(workflowobj, ("CommandLineTool", "Workflow"), discover_default_secondary_files)
 
-    for d in list(discovered.keys()):
+    for d in list(discovered):
         # Only interested in discovered secondaryFiles which are local
         # files that need to be uploaded.
         if d.startswith("file:"):
@@ -232,7 +236,7 @@ def packed_workflow(arvrunner, tool, merged_map):
     packed = pack(tool.doc_loader, tool.doc_loader.fetch(tool.tool["id"]),
                   tool.tool["id"], tool.metadata, rewrite_out=rewrites)
 
-    rewrite_to_orig = {v: k for k,v in rewrites.items()}
+    rewrite_to_orig = {v: k for k,v in viewitems(rewrites)}
 
     def visit(v, cur_id):
         if isinstance(v, dict):
@@ -463,7 +467,7 @@ class Runner(Process):
             if "cwl.output.json" in outc:
                 with outc.open("cwl.output.json", "rb") as f:
                     if f.size() > 0:
-                        outputs = json.load(f)
+                        outputs = json.loads(f.read().decode())
             def keepify(fileobj):
                 path = fileobj["location"]
                 if not path.startswith("keep:"):
index 1c233fac0ad98f4b0421a4e0856b00fd19d1422f..d75fec6c63e719949d6f19b7d2813d9f828262a6 100644 (file)
@@ -2,7 +2,12 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
-import Queue
+from future import standard_library
+standard_library.install_aliases()
+from builtins import range
+from builtins import object
+
+import queue
 import threading
 import logging
 
@@ -11,13 +16,13 @@ logger = logging.getLogger('arvados.cwl-runner')
 class TaskQueue(object):
     def __init__(self, lock, thread_count):
         self.thread_count = thread_count
-        self.task_queue = Queue.Queue(maxsize=self.thread_count)
+        self.task_queue = queue.Queue(maxsize=self.thread_count)
         self.task_queue_threads = []
         self.lock = lock
         self.in_flight = 0
         self.error = None
 
-        for r in xrange(0, self.thread_count):
+        for r in range(0, self.thread_count):
             t = threading.Thread(target=self.task_queue_func)
             self.task_queue_threads.append(t)
             t.start()
@@ -51,7 +56,7 @@ class TaskQueue(object):
                     return
                 self.task_queue.put(task, block=True, timeout=3)
                 return
-            except Queue.Full:
+            except queue.Full:
                 pass
             finally:
                 unlock.acquire()
@@ -62,7 +67,7 @@ class TaskQueue(object):
             # Drain queue
             while not self.task_queue.empty():
                 self.task_queue.get(True, .1)
-        except Queue.Empty:
+        except queue.Empty:
             pass
 
     def join(self):
index 98a2a89a1d281e056ee3067752e6094349123115..776fc6bc25dae06e232e2546cab501246d6cd6b3 100644 (file)
@@ -26,6 +26,9 @@ def get_current_container(api, num_retries=0, logger=None):
         current_container = api.containers().current().execute(num_retries=num_retries)
     except ApiError as e:
         # Status code 404 just means we're not running in a container.
-        if e.resp.status != 404 and logger:
-            logger.info("Getting current container: %s", e)
+        if e.resp.status != 404:
+            if logger:
+                logger.info("Getting current container: %s", e)
+            raise e
+            
     return current_container
index d13dd5ec538e678268d7b79836d745ba89d46047..fa35fe7da6380baf1f82cb8a890e21e9e31a7afd 100644 (file)
@@ -2,6 +2,9 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from builtins import str
+from builtins import next
+
 import subprocess
 import time
 import os
similarity index 51%
rename from backports/python-pycrypto/fpm-info.sh
rename to sdk/cwl/fpm-info.sh
index 85c401f4aefc27f74e1b8e3740c3eff0ea03afa9..5c47532db9ac9efa12ff9cc10b4e17b9d8ec9ae1 100644 (file)
@@ -3,13 +3,12 @@
 # SPDX-License-Identifier: Apache-2.0
 
 case "$TARGET" in
-    centos*)
-        fpm_depends+=(glibc)
-        ;;
     debian8)
-        fpm_depends+=(libc6 libgmp10)
+        fpm_depends+=(libgnutls-deb0-28 libcurl3-gnutls)
         ;;
     debian* | ubuntu*)
-        fpm_depends+=(libc6)
+        fpm_depends+=(libcurl3-gnutls libpython2.7)
         ;;
 esac
+
+fpm_args+=(--conflicts=python-cwltool --conflicts=cwltool)
index 4dc8448476123934dae7193fe680141671a2b7ec..d6a4c24a785e0ca6258550dee4b41c2cc01b9ad7 100644 (file)
@@ -2,6 +2,9 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from builtins import str
+from builtins import next
+
 from setuptools.command.egg_info import egg_info
 import subprocess
 import time
index 3bd62532a8b80b3d3513107470b827ba6ca4d02c..711796374849c115296e089e31a44729330f45fb 100644 (file)
@@ -45,6 +45,10 @@ setup(name='arvados-cwl-runner',
       data_files=[
           ('share/doc/arvados-cwl-runner', ['LICENSE-2.0.txt', 'README.rst']),
       ],
+      classifiers=[
+          'Programming Language :: Python :: 2',
+          'Programming Language :: Python :: 3',
+      ],
       test_suite='tests',
       tests_require=[
           'mock>=1.0',
index a6f4022cc3559adb40f7a5891495de2fbfd78c2a..37eb5171ebbc55779f86e0e275e4eb8d7a490cd6 100755 (executable)
@@ -13,6 +13,9 @@ reset_container=1
 leave_running=0
 config=dev
 tag="latest"
+pythoncmd=python
+suite=conformance
+runapi=containers
 
 while test -n "$1" ; do
     arg="$1"
@@ -33,8 +36,24 @@ while test -n "$1" ; do
             tag=$2
             shift ; shift
             ;;
+        --build)
+            build=1
+            shift
+            ;;
+        --pythoncmd)
+            pythoncmd=$2
+            shift ; shift
+            ;;
+        --suite)
+            suite=$2
+            shift ; shift
+            ;;
+       --api)
+           runapi=$2
+            shift ; shift
+            ;;
         -h|--help)
-            echo "$0 [--no-reset-container] [--leave-running] [--config dev|localdemo] [--tag docker_tag]"
+            echo "$0 [--no-reset-container] [--leave-running] [--config dev|localdemo] [--tag docker_tag] [--build] [--pythoncmd python(2|3)] [--suite (integration|conformance)]"
             exit
             ;;
         *)
@@ -60,13 +79,21 @@ set -eu -o pipefail
 
 . /usr/local/lib/arvbox/common.sh
 
+export PYCMD=$pythoncmd
+
 if test $config = dev ; then
   cd /usr/src/arvados/sdk/cwl
-  python setup.py sdist
+  \$PYCMD setup.py sdist
   pip_install \$(ls -r dist/arvados-cwl-runner-*.tar.gz | head -n1)
 fi
 
-pip install cwltest
+set -x
+
+if [ \$PYCMD = "python3" ]; then
+    pip3 install cwltest
+else
+    pip install cwltest
+fi
 
 mkdir -p /tmp/cwltest
 cd /tmp/cwltest
@@ -80,7 +107,9 @@ export ARVADOS_API_HOST_INSECURE=1
 export ARVADOS_API_TOKEN=\$(cat /var/lib/arvados/superuser_token)
 
 
-if test "$tag" = "latest" ; then
+if test -n "$build" ; then
+   /usr/src/arvados/build/build-dev-docker-jobs-image.sh
+elif test "$tag" = "latest" ; then
   arv-keepdocker --pull arvados/jobs $tag
 else
   jobsimg=\$(curl https://versions.arvados.org/v1/commit/$tag | python -c "import json; import sys; sys.stdout.write(json.load(sys.stdin)['Versions']['Docker']['arvados/jobs'])")
@@ -102,7 +131,12 @@ EOF2
 chmod +x /tmp/cwltest/arv-cwl-containers
 
 env
-exec ./run_test.sh RUNNER=/tmp/cwltest/arv-cwl-containers EXTRA=--compute-checksum $@
+if [[ "$suite" = "conformance" ]] ; then
+   exec ./run_test.sh RUNNER=/tmp/cwltest/arv-cwl-${runapi} EXTRA=--compute-checksum $@
+elif [[ "$suite" = "integration" ]] ; then
+   cd /usr/src/arvados/sdk/cwl/tests
+   exec ./arvados-tests.sh $@
+fi
 EOF
 
 CODE=$?
index a7445449af6030e7afee4bdb524ac55afc90b8ec..697f38017d4f0060afdae7915f472e90a9652770 100644 (file)
@@ -14,6 +14,7 @@ expression: |
   ${
     var samples = {};
     var pattern = /^(.+)(_S[0-9]{1,3}_)(.+)$/;
+    inputs.dir.listing = inputs.dir.listing.sort(function(a, b) { return a.basename.localeCompare(b.basename); });
     for (var i = 0; i < inputs.dir.listing.length; i++) {
       var file = inputs.dir.listing[i];
       var groups = file.basename.match(pattern);
@@ -32,4 +33,4 @@ expression: |
                  "listing": samples[sampleid]});
     });
     return {"out": dirs};
-  }
\ No newline at end of file
+  }
index e51c7a2531dbea456112ae577ec4698c88883e09..8b8ff28c789d771ba0c2e54855beb82381ee6a83 100644 (file)
             "size": 32
         },
         {
-            "checksum": "sha1$83483b9c65d99967aecc794c14f9f4743314d186",
-            "location": "sample2_S01_R3_001.fastq.txt",
+            "checksum": "sha1$5f3b4df1b0f7fdced751fc6079778600ad9fdb45",
+            "location": "sample2_S01_R1_001.fastq.txt",
             "class": "File",
             "size": 32
         }
index b3338939edd983850ec7d426fa32619176cc4d84..1458772a3f65f22dfe494df7ddbe55d7ca308f2e 100644 (file)
@@ -2,6 +2,7 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from __future__ import print_function
 import arvados
 import json
 
index 6fe90813e7a720c9ba5c11d9650af34e49ee9cdd..40bb843b2980877a0dbe10f18b41463c255609e5 100644 (file)
@@ -2,6 +2,7 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from __future__ import print_function
 import arvados
 import json
 
index 99c26523ed471dc6d14b165aee9cceba5d9e57b5..e45bd72642df7e735bdc0d5529286536bf536de8 100644 (file)
@@ -2,4 +2,5 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
-print "Hello world"
+from __future__ import print_function
+print("Hello world")
index 50c0c60b1d0a337527ddd2342ae1ed46e22b1708..04e67b7dbd48aaefec075e77c2a8836d81cb2631 100644 (file)
@@ -2,6 +2,8 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from builtins import object
+
 import difflib
 import json
 import re
index a34d550f62ad2b24a1ff156d7b740377c811cab5..de21fc0b92d1c7437978be0a5018c3ea51fd76c3 100644 (file)
@@ -2,6 +2,9 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from builtins import str
+from builtins import object
+
 import arvados_cwl
 import arvados_cwl.context
 import arvados_cwl.util
index 0c66c39c0b4607e492725a280d8dfca3aa52ec19..88bd49fcd329faee02fc29f777adbdd41d3f21a2 100644 (file)
@@ -2,8 +2,11 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from future import standard_library
+standard_library.install_aliases()
+
 import copy
-import cStringIO
+import io
 import functools
 import hashlib
 import json
index 2aaac0ae50699f5c012f36ba2f28eee1ccd281c4..022d75be11a09031746adf7a39975793ec293e83 100644 (file)
@@ -2,6 +2,11 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from future import standard_library
+standard_library.install_aliases()
+from builtins import str
+from builtins import next
+
 import functools
 import json
 import logging
@@ -9,7 +14,7 @@ import mock
 import os
 import unittest
 import copy
-import StringIO
+import io
 
 import arvados
 import arvados_cwl
@@ -126,7 +131,7 @@ class TestJob(unittest.TestCase):
                     # sharing link on the job
                     runner.api.links().create.side_effect = ApiError(
                         mock.MagicMock(return_value={'status': 403}),
-                        'Permission denied')
+                        bytes(b'Permission denied'))
                     j.run(runtimeContext)
                 else:
                     assert not runner.api.links().create.called
@@ -213,11 +218,12 @@ class TestJob(unittest.TestCase):
         runner.num_retries = 0
         runner.ignore_docker_for_reuse = False
 
-        reader().open.return_value = StringIO.StringIO(
-            """2016-11-02_23:12:18 c97qk-8i9sb-cryqw2blvzy4yaj 13358 0 stderr 2016/11/02 23:12:18 crunchrunner: $(task.tmpdir)=/tmp/crunch-job-task-work/compute3.1/tmpdir
+        reader().keys.return_value = "log.txt"
+        reader().open.return_value = io.StringIO(
+            str(u"""2016-11-02_23:12:18 c97qk-8i9sb-cryqw2blvzy4yaj 13358 0 stderr 2016/11/02 23:12:18 crunchrunner: $(task.tmpdir)=/tmp/crunch-job-task-work/compute3.1/tmpdir
 2016-11-02_23:12:18 c97qk-8i9sb-cryqw2blvzy4yaj 13358 0 stderr 2016/11/02 23:12:18 crunchrunner: $(task.outdir)=/tmp/crunch-job-task-work/compute3.1/outdir
 2016-11-02_23:12:18 c97qk-8i9sb-cryqw2blvzy4yaj 13358 0 stderr 2016/11/02 23:12:18 crunchrunner: $(task.keep)=/keep
-        """)
+        """))
         api.collections().list().execute.side_effect = ({"items": []},
                                                         {"items": [{"manifest_text": "XYZ"}]},
                                                         {"items": []},
@@ -286,11 +292,12 @@ class TestJob(unittest.TestCase):
         runner.project_uuid = "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
         runner.num_retries = 0
 
-        reader().open.return_value = StringIO.StringIO(
-            """2016-11-02_23:12:18 c97qk-8i9sb-cryqw2blvzy4yaj 13358 0 stderr 2016/11/02 23:12:18 crunchrunner: $(task.tmpdir)=/tmp/crunch-job-task-work/compute3.1/tmpdir
+        reader().keys.return_value = "log.txt"
+        reader().open.return_value = io.StringIO(
+            str(u"""2016-11-02_23:12:18 c97qk-8i9sb-cryqw2blvzy4yaj 13358 0 stderr 2016/11/02 23:12:18 crunchrunner: $(task.tmpdir)=/tmp/crunch-job-task-work/compute3.1/tmpdir
 2016-11-02_23:12:18 c97qk-8i9sb-cryqw2blvzy4yaj 13358 0 stderr 2016/11/02 23:12:18 crunchrunner: $(task.outdir)=/tmp/crunch-job-task-work/compute3.1/outdir
 2016-11-02_23:12:18 c97qk-8i9sb-cryqw2blvzy4yaj 13358 0 stderr 2016/11/02 23:12:18 crunchrunner: $(task.keep)=/keep
-        """)
+        """))
 
         api.collections().list().execute.side_effect = (
             {"items": [{"uuid": "zzzzz-4zz18-zzzzzzzzzzzzzz2"}]},
@@ -398,8 +405,8 @@ class TestWorkflow(unittest.TestCase):
         arvtool.formatgraph = None
         it = arvtool.job({}, mock.MagicMock(), runtimeContext)
 
-        it.next().run(runtimeContext)
-        it.next().run(runtimeContext)
+        next(it).run(runtimeContext)
+        next(it).run(runtimeContext)
 
         with open("tests/wf/scatter2_subwf.cwl") as f:
             subwf = StripYAMLComments(f.read())
@@ -435,7 +442,7 @@ class TestWorkflow(unittest.TestCase):
 
         mockc.open().__enter__().write.assert_has_calls([mock.call(subwf)])
         mockc.open().__enter__().write.assert_has_calls([mock.call(
-'''{
+bytes(b'''{
   "fileblub": {
     "basename": "token.txt",
     "class": "File",
@@ -443,7 +450,7 @@ class TestWorkflow(unittest.TestCase):
     "size": 0
   },
   "sleeptime": 5
-}''')])
+}'''))])
 
     # The test passes no builder.resources
     # Hence the default resources will apply: {'cores': 1, 'ram': 1024, 'outdirSize': 1024, 'tmpdirSize': 1024}
@@ -477,8 +484,9 @@ class TestWorkflow(unittest.TestCase):
         arvtool = arvados_cwl.ArvadosWorkflow(runner, tool, loadingContext)
         arvtool.formatgraph = None
         it = arvtool.job({}, mock.MagicMock(), runtimeContext)
-        it.next().run(runtimeContext)
-        it.next().run(runtimeContext)
+        
+        next(it).run(runtimeContext)
+        next(it).run(runtimeContext)
 
         with open("tests/wf/echo-subwf.cwl") as f:
             subwf = StripYAMLComments(f.read())
index baeb4145ee6dbc5ba4db326f88acd54ce04352f4..562d1765daa24254cf4ad1a33b03af1129f57eff 100644 (file)
@@ -2,12 +2,15 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from future import standard_library
+standard_library.install_aliases()
+
 import functools
 import json
 import logging
 import mock
 import os
-import StringIO
+import io
 import unittest
 
 import arvados
@@ -35,7 +38,7 @@ class TestMakeOutput(unittest.TestCase):
         final_uuid = final.manifest_locator()
         num_retries = runner.num_retries
 
-        cwlout = StringIO.StringIO()
+        cwlout = io.StringIO()
         openmock = mock.MagicMock()
         final.open.return_value = openmock
         openmock.__enter__.return_value = cwlout
index 90dab01471ef61ab380955e6301a73306648edef..782282d2a0d4312a8a25a18b970d009bc6a9f66f 100644 (file)
@@ -2,8 +2,14 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from future import standard_library
+standard_library.install_aliases()
+from builtins import object
+from builtins import str
+from future.utils import viewvalues
+
 import copy
-import cStringIO
+import io
 import functools
 import hashlib
 import json
@@ -12,6 +18,8 @@ import mock
 import sys
 import unittest
 
+from io import BytesIO, StringIO
+
 import arvados
 import arvados.collection
 import arvados_cwl
@@ -33,7 +41,7 @@ def stubs(func):
     @mock.patch("arvados.keep.KeepClient")
     @mock.patch("arvados.events.subscribe")
     def wrapped(self, events, keep_client1, keep_client2, keepdocker, *args, **kwargs):
-        class Stubs:
+        class Stubs(object):
             pass
         stubs = Stubs()
         stubs.events = events
@@ -60,6 +68,11 @@ def stubs(func):
         stubs.fake_user_uuid = "zzzzz-tpzed-zzzzzzzzzzzzzzz"
         stubs.fake_container_uuid = "zzzzz-dz642-zzzzzzzzzzzzzzz"
 
+        if sys.version_info[0] < 3:
+            stubs.capture_stdout = BytesIO()
+        else:
+            stubs.capture_stdout = StringIO()
+
         stubs.api = mock.MagicMock()
         stubs.api._rootDesc = get_rootDesc()
 
@@ -78,18 +91,18 @@ def stubs(func):
                 return self.exe
 
         def collection_createstub(created_collections, body, ensure_unique_name=None):
-            mt = body["manifest_text"]
+            mt = body["manifest_text"].encode('utf-8')
             uuid = "zzzzz-4zz18-zzzzzzzzzzzzzx%d" % len(created_collections)
             pdh = "%s+%i" % (hashlib.md5(mt).hexdigest(), len(mt))
             created_collections[uuid] = {
                 "uuid": uuid,
                 "portable_data_hash": pdh,
-                "manifest_text": mt
+                "manifest_text": mt.decode('utf-8')
             }
             return CollectionExecute(created_collections[uuid])
 
         def collection_getstub(created_collections, uuid):
-            for v in created_collections.itervalues():
+            for v in viewvalues(created_collections):
                 if uuid in (v["uuid"], v["portable_data_hash"]):
                     return CollectionExecute(v)
 
@@ -318,12 +331,10 @@ class TestSubmit(unittest.TestCase):
                 return '999999999999999999999999999999d4+99'
         arvdock.side_effect = get_image
 
-        capture_stdout = cStringIO.StringIO()
         exited = arvados_cwl.main(
             ["--submit", "--no-wait", "--api=jobs", "--debug",
              "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
-        self.assertEqual(exited, 0)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
 
         stubs.api.collections().create.assert_has_calls([
             mock.call(body=JsonDiffMatcher({
@@ -354,19 +365,17 @@ class TestSubmit(unittest.TestCase):
         expect_pipeline = copy.deepcopy(stubs.expect_pipeline_instance)
         stubs.api.pipeline_instances().create.assert_called_with(
             body=JsonDiffMatcher(expect_pipeline))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_pipeline_uuid + '\n')
-
+        self.assertEqual(exited, 0)
 
     @mock.patch("time.sleep")
     @stubs
     def test_submit_no_reuse(self, stubs, tm):
-        capture_stdout = cStringIO.StringIO()
         exited = arvados_cwl.main(
             ["--submit", "--no-wait", "--api=jobs", "--debug", "--disable-reuse",
              "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
-        self.assertEqual(exited, 0)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
 
         expect_pipeline = copy.deepcopy(stubs.expect_pipeline_instance)
         expect_pipeline["components"]["cwl-runner"]["script_parameters"]["arv:enable_reuse"] = {"value": False}
@@ -374,8 +383,9 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.pipeline_instances().create.assert_called_with(
             body=JsonDiffMatcher(expect_pipeline))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_pipeline_uuid + '\n')
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_error_when_multiple_storage_classes_specified(self, stubs):
@@ -389,49 +399,44 @@ class TestSubmit(unittest.TestCase):
     @mock.patch("time.sleep")
     @stubs
     def test_submit_on_error(self, stubs, tm):
-        capture_stdout = cStringIO.StringIO()
         exited = arvados_cwl.main(
             ["--submit", "--no-wait", "--api=jobs", "--debug", "--on-error=stop",
              "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
-        self.assertEqual(exited, 0)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
 
         expect_pipeline = copy.deepcopy(stubs.expect_pipeline_instance)
         expect_pipeline["components"]["cwl-runner"]["script_parameters"]["arv:on_error"] = "stop"
 
         stubs.api.pipeline_instances().create.assert_called_with(
             body=JsonDiffMatcher(expect_pipeline))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_pipeline_uuid + '\n')
-
+        self.assertEqual(exited, 0)
 
     @mock.patch("time.sleep")
     @stubs
     def test_submit_runner_ram(self, stubs, tm):
-        capture_stdout = cStringIO.StringIO()
         exited = arvados_cwl.main(
             ["--submit", "--no-wait", "--debug", "--submit-runner-ram=2048",
              "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
-        self.assertEqual(exited, 0)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
 
         expect_pipeline = copy.deepcopy(stubs.expect_pipeline_instance)
         expect_pipeline["components"]["cwl-runner"]["runtime_constraints"]["min_ram_mb_per_node"] = 2048
 
         stubs.api.pipeline_instances().create.assert_called_with(
             body=JsonDiffMatcher(expect_pipeline))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_pipeline_uuid + '\n')
-
+        self.assertEqual(exited, 0)
 
     @mock.patch("time.sleep")
     @stubs
     def test_submit_invalid_runner_ram(self, stubs, tm):
-        capture_stdout = cStringIO.StringIO()
         exited = arvados_cwl.main(
             ["--submit", "--no-wait", "--debug", "--submit-runner-ram=-2048",
              "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
         self.assertEqual(exited, 1)
 
     @mock.patch("time.sleep")
@@ -439,30 +444,27 @@ class TestSubmit(unittest.TestCase):
     def test_submit_output_name(self, stubs, tm):
         output_name = "test_output_name"
 
-        capture_stdout = cStringIO.StringIO()
         exited = arvados_cwl.main(
             ["--submit", "--no-wait", "--debug", "--output-name", output_name,
              "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
-        self.assertEqual(exited, 0)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
 
         expect_pipeline = copy.deepcopy(stubs.expect_pipeline_instance)
         expect_pipeline["components"]["cwl-runner"]["script_parameters"]["arv:output_name"] = output_name
 
         stubs.api.pipeline_instances().create.assert_called_with(
             body=JsonDiffMatcher(expect_pipeline))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_pipeline_uuid + '\n')
-
+        self.assertEqual(exited, 0)
 
     @mock.patch("time.sleep")
     @stubs
     def test_submit_pipeline_name(self, stubs, tm):
-        capture_stdout = cStringIO.StringIO()
         exited = arvados_cwl.main(
             ["--submit", "--no-wait", "--debug", "--name=hello job 123",
              "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
         self.assertEqual(exited, 0)
 
         expect_pipeline = copy.deepcopy(stubs.expect_pipeline_instance)
@@ -470,7 +472,7 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.pipeline_instances().create.assert_called_with(
             body=JsonDiffMatcher(expect_pipeline))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_pipeline_uuid + '\n')
 
     @mock.patch("time.sleep")
@@ -478,11 +480,10 @@ class TestSubmit(unittest.TestCase):
     def test_submit_output_tags(self, stubs, tm):
         output_tags = "tag0,tag1,tag2"
 
-        capture_stdout = cStringIO.StringIO()
         exited = arvados_cwl.main(
             ["--submit", "--no-wait", "--debug", "--output-tags", output_tags,
              "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
         self.assertEqual(exited, 0)
 
         expect_pipeline = copy.deepcopy(stubs.expect_pipeline_instance)
@@ -490,7 +491,7 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.pipeline_instances().create.assert_called_with(
             body=JsonDiffMatcher(expect_pipeline))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_pipeline_uuid + '\n')
 
     @mock.patch("time.sleep")
@@ -511,16 +512,11 @@ class TestSubmit(unittest.TestCase):
             body=JsonDiffMatcher(expect_pipeline))
 
     @stubs
-    def test_submit_container(self, stubs):
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug",
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+    def test_submit_container(self, stubs):        
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug",
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         stubs.api.collections().create.assert_has_calls([
             mock.call(body=JsonDiffMatcher({
@@ -539,20 +535,16 @@ class TestSubmit(unittest.TestCase):
         expect_container = copy.deepcopy(stubs.expect_container_spec)
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_container_no_reuse(self, stubs):
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug", "--disable-reuse",
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug", "--disable-reuse",
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         expect_container = copy.deepcopy(stubs.expect_container_spec)
         expect_container["command"] = [
@@ -566,18 +558,16 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
-                         stubs.expect_container_request_uuid + '\n')
-
+        self.assertEqual(stubs.capture_stdout.getvalue(),
+                         stubs.expect_container_request_uuid + '\n') 
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_container_reuse_disabled_by_workflow(self, stubs):
-        capture_stdout = cStringIO.StringIO()
-
         exited = arvados_cwl.main(
             ["--submit", "--no-wait", "--api=containers", "--debug",
              "tests/wf/submit_wf_no_reuse.cwl", "tests/submit_test_job.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
         self.assertEqual(exited, 0)
 
         expect_container = copy.deepcopy(stubs.expect_container_spec)
@@ -602,22 +592,17 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
 
 
     @stubs
     def test_submit_container_on_error(self, stubs):
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug", "--on-error=stop",
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
-
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug", "--on-error=stop",
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
         expect_container = copy.deepcopy(stubs.expect_container_spec)
         expect_container["command"] = ['arvados-cwl-runner', '--local', '--api=containers',
                                        '--no-log-timestamps', '--disable-validate',
@@ -628,22 +613,18 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_container_output_name(self, stubs):
         output_name = "test_output_name"
-
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug", "--output-name", output_name,
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+  
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug", "--output-name", output_name,
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         expect_container = copy.deepcopy(stubs.expect_container_spec)
         expect_container["command"] = ['arvados-cwl-runner', '--local', '--api=containers',
@@ -656,20 +637,16 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
+        self.assertEqual(exited, 0)
 
     @stubs
-    def test_submit_storage_classes(self, stubs):
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--debug", "--submit", "--no-wait", "--api=containers", "--storage-classes=foo",
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+    def test_submit_storage_classes(self, stubs):     
+        exited = arvados_cwl.main(
+            ["--debug", "--submit", "--no-wait", "--api=containers", "--storage-classes=foo",
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         expect_container = copy.deepcopy(stubs.expect_container_spec)
         expect_container["command"] = ['arvados-cwl-runner', '--local', '--api=containers',
@@ -681,8 +658,9 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
+        self.assertEqual(exited, 0)
 
     @mock.patch("arvados_cwl.task_queue.TaskQueue")
     @mock.patch("arvados_cwl.arvworkflow.ArvadosWorkflow.job")
@@ -694,16 +672,13 @@ class TestSubmit(unittest.TestCase):
             return []
         job.side_effect = set_final_output
 
-        try:
-            exited = arvados_cwl.main(
-                ["--debug", "--local", "--storage-classes=foo",
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                sys.stdin, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+        exited = arvados_cwl.main(
+            ["--debug", "--local", "--storage-classes=foo",
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            sys.stdin, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         make_output.assert_called_with(u'Output of submit_wf.cwl', ['foo'], '', 'zzzzz-4zz18-zzzzzzzzzzzzzzzz')
+        self.assertEqual(exited, 0)
 
     @mock.patch("arvados_cwl.task_queue.TaskQueue")
     @mock.patch("arvados_cwl.arvworkflow.ArvadosWorkflow.job")
@@ -715,28 +690,20 @@ class TestSubmit(unittest.TestCase):
             return []
         job.side_effect = set_final_output
 
-        try:
-            exited = arvados_cwl.main(
-                ["--debug", "--local",
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                sys.stdin, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+        exited = arvados_cwl.main(
+            ["--debug", "--local",
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            sys.stdin, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         make_output.assert_called_with(u'Output of submit_wf.cwl', ['default'], '', 'zzzzz-4zz18-zzzzzzzzzzzzzzzz')
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_container_output_ttl(self, stubs):
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug", "--intermediate-output-ttl", "3600",
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug", "--intermediate-output-ttl", "3600",
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         expect_container = copy.deepcopy(stubs.expect_container_spec)
         expect_container["command"] = ['arvados-cwl-runner', '--local', '--api=containers',
@@ -749,20 +716,17 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_container_trash_intermediate(self, stubs):
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug", "--trash-intermediate",
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug", "--trash-intermediate",
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
+            
 
         expect_container = copy.deepcopy(stubs.expect_container_spec)
         expect_container["command"] = ['arvados-cwl-runner', '--local', '--api=containers',
@@ -775,22 +739,18 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_container_output_tags(self, stubs):
         output_tags = "tag0,tag1,tag2"
 
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug", "--output-tags", output_tags,
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug", "--output-tags", output_tags,
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         expect_container = copy.deepcopy(stubs.expect_container_spec)
         expect_container["command"] = ['arvados-cwl-runner', '--local', '--api=containers',
@@ -802,56 +762,48 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_container_runner_ram(self, stubs):
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug", "--submit-runner-ram=2048",
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug", "--submit-runner-ram=2048",
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         expect_container = copy.deepcopy(stubs.expect_container_spec)
         expect_container["runtime_constraints"]["ram"] = (2048+256)*1024*1024
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
+        self.assertEqual(exited, 0)
 
     @mock.patch("arvados.collection.CollectionReader")
     @mock.patch("time.sleep")
     @stubs
     def test_submit_file_keepref(self, stubs, tm, collectionReader):
-        capture_stdout = cStringIO.StringIO()
         collectionReader().find.return_value = arvados.arvfile.ArvadosFile(mock.MagicMock(), "blorp.txt")
         exited = arvados_cwl.main(
             ["--submit", "--no-wait", "--api=containers", "--debug",
              "tests/wf/submit_keepref_wf.cwl"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
         self.assertEqual(exited, 0)
 
-
     @mock.patch("arvados.collection.CollectionReader")
     @mock.patch("time.sleep")
     @stubs
     def test_submit_keepref(self, stubs, tm, reader):
-        capture_stdout = cStringIO.StringIO()
-
         with open("tests/wf/expect_arvworkflow.cwl") as f:
             reader().open().__enter__().read.return_value = f.read()
 
         exited = arvados_cwl.main(
             ["--submit", "--no-wait", "--api=containers", "--debug",
              "keep:99999999999999999999999999999994+99/expect_arvworkflow.cwl#main", "-x", "XxX"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
-        self.assertEqual(exited, 0)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
 
         expect_container = {
             'priority': 500,
@@ -896,24 +848,21 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
-
+        self.assertEqual(exited, 0)
 
     @mock.patch("arvados.collection.CollectionReader")
     @mock.patch("time.sleep")
     @stubs
     def test_submit_jobs_keepref(self, stubs, tm, reader):
-        capture_stdout = cStringIO.StringIO()
-
         with open("tests/wf/expect_arvworkflow.cwl") as f:
             reader().open().__enter__().read.return_value = f.read()
 
         exited = arvados_cwl.main(
             ["--submit", "--no-wait", "--api=jobs", "--debug",
              "keep:99999999999999999999999999999994+99/expect_arvworkflow.cwl#main", "-x", "XxX"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
-        self.assertEqual(exited, 0)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
 
         expect_pipeline = copy.deepcopy(stubs.expect_pipeline_instance)
         expect_pipeline["components"]["cwl-runner"]["script_parameters"]["x"] = "XxX"
@@ -923,20 +872,18 @@ class TestSubmit(unittest.TestCase):
         expect_pipeline["name"] = "expect_arvworkflow.cwl#main"
         stubs.api.pipeline_instances().create.assert_called_with(
             body=JsonDiffMatcher(expect_pipeline))
+        self.assertEqual(exited, 0)
 
     @mock.patch("time.sleep")
     @stubs
     def test_submit_arvworkflow(self, stubs, tm):
-        capture_stdout = cStringIO.StringIO()
-
         with open("tests/wf/expect_arvworkflow.cwl") as f:
             stubs.api.workflows().get().execute.return_value = {"definition": f.read(), "name": "a test workflow"}
 
         exited = arvados_cwl.main(
             ["--submit", "--no-wait", "--api=containers", "--debug",
              "962eh-7fd4e-gkbzl62qqtfig37", "-x", "XxX"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
-        self.assertEqual(exited, 0)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
 
         expect_container = {
             'priority': 500,
@@ -1020,60 +967,47 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
-
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_container_name(self, stubs):
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug", "--name=hello container 123",
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug", "--name=hello container 123",
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         expect_container = copy.deepcopy(stubs.expect_container_spec)
         expect_container["name"] = "hello container 123"
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
-
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_missing_input(self, stubs):
-        capture_stdout = cStringIO.StringIO()
         exited = arvados_cwl.main(
             ["--submit", "--no-wait", "--api=containers", "--debug",
              "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
         self.assertEqual(exited, 0)
 
-        capture_stdout = cStringIO.StringIO()
         exited = arvados_cwl.main(
             ["--submit", "--no-wait", "--api=containers", "--debug",
              "tests/wf/submit_wf.cwl", "tests/submit_test_job_missing.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
         self.assertEqual(exited, 1)
 
-
     @stubs
     def test_submit_container_project(self, stubs):
         project_uuid = 'zzzzz-j7d0g-zzzzzzzzzzzzzzz'
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug", "--project-uuid="+project_uuid,
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug", "--project-uuid="+project_uuid,
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         expect_container = copy.deepcopy(stubs.expect_container_spec)
         expect_container["owner_uuid"] = project_uuid
@@ -1087,21 +1021,16 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_container_eval_timeout(self, stubs):
-        project_uuid = 'zzzzz-j7d0g-zzzzzzzzzzzzzzz'
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug", "--eval-timeout=60",
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug", "--eval-timeout=60",
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         expect_container = copy.deepcopy(stubs.expect_container_spec)
         expect_container["command"] = ['arvados-cwl-runner', '--local', '--api=containers',
@@ -1113,21 +1042,16 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_container_collection_cache(self, stubs):
-        project_uuid = 'zzzzz-j7d0g-zzzzzzzzzzzzzzz'
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug", "--collection-cache-size=500",
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug", "--collection-cache-size=500",
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         expect_container = copy.deepcopy(stubs.expect_container_spec)
         expect_container["command"] = ['arvados-cwl-runner', '--local', '--api=containers',
@@ -1140,22 +1064,16 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
-
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_container_thread_count(self, stubs):
-        project_uuid = 'zzzzz-j7d0g-zzzzzzzzzzzzzzz'
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug", "--thread-count=20",
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug", "--thread-count=20",
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         expect_container = copy.deepcopy(stubs.expect_container_spec)
         expect_container["command"] = ['arvados-cwl-runner', '--local', '--api=containers',
@@ -1167,82 +1085,64 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
-
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_job_runner_image(self, stubs):
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=jobs", "--debug", "--submit-runner-image=arvados/jobs:123",
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=jobs", "--debug", "--submit-runner-image=arvados/jobs:123",
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         stubs.expect_pipeline_instance["components"]["cwl-runner"]["runtime_constraints"]["docker_image"] = "999999999999999999999999999999d5+99"
 
         expect_pipeline = copy.deepcopy(stubs.expect_pipeline_instance)
         stubs.api.pipeline_instances().create.assert_called_with(
             body=JsonDiffMatcher(expect_pipeline))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_pipeline_uuid + '\n')
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_container_runner_image(self, stubs):
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug", "--submit-runner-image=arvados/jobs:123",
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug", "--submit-runner-image=arvados/jobs:123",
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         stubs.expect_container_spec["container_image"] = "999999999999999999999999999999d5+99"
 
         expect_container = copy.deepcopy(stubs.expect_container_spec)
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_priority(self, stubs):
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug", "--priority=669",
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug", "--priority=669",
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         stubs.expect_container_spec["priority"] = 669
 
         expect_container = copy.deepcopy(stubs.expect_container_spec)
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
-
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_wf_runner_resources(self, stubs):
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug",
-                 "tests/wf/submit_wf_runner_resources.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug",
+                "tests/wf/submit_wf_runner_resources.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         expect_container = copy.deepcopy(stubs.expect_container_spec)
         expect_container["runtime_constraints"] = {
@@ -1270,8 +1170,9 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
+        self.assertEqual(exited, 0)
 
     def tearDown(self):
         arvados_cwl.arvdocker.arv_docker_clear_cache()
@@ -1315,16 +1216,10 @@ class TestSubmit(unittest.TestCase):
 
     @stubs
     def test_submit_secrets(self, stubs):
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug",
-                 "tests/wf/secret_wf.cwl", "tests/secret_test_job.yml"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
-
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug",
+                "tests/wf/secret_wf.cwl", "tests/secret_test_job.yml"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         expect_container = {
             "command": [
@@ -1479,8 +1374,9 @@ class TestSubmit(unittest.TestCase):
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_request_uuid(self, stubs):
@@ -1492,50 +1388,41 @@ class TestSubmit(unittest.TestCase):
             "state": "Queued"
         }
 
-        capture_stdout = cStringIO.StringIO()
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug", "--submit-request-uuid=zzzzz-xvhdp-yyyyyyyyyyyyyyy",
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug", "--submit-request-uuid=zzzzz-xvhdp-yyyyyyyyyyyyyyy",
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         stubs.api.container_requests().update.assert_called_with(
             uuid="zzzzz-xvhdp-yyyyyyyyyyyyyyy", body=JsonDiffMatcher(stubs.expect_container_spec), cluster_id="zzzzz")
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_container_cluster_id(self, stubs):
-        capture_stdout = cStringIO.StringIO()
         stubs.api._rootDesc["remoteHosts"]["zbbbb"] = "123"
-        try:
-            exited = arvados_cwl.main(
-                ["--submit", "--no-wait", "--api=containers", "--debug", "--submit-runner-cluster=zbbbb",
-                 "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-                capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
-            self.assertEqual(exited, 0)
-        except:
-            logging.exception("")
+
+        exited = arvados_cwl.main(
+            ["--submit", "--no-wait", "--api=containers", "--debug", "--submit-runner-cluster=zbbbb",
+                "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
 
         expect_container = copy.deepcopy(stubs.expect_container_spec)
 
         stubs.api.container_requests().create.assert_called_with(
             body=JsonDiffMatcher(expect_container), cluster_id="zbbbb")
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_container_request_uuid + '\n')
-
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_submit_validate_cluster_id(self, stubs):
-        capture_stdout = cStringIO.StringIO()
         stubs.api._rootDesc["remoteHosts"]["zbbbb"] = "123"
         exited = arvados_cwl.main(
             ["--submit", "--no-wait", "--api=containers", "--debug", "--submit-runner-cluster=zcccc",
              "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api, keep_client=stubs.keep_client)
         self.assertEqual(exited, 1)
 
 
@@ -1565,15 +1452,12 @@ class TestCreateTemplate(unittest.TestCase):
     def test_create(self, stubs):
         project_uuid = 'zzzzz-j7d0g-zzzzzzzzzzzzzzz'
 
-        capture_stdout = cStringIO.StringIO()
-
         exited = arvados_cwl.main(
             ["--create-workflow", "--debug",
              "--api=jobs",
              "--project-uuid", project_uuid,
              "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
-        self.assertEqual(exited, 0)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
 
         stubs.api.pipeline_instances().create.refute_called()
         stubs.api.jobs().create.refute_called()
@@ -1590,24 +1474,21 @@ class TestCreateTemplate(unittest.TestCase):
         stubs.api.pipeline_templates().create.assert_called_with(
             body=JsonDiffMatcher(expect_template), ensure_unique_name=True)
 
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_pipeline_template_uuid + '\n')
-
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_create_name(self, stubs):
         project_uuid = 'zzzzz-j7d0g-zzzzzzzzzzzzzzz'
 
-        capture_stdout = cStringIO.StringIO()
-
         exited = arvados_cwl.main(
             ["--create-workflow", "--debug",
              "--project-uuid", project_uuid,
              "--api=jobs",
              "--name", "testing 123",
              "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
-        self.assertEqual(exited, 0)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
 
         stubs.api.pipeline_instances().create.refute_called()
         stubs.api.jobs().create.refute_called()
@@ -1624,16 +1505,14 @@ class TestCreateTemplate(unittest.TestCase):
         stubs.api.pipeline_templates().create.assert_called_with(
             body=JsonDiffMatcher(expect_template), ensure_unique_name=True)
 
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_pipeline_template_uuid + '\n')
-
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_update_name(self, stubs):
         project_uuid = 'zzzzz-j7d0g-zzzzzzzzzzzzzzz'
 
-        capture_stdout = cStringIO.StringIO()
-
         exited = arvados_cwl.main(
             ["--update-workflow", self.existing_template_uuid,
              "--debug",
@@ -1641,8 +1520,7 @@ class TestCreateTemplate(unittest.TestCase):
              "--api=jobs",
              "--name", "testing 123",
              "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
-        self.assertEqual(exited, 0)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
 
         stubs.api.pipeline_instances().create.refute_called()
         stubs.api.jobs().create.refute_called()
@@ -1660,9 +1538,10 @@ class TestCreateTemplate(unittest.TestCase):
         stubs.api.pipeline_templates().update.assert_called_with(
             body=JsonDiffMatcher(expect_template), uuid=self.existing_template_uuid)
 
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          self.existing_template_uuid + '\n')
-
+        self.assertEqual(exited, 0)
+        
 
 class TestCreateWorkflow(unittest.TestCase):
     existing_workflow_uuid = "zzzzz-7fd4e-validworkfloyml"
@@ -1673,15 +1552,12 @@ class TestCreateWorkflow(unittest.TestCase):
     def test_create(self, stubs):
         project_uuid = 'zzzzz-j7d0g-zzzzzzzzzzzzzzz'
 
-        capture_stdout = cStringIO.StringIO()
-
         exited = arvados_cwl.main(
             ["--create-workflow", "--debug",
              "--api=containers",
              "--project-uuid", project_uuid,
              "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
-        self.assertEqual(exited, 0)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
 
         stubs.api.pipeline_templates().create.refute_called()
         stubs.api.container_requests().create.refute_called()
@@ -1697,24 +1573,21 @@ class TestCreateWorkflow(unittest.TestCase):
         stubs.api.workflows().create.assert_called_with(
             body=JsonDiffMatcher(body))
 
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_workflow_uuid + '\n')
-
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_create_name(self, stubs):
         project_uuid = 'zzzzz-j7d0g-zzzzzzzzzzzzzzz'
 
-        capture_stdout = cStringIO.StringIO()
-
         exited = arvados_cwl.main(
             ["--create-workflow", "--debug",
              "--api=containers",
              "--project-uuid", project_uuid,
              "--name", "testing 123",
              "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
-        self.assertEqual(exited, 0)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
 
         stubs.api.pipeline_templates().create.refute_called()
         stubs.api.container_requests().create.refute_called()
@@ -1730,14 +1603,16 @@ class TestCreateWorkflow(unittest.TestCase):
         stubs.api.workflows().create.assert_called_with(
             body=JsonDiffMatcher(body))
 
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_workflow_uuid + '\n')
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_incompatible_api(self, stubs):
-        capture_stderr = cStringIO.StringIO()
-        logging.getLogger('arvados.cwl-runner').addHandler(
-            logging.StreamHandler(capture_stderr))
+        capture_stderr = io.StringIO()
+        acr_logger = logging.getLogger('arvados.cwl-runner')
+        stderr_logger = logging.StreamHandler(capture_stderr)
+        acr_logger.addHandler(stderr_logger)
 
         exited = arvados_cwl.main(
             ["--update-workflow", self.existing_workflow_uuid,
@@ -1749,17 +1624,15 @@ class TestCreateWorkflow(unittest.TestCase):
         self.assertRegexpMatches(
             capture_stderr.getvalue(),
             "--update-workflow arg '{}' uses 'containers' API, but --api='jobs' specified".format(self.existing_workflow_uuid))
+        acr_logger.removeHandler(stderr_logger)
 
     @stubs
     def test_update(self, stubs):
-        capture_stdout = cStringIO.StringIO()
-
         exited = arvados_cwl.main(
             ["--update-workflow", self.existing_workflow_uuid,
              "--debug",
              "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
-        self.assertEqual(exited, 0)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
 
         body = {
             "workflow": {
@@ -1771,20 +1644,17 @@ class TestCreateWorkflow(unittest.TestCase):
         stubs.api.workflows().update.assert_called_with(
             uuid=self.existing_workflow_uuid,
             body=JsonDiffMatcher(body))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          self.existing_workflow_uuid + '\n')
-
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_update_name(self, stubs):
-        capture_stdout = cStringIO.StringIO()
-
         exited = arvados_cwl.main(
             ["--update-workflow", self.existing_workflow_uuid,
              "--debug", "--name", "testing 123",
              "tests/wf/submit_wf.cwl", "tests/submit_test_job.json"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
-        self.assertEqual(exited, 0)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
 
         body = {
             "workflow": {
@@ -1796,23 +1666,20 @@ class TestCreateWorkflow(unittest.TestCase):
         stubs.api.workflows().update.assert_called_with(
             uuid=self.existing_workflow_uuid,
             body=JsonDiffMatcher(body))
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          self.existing_workflow_uuid + '\n')
-
+        self.assertEqual(exited, 0)
 
     @stubs
     def test_create_collection_per_tool(self, stubs):
         project_uuid = 'zzzzz-j7d0g-zzzzzzzzzzzzzzz'
 
-        capture_stdout = cStringIO.StringIO()
-
         exited = arvados_cwl.main(
             ["--create-workflow", "--debug",
              "--api=containers",
              "--project-uuid", project_uuid,
              "tests/collection_per_tool/collection_per_tool.cwl"],
-            capture_stdout, sys.stderr, api_client=stubs.api)
-        self.assertEqual(exited, 0)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
 
         toolfile = "tests/collection_per_tool/collection_per_tool_packed.cwl"
         expect_workflow = StripYAMLComments(open(toolfile).read())
@@ -1828,8 +1695,9 @@ class TestCreateWorkflow(unittest.TestCase):
         stubs.api.workflows().create.assert_called_with(
             body=JsonDiffMatcher(body))
 
-        self.assertEqual(capture_stdout.getvalue(),
+        self.assertEqual(stubs.capture_stdout.getvalue(),
                          stubs.expect_workflow_uuid + '\n')
+        self.assertEqual(exited, 0)
 
 class TestTemplateInputs(unittest.TestCase):
     expect_template = {
@@ -1884,19 +1752,19 @@ class TestTemplateInputs(unittest.TestCase):
         exited = arvados_cwl.main(
             ["--create-template",
              "tests/wf/inputs_test.cwl", "tests/order/empty_order.json"],
-            cStringIO.StringIO(), sys.stderr, api_client=stubs.api)
-        self.assertEqual(exited, 0)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
 
         stubs.api.pipeline_templates().create.assert_called_with(
             body=JsonDiffMatcher(self.expect_template), ensure_unique_name=True)
 
+        self.assertEqual(exited, 0)
+
     @stubs
     def test_inputs(self, stubs):
         exited = arvados_cwl.main(
             ["--create-template",
              "tests/wf/inputs_test.cwl", "tests/order/inputs_test_order.json"],
-            cStringIO.StringIO(), sys.stderr, api_client=stubs.api)
-        self.assertEqual(exited, 0)
+            stubs.capture_stdout, sys.stderr, api_client=stubs.api)
 
         expect_template = copy.deepcopy(self.expect_template)
         params = expect_template[
@@ -1908,3 +1776,4 @@ class TestTemplateInputs(unittest.TestCase):
 
         stubs.api.pipeline_templates().create.assert_called_with(
             body=JsonDiffMatcher(expect_template), ensure_unique_name=True)
+        self.assertEqual(exited, 0)
index 948f31d4f9815f3deadf595c1f5cbd3e1a464c29..86a053ea484835980c791d4a728824919d01f78f 100644 (file)
@@ -23,37 +23,37 @@ class TestUrljoin(unittest.TestCase):
 
         cf = CollectionFetcher({}, None)
 
-        self.assertEquals("keep:99999999999999999999999999999991+99/hw.py",
+        self.assertEqual("keep:99999999999999999999999999999991+99/hw.py",
                           cf.urljoin("keep:99999999999999999999999999999991+99", "hw.py"))
 
-        self.assertEquals("keep:99999999999999999999999999999991+99/hw.py",
+        self.assertEqual("keep:99999999999999999999999999999991+99/hw.py",
                           cf.urljoin("keep:99999999999999999999999999999991+99/", "hw.py"))
 
-        self.assertEquals("keep:99999999999999999999999999999991+99/hw.py#main",
+        self.assertEqual("keep:99999999999999999999999999999991+99/hw.py#main",
                           cf.urljoin("keep:99999999999999999999999999999991+99", "hw.py#main"))
 
-        self.assertEquals("keep:99999999999999999999999999999991+99/hw.py#main",
+        self.assertEqual("keep:99999999999999999999999999999991+99/hw.py#main",
                           cf.urljoin("keep:99999999999999999999999999999991+99/hw.py", "#main"))
 
-        self.assertEquals("keep:99999999999999999999999999999991+99/dir/hw.py#main",
+        self.assertEqual("keep:99999999999999999999999999999991+99/dir/hw.py#main",
                           cf.urljoin("keep:99999999999999999999999999999991+99/dir/hw.py", "#main"))
 
-        self.assertEquals("keep:99999999999999999999999999999991+99/dir/wh.py",
+        self.assertEqual("keep:99999999999999999999999999999991+99/dir/wh.py",
                           cf.urljoin("keep:99999999999999999999999999999991+99/dir/hw.py", "wh.py"))
 
-        self.assertEquals("keep:99999999999999999999999999999991+99/wh.py",
+        self.assertEqual("keep:99999999999999999999999999999991+99/wh.py",
                           cf.urljoin("keep:99999999999999999999999999999991+99/dir/hw.py", "/wh.py"))
 
-        self.assertEquals("keep:99999999999999999999999999999991+99/wh.py#main",
+        self.assertEqual("keep:99999999999999999999999999999991+99/wh.py#main",
                           cf.urljoin("keep:99999999999999999999999999999991+99/dir/hw.py", "/wh.py#main"))
 
-        self.assertEquals("keep:99999999999999999999999999999991+99/wh.py",
+        self.assertEqual("keep:99999999999999999999999999999991+99/wh.py",
                           cf.urljoin("keep:99999999999999999999999999999991+99/hw.py#main", "wh.py"))
 
-        self.assertEquals("keep:99999999999999999999999999999992+99",
+        self.assertEqual("keep:99999999999999999999999999999992+99",
                           cf.urljoin("keep:99999999999999999999999999999991+99", "keep:99999999999999999999999999999992+99"))
 
-        self.assertEquals("keep:99999999999999999999999999999991+99/dir/wh.py",
+        self.assertEqual("keep:99999999999999999999999999999991+99/dir/wh.py",
                           cf.urljoin("keep:99999999999999999999999999999991+99/dir/", "wh.py"))
 
     def test_resolver(self):
index 2532bd596c0f3dfac3554d3b5fe31ffb9d7e50d4..3ca02c7df65f023c32dab341224534f588d32e67 100644 (file)
@@ -2,6 +2,8 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from builtins import bytes
+
 import unittest
 import mock
 import datetime
@@ -39,7 +41,16 @@ class TestUtil(unittest.TestCase):
 
     def test_get_current_container_error(self):
         api = mock.MagicMock()
-        api.containers().current().execute.side_effect = ApiError(httplib2.Response({"status": 300}), "")
+        api.containers().current().execute.side_effect = ApiError(httplib2.Response({"status": 300}), bytes(b""))
+        logger = mock.MagicMock()
+
+        with self.assertRaises(ApiError):
+            get_current_container(api, num_retries=0, logger=logger)
+
+    def test_get_current_container_404_error(self):
+        api = mock.MagicMock()
+        api.containers().current().execute.side_effect = ApiError(httplib2.Response({"status": 404}), bytes(b""))
         logger = mock.MagicMock()
 
-        self.assertRaises(ApiError, get_current_container(api, num_retries=0, logger=logger))
+        current_container = get_current_container(api, num_retries=0, logger=logger)
+        self.assertEqual(current_container, None)
\ No newline at end of file
index 355872232bc7f430a8b61f7e8f8dffbe09cc5530..b4322a809320b7be5823296f6cb72a39d4273f24 100644 (file)
@@ -2,6 +2,9 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+from __future__ import print_function
+from __future__ import division
+
 import arvados
 import sys
 import os
@@ -9,7 +12,7 @@ import os
 if "JOB_UUID" in os.environ:
     requested = arvados.api().jobs().get(uuid=os.environ["JOB_UUID"]).execute()["runtime_constraints"]["min_ram_mb_per_node"]
 else:
-    requested = arvados.api().containers().current().execute()["runtime_constraints"]["ram"]/(1024*1024)
+    requested = arvados.api().containers().current().execute()["runtime_constraints"]["ram"] // (1024*1024)
 
 print("Requested %d expected %d" % (requested, int(sys.argv[1])))
 
index d33956ccc3f74caa7d6b64958b4c9863f09bbd70..f9e370794d4e90d87a12deb54167c1d700ba16f1 100644 (file)
@@ -18,9 +18,17 @@ MAINTAINER Ward Vandewege <ward@curoverse.com>
 
 ENV DEBIAN_FRONTEND noninteractive
 
-RUN apt-get update -q && apt-get install -qy git python-pip python-virtualenv python-dev libcurl4-gnutls-dev libgnutls28-dev nodejs python-pyasn1-modules
+ARG pythoncmd=python
 
-RUN pip install -U setuptools six requests
+RUN apt-get update -q && apt-get install -qy --no-install-recommends \
+    git ${pythoncmd}-pip ${pythoncmd}-virtualenv ${pythoncmd}-dev libcurl4-gnutls-dev \
+    libgnutls28-dev nodejs ${pythoncmd}-pyasn1-modules build-essential
+
+RUN if [ "$pythoncmd" = "python3" ]; then \
+       pip3 install -U setuptools six requests ; \
+    else \
+       pip install -U setuptools six requests ; \
+    fi
 
 ARG sdk
 ARG runner
@@ -32,10 +40,10 @@ ADD cwl/salad_dist/$salad /tmp/
 ADD cwl/cwltool_dist/$cwltool /tmp/
 ADD cwl/dist/$runner /tmp/
 
-RUN cd /tmp/arvados-python-client-* && python setup.py install
-RUN if test -d /tmp/schema-salad-* ; then cd /tmp/schema-salad-* && python setup.py install ; fi
-RUN if test -d /tmp/cwltool-* ; then cd /tmp/cwltool-* && python setup.py install ; fi
-RUN cd /tmp/arvados-cwl-runner-* && python setup.py install
+RUN cd /tmp/arvados-python-client-* && $pythoncmd setup.py install
+RUN if test -d /tmp/schema-salad-* ; then cd /tmp/schema-salad-* && $pythoncmd setup.py install ; fi
+RUN if test -d /tmp/cwltool-* ; then cd /tmp/cwltool-* && $pythoncmd setup.py install ; fi
+RUN cd /tmp/arvados-cwl-runner-* && $pythoncmd setup.py install
 
 # Install dependencies and set up system.
 RUN /usr/sbin/adduser --disabled-password \
index 6440bdfbd4795756ac6d059738b443e5e8b06d97..6c323f5a453086615051b78a5744e071d127f8fc 100644 (file)
@@ -4,7 +4,10 @@
 
 case "$TARGET" in
     debian* | ubuntu*)
-        fpm_depends+=('libpam-python')
+        fpm_depends+=('libpam-python' 'libcurl3-gnutls')
+        ;;
+    centos*)
+        fpm_depends+=('python-pam')
         ;;
     *)
         echo >&2 "ERROR: $PACKAGE: pam_python.so dependency unavailable in $TARGET."
index 2c0045d6a0d60d9bb71514d3eb2ab0b7a7d3336b..7c3406d30040228e9d5e9a333ee56e9459605eb2 100644 (file)
@@ -2,4 +2,6 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+import sys
+sys.path.append('/usr/share/python2.7/dist/libpam-arvados/lib/python2.7/site-packages')
 from arvados_pam import *
index 55fc6b626d5de9798b989d2b252d158ca89baab6..811f096c60808b2033c8123d5330909ee88db816 100644 (file)
@@ -133,6 +133,7 @@ def docker_images():
     next(list_output)  # Ignore the header line
     for line in list_output:
         words = line.split()
+        words = [word.decode() for word in words]
         size_index = len(words) - 2
         repo, tag, imageid = words[:3]
         ctime = ' '.join(words[3:size_index])
@@ -503,7 +504,7 @@ def main(arguments=None, stdout=sys.stdout, install_sig_handlers=True, api=None)
         else:
             json_filename = raw_image_hash + '/json'
         json_file = image_tar.extractfile(image_tar.getmember(json_filename))
-        image_metadata = json.load(json_file)
+        image_metadata = json.loads(json_file.read().decode())
         json_file.close()
         image_tar.close()
         link_base = {'head_uuid': coll_uuid, 'properties': {}}
similarity index 68%
rename from backports/deb-fuse/fpm-info.sh
rename to sdk/python/fpm-info.sh
index 46088c0c6dc88d77addda471e2617768f355a0cd..7a89cf03a0935c109bb7dbfa4af7d27968dcc84f 100644 (file)
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: Apache-2.0
 
 case "$TARGET" in
-    ubuntu1204)
-        fpm_depends+=('libfuse2 = 2.9.2-5')
+    debian* | ubuntu*)
+        fpm_depends+=(libcurl3-gnutls)
         ;;
 esac
index 9b38f07140049807947c8c3f3221966136a7a3d9..5c781b158350fa6d7d869b061b24d0cfd95dcae1 100644 (file)
@@ -56,6 +56,10 @@ setup(name='arvados-python-client',
           'ws4py >=0.4.2',
           'subprocess32 >=3.5.1',
       ],
+      classifiers=[
+          'Programming Language :: Python :: 2',
+          'Programming Language :: Python :: 3',
+      ],
       test_suite='tests',
       tests_require=['pbr<1.7.0', 'mock>=1.0', 'PyYAML'],
       zip_safe=False
diff --git a/services/dockercleaner/README.rst b/services/dockercleaner/README.rst
new file mode 100644 (file)
index 0000000..dd2b7e9
--- /dev/null
@@ -0,0 +1,5 @@
+.. Copyright (C) The Arvados Authors. All rights reserved.
+..
+.. SPDX-License-Identifier: Apache-2.0
+
+Arvados Docker Cleaner.
index 0221707cf410f7a0e417a42ccfda8afa27d5bf70..29697e440a3dfb5a76f3752b97185301248cdb70 100644 (file)
@@ -23,7 +23,7 @@ RestartPreventExitStatus=2
 # This unwieldy ExecStart command detects at runtime whether
 # arvados-docker-cleaner is installed with the Python 3.3 Software
 # Collection, and if so, invokes it with the "scl" wrapper.
-ExecStart=/bin/sh -c 'if [ -e /opt/rh/python33/root/bin/arvados-docker-cleaner ]; then exec scl enable python33 arvados-docker-cleaner; else exec arvados-docker-cleaner; fi'
+ExecStart=/bin/sh -c 'if [ -e /opt/rh/rh-python35/root/bin/arvados-docker-cleaner ]; then exec scl enable rh-python35 arvados-docker-cleaner; else exec arvados-docker-cleaner; fi'
 
 # systemd<=219 (centos:7, debian:8, ubuntu:trusty) obeys StartLimitInterval in the [Service] section
 StartLimitInterval=0
diff --git a/services/dockercleaner/bin/arvados-docker-cleaner b/services/dockercleaner/bin/arvados-docker-cleaner
new file mode 100755 (executable)
index 0000000..c00593f
--- /dev/null
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
+from __future__ import absolute_import, print_function
+
+from arvados_docker.cleaner import main
+main()
index 6cf69fb782ee5ce876fe9ae6a64a6c7dbce3239d..fd94ef7afa3340edea84a486e4abd03810fe1b8d 100644 (file)
@@ -3,3 +3,12 @@
 # SPDX-License-Identifier: AGPL-3.0
 
 fpm_depends+=(fuse)
+
+case "$TARGET" in
+    centos*)
+        fpm_depends+=(fuse-libs)
+        ;;
+    debian* | ubuntu*)
+        fpm_depends+=(libcurl3-gnutls libpython2.7)
+        ;;
+esac
diff --git a/services/nodemanager/fpm-info.sh b/services/nodemanager/fpm-info.sh
new file mode 100644 (file)
index 0000000..c4a9dbb
--- /dev/null
@@ -0,0 +1,9 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
+case "$TARGET" in
+    debian* | ubuntu*)
+        fpm_depends+=(libcurl3-gnutls libpython2.7)
+        ;;
+esac
index a258b8e2329eeb2aa1c6b6707678e89d750849df..66aebf80d4236d6b575a178641bd5eae8c14a1bc 100755 (executable)
@@ -361,7 +361,12 @@ case "$subcmd" in
         ;;
 
     sh*)
-        exec docker exec -ti -e LINES=$(tput lines) -e COLUMNS=$(tput cols) -e TERM=$TERM -e GEM_HOME=/var/lib/gems $ARVBOX_CONTAINER /bin/bash
+        exec docker exec -ti \
+              -e LINES=$(tput lines) \
+              -e COLUMNS=$(tput cols) \
+              -e TERM=$TERM \
+              -e GEM_HOME=/var/lib/gems \
+              $ARVBOX_CONTAINER /bin/bash
         ;;
 
     pipe)
index 1c1ad17814b5e4b8f12ce51450afee5dcf8da42a..162edc927fe04a566422a53aca7735ee1bd31096 100644 (file)
@@ -19,7 +19,8 @@ RUN apt-get update && \
     apt-transport-https ca-certificates slurm-wlm \
     linkchecker python3-virtualenv python-virtualenv xvfb iceweasel \
     libgnutls28-dev python3-dev vim cadaver cython gnupg dirmngr \
-    libsecret-1-dev r-base r-cran-testthat libxml2-dev pandoc && \
+    libsecret-1-dev r-base r-cran-testthat libxml2-dev pandoc \
+    python3-setuptools python3-pip && \
     apt-get clean
 
 ENV RUBYVERSION_MINOR 2.3
index 56d0fa01351c20e02039ca0d801dcf3e8ca10cbd..bbd11f03416a9783904a48cb6823136ceb5c0686 100644 (file)
@@ -66,6 +66,7 @@ run_bundler() {
     fi
 }
 
+PYCMD=""
 pip_install() {
     pushd /var/lib/pip
     for p in $(ls http*.tar.gz) $(ls http*.tar.bz2) $(ls http*.whl) $(ls http*.zip) ; do
@@ -75,7 +76,13 @@ pip_install() {
     done
     popd
 
-    if ! pip install --no-index --find-links /var/lib/pip $1 ; then
-        pip install $1
+    if [ "$PYCMD" = "python3" ]; then
+       if ! pip3 install --no-index --find-links /var/lib/pip $1 ; then
+            pip3 install $1
+       fi
+    else
+       if ! pip install --no-index --find-links /var/lib/pip $1 ; then
+            pip install $1
+       fi
     fi
 }
index 2b802f2ab09c0be2b4aa43c934970f0e6706dd92..1b062ad8d131c141dd55a18bf0a474a6991a0186 100755 (executable)
@@ -37,6 +37,13 @@ if test ! -s /var/lib/arvados/root-cert.pem ; then
 fi
 
 if test ! -s /var/lib/arvados/server-cert-${localip}.pem ; then
+
+    if [[ $localip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
+       san=IP:$localip
+    else
+       san=DNS:$localip
+    fi
+
     # req           signing request sub-command
     # -new          new certificate request
     # -nodes        "no des" don't encrypt key
@@ -56,7 +63,7 @@ if test ! -s /var/lib/arvados/server-cert-${localip}.pem ; then
            -reqexts x509_ext \
            -extensions x509_ext \
            -config <(cat /etc/ssl/openssl.cnf \
-                         <(printf "\n[x509_ext]\nkeyUsage=critical,digitalSignature,keyEncipherment\nsubjectAltName=DNS:localhost,IP:$localip")) \
+                         <(printf "\n[x509_ext]\nkeyUsage=critical,digitalSignature,keyEncipherment\nsubjectAltName=DNS:localhost,$san")) \
             -out /var/lib/arvados/server-cert-${localip}.csr \
             -keyout /var/lib/arvados/server-cert-${localip}.key \
             -days 365
@@ -69,7 +76,7 @@ if test ! -s /var/lib/arvados/server-cert-${localip}.pem ; then
            -out /var/lib/arvados/server-cert-${localip}.pem \
            -set_serial $RANDOM$RANDOM \
            -extfile <(cat /etc/ssl/openssl.cnf \
-                         <(printf "\n[x509_ext]\nkeyUsage=critical,digitalSignature,keyEncipherment\nsubjectAltName=DNS:localhost,IP:$localip")) \
+                         <(printf "\n[x509_ext]\nkeyUsage=critical,digitalSignature,keyEncipherment\nsubjectAltName=DNS:localhost,$san")) \
            -extensions x509_ext
 
     chown arvbox:arvbox /var/lib/arvados/server-cert-${localip}.*
@@ -78,4 +85,4 @@ fi
 cp /var/lib/arvados/root-cert.pem /usr/local/share/ca-certificates/arvados-testing-cert.crt
 update-ca-certificates
 
-sv stop certificate
\ No newline at end of file
+sv stop certificate
diff --git a/tools/crunchstat-summary/README.rst b/tools/crunchstat-summary/README.rst
new file mode 100644 (file)
index 0000000..fa8e1bd
--- /dev/null
@@ -0,0 +1,5 @@
+.. Copyright (C) The Arvados Authors. All rights reserved.
+..
+.. SPDX-License-Identifier: Apache-2.0
+
+Arvados Crunchstat Summary.
diff --git a/tools/crunchstat-summary/fpm-info.sh b/tools/crunchstat-summary/fpm-info.sh
new file mode 100644 (file)
index 0000000..0abc6a0
--- /dev/null
@@ -0,0 +1,9 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
+case "$TARGET" in
+    debian* | ubuntu*)
+        fpm_depends+=(libcurl3-gnutls)
+        ;;
+esac
index 04adba8494e20e5151b972ac7b7a3f547e09dd44..642428181c685858fa1b6ee4d4861c6836e3e211 100755 (executable)
@@ -23,7 +23,7 @@ if '--short-tests-only' in sys.argv:
 
 setup(name='crunchstat_summary',
       version=version,
-      description='read crunch log files and summarize resource usage',
+      description='Arvados crunchstat-summary reads crunch log files and summarizes resource usage',
       author='Arvados',
       author_email='info@arvados.org',
       url="https://arvados.org",