Merge branch '17813-docker-to-singularity' into main
authorTom Clegg <tom@curii.com>
Mon, 26 Jul 2021 20:02:31 +0000 (16:02 -0400)
committerTom Clegg <tom@curii.com>
Mon, 26 Jul 2021 20:02:31 +0000 (16:02 -0400)
refs #17813

Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom@curii.com>

37 files changed:
build/package-build-dockerfiles/centos7/Dockerfile
build/package-build-dockerfiles/debian10/Dockerfile
build/package-build-dockerfiles/ubuntu1604/Dockerfile
build/package-build-dockerfiles/ubuntu1804/Dockerfile
build/package-build-dockerfiles/ubuntu2004/Dockerfile
build/package-test-dockerfiles/centos7/Dockerfile
build/package-test-dockerfiles/debian10/Dockerfile
build/package-test-dockerfiles/ubuntu1604/Dockerfile
build/package-test-dockerfiles/ubuntu1804/Dockerfile
build/package-test-dockerfiles/ubuntu2004/Dockerfile
build/rails-package-scripts/arvados-api-server.sh
build/rails-package-scripts/postinst.sh
build/run-build-packages.sh
build/run-tests.sh
doc/_includes/_create_superuser_token.liquid
doc/_includes/_install_rails_command.liquid
doc/admin/config-migration.html.textile.liquid
doc/admin/restricting-upload-download.html.textile.liquid
doc/admin/token-expiration-policy.html.textile.liquid
doc/install/install-arv-git-httpd.html.textile.liquid
doc/install/install-keep-web.html.textile.liquid
doc/user/cwl/cwl-extensions.html.textile.liquid
doc/user/topics/arv-copy.html.textile.liquid
go.mod
go.sum
lib/boot/passenger.go
lib/boot/supervisor.go
lib/config/export.go
lib/controller/localdb/login_oidc.go
lib/controller/localdb/login_oidc_test.go
lib/install/deps.go
sdk/go/arvadostest/oidc_provider.go
sdk/python/arvados/commands/arv_copy.py
sdk/python/tests/test_arv_copy.py
tools/arvbox/lib/arvbox/docker/Dockerfile.demo
tools/arvbox/lib/arvbox/docker/service/crunch-dispatch-local/run
tools/arvbox/lib/arvbox/docker/service/crunch-dispatch-local/run-service [new file with mode: 0755]

index b2d32b6761a78231955bb14d1b691dfbccc0d79a..332a8dc83003d4512da61e27613b6f2121eaa426 100644 (file)
@@ -16,7 +16,7 @@ RUN gpg --import --no-tty /tmp/mpapis.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.5 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.5 && \
-    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.0.2 && \
+    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19 && \
     /usr/local/rvm/bin/rvm-exec default gem install fpm --version 1.10.2
 
 # Install Bash 4.4.12 // see https://dev.arvados.org/issues/15612
index 90833f011d3d1029d2e89221beb966a51757cde4..ad8198fa0db0461fefcf49aca0c7aff9b77db734 100644 (file)
@@ -22,7 +22,7 @@ RUN gpg --import --no-tty /tmp/mpapis.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.5 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.5 && \
-    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.0.2 && \
+    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19 && \
     /usr/local/rvm/bin/rvm-exec default gem install fpm --version 1.10.2
 
 # Install golang binary
index 880576f2bf480f4bbde7eb925fd6643dab5158af..77df54dcbd11f45c31f062a0ee8bc10619bfc824 100644 (file)
@@ -21,7 +21,7 @@ RUN gpg --import --no-tty /tmp/mpapis.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.5 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.5 && \
-    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.0.2 && \
+    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19 && \
     /usr/local/rvm/bin/rvm-exec default gem install fpm --version 1.10.2
 
 # Install golang binary
index fd18f3e202a81ecf29a29335221c8b84d1b40dc4..65c477a91684feaa19acb940b816013377848190 100644 (file)
@@ -21,7 +21,7 @@ RUN gpg --import --no-tty /tmp/mpapis.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.5 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.5 && \
-    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.0.2 && \
+    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19 && \
     /usr/local/rvm/bin/rvm-exec default gem install fpm --version 1.10.2
 
 # Install golang binary
index 0e11b8738e1f9a6a4d8e825f1a6a8a2ccfee8437..ba6c57df3880797e22218893ab1e42d6660227c4 100644 (file)
@@ -21,7 +21,7 @@ RUN gpg --import --no-tty /tmp/mpapis.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.5 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.5 && \
-    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.0.2 && \
+    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19 && \
     /usr/local/rvm/bin/rvm-exec default gem install fpm --version 1.10.2
 
 # Install golang binary
index eebeac0c83b993c4cbd61f5e0453849586f4e1e1..f83941824e2e05c192f042ac3bb2cd4347762120 100644 (file)
@@ -17,7 +17,7 @@ RUN touch /var/lib/rpm/* && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.5 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.5 && \
-    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.0.2
+    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.9
 
 # Install Bash 4.4.12  // see https://dev.arvados.org/issues/15612
 RUN cd /usr/local/src \
index 32996e4a54eb395252730198d87d49f08eb78b70..3f9393ee55e592f3deb93bc2a2cf15c6881d245d 100644 (file)
@@ -19,7 +19,7 @@ RUN gpg --import --no-tty /tmp/mpapis.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.5 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.5 && \
-    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.0.2
+    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19
 
 # udev daemon can't start in a container, so don't try.
 RUN mkdir -p /etc/udev/disabled
index e0432c20eed471f728bc69b320dbb57849df0b16..0b03e412a120f22bcf999a8aa17ad077e01e4a5c 100644 (file)
@@ -19,7 +19,7 @@ RUN gpg --import --no-tty /tmp/mpapis.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.5 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.5 && \
-    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.0.2
+    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19
 
 # udev daemon can't start in a container, so don't try.
 RUN mkdir -p /etc/udev/disabled
index 2d4189879ec6c86ec38e7f80d49b1a15569c65f3..7347f32c8fe7c5afa36c903dff25671f8c2650c2 100644 (file)
@@ -19,7 +19,7 @@ RUN gpg --import --no-tty /tmp/mpapis.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.5 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.5 && \
-    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.0.2
+    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19
 
 # udev daemon can't start in a container, so don't try.
 RUN mkdir -p /etc/udev/disabled
index 0a3bda8f147654e7c07e2737deec30fd0bc5142e..061c8848ee39e9f6a409a7d25e4fc1333cb79bfe 100644 (file)
@@ -19,7 +19,7 @@ RUN gpg --import --no-tty /tmp/mpapis.asc && \
     curl -L https://get.rvm.io | bash -s stable && \
     /usr/local/rvm/bin/rvm install 2.5 && \
     /usr/local/rvm/bin/rvm alias create default ruby-2.5 && \
-    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.0.2
+    /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19
 
 # udev daemon can't start in a container, so don't try.
 RUN mkdir -p /etc/udev/disabled
index 027383ab4f62294aa9661b5e9ce1651457f3bf1a..a513c3ad09f885dc18c7187822418d77e535e201 100644 (file)
@@ -21,7 +21,7 @@ setup_before_nginx_restart() {
   # initialize git_internal_dir
   # usually /var/lib/arvados/internal.git (set in application.default.yml )
   if [ "$APPLICATION_READY" = "1" ]; then
-      GIT_INTERNAL_DIR=$($COMMAND_PREFIX bundle exec rake config:dump 2>&1 | grep GitInternalDir | awk '{ print $2 }' |tr -d '"')
+      GIT_INTERNAL_DIR=$($COMMAND_PREFIX bin/rake config:dump 2>&1 | grep GitInternalDir | awk '{ print $2 }' |tr -d '"')
       if [ ! -e "$GIT_INTERNAL_DIR" ]; then
         run_and_report "Creating git_internal_dir '$GIT_INTERNAL_DIR'" \
           mkdir -p "$GIT_INTERNAL_DIR"
index bcd7a27c85125c729fb304ef7a2e70d105950044..f6ae48c0fc4e9373be9d3756698016f28f64493d 100644 (file)
@@ -125,17 +125,17 @@ setup_conffile() {
 }
 
 prepare_database() {
-  DB_MIGRATE_STATUS=`$COMMAND_PREFIX bundle exec rake db:migrate:status 2>&1 || true`
+  DB_MIGRATE_STATUS=`$COMMAND_PREFIX bin/rake db:migrate:status 2>&1 || true`
   if echo "$DB_MIGRATE_STATUS" | grep -qF 'Schema migrations table does not exist yet.'; then
       # The database exists, but the migrations table doesn't.
-      run_and_report "Setting up database" $COMMAND_PREFIX bundle exec \
-                     rake "$RAILSPKG_DATABASE_LOAD_TASK" db:seed
+      run_and_report "Setting up database" $COMMAND_PREFIX bin/rake \
+                     "$RAILSPKG_DATABASE_LOAD_TASK" db:seed
   elif echo "$DB_MIGRATE_STATUS" | grep -q '^database: '; then
       run_and_report "Running db:migrate" \
-                     $COMMAND_PREFIX bundle exec rake db:migrate
+                     $COMMAND_PREFIX bin/rake db:migrate
   elif echo "$DB_MIGRATE_STATUS" | grep -q 'database .* does not exist'; then
       if ! run_and_report "Running db:setup" \
-           $COMMAND_PREFIX bundle exec rake db:setup 2>/dev/null; then
+           $COMMAND_PREFIX bin/rake db:setup 2>/dev/null; then
           echo "Warning: unable to set up database." >&2
           DATABASE_READY=0
       fi
@@ -198,12 +198,15 @@ configure_version() {
   cd "$RELEASE_PATH"
   export RAILS_ENV=production
 
-  if ! $COMMAND_PREFIX bundle --version >/dev/null; then
-      run_and_report "Installing bundler" $COMMAND_PREFIX gem install bundler --version 1.17.3
+  if ! $COMMAND_PREFIX bundle --version >/dev/null 2>&1; then
+      run_and_report "Installing bundler" $COMMAND_PREFIX gem install bundler --version 2.2.19 --no-document
   fi
 
+  run_and_report "Running bundle config set --local path $SHARED_PATH/vendor_bundle" \
+      $COMMAND_PREFIX bin/bundle config set --local path $SHARED_PATH/vendor_bundle
+
   run_and_report "Running bundle install" \
-      $COMMAND_PREFIX bundle install --path $SHARED_PATH/vendor_bundle --local --quiet
+      $COMMAND_PREFIX bin/bundle install --local --quiet
 
   echo -n "Ensuring directory and file permissions ..."
   # Ensure correct ownership of a few files
@@ -230,7 +233,7 @@ configure_version() {
       # warn about config errors (deprecated/removed keys from
       # previous version, etc)
       run_and_report "Checking configuration for completeness" \
-                     $COMMAND_PREFIX bundle exec rake config:check || APPLICATION_READY=0
+                     $COMMAND_PREFIX bin/rake config:check || APPLICATION_READY=0
   else
       APPLICATION_READY=0
   fi
index e231a83df8d22e291a7d048bc8fa3d00c136a109..d46c246da7c9fadb0fe96fbe7edce0f4c623c351 100755 (executable)
@@ -401,8 +401,8 @@ if [[ "$?" == "0" ]] ; then
       mv /tmp/x /etc/arvados/config.yml
       perl -p -i -e 'BEGIN{undef $/;} s/WebDAV(.*?):\n( *)ExternalURL: ""/WebDAV$1:\n$2ExternalURL: "example.com"/g' /etc/arvados/config.yml
 
-      ARVADOS_CONFIG=none RAILS_ENV=production RAILS_GROUPS=assets bundle exec rake npm:install >"$STDOUT_IF_DEBUG"
-      ARVADOS_CONFIG=none RAILS_ENV=production RAILS_GROUPS=assets bundle exec rake assets:precompile >"$STDOUT_IF_DEBUG"
+      ARVADOS_CONFIG=none RAILS_ENV=production RAILS_GROUPS=assets bin/rake npm:install >"$STDOUT_IF_DEBUG"
+      ARVADOS_CONFIG=none RAILS_ENV=production RAILS_GROUPS=assets bin/rake assets:precompile >"$STDOUT_IF_DEBUG"
 
       # Remove generated configuration files so they don't go in the package.
       rm -rf /etc/arvados/
index e309d24011d4f01079ae7707c2e6b1f0bbd45832..71da30ce43be5bc0b9e53fc2598fdc9face4e8c7 100755 (executable)
@@ -517,10 +517,10 @@ setup_ruby_environment() {
             || fatal 'rvm gemset setup'
 
         rvm env
-        (bundle version | grep -q 2.0.2) || gem install bundler -v 2.0.2
+        (bundle version | grep -q 2.2.19) || gem install bundler -v 2.2.19
         bundle="$(which bundle)"
         echo "$bundle"
-        "$bundle" version | grep 2.0.2 || fatal 'install bundler'
+        "$bundle" version | grep 2.2.19 || fatal 'install bundler'
     else
         # When our "bundle install"s need to install new gems to
         # satisfy dependencies, we want them to go where "gem install
@@ -550,7 +550,7 @@ setup_ruby_environment() {
         (
             export HOME=$GEMHOME
             bundlers="$(gem list --details bundler)"
-            versions=(1.16.6 1.17.3 2.0.2)
+            versions=(2.2.19)
             for v in ${versions[@]}; do
                 if ! echo "$bundlers" | fgrep -q "($v)"; then
                     gem install --user $(for v in ${versions[@]}; do echo bundler:${v}; done)
index 07d8a4ae40ac7e0caabed2713bda5fb7a139379f..ed085ea105b5fa48009200b59f1bdfd553cf63b4 100644 (file)
@@ -8,7 +8,7 @@ On the <strong>API server</strong>, use the following commands:
 
 <notextile>
 <pre><code>~$ <span class="userinput">cd /var/www/arvados-api/current</span>
-$ <span class="userinput">sudo -u <b>webserver-user</b> RAILS_ENV=production bundle exec script/create_superuser_token.rb</span>
+$ <span class="userinput">sudo -u <b>webserver-user</b> RAILS_ENV=production bin/bundle exec script/create_superuser_token.rb</span>
 zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
 </code></pre>
 </notextile>
index 10c17a0c2d4bdbe703b3cf91d7ea434ca5e1e4e5..b648e92161e63ea485f0585242caf7947da3bb78 100644 (file)
@@ -8,7 +8,7 @@ SPDX-License-Identifier: CC-BY-SA-3.0
 This template recognizes four variables:
 * railshost: The hostname included in the prompt, to let the user know where to run the command.  If this is the empty string, no hostname will be displayed.  Default "apiserver".
 * railsdir: The directory included in the prompt, to let the user know where to run the command.  Default "/var/www/arvados-api/current".
-* railscmd: The full command to run.  Default "bundle exec rails console".
+* railscmd: The full command to run.  Default "bin/rails console".
 * railsout: The expected output of the command, if any.
 {% endcomment %} Change *@webserver-user@* to the user that runs your web server process.  If you install Phusion Passenger as we recommend, this is *@www-data@* on Debian-based systems, and *@nginx@* on Red Hat-based systems.
 
@@ -25,7 +25,7 @@ This template recognizes four variables:
 {% endunless %}
 
 {% unless railscmd %}
-  {% assign railscmd = "bundle exec rails console" %}
+  {% assign railscmd = "bin/rails console" %}
 {% endunless %}
 
 <notextile>
index a1f7872df4bff34e520d26c2f33680fdaec031a6..e36655a0f9eaecb4949f47334fa597225c5e57d5 100644 (file)
@@ -23,7 +23,7 @@ The legacy API server configuration is stored in @config/application.yml@ and @c
 Change to the API server directory and use the following commands:
 
 <pre>
-$ RAILS_ENV=production bundle exec rake config:migrate > config.yml
+$ RAILS_ENV=production bin/rake config:migrate > config.yml
 $ cp config.yml /etc/arvados/config.yml
 </pre>
 
@@ -32,7 +32,7 @@ This will print the contents of @config.yml@ after merging the legacy @applicati
 If you wish to update @config.yml@ configuration by hand, or check that everything has been migrated, use @config:diff@ to print configuration items that differ between @application.yml@ and the system @config.yml@.
 
 <pre>
-$ RAILS_ENV=production bundle exec rake config:diff
+$ RAILS_ENV=production bin/rake config:diff
 </pre>
 
 This command will also report if no migrations are required.
@@ -44,7 +44,7 @@ The legacy workbench configuration is stored in @config/application.yml@.  After
 Change to the workbench server directory and use the following commands:
 
 <pre>
-$ RAILS_ENV=production bundle exec rake config:migrate > config.yml
+$ RAILS_ENV=production bin/rake config:migrate > config.yml
 $ cp config.yml /etc/arvados/config.yml
 </pre>
 
@@ -53,7 +53,7 @@ This will print the contents of @config.yml@ after merging the legacy @applicati
 If you wish to update @config.yml@ configuration by hand, or check that everything has been migrated, use @config:diff@ to print configuration items that differ between @application.yml@ and the system @config.yml@.
 
 <pre>
-$ RAILS_ENV=production bundle exec rake config:diff
+$ RAILS_ENV=production bin/rake config:diff
 </pre>
 
 This command will also report if no migrations are required.
index ea10752342d69beb264f5d5a096adc5dc935aa9e..44a0467cf472f66afc4e0bf759be89894606bf94 100644 (file)
@@ -18,7 +18,7 @@ There are two services involved in accessing data from outside the cluster.
 
 h2. Keepproxy Permissions
 
-Permitting @keeproxy@ makes it possible to use @arv-put@ and @arv-get@, and upload from Workbench 1.  It works in terms of individual 64 MiB keep blocks.  It prints a log each time a user uploads or downloads an individual block.
+Permitting @keeproxy@ makes it possible to use @arv-put@ and @arv-get@, and upload from Workbench 1.  It works in terms of individual 64 MiB keep blocks.  It prints a log line each time a user uploads or downloads an individual block. Those logs are usually stored by @journald@ or @syslog@.
 
 The default policy allows anyone to upload or download.
 
@@ -33,8 +33,6 @@ The default policy allows anyone to upload or download.
           Upload: true
 </pre>
 
-If you create a sharing link as an admin user, and then give someone the token from the sharing link to download a file using @arv-get@, because the downloader is anonymous, the download permission will be restricted based on the "User" role and not the "Admin" role.
-
 h2. WebDAV and S3 API Permissions
 
 Permitting @WebDAV@ makes it possible to use WebDAV, S3 API, download from Workbench 1, and upload/download with Workbench 2.  It works in terms of individual files.  It prints a log each time a user uploads or downloads a file.  When @WebDAVLogEvents@ (default true) is enabled, it also adds an entry into the API server @logs@ table.
@@ -49,7 +47,7 @@ The default policy allows anyone to upload or download.
 
 <pre>
     Collections:
-      WebDAVPermisison:
+      WebDAVPermission:
         User:
           Download: true
           Upload: true
@@ -57,9 +55,11 @@ The default policy allows anyone to upload or download.
           Download: true
           Upload: true
       WebDAVLogEvents: true
-</pre>
+      </pre>
 
-If you create a sharing link as an admin user, and then give someone the token from the sharing link to download a file over HTTP (WebDAV or S3 API), because the downloader is anonymous, the download permission will be restricted based on the "User" role and not the "Admin" role.
+When a user or admin creates a sharing link, a custom scoped token is embedded in that link. This effectively allows anonymous user access to the associated data via that link. These custom scoped tokens are always treated as user tokens for the purposes of restricting download access, even when created by an admin user. In other words, these custom scoped tokens, when used in a sharing link, are always subject to the value of the @WebDAVPermission/User/Download@ configuration setting.
+
+If that custom scoped token is used with @arv-get@, its use will be subject to the value of the @KeepproxyPermission/User/Download@ configuration setting.
 
 h2. Shell node and container permissions
 
@@ -67,7 +67,7 @@ Be aware that even when upload and download from outside the network is not allo
 
 h2. Choosing a policy
 
-This distinction between WebDAV and Keepproxy is important for auditing.  WebDAV records 'upload' and 'download' events on the API server that are included in the "User Activity Report":user-activity.html ,  whereas @keepproxy@ only logs upload and download of individual blocks, which require a reverse lookup to determine the collection(s) and file(s) a block is associated with.
+This distinction between WebDAV and Keepproxy is important for auditing.  WebDAV records 'upload' and 'download' events on the API server that are included in the "User Activity Report":user-activity.html,  whereas @keepproxy@ only logs upload and download of individual blocks, which require a reverse lookup to determine the collection(s) and file(s) a block is associated with.
 
 You set separate permissions for @WebDAV@ and @Keepproxy@, with separate policies for regular users and admin users.
 
@@ -81,7 +81,7 @@ For ease of access auditing, this policy prevents downloads using @arv-get@.  Do
 
 <pre>
     Collections:
-      WebDAVPermisison:
+      WebDAVPermission:
         User:
           Download: true
           Upload: true
@@ -105,7 +105,7 @@ This policy prevents regular users (non-admin) from downloading data.  Uploading
 
 <pre>
     Collections:
-      WebDAVPermisison:
+      WebDAVPermission:
         User:
           Download: false
           Upload: true
@@ -129,7 +129,7 @@ This policy is suitable for an installation where data is being shared with a gr
 
 <pre>
     Collections:
-      WebDAVPermisison:
+      WebDAVPermission:
         User:
           Download: true
           Upload: false
@@ -146,3 +146,24 @@ This policy is suitable for an installation where data is being shared with a gr
           Upload: true
       WebDAVLogEvents: true
 </pre>
+
+
+h2. Accessing the audit log
+
+When @WebDAVLogEvents@ is enabled, uploads and downloads of files are logged in the Arvados audit log. These events are included in the "User Activity Report":user-activity.html. The audit log can also be accessed via the API, SDKs or command line. For example, to show the 100 most recent file downloads:
+
+<pre>
+arv log list --filters '[["event_type","=","file_download"]]' -o 'created_at desc' -l 100
+</pre>
+
+For uploads, use the @file_upload@ event type.
+
+Note that this only covers upload and download activity via WebDAV, S3, Workbench 1 (download only) and Workbench 2.
+
+File upload in Workbench 1 and the @arv-get@ and @arv-put@ tools use @Keepproxy@, which does not log activity to the audit log because it operates at the block level, not the file level. @Keepproxy@ records the uuid of the user that owns the token used in the request in its system logs. Those logs are usually stored by @journald@ or @syslog@. A typical log line for such a block download looks like this:
+
+<pre>
+Jul 20 15:03:38 workbench.xxxx1.arvadosapi.com keepproxy[63828]: {"level":"info","locator":"abcdefghijklmnopqrstuvwxyz012345+53251584","msg":"Block download","time":"2021-07-20T15:03:38.458792300Z","user_full_name":"Albert User","user_uuid":"ce8i5-tpzed-abcdefghijklmno"}
+</pre>
+
+It is possible to do a reverse lookup from the locator to find all matching collections: the @manifest_text@ field of a collection lists all the block locators that are part of the collection. The @manifest_text@ field also provides the relevant filename in the collection. Because this lookup is rather involved and there is no automated tool to do it, we recommend disabling @KeepproxyPermission/User/Download@ and @KeepproxyPermission/User/Upload@ for sites where the audit log is important and @arv-get@ and @arv-put@ are not essential.
index c71d86c47f234b6cd3db8b2580faabcc46eb6a0c..5efbccbc19a0c4289643ba98632c24fda8b6f985 100644 (file)
@@ -113,7 +113,7 @@ If you have an existing Arvados installation and want to set a token lifetime po
 The @db:check_long_lived_tokens@ task will list which users have tokens with no expiration date.
 
 <notextile>
-<pre><code># <span class="userinput">bundle exec rake db:check_long_lived_tokens</span>
+<pre><code># <span class="userinput">bin/rake db:check_long_lived_tokens</span>
 Found 6 long-lived tokens from users:
 user2,user2@example.com,zzzzz-tpzed-5vzt5wc62k46p6r
 admin,admin@example.com,zzzzz-tpzed-6drplgwq9nm5cox
@@ -124,7 +124,7 @@ user1,user1@example.com,zzzzz-tpzed-ftz2tfurbpf7xox
 To apply the new policy to existing tokens, use the @db:fix_long_lived_tokens@ task.
 
 <notextile>
-<pre><code># <span class="userinput">bundle exec rake db:fix_long_lived_tokens</span>
+<pre><code># <span class="userinput">bin/rake db:fix_long_lived_tokens</span>
 Setting token expiration to: 2020-08-25 03:30:50 +0000
 6 tokens updated.
 </code></pre>
index 3d70fc4de9497e8bb20b48cec6ecdfa8f62ef2ca..b7589032561cb03046bd597bd973506a665278d9 100644 (file)
@@ -183,7 +183,7 @@ $ sudo chmod og-rwx /var/www/arvados-api/current/config/arvados-clients.yml
 
 h3. Test configuration
 
-notextile. <pre><code>$ <span class="userinput">sudo -u git -i bash -c 'cd /var/www/arvados-api/current && bundle exec script/arvados-git-sync.rb production'</span></code></pre>
+notextile. <pre><code>$ <span class="userinput">sudo -u git -i bash -c 'cd /var/www/arvados-api/current && bin/bundle exec script/arvados-git-sync.rb production'</span></code></pre>
 
 h3. Enable the synchronization script
 
@@ -192,7 +192,7 @@ The API server package includes a script that retrieves the current set of repos
 Create @/etc/cron.d/arvados-git-sync@ with the following content:
 
 <notextile>
-<pre><code><span class="userinput">*/5 * * * * git cd /var/www/arvados-api/current && bundle exec script/arvados-git-sync.rb production</span>
+<pre><code><span class="userinput">*/5 * * * * git cd /var/www/arvados-api/current && bin/bundle exec script/arvados-git-sync.rb production</span>
 </code></pre>
 </notextile>
 
index 033efe63f1b76786e058ab9adf385f406adbd31b..5ff9f44194fa5996f90de4ab75ebfb55a542dc6f 100644 (file)
@@ -105,7 +105,7 @@ h2. Set InternalURLs
 
 h2(#update-config). Configure anonymous user token
 
-{% assign railscmd = "bundle exec ./script/get_anonymous_user_token.rb --get" %}
+{% assign railscmd = "bin/bundle exec ./script/get_anonymous_user_token.rb --get" %}
 {% assign railsout = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" %}
 If you intend to use Keep-web to serve public data to anonymous clients, configure it with an anonymous token.
 
index 09a553becfbff4d65ecbc9c82467b2cf557c8640..0987218e3c0f7a84aff9316614e2c964bc70a561 100644 (file)
@@ -89,7 +89,7 @@ Specify desired handling of intermediate output collections.
 table(table table-bordered table-condensed).
 |_. Field |_. Type |_. Description |
 |outputTTL|int|If the value is greater than zero, consider intermediate output collections to be temporary and should be automatically trashed. Temporary collections will be trashed @outputTTL@ seconds after creation.  A value of zero means intermediate output should be retained indefinitely (this is the default behavior).
-Note: arvados-cwl-runner currently does not take workflow dependencies into account when setting the TTL on an intermediate output collection. If the TTL is too short, it is possible for a collection to be trashed before downstream steps that consume it are started.  The recommended minimum value for TTL is the expected duration of the entire the workflow.|
+Note: arvados-cwl-runner currently does not take workflow dependencies into account when setting the TTL on an intermediate output collection. If the TTL is too short, it is possible for a collection to be trashed before downstream steps that consume it are started.  The recommended minimum value for TTL is the expected duration of the entire workflow.|
 
 h2. cwltool:Secrets
 
index d35df4fcec9f92f12e2b9dc3020667be5f4153f0..6e41a4f237d0bcf7d133007c96c742a2c7fb75d9 100644 (file)
@@ -57,12 +57,14 @@ arvados.arv-copy[1234] INFO: Success: created copy with uuid dstcl-4zz18-xxxxxxx
 
 The output of arv-copy displays the uuid of the collection generated in the destination cluster. By default, the output is placed in your home project in the destination cluster. If you want to place your collection in an existing project, you can specify the project you want it to be in using the tag @--project-uuid@ followed by the project uuid.
 
-For example, this will copy the collection to project dstcl-j7d0g-a894213ukjhal12 in the destination cluster.
+For example, this will copy the collection to project @dstcl-j7d0g-a894213ukjhal12@ in the destination cluster.
 
 <notextile> <pre><code>~$ <span class="userinput">arv-copy --src pirca --dst dstcl --project-uuid dstcl-j7d0g-a894213ukjhal12 jutro-4zz18-tv416l321i4r01e
 </code></pre>
 </notextile>
 
+Additionally, if you need to specify the storage classes where to save the copied data on the destination cluster, you can do that by using the @--storage-classes LIST@ argument, where @LIST@ is a comma-separated list of storage class names.
+
 h3. How to copy a workflow
 
 We will use the uuid @jutro-7fd4e-mkmmq53m1ze6apx@ as an example workflow.
diff --git a/go.mod b/go.mod
index b70f6f3b476789f69f1845bffb6bfd4fcac80885..adca449b7143ff3b01d2e3a9e037eac2114320a8 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -44,7 +44,7 @@ require (
        github.com/johannesboyne/gofakes3 v0.0.0-20200716060623-6b2b4cb092cc
        github.com/julienschmidt/httprouter v1.2.0
        github.com/kevinburke/ssh_config v0.0.0-20171013211458-802051befeb5 // indirect
-       github.com/lib/pq v1.3.0
+       github.com/lib/pq v1.10.2
        github.com/msteinert/pam v0.0.0-20190215180659-f29b9f28d6f9
        github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
        github.com/opencontainers/image-spec v1.0.1-0.20171125024018-577479e4dc27 // indirect
@@ -62,8 +62,6 @@ require (
        golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4
        golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
        golang.org/x/sys v0.0.0-20210603125802-9665404d3644
-       golang.org/x/tools v0.1.0 // indirect
-       golang.org/x/sys v0.0.0-20210510120138-977fb7262007
        golang.org/x/tools v0.1.2 // indirect
        google.golang.org/api v0.13.0
        gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
diff --git a/go.sum b/go.sum
index 1fd37ed11ce411e625518eb3189c225e80b74616..2f575eae919cf129009ad887c5e91ada2448edcb 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -179,6 +179,8 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB
 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
 github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
+github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4=
 github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
@@ -316,11 +318,11 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k=
 golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5oFh1lOjihRcEDROi0I=
-golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
 golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5oFh1lOjihRcEDROi0I=
+golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
index d77a4d76e7e101f828a8695e8ead5b2f8685ed14..f0cd02946f376719c4ab8907d01d5533903a24d4 100644 (file)
@@ -54,9 +54,9 @@ func (runner installPassenger) Run(ctx context.Context, fail func(error), super
        if err != nil {
                return err
        }
-       for _, version := range []string{"1.16.6", "1.17.3", "2.0.2"} {
+       for _, version := range []string{"2.2.19"} {
                if !strings.Contains(buf.String(), "("+version+")") {
-                       err = super.RunProgram(ctx, runner.src, runOptions{}, "gem", "install", "--user", "--conservative", "--no-document", "bundler:1.16.6", "bundler:1.17.3", "bundler:2.0.2")
+                       err = super.RunProgram(ctx, runner.src, runOptions{}, "gem", "install", "--user", "--conservative", "--no-document", "bundler:2.2.19")
                        if err != nil {
                                return err
                        }
index 0f497a443befbbb7b7942fcd69f1bb7bb0ac9dec..4e009f45ab55ad6353944bbea5cb7ca5b09811ac 100644 (file)
@@ -741,6 +741,11 @@ func (super *Supervisor) autofillConfig(cfg *arvados.Config) error {
                                AccessViaHosts: map[arvados.URL]arvados.VolumeAccess{
                                        url: {},
                                },
+                               StorageClasses: map[string]bool{
+                                       "default": true,
+                                       "foo":     true,
+                                       "bar":     true,
+                               },
                        }
                }
        }
index 8753b52f27e17dee80958fd32ab25e46cda2f9fb..bb939321c9ce17e220bb031f041efae53c79fa46 100644 (file)
@@ -232,7 +232,7 @@ var whitelist = map[string]bool{
        "Volumes.*.ReadOnly":                                  true,
        "Volumes.*.Replication":                               true,
        "Volumes.*.StorageClasses":                            true,
-       "Volumes.*.StorageClasses.*":                          false,
+       "Volumes.*.StorageClasses.*":                          true,
        "Workbench":                                           true,
        "Workbench.ActivationContactLink":                     false,
        "Workbench.APIClientConnectTimeout":                   true,
index 61dc5c816b35661f39c4a800ab17f1bf55325f06..6182469ac378d58b1e1f864bf4d98a6b48a022fb 100644 (file)
@@ -177,12 +177,19 @@ func (ctrl *oidcLoginController) getAuthInfo(ctx context.Context, token *oauth2.
        } else if verified, _ := claims[ctrl.EmailVerifiedClaim].(bool); verified || ctrl.EmailVerifiedClaim == "" {
                // Fall back to this info if the People API call
                // (below) doesn't return a primary && verified email.
-               name, _ := claims["name"].(string)
-               if names := strings.Fields(strings.TrimSpace(name)); len(names) > 1 {
-                       ret.FirstName = strings.Join(names[0:len(names)-1], " ")
-                       ret.LastName = names[len(names)-1]
-               } else if len(names) > 0 {
-                       ret.FirstName = names[0]
+               givenName, _ := claims["given_name"].(string)
+               familyName, _ := claims["family_name"].(string)
+               if givenName != "" && familyName != "" {
+                       ret.FirstName = givenName
+                       ret.LastName = familyName
+               } else {
+                       name, _ := claims["name"].(string)
+                       if names := strings.Fields(strings.TrimSpace(name)); len(names) > 1 {
+                               ret.FirstName = strings.Join(names[0:len(names)-1], " ")
+                               ret.LastName = names[len(names)-1]
+                       } else if len(names) > 0 {
+                               ret.FirstName = names[0]
+                       }
                }
                ret.Email, _ = claims[ctrl.EmailClaim].(string)
        }
index 4be7d58f699c455ee67e31a206bcebfc889ed0ad..4778e45f5fe48f3a8edeb7e9afa295524d7af5e4 100644 (file)
@@ -56,6 +56,8 @@ func (s *OIDCLoginSuite) SetUpTest(c *check.C) {
        s.fakeProvider.AuthEmail = "active-user@arvados.local"
        s.fakeProvider.AuthEmailVerified = true
        s.fakeProvider.AuthName = "Fake User Name"
+       s.fakeProvider.AuthGivenName = "Fake"
+       s.fakeProvider.AuthFamilyName = "User Name"
        s.fakeProvider.ValidCode = fmt.Sprintf("abcdefgh-%d", time.Now().Unix())
        s.fakeProvider.PeopleAPIResponse = map[string]interface{}{}
 
@@ -421,8 +423,8 @@ func (s *OIDCLoginSuite) TestGoogleLogin_Success(c *check.C) {
        c.Check(token, check.Matches, `v2/zzzzz-gj3su-.{15}/.{32,50}`)
 
        authinfo := getCallbackAuthInfo(c, s.railsSpy)
-       c.Check(authinfo.FirstName, check.Equals, "Fake User")
-       c.Check(authinfo.LastName, check.Equals, "Name")
+       c.Check(authinfo.FirstName, check.Equals, "Fake")
+       c.Check(authinfo.LastName, check.Equals, "User Name")
        c.Check(authinfo.Email, check.Equals, "active-user@arvados.local")
        c.Check(authinfo.AlternateEmails, check.HasLen, 0)
 
@@ -446,6 +448,7 @@ func (s *OIDCLoginSuite) TestGoogleLogin_Success(c *check.C) {
 
 func (s *OIDCLoginSuite) TestGoogleLogin_RealName(c *check.C) {
        s.fakeProvider.AuthEmail = "joe.smith@primary.example.com"
+       s.fakeProvider.AuthEmailVerified = true
        s.fakeProvider.PeopleAPIResponse = map[string]interface{}{
                "names": []map[string]interface{}{
                        {
@@ -471,8 +474,10 @@ func (s *OIDCLoginSuite) TestGoogleLogin_RealName(c *check.C) {
        c.Check(authinfo.LastName, check.Equals, "Psmith")
 }
 
-func (s *OIDCLoginSuite) TestGoogleLogin_OIDCRealName(c *check.C) {
+func (s *OIDCLoginSuite) TestGoogleLogin_OIDCNameWithoutGivenAndFamilyNames(c *check.C) {
        s.fakeProvider.AuthName = "Joe P. Smith"
+       s.fakeProvider.AuthGivenName = ""
+       s.fakeProvider.AuthFamilyName = ""
        s.fakeProvider.AuthEmail = "joe.smith@primary.example.com"
        state := s.startLogin(c)
        s.localdb.Login(context.Background(), arvados.LoginOptions{
index 77a64df895e584fd38ee5b2cb516ac5891eeb8e6..73aecd01e634ed844e1b4298fd2314fba3bb596e 100644 (file)
@@ -490,7 +490,7 @@ make -C ./builddir install
                                {"mkdir", "-p", "log", "tmp", ".bundle", "/var/www/.gem", "/var/www/.bundle", "/var/www/.passenger"},
                                {"touch", "log/production.log"},
                                {"chown", "-R", "--from=root", "www-data:www-data", "/var/www/.gem", "/var/www/.bundle", "/var/www/.passenger", "log", "tmp", ".bundle", "Gemfile.lock", "config.ru", "config/environment.rb"},
-                               {"sudo", "-u", "www-data", "/var/lib/arvados/bin/gem", "install", "--user", "--conservative", "--no-document", "bundler:1.16.6", "bundler:1.17.3", "bundler:2.0.2"},
+                               {"sudo", "-u", "www-data", "/var/lib/arvados/bin/gem", "install", "--user", "--conservative", "--no-document", "bundler:2.2.19"},
                                {"sudo", "-u", "www-data", "/var/lib/arvados/bin/bundle", "install", "--deployment", "--jobs", "8", "--path", "/var/www/.gem"},
                                {"sudo", "-u", "www-data", "/var/lib/arvados/bin/bundle", "exec", "passenger-config", "build-native-support"},
                                {"sudo", "-u", "www-data", "/var/lib/arvados/bin/bundle", "exec", "passenger-config", "install-standalone-runtime"},
index de21302e5a048dfbca340abf24cb6c5359de7305..fa5e55c42e10af410d86d0e16fc23a637dbaeff2 100644 (file)
@@ -29,6 +29,8 @@ type OIDCProvider struct {
        AuthEmail          string
        AuthEmailVerified  bool
        AuthName           string
+       AuthGivenName      string
+       AuthFamilyName     string
        AccessTokenPayload map[string]interface{}
 
        PeopleAPIResponse map[string]interface{}
@@ -96,6 +98,8 @@ func (p *OIDCProvider) serveOIDC(w http.ResponseWriter, req *http.Request) {
                        "email":          p.AuthEmail,
                        "email_verified": p.AuthEmailVerified,
                        "name":           p.AuthName,
+                       "given_name":     p.AuthGivenName,
+                       "family_name":    p.AuthFamilyName,
                        "alt_verified":   true,                    // for custom claim tests
                        "alt_email":      "alt_email@example.com", // for custom claim tests
                        "alt_username":   "desired-username",      // for custom claim tests
@@ -131,8 +135,8 @@ func (p *OIDCProvider) serveOIDC(w http.ResponseWriter, req *http.Request) {
                json.NewEncoder(w).Encode(map[string]interface{}{
                        "sub":            "fake-user-id",
                        "name":           p.AuthName,
-                       "given_name":     p.AuthName,
-                       "family_name":    "",
+                       "given_name":     p.AuthGivenName,
+                       "family_name":    p.AuthFamilyName,
                        "alt_username":   "desired-username",
                        "email":          p.AuthEmail,
                        "email_verified": p.AuthEmailVerified,
index 93fd6b598aefab0448e450391beecccbb2419f42..79dabd38b2d847072aa7d8eccb119c0224469244 100755 (executable)
@@ -102,6 +102,9 @@ def main():
     copy_opts.add_argument(
         '--project-uuid', dest='project_uuid',
         help='The UUID of the project at the destination to which the collection or workflow should be copied.')
+    copy_opts.add_argument(
+        '--storage-classes', dest='storage_classes',
+        help='Comma separated list of storage classes to be used when saving data to the destinaton Arvados instance.')
 
     copy_opts.add_argument(
         'object_uuid',
@@ -114,6 +117,9 @@ def main():
         parents=[copy_opts, arv_cmd.retry_opt])
     args = parser.parse_args()
 
+    if args.storage_classes:
+        args.storage_classes = [x for x in args.storage_classes.strip().replace(' ', '').split(',') if x]
+
     if args.verbose:
         logger.setLevel(logging.DEBUG)
     else:
@@ -410,6 +416,9 @@ def create_collection_from(c, src, dst, args):
     if not body["name"]:
         body['name'] = "copied from " + collection_uuid
 
+    if args.storage_classes:
+        body['storage_classes_desired'] = args.storage_classes
+
     body['owner_uuid'] = args.project_uuid
 
     dst_collection = dst.collections().create(body=body, ensure_unique_name=True).execute(num_retries=args.retries)
@@ -563,7 +572,7 @@ def copy_collection(obj_uuid, src, dst, args):
                 if progress_writer:
                     progress_writer.report(obj_uuid, bytes_written, bytes_expected)
                 data = src_keep.get(word)
-                dst_locator = dst_keep.put(data)
+                dst_locator = dst_keep.put(data, classes=(args.storage_classes or []))
                 dst_locators[blockhash] = dst_locator
                 bytes_written += loc.size
             dst_manifest.write(' ')
index 452c2beba2b0639abfdf637e3f503f2f25526f7a..b560018d385bfd3f62f366333527f54a3ec272c2 100644 (file)
@@ -42,6 +42,8 @@ class ArvCopyVersionTestCase(run_test_server.TestCaseWithServers, tutil.VersionC
         with c.open('foo', 'wt') as f:
             f.write('foo')
         c.save_new("arv-copy foo collection", owner_uuid=src_proj)
+        coll_record = api.collections().get(uuid=c.manifest_locator()).execute()
+        assert coll_record['storage_classes_desired'] == ['default']
 
         dest_proj = api.groups().create(body={"group": {"name": "arv-copy dest project", "group_class": "project"}}).execute()["uuid"]
 
@@ -60,7 +62,7 @@ class ArvCopyVersionTestCase(run_test_server.TestCaseWithServers, tutil.VersionC
             assert len(contents["items"]) == 0
 
             try:
-                self.run_copy(["--project-uuid", dest_proj, src_proj])
+                self.run_copy(["--project-uuid", dest_proj, "--storage-classes", "foo", src_proj])
             except SystemExit as e:
                 assert e.code == 0
 
@@ -76,6 +78,7 @@ class ArvCopyVersionTestCase(run_test_server.TestCaseWithServers, tutil.VersionC
             assert contents["items"][0]["uuid"] != c.manifest_locator()
             assert contents["items"][0]["name"] == "arv-copy foo collection"
             assert contents["items"][0]["portable_data_hash"] == c.portable_data_hash()
+            assert contents["items"][0]["storage_classes_desired"] == ["foo"]
 
         finally:
             os.environ['HOME'] = home_was
index 92099614a81e7cdd881bcb7f97897dc2a1a5d76d..cb0dc2d652d9a8c54fb7db3bd39cb9255015faff 100644 (file)
@@ -47,7 +47,7 @@ RUN sudo -u arvbox /var/lib/arvbox/service/doc/run-service --only-deps
 RUN sudo -u arvbox /var/lib/arvbox/service/vm/run-service --only-deps
 RUN sudo -u arvbox /var/lib/arvbox/service/keepproxy/run-service --only-deps
 RUN sudo -u arvbox /var/lib/arvbox/service/arv-git-httpd/run-service --only-deps
-RUN sudo -u arvbox /var/lib/arvbox/service/crunch-dispatch-local/run-service --only-deps
+RUN /var/lib/arvbox/service/crunch-dispatch-local/run --only-deps
 RUN sudo -u arvbox /var/lib/arvbox/service/websockets/run --only-deps
 RUN sudo -u arvbox /usr/local/lib/arvbox/keep-setup.sh --only-deps
 RUN sudo -u arvbox /var/lib/arvbox/service/sdk/run-service
index 821afdce50b1fac246071dabc7e5fd507b201c84..3ce2220d0e26d5dc70705e8c8cafb1a7303225ae 100755 (executable)
@@ -6,25 +6,11 @@
 exec 2>&1
 set -ex -o pipefail
 
-. /usr/local/lib/arvbox/common.sh
-. /usr/local/lib/arvbox/go-setup.sh
+# singularity can use suid
+chown root /var/lib/arvados/bin/singularity \
+      /var/lib/arvados/etc/singularity/singularity.conf \
+      /var/lib/arvados/etc/singularity/capability.json \
+      /var/lib/arvados/etc/singularity/ecl.toml
+chmod u+s /var/lib/arvados/bin/singularity
 
-flock /var/lib/gopath/gopath.lock go install "git.arvados.org/arvados.git/services/crunch-dispatch-local"
-install $GOPATH/bin/crunch-dispatch-local /usr/local/bin
-ln -sf arvados-server /usr/local/bin/crunch-run
-
-if test "$1" = "--only-deps" ; then
-    exit
-fi
-
-cat > /usr/local/bin/crunch-run.sh <<EOF
-#!/bin/sh
-exec /usr/local/bin/crunch-run -container-enable-networking=default -container-network-mode=host \$@
-EOF
-chmod +x /usr/local/bin/crunch-run.sh
-
-export ARVADOS_API_HOST=$localip:${services[controller-ssl]}
-export ARVADOS_API_HOST_INSECURE=1
-export ARVADOS_API_TOKEN=$(cat $ARVADOS_CONTAINER_PATH/superuser_token)
-
-exec /usr/local/bin/crunch-dispatch-local -crunch-run-command=/usr/local/bin/crunch-run.sh -poll-interval=1
+exec /usr/local/lib/arvbox/runsu.sh $0-service $1
diff --git a/tools/arvbox/lib/arvbox/docker/service/crunch-dispatch-local/run-service b/tools/arvbox/lib/arvbox/docker/service/crunch-dispatch-local/run-service
new file mode 100755 (executable)
index 0000000..821afdc
--- /dev/null
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
+exec 2>&1
+set -ex -o pipefail
+
+. /usr/local/lib/arvbox/common.sh
+. /usr/local/lib/arvbox/go-setup.sh
+
+flock /var/lib/gopath/gopath.lock go install "git.arvados.org/arvados.git/services/crunch-dispatch-local"
+install $GOPATH/bin/crunch-dispatch-local /usr/local/bin
+ln -sf arvados-server /usr/local/bin/crunch-run
+
+if test "$1" = "--only-deps" ; then
+    exit
+fi
+
+cat > /usr/local/bin/crunch-run.sh <<EOF
+#!/bin/sh
+exec /usr/local/bin/crunch-run -container-enable-networking=default -container-network-mode=host \$@
+EOF
+chmod +x /usr/local/bin/crunch-run.sh
+
+export ARVADOS_API_HOST=$localip:${services[controller-ssl]}
+export ARVADOS_API_HOST_INSECURE=1
+export ARVADOS_API_TOKEN=$(cat $ARVADOS_CONTAINER_PATH/superuser_token)
+
+exec /usr/local/bin/crunch-dispatch-local -crunch-run-command=/usr/local/bin/crunch-run.sh -poll-interval=1