[ARVADOS] updated: 2.1.0-309-ga4a17913e

Git user git at public.arvados.org
Tue Jan 19 20:45:27 UTC 2021


Summary of changes:
 .gitignore                                         |    2 +
 .licenseignore                                     |    4 +
 CONTRIBUTING.md                                    |    2 +-
 apps/workbench/Gemfile                             |   24 +-
 apps/workbench/Gemfile.lock                        |  140 +-
 .../app/controllers/application_controller.rb      |    5 +-
 .../controllers/container_requests_controller.rb   |   63 +-
 .../app/controllers/projects_controller.rb         |    2 +-
 .../app/controllers/trash_items_controller.rb      |   12 +-
 apps/workbench/app/controllers/users_controller.rb |   12 +
 .../app/controllers/work_units_controller.rb       |    4 +
 apps/workbench/app/helpers/application_helper.rb   |    5 +
 apps/workbench/app/models/arvados_base.rb          |    6 +
 apps/workbench/app/models/container_request.rb     |   24 +
 apps/workbench/app/models/user.rb                  |    2 +-
 .../_extra_tab_line_buttons.html.erb               |   47 +-
 .../views/container_requests/_show_inputs.html.erb |   18 +-
 .../app/views/users/_virtual_machines.html.erb     |    2 +-
 apps/workbench/app/views/users/profile.html.erb    |   21 +-
 .../app/views/virtual_machines/webshell.html.erb   |   42 +-
 .../app/views/work_units/_show_component.html.erb  |    8 +-
 apps/workbench/bin/bundle                          |    2 +-
 apps/workbench/bin/setup                           |    6 +-
 apps/workbench/bin/update                          |    3 +
 apps/workbench/bin/yarn                            |   15 +
 apps/workbench/config/application.default.yml      |    1 -
 apps/workbench/config/application.rb               |    7 +-
 apps/workbench/config/boot.rb                      |    1 +
 apps/workbench/config/initializers/assets.rb       |    2 +-
 .../config/initializers/content_security_policy.rb |    0
 .../config/initializers/new_framework_defaults.rb  |    3 -
 .../initializers/new_framework_defaults_5_1.rb     |   18 +
 .../initializers/new_framework_defaults_5_2.rb     |    0
 apps/workbench/config/routes.rb                    |    2 +-
 apps/workbench/config/secrets.yml                  |   18 +-
 .../assets/javascripts}/webshell/shell_in_a_box.js |   52 +-
 .../assets/stylesheets}/webshell/styles.css        |   38 +-
 .../container_requests_controller_test.rb          |   23 +-
 .../test/integration/anonymous_access_test.rb      |    2 +-
 apps/workbench/test/integration/work_units_test.rb |   23 +-
 build/README                                       |    4 +-
 build/build-dev-docker-jobs-image.sh               |   12 +-
 build/package-build-dockerfiles/Makefile           |   19 +-
 build/package-build-dockerfiles/centos7/Dockerfile |   12 +-
 .../{debian9 => ubuntu2004}/Dockerfile             |    7 +-
 build/package-test-dockerfiles/Makefile            |   18 +-
 .../{debian9 => ubuntu2004}/Dockerfile             |    6 +-
 ...age-rh-python36-python-arvados-python-client.sh |    2 +-
 ...ges-debian10.sh => test-packages-ubuntu2004.sh} |    0
 build/rails-package-scripts/README.md              |    4 +-
 build/rails-package-scripts/arvados-sso-server.sh  |   13 -
 build/rails-package-scripts/postinst.sh            |    9 +-
 build/run-build-docker-images.sh                   |   65 +-
 build/run-build-docker-jobs-image.sh               |   63 +-
 build/run-build-packages-one-target.sh             |   15 +-
 build/run-build-packages-python-and-ruby.sh        |   13 +-
 build/run-build-packages-sso.sh                    |  158 -
 build/run-build-packages.sh                        |    9 +-
 build/run-library.sh                               |   75 +-
 build/run-tests.sh                                 |  163 +-
 build/version-at-commit.sh                         |    5 +-
 cmd/arvados-client/cmd.go                          |    2 +
 cmd/arvados-dev/buildpackage.go                    |  112 -
 cmd/arvados-dev/buildpackage_test.go               |   77 -
 cmd/arvados-dev/cmd.go                             |   25 -
 cmd/arvados-dev/docker-boot.sh                     |   71 -
 cmd/arvados-dev/docker-build-install.sh            |  128 -
 cmd/arvados-package/build.go                       |  162 +
 cmd/arvados-package/build_test.go                  |   67 +
 cmd/arvados-package/cmd.go                         |  132 +
 cmd/arvados-package/fpm.go                         |  113 +
 cmd/arvados-package/install.go                     |  122 +
 doc/Gemfile                                        |    2 +-
 doc/Gemfile.lock                                   |   40 +-
 doc/README.textile                                 |   22 +-
 doc/Rakefile                                       |    6 +-
 doc/_config.yml                                    |   55 +-
 doc/_includes/_0_filter_py.liquid                  |   35 -
 ...min_list_collections_without_property_py.liquid |    2 +-
 ...property_to_collections_under_project_py.liquid |    2 +-
 .../_admin_update_collection_property_py.liquid    |    2 +-
 doc/_includes/_alert-incomplete.liquid             |   11 -
 doc/_includes/_alert_stub.liquid                   |   11 -
 doc/_includes/_arv_copy_expectations.liquid        |   12 -
 doc/_includes/_compute_ping_rb.liquid              |  290 --
 doc/_includes/_concurrent_hash_script_py.liquid    |   88 -
 doc/_includes/_crunch1only_begin.liquid            |    8 -
 doc/_includes/_crunch1only_end.liquid              |    7 -
 doc/_includes/_example_docker.liquid               |   34 -
 doc/_includes/_example_sdk_go.liquid               |    8 +-
 doc/_includes/_install_compute_docker.liquid       |    2 +-
 doc/_includes/_install_git.liquid                  |    9 -
 doc/_includes/_install_rails_reconfigure.liquid    |   17 -
 doc/_includes/_install_ruby_and_bundler.liquid     |   22 +-
 doc/_includes/_install_ruby_and_bundler_sso.liquid |   69 -
 doc/_includes/_install_runit.liquid                |   19 -
 doc/_includes/_pipeline_deprecation_notice.liquid  |    9 -
 doc/_includes/_run_command_foreach_example.liquid  |   46 -
 doc/_includes/_run_command_simple_example.liquid   |   43 -
 doc/_includes/_run_md5sum_py.liquid                |   24 -
 doc/_includes/_ssh_addkey.liquid                   |    6 +-
 .../_tutorial_bwa_sortsam_pipeline.liquid          |   78 -
 doc/_includes/_tutorial_cluster_name.liquid        |    9 -
 doc/_includes/_tutorial_expectations.liquid        |    2 +-
 doc/_includes/_tutorial_hash_script_py.liquid      |   50 -
 doc/_includes/_tutorial_hello_cwl.liquid           |   10 +
 doc/_includes/_tutorial_submit_job.liquid          |   25 -
 doc/_includes/_what_is_cwl.liquid                  |    2 +-
 doc/_layouts/default.html.liquid                   |   49 +-
 .../collection-versioning.html.textile.liquid      |    2 +-
 doc/admin/config.html.textile.liquid               |    2 +-
 doc/admin/federation.html.textile.liquid           |   35 +-
 doc/admin/keep-balance.html.textile.liquid         |    4 +-
 doc/admin/keep-recovering-data.html.textile.liquid |  109 +
 ...overing-deleted-collections.html.textile.liquid |   37 -
 doc/admin/scoped-tokens.html.textile.liquid        |    6 +
 doc/admin/spot-instances.html.textile.liquid       |   23 +-
 .../token-expiration-policy.html.textile.liquid    |   62 +
 doc/admin/upgrading.html.textile.liquid            |   33 +-
 doc/admin/user-activity.html.textile.liquid        |  101 +
 doc/admin/user-management-cli.html.textile.liquid  |  104 +-
 doc/api/index.html.textile.liquid                  |    2 +-
 doc/api/keep-s3.html.textile.liquid                |   89 +
 doc/api/keep-web-urls.html.textile.liquid          |   75 +
 doc/api/keep-webdav.html.textile.liquid            |  103 +
 doc/api/methods.html.textile.liquid                |    6 +-
 doc/api/methods/collections.html.textile.liquid    |    4 +-
 doc/api/methods/groups.html.textile.liquid         |    2 +
 doc/api/methods/jobs.html.textile.liquid           |   16 +-
 doc/api/methods/links.html.textile.liquid          |   22 +-
 .../methods/pipeline_templates.html.textile.liquid |   16 +-
 doc/api/tokens.html.textile.liquid                 |    2 +-
 doc/architecture/Arvados_arch.odg                  |  Bin 14997 -> 17162 bytes
 doc/architecture/federation.html.textile.liquid    |   31 +-
 doc/architecture/keep-clients.html.textile.liquid  |   39 +
 .../keep-data-lifecycle.html.textile.liquid        |   59 +
 .../manifest-format.html.textile.liquid}           |  197 +-
 doc/architecture/storage.html.textile.liquid       |   40 +
 doc/css/layout.css                                 |   57 +
 .../pipeline_templates/gatk-exome-fq-snp.json      |  175 -
 doc/examples/pipeline_templates/rtg-fq-snp.json    |   76 -
 doc/examples/ruby/list-active-nodes.rb             |   16 -
 doc/images/Arvados_arch.svg                        |  450 +-
 doc/images/Keep_manifests.svg                      |  158 +-
 doc/images/wgs-tutorial/image1.png                 |  Bin 0 -> 223266 bytes
 doc/images/wgs-tutorial/image2.png                 |  Bin 0 -> 51157 bytes
 doc/images/wgs-tutorial/image3.png                 |  Bin 0 -> 96569 bytes
 doc/images/wgs-tutorial/image4.png                 |  Bin 0 -> 78882 bytes
 doc/images/wgs-tutorial/image5.png                 |  Bin 0 -> 315990 bytes
 doc/images/wgs-tutorial/image6.png                 |  Bin 0 -> 287176 bytes
 doc/index.html.liquid                              |   11 +-
 .../arvados-on-kubernetes-GKE.html.textile.liquid  |    8 -
 ...ados-on-kubernetes-minikube.html.textile.liquid |    6 +-
 .../arvados-on-kubernetes.html.textile.liquid      |    4 -
 doc/install/arvbox.html.textile.liquid             |   39 +-
 doc/install/automatic.html.textile.liquid          |    8 +-
 doc/install/config.html.textile.liquid             |    2 +-
 ...opy_pipeline_from_curoverse.html.textile.liquid |   68 -
 .../install-compute-node.html.textile.liquid       |   58 +-
 .../install-dispatch-cloud.html.textile.liquid     |   17 +-
 .../install-dispatch.html.textile.liquid           |    2 +-
 doc/install/index.html.textile.liquid              |    7 +-
 doc/install/install-api-server.html.textile.liquid |   19 +-
 .../install-compute-ping.html.textile.liquid       |   14 -
 doc/install/install-keep-web.html.textile.liquid   |    6 +-
 ...nstall-manual-prerequisites.html.textile.liquid |    7 +-
 doc/install/install-postgresql.html.textile.liquid |   10 +-
 .../install-shell-server.html.textile.liquid       |   62 +-
 doc/install/install-webshell.html.textile.liquid   |   11 +-
 doc/install/new_cluster_checklist_AWS.xlsx         |  Bin 5647 -> 5712 bytes
 doc/install/new_cluster_checklist_Azure.xlsx       |  Bin 5666 -> 5748 bytes
 doc/install/new_cluster_checklist_slurm.xlsx       |  Bin 5645 -> 5669 bytes
 doc/install/packages.html.textile.liquid           |    7 +-
 doc/install/salt-multi-host.html.textile.liquid    |  110 +
 doc/install/salt-single-host.html.textile.liquid   |  215 +
 doc/install/salt-vagrant.html.textile.liquid       |  127 +
 doc/install/salt.html.textile.liquid               |   29 +
 doc/sdk/cli/install.html.textile.liquid            |    2 +-
 doc/sdk/cli/reference.html.textile.liquid          |    2 +
 doc/sdk/go/example.html.textile.liquid             |    4 +-
 doc/sdk/java-v2/example.html.textile.liquid        |    2 +-
 doc/sdk/java-v2/index.html.textile.liquid          |    2 +-
 ...quid => arvados-cwl-runner.html.textile.liquid} |   42 +-
 doc/sdk/python/arvados-fuse.html.textile.liquid    |   10 +-
 doc/sdk/python/cookbook.html.textile.liquid        |   55 +-
 doc/sdk/python/events.html.textile.liquid          |    4 +-
 doc/sdk/python/sdk-python.html.textile.liquid      |   26 +-
 doc/sdk/ruby/example.html.textile.liquid           |    2 +-
 doc/sdk/ruby/index.html.textile.liquid             |    2 +-
 .../firstpipeline.html.textile.liquid              |   94 -
 .../getting_started/nextsteps.html.textile.liquid  |   12 -
 .../publicproject.html.textile.liquid              |  133 -
 .../getting_started/sharedata.html.textile.liquid  |  102 -
 doc/start/index.html.textile.liquid                |  133 -
 doc/user/composer/composer.html.textile.liquid     |    2 +-
 doc/user/cwl/bwa-mem/bwa-mem-input-mixed.yml       |    6 +-
 doc/user/cwl/bwa-mem/bwa-mem-input-uuids.yml       |    6 +-
 doc/user/cwl/bwa-mem/bwa-mem.cwl                   |    6 +-
 doc/user/cwl/cwl-extensions.html.textile.liquid    |    2 +-
 doc/user/cwl/cwl-run-options.html.textile.liquid   |   24 +-
 doc/user/cwl/cwl-runner.html.textile.liquid        |  190 +-
 doc/user/cwl/cwl-style.html.textile.liquid         |    2 +-
 doc/user/cwl/cwl-versions.html.textile.liquid      |    4 +-
 .../check-environment.html.textile.liquid          |   10 +-
 .../ssh-access-unix.html.textile.liquid            |   22 +-
 .../ssh-access-windows.html.textile.liquid         |   14 +-
 .../vm-login-with-webshell.html.textile.liquid     |    6 +-
 .../getting_started/workbench.html.textile.liquid  |   22 +-
 doc/user/index.html.textile.liquid                 |   11 +-
 doc/user/topics/arv-copy.html.textile.liquid       |   91 +-
 doc/user/topics/arv-docker.html.textile.liquid     |  155 +-
 doc/user/topics/arv-web.html.textile.liquid        |  106 -
 doc/user/topics/keep.html.textile.liquid           |   59 -
 ...rial-gatk-variantfiltration.html.textile.liquid |  173 -
 doc/user/topics/tutorial-job1.html.textile.liquid  |  214 -
 .../add-new-repository.html.textile.liquid         |    2 +-
 .../git-arvados-guide.html.textile.liquid          |   36 +-
 ...l-keep-collection-lifecycle.html.textile.liquid |   48 +-
 .../tutorial-keep-get.html.textile.liquid          |   93 +-
 ...torial-keep-mount-gnu-linux.html.textile.liquid |   21 +-
 .../tutorial-keep-mount-os-x.html.textile.liquid   |   10 +-
 ...tutorial-keep-mount-windows.html.textile.liquid |    4 +-
 .../tutorials/tutorial-keep.html.textile.liquid    |   61 +-
 ...tutorial-workflow-workbench.html.textile.liquid |   16 +-
 .../tutorials/wgs-tutorial.html.textile.liquid     |  357 ++
 .../writing-cwl-workflow.html.textile.liquid       |  120 +-
 doc/zenweb-liquid.rb                               |   14 +-
 docker/jobs/Dockerfile                             |    8 +-
 docker/jobs/apt.arvados.org-dev.list               |    2 +-
 docker/jobs/apt.arvados.org-stable.list            |    2 +-
 docker/jobs/apt.arvados.org-testing.list           |    2 +-
 docker/migrate-docker19/Dockerfile                 |    2 +-
 lib/boot/cert.go                                   |   10 +-
 lib/boot/cmd.go                                    |    5 +
 lib/boot/nginx.go                                  |   22 +-
 lib/boot/passenger.go                              |   33 +-
 lib/boot/postgresql.go                             |   31 +-
 lib/boot/seed.go                                   |    6 +-
 lib/boot/service.go                                |    8 +-
 lib/boot/supervisor.go                             |  143 +-
 lib/cloud/azure/azure.go                           |   19 +-
 lib/cloud/azure/azure_test.go                      |   24 +-
 lib/cloud/cloudtest/tester.go                      |   15 +-
 lib/cloud/ec2/ec2.go                               |   17 +-
 lib/cloud/ec2/ec2_test.go                          |    8 +-
 lib/cmd/cmd.go                                     |    2 +-
 lib/config/cmd.go                                  |   16 +-
 lib/config/cmd_test.go                             |    6 +-
 lib/config/config.default.yml                      |   64 +-
 lib/config/deprecated_test.go                      |   18 +-
 lib/config/export.go                               |    8 +-
 lib/config/generated_config.go                     |   64 +-
 lib/config/load.go                                 |   18 +
 lib/config/load_test.go                            |   41 +-
 lib/controller/api/routable.go                     |   13 +
 lib/controller/auth_test.go                        |  126 +
 lib/controller/fed_collections.go                  |   12 +-
 lib/controller/fed_containers.go                   |   12 +-
 lib/controller/fed_generic.go                      |   34 +-
 lib/controller/federation.go                       |   13 +-
 lib/controller/federation/conn.go                  |  143 +-
 lib/controller/federation/federation_test.go       |    2 +-
 lib/controller/federation/login_test.go            |    2 -
 lib/controller/federation/user_test.go             |   54 +
 lib/controller/federation_test.go                  |    4 +-
 lib/controller/handler.go                          |    7 +-
 lib/controller/handler_test.go                     |    4 +-
 lib/controller/integration_test.go                 |  314 +-
 lib/controller/localdb/login.go                    |   48 +-
 lib/controller/localdb/login_ldap_test.go          |    2 +-
 lib/controller/localdb/login_oidc.go               |  257 +-
 lib/controller/localdb/login_oidc_test.go          |  224 +-
 lib/controller/localdb/login_testuser.go           |  104 +
 lib/controller/localdb/login_testuser_test.go      |  103 +
 lib/controller/railsproxy/railsproxy.go            |    3 +-
 lib/controller/rpc/conn.go                         |    9 +-
 lib/controller/rpc/conn_test.go                    |    6 +-
 lib/controller/semaphore.go                        |    3 +-
 lib/costanalyzer/cmd.go                            |   43 +
 lib/costanalyzer/costanalyzer.go                   |  568 +++
 lib/costanalyzer/costanalyzer_test.go              |  325 ++
 lib/crunchrun/background.go                        |   22 +-
 lib/crunchrun/copier.go                            |    3 +-
 lib/crunchrun/crunchrun.go                         |  113 +-
 lib/crunchrun/crunchrun_test.go                    |   44 +-
 lib/crunchrun/logging.go                           |    5 +-
 lib/crunchrun/logging_test.go                      |    6 +-
 lib/ctrlctx/db.go                                  |    1 +
 lib/dispatchcloud/container/queue.go               |    8 +-
 lib/dispatchcloud/dispatcher.go                    |   12 +-
 lib/dispatchcloud/dispatcher_test.go               |   20 +-
 lib/dispatchcloud/driver.go                        |    5 +-
 lib/dispatchcloud/scheduler/run_queue.go           |   48 +-
 lib/dispatchcloud/scheduler/run_queue_test.go      |  134 +-
 lib/dispatchcloud/scheduler/scheduler.go           |   66 +-
 lib/dispatchcloud/scheduler/sync.go                |    6 +-
 lib/dispatchcloud/scheduler/sync_test.go           |    4 +-
 .../{ssh_executor => sshexecutor}/executor.go      |    4 +-
 .../{ssh_executor => sshexecutor}/executor_test.go |    2 +-
 lib/dispatchcloud/test/queue.go                    |   27 +-
 lib/dispatchcloud/test/ssh_service.go              |    2 +
 lib/dispatchcloud/test/stub_driver.go              |  148 +-
 lib/dispatchcloud/worker/pool.go                   |  209 +-
 lib/dispatchcloud/worker/pool_test.go              |   40 +
 lib/dispatchcloud/worker/verify.go                 |    6 +-
 lib/dispatchcloud/worker/worker.go                 |   59 +-
 lib/dispatchcloud/worker/worker_test.go            |    2 +
 lib/install/deps.go                                |   89 +-
 lib/install/init.go                                |    8 +-
 lib/mount/command.go                               |    1 +
 lib/pam/fpm-info.sh                                |    2 +
 lib/pam/pam-configs-arvados                        |    9 +-
 lib/service/cmd.go                                 |    4 +-
 lib/service/cmd_test.go                            |    9 +-
 lib/service/tls.go                                 |    2 +-
 sdk/R/DESCRIPTION                                  |    6 +-
 sdk/R/R/Arvados.R                                  | 4821 +++++++-------------
 sdk/R/R/ArvadosFile.R                              |    2 -
 sdk/R/R/Collection.R                               |    8 +-
 sdk/R/R/CollectionTree.R                           |    4 -
 sdk/R/R/HttpParser.R                               |    5 +-
 sdk/R/R/HttpRequest.R                              |    4 +-
 sdk/R/R/RESTService.R                              |   15 +-
 sdk/R/R/Subcollection.R                            |    2 -
 sdk/R/R/autoGenAPI.R                               |   12 +-
 sdk/R/README.Rmd                                   |   22 +-
 sdk/R/tests/testthat/test-ArvadosFile.R            |   12 +-
 sdk/R/tests/testthat/test-Collection.R             |   22 +-
 sdk/R/tests/testthat/test-CollectionTree.R         |   22 +-
 sdk/R/tests/testthat/test-HttpParser.R             |    8 +-
 sdk/R/tests/testthat/test-HttpRequest.R            |   14 +-
 sdk/R/tests/testthat/test-RESTService.R            |   54 +-
 sdk/R/tests/testthat/test-Subcollection.R          |   28 +-
 sdk/cli/arvados-cli.gemspec                        |    3 +-
 sdk/cli/test/test_arv-keep-get.rb                  |    6 +-
 sdk/cwl/arvados_cwl/__init__.py                    |    8 +-
 sdk/cwl/arvados_cwl/arv-cwl-schema-v1.0.yml        |    6 +
 sdk/cwl/arvados_cwl/arv-cwl-schema-v1.1.yml        |    6 +
 sdk/cwl/arvados_cwl/arv-cwl-schema-v1.2.yml        |    6 +
 sdk/cwl/arvados_cwl/arvcontainer.py                |   12 +-
 sdk/cwl/arvados_cwl/arvdocker.py                   |    6 +-
 sdk/cwl/arvados_cwl/arvworkflow.py                 |   37 +-
 sdk/cwl/arvados_cwl/executor.py                    |    7 +-
 sdk/cwl/arvados_cwl/pathmapper.py                  |    4 +-
 sdk/cwl/arvados_cwl/runner.py                      |   21 +-
 sdk/cwl/arvados_cwl/task_queue.py                  |   77 -
 sdk/cwl/arvados_version.py                         |   43 +-
 sdk/cwl/bin/arvados-cwl-runner                     |    2 +-
 sdk/cwl/bin/cwl-runner                             |    2 +-
 sdk/cwl/fpm-info.sh                                |    7 +-
 sdk/cwl/gittaggers.py                              |   48 -
 sdk/cwl/setup.py                                   |    4 +-
 sdk/cwl/test_with_arvbox.sh                        |    6 +-
 .../collection_per_tool_packed.cwl                 |    8 +-
 sdk/cwl/tests/federation/arvboxcwl/fed-config.cwl  |    3 +-
 sdk/cwl/tests/federation/arvboxcwl/start.cwl       |    2 +-
 sdk/cwl/tests/test_submit.py                       |   79 +-
 sdk/cwl/tests/test_tq.py                           |    2 +-
 sdk/cwl/tests/tool/submit_tool.cwl                 |    2 +-
 sdk/cwl/tests/tool/tool_with_sf.cwl                |    2 +-
 sdk/cwl/tests/wf/16169-step.cwl                    |    2 +-
 sdk/cwl/tests/wf/expect_arvworkflow.cwl            |    2 +-
 sdk/cwl/tests/wf/expect_packed.cwl                 |    2 +-
 ...{expect_packed.cwl => expect_upload_packed.cwl} |   10 +-
 sdk/cwl/tests/wf/secret_wf.cwl                     |    2 +-
 sdk/cwl/tests/wf/submit_wf_packed.cwl              |    2 +-
 sdk/dev-jobs.dockerfile                            |    8 +-
 sdk/go/arvados/blob_signature.go                   |    3 +-
 sdk/go/arvados/client.go                           |    7 +-
 sdk/go/arvados/config.go                           |   61 +-
 sdk/go/arvados/container.go                        |    4 +-
 sdk/go/arvados/fs_base.go                          |    3 +-
 sdk/go/arvados/fs_collection.go                    |   35 +-
 sdk/go/arvados/fs_project_test.go                  |    1 +
 sdk/go/arvados/keep_service.go                     |    2 +-
 sdk/go/arvados/link.go                             |    2 +-
 sdk/go/arvadosclient/arvadosclient.go              |   46 +-
 sdk/go/arvadostest/api.go                          |   80 +-
 sdk/go/arvadostest/db.go                           |    1 +
 sdk/go/arvadostest/fixtures.go                     |   25 +-
 sdk/go/arvadostest/oidc_provider.go                |  174 +
 sdk/go/auth/auth.go                                |    2 +-
 sdk/go/auth/salt.go                                |    3 +-
 sdk/go/blockdigest/blockdigest.go                  |    8 +-
 sdk/go/blockdigest/blockdigest_test.go             |    4 +-
 sdk/go/blockdigest/testing.go                      |    2 +-
 sdk/go/health/aggregator.go                        |    3 +
 sdk/go/health/handler_test.go                      |    3 +-
 sdk/go/httpserver/logger.go                        |    3 +-
 sdk/go/keepclient/hashcheck.go                     |   32 +-
 sdk/go/keepclient/keepclient.go                    |   48 +-
 sdk/go/keepclient/keepclient_test.go               |   51 +-
 sdk/go/keepclient/root_sorter.go                   |    5 +-
 sdk/go/keepclient/root_sorter_test.go              |   14 +-
 sdk/go/keepclient/support.go                       |   83 +-
 sdk/go/manifest/manifest.go                        |   70 +-
 sdk/go/stats/duration.go                           |    2 +-
 sdk/python/README.rst                              |    4 +-
 sdk/python/arvados/api.py                          |    4 +
 sdk/python/arvados/commands/arv_copy.py            |   86 +-
 sdk/python/arvados/commands/get.py                 |    2 +-
 sdk/python/arvados/commands/run.py                 |    2 +-
 sdk/python/arvados/keep.py                         |    6 +-
 sdk/python/arvados/util.py                         |   61 +
 sdk/python/arvados_version.py                      |   39 +-
 sdk/python/bin/arv-copy                            |    2 +-
 sdk/python/bin/arv-federation-migrate              |    2 +-
 sdk/python/bin/arv-get                             |    2 +-
 sdk/python/bin/arv-keepdocker                      |    2 +-
 sdk/python/bin/arv-ls                              |    2 +-
 sdk/python/bin/arv-migrate-docker19                |    2 +-
 sdk/python/bin/arv-normalize                       |    2 +-
 sdk/python/bin/arv-put                             |    2 +-
 sdk/python/bin/arv-ws                              |    2 +-
 sdk/python/gittaggers.py                           |   29 -
 sdk/python/setup.py                                |    2 +-
 sdk/python/tests/fed-migrate/README                |    4 +-
 sdk/python/tests/fed-migrate/fed-migrate.cwl       |    6 +-
 sdk/python/tests/fed-migrate/fed-migrate.cwlex     |    6 +-
 sdk/python/tests/fed-migrate/superuser-tok.cwl     |    2 +-
 sdk/python/tests/nginx.conf                        |   10 +-
 sdk/python/tests/run_test_server.py                |   40 +-
 sdk/python/tests/test_arv_copy.py                  |   56 +-
 sdk/python/tests/test_util.py                      |  137 +
 sdk/ruby/arvados.gemspec                           |    3 +-
 sdk/ruby/lib/arvados.rb                            |   33 +-
 .../api/app/controllers/application_controller.rb  |    6 +-
 .../v1/api_client_authorizations_controller.rb     |    8 +-
 .../arvados/v1/collections_controller.rb           |   37 +-
 .../arvados/v1/container_requests_controller.rb    |    4 +-
 .../controllers/arvados/v1/groups_controller.rb    |   25 +-
 .../app/controllers/arvados/v1/jobs_controller.rb  |    8 +-
 .../controllers/arvados/v1/schema_controller.rb    |    2 +-
 .../app/controllers/arvados/v1/users_controller.rb |   36 +-
 .../app/controllers/user_sessions_controller.rb    |    5 +
 services/api/app/middlewares/arvados_api_token.rb  |    2 +-
 services/api/app/models/api_client.rb              |   26 +-
 .../api/app/models/api_client_authorization.rb     |  240 +-
 services/api/app/models/arvados_model.rb           |   74 +-
 services/api/app/models/collection.rb              |   23 +-
 services/api/app/models/database_seeds.rb          |   20 +-
 services/api/app/models/link.rb                    |    2 +
 services/api/app/models/user.rb                    |  101 +-
 .../views/user_notifier/account_is_setup.text.erb  |   15 +-
 services/api/config/application.rb                 |    2 +-
 services/api/config/arvados_config.rb              |    9 +-
 .../20200914203202_public_favorites_project.rb     |   23 +
 .../20201103170213_refresh_trashed_groups.rb       |   17 +
 .../migrate/20201105190435_refresh_permissions.rb  |   15 +
 ...202174753_fix_collection_versions_timestamps.rb |   17 +
 services/api/db/structure.sql                      |   20 +-
 .../20200501150153_permission_table_constants.rb   |    2 +-
 services/api/lib/config_loader.rb                  |   16 +-
 services/api/lib/create_superuser_token.rb         |    2 +-
 services/api/lib/current_api_client.rb             |   46 +
 services/api/lib/enable_jobs_api.rb                |   23 +-
 .../api/lib/fix_collection_versions_timestamps.rb  |   43 +
 .../api/lib/tasks/manage_long_lived_tokens.rake    |   61 +
 services/api/lib/update_permissions.rb             |   10 +-
 services/api/script/get_anonymous_user_token.rb    |   48 +-
 services/api/script/rails                          |    2 +-
 services/api/test/fixtures/api_clients.yml         |    7 +
 services/api/test/fixtures/collections.yml         |  104 +-
 services/api/test/fixtures/container_requests.yml  |  234 +-
 services/api/test/fixtures/containers.yml          |  147 +
 services/api/test/fixtures/groups.yml              |    7 +
 services/api/test/fixtures/links.yml               |   14 +
 services/api/test/fixtures/logs.yml                |   17 +-
 services/api/test/fixtures/workflows.yml           |   25 +
 .../arvados/v1/collections_controller_test.rb      |   12 +-
 .../arvados/v1/groups_controller_test.rb           |   42 +-
 .../arvados/v1/schema_controller_test.rb           |    6 +-
 .../functional/arvados/v1/users_controller_test.rb |   26 +
 .../functional/user_sessions_controller_test.rb    |   25 +-
 .../api_client_authorizations_api_test.rb          |   46 +-
 .../api/test/integration/collections_api_test.rb   |   78 +
 services/api/test/integration/remote_user_test.rb  |  132 +-
 services/api/test/test_helper.rb                   |   19 +-
 services/api/test/unit/api_client_test.rb          |   45 +-
 services/api/test/unit/application_test.rb         |   12 +-
 services/api/test/unit/collection_test.rb          |   84 +-
 services/api/test/unit/container_request_test.rb   |   10 +-
 .../api/test/unit/create_superuser_token_test.rb   |   27 +-
 services/api/test/unit/job_test.rb                 |    2 +-
 services/api/test/unit/log_test.rb                 |   53 +-
 services/api/test/unit/permission_test.rb          |   20 +
 services/api/test/unit/user_notifier_test.rb       |   18 +
 services/api/test/unit/user_test.rb                |   75 +-
 services/arv-git-httpd/auth_handler_test.go        |    2 +-
 services/arv-git-httpd/git_handler_test.go         |    2 +-
 services/arv-git-httpd/gitolite_test.go            |    2 +-
 services/arv-git-httpd/integration_test.go         |    2 +-
 services/arv-web/README                            |    6 -
 services/arv-web/arv-web.py                        |  256 --
 services/arv-web/sample-cgi-app/docker_image       |    1 -
 services/arv-web/sample-cgi-app/public/.htaccess   |    3 -
 services/arv-web/sample-cgi-app/public/index.cgi   |    4 -
 services/arv-web/sample-cgi-app/tmp/.keepkeep      |    0
 services/arv-web/sample-rack-app/config.ru         |    8 -
 services/arv-web/sample-rack-app/docker_image      |    1 -
 services/arv-web/sample-rack-app/public/.keepkeep  |    0
 services/arv-web/sample-rack-app/tmp/.keepkeep     |    0
 services/arv-web/sample-static-page/docker_image   |    1 -
 .../arv-web/sample-static-page/public/index.html   |   10 -
 services/arv-web/sample-static-page/tmp/.keepkeep  |    0
 services/arv-web/sample-wsgi-app/docker_image      |    1 -
 services/arv-web/sample-wsgi-app/passenger_wsgi.py |    7 -
 services/arv-web/sample-wsgi-app/public/.keepkeep  |    0
 services/arv-web/sample-wsgi-app/tmp/.keepkeep     |    0
 .../crunch-dispatch-local.service                  |   29 +
 .../crunch-dispatch-local/fpm-info.sh              |    4 +-
 .../crunch-dispatch-slurm/crunch-dispatch-slurm.go |    2 +-
 services/crunch-dispatch-slurm/squeue.go           |   15 +-
 services/dockercleaner/arvados_version.py          |   35 +-
 services/dockercleaner/bin/arvados-docker-cleaner  |    2 +-
 services/dockercleaner/fpm-info.sh                 |    2 +-
 services/dockercleaner/gittaggers.py               |    1 -
 services/fuse/README.rst                           |    2 +-
 services/fuse/arvados_fuse/fusedir.py              |   15 +-
 services/fuse/arvados_fuse/unmount.py              |    1 +
 services/fuse/arvados_version.py                   |   39 +-
 services/fuse/bin/arv-mount                        |    2 +-
 services/fuse/gittaggers.py                        |    1 -
 services/fuse/setup.py                             |    2 +-
 services/keep-web/cache.go                         |   21 +-
 services/keep-web/doc.go                           |  156 +-
 services/keep-web/handler.go                       |   63 +-
 services/keep-web/handler_test.go                  |   35 +-
 services/keep-web/s3.go                            |  377 +-
 services/keep-web/s3_test.go                       |  342 +-
 services/keep-web/s3aws_test.go                    |   77 +
 services/keep-web/server_test.go                   |   19 +-
 services/keepproxy/keepproxy.go                    |   77 +-
 services/keepproxy/keepproxy_test.go               |    2 +-
 services/keepstore/keepstore.go                    |    4 +-
 services/keepstore/proxy_remote_test.go            |    2 +-
 services/keepstore/pull_worker.go                  |    7 +-
 services/keepstore/s3_volume.go                    |    5 +-
 services/keepstore/s3aws_volume.go                 |   12 +-
 services/keepstore/volume.go                       |    3 +-
 services/login-sync/arvados-login-sync.gemspec     |    3 +-
 services/login-sync/bin/arvados-login-sync         |  104 +-
 services/login-sync/test/test_add_user.rb          |   13 +-
 services/ws/doc.go                                 |    2 +-
 services/ws/service_test.go                        |    2 +-
 tools/arvbox/bin/arvbox                            |  288 +-
 tools/arvbox/lib/arvbox/docker/Dockerfile.base     |  173 +-
 tools/arvbox/lib/arvbox/docker/Dockerfile.demo     |   30 +-
 tools/arvbox/lib/arvbox/docker/Dockerfile.dev      |    9 +-
 tools/arvbox/lib/arvbox/docker/api-setup.sh        |   43 +-
 tools/arvbox/lib/arvbox/docker/cluster-config.sh   |  116 +-
 tools/arvbox/lib/arvbox/docker/common.sh           |   36 +-
 tools/arvbox/lib/arvbox/docker/createusers.sh      |   22 +-
 tools/arvbox/lib/arvbox/docker/devenv.sh           |    3 +-
 tools/arvbox/lib/arvbox/docker/edit_users.py       |   70 +
 tools/arvbox/lib/arvbox/docker/go-setup.sh         |   13 +-
 tools/arvbox/lib/arvbox/docker/keep-setup.sh       |   40 +-
 tools/arvbox/lib/arvbox/docker/runit/2             |    2 +-
 tools/arvbox/lib/arvbox/docker/runsu.sh            |    9 +-
 .../lib/arvbox/docker/service/api/run-service      |   12 +-
 .../docker/service/arv-git-httpd/run-service       |    2 +-
 .../lib/arvbox/docker/service/certificate/run      |    8 +-
 .../lib/arvbox/docker/service/controller/run       |    2 +-
 .../service/crunch-dispatch-local/run-service      |    2 +-
 .../lib/arvbox/docker/service/doc/run-service      |    7 +-
 .../lib/arvbox/docker/service/gitolite/run-service |   42 +-
 .../arvbox/docker/service/keepproxy/run-service    |   23 -
 tools/arvbox/lib/arvbox/docker/service/nginx/run   |   65 +-
 .../arvbox/lib/arvbox/docker/service/postgres/run  |    3 +-
 .../lib/arvbox/docker/service/postgres/run-service |    3 +-
 .../lib/arvbox/docker/service/ready/run-service    |   11 +-
 .../lib/arvbox/docker/service/sdk/run-service      |   20 +-
 tools/arvbox/lib/arvbox/docker/service/sso/run     |    1 -
 .../lib/arvbox/docker/service/sso/run-service      |   88 -
 tools/arvbox/lib/arvbox/docker/service/vm/run      |    4 +-
 .../lib/arvbox/docker/service/vm/run-service       |   10 +-
 .../service/{sso => webshell}/log/main/.gitstub    |    0
 .../docker/service/{sso => webshell}/log/run       |    0
 .../arvbox/lib/arvbox/docker/service/webshell/run  |   43 +
 .../lib/arvbox/docker/service/webshell/run-service |   13 +
 .../lib/arvbox/docker/service/websockets/run       |    2 +-
 .../arvbox/lib/arvbox/docker/service/workbench/run |    8 +-
 .../arvbox/docker/service/workbench/run-service    |   42 +-
 .../arvbox/docker/service/workbench2/run-service   |    8 +-
 tools/arvbox/lib/arvbox/docker/waitforpostgres.sh  |    2 +-
 tools/arvbox/lib/arvbox/docker/yml_override.py     |    4 +-
 tools/compute-images/scripts/base.sh               |    2 +-
 tools/copy-tutorial/copy-tutorial.sh               |   83 +
 tools/crunchstat-summary/arvados_version.py        |   39 +-
 tools/crunchstat-summary/bin/crunchstat-summary    |    2 +-
 tools/crunchstat-summary/gittaggers.py             |    1 -
 tools/crunchstat-summary/setup.py                  |    2 +-
 tools/keep-xref/keep-xref.py                       |    2 +-
 tools/salt-install/README.md                       |   20 +
 tools/salt-install/Vagrantfile                     |   42 +
 tools/salt-install/provision.sh                    |  285 ++
 tools/salt-install/single_host/arvados.sls         |  159 +
 .../salt-install/single_host/docker.sls            |    8 +-
 tools/salt-install/single_host/locale.sls          |   14 +
 .../single_host/nginx_api_configuration.sls        |   28 +
 .../single_host/nginx_controller_configuration.sls |   58 +
 .../single_host/nginx_keepproxy_configuration.sls  |   57 +
 .../single_host/nginx_keepweb_configuration.sls    |   57 +
 tools/salt-install/single_host/nginx_passenger.sls |   24 +
 .../single_host/nginx_webshell_configuration.sls   |   74 +
 .../single_host/nginx_websocket_configuration.sls  |   58 +
 .../single_host/nginx_workbench2_configuration.sls |   48 +
 .../single_host/nginx_workbench_configuration.sls  |   73 +
 tools/salt-install/single_host/postgresql.sls      |   42 +
 tools/salt-install/tests/hasher-workflow-job.yml   |   10 +
 tools/salt-install/tests/hasher-workflow.cwl       |   65 +
 tools/salt-install/tests/hasher.cwl                |   24 +
 tools/salt-install/tests/run-test.sh               |   68 +
 .../salt-install/tests/test.txt                    |    2 +-
 tools/sync-groups/sync-groups.go                   |   10 +-
 tools/sync-groups/sync-groups_test.go              |    8 -
 .../user-activity/MANIFEST.in                      |    5 +-
 tools/user-activity/README.rst                     |    5 +
 agpl-3.0.txt => tools/user-activity/agpl-3.0.txt   |    0
 .../arvados_user_activity/__init__.py              |    4 -
 tools/user-activity/arvados_user_activity/main.py  |  152 +
 tools/user-activity/arvados_version.py             |   58 +
 .../user-activity/bin/arv-user-activity            |    7 +-
 .../fpm-info.sh                                    |    0
 .../{crunchstat-summary => user-activity}/setup.py |   27 +-
 tools/vocabulary-migrate/vocabulary-migrate.py     |    2 +-
 626 files changed, 15651 insertions(+), 11292 deletions(-)
 create mode 100755 apps/workbench/bin/yarn
 copy {services/api => apps/workbench}/config/initializers/content_security_policy.rb (100%)
 create mode 100644 apps/workbench/config/initializers/new_framework_defaults_5_1.rb
 copy {services/api => apps/workbench}/config/initializers/new_framework_defaults_5_2.rb (100%)
 rename apps/workbench/{public => lib/assets/javascripts}/webshell/shell_in_a_box.js (99%)
 rename apps/workbench/{public => lib/assets/stylesheets}/webshell/styles.css (93%)
 rename build/package-build-dockerfiles/{debian9 => ubuntu2004}/Dockerfile (81%)
 rename build/package-test-dockerfiles/{debian9 => ubuntu2004}/Dockerfile (87%)
 copy build/package-testing/{test-packages-debian10.sh => test-packages-ubuntu2004.sh} (100%)
 delete mode 100644 build/rails-package-scripts/arvados-sso-server.sh
 delete mode 100755 build/run-build-packages-sso.sh
 delete mode 100644 cmd/arvados-dev/buildpackage.go
 delete mode 100644 cmd/arvados-dev/buildpackage_test.go
 delete mode 100644 cmd/arvados-dev/cmd.go
 delete mode 100755 cmd/arvados-dev/docker-boot.sh
 delete mode 100755 cmd/arvados-dev/docker-build-install.sh
 create mode 100644 cmd/arvados-package/build.go
 create mode 100644 cmd/arvados-package/build_test.go
 create mode 100644 cmd/arvados-package/cmd.go
 create mode 100644 cmd/arvados-package/fpm.go
 create mode 100644 cmd/arvados-package/install.go
 delete mode 100644 doc/_includes/_0_filter_py.liquid
 delete mode 100644 doc/_includes/_alert-incomplete.liquid
 delete mode 100644 doc/_includes/_alert_stub.liquid
 delete mode 100644 doc/_includes/_arv_copy_expectations.liquid
 delete mode 100644 doc/_includes/_compute_ping_rb.liquid
 delete mode 100644 doc/_includes/_concurrent_hash_script_py.liquid
 delete mode 100644 doc/_includes/_crunch1only_begin.liquid
 delete mode 100644 doc/_includes/_crunch1only_end.liquid
 delete mode 100644 doc/_includes/_example_docker.liquid
 delete mode 100644 doc/_includes/_install_git.liquid
 delete mode 100644 doc/_includes/_install_rails_reconfigure.liquid
 delete mode 100644 doc/_includes/_install_ruby_and_bundler_sso.liquid
 delete mode 100644 doc/_includes/_install_runit.liquid
 delete mode 100644 doc/_includes/_pipeline_deprecation_notice.liquid
 delete mode 100644 doc/_includes/_run_command_foreach_example.liquid
 delete mode 100644 doc/_includes/_run_command_simple_example.liquid
 delete mode 100644 doc/_includes/_run_md5sum_py.liquid
 delete mode 100644 doc/_includes/_tutorial_bwa_sortsam_pipeline.liquid
 delete mode 100644 doc/_includes/_tutorial_cluster_name.liquid
 delete mode 100644 doc/_includes/_tutorial_hash_script_py.liquid
 create mode 100644 doc/_includes/_tutorial_hello_cwl.liquid
 delete mode 100644 doc/_includes/_tutorial_submit_job.liquid
 create mode 100644 doc/admin/keep-recovering-data.html.textile.liquid
 delete mode 100644 doc/admin/recovering-deleted-collections.html.textile.liquid
 create mode 100644 doc/admin/token-expiration-policy.html.textile.liquid
 create mode 100644 doc/admin/user-activity.html.textile.liquid
 create mode 100644 doc/api/keep-s3.html.textile.liquid
 create mode 100644 doc/api/keep-web-urls.html.textile.liquid
 create mode 100644 doc/api/keep-webdav.html.textile.liquid
 create mode 100644 doc/architecture/keep-clients.html.textile.liquid
 create mode 100644 doc/architecture/keep-data-lifecycle.html.textile.liquid
 rename doc/{api/storage.html.textile.liquid => architecture/manifest-format.html.textile.liquid} (51%)
 create mode 100644 doc/architecture/storage.html.textile.liquid
 create mode 100644 doc/css/layout.css
 delete mode 100644 doc/examples/pipeline_templates/gatk-exome-fq-snp.json
 delete mode 100644 doc/examples/pipeline_templates/rtg-fq-snp.json
 delete mode 100755 doc/examples/ruby/list-active-nodes.rb
 create mode 100644 doc/images/wgs-tutorial/image1.png
 create mode 100644 doc/images/wgs-tutorial/image2.png
 create mode 100644 doc/images/wgs-tutorial/image3.png
 create mode 100644 doc/images/wgs-tutorial/image4.png
 create mode 100644 doc/images/wgs-tutorial/image5.png
 create mode 100644 doc/images/wgs-tutorial/image6.png
 delete mode 100644 doc/install/copy_pipeline_from_curoverse.html.textile.liquid
 delete mode 100644 doc/install/install-compute-ping.html.textile.liquid
 create mode 100644 doc/install/salt-multi-host.html.textile.liquid
 create mode 100644 doc/install/salt-single-host.html.textile.liquid
 create mode 100644 doc/install/salt-vagrant.html.textile.liquid
 create mode 100644 doc/install/salt.html.textile.liquid
 copy doc/sdk/python/{arvados-fuse.html.textile.liquid => arvados-cwl-runner.html.textile.liquid} (55%)
 delete mode 100644 doc/start/getting_started/firstpipeline.html.textile.liquid
 delete mode 100644 doc/start/getting_started/nextsteps.html.textile.liquid
 delete mode 100644 doc/start/getting_started/publicproject.html.textile.liquid
 delete mode 100644 doc/start/getting_started/sharedata.html.textile.liquid
 delete mode 100644 doc/start/index.html.textile.liquid
 delete mode 100644 doc/user/topics/arv-web.html.textile.liquid
 delete mode 100644 doc/user/topics/keep.html.textile.liquid
 delete mode 100644 doc/user/topics/tutorial-gatk-variantfiltration.html.textile.liquid
 delete mode 100644 doc/user/topics/tutorial-job1.html.textile.liquid
 create mode 100644 doc/user/tutorials/wgs-tutorial.html.textile.liquid
 create mode 100644 lib/controller/auth_test.go
 create mode 100644 lib/controller/localdb/login_testuser.go
 create mode 100644 lib/controller/localdb/login_testuser_test.go
 create mode 100644 lib/costanalyzer/cmd.go
 create mode 100644 lib/costanalyzer/costanalyzer.go
 create mode 100644 lib/costanalyzer/costanalyzer_test.go
 rename lib/dispatchcloud/{ssh_executor => sshexecutor}/executor.go (98%)
 rename lib/dispatchcloud/{ssh_executor => sshexecutor}/executor_test.go (99%)
 delete mode 100644 sdk/cwl/arvados_cwl/task_queue.py
 delete mode 100644 sdk/cwl/gittaggers.py
 copy sdk/cwl/tests/wf/{expect_packed.cwl => expect_upload_packed.cwl} (91%)
 create mode 100644 sdk/go/arvadostest/oidc_provider.go
 delete mode 100644 sdk/python/gittaggers.py
 create mode 100644 services/api/db/migrate/20200914203202_public_favorites_project.rb
 create mode 100644 services/api/db/migrate/20201103170213_refresh_trashed_groups.rb
 create mode 100644 services/api/db/migrate/20201105190435_refresh_permissions.rb
 create mode 100644 services/api/db/migrate/20201202174753_fix_collection_versions_timestamps.rb
 create mode 100644 services/api/lib/fix_collection_versions_timestamps.rb
 create mode 100644 services/api/lib/tasks/manage_long_lived_tokens.rake
 delete mode 100644 services/arv-web/README
 delete mode 100755 services/arv-web/arv-web.py
 delete mode 100644 services/arv-web/sample-cgi-app/docker_image
 delete mode 100644 services/arv-web/sample-cgi-app/public/.htaccess
 delete mode 100755 services/arv-web/sample-cgi-app/public/index.cgi
 delete mode 100644 services/arv-web/sample-cgi-app/tmp/.keepkeep
 delete mode 100644 services/arv-web/sample-rack-app/config.ru
 delete mode 100644 services/arv-web/sample-rack-app/docker_image
 delete mode 100644 services/arv-web/sample-rack-app/public/.keepkeep
 delete mode 100644 services/arv-web/sample-rack-app/tmp/.keepkeep
 delete mode 100644 services/arv-web/sample-static-page/docker_image
 delete mode 100644 services/arv-web/sample-static-page/public/index.html
 delete mode 100644 services/arv-web/sample-static-page/tmp/.keepkeep
 delete mode 100644 services/arv-web/sample-wsgi-app/docker_image
 delete mode 100644 services/arv-web/sample-wsgi-app/passenger_wsgi.py
 delete mode 100644 services/arv-web/sample-wsgi-app/public/.keepkeep
 delete mode 100644 services/arv-web/sample-wsgi-app/tmp/.keepkeep
 create mode 100644 services/crunch-dispatch-local/crunch-dispatch-local.service
 copy apps/workbench/app/models/application_record.rb => services/crunch-dispatch-local/fpm-info.sh (55%)
 delete mode 120000 services/dockercleaner/gittaggers.py
 delete mode 120000 services/fuse/gittaggers.py
 create mode 100644 services/keep-web/s3aws_test.go
 create mode 100755 tools/arvbox/lib/arvbox/docker/edit_users.py
 delete mode 120000 tools/arvbox/lib/arvbox/docker/service/sso/run
 delete mode 100755 tools/arvbox/lib/arvbox/docker/service/sso/run-service
 rename tools/arvbox/lib/arvbox/docker/service/{sso => webshell}/log/main/.gitstub (100%)
 rename tools/arvbox/lib/arvbox/docker/service/{sso => webshell}/log/run (100%)
 create mode 100755 tools/arvbox/lib/arvbox/docker/service/webshell/run
 create mode 100755 tools/arvbox/lib/arvbox/docker/service/webshell/run-service
 create mode 100755 tools/copy-tutorial/copy-tutorial.sh
 delete mode 120000 tools/crunchstat-summary/gittaggers.py
 create mode 100644 tools/salt-install/README.md
 create mode 100644 tools/salt-install/Vagrantfile
 create mode 100755 tools/salt-install/provision.sh
 create mode 100644 tools/salt-install/single_host/arvados.sls
 copy apps/workbench/app/models/application_record.rb => tools/salt-install/single_host/docker.sls (55%)
 create mode 100644 tools/salt-install/single_host/locale.sls
 create mode 100644 tools/salt-install/single_host/nginx_api_configuration.sls
 create mode 100644 tools/salt-install/single_host/nginx_controller_configuration.sls
 create mode 100644 tools/salt-install/single_host/nginx_keepproxy_configuration.sls
 create mode 100644 tools/salt-install/single_host/nginx_keepweb_configuration.sls
 create mode 100644 tools/salt-install/single_host/nginx_passenger.sls
 create mode 100644 tools/salt-install/single_host/nginx_webshell_configuration.sls
 create mode 100644 tools/salt-install/single_host/nginx_websocket_configuration.sls
 create mode 100644 tools/salt-install/single_host/nginx_workbench2_configuration.sls
 create mode 100644 tools/salt-install/single_host/nginx_workbench_configuration.sls
 create mode 100644 tools/salt-install/single_host/postgresql.sls
 create mode 100644 tools/salt-install/tests/hasher-workflow-job.yml
 create mode 100644 tools/salt-install/tests/hasher-workflow.cwl
 create mode 100644 tools/salt-install/tests/hasher.cwl
 create mode 100755 tools/salt-install/tests/run-test.sh
 copy lib/pam/fpm-info.sh => tools/salt-install/tests/test.txt (76%)
 copy apps/workbench/app/models/application_record.rb => tools/user-activity/MANIFEST.in (55%)
 create mode 100644 tools/user-activity/README.rst
 copy agpl-3.0.txt => tools/user-activity/agpl-3.0.txt (100%)
 copy apps/workbench/app/models/application_record.rb => tools/user-activity/arvados_user_activity/__init__.py (55%)
 create mode 100755 tools/user-activity/arvados_user_activity/main.py
 create mode 100644 tools/user-activity/arvados_version.py
 rename apps/workbench/app/models/application_record.rb => tools/user-activity/bin/arv-user-activity (51%)
 mode change 100644 => 100755
 copy tools/{crunchstat-summary => user-activity}/fpm-info.sh (100%)
 copy tools/{crunchstat-summary => user-activity}/setup.py (50%)

       via  a4a17913e299851f0b5979189d36997a62ff43e1 (commit)
       via  edc2687671a2fec74304c6e00092034d50c8f667 (commit)
       via  d20342c56db7e148f793a29fd79619ce2e3f0243 (commit)
       via  4085665f87c82939961e55bf004ca47c03ca30ac (commit)
       via  1297d71125f5a694996147406edf38bdc913396c (commit)
       via  41305b5ac71cc9a306dc654c42c11ffcc4258a47 (commit)
       via  025639399f5c3c7c836109442cba71f38405149c (commit)
       via  2df04c08ce5a0c4e82345d3e57404c040bb6eee4 (commit)
       via  42d491072c6757a68cbc597961237a1566de4172 (commit)
       via  bfd4fc641457a4786a5c14b7ae574acc65e1f2b8 (commit)
       via  e98f4df4aa47fba614e2a078c0ab6d4213d96674 (commit)
       via  b979f80113c4f8a4c13c96b4679c28788c099333 (commit)
       via  c1a84bf6f6c570cc632a5ba8c6406543e2206e3a (commit)
       via  96afcc7682db1f1f67bcf4ae6acab54927418f1e (commit)
       via  a622b6980539db9563b6a92e0996197b61dae862 (commit)
       via  5280006cf7e9ce93db3390d76f7760353b10479d (commit)
       via  045e3127cb48845c7d988d01488c055f02ae2ec3 (commit)
       via  1ce3429c4005567a450a28f774e3f543010cd5c6 (commit)
       via  cc0e5b0c7c017b16afbfd5f0be5cb185290901fe (commit)
       via  9a0172e4aa5ef715db657a6d0d2cadbf6a54344e (commit)
       via  57c3fbfb0f75dc38be717d52f29abe5bcefea1bb (commit)
       via  6cd0e19a277812f302f46693d824cc17d17ed6b1 (commit)
       via  d71d4273d1f3d0b6381efafa649b81c6b4107cf1 (commit)
       via  2320fbe71cb3ed0e6684d56e3ce1c0300ce660b3 (commit)
       via  2cfb41d14010e26d97df93c4cf8ad00f0ac01701 (commit)
       via  f53363ea4642dd165decc6786b835979a1dc9f73 (commit)
       via  0861b6befc12dc9e7bf64c573f82b3f4b470ab53 (commit)
       via  985ece13dd7147f153c7a59c5b3665570c5943c8 (commit)
       via  8da2f73faeeecd81f52949451fe07a674ba47df6 (commit)
       via  e4a6240bf2ca163c36a4357ef0f80958c40bd39a (commit)
       via  1917992733f0a467cd068bedfa236efd6f4c37bc (commit)
       via  e1756a76e8c7fed496f513909bd2c295e24cf8ee (commit)
       via  9c139cc4e2f519e2deb3617918a9199b76c33f10 (commit)
       via  ae339cf6802741ea52fbe5cd8716306dcf99b021 (commit)
       via  684b81a42cb9290bde284723603d6e4dbfd7ad35 (commit)
       via  d77f9e6f8a14e14f477dfbf944914c78d0805e9f (commit)
       via  0137f9e3cd33fe676a862afd727563e2602e0984 (commit)
       via  6c1fd146c0b22b374f00ef94c961df8e1e1913a7 (commit)
       via  706c36ff5644bb675af36c15c5f30ef0adde9102 (commit)
       via  d0157c3b0749e35fbbc46a1d7f8d9c281bd58ad4 (commit)
       via  3d7250d6ec9e599d17582e8015a34de65661e58d (commit)
       via  a19b9565c586cb97cfc2777bbaf17b9fbf6d98af (commit)
       via  b8679688545cab79988c568b531d2496fc93cd6e (commit)
       via  c16c3f3e2d875f254bbc0bf86ebfdb97af1cc28d (commit)
       via  533f0c79e26d71f9ea24a82f7857ede35aa4d12a (commit)
       via  3aaefcb3c76ff470b475d950398d01255e87712a (commit)
       via  c59af50bc2f7a366cd12a8dd6fc7d7e3b1c32480 (commit)
       via  f1bc1872a9ead4f3cb1c23c79507870c1b0f7b53 (commit)
       via  3feaf72ad2a9a7b740bb3976f351f5020129eda4 (commit)
       via  209403e32bdd6164404240af2959de86a3c46165 (commit)
       via  40500de7ecb33a0f2197b2fe2449e6fc14b835a4 (commit)
       via  0ea8f67a0062444938ea38d0c354bce3503649d9 (commit)
       via  54849feb0cf30bd3d78f14f1a41e6bc464fb80d6 (commit)
       via  d5c034b4e90d3fba74e5b0a879d8af424023d7b1 (commit)
       via  2c8874c0625a2126813d4df7170076f95cdc7327 (commit)
       via  92086abf6fd3425b5c98e32a5d009734e7210fc9 (commit)
       via  8d6a62282e3026d70e25f824116e6d05838e6258 (commit)
       via  d913210ab6a77cc174a3d9e34062aa6adb542a43 (commit)
       via  fb88a62276c929dc009d96f8b4f1497ae20d811e (commit)
       via  32ad82494652c10e4dfdf7c61782ab6a7684aba0 (commit)
       via  06ebdde986c499a69b6b8faeb9b8f4ee01d19b04 (commit)
       via  9e75bd68c7a0171e85632b30f62ae19e923af096 (commit)
       via  41911de2ad09ab8f7621805bc199d77ca76f391b (commit)
       via  e43bfac54f9b807cfbb01e758fdab7a5d15a83a7 (commit)
       via  d5745d536d013a6731e0e6a872abe34d71f0995e (commit)
       via  2f8da8b76071a44b0ce28638cf5322b24e15c73d (commit)
       via  8d4900e4c7db1ec09aec4bd54e94052b5d2b5c57 (commit)
       via  653f8d8ba8d07a2d7081a924a67ee31b1a8ceebd (commit)
       via  8239993669bd614c2aaa1c014e870990df3a8354 (commit)
       via  d9a6e1a21c215def927b78231f9c10b388ac6b47 (commit)
       via  97c83ddd8852d5ca445527f9914a31a8976a9031 (commit)
       via  b14def1a3c07506ef1251223224e88d2d0a1805d (commit)
       via  6f27bbc6e8797f5faeeb110fa7702900a09813e9 (commit)
       via  91ef36eeea827569ec3745696e233aad0f8063aa (commit)
       via  1885a75ffade67a10f76a9bcac97d0978c072915 (commit)
       via  611bbeff666694a0932667b73a202fd3a30f3253 (commit)
       via  b2c1a6e50a3bfc8890c7c9197e49077b6032a087 (commit)
       via  b43a1bccda8980c6fcb9b3fbaad36b986c472028 (commit)
       via  2c8b44cdaefa4434eadbbe2cb24dabac8cc3bfa9 (commit)
       via  8d39d92808607b59f2335c1251c480ac56ba7016 (commit)
       via  01787232bc50632417b3e4bb9acea09e70472177 (commit)
       via  7f0be81629ed7d5413f22fc194504c9d9ec3ec13 (commit)
       via  80a90301263f46ebb7b26297093763882f2cf582 (commit)
       via  efeca068c2c25ee075ee8907a1937a5d4119775c (commit)
       via  3083521d8b6c83b0d80e4f63c56ee434ad8fa697 (commit)
       via  83898701e9c75661a240cadcf31f80cbccbb698e (commit)
       via  856fd8070951c570464dbcc2785c9be689d315b9 (commit)
       via  3ecc1fc9faccc10684b52d90314d7c2176316cbe (commit)
       via  55ee5b82e562869a558061b2afe6e971c2b45309 (commit)
       via  8fa0ae7ef4f9e8b9642cf0cf8c8eb5998daa9d21 (commit)
       via  a43455031646dec862ce2ddb7a4fd630caff2bed (commit)
       via  ebd40412f42b53c121134d40dff577b56f3c50c6 (commit)
       via  050106662d06b96996e4c33ea3e896bc154783c8 (commit)
       via  6f5431413448f52f3ae5c88553b7f7ee1532b9fd (commit)
       via  641876e22db7b51231415574366c76acd39794a5 (commit)
       via  1f773811a85c564bec4606d7ad05e7805fa41f22 (commit)
       via  e58d099d4a0fd73e413c4bb5229dd6069d4c1288 (commit)
       via  7b009edfb17684630028f2277efa5201f11350fa (commit)
       via  057cf02deb6812d3f8e57843dfe6e03c0bda7198 (commit)
       via  f46eee810702b655737007bdfecf91201cdb27ca (commit)
       via  104427eeb7fc75ee9362307582d13f4051548bec (commit)
       via  67ef4d23ece096e72da0ada75d4f2faa181df412 (commit)
       via  2ec206855a2e2969f83793dba2d3d649ea569bae (commit)
       via  1cd3e6f767a514662e55630bc21f4efaadd47ae8 (commit)
       via  d82331f5dc7860005cf88dab9a8f298ae402a857 (commit)
       via  9869b312368e2dd7a7156c7fbd53714f73a77ead (commit)
       via  c4f5d2f5e3f69258773dd3335137bb8b9edaa24c (commit)
       via  d115ba8b035bbc3c099c5aa8890a8dd2b61b164e (commit)
       via  b3fad38bb4fd356e5ce924e792be7f4113d1c746 (commit)
       via  f99e500a39b96f15c2814b742737b2f234766bbd (commit)
       via  45cc809dfeab1d603e80cec3d44770d7f5a7c8ae (commit)
       via  8816b40cc3d2ba4d5c91696eba32a09b85ac5abc (commit)
       via  15b6b485b5b412da574a9f8178010260b70eab74 (commit)
       via  c75f2e9b8a29bcdadcb092122f6d30e2930c08a3 (commit)
       via  7454769dd9bbfbac3af674dfff919c6d0bbc3896 (commit)
       via  3f4edc70aa8866f735f49b435434828d7b42c2ce (commit)
       via  4021b305ad0231f0cbd533a4d7b96d2437bc7037 (commit)
       via  99187b7a8e77008cf37efd2600e9fb49e1570943 (commit)
       via  8b1f33a3bdf2ce232ca300710649141fce5c71ff (commit)
       via  e3348e128e63014a1122ce42fb2a3eb23ed64c35 (commit)
       via  186d199ed06554cc5ddbdd7fc9d33622710fff88 (commit)
       via  1cfcb49baf325386a409a1fe549dfb61e4982496 (commit)
       via  acbdd9ad58e73cbf541a75fa273353bdc7a93dd6 (commit)
       via  848463f989bd4fcf9f7ba78ee597c4ee7064e000 (commit)
       via  b30db5651d5e27c88ef718be9db9b25e88064427 (commit)
       via  1dcd10a37c3dd8166ddf06053d895d546f8ad3d4 (commit)
       via  0c5e55d63d1f8b472845bd7160057ddea07044d6 (commit)
       via  11c4d6f005ad651313e615fa4058185732fbe35d (commit)
       via  76928023247b3350e33a380e62d9aff286f528ae (commit)
       via  9432f0013765366507329649a5b8e1ea6345aaa2 (commit)
       via  872584d6c225c5ca1d20dcf6b0fc74c3df6a1257 (commit)
       via  51d712fe2f3e46fe6b2358bb20196c6d4e4e26a3 (commit)
       via  e9eaf87eca20700a7230631eaf6b68852daeda5a (commit)
       via  7d94b1ed55350c01689ad048aee961b261263dd9 (commit)
       via  aa44987f259d1a01fe98f53d96ed32f1dc134e85 (commit)
       via  6aa85f4debd2acb62368c01633f21a328dbb76ab (commit)
       via  917330c81bb370225ccd0e051dbdca3d1870710e (commit)
       via  c36bac7d8ec9f7f579ddfdc06a328fa3668e80a3 (commit)
       via  cc9b9dac7be9c0bbf1d8e227466e9c71a7b3d35e (commit)
       via  6ee51615491f0d00e76389b40119fed2329eda7c (commit)
       via  aa1c0f3049f7b78e7590dde868b915bef9a7ebbe (commit)
       via  0cfb2b0646ad8129c82883717af7a51d28e6876a (commit)
       via  12be280ef9de36f154d11933ef4d62345017d6f5 (commit)
       via  c85b48eba118a277a9b2a34a1dbc9c05001a6c28 (commit)
       via  41a8a689f8d40f890914957c61d0251f61f7dde9 (commit)
       via  b95c8179505ecda2c0afab418d6c9614537a942b (commit)
       via  0fe238d1f4240d22b2c58838b03a7607656652d3 (commit)
       via  84bf8b982abf26da6bbbfcc65e2455ec2ea3906f (commit)
       via  e643759e12dcdd0d79a82e78de58669b956204da (commit)
       via  1884c6d206b9bc50af7e04e8027f948101361c9b (commit)
       via  34f5aff9a166c0e03564b607981284b6d4af9548 (commit)
       via  56240e53743237df9a190781a2220fa8d63d4b8e (commit)
       via  9d755d7dc0df6975e8b46cbaac6867abefdd138f (commit)
       via  c11f254a98e7caf437422d86eab38c7ba4f04096 (commit)
       via  f8b5741b4f39e01862837a553b3b9b24089c110e (commit)
       via  199ca290ab259ba21f798bb059bb808fe3b609ba (commit)
       via  40a4776f3e3b55944aa1267ac51a329d77218b18 (commit)
       via  2c3df643bc9effb76a26d56c6b4881856003c053 (commit)
       via  a555df85fe5647cfd83ee3f8d1b254f97fb77a18 (commit)
       via  baeef76a2b3b60fb3613d01b1df2916397e8c589 (commit)
       via  708f00954061975ed9f0385e2d4f6427a75d99d5 (commit)
       via  6bf9e1a4b5640f3cdd057810f0c9b8a945bb88bd (commit)
       via  b39f7a6141ecd5c53531b7705c0496623b4df9e9 (commit)
       via  6790e4990fa54d81decdd555beee337144d1fab1 (commit)
       via  0a84d58321c48b099dcb72f26948a8b5ece29c0b (commit)
       via  57f2cba0dfce2eca7dbb9b6f670f5472d52e77d8 (commit)
       via  6b7cdd93c4caeb35d105f818b40cc9e178b63a48 (commit)
       via  4f2cfd5d6bccc742d308585e7b4595b0de3db1a8 (commit)
       via  4bcecb9f823b4aaab8bd803aa4e90b3d8be9d92a (commit)
       via  aaa37d337cfab7eaa9b616cdccb2ea662dd6c7a8 (commit)
       via  bee9aff3bd6b69f81a0dd53fa7b4118d0eeeb0a9 (commit)
       via  998f990baafdd07501d801d063c7ed6b21feec6a (commit)
       via  6a613ba162b66beab17bcdf6192034d6ed335ad4 (commit)
       via  40a52eaf419c4a7c2f0e32cc87aaba29e0098439 (commit)
       via  395fa167d4be136cd34e9712d98f55d70872de45 (commit)
       via  41a24992268299cf05abbf723558b7b7f0d0b296 (commit)
       via  0024bcc58d6401c50b73c67b653535ccc4799db4 (commit)
       via  5d23eb939e64e4cf86dccb33aa24d9be3addf068 (commit)
       via  b7e1983d42b3ced751223d2b2b58c082f08bdad4 (commit)
       via  15d64feed20daa4a422ff9092615ac1e295d5ca2 (commit)
       via  185b8af696c553c0978f27e720c6924148af22fd (commit)
       via  228b24697f28441133c5d53cacf7bfe034ee5f56 (commit)
       via  5764b83d10b4969ac99ec8c4d716670604b20e82 (commit)
       via  e8e6434446cc88d7850f158d3c016d4039b25e81 (commit)
       via  82e63aa2aeaf2747a21058498f234f135d9867a6 (commit)
       via  e1937e57fe2c0e99b6b636049142cc7598f80231 (commit)
       via  9cdc2f320fe54562711d46ef7a9213697f2013b5 (commit)
       via  059e2806a7ac61a5b6849f755294b770ea91d0cb (commit)
       via  2d98a947ca12fa6b1391e8b882bbcfbe43970ee3 (commit)
       via  87ee4948cf07f2e36bffd948caa74c885b9927b1 (commit)
       via  b215c29447ea3b7c0c066cc4262308f26f6629fa (commit)
       via  8e60faf420f02d750bbaf7792343a95d2c2674ae (commit)
       via  17d37d113e9a0636ed8f12aa27bcdc9b04a166fa (commit)
       via  865690034f9018fad10ebb701cb8bf2015511962 (commit)
       via  f19253b56850687a74e51bcec16a1c066f1ec508 (commit)
       via  d06e6d2515ca2109f03c8c7ac9f63ddd0ec9823f (commit)
       via  473bb653e61fa0e3c825ba0f1f56c310e22e1ce9 (commit)
       via  47b3757a87151d9d7554f5e38c79e485558812c5 (commit)
       via  833220f67a5dfa5af83c71fdedde14702f4badcf (commit)
       via  077e8c70a8f541ae85cb98805ca6f48a693dd767 (commit)
       via  9adb8ea50fcf555c7ec73cb0924c869af2345f86 (commit)
       via  f69605f9427aa401b0f83c1e131e3c455eae4e38 (commit)
       via  dc421ad7078f9478d3a96a1250f89ffc2b13e897 (commit)
       via  fb329a132418fd54a027d30277f31c73443840ab (commit)
       via  13fa7a29e911e4c0e2a73375e8d312c9b54da8c2 (commit)
       via  293163eff8dffab007b0a420f2cc8e0a795ceb50 (commit)
       via  410412b172c36e3c66a7c2377c5488b94f9f6deb (commit)
       via  8d62d02834f289b30adafdeeb824ac03da5ff745 (commit)
       via  15aa3f9e8de69cb638bad461628f115f8a5bc276 (commit)
       via  0b28f60f34c4cd0106170c3730a5d27555c0e66a (commit)
       via  ad92a003eb3c4efdd3f880b5301033b755d6d247 (commit)
       via  fe3a451ad1d3613fd0953919fc44e5df18219fc4 (commit)
       via  3698dba58f052d275835eeb46c47de36a6673229 (commit)
       via  f6eb1f2b73bef0fa2f2d5e909ecc4bc64fc1e0b6 (commit)
       via  54778a698c7dcc30548f5d107a3d42b834ffb13e (commit)
       via  5d825f773a037ccf977918cd4dff866792390826 (commit)
       via  e6f3c9faab3f10d7efc7348be2ef85a6ea14766b (commit)
       via  cb5bace40cc3cac007ce5940a0f89a3e40952c43 (commit)
       via  3e646ecf38466b7b33cfb0548b043e6ca7b2225c (commit)
       via  c3d17077625d53e82948cd2c5eaf08c6fb1466bd (commit)
       via  397981dadc145225c691c8643b10527c9710f1fb (commit)
       via  38d30028fef230051217c29ba75d58a5f52cc716 (commit)
       via  e94e9b92438edc3c9142084ddeeedec3c9d21c8b (commit)
       via  a84890bb3791f3df021afc79ccfaf15698696e93 (commit)
       via  c4040df1bab985a8490d24ac9dd027de4c118a53 (commit)
       via  b699f6a0005d2d692b0394fb4bad26c46df6b498 (commit)
       via  aeec2b8abaa78a4f3b91bd177624d17ef9392380 (commit)
       via  e39c95a84525375bc401ffd9fe95baca9dcb3163 (commit)
       via  90b4ef014fd97787f26735083bad4c2ac1a174c5 (commit)
       via  95dbb33e42c6ad71151bd4b8c982569b7d90ae24 (commit)
       via  9429158c8ecf253a700c7eb4f87ad142a8e1522c (commit)
       via  4f8b6fc2dd343758b0ac2329db59fb62b0c6a736 (commit)
       via  e5fd3db8efdd8e6b8f65d81663ae65964b64c206 (commit)
       via  5a7fdde499ed5baa889a70fb9d1a0aef01eda22b (commit)
       via  2221946b2e7322f9680f5d9617ba98b620158c0d (commit)
       via  1008fd532fb9229b0fc0c1d9afb547bb6cfe4244 (commit)
       via  4513a54a9af3198be882d2f8f4be2260383efd7c (commit)
       via  801add452adb8804711ee10deff82243913fc9df (commit)
       via  34cb1075a924eb30f2f9d88ba74836043c60e73b (commit)
       via  e04c307f011f5ce3b42dff062e1394256f604037 (commit)
       via  dfeee281597cef5539f8c78bc249a6c9bfc19c18 (commit)
       via  b8de8845c856f7fe1232e5f048824211d1207ee7 (commit)
       via  27ab60e21b3cf9c908716ae74e63aba8e4cb6349 (commit)
       via  0e03883d091aa7b577bd4f9575ecd298861d4ce1 (commit)
       via  784cff6b13e4b95435e4a6f9c16e6fee66797375 (commit)
       via  f1f8e6488da533641dc83f157df1313c352ee3fe (commit)
       via  8a164579625de9f1f8be73b4c02c3e5ae1bfdc36 (commit)
       via  a3123a238eef6c3fc09434891284ef73e57cbf81 (commit)
       via  0dddb614432b0b7474b44b4a6f1b1ea7cd9c4e13 (commit)
       via  8795c42cfcd79dd0608e1ba580e5f8f5870851b4 (commit)
       via  24223057a8dd3a03f1c6457287cb12167c6b67ee (commit)
       via  4312333bb8bd27e0b910b430edee91329124b02a (commit)
       via  525583680b668412a1faa88e8306e27695178429 (commit)
       via  dad333f819ba1e4c7634527130634da40585f3aa (commit)
       via  ff6785340ccbe4436bc0ee3b81cf084b3456a15d (commit)
       via  a02f66383e58001b40c4cf732155397eb99d3207 (commit)
       via  7a1a5ddcb4af8a8f81511a1e36e1157a288a4677 (commit)
       via  8876199fb07f53263cd431a8a5cb15f4b9444361 (commit)
       via  359187c8fc0c0a72ba66222c61f19db0f617e3d9 (commit)
       via  e46e9a2a7560e6d349ed0ad128a9e6da4abd25f1 (commit)
       via  47d63870a11d6f026b2c7da84cd7572b110fc94b (commit)
       via  4bcdecf24604bab59211ec30d187c20daef4c602 (commit)
       via  646aabae7f0644c82b2c5cd36cfc98e3a674dbc8 (commit)
       via  f43a1f883619d2ec25439145b9b35fec1265b0cc (commit)
       via  5db3c780fe883be7d88b33a88ca0bc57deb868f2 (commit)
       via  1eaeddc8f1e15dd23220c4511b36e802daad3950 (commit)
       via  4878068a7b74974b053c619350f8bd58be029c9b (commit)
       via  e94ddba9d544b173e5b56b41c6ac76ea0b072a26 (commit)
       via  c95df2beb29c07c9be48f05a20c628ad437c142f (commit)
       via  aa2908778c80944e7141f4819a15c95b8dd4eeb0 (commit)
       via  8127b5d5dd999248731dd67c1c99e2045795e3e2 (commit)
       via  c6c2f3518bc745eed95b5f5b81db5d17db4366ff (commit)
       via  f8e0c7ac7a834733e189a906c2f9299f9ed010f5 (commit)
       via  244e797aed6f895dcdfe72ed90b31f3fe4cf6f85 (commit)
       via  94bece8122a20f8c06bb043779725fa319f1e3ca (commit)
       via  cf48ae2fab8908c3933f5d705f32f0188af656f6 (commit)
       via  3804a550dd9b1a3a91dd38cc6fecd35f4b268678 (commit)
       via  960ec481104a8d378b1e23be7faa8c10c5fad657 (commit)
       via  729b2762630b343b50aa1cb74733635ebcc52eb4 (commit)
       via  c0cbdeb1567d4a4f190a01d3fe89aa975e51e47b (commit)
       via  79393ed87b04db4c4c906890a4f9793f95efb27f (commit)
       via  9c68245e24eb0553c2bb56c4cfbee60bda469281 (commit)
       via  54e8f7060b89ff28b316883798ff6080fc3f166d (commit)
       via  c2565be8a4af26ffe798d9d83d4f4119046f83b4 (commit)
       via  885a103aafafc37a5ebc5052feca6453cd0f096a (commit)
       via  26d877228efa7b24e9c266748cf4c5edeafbc3b5 (commit)
       via  c20d55097c736db8881db8702ed89501020c2b5a (commit)
       via  7ce1e5122b6e913d90010254009c3c9efc5e1f60 (commit)
       via  6440951d141dbb7ec953a90f0bd5d7f47035707d (commit)
       via  9df2ccdfc085a8b33aed9568c433b7f6e2c24353 (commit)
       via  1021d0b3c6bef69d30871093ce535987f2e6fdfa (commit)
       via  2958a94fafbab941f8d6eb76bb2785b5c2868d3d (commit)
       via  33cd4c0daf9bb5134d14fc34389e19697fa2ea3c (commit)
       via  77bf8cb84c0271fb38dd3622930864d0d29eb2a7 (commit)
       via  146087a2dd14c5b564a860d77c88f6da07edaf94 (commit)
       via  ab9833a2d881e18f15bf6c9d39126afbcd0a48c9 (commit)
       via  0c98c5c9c5902a94dc614736a46b43fd43faba6e (commit)
       via  4e8c0dc4cf8077ef4805b5c3a329d856bb3a5261 (commit)
       via  52fa64f15a837ea4929183813ee34e68fea67640 (commit)
       via  18b6c49d69b8264273150cd29b2bf0b57c54e2a8 (commit)
       via  2af7b0336b2b92e38f6966b8bbc233c05704815d (commit)
       via  5d91989697c9954f346ce77b95a8a83f54ee6957 (commit)
       via  8109f3ba459c2fed2111fb72523637fa12b40ffc (commit)
       via  1f26b2f67d5f01c003c840be909bad6693cec045 (commit)
       via  cc6a39697017623caeeb7c494707408322067813 (commit)
       via  19f9424903f6b4997dc5a6c299faf70d5fdf4744 (commit)
       via  24203f1ee9af616dc3d2974465bc090dbb21eee5 (commit)
       via  a62f366d7c2b236aba0eceef37098a1fbe89c03d (commit)
       via  8d86e150e2396789cffa11279542b961c6f41650 (commit)
       via  764da69855e222afd3ba888c34e6fe10f3578aca (commit)
       via  f88b3d8cad3775806f1fc7ac8a382cba7e3be639 (commit)
       via  bdabe39ff5360f904de323cd850195237179dcaf (commit)
       via  119720800f986c4f09601ff2bf65f0309fab8a99 (commit)
       via  9deed27d5b61b2e51de1c70ae8baf06f18588e4d (commit)
       via  0924b8c3a5d500a480018c045264202ea6cb630b (commit)
       via  75ddf9c801c1212d9ac0e674aff348a0f591bace (commit)
       via  33f712764465c29c20acd025ad8421726df6423f (commit)
       via  3facf89bf048487ee718fe15d012b489f2d407b7 (commit)
       via  1baadb52c16c2d173a08845004cc33278e041c15 (commit)
       via  de961f4152f551692ac8a8b4392f971496273844 (commit)
       via  da8b6f7d9582d0829e1318f7f914730a47112e7a (commit)
       via  fa785db309d7b53905d327d6bfcab6445537a75f (commit)
       via  02d601eb27bd5b5217b9ee25869118eae406207c (commit)
       via  cc8cffec8e1c612b6be03f4446ab6beebf479f5b (commit)
       via  bf3624d8dc43bb98d9cf329657b2178181bdfb35 (commit)
       via  d356f441d55dfdc26a0ec3f1db344923b1e9b79d (commit)
       via  4634996f95b20da8bf0f523e4b901e2a83a43633 (commit)
       via  79455c249d7227627948b5b9ff121efd42fbc4fe (commit)
       via  08bf214e0170019e78c4c5496944ede12bf14978 (commit)
       via  4cc84d12503c936e1a32664cdee836215dc4705f (commit)
       via  45cabb9bf786f7d90fa7a9b89de0e40a871a793b (commit)
       via  2abdbcf641c2c6cb14764a3ed0d83849a4c7736a (commit)
       via  fa78e264ef585f02348f4f5c0a7183746a708a8f (commit)
       via  cabf89d1fd8b40a2624d101a95c6587bfdd91fed (commit)
       via  b77ee5df26c7483f63f18f116e5facf86d0512be (commit)
       via  726afb550fa67028a4c122ec8dd00838ef4723de (commit)
       via  7301e68e41869fd5931ef0b0f80890aa1220938d (commit)
       via  0dc94486b18b8797d3970eb9a982a7c9de3ada88 (commit)
       via  e7279d31e76f64a608c111b075906d46abf09c14 (commit)
       via  8fb2167d3f59ed408a413d90e727a39978a5c0a5 (commit)
       via  8d3f2e69e8427c8541d1796329d63ec84955e2c5 (commit)
       via  2a1a143938bfbfa9713c8f368898a8dda1ac685f (commit)
       via  5cefb12be01e9df6997f88696048ecb5d77d305e (commit)
       via  67d6cbddddda5fb295c23f31499e6a8316345493 (commit)
       via  15239a9f1bcd4897dd63df774bb8792a8055295a (commit)
       via  bc25855ab7a6aa0e75494f303889d8ca9fcc41f4 (commit)
       via  b096358dfbd438e89d77b6d4899817b82aca3ca3 (commit)
       via  a1305701c34508c80f638e2c7666b255019ba9a4 (commit)
       via  c9c0706ab97753cc8517096b66057d418908cd35 (commit)
       via  4f65b579bf1247a04d48a53b6cc5111c34e6a5a0 (commit)
       via  7d91fe636e1ce09697fdff28b43e4020df041f17 (commit)
       via  733143de395a2dd5949a529d6c3880f8e2b21470 (commit)
       via  bcb16d1825fd2e3105a51a2a2f9a119d71f33c8d (commit)
       via  ac82dcc51a03f0ac1e3b6fc8e9e65ab86872ac26 (commit)
       via  72f669602572eeccb7d251df669bcfbe63b137d2 (commit)
       via  22e3ec0b8647ba1236d1f0e0cd55dcdb4cca7702 (commit)
       via  b23a4f4386ae1fba418b419a6f428071fcbe2707 (commit)
       via  a463a62cdef50691f333c5c6f0d2860a542e138a (commit)
       via  1fb68cf0a5f6ad058a54d4f822385983b3504987 (commit)
       via  2e8b59d84088588205d1d649f689008bae631b6f (commit)
       via  a101ebf75507a0913d2ed324bf0efcec982b27cd (commit)
       via  71cc832bcd92fccf4f867cda3b49320cbb51785e (commit)
       via  6a67a1b576bb695e9b274c277b7220590da1a39d (commit)
       via  bbc1590401a1d15a4ca101df37415c9a2aa99ac9 (commit)
       via  6d419ba53592a3e60c8aef5be7bc99643ab3a6ac (commit)
       via  b27c53dedf632f614356305bc624befa5477b98e (commit)
       via  27992e62e71eb2ad4297c4eb3f4e787c4b000b90 (commit)
       via  2bf23f1aca56b8f3c5a330d38018a971dcb50fd6 (commit)
       via  5c64431a097bd2659127c653004c58203811f9e1 (commit)
       via  7874e2fb4eae63fa9bcadb2edff088213c0e7478 (commit)
       via  d6ea055606feac9b70a0419bce5405e5274633e7 (commit)
       via  76073b912b371c3940087897aecdce4430b7aa1d (commit)
       via  69274f95798389376e00de7f07a9822858c3ee62 (commit)
       via  154bfc562eafc642cc801f25b3c258e3846633ba (commit)
       via  4adf06fe21ff6aa9c08afee2268871c85394b217 (commit)
       via  819e06bd1bbff1ad4ecf250d621a807033907c29 (commit)
       via  d371cc9924105d7db4389edbe3a765e759a080f8 (commit)
       via  56524d5ff75c38af0df5f9bc7852dec1ac756f3c (commit)
       via  dd3b2b4e0a38c715107ae0ce404b275f96cf25f6 (commit)
       via  7499f61a2912cfdb1a316808fafa6e6ee77ee2e0 (commit)
       via  580d77ef4d6b244971bc26c649e017e912ca8737 (commit)
       via  e97a5d828bdf7cb9626d72efd94d3bcf718a18c9 (commit)
       via  53c3b64c9725710f5a39321554a904bd90d28c16 (commit)
       via  8d80af898f936d472e6240793be6090937febf64 (commit)
       via  ee50db7bf774f15c189935d4d2cb4d8c45333795 (commit)
       via  b15d39ec33dde9639f09bd1aff22fde7806aa24a (commit)
       via  625076c05698e37beb732850dc01248be9dbe7f6 (commit)
       via  5132075320db7a19e12a5454a70f894c30e917e8 (commit)
       via  56e2a953bff7183f19845415b5f8de36a664f5c4 (commit)
       via  f88624b9408ea31c25e128269305aff4c7dba2ce (commit)
       via  e7d06f9da1396e2ba69318b3bc8d3de690c6437a (commit)
       via  68eb70370ccf2ec7879146f3980e05019d2b67a1 (commit)
       via  7850378a1ffb342fba2ba197370e17d1b777326f (commit)
       via  535ff008c43648a7dadeb3f2176abc1540d4ac9b (commit)
       via  a58c3c3744fe4673cb8eb4a2b84946144bd2271e (commit)
       via  5b50385a801d8ff94136a3ad4bd8ab5c56175046 (commit)
       via  02f779feef0138420f8d7dc908eba040bc2dd904 (commit)
       via  641912ed2366dcd87c659fb73d8139e02cc6d05f (commit)
       via  c3944344c170a2b1014347cce3ea5388f2b8b79c (commit)
       via  a13547aec78a75da2174e083f6015280787cd597 (commit)
       via  f07a244584325cef746309070205c4039e4564ba (commit)
       via  dbaa58c1c806799435ca5741b3f61bc6b65b6569 (commit)
       via  e71aee834568e3bd058f21bff714621073fd5385 (commit)
       via  8503c026e63af2f396e82194e4ba24f1b49c1482 (commit)
       via  8142a4596bb2bf5a9966aa5e79ff587bf9e9e9a6 (commit)
       via  126139084160563c2b4fe3969461c40ecbbf6951 (commit)
       via  a3eefdae693e4195ca4f46b7873f3055f4a0d377 (commit)
       via  b7c4169e3d729ab4c45fde472e1da26d900f808d (commit)
       via  40fd03351707cd5892d40014cf366c7ec1834b85 (commit)
       via  2a3c78659dfdb264cd65ef6ababbd973062b4eae (commit)
       via  73f5326abbb4a7aa706e24382f742d6afc712172 (commit)
       via  a0398ebd1c50b1be2433c109af6bb0d263c54ea5 (commit)
       via  7e503a238d67b79a9f87e50086ca217d4873726e (commit)
       via  65ed3963aabde8a25b1c4c0bb9ca858edf76c277 (commit)
       via  799f8e333e7067cee0db0ee8bbcf45a56602d1f1 (commit)
       via  f317fc0d8e77ce950b6a650149600b0c8f6c38f3 (commit)
       via  eaf4338060c06006b451f79b4dba0ece41f7fef9 (commit)
       via  79bce4a71a58118a9003882e0ca9bbfb9d2957a9 (commit)
       via  3e029ed0f5c3774ac8e860cdcebf0619d924793f (commit)
       via  aabff656faab97bcc70bb3d4a5001068f7d395c8 (commit)
       via  3f5b1be0f705c8f1491fdca5e3b57982d97378fd (commit)
       via  c0eed4ee7f222f436beb8528e31ed344d6f9bd71 (commit)
       via  407fc461d20ece8b11b7b56f29a3caff3083ff8d (commit)
       via  e2d623bd4c686100772924b2b15ab808bbb147d0 (commit)
       via  d6598fd6339e6219a7103781433356dfde546527 (commit)
       via  6e56f24fcafcefbe6209a9ef53d784aef16c9711 (commit)
       via  7e358c01226d55a44ca7b6224f9c33c38510572b (commit)
       via  f4d0ea9ca3ef4badd38957f794d12474831cee44 (commit)
       via  e696a09cd482ddedeec742127297e90287012356 (commit)
       via  c986fef1ed1ad3967639f75d6e2d6ab0c63e4937 (commit)
       via  a5dbdd1dbcdfcb835e7c1fe741e4c00927177404 (commit)
       via  6350ddac78dbd2b29e5dc4117fd57300f7f8a098 (commit)
       via  62f82658619bd59644b4bdac6b83be8fe87aca0d (commit)
       via  e6f14dd73771fffb1f205729f0755623538c5590 (commit)
       via  62403e0d1d95f8526d17222a66356382e2d4b028 (commit)
       via  f0cc3c391e64799ba18e61e069487ca841195093 (commit)
       via  3f18ac306f64ef81a9173c6ae452a428ac816309 (commit)
       via  ab439e74c340896f52629996f54614ea190f0f5e (commit)
       via  d9fbc49d0ea6fea5890d10f9dad2dc53ce4a79d7 (commit)
       via  b6cee2725115e8740e3f2569a2e1ea023aa189e4 (commit)
       via  224f4793b7c147cb3ef9a261e3a60cddb557e1f1 (commit)
       via  c8a640d527db530875b52c9975a34709a2f32f7c (commit)
       via  72298b61214bb31f0522ff966acd4d42ec3d131e (commit)
       via  8a73021bbc704581db9a71d7d6a3332d89329bd5 (commit)
       via  b1df618b0c33eccc4ab15d89aad4a10fbf245993 (commit)
       via  3c893d29ad7a9acda0c25b47fd0c9ba5a4a5193a (commit)
       via  5aa318268437efe1e1a6dac3ff139a0b698f5da5 (commit)
       via  98bd6c43fca91b76d528c8ed5b83c655c86ffe3c (commit)
       via  86ed259ee56afd84d169bd3ed275fee5820b3d8b (commit)
       via  3491f49a911ef8cf27a5b055dabf854074c0118d (commit)
       via  3ebf3b7068dc55a8458ea12c01dee1e88a468b84 (commit)
       via  bf8027f01cf079bc6d18de884de3e484ec2bf1b9 (commit)
       via  5dafff1ed428fc1018e0ced86e1a07406d7e57f5 (commit)
       via  0e62f44f65bf70d398b2150923b65eb406d53307 (commit)
       via  94a7479527652cd513a35f75e1da1798d9fdc213 (commit)
       via  04c8cb55335a894a0a354d06da31168ccb504e83 (commit)
       via  13035b7fa370e0f81a4139f19276543c6f86b647 (commit)
       via  3489a9b5ce083cd17dae6d50c8c5ceeee29b074b (commit)
       via  ffae5e0d4427cf6d41b4f1d270c0cdc29385e2ae (commit)
       via  8f9a16c4e784b40e8661174fff32564e8c1c7f69 (commit)
       via  7f4da9388e3d5ec8f38f6d6408916d1d46dfb10f (commit)
       via  99df0022e64521d35225c0ddd531920e62ddfffb (commit)
       via  c4bee0bdd8866a474dd2bd71f132960681ab3bb2 (commit)
       via  c9bfe925c507a9847a2b8288f28b2c73c7c1e47f (commit)
       via  bdeca9098f356a4b2b088a3cf4c9276bb6cd5bdb (commit)
       via  b07b70d9024e7203f4cae3bbc526fc36e9cca19e (commit)
       via  301e3064182f1ac65fce6e9ee9b2d30443cf5e2a (commit)
       via  1e3dce82b4f2f5a8c0d3a75c84bd7a18c4dd82dc (commit)
       via  21a8bf8d7f82bfd4f59afbce64d52eabe621151b (commit)
       via  4cfab58ae5b052884e1a42277a45aab23f3b1798 (commit)
       via  3b6e82324391c86b1ecbd11ced7c12f8fcae8db4 (commit)
       via  5aca412951f88d5114b577782e502a3457205d4c (commit)
       via  9314e5dbcf51231eba0deb7e14522a281da22925 (commit)
       via  b4f1461e394cc1fe0b7b5f9f56b96121cc46ff2e (commit)
       via  9b7a2816e223bd0cae3c9c69cf70afa74748a07d (commit)
       via  274ca75e0b5277d6d591b45e29b1a2c9185bed5a (commit)
       via  237ebe3735eb8c4622c602d02c1a6119cff42b6b (commit)
       via  1771152da97200b038378666457d18679f4c8cd7 (commit)
       via  dafd68e639a416fcae216c639c6e38beab53b214 (commit)
       via  49a89ce984eb69ef4316882e91dec652dc353e39 (commit)
       via  3ee2186cb06b822f113696ccb24a78b79269d318 (commit)
       via  47aa52f1b343c93e09908b69d40bf8b389e8b15c (commit)
       via  472fff42d6105a4457deeb1579e9d14caffc82dc (commit)
       via  8bad7194a84fd1973f9b19d68db3dd56cbca3162 (commit)
       via  21dc468b7c86996d05f019650d2b7b3e472c5ed5 (commit)
       via  0f3db3d5f1bc976f38f6eed05c236ece79b7f876 (commit)
       via  51d7a5b2a23074a130aa6dd74cbaf5f335920769 (commit)
       via  36e3b4021e376e74806df16816bd3f207ff37ecb (commit)
       via  5c5ac412b722025d1af37f81bea60a4b503ce6aa (commit)
       via  64d38dcbfb53c240a99523e250ad576788954a56 (commit)
       via  8f8329e7d99e9d1c0e753fb26bf4dc1e76828017 (commit)
       via  513865a8e58b8adf28c17f12093053cdb62cfa71 (commit)
       via  0036a0a5755f6c0fb5c7747c7d4442c0972b696c (commit)
       via  a5b73a1a47bed348098dc116950a01b77c04c208 (commit)
       via  72beb46ad804361a8ae012b1bc4475480912d8a8 (commit)
       via  6ed2e2c51fe463bfcf1b484d764af5bf47d416ad (commit)
       via  3e068db7568de699f057e4e1ae2ea8c9a32b88a2 (commit)
       via  201812edc08fc1fd11cc6635e2224adad2b913f5 (commit)
       via  8a00acc17403e7836b88b1e9e66b4ff47d5505f2 (commit)
       via  b1a9b18e4bd1691294b60a90c595bccd29725ca7 (commit)
       via  a528347f7edc85282c3f618fbae4030e9f9da226 (commit)
       via  3241db378301b3d507e928776d5e3e511c38a998 (commit)
       via  279388ea25c8f464f31b62ade9bc09c44e8f9078 (commit)
       via  f7f5dfb456c1ddb6db63cf6e6a79e5d468d20a20 (commit)
       via  71c57454fc3adf2d63db8b3cb1d0e8ecdff5c93f (commit)
       via  16919ef3f156ee7cc99fa78af3701f1d8a66ec25 (commit)
       via  c1bd1ee9ed5c36a3af524178e876a9b2255ab5f0 (commit)
       via  fbd40a96ea616d8042db23371083ebf80684825f (commit)
       via  ac4599592d265dc5a922ec8f468d46cfe7de52e2 (commit)
       via  a730ff3281e2a4eff04240e6233c9c13ac8fdbfb (commit)
       via  b30659d514ce281209fa7b99863413832fa8d44b (commit)
       via  b6462cf67d9c3a0d9eb6d2d6997b2a88ece8ad6c (commit)
       via  98db65de63c9e2acfeae6636ccc619171635bda0 (commit)
       via  8a17791b5f16b785eeaff86051dbcce84699ceac (commit)
       via  b35dfa1f2b6c2fe57b7bc8a6e107425ed4e44f2a (commit)
       via  09ff850dc6e3e8f10d7d96adfc02674222f7aa9a (commit)
       via  76182f26191190c405077106becdde149c0ad7c5 (commit)
       via  b521d2c5254e439e23cd750f86d55eadffb3e4b9 (commit)
       via  64eac5879fe80f9ad52665421962740390a14eee (commit)
       via  bcee68ee657af1591d1ae0624e2d12029b0b92d5 (commit)
       via  0b38c1d85c04e15ec45dcaaf63882c01dd3f91d7 (commit)
       via  cf0dfaa4494d591bb34c2fa23589061f4d89d0aa (commit)
       via  201e2b7e3965aebc87de3139d31b8f14a312ec6f (commit)
       via  0ff4ed45a7ab1730118eadfb92ddea7d332f0328 (commit)
       via  4355586821d71fed6a3fe95fea69f548797f77d8 (commit)
       via  509a6d6764aae8b8bbe5b32c21c8f64a49d02ad3 (commit)
       via  b108bdfa0f3c74239fa565a1d14db945eb4dcf18 (commit)
       via  bc11ee32eeb31c63a3fb99819087d2def0988789 (commit)
       via  a5fef23f2863cd0183ff596f4579110e2ddb3b3d (commit)
       via  9e9142058cdee68ad567836799883b1aa6962bbd (commit)
       via  db13716484018404860275de75d278e0aaa08d8a (commit)
       via  4e6985fea736b4a46537005bf853de80be1b013a (commit)
       via  cf16a3c479626c18e408a12c18c5a6ed547f85dc (commit)
       via  da85d6516630d06ae3c34b4a52dc5ddff9fd5ace (commit)
       via  baa1f256924655d67b704f35981e9839743fab99 (commit)
       via  0ea4bd88c687a6c7c5067bdd05fb1e6f7e8fb8b9 (commit)
       via  8991b43990aa7a77edd78f165114b93a6a207985 (commit)
       via  ab00a0a441ab4ff6dccfe94e03db1705e25bfba9 (commit)
       via  ddae1b57f077d8a7c091b3cdf9ecaa562703fb3c (commit)
       via  2b4eccc7386b33d2de4a06f5d8da18cd94391662 (commit)
       via  f3e3a6cc4b72120f856e14f3039b1c0c1f0326bd (commit)
       via  5ce6d49b5a632b8e846fb0d794444ecd39f74fa5 (commit)
       via  27566b089a00a4038fceb320175b37fcb0e77033 (commit)
       via  87977ae72b8cfded3263b109caa5245fa1abd74f (commit)
       via  8661ab4aa19494699915a9a9c1c492345d367855 (commit)
       via  bee95c1cdbc3859f47a0a95940680ebaa2a4c9a5 (commit)
       via  ffe94bef9cd17abb522d7fabb32326405d466a94 (commit)
       via  b36ffab0228e53226614f7d33e4a8e3921d0256f (commit)
       via  ae50c333f57298b5d4b81229476cd990aab1dad5 (commit)
       via  ecc2f49233c0b52820e856ba0b18e4123d99d228 (commit)
       via  434dee9ff1b42d7169fbd9368263e6a0f5c40bed (commit)
       via  5ce67dcb90e196227d920c52fc1a7256e39ede92 (commit)
       via  d3b6bdd6ef2b543c607bd7c3cdf9df5c74e90dc0 (commit)
       via  83d9f52a85cd19e9821d54b3d6ec9efdff337777 (commit)
       via  065aa362326aae3ec05958436053c72299bdad7d (commit)
       via  be28c5f528a93ee32eef4c1dc2d0872cb718b29f (commit)
       via  4706c89f091563cc56a6d4f819e025850031a009 (commit)
       via  43da0e7ce859cb8ed3385417a2fc97a36cc688e6 (commit)
       via  a46ef7496b83b2778de8db36e4948b55dddf3754 (commit)
       via  92ff0d8081ad46b1c7e7c3407745d6b9cde50a1a (commit)
       via  ecff7e34ea7d5e8321c2821cae476355bffbc248 (commit)
       via  6d827e6be83d9b3129b4bc7a812d43d2ca874174 (commit)
       via  d67b634b9afe9bebeaef461dfdd2edfa4e5740fd (commit)
       via  5895b2710b4331109a0056275e8b046a53b5ba06 (commit)
       via  add09f355520b2bd1214b8c74d5a8d6c8e76dc88 (commit)
       via  62b3435fc45adff01541c508be22e10be83427ce (commit)
       via  1617202c337078fb94ea19893c73061983be94ad (commit)
       via  3e975aa25c141ccd3f08335906d96d9ff7035bf2 (commit)
       via  81ff58f4addd05346161a9b44648d1ab31e027bc (commit)
       via  5c4b585cd03d6fba1779113f7cba6b34e0c526b7 (commit)
       via  f9e6c9f5e30cbf0fc3d6f9981b6e3673d603f3e1 (commit)
       via  505c8fa50631201e289cc55230d46fdf52fa2055 (commit)
       via  a7631a1ccb6e2a6925d00a06562e171c4ce4ea2f (commit)
       via  8a41cc44ee196c9347785baa476a370abe77c75c (commit)
       via  b4091adb7ac1a85de6ae1f18895e9d8f9da5d441 (commit)
       via  bd8bdd90055d61263eff5bdb9a953c57319aa83d (commit)
       via  67207bade066ddf25b5d0056a5df6201e7ecab2c (commit)
       via  3e38df9fabcbf421ef0b0aac2e82f92373c0e70f (commit)
       via  47833c68da26e2dd1fd65784cb56a352503dbcb9 (commit)
       via  7af2ada1dec46b67b80d3c89a8f961c17525dd02 (commit)
       via  4de0821a28d54153c6046655d4a2d8f57da7e005 (commit)
       via  17941a42ec6772f67dc7b451039cd706301f1bdd (commit)
       via  d51eee69da0b9b572b5319d3429267bedb2fb3ae (commit)
       via  09f4d9f7fd5fc0518aa7d614c7f061c0b8f7d5a4 (commit)
       via  46fefa537c9bf8c2835a5ae26bf77a8dfb3fe10f (commit)
       via  b000158ff1d8083d3179614e99f4a26bf66eeae9 (commit)
       via  d94f8f7d99dc2ea08db259e150269a2be7396ba5 (commit)
       via  7a7a1395490eb9b9789b79f88a77fe709a898feb (commit)
       via  0e4b898a5d6735be7e0ef902dc185f037428e6f1 (commit)
       via  27064ba138bfadd672ff71b32769cb357d051e01 (commit)
       via  a74931f3bb276c84ce164802b44b4486d1a9b54f (commit)
       via  3b1387f71c5e881f062cf620dbd0fb2634a5dd40 (commit)
       via  1a51cf3bb6753fc34c3cc8556ba656280d7b6b88 (commit)
       via  75eb37bf5ace53c447c8c6cbf069883fd1c47147 (commit)
       via  84d176d4e66d3eea140220ac8ec127ceba0f34a8 (commit)
       via  deac9af545f0da1903e41b9f1ac76b297232a643 (commit)
       via  36ccf5e18984c80f3903c08fec59e064fbbf4be9 (commit)
       via  6a4b8910332f7fcf9a5b0784467a6bfa0a702c70 (commit)
       via  e1c81c58c6810a1a84d71855330097c2fc4e2c3e (commit)
       via  29607f728e57e22021b827a6ec34daa8aaa04f5a (commit)
       via  d6897f2bee374d4a71fb96f0a794fba598174407 (commit)
       via  26519f015ebbd7e7b4ef288d4e89d877ea05c0ec (commit)
       via  2fc9d1ac9dbb3557541c449820f4bba4cd4b7313 (commit)
       via  29e7c39df5bbe3eae5007b0e56eb93aace7728bd (commit)
       via  8249ba28de8143ae6b662b44cb0d823d7f2fe890 (commit)
       via  20dad0340d1230f041824afb4f8c19c848ba16f3 (commit)
       via  00e16fb980a0a234d5944ffb06c5614d19280921 (commit)
       via  9ef2a81fb159c8b4aad625cd4a45fd89b21e3ac6 (commit)
       via  614145d096375ae18c7020e8f9205eaa2a1d0d39 (commit)
       via  1f798f8be40a6b4abc6bcc2393302fc4d3062640 (commit)
       via  2094173f347a22f32e8da4590bb6594dad5d7ebd (commit)
       via  a644bfd36efe4d0ea885d3a1c20809deb748e42e (commit)
       via  e28343a194a91f708ec8da8c4dc8eb956fecb85d (commit)
       via  4a7d0843a42986501fbfd18ba7ab96fc8669d1af (commit)
       via  2160f72372422c1970a3effb9ba6961b94da318d (commit)
       via  965b6fc27b3eaf3a812132cea093b03b02f35896 (commit)
       via  1de49feb938cc265ec90786c22a1456237796aef (commit)
       via  0371c7348509369fe338951b0df86325819622d5 (commit)
       via  e49cf0412503926eccfe829f2135c5a072b6acc9 (commit)
       via  d3fbb6b33a5b4a55dda969c7e7360cc31e1de0f6 (commit)
       via  f6d0a07763cbffee6a03864d20b8d753b9aefb82 (commit)
       via  60bbffb69b908f7a1146fc0c1904aae2775cdf1e (commit)
       via  27babdaf446a70fdd7742104846de9afd9b75b22 (commit)
       via  7556d0ea3265a898d0170bf32bab82e8d9920dde (commit)
       via  7b6a085a92e78787a15a34ad8e536444ad230552 (commit)
       via  658f6be33e100b4cefd3ca7c332fe13970d6a245 (commit)
       via  e5533f58701d271b7362ac2527f925402b0be1b0 (commit)
       via  33b27555b25e70a0d37c5a8267450fddf3bd81b1 (commit)
       via  409690acd4085f0c4ec764034f09c26a0b555f0c (commit)
       via  7e47f5aaebcd7e4166e5e647f7b59af0914825bd (commit)
       via  85864f3fbee06c2dd0729d7c63eddde7f935746e (commit)
       via  20cea53c48260a0cec3d588c2af520b27433b8c1 (commit)
       via  929bf2ca704f43685c58da9fd60dceac037d3593 (commit)
       via  dba9e46d852b50d2d72bd9619667f69637370fd7 (commit)
       via  2ea2aedaaadd0fcd204fe891df8b2ab56acf7dee (commit)
       via  635ea4273130253cba3e00f4b0dca7d7734a741d (commit)
       via  337b055122485e669cc601c91a78f8fdd2625b3e (commit)
       via  ddaa9596ebf94aa7b6ee720e06ceccd2d7dc43fc (commit)
       via  2d046b9d2f27779f1e74e951fd7108dd88ba57c3 (commit)
      from  20649f2d57f8e5c8bddfb672c164b7a96f75efab (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit a4a17913e299851f0b5979189d36997a62ff43e1
Author: Tom Clegg <tom at curii.com>
Date:   Tue Jan 19 15:42:50 2021 -0500

    16306: Hide "easy install" option from the install docs.
    
    To be un-hidden when it is fully implemented and usable.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/doc/_config.yml b/doc/_config.yml
index 5386e8797..75a55b469 100644
--- a/doc/_config.yml
+++ b/doc/_config.yml
@@ -208,8 +208,6 @@ navbar:
       - install/arvados-on-kubernetes.html.textile.liquid
       - install/arvados-on-kubernetes-minikube.html.textile.liquid
       - install/arvados-on-kubernetes-GKE.html.textile.liquid
-    - Automatic installation:
-      - install/automatic.html.textile.liquid
     - Manual installation:
       - install/install-manual-prerequisites.html.textile.liquid
       - install/packages.html.textile.liquid
diff --git a/doc/install/automatic.html.textile.liquid b/doc/install/automatic.html.textile.liquid
index 049bf6891..79e850538 100644
--- a/doc/install/automatic.html.textile.liquid
+++ b/doc/install/automatic.html.textile.liquid
@@ -9,6 +9,10 @@ Copyright (C) The Arvados Authors. All rights reserved.
 SPDX-License-Identifier: CC-BY-SA-3.0
 {% endcomment %}
 
+{% include 'notebox_begin' %}
+This installation method is not fully implemented, which is why this page is not yet listed in the "table of installation options":{{site.baseurl}}/install/index.html or in the left nav.
+{% include 'notebox_end' %}
+
 This method sets up a new Arvados cluster using a single host/VM. It is the easiest way to get a new production cluster up and running.
 
 A single-node installation supports all Arvados functionality at small scale. Substantial workloads will require additional nodes and configuration steps.
@@ -24,7 +28,9 @@ You will need:
 h2. Initialize the cluster
 
 <pre>
-# apt-get install arvados-server
+# echo > /etc/apt/sources.list.d/arvados.list "deb http://apt.arvados.org/buster buster main"
+# apt-get update
+# apt-get install arvados-server-easy
 # arvados-server init -type production -cluster-id x9999 -controller-address x9999.example.com -admin-email example at gmail.com.example
 </pre>
 
diff --git a/doc/install/index.html.textile.liquid b/doc/install/index.html.textile.liquid
index f16ae2dad..1b27ca6ed 100644
--- a/doc/install/index.html.textile.liquid
+++ b/doc/install/index.html.textile.liquid
@@ -25,7 +25,6 @@ table(table table-bordered table-condensed).
 |"Installation with Salt":salt-single-host.html (single host)|Easy|no|yes|no|yes|yes|
 |"Installation with Salt":salt-multi-host.html (multi host)|Moderate|yes|yes|yes|yes|yes|
 |"Arvados on Kubernetes":arvados-on-kubernetes.html|Easy ^1^|yes|yes ^2^|no ^2^|no|yes|
-|"Automatic single-node install":automatic.html (experimental)|Easy|yes|yes|no|yes|yes|
 |"Manual installation":install-manual-prerequisites.html|Hard|yes|yes|yes|no|no|
 |"Cluster Operation Subscription supported by Curii":mailto:info at curii.com|N/A ^3^|yes|yes|yes|yes|yes|
 </div>

commit edc2687671a2fec74304c6e00092034d50c8f667
Author: Tom Clegg <tom at curii.com>
Date:   Tue Jan 19 15:32:15 2021 -0500

    16306: Fixup test.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/cmd/arvados-package/build_test.go b/cmd/arvados-package/build_test.go
index 9f002b535..b4ad68b1d 100644
--- a/cmd/arvados-package/build_test.go
+++ b/cmd/arvados-package/build_test.go
@@ -32,6 +32,8 @@ func (s *BuildSuite) TestBuildAndInstall(c *check.C) {
 	}
 	tmpdir := c.MkDir()
 	defer os.RemoveAll(tmpdir)
+	err := os.Chmod(tmpdir, 0755)
+	c.Assert(err, check.IsNil)
 
 	cmd := exec.Command("go", "run", ".",
 		"build",
@@ -41,13 +43,16 @@ func (s *BuildSuite) TestBuildAndInstall(c *check.C) {
 	)
 	cmd.Stdout = os.Stderr
 	cmd.Stderr = os.Stderr
-	err := cmd.Run()
+	err = cmd.Run()
 	c.Check(err, check.IsNil)
 
 	fi, err := os.Stat(tmpdir + "/arvados-server-easy_1.2.3~rc4_amd64.deb")
 	c.Assert(err, check.IsNil)
 	c.Logf("%#v", fi)
 
+	buf, _ := exec.Command("ls", "-l", tmpdir).CombinedOutput()
+	c.Logf("%s", buf)
+
 	cmd = exec.Command("go", "run", ".",
 		"testinstall",
 		"-package-dir", tmpdir,

commit d20342c56db7e148f793a29fd79619ce2e3f0243
Author: Tom Clegg <tom at curii.com>
Date:   Mon Jan 18 16:33:16 2021 -0500

    16306: Remove old bash scripts.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/cmd/arvados-package/docker-boot.sh b/cmd/arvados-package/docker-boot.sh
deleted file mode 100755
index 39a8a56c8..000000000
--- a/cmd/arvados-package/docker-boot.sh
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/bin/bash
-# Copyright (C) The Arvados Authors. All rights reserved.
-#
-# SPDX-License-Identifier: AGPL-3.0
-
-# Bring up a docker container with some locally-built commands (e.g.,
-# cmd/arvados-server) replacing the ones that came with
-# arvados-server-easy when the arvados-installpackage-* image was
-# built.
-#
-# Assumes docker-build-install.sh has already succeeded.
-#
-# Example:
-#
-#    docker-boot.sh cmd/arvados-server services/keep-balance
-
-set -e -o pipefail
-
-declare -A opts=()
-while [[ $# -gt 0 ]]; do
-    case "$1" in
-        --os)
-            shift
-            opts[os]="$1"
-            shift
-            ;;
-        --shell)
-            shift
-            opts[shell]=1
-            ;;
-        *)
-            break
-            ;;
-    esac
-done
-
-cleanup() {
-    if [[ -n "${tmpdir}" ]]; then
-        rm -rf "${tmpdir}"
-    fi
-}
-trap cleanup ERR EXIT
-
-tmpdir=$(mktemp -d)
-version=$(git describe --tag --dirty)
-
-declare -a volargs=()
-for inject in "$@"; do
-    case "$inject" in
-        nginx.conf)
-            volargs+=(-v "$(pwd)/sdk/python/tests/$inject:/var/lib/arvados/share/$inject:ro")
-            ;;
-        *)
-            echo >&2 "building $inject..."
-            (cd $inject && GOBIN=$tmpdir go install -ldflags "-X git.arvados.org/arvados.git/lib/cmd.version=${version} -X main.version=${version}")
-            cmd="$(basename "$inject")"
-            volargs+=(-v "$tmpdir/$cmd:/var/lib/arvados/bin/$cmd:ro")
-            ;;
-    esac
-done
-
-osbase=${opts[os]:-debian:10}
-installimage=arvados-installpackage-${osbase}
-command="/var/lib/arvados/bin/arvados-server boot -listen-host 0.0.0.0"
-if [[ "${opts[shell]}" ]]; then
-    command="bash -login"
-fi
-docker run -it --rm \
-       "${volargs[@]}" \
-       "${installimage}" \
-       bash -c "/etc/init.d/postgresql start && /var/lib/arvados/bin/arvados-server init -cluster-id x1234 && $command"
diff --git a/cmd/arvados-package/docker-build-install.sh b/cmd/arvados-package/docker-build-install.sh
deleted file mode 100755
index 4fdcccbce..000000000
--- a/cmd/arvados-package/docker-build-install.sh
+++ /dev/null
@@ -1,133 +0,0 @@
-#!/bin/bash
-# Copyright (C) The Arvados Authors. All rights reserved.
-#
-# SPDX-License-Identifier: AGPL-3.0
-
-# Build an arvados-server-easy package, then install and run it on a
-# base OS image.
-#
-# Examples:
-#
-#    docker-build-install.sh --force-buildimage --force-installimage     # always build fresh docker images
-#
-#    docker-build-install.sh                                             # reuse cached docker images if possible
-
-set -e -o pipefail
-
-declare -A opts=()
-while [[ $# -gt 0 ]]; do
-    arg="$1"
-    shift
-    case "$arg" in
-        --force-buildimage)
-            opts[force-buildimage]=1
-            ;;
-        --force-installimage)
-            opts[force-installimage]=1
-            ;;
-        --os)
-            opts[os]="$1"
-            shift
-            ;;
-        *)
-            echo >&2 "invalid argument '$arg'"
-            exit 2
-            ;;
-    esac
-done
-
-cleanup() {
-    if [[ -n "${buildctr}" ]]; then
-        docker rm "${buildctr}" || true
-    fi
-    if [[ -n "${installctr}" ]]; then
-        docker rm "${installctr}" || true
-    fi
-}
-trap cleanup ERR EXIT
-
-version=$(git describe --tag --dirty)
-osbase=${opts[os]:-debian:10}
-
-mkdir -p /tmp/pkg
-
-buildimage=arvados-package-build-${osbase}
-if [[ "${opts[force-buildimage]}" || -z "$(docker images --format {{.Repository}} "${buildimage}")" ]]; then
-    (
-        echo >&2 building arvados-server...
-        cd cmd/arvados-server
-        go install
-    )
-    echo >&2 building ${buildimage}...
-    buildctr=${buildimage/:/-}
-    docker rm "${buildctr}" || true
-    docker run \
-           --name "${buildctr}" \
-           --tmpfs /tmp:exec,mode=01777 \
-           -v "${GOPATH:-${HOME}/go}"/bin/arvados-server:/arvados-server:ro \
-           -v "$(pwd)":/arvados:ro \
-           "${osbase}" \
-           /arvados-server install \
-           -eatmydata \
-           -type package \
-           -source /arvados \
-           -package-version "${version}"
-    docker commit "${buildctr}" "${buildimage}"
-    docker rm "${buildctr}"
-    buildctr=
-fi
-
-pkgfile=/tmp/pkg/arvados-server-easy_${version}_amd64.deb
-rm -v -f "${pkgfile}"
-
-(
-    echo >&2 building arvados-package...
-    cd cmd/arvados-package
-    go install
-)
-echo >&2 building ${pkgfile}...
-docker run --rm \
-       --tmpfs /tmp:exec,mode=01777 \
-       -v /tmp/pkg:/pkg \
-       -v "${GOPATH:-${HOME}/go}"/bin/arvados-package:/arvados-package:ro \
-       -v "$(pwd)":/arvados:ro \
-       "${buildimage}" \
-       eatmydata \
-       /arvados-package build \
-       -source /arvados \
-       -package-version "${version}" \
-       -output-directory /pkg
-
-ls -l ${pkgfile}
-(
-    echo >&2 dpkg-scanpackages...
-    cd /tmp/pkg
-    dpkg-scanpackages . | gzip > Packages.gz
-)
-sourcesfile=/tmp/sources.conf.d-arvados
-echo >$sourcesfile "deb [trusted=yes] file:///pkg ./"
-
-installimage="arvados-installpackage-${osbase}"
-if [[ "${opts[force-installimage]}" || -z "$(docker images --format {{.Repository}} "${installimage}")" ]]; then
-    echo >&2 building ${installimage}...
-    installctr=${installimage/:/-}
-    docker rm "${installctr}" || true
-    docker run -it \
-           --name "${installctr}" \
-           --tmpfs /tmp \
-           -v /tmp/pkg:/pkg:ro \
-           -v ${sourcesfile}:/etc/apt/sources.list.d/arvados-local.list:ro \
-           --env DEBIAN_FRONTEND=noninteractive \
-           "${osbase}" \
-           bash -c 'apt update && apt install -y eatmydata && eatmydata apt install -y arvados-server-easy postgresql && eatmydata apt remove -y arvados-server-easy'
-    docker commit "${installctr}" "${installimage}"
-    docker rm "${installctr}"
-    installctr=
-fi
-
-echo >&2 installing ${pkgfile} in ${installimage}, then starting arvados...
-docker run -it --rm \
-       -v /tmp/pkg:/pkg:ro \
-       -v ${sourcesfile}:/etc/apt/sources.list.d/arvados-local.list:ro \
-       "${installimage}" \
-       bash -c 'apt update && DEBIAN_FRONTEND=noninteractive eatmydata apt install --reinstall -y arvados-server-easy postgresql && /etc/init.d/postgresql start && /var/lib/arvados/bin/arvados-server init -cluster-id x1234 && /var/lib/arvados/bin/arvados-server boot -listen-host 0.0.0.0'
diff --git a/cmd/arvados-package/install.go b/cmd/arvados-package/install.go
index 719258a9b..774771efb 100644
--- a/cmd/arvados-package/install.go
+++ b/cmd/arvados-package/install.go
@@ -19,27 +19,6 @@ import (
 	"github.com/docker/docker/client"
 )
 
-// sourcesfile=/tmp/sources.conf.d-arvados
-// echo >$sourcesfile "deb [trusted=yes] file:///pkg ./"
-
-// installimage="arvados-installpackage-${osbase}"
-// if [[ "${opts[force-installimage]}" || -z "$(docker images --format {{.Repository}} "${installimage}")" ]]; then
-//     echo >&2 building ${installimage}...
-//     installctr=${installimage/:/-}
-//     docker rm "${installctr}" || true
-//     docker run -it \
-//            --name "${installctr}" \
-//            --tmpfs /tmp \
-//            -v /tmp/pkg:/pkg:ro \
-//            -v ${sourcesfile}:/etc/apt/sources.list.d/arvados-local.list:ro \
-//            --env DEBIAN_FRONTEND=noninteractive \
-//            "${osbase}" \
-//            bash -c 'apt update && apt install -y eatmydata && eatmydata apt install -y arvados-server-easy postgresql && eatmydata apt remove -y arvados-server-easy'
-//     docker commit "${installctr}" "${installimage}"
-//     docker rm "${installctr}"
-//     installctr=
-// fi
-
 func testinstall(ctx context.Context, opts opts, stdin io.Reader, stdout, stderr io.Writer) error {
 	if opts.PackageVersion != "" {
 		return errors.New("not implemented: package version was specified, but I only know how to test the latest version in pkgdir")

commit 4085665f87c82939961e55bf004ca47c03ca30ac
Author: Tom Clegg <tom at curii.com>
Date:   Mon Jan 18 16:31:31 2021 -0500

    16306: Update tests.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/cmd/arvados-package/build_test.go b/cmd/arvados-package/build_test.go
index abb54532d..9f002b535 100644
--- a/cmd/arvados-package/build_test.go
+++ b/cmd/arvados-package/build_test.go
@@ -5,10 +5,8 @@
 package main
 
 import (
-	"flag"
 	"os"
 	"os/exec"
-	"path/filepath"
 	"testing"
 
 	"gopkg.in/check.v1"
@@ -18,13 +16,6 @@ var buildimage string
 
 func init() {
 	os.Args = append(os.Args, "-test.timeout=30m") // kludge
-
-	// This enables a hack to speed up repeated tests: hit "docker
-	// commit --pause {containername} checkpointtag" after the
-	// test container has downloaded/compiled some stuff, then run
-	// tests with "-test.buildimage=checkpointtag" next time to
-	// retry/resume/update from that point.
-	flag.StringVar(&buildimage, "test.buildimage", "debian:10", "docker image to use when running buildpackage")
 }
 
 type BuildSuite struct{}
@@ -42,36 +33,30 @@ func (s *BuildSuite) TestBuildAndInstall(c *check.C) {
 	tmpdir := c.MkDir()
 	defer os.RemoveAll(tmpdir)
 
-	err := os.Mkdir(tmpdir+"/pkg", 0755)
-	c.Assert(err, check.IsNil)
-	err = os.Mkdir(tmpdir+"/bin", 0755)
-	c.Assert(err, check.IsNil)
-
-	cmd := exec.Command("go", "install")
-	cmd.Env = append(append([]string(nil), os.Environ()...), "GOPATH="+tmpdir)
-	cmd.Stdout = os.Stdout
+	cmd := exec.Command("go", "run", ".",
+		"build",
+		"-package-dir", tmpdir,
+		"-package-version", "1.2.3~rc4",
+		"-source", "../..",
+	)
+	cmd.Stdout = os.Stderr
 	cmd.Stderr = os.Stderr
-	err = cmd.Run()
-	c.Assert(err, check.IsNil)
+	err := cmd.Run()
+	c.Check(err, check.IsNil)
 
-	srctree, err := filepath.Abs("../..")
+	fi, err := os.Stat(tmpdir + "/arvados-server-easy_1.2.3~rc4_amd64.deb")
 	c.Assert(err, check.IsNil)
+	c.Logf("%#v", fi)
 
-	cmd = exec.Command("docker", "run", "--rm",
-		"-v", tmpdir+"/pkg:/pkg",
-		"-v", tmpdir+"/bin/arvados-package:/arvados-package:ro",
-		"-v", srctree+":/usr/local/src/arvados:ro",
-		buildimage,
-		"/arvados-package", "build",
-		"-package-version", "0.9.99",
-		"-source", "/usr/local/src/arvados",
-		"-output-directory", "/pkg")
-	cmd.Stdout = os.Stdout
+	cmd = exec.Command("go", "run", ".",
+		"testinstall",
+		"-package-dir", tmpdir,
+	)
+	cmd.Stdout = os.Stderr
 	cmd.Stderr = os.Stderr
 	err = cmd.Run()
-	c.Assert(err, check.IsNil)
+	c.Check(err, check.IsNil)
 
-	fi, err := os.Stat(tmpdir + "/pkg/arvados-server-easy_0.9.99_amd64.deb")
-	c.Assert(err, check.IsNil)
-	c.Logf("%#v", fi)
+	err = os.RemoveAll(tmpdir)
+	c.Check(err, check.IsNil)
 }

commit 1297d71125f5a694996147406edf38bdc913396c
Author: Tom Clegg <tom at curii.com>
Date:   Mon Jan 18 16:31:40 2021 -0500

    16306: Use cwd as default source tree.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/cmd/arvados-package/cmd.go b/cmd/arvados-package/cmd.go
index 6cf3ba3c0..b0c0e9e3c 100644
--- a/cmd/arvados-package/cmd.go
+++ b/cmd/arvados-package/cmd.go
@@ -68,7 +68,8 @@ type opts struct {
 
 func parseFlags(args []string) (opts, error) {
 	opts := opts{
-		TargetOS: "debian:10",
+		SourceDir: ".",
+		TargetOS:  "debian:10",
 	}
 	flags := flag.NewFlagSet("", flag.ContinueOnError)
 	flags.StringVar(&opts.PackageVersion, "package-version", opts.PackageVersion, "package version to build/test, like \"1.2.3\"")
@@ -123,5 +124,9 @@ Options:
 		opts.SourceDir = d
 	}
 	opts.PackageDir = filepath.Clean(opts.PackageDir)
+	opts.SourceDir, err = filepath.Abs(opts.SourceDir)
+	if err != nil {
+		return opts, err
+	}
 	return opts, nil
 }

commit 41305b5ac71cc9a306dc654c42c11ffcc4258a47
Merge: b979f8011 025639399
Author: Tom Clegg <tom at curii.com>
Date:   Mon Jan 18 13:55:27 2021 -0500

    16306: Merge branch 'master'
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --cc lib/boot/supervisor.go
index e892d3e62,f2e715a76..838808df5
--- a/lib/boot/supervisor.go
+++ b/lib/boot/supervisor.go
@@@ -244,11 -222,11 +244,11 @@@ func (super *Supervisor) run(cfg *arvad
  		runGoProgram{src: "services/keepproxy", svc: super.cluster.Services.Keepproxy, depends: []supervisedTask{runPassenger{src: "services/api"}}},
  		runGoProgram{src: "services/keepstore", svc: super.cluster.Services.Keepstore},
  		runGoProgram{src: "services/keep-web", svc: super.cluster.Services.WebDAV},
- 		runServiceCommand{name: "ws", svc: super.cluster.Services.Websocket, depends: []supervisedTask{runPostgreSQL{}}},
+ 		runServiceCommand{name: "ws", svc: super.cluster.Services.Websocket, depends: []supervisedTask{seedDatabase{}}},
  		installPassenger{src: "services/api"},
- 		runPassenger{src: "services/api", varlibdir: "railsapi", svc: super.cluster.Services.RailsAPI, depends: []supervisedTask{createCertificates{}, runPostgreSQL{}, installPassenger{src: "services/api"}}},
- 		installPassenger{src: "apps/workbench", depends: []supervisedTask{installPassenger{src: "services/api"}}}, // dependency ensures workbench doesn't delay api startup
 -		runPassenger{src: "services/api", svc: super.cluster.Services.RailsAPI, depends: []supervisedTask{createCertificates{}, seedDatabase{}, installPassenger{src: "services/api"}}},
++		runPassenger{src: "services/api", varlibdir: "railsapi", svc: super.cluster.Services.RailsAPI, depends: []supervisedTask{createCertificates{}, seedDatabase{}, installPassenger{src: "services/api"}}},
+ 		installPassenger{src: "apps/workbench", depends: []supervisedTask{seedDatabase{}}}, // dependency ensures workbench doesn't delay api install/startup
 -		runPassenger{src: "apps/workbench", svc: super.cluster.Services.Workbench1, depends: []supervisedTask{installPassenger{src: "apps/workbench"}}},
 +		runPassenger{src: "apps/workbench", varlibdir: "workbench1", svc: super.cluster.Services.Workbench1, depends: []supervisedTask{installPassenger{src: "apps/workbench"}}},
  		seedDatabase{},
  	}
  	if super.ClusterType != "test" {
@@@ -682,26 -605,27 +682,26 @@@ func (super *Supervisor) autofillConfig
  			}
  		}
  	}
 -	if cluster.SystemRootToken == "" {
 -		cluster.SystemRootToken = randomHexString(64)
 -	}
 -	if cluster.ManagementToken == "" {
 -		cluster.ManagementToken = randomHexString(64)
 -	}
 -	if cluster.Collections.BlobSigningKey == "" {
 -		cluster.Collections.BlobSigningKey = randomHexString(64)
 -	}
 -	if cluster.Users.AnonymousUserToken == "" {
 -		cluster.Users.AnonymousUserToken = randomHexString(64)
 -	}
 -
 -	if super.ClusterType != "production" && cluster.Containers.DispatchPrivateKey == "" {
 -		buf, err := ioutil.ReadFile(filepath.Join(super.SourcePath, "lib", "dispatchcloud", "test", "sshkey_dispatch"))
 -		if err != nil {
 -			return err
 -		}
 -		cluster.Containers.DispatchPrivateKey = string(buf)
 -	}
  	if super.ClusterType != "production" {
 +		if cluster.SystemRootToken == "" {
 +			cluster.SystemRootToken = randomHexString(64)
 +		}
 +		if cluster.ManagementToken == "" {
 +			cluster.ManagementToken = randomHexString(64)
 +		}
- 		if cluster.API.RailsSessionSecretToken == "" {
- 			cluster.API.RailsSessionSecretToken = randomHexString(64)
- 		}
 +		if cluster.Collections.BlobSigningKey == "" {
 +			cluster.Collections.BlobSigningKey = randomHexString(64)
 +		}
++		if cluster.Users.AnonymousUserToken == "" {
++			cluster.Users.AnonymousUserToken = randomHexString(64)
++		}
 +		if cluster.Containers.DispatchPrivateKey == "" {
 +			buf, err := ioutil.ReadFile(filepath.Join(super.SourcePath, "lib", "dispatchcloud", "test", "sshkey_dispatch"))
 +			if err != nil {
 +				return err
 +			}
 +			cluster.Containers.DispatchPrivateKey = string(buf)
 +		}
  		cluster.TLS.Insecure = true
  	}
  	if super.ClusterType == "test" {

commit b979f80113c4f8a4c13c96b4679c28788c099333
Author: Tom Clegg <tom at curii.com>
Date:   Thu Jan 7 17:24:29 2021 -0500

    16306: Command usage help.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/cmd/arvados-package/build.go b/cmd/arvados-package/build.go
index c85979268..cf9cbfa6c 100644
--- a/cmd/arvados-package/build.go
+++ b/cmd/arvados-package/build.go
@@ -108,7 +108,7 @@ func build(ctx context.Context, opts opts, stdin io.Reader, stdout, stderr io.Wr
 		"-v", selfbin+":/arvados-package:ro",
 		"-v", opts.SourceDir+":/arvados:ro",
 		buildImageName,
-		"eatmydata", "/arvados-package", "fpm",
+		"eatmydata", "/arvados-package", "_fpm",
 		"-source", "/arvados",
 		"-package-version", opts.PackageVersion,
 		"-package-dir", "/pkg",
diff --git a/cmd/arvados-package/cmd.go b/cmd/arvados-package/cmd.go
index 9b9971e92..6cf3ba3c0 100644
--- a/cmd/arvados-package/cmd.go
+++ b/cmd/arvados-package/cmd.go
@@ -11,6 +11,7 @@ import (
 	"io"
 	"os"
 	"path/filepath"
+	"strings"
 
 	"git.arvados.org/arvados.git/lib/cmd"
 	"git.arvados.org/arvados.git/lib/install"
@@ -24,13 +25,17 @@ var (
 		"--version": cmd.Version,
 
 		"build":       cmdFunc(build),
-		"fpm":         cmdFunc(fpm),
 		"testinstall": cmdFunc(testinstall),
+		"_fpm":        cmdFunc(fpm),    // internal use
 		"_install":    install.Command, // internal use
 	})
 )
 
 func main() {
+	if len(os.Args) < 2 || strings.HasPrefix(os.Args[1], "-") {
+		parseFlags([]string{"-help"})
+		os.Exit(2)
+	}
 	os.Exit(handler.RunCommand(os.Args[0], os.Args[1:], os.Stdin, os.Stdout, os.Stderr))
 }
 
@@ -72,6 +77,37 @@ func parseFlags(args []string) (opts, error) {
 	flags.StringVar(&opts.PackageChown, "package-chown", opts.PackageChown, "desired uid:gid for new package (default is current user:group)")
 	flags.StringVar(&opts.TargetOS, "target-os", opts.TargetOS, "target operating system vendor:version")
 	flags.BoolVar(&opts.RebuildImage, "rebuild-image", opts.RebuildImage, "rebuild docker image(s) instead of using existing")
+	flags.Usage = func() {
+		fmt.Fprint(flags.Output(), `Usage: arvados-package <subcommand> [options]
+
+Subcommands:
+	build
+		use a docker container to build a package from a checked
+		out version of the arvados source tree
+	testinstall
+		use a docker container to install a package and confirm
+		the resulting installation is functional
+	version
+		show program version
+
+Internally used subcommands:
+	_fpm
+		build a package
+	_install
+		equivalent to "arvados-server install"
+
+Automation/integration notes:
+	The first time a given machine runs "build" or "testinstall" (and
+	any time the -rebuild-image is used), new docker images are built,
+	which is quite slow. If you use on-demand VMs to run automated builds,
+	run "build" and "testinstall" once when setting up your initial VM
+	image, and be prepared to rebuild that VM image when package-building
+	slows down (this will happen when new dependencies are introduced).
+
+Options:
+`)
+		flags.PrintDefaults()
+	}
 	err := flags.Parse(args)
 	if err != nil {
 		return opts, err

commit 57c3fbfb0f75dc38be717d52f29abe5bcefea1bb
Author: Tom Clegg <tom at curii.com>
Date:   Mon Jan 4 15:58:24 2021 -0500

    16306: Remove daemontools dependency.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/lib/boot/passenger.go b/lib/boot/passenger.go
index 4a605e35a..84f51d0a7 100644
--- a/lib/boot/passenger.go
+++ b/lib/boot/passenger.go
@@ -148,11 +148,11 @@ func (runner runPassenger) Run(ctx context.Context, fail func(error), super *Sup
 		if super.ClusterType == "production" {
 			opts.user = "www-data"
 		} else {
-			// This would be desirable in the production
-			// case too, but it fails with sudo because
-			// /dev/stderr is a symlink to a pty owned by
-			// root: "nginx: [emerg] open() "/dev/stderr"
-			// failed (13: Permission denied)"
+			// This would be desirable when changing uid
+			// too, but it fails because /dev/stderr is a
+			// symlink to a pty owned by root: "nginx:
+			// [emerg] open() "/dev/stderr" failed (13:
+			// Permission denied)"
 			cmdline = append(cmdline, "--log-file", "/dev/stderr")
 		}
 		err = super.RunProgram(ctx, appdir, opts, cmdline[0], cmdline[1:]...)
diff --git a/lib/boot/postgresql.go b/lib/boot/postgresql.go
index daa0414a3..4ed7603d2 100644
--- a/lib/boot/postgresql.go
+++ b/lib/boot/postgresql.go
@@ -60,6 +60,7 @@ func (runPostgreSQL) Run(ctx context.Context, fail func(error), super *Superviso
 		return err
 	}
 	prog, args := filepath.Join(bindir, "initdb"), []string{"-D", datadir, "-E", "utf8"}
+	opts := runOptions{}
 	if iamroot {
 		postgresUser, err := user.Lookup("postgres")
 		if err != nil {
@@ -85,15 +86,9 @@ func (runPostgreSQL) Run(ctx context.Context, fail func(error), super *Superviso
 		if err != nil {
 			return err
 		}
-		// We can't use "sudo -u" here because it creates an
-		// intermediate process that interferes with our
-		// ability to reliably kill postgres. The setuidgid
-		// program just calls exec without forking, so it
-		// doesn't have this problem.
-		args = append([]string{"postgres", prog}, args...)
-		prog = "setuidgid"
-	}
-	err = super.RunProgram(ctx, super.tempdir, runOptions{}, prog, args...)
+		opts.user = "postgres"
+	}
+	err = super.RunProgram(ctx, super.tempdir, opts, prog, args...)
 	if err != nil {
 		return err
 	}
@@ -120,11 +115,11 @@ func (runPostgreSQL) Run(ctx context.Context, fail func(error), super *Superviso
 			"-k", datadir, // socket dir
 			"-p", super.cluster.PostgreSQL.Connection["port"],
 		}
+		opts := runOptions{}
 		if iamroot {
-			args = append([]string{"postgres", prog}, args...)
-			prog = "setuidgid"
+			opts.user = "postgres"
 		}
-		fail(super.RunProgram(ctx, super.tempdir, runOptions{}, prog, args...))
+		fail(super.RunProgram(ctx, super.tempdir, opts, prog, args...))
 	}()
 
 	for {
diff --git a/lib/boot/supervisor.go b/lib/boot/supervisor.go
index 5e88775e5..e892d3e62 100644
--- a/lib/boot/supervisor.go
+++ b/lib/boot/supervisor.go
@@ -491,9 +491,6 @@ func (super *Supervisor) RunProgram(ctx context.Context, dir string, opts runOpt
 
 	logprefix := prog
 	{
-		if logprefix == "setuidgid" && len(args) >= 3 {
-			logprefix = args[2]
-		}
 		innerargs := args
 		if logprefix == "sudo" {
 			for i := 0; i < len(args); i++ {
@@ -556,6 +553,15 @@ func (super *Supervisor) RunProgram(ctx context.Context, dir string, opts runOpt
 	cmd.Env = dedupEnv(env)
 
 	if opts.user != "" {
+		// Note: We use this approach instead of "sudo"
+		// because in certain circumstances (we are pid 1 in a
+		// docker container, and our passenger child process
+		// changes to pgid 1) the intermediate sudo process
+		// notices we have the same pgid as our child and
+		// refuses to propagate signals from us to our child,
+		// so we can't signal/shutdown our passenger/rails
+		// apps. "chpst" or "setuidgid" would work, but these
+		// few lines avoid depending on runit/daemontools.
 		u, err := user.Lookup(opts.user)
 		if err != nil {
 			return fmt.Errorf("user.Lookup(%q): %w", opts.user, err)
diff --git a/lib/install/deps.go b/lib/install/deps.go
index 049df2564..504cdff8f 100644
--- a/lib/install/deps.go
+++ b/lib/install/deps.go
@@ -141,7 +141,6 @@ func (inst *installCommand) RunCommand(prog string, args []string, stdin io.Read
 			"cadaver",
 			"curl",
 			"cython3",
-			"daemontools", // lib/boot uses setuidgid to drop privileges when running as root
 			"default-jdk-headless",
 			"default-jre-headless",
 			"gettext",

commit 6cd0e19a277812f302f46693d824cc17d17ed6b1
Author: Tom Clegg <tom at curii.com>
Date:   Mon Jan 4 15:42:35 2021 -0500

    16306: Exit 0 when startup-then-shutdown goes as planned.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/lib/boot/cmd.go b/lib/boot/cmd.go
index e0e275522..373613bb3 100644
--- a/lib/boot/cmd.go
+++ b/lib/boot/cmd.go
@@ -108,6 +108,11 @@ func (bcmd bootCommand) run(ctx context.Context, prog string, args []string, std
 		fmt.Fprintln(stdout, url)
 		if *shutdown {
 			super.Stop()
+			// Wait for children to exit. Don't report the
+			// ensuing "context cancelled" error, though:
+			// return nil to indicate successful startup.
+			_ = super.Wait()
+			return nil
 		}
 	}
 	// Wait for signal/crash + orderly shutdown

commit d71d4273d1f3d0b6381efafa649b81c6b4107cf1
Author: Tom Clegg <tom at curii.com>
Date:   Mon Jan 4 15:26:46 2021 -0500

    16306: Fix inability to shutdown passenger processes.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/lib/boot/cert.go b/lib/boot/cert.go
index 8f6339e63..b2b8c896c 100644
--- a/lib/boot/cert.go
+++ b/lib/boot/cert.go
@@ -39,17 +39,17 @@ func (createCertificates) Run(ctx context.Context, fail func(error), super *Supe
 	}
 
 	// Generate root key
-	err := super.RunProgram(ctx, super.tempdir, nil, nil, "openssl", "genrsa", "-out", "rootCA.key", "4096")
+	err := super.RunProgram(ctx, super.tempdir, runOptions{}, "openssl", "genrsa", "-out", "rootCA.key", "4096")
 	if err != nil {
 		return err
 	}
 	// Generate a self-signed root certificate
-	err = super.RunProgram(ctx, super.tempdir, nil, nil, "openssl", "req", "-x509", "-new", "-nodes", "-key", "rootCA.key", "-sha256", "-days", "3650", "-out", "rootCA.crt", "-subj", "/C=US/ST=MA/O=Example Org/CN=localhost")
+	err = super.RunProgram(ctx, super.tempdir, runOptions{}, "openssl", "req", "-x509", "-new", "-nodes", "-key", "rootCA.key", "-sha256", "-days", "3650", "-out", "rootCA.crt", "-subj", "/C=US/ST=MA/O=Example Org/CN=localhost")
 	if err != nil {
 		return err
 	}
 	// Generate server key
-	err = super.RunProgram(ctx, super.tempdir, nil, nil, "openssl", "genrsa", "-out", "server.key", "2048")
+	err = super.RunProgram(ctx, super.tempdir, runOptions{}, "openssl", "genrsa", "-out", "server.key", "2048")
 	if err != nil {
 		return err
 	}
@@ -63,12 +63,12 @@ func (createCertificates) Run(ctx context.Context, fail func(error), super *Supe
 		return err
 	}
 	// Generate signing request
-	err = super.RunProgram(ctx, super.tempdir, nil, nil, "openssl", "req", "-new", "-sha256", "-key", "server.key", "-subj", "/C=US/ST=MA/O=Example Org/CN=localhost", "-reqexts", "SAN", "-config", "server.cfg", "-out", "server.csr")
+	err = super.RunProgram(ctx, super.tempdir, runOptions{}, "openssl", "req", "-new", "-sha256", "-key", "server.key", "-subj", "/C=US/ST=MA/O=Example Org/CN=localhost", "-reqexts", "SAN", "-config", "server.cfg", "-out", "server.csr")
 	if err != nil {
 		return err
 	}
 	// Sign certificate
-	err = super.RunProgram(ctx, super.tempdir, nil, nil, "openssl", "x509", "-req", "-in", "server.csr", "-CA", "rootCA.crt", "-CAkey", "rootCA.key", "-CAcreateserial", "-out", "server.crt", "-extfile", "server.cfg", "-extensions", "SAN", "-days", "3650", "-sha256")
+	err = super.RunProgram(ctx, super.tempdir, runOptions{}, "openssl", "x509", "-req", "-in", "server.csr", "-CA", "rootCA.crt", "-CAkey", "rootCA.key", "-CAcreateserial", "-out", "server.crt", "-extfile", "server.cfg", "-extensions", "SAN", "-days", "3650", "-sha256")
 	if err != nil {
 		return err
 	}
diff --git a/lib/boot/nginx.go b/lib/boot/nginx.go
index d49fabe56..d14d05152 100644
--- a/lib/boot/nginx.go
+++ b/lib/boot/nginx.go
@@ -120,7 +120,7 @@ func (runNginx) Run(ctx context.Context, fail func(error), super *Supervisor) er
 	super.waitShutdown.Add(1)
 	go func() {
 		defer super.waitShutdown.Done()
-		fail(super.RunProgram(ctx, ".", nil, nil, nginx, args...))
+		fail(super.RunProgram(ctx, ".", runOptions{}, nginx, args...))
 	}()
 	// Choose one of the ports where Nginx should listen, and wait
 	// here until we can connect. If ExternalURL is https://foo (with no port) then we connect to "foo:https"
diff --git a/lib/boot/passenger.go b/lib/boot/passenger.go
index 03464aaf7..4a605e35a 100644
--- a/lib/boot/passenger.go
+++ b/lib/boot/passenger.go
@@ -50,32 +50,32 @@ func (runner installPassenger) Run(ctx context.Context, fail func(error), super
 	defer passengerInstallMutex.Unlock()
 
 	var buf bytes.Buffer
-	err = super.RunProgram(ctx, runner.src, &buf, nil, "gem", "list", "--details", "bundler")
+	err = super.RunProgram(ctx, runner.src, runOptions{output: &buf}, "gem", "list", "--details", "bundler")
 	if err != nil {
 		return err
 	}
 	for _, version := range []string{"1.16.6", "1.17.3", "2.0.2"} {
 		if !strings.Contains(buf.String(), "("+version+")") {
-			err = super.RunProgram(ctx, runner.src, nil, nil, "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:1.16.6", "bundler:1.17.3", "bundler:2.0.2")
 			if err != nil {
 				return err
 			}
 			break
 		}
 	}
-	err = super.RunProgram(ctx, runner.src, nil, nil, "bundle", "install", "--jobs", "4", "--path", filepath.Join(os.Getenv("HOME"), ".gem"))
+	err = super.RunProgram(ctx, runner.src, runOptions{}, "bundle", "install", "--jobs", "4", "--path", filepath.Join(os.Getenv("HOME"), ".gem"))
 	if err != nil {
 		return err
 	}
-	err = super.RunProgram(ctx, runner.src, nil, nil, "bundle", "exec", "passenger-config", "build-native-support")
+	err = super.RunProgram(ctx, runner.src, runOptions{}, "bundle", "exec", "passenger-config", "build-native-support")
 	if err != nil {
 		return err
 	}
-	err = super.RunProgram(ctx, runner.src, nil, nil, "bundle", "exec", "passenger-config", "install-standalone-runtime")
+	err = super.RunProgram(ctx, runner.src, runOptions{}, "bundle", "exec", "passenger-config", "install-standalone-runtime")
 	if err != nil {
 		return err
 	}
-	err = super.RunProgram(ctx, runner.src, nil, nil, "bundle", "exec", "passenger-config", "validate-install")
+	err = super.RunProgram(ctx, runner.src, runOptions{}, "bundle", "exec", "passenger-config", "validate-install")
 	if err != nil && !strings.Contains(err.Error(), "exit status 2") {
 		// Exit code 2 indicates there were warnings (like
 		// "other passenger installations have been detected",
@@ -139,8 +139,14 @@ func (runner runPassenger) Run(ctx context.Context, fail func(error), super *Sup
 			"--no-install-runtime",
 			"--pid-file", filepath.Join(super.wwwtempdir, "passenger."+strings.Replace(appdir, "/", "_", -1)+".pid"),
 		}
+		opts := runOptions{
+			env: append([]string{
+				"HOME=/var/www",
+				"TMPDIR=" + super.wwwtempdir,
+			}, railsEnv...),
+		}
 		if super.ClusterType == "production" {
-			cmdline = append([]string{"sudo", "-u", "www-data", "-E", "HOME=/var/www", "PATH=/var/lib/arvados/bin:" + os.Getenv("PATH"), "/var/lib/arvados/bin/bundle"}, cmdline[1:]...)
+			opts.user = "www-data"
 		} else {
 			// This would be desirable in the production
 			// case too, but it fails with sudo because
@@ -149,8 +155,7 @@ func (runner runPassenger) Run(ctx context.Context, fail func(error), super *Sup
 			// failed (13: Permission denied)"
 			cmdline = append(cmdline, "--log-file", "/dev/stderr")
 		}
-		env := append([]string{"TMPDIR=" + super.wwwtempdir}, railsEnv...)
-		err = super.RunProgram(ctx, appdir, nil, env, cmdline[0], cmdline[1:]...)
+		err = super.RunProgram(ctx, appdir, opts, cmdline[0], cmdline[1:]...)
 		fail(err)
 	}()
 	return nil
diff --git a/lib/boot/postgresql.go b/lib/boot/postgresql.go
index e45c4e168..daa0414a3 100644
--- a/lib/boot/postgresql.go
+++ b/lib/boot/postgresql.go
@@ -48,7 +48,7 @@ func (runPostgreSQL) Run(ctx context.Context, fail func(error), super *Superviso
 	}
 
 	buf := bytes.NewBuffer(nil)
-	err = super.RunProgram(ctx, super.tempdir, buf, nil, "pg_config", "--bindir")
+	err = super.RunProgram(ctx, super.tempdir, runOptions{output: buf}, "pg_config", "--bindir")
 	if err != nil {
 		return err
 	}
@@ -93,17 +93,17 @@ func (runPostgreSQL) Run(ctx context.Context, fail func(error), super *Superviso
 		args = append([]string{"postgres", prog}, args...)
 		prog = "setuidgid"
 	}
-	err = super.RunProgram(ctx, super.tempdir, nil, nil, prog, args...)
+	err = super.RunProgram(ctx, super.tempdir, runOptions{}, prog, args...)
 	if err != nil {
 		return err
 	}
 
-	err = super.RunProgram(ctx, super.tempdir, nil, nil, "cp", "server.crt", "server.key", datadir)
+	err = super.RunProgram(ctx, super.tempdir, runOptions{}, "cp", "server.crt", "server.key", datadir)
 	if err != nil {
 		return err
 	}
 	if iamroot {
-		err = super.RunProgram(ctx, super.tempdir, nil, nil, "chown", "postgres", datadir+"/server.crt", datadir+"/server.key")
+		err = super.RunProgram(ctx, super.tempdir, runOptions{}, "chown", "postgres", datadir+"/server.crt", datadir+"/server.key")
 		if err != nil {
 			return err
 		}
@@ -124,7 +124,7 @@ func (runPostgreSQL) Run(ctx context.Context, fail func(error), super *Superviso
 			args = append([]string{"postgres", prog}, args...)
 			prog = "setuidgid"
 		}
-		fail(super.RunProgram(ctx, super.tempdir, nil, nil, prog, args...))
+		fail(super.RunProgram(ctx, super.tempdir, runOptions{}, prog, args...))
 	}()
 
 	for {
diff --git a/lib/boot/seed.go b/lib/boot/seed.go
index 1f6cb764e..bd1e94265 100644
--- a/lib/boot/seed.go
+++ b/lib/boot/seed.go
@@ -23,11 +23,11 @@ func (seedDatabase) Run(ctx context.Context, fail func(error), super *Supervisor
 	if super.ClusterType == "production" {
 		return nil
 	}
-	err = super.RunProgram(ctx, "services/api", nil, railsEnv, "bundle", "exec", "rake", "db:setup")
+	err = super.RunProgram(ctx, "services/api", runOptions{env: railsEnv}, "bundle", "exec", "rake", "db:setup")
 	if err != nil {
 		return err
 	}
-	err = super.RunProgram(ctx, "services/api", nil, railsEnv, "bundle", "exec", "./script/get_anonymous_user_token.rb")
+	err = super.RunProgram(ctx, "services/api", runOptions{env: railsEnv}, "bundle", "exec", "./script/get_anonymous_user_token.rb")
 	if err != nil {
 		return err
 	}
diff --git a/lib/boot/service.go b/lib/boot/service.go
index 77fdc98be..090e85244 100644
--- a/lib/boot/service.go
+++ b/lib/boot/service.go
@@ -31,7 +31,7 @@ func (runner runServiceCommand) String() string {
 
 func (runner runServiceCommand) Run(ctx context.Context, fail func(error), super *Supervisor) error {
 	binfile := filepath.Join(super.bindir, "arvados-server")
-	err := super.RunProgram(ctx, super.bindir, nil, nil, binfile, "-version")
+	err := super.RunProgram(ctx, super.bindir, runOptions{}, binfile, "-version")
 	if err != nil {
 		return err
 	}
@@ -46,7 +46,7 @@ func (runner runServiceCommand) Run(ctx context.Context, fail func(error), super
 		super.waitShutdown.Add(1)
 		go func() {
 			defer super.waitShutdown.Done()
-			fail(super.RunProgram(ctx, super.tempdir, nil, []string{"ARVADOS_SERVICE_INTERNAL_URL=" + u.String()}, binfile, runner.name, "-config", super.configfile))
+			fail(super.RunProgram(ctx, super.tempdir, runOptions{env: []string{"ARVADOS_SERVICE_INTERNAL_URL=" + u.String()}}, binfile, runner.name, "-config", super.configfile))
 		}()
 	}
 	return nil
@@ -77,7 +77,7 @@ func (runner runGoProgram) Run(ctx context.Context, fail func(error), super *Sup
 		return ctx.Err()
 	}
 
-	err = super.RunProgram(ctx, super.tempdir, nil, nil, binfile, "-version")
+	err = super.RunProgram(ctx, super.tempdir, runOptions{}, binfile, "-version")
 	if err != nil {
 		return err
 	}
@@ -93,7 +93,7 @@ func (runner runGoProgram) Run(ctx context.Context, fail func(error), super *Sup
 		super.waitShutdown.Add(1)
 		go func() {
 			defer super.waitShutdown.Done()
-			fail(super.RunProgram(ctx, super.tempdir, nil, []string{"ARVADOS_SERVICE_INTERNAL_URL=" + u.String()}, binfile))
+			fail(super.RunProgram(ctx, super.tempdir, runOptions{env: []string{"ARVADOS_SERVICE_INTERNAL_URL=" + u.String()}}, binfile))
 		}()
 	}
 	return nil
diff --git a/lib/boot/supervisor.go b/lib/boot/supervisor.go
index 7dba9b5dc..5e88775e5 100644
--- a/lib/boot/supervisor.go
+++ b/lib/boot/supervisor.go
@@ -21,6 +21,7 @@ import (
 	"os/user"
 	"path/filepath"
 	"reflect"
+	"strconv"
 	"strings"
 	"sync"
 	"syscall"
@@ -206,13 +207,13 @@ func (super *Supervisor) run(cfg *arvados.Config) error {
 	} else if super.SourceVersion == "" {
 		// Find current source tree version.
 		var buf bytes.Buffer
-		err = super.RunProgram(super.ctx, ".", &buf, nil, "git", "diff", "--shortstat")
+		err = super.RunProgram(super.ctx, ".", runOptions{output: &buf}, "git", "diff", "--shortstat")
 		if err != nil {
 			return err
 		}
 		dirty := buf.Len() > 0
 		buf.Reset()
-		err = super.RunProgram(super.ctx, ".", &buf, nil, "git", "log", "-n1", "--format=%H")
+		err = super.RunProgram(super.ctx, ".", runOptions{output: &buf}, "git", "log", "-n1", "--format=%H")
 		if err != nil {
 			return err
 		}
@@ -407,7 +408,7 @@ func (super *Supervisor) installGoProgram(ctx context.Context, srcpath string) (
 	if super.ClusterType == "production" {
 		return binfile, nil
 	}
-	err := super.RunProgram(ctx, filepath.Join(super.SourcePath, srcpath), nil, []string{"GOBIN=" + super.bindir}, "go", "install", "-ldflags", "-X git.arvados.org/arvados.git/lib/cmd.version="+super.SourceVersion+" -X main.version="+super.SourceVersion)
+	err := super.RunProgram(ctx, filepath.Join(super.SourcePath, srcpath), runOptions{env: []string{"GOBIN=" + super.bindir}}, "go", "install", "-ldflags", "-X git.arvados.org/arvados.git/lib/cmd.version="+super.SourceVersion+" -X main.version="+super.SourceVersion)
 	return binfile, err
 }
 
@@ -470,6 +471,12 @@ func (super *Supervisor) lookPath(prog string) string {
 	return prog
 }
 
+type runOptions struct {
+	output io.Writer // attach stdout
+	env    []string  // add/replace environment variables
+	user   string    // run as specified user
+}
+
 // RunProgram runs prog with args, using dir as working directory. If ctx is
 // cancelled while the child is running, RunProgram terminates the child, waits
 // for it to exit, then returns.
@@ -478,7 +485,7 @@ func (super *Supervisor) lookPath(prog string) string {
 //
 // Child's stdout will be written to output if non-nil, otherwise the
 // boot command's stderr.
-func (super *Supervisor) RunProgram(ctx context.Context, dir string, output io.Writer, env []string, prog string, args ...string) error {
+func (super *Supervisor) RunProgram(ctx context.Context, dir string, opts runOptions, prog string, args ...string) error {
 	cmdline := fmt.Sprintf("%s", append([]string{prog}, args...))
 	super.logger.WithField("command", cmdline).WithField("dir", dir).Info("executing")
 
@@ -531,10 +538,10 @@ func (super *Supervisor) RunProgram(ctx context.Context, dir string, output io.W
 	}()
 	copiers.Add(1)
 	go func() {
-		if output == nil {
+		if opts.output == nil {
 			io.Copy(logwriter, stdout)
 		} else {
-			io.Copy(output, stdout)
+			io.Copy(opts.output, stdout)
 		}
 		copiers.Done()
 	}()
@@ -544,10 +551,25 @@ func (super *Supervisor) RunProgram(ctx context.Context, dir string, output io.W
 	} else {
 		cmd.Dir = filepath.Join(super.SourcePath, dir)
 	}
-	env = append([]string(nil), env...)
+	env := append([]string(nil), opts.env...)
 	env = append(env, super.environ...)
 	cmd.Env = dedupEnv(env)
 
+	if opts.user != "" {
+		u, err := user.Lookup(opts.user)
+		if err != nil {
+			return fmt.Errorf("user.Lookup(%q): %w", opts.user, err)
+		}
+		uid, _ := strconv.Atoi(u.Uid)
+		gid, _ := strconv.Atoi(u.Gid)
+		cmd.SysProcAttr = &syscall.SysProcAttr{
+			Credential: &syscall.Credential{
+				Uid: uint32(uid),
+				Gid: uint32(gid),
+			},
+		}
+	}
+
 	exited := false
 	defer func() { exited = true }()
 	go func() {

commit 2cfb41d14010e26d97df93c4cf8ad00f0ac01701
Author: Tom Clegg <tom at curii.com>
Date:   Mon Jan 4 11:22:09 2021 -0500

    16306: Refactor docker scripts into arvados-package command.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/cmd/arvados-package/build.go b/cmd/arvados-package/build.go
index 1343ca77b..c85979268 100644
--- a/cmd/arvados-package/build.go
+++ b/cmd/arvados-package/build.go
@@ -5,120 +5,158 @@
 package main
 
 import (
+	"bytes"
 	"context"
-	"flag"
 	"fmt"
 	"io"
+	"io/ioutil"
 	"os"
 	"os/exec"
+	"os/user"
+	"path/filepath"
+	"strings"
 
-	"git.arvados.org/arvados.git/lib/install"
 	"git.arvados.org/arvados.git/sdk/go/ctxlog"
-	"github.com/sirupsen/logrus"
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
 )
 
-type build struct{}
-
-func (bld build) RunCommand(prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) int {
-	logger := ctxlog.New(stderr, "text", "info")
-	err := (&builder{
-		PackageVersion: "0.0.0",
-		logger:         logger,
-	}).run(context.Background(), prog, args, stdin, stdout, stderr)
-	if err != nil {
-		logger.WithError(err).Error("failed")
-		return 1
+func build(ctx context.Context, opts opts, stdin io.Reader, stdout, stderr io.Writer) error {
+	if opts.PackageVersion == "" {
+		var buf bytes.Buffer
+		cmd := exec.CommandContext(ctx, "git", "describe", "--tag", "--dirty")
+		cmd.Stdout = &buf
+		cmd.Stderr = stderr
+		cmd.Dir = opts.SourceDir
+		err := cmd.Run()
+		if err != nil {
+			return fmt.Errorf("git describe: %w", err)
+		}
+		opts.PackageVersion = strings.TrimSpace(buf.String())
+		ctxlog.FromContext(ctx).Infof("version not specified; using %s", opts.PackageVersion)
 	}
-	return 0
-}
 
-type builder struct {
-	PackageVersion string
-	SourcePath     string
-	OutputDir      string
-	SkipInstall    bool
-	logger         logrus.FieldLogger
-}
+	if opts.PackageChown == "" {
+		whoami, err := user.Current()
+		if err != nil {
+			return fmt.Errorf("user.Current: %w", err)
+		}
+		opts.PackageChown = whoami.Uid + ":" + whoami.Gid
+	}
 
-func (bldr *builder) run(ctx context.Context, prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) error {
-	flags := flag.NewFlagSet("", flag.ContinueOnError)
-	flags.StringVar(&bldr.PackageVersion, "package-version", bldr.PackageVersion, "package version")
-	flags.StringVar(&bldr.SourcePath, "source", bldr.SourcePath, "source tree location")
-	flags.StringVar(&bldr.OutputDir, "output-directory", bldr.OutputDir, "destination directory for new package (default is cwd)")
-	flags.BoolVar(&bldr.SkipInstall, "skip-install", bldr.SkipInstall, "skip install step, assume you have already run 'arvados-server install -type package'")
-	err := flags.Parse(args)
+	// Build in a tempdir, then move to the desired destination
+	// dir. Otherwise, errors might cause us to leave a mess:
+	// truncated files, files owned by root, etc.
+	_, prog := filepath.Split(os.Args[0])
+	tmpdir, err := ioutil.TempDir(opts.PackageDir, prog+".")
 	if err != nil {
 		return err
 	}
-	if len(flags.Args()) > 0 {
-		return fmt.Errorf("unrecognized command line arguments: %v", flags.Args())
+	defer os.RemoveAll(tmpdir)
+
+	selfbin, err := os.Readlink("/proc/self/exe")
+	if err != nil {
+		return fmt.Errorf("readlink /proc/self/exe: %w", err)
 	}
-	if !bldr.SkipInstall {
-		exitcode := install.Command.RunCommand("arvados-server install", []string{
+	buildImageName := "arvados-package-build-" + opts.TargetOS
+	packageFilename := "arvados-server-easy_" + opts.PackageVersion + "_amd64.deb"
+
+	if ok, err := dockerImageExists(ctx, buildImageName); err != nil {
+		return err
+	} else if !ok || opts.RebuildImage {
+		buildCtrName := strings.Replace(buildImageName, ":", "-", -1)
+		err = dockerRm(ctx, buildCtrName)
+		if err != nil {
+			return err
+		}
+
+		defer dockerRm(ctx, buildCtrName)
+		cmd := exec.CommandContext(ctx, "docker", "run",
+			"--name", buildCtrName,
+			"--tmpfs", "/tmp:exec,mode=01777",
+			"-v", selfbin+":/arvados-package:ro",
+			"-v", opts.SourceDir+":/arvados:ro",
+			opts.TargetOS,
+			"/arvados-package", "_install",
+			"-eatmydata",
 			"-type", "package",
-			"-package-version", bldr.PackageVersion,
-			"-source", bldr.SourcePath,
-		}, stdin, stdout, stderr)
-		if exitcode != 0 {
-			return fmt.Errorf("arvados-server install failed: exit code %d", exitcode)
+			"-source", "/arvados",
+			"-package-version", opts.PackageVersion,
+		)
+		cmd.Stdout = stdout
+		cmd.Stderr = stderr
+		err = cmd.Run()
+		if err != nil {
+			return fmt.Errorf("docker run: %w", err)
 		}
+
+		cmd = exec.CommandContext(ctx, "docker", "commit", buildCtrName, buildImageName)
+		cmd.Stdout = stdout
+		cmd.Stderr = stderr
+		err = cmd.Run()
+		if err != nil {
+			return fmt.Errorf("docker commit: %w", err)
+		}
+
+		ctxlog.FromContext(ctx).Infof("created docker image %s", buildImageName)
 	}
-	cmd := exec.Command("/var/lib/arvados/bin/gem", "install", "--user", "--no-document", "fpm")
+
+	cmd := exec.CommandContext(ctx, "docker", "run",
+		"--rm",
+		"--tmpfs", "/tmp:exec,mode=01777",
+		"-v", tmpdir+":/pkg",
+		"-v", selfbin+":/arvados-package:ro",
+		"-v", opts.SourceDir+":/arvados:ro",
+		buildImageName,
+		"eatmydata", "/arvados-package", "fpm",
+		"-source", "/arvados",
+		"-package-version", opts.PackageVersion,
+		"-package-dir", "/pkg",
+		"-package-chown", opts.PackageChown,
+	)
 	cmd.Stdout = stdout
 	cmd.Stderr = stderr
 	err = cmd.Run()
 	if err != nil {
-		return fmt.Errorf("gem install fpm: %w", err)
+		return fmt.Errorf("docker run: %w", err)
 	}
 
-	if _, err := os.Stat("/root/.gem/ruby/2.5.0/gems/fpm-1.11.0/lib/fpm/package/deb.rb"); err == nil {
-		// Workaround for fpm bug https://github.com/jordansissel/fpm/issues/1739
-		cmd = exec.Command("sed", "-i", `/require "digest"/a require "zlib"`, "/root/.gem/ruby/2.5.0/gems/fpm-1.11.0/lib/fpm/package/deb.rb")
-		cmd.Stdout = stdout
-		cmd.Stderr = stderr
-		err = cmd.Run()
-		if err != nil {
-			return fmt.Errorf("monkeypatch fpm: %w", err)
-		}
+	err = os.Rename(tmpdir+"/"+packageFilename, opts.PackageDir+"/"+packageFilename)
+	if err != nil {
+		return err
 	}
 
-	// Remove unneeded files. This is much faster than "fpm
-	// --exclude X" because fpm copies everything into a staging
-	// area before looking at the --exclude args.
-	cmd = exec.Command("bash", "-c", "cd /var/www/.gem/ruby && rm -rf */cache */bundler/gems/*/.git */bundler/gems/arvados-*/[^s]* */bundler/gems/arvados-*/s[^d]* */bundler/gems/arvados-*/sdk/[^cr]* */gems/passenger-*/src/cxx* ruby/*/gems/*/ext /var/lib/arvados/go")
+	cmd = exec.CommandContext(ctx, "bash", "-c", "dpkg-scanpackages . | gzip > Packages.gz.tmp && mv Packages.gz.tmp Packages.gz")
 	cmd.Stdout = stdout
 	cmd.Stderr = stderr
+	cmd.Dir = opts.PackageDir
 	err = cmd.Run()
 	if err != nil {
-		return fmt.Errorf("rm -rf [...]: %w", err)
+		return fmt.Errorf("dpkg-scanpackages: %w", err)
 	}
 
-	format := "deb" // TODO: rpm
+	return nil
+}
 
-	cmd = exec.Command("/root/.gem/ruby/2.5.0/bin/fpm",
-		"--name", "arvados-server-easy",
-		"--version", bldr.PackageVersion,
-		"--input-type", "dir",
-		"--output-type", format)
-	deps, err := install.ProductionDependencies()
+func dockerRm(ctx context.Context, name string) error {
+	cli, err := client.NewEnvClient()
 	if err != nil {
 		return err
 	}
-	for _, pkg := range deps {
-		cmd.Args = append(cmd.Args, "--depends", pkg)
+	ctrs, err := cli.ContainerList(ctx, types.ContainerListOptions{All: true, Limit: -1})
+	if err != nil {
+		return err
 	}
-	cmd.Args = append(cmd.Args,
-		"--verbose",
-		"--deb-use-file-permissions",
-		"--rpm-use-file-permissions",
-		"/var/lib/arvados",
-		"/var/www/.gem",
-		"/var/www/.passenger",
-		"/var/www/.bundle",
-	)
-	fmt.Fprintf(stderr, "... %s\n", cmd.Args)
-	cmd.Dir = bldr.OutputDir
-	cmd.Stdout = stdout
-	cmd.Stderr = stderr
-	return cmd.Run()
+	for _, ctr := range ctrs {
+		for _, ctrname := range ctr.Names {
+			if ctrname == "/"+name {
+				err = cli.ContainerRemove(ctx, ctr.ID, types.ContainerRemoveOptions{})
+				if err != nil {
+					return fmt.Errorf("error removing container %s: %w", ctr.ID, err)
+				}
+				break
+			}
+		}
+	}
+	return nil
 }
diff --git a/cmd/arvados-package/cmd.go b/cmd/arvados-package/cmd.go
index 02bc16cea..9b9971e92 100644
--- a/cmd/arvados-package/cmd.go
+++ b/cmd/arvados-package/cmd.go
@@ -5,9 +5,16 @@
 package main
 
 import (
+	"context"
+	"flag"
+	"fmt"
+	"io"
 	"os"
+	"path/filepath"
 
 	"git.arvados.org/arvados.git/lib/cmd"
+	"git.arvados.org/arvados.git/lib/install"
+	"git.arvados.org/arvados.git/sdk/go/ctxlog"
 )
 
 var (
@@ -16,10 +23,69 @@ var (
 		"-version":  cmd.Version,
 		"--version": cmd.Version,
 
-		"build": build{},
+		"build":       cmdFunc(build),
+		"fpm":         cmdFunc(fpm),
+		"testinstall": cmdFunc(testinstall),
+		"_install":    install.Command, // internal use
 	})
 )
 
 func main() {
 	os.Exit(handler.RunCommand(os.Args[0], os.Args[1:], os.Stdin, os.Stdout, os.Stderr))
 }
+
+type cmdFunc func(ctx context.Context, opts opts, stdin io.Reader, stdout, stderr io.Writer) error
+
+func (cf cmdFunc) RunCommand(prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) int {
+	logger := ctxlog.New(stderr, "text", "info")
+	ctx := ctxlog.Context(context.Background(), logger)
+	opts, err := parseFlags(args)
+	if err != nil {
+		logger.WithError(err).Error("error parsing command line flags")
+		return 1
+	}
+	err = cf(ctx, opts, stdin, stdout, stderr)
+	if err != nil {
+		logger.WithError(err).Error("failed")
+		return 1
+	}
+	return 0
+}
+
+type opts struct {
+	PackageVersion string
+	PackageDir     string
+	PackageChown   string
+	RebuildImage   bool
+	SourceDir      string
+	TargetOS       string
+}
+
+func parseFlags(args []string) (opts, error) {
+	opts := opts{
+		TargetOS: "debian:10",
+	}
+	flags := flag.NewFlagSet("", flag.ContinueOnError)
+	flags.StringVar(&opts.PackageVersion, "package-version", opts.PackageVersion, "package version to build/test, like \"1.2.3\"")
+	flags.StringVar(&opts.SourceDir, "source", opts.SourceDir, "arvados source tree location")
+	flags.StringVar(&opts.PackageDir, "package-dir", opts.PackageDir, "destination directory for new package (default is cwd)")
+	flags.StringVar(&opts.PackageChown, "package-chown", opts.PackageChown, "desired uid:gid for new package (default is current user:group)")
+	flags.StringVar(&opts.TargetOS, "target-os", opts.TargetOS, "target operating system vendor:version")
+	flags.BoolVar(&opts.RebuildImage, "rebuild-image", opts.RebuildImage, "rebuild docker image(s) instead of using existing")
+	err := flags.Parse(args)
+	if err != nil {
+		return opts, err
+	}
+	if len(flags.Args()) > 0 {
+		return opts, fmt.Errorf("unrecognized command line arguments: %v", flags.Args())
+	}
+	if opts.SourceDir == "" {
+		d, err := os.Getwd()
+		if err != nil {
+			return opts, fmt.Errorf("Getwd: %w", err)
+		}
+		opts.SourceDir = d
+	}
+	opts.PackageDir = filepath.Clean(opts.PackageDir)
+	return opts, nil
+}
diff --git a/cmd/arvados-package/build.go b/cmd/arvados-package/fpm.go
similarity index 53%
copy from cmd/arvados-package/build.go
copy to cmd/arvados-package/fpm.go
index 1343ca77b..a86232036 100644
--- a/cmd/arvados-package/build.go
+++ b/cmd/arvados-package/fpm.go
@@ -6,67 +6,37 @@ package main
 
 import (
 	"context"
-	"flag"
 	"fmt"
 	"io"
 	"os"
 	"os/exec"
+	"path/filepath"
 
 	"git.arvados.org/arvados.git/lib/install"
-	"git.arvados.org/arvados.git/sdk/go/ctxlog"
-	"github.com/sirupsen/logrus"
 )
 
-type build struct{}
-
-func (bld build) RunCommand(prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) int {
-	logger := ctxlog.New(stderr, "text", "info")
-	err := (&builder{
-		PackageVersion: "0.0.0",
-		logger:         logger,
-	}).run(context.Background(), prog, args, stdin, stdout, stderr)
-	if err != nil {
-		logger.WithError(err).Error("failed")
-		return 1
+func fpm(ctx context.Context, opts opts, stdin io.Reader, stdout, stderr io.Writer) error {
+	var chownUid, chownGid int
+	if opts.PackageChown != "" {
+		_, err := fmt.Sscanf(opts.PackageChown, "%d:%d", &chownUid, &chownGid)
+		if err != nil {
+			return fmt.Errorf("invalid value %q for PackageChown: %w", opts.PackageChown, err)
+		}
 	}
-	return 0
-}
-
-type builder struct {
-	PackageVersion string
-	SourcePath     string
-	OutputDir      string
-	SkipInstall    bool
-	logger         logrus.FieldLogger
-}
 
-func (bldr *builder) run(ctx context.Context, prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) error {
-	flags := flag.NewFlagSet("", flag.ContinueOnError)
-	flags.StringVar(&bldr.PackageVersion, "package-version", bldr.PackageVersion, "package version")
-	flags.StringVar(&bldr.SourcePath, "source", bldr.SourcePath, "source tree location")
-	flags.StringVar(&bldr.OutputDir, "output-directory", bldr.OutputDir, "destination directory for new package (default is cwd)")
-	flags.BoolVar(&bldr.SkipInstall, "skip-install", bldr.SkipInstall, "skip install step, assume you have already run 'arvados-server install -type package'")
-	err := flags.Parse(args)
-	if err != nil {
-		return err
-	}
-	if len(flags.Args()) > 0 {
-		return fmt.Errorf("unrecognized command line arguments: %v", flags.Args())
-	}
-	if !bldr.SkipInstall {
-		exitcode := install.Command.RunCommand("arvados-server install", []string{
-			"-type", "package",
-			"-package-version", bldr.PackageVersion,
-			"-source", bldr.SourcePath,
-		}, stdin, stdout, stderr)
-		if exitcode != 0 {
-			return fmt.Errorf("arvados-server install failed: exit code %d", exitcode)
-		}
+	exitcode := install.Command.RunCommand("arvados-server install", []string{
+		"-type", "package",
+		"-package-version", opts.PackageVersion,
+		"-source", opts.SourceDir,
+	}, stdin, stdout, stderr)
+	if exitcode != 0 {
+		return fmt.Errorf("arvados-server install failed: exit code %d", exitcode)
 	}
+
 	cmd := exec.Command("/var/lib/arvados/bin/gem", "install", "--user", "--no-document", "fpm")
 	cmd.Stdout = stdout
 	cmd.Stderr = stderr
-	err = cmd.Run()
+	err := cmd.Run()
 	if err != nil {
 		return fmt.Errorf("gem install fpm: %w", err)
 	}
@@ -94,10 +64,12 @@ func (bldr *builder) run(ctx context.Context, prog string, args []string, stdin
 	}
 
 	format := "deb" // TODO: rpm
+	pkgfile := filepath.Join(opts.PackageDir, "arvados-server-easy_"+opts.PackageVersion+"_amd64."+format)
 
 	cmd = exec.Command("/root/.gem/ruby/2.5.0/bin/fpm",
+		"--package", pkgfile,
 		"--name", "arvados-server-easy",
-		"--version", bldr.PackageVersion,
+		"--version", opts.PackageVersion,
 		"--input-type", "dir",
 		"--output-type", format)
 	deps, err := install.ProductionDependencies()
@@ -117,8 +89,25 @@ func (bldr *builder) run(ctx context.Context, prog string, args []string, stdin
 		"/var/www/.bundle",
 	)
 	fmt.Fprintf(stderr, "... %s\n", cmd.Args)
-	cmd.Dir = bldr.OutputDir
+	cmd.Dir = opts.PackageDir
+	cmd.Stdout = stdout
+	cmd.Stderr = stderr
+	err = cmd.Run()
+	if err != nil {
+		return fmt.Errorf("fpm: %w", err)
+	}
+
+	if opts.PackageChown != "" {
+		err = os.Chown(pkgfile, chownUid, chownGid)
+		if err != nil {
+			return fmt.Errorf("chown %s: %w", pkgfile, err)
+		}
+	}
+
+	cmd = exec.Command("ls", "-l", pkgfile)
 	cmd.Stdout = stdout
 	cmd.Stderr = stderr
-	return cmd.Run()
+	_ = cmd.Run()
+
+	return nil
 }
diff --git a/cmd/arvados-package/install.go b/cmd/arvados-package/install.go
new file mode 100644
index 000000000..719258a9b
--- /dev/null
+++ b/cmd/arvados-package/install.go
@@ -0,0 +1,143 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+package main
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
+)
+
+// sourcesfile=/tmp/sources.conf.d-arvados
+// echo >$sourcesfile "deb [trusted=yes] file:///pkg ./"
+
+// installimage="arvados-installpackage-${osbase}"
+// if [[ "${opts[force-installimage]}" || -z "$(docker images --format {{.Repository}} "${installimage}")" ]]; then
+//     echo >&2 building ${installimage}...
+//     installctr=${installimage/:/-}
+//     docker rm "${installctr}" || true
+//     docker run -it \
+//            --name "${installctr}" \
+//            --tmpfs /tmp \
+//            -v /tmp/pkg:/pkg:ro \
+//            -v ${sourcesfile}:/etc/apt/sources.list.d/arvados-local.list:ro \
+//            --env DEBIAN_FRONTEND=noninteractive \
+//            "${osbase}" \
+//            bash -c 'apt update && apt install -y eatmydata && eatmydata apt install -y arvados-server-easy postgresql && eatmydata apt remove -y arvados-server-easy'
+//     docker commit "${installctr}" "${installimage}"
+//     docker rm "${installctr}"
+//     installctr=
+// fi
+
+func testinstall(ctx context.Context, opts opts, stdin io.Reader, stdout, stderr io.Writer) error {
+	if opts.PackageVersion != "" {
+		return errors.New("not implemented: package version was specified, but I only know how to test the latest version in pkgdir")
+	}
+	depsImageName := "arvados-package-deps-" + opts.TargetOS
+	depsCtrName := strings.Replace(depsImageName, ":", "-", -1)
+
+	_, prog := filepath.Split(os.Args[0])
+	tmpdir, err := ioutil.TempDir("", prog+".")
+	if err != nil {
+		return fmt.Errorf("TempDir: %w", err)
+	}
+	defer os.RemoveAll(tmpdir)
+
+	sourcesFile := tmpdir + "/arvados-local.list"
+	err = ioutil.WriteFile(sourcesFile, []byte("deb [trusted=yes] file:///pkg ./\n"), 0644)
+	if err != nil {
+		return fmt.Errorf("Write %s: %w", sourcesFile, err)
+	}
+
+	if exists, err := dockerImageExists(ctx, depsImageName); err != nil {
+		return err
+	} else if !exists || opts.RebuildImage {
+		err = dockerRm(ctx, depsCtrName)
+		if err != nil {
+			return err
+		}
+		defer dockerRm(ctx, depsCtrName)
+		cmd := exec.CommandContext(ctx, "docker", "run",
+			"--name", depsCtrName,
+			"--tmpfs", "/tmp:exec,mode=01777",
+			"-v", opts.PackageDir+":/pkg:ro",
+			"-v", sourcesFile+":/etc/apt/sources.list.d/arvados-local.list:ro",
+			"--env", "DEBIAN_FRONTEND=noninteractive",
+			opts.TargetOS,
+			"bash", "-c", `
+set -e
+apt-get update
+apt-get install -y eatmydata
+eatmydata apt-get install -y --no-install-recommends arvados-server-easy postgresql
+eatmydata apt-get remove -y arvados-server-easy
+`)
+		cmd.Stdout = stdout
+		cmd.Stderr = stderr
+		err = cmd.Run()
+		if err != nil {
+			return fmt.Errorf("docker run: %w", err)
+		}
+
+		cmd = exec.CommandContext(ctx, "docker", "commit", depsCtrName, depsImageName)
+		cmd.Stdout = stdout
+		cmd.Stderr = stderr
+		err = cmd.Run()
+		if err != nil {
+			return fmt.Errorf("docker commit: %w", err)
+		}
+	}
+
+	cmd := exec.CommandContext(ctx, "docker", "run", "--rm",
+		"--tmpfs", "/tmp:exec,mode=01777",
+		"-v", opts.PackageDir+":/pkg:ro",
+		"-v", sourcesFile+":/etc/apt/sources.list.d/arvados-local.list:ro",
+		"--env", "DEBIAN_FRONTEND=noninteractive",
+		depsImageName,
+		"bash", "-c", `
+set -e
+PATH="/var/lib/arvados/bin:$PATH"
+apt-get update
+eatmydata apt-get install --reinstall -y --no-install-recommends arvados-server-easy
+apt-get -y autoremove
+/etc/init.d/postgresql start
+arvados-server init -cluster-id x1234
+exec arvados-server boot -listen-host 0.0.0.0 -shutdown
+`)
+	cmd.Stdout = stdout
+	cmd.Stderr = stderr
+	err = cmd.Run()
+	if err != nil {
+		return fmt.Errorf("docker run: %w", err)
+	}
+	return nil
+}
+
+func dockerImageExists(ctx context.Context, name string) (bool, error) {
+	cli, err := client.NewEnvClient()
+	if err != nil {
+		return false, err
+	}
+	imgs, err := cli.ImageList(ctx, types.ImageListOptions{All: true})
+	if err != nil {
+		return false, err
+	}
+	for _, img := range imgs {
+		for _, tag := range img.RepoTags {
+			if tag == name {
+				return true, nil
+			}
+		}
+	}
+	return false, nil
+}

commit 985ece13dd7147f153c7a59c5b3665570c5943c8
Author: Tom Clegg <tom at curii.com>
Date:   Tue Dec 29 15:18:19 2020 -0500

    16306: Rename arvados-dev buildpackage -> arvados-package build
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/cmd/arvados-dev/buildpackage.go b/cmd/arvados-package/build.go
similarity index 96%
rename from cmd/arvados-dev/buildpackage.go
rename to cmd/arvados-package/build.go
index a24fa47c9..1343ca77b 100644
--- a/cmd/arvados-dev/buildpackage.go
+++ b/cmd/arvados-package/build.go
@@ -17,9 +17,9 @@ import (
 	"github.com/sirupsen/logrus"
 )
 
-type buildPackage struct{}
+type build struct{}
 
-func (bld buildPackage) RunCommand(prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) int {
+func (bld build) RunCommand(prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) int {
 	logger := ctxlog.New(stderr, "text", "info")
 	err := (&builder{
 		PackageVersion: "0.0.0",
diff --git a/cmd/arvados-dev/buildpackage_test.go b/cmd/arvados-package/build_test.go
similarity index 86%
rename from cmd/arvados-dev/buildpackage_test.go
rename to cmd/arvados-package/build_test.go
index 61bdeae82..abb54532d 100644
--- a/cmd/arvados-dev/buildpackage_test.go
+++ b/cmd/arvados-package/build_test.go
@@ -27,13 +27,13 @@ func init() {
 	flag.StringVar(&buildimage, "test.buildimage", "debian:10", "docker image to use when running buildpackage")
 }
 
-type BuildpackageSuite struct{}
+type BuildSuite struct{}
 
-var _ = check.Suite(&BuildpackageSuite{})
+var _ = check.Suite(&BuildSuite{})
 
 func Test(t *testing.T) { check.TestingT(t) }
 
-func (s *BuildpackageSuite) TestBuildAndInstall(c *check.C) {
+func (s *BuildSuite) TestBuildAndInstall(c *check.C) {
 	if testing.Short() {
 		c.Skip("skipping docker tests in short mode")
 	} else if _, err := exec.Command("docker", "info").CombinedOutput(); err != nil {
@@ -59,10 +59,10 @@ func (s *BuildpackageSuite) TestBuildAndInstall(c *check.C) {
 
 	cmd = exec.Command("docker", "run", "--rm",
 		"-v", tmpdir+"/pkg:/pkg",
-		"-v", tmpdir+"/bin/arvados-dev:/arvados-dev:ro",
+		"-v", tmpdir+"/bin/arvados-package:/arvados-package:ro",
 		"-v", srctree+":/usr/local/src/arvados:ro",
 		buildimage,
-		"/arvados-dev", "buildpackage",
+		"/arvados-package", "build",
 		"-package-version", "0.9.99",
 		"-source", "/usr/local/src/arvados",
 		"-output-directory", "/pkg")
@@ -71,7 +71,7 @@ func (s *BuildpackageSuite) TestBuildAndInstall(c *check.C) {
 	err = cmd.Run()
 	c.Assert(err, check.IsNil)
 
-	fi, err := os.Stat(tmpdir + "/pkg/arvados-server_0.9.99_amd64.deb")
+	fi, err := os.Stat(tmpdir + "/pkg/arvados-server-easy_0.9.99_amd64.deb")
 	c.Assert(err, check.IsNil)
 	c.Logf("%#v", fi)
 }
diff --git a/cmd/arvados-dev/cmd.go b/cmd/arvados-package/cmd.go
similarity index 92%
rename from cmd/arvados-dev/cmd.go
rename to cmd/arvados-package/cmd.go
index e0d5144e5..02bc16cea 100644
--- a/cmd/arvados-dev/cmd.go
+++ b/cmd/arvados-package/cmd.go
@@ -16,7 +16,7 @@ var (
 		"-version":  cmd.Version,
 		"--version": cmd.Version,
 
-		"buildpackage": buildPackage{},
+		"build": build{},
 	})
 )
 
diff --git a/cmd/arvados-dev/docker-boot.sh b/cmd/arvados-package/docker-boot.sh
similarity index 100%
rename from cmd/arvados-dev/docker-boot.sh
rename to cmd/arvados-package/docker-boot.sh
diff --git a/cmd/arvados-dev/docker-build-install.sh b/cmd/arvados-package/docker-build-install.sh
similarity index 92%
rename from cmd/arvados-dev/docker-build-install.sh
rename to cmd/arvados-package/docker-build-install.sh
index 966318b94..4fdcccbce 100755
--- a/cmd/arvados-dev/docker-build-install.sh
+++ b/cmd/arvados-package/docker-build-install.sh
@@ -51,7 +51,7 @@ osbase=${opts[os]:-debian:10}
 
 mkdir -p /tmp/pkg
 
-buildimage=arvados-buildpackage-${osbase}
+buildimage=arvados-package-build-${osbase}
 if [[ "${opts[force-buildimage]}" || -z "$(docker images --format {{.Repository}} "${buildimage}")" ]]; then
     (
         echo >&2 building arvados-server...
@@ -81,19 +81,19 @@ pkgfile=/tmp/pkg/arvados-server-easy_${version}_amd64.deb
 rm -v -f "${pkgfile}"
 
 (
-    echo >&2 building arvados-dev...
-    cd cmd/arvados-dev
+    echo >&2 building arvados-package...
+    cd cmd/arvados-package
     go install
 )
 echo >&2 building ${pkgfile}...
 docker run --rm \
        --tmpfs /tmp:exec,mode=01777 \
        -v /tmp/pkg:/pkg \
-       -v "${GOPATH:-${HOME}/go}"/bin/arvados-dev:/arvados-dev:ro \
+       -v "${GOPATH:-${HOME}/go}"/bin/arvados-package:/arvados-package:ro \
        -v "$(pwd)":/arvados:ro \
        "${buildimage}" \
        eatmydata \
-       /arvados-dev buildpackage \
+       /arvados-package build \
        -source /arvados \
        -package-version "${version}" \
        -output-directory /pkg
@@ -119,7 +119,7 @@ if [[ "${opts[force-installimage]}" || -z "$(docker images --format {{.Repositor
            -v ${sourcesfile}:/etc/apt/sources.list.d/arvados-local.list:ro \
            --env DEBIAN_FRONTEND=noninteractive \
            "${osbase}" \
-           bash -c 'apt update && apt install -y eatmydata && eatmydata apt install -y arvados-server-easy postgresql'
+           bash -c 'apt update && apt install -y eatmydata && eatmydata apt install -y arvados-server-easy postgresql && eatmydata apt remove -y arvados-server-easy'
     docker commit "${installctr}" "${installimage}"
     docker rm "${installctr}"
     installctr=

commit e1756a76e8c7fed496f513909bd2c295e24cf8ee
Author: Tom Clegg <tom at curii.com>
Date:   Mon Dec 28 10:36:51 2020 -0500

    16306: Comment out Workbench2 so health check succeeds.
    
    To be re-enabled when supported by install/package/boot.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/lib/install/init.go b/lib/install/init.go
index 8debf59be..d4d9ef47e 100644
--- a/lib/install/init.go
+++ b/lib/install/init.go
@@ -149,10 +149,10 @@ func (initcmd *initCommand) RunCommand(prog string, args []string, stdin io.Read
         InternalURLs:
           "http://0.0.0.0:8001/": {}
         ExternalURL: {{printf "%q" ( print "https://workbench." .Domain "/" ) }}
-      Workbench2:
-        InternalURLs:
-          "http://0.0.0.0:8002/": {}
-        ExternalURL: {{printf "%q" ( print "https://workbench2." .Domain "/" ) }}
+      #Workbench2:
+      #  InternalURLs:
+      #    "http://0.0.0.0:8002/": {}
+      #  ExternalURL: {{printf "%q" ( print "https://workbench2." .Domain "/" ) }}
       Health:
         InternalURLs:
           "http://0.0.0.0:9007/": {}

commit 9c139cc4e2f519e2deb3617918a9199b76c33f10
Author: Tom Clegg <tom at curii.com>
Date:   Mon Dec 28 10:35:39 2020 -0500

    16306: Fix env var ordering.
    
    Ensure our GOBIN takes precedence over inherited value.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/lib/install/deps.go b/lib/install/deps.go
index 4f5b251cb..049df2564 100644
--- a/lib/install/deps.go
+++ b/lib/install/deps.go
@@ -508,7 +508,8 @@ rm ${zip}
 		} {
 			fmt.Fprintf(stderr, "building %s...\n", srcdir)
 			cmd := exec.Command("go", "install", "-ldflags", "-X git.arvados.org/arvados.git/lib/cmd.version="+inst.PackageVersion+" -X main.version="+inst.PackageVersion)
-			cmd.Env = append([]string{"GOBIN=/var/lib/arvados/bin"}, os.Environ()...)
+			cmd.Env = append(cmd.Env, os.Environ()...)
+			cmd.Env = append(cmd.Env, "GOBIN=/var/lib/arvados/bin")
 			cmd.Dir = filepath.Join(inst.SourcePath, srcdir)
 			cmd.Stdout = stdout
 			cmd.Stderr = stderr

commit ae339cf6802741ea52fbe5cd8716306dcf99b021
Author: Tom Clegg <tom at curii.com>
Date:   Mon Dec 28 10:35:26 2020 -0500

    16306: Remove more unneeded files from package.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/cmd/arvados-dev/buildpackage.go b/cmd/arvados-dev/buildpackage.go
index a6e0b544a..a24fa47c9 100644
--- a/cmd/arvados-dev/buildpackage.go
+++ b/cmd/arvados-dev/buildpackage.go
@@ -85,12 +85,12 @@ func (bldr *builder) run(ctx context.Context, prog string, args []string, stdin
 	// Remove unneeded files. This is much faster than "fpm
 	// --exclude X" because fpm copies everything into a staging
 	// area before looking at the --exclude args.
-	cmd = exec.Command("bash", "-c", "cd /var/www/.gem/ruby && rm -rf */cache */bundler/gems/*/.git /var/lib/arvados/go")
+	cmd = exec.Command("bash", "-c", "cd /var/www/.gem/ruby && rm -rf */cache */bundler/gems/*/.git */bundler/gems/arvados-*/[^s]* */bundler/gems/arvados-*/s[^d]* */bundler/gems/arvados-*/sdk/[^cr]* */gems/passenger-*/src/cxx* ruby/*/gems/*/ext /var/lib/arvados/go")
 	cmd.Stdout = stdout
 	cmd.Stderr = stderr
 	err = cmd.Run()
 	if err != nil {
-		return fmt.Errorf("rm -rf /var/www/.gem/ruby/*/cache/: %w", err)
+		return fmt.Errorf("rm -rf [...]: %w", err)
 	}
 
 	format := "deb" // TODO: rpm

commit 684b81a42cb9290bde284723603d6e4dbfd7ad35
Author: Tom Clegg <tom at curii.com>
Date:   Mon Dec 28 10:35:03 2020 -0500

    16306: Fix permission issues.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/lib/boot/supervisor.go b/lib/boot/supervisor.go
index 20576b6b9..7dba9b5dc 100644
--- a/lib/boot/supervisor.go
+++ b/lib/boot/supervisor.go
@@ -162,7 +162,7 @@ func (super *Supervisor) run(cfg *arvados.Config) error {
 	if err != nil {
 		return err
 	}
-	conffile, err := os.OpenFile(filepath.Join(super.tempdir, "config.yml"), os.O_CREATE|os.O_WRONLY, 0644)
+	conffile, err := os.OpenFile(filepath.Join(super.wwwtempdir, "config.yml"), os.O_CREATE|os.O_WRONLY, 0644)
 	if err != nil {
 		return err
 	}
diff --git a/lib/install/deps.go b/lib/install/deps.go
index 2b0faefe2..4f5b251cb 100644
--- a/lib/install/deps.go
+++ b/lib/install/deps.go
@@ -446,7 +446,7 @@ rm ${zip}
 		} {
 			fmt.Fprintf(stderr, "building %s...\n", srcdir)
 			cmd := exec.Command("rsync",
-				"-a", "--no-owner", "--delete-after", "--delete-excluded",
+				"-a", "--no-owner", "--no-group", "--delete-after", "--delete-excluded",
 				"--exclude", "/coverage",
 				"--exclude", "/log",
 				"--exclude", "/tmp",
@@ -469,7 +469,6 @@ rm ${zip}
 				{"sudo", "-u", "www-data", "/var/lib/arvados/bin/bundle", "exec", "passenger-config", "install-standalone-runtime"},
 			} {
 				cmd = exec.Command(cmdline[0], cmdline[1:]...)
-				cmd.Env = append([]string{}, os.Environ()...)
 				cmd.Dir = "/var/lib/arvados/" + dstdir
 				cmd.Stdout = stdout
 				cmd.Stderr = stderr

commit d77f9e6f8a14e14f477dfbf944914c78d0805e9f
Author: Tom Clegg <tom at curii.com>
Date:   Mon Dec 28 10:33:27 2020 -0500

    16306: Circumvent Rails redirect-to-https in workbench health check.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/sdk/go/health/aggregator.go b/sdk/go/health/aggregator.go
index 794adabdd..a666ef8ec 100644
--- a/sdk/go/health/aggregator.go
+++ b/sdk/go/health/aggregator.go
@@ -193,6 +193,9 @@ func (agg *Aggregator) ping(target *url.URL) (result CheckResult) {
 	}
 	req.Header.Set("Authorization", "Bearer "+agg.Cluster.ManagementToken)
 
+	// Avoid workbench1's redirect-http-to-https feature
+	req.Header.Set("X-Forwarded-Proto", "https")
+
 	ctx, cancel := context.WithTimeout(req.Context(), time.Duration(agg.timeout))
 	defer cancel()
 	req = req.WithContext(ctx)

commit 0137f9e3cd33fe676a862afd727563e2602e0984
Author: Tom Clegg <tom at curii.com>
Date:   Mon Dec 28 10:32:47 2020 -0500

    16306: Add health check endpoint to dispatcher.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/lib/dispatchcloud/dispatcher.go b/lib/dispatchcloud/dispatcher.go
index 7614a143a..ae91a710e 100644
--- a/lib/dispatchcloud/dispatcher.go
+++ b/lib/dispatchcloud/dispatcher.go
@@ -22,6 +22,7 @@ import (
 	"git.arvados.org/arvados.git/sdk/go/arvados"
 	"git.arvados.org/arvados.git/sdk/go/auth"
 	"git.arvados.org/arvados.git/sdk/go/ctxlog"
+	"git.arvados.org/arvados.git/sdk/go/health"
 	"git.arvados.org/arvados.git/sdk/go/httpserver"
 	"github.com/julienschmidt/httprouter"
 	"github.com/prometheus/client_golang/prometheus"
@@ -164,6 +165,11 @@ func (disp *dispatcher) initialize() {
 		})
 		mux.Handler("GET", "/metrics", metricsH)
 		mux.Handler("GET", "/metrics.json", metricsH)
+		mux.Handler("GET", "/_health/:check", &health.Handler{
+			Token:  disp.Cluster.ManagementToken,
+			Prefix: "/_health/",
+			Routes: health.Routes{"ping": disp.CheckHealth},
+		})
 		disp.httpHandler = auth.RequireLiteralToken(disp.Cluster.ManagementToken, mux)
 	}
 }

commit 6c1fd146c0b22b374f00ef94c961df8e1e1913a7
Author: Tom Clegg <tom at curii.com>
Date:   Mon Dec 28 10:32:13 2020 -0500

    16306: Use tmpfs to speed up package building.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/cmd/arvados-dev/docker-build-install.sh b/cmd/arvados-dev/docker-build-install.sh
index 7b7f25ff9..966318b94 100755
--- a/cmd/arvados-dev/docker-build-install.sh
+++ b/cmd/arvados-dev/docker-build-install.sh
@@ -63,7 +63,7 @@ if [[ "${opts[force-buildimage]}" || -z "$(docker images --format {{.Repository}
     docker rm "${buildctr}" || true
     docker run \
            --name "${buildctr}" \
-           -v /tmp/pkg:/pkg \
+           --tmpfs /tmp:exec,mode=01777 \
            -v "${GOPATH:-${HOME}/go}"/bin/arvados-server:/arvados-server:ro \
            -v "$(pwd)":/arvados:ro \
            "${osbase}" \
@@ -87,6 +87,7 @@ rm -v -f "${pkgfile}"
 )
 echo >&2 building ${pkgfile}...
 docker run --rm \
+       --tmpfs /tmp:exec,mode=01777 \
        -v /tmp/pkg:/pkg \
        -v "${GOPATH:-${HOME}/go}"/bin/arvados-dev:/arvados-dev:ro \
        -v "$(pwd)":/arvados:ro \
@@ -113,6 +114,7 @@ if [[ "${opts[force-installimage]}" || -z "$(docker images --format {{.Repositor
     docker rm "${installctr}" || true
     docker run -it \
            --name "${installctr}" \
+           --tmpfs /tmp \
            -v /tmp/pkg:/pkg:ro \
            -v ${sourcesfile}:/etc/apt/sources.list.d/arvados-local.list:ro \
            --env DEBIAN_FRONTEND=noninteractive \
diff --git a/lib/install/deps.go b/lib/install/deps.go
index 34fe7cc6d..2b0faefe2 100644
--- a/lib/install/deps.go
+++ b/lib/install/deps.go
@@ -224,17 +224,16 @@ func (inst *installCommand) RunCommand(prog string, args []string, stdin io.Read
 		logger.Print("ruby " + rubyversion + " already installed")
 	} else {
 		err = inst.runBash(`
-tmp=/var/lib/arvados/tmp/ruby-`+rubyversion+`
-trap "rm -r ${tmp}" ERR
-wget --progress=dot:giga -O- https://cache.ruby-lang.org/pub/ruby/2.5/ruby-`+rubyversion+`.tar.gz | tar -C /var/lib/arvados/tmp -xzf -
-cd ${tmp}
+tmp="$(mktemp -d)"
+trap 'rm -r "${tmp}"' ERR EXIT
+wget --progress=dot:giga -O- https://cache.ruby-lang.org/pub/ruby/2.5/ruby-`+rubyversion+`.tar.gz | tar -C "${tmp}" -xzf -
+cd "${tmp}/ruby-`+rubyversion+`"
 ./configure --disable-install-static-library --enable-shared --disable-install-doc --prefix /var/lib/arvados
 make -j8
 make install
 /var/lib/arvados/bin/gem install bundler --no-ri --no-rdoc
 # "gem update --system" can be removed when we use ruby ≥2.6.3: https://bundler.io/blog/2019/05/14/solutions-for-cant-find-gem-bundler-with-executable-bundle.html
 /var/lib/arvados/bin/gem update --system --no-ri --no-rdoc
-rm -r ${tmp}
 `, stdout, stderr)
 		if err != nil {
 			return 1

commit 706c36ff5644bb675af36c15c5f30ef0adde9102
Author: Tom Clegg <tom at curii.com>
Date:   Mon Dec 28 10:29:16 2020 -0500

    16306: Add -eatmydata flag.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/cmd/arvados-dev/docker-build-install.sh b/cmd/arvados-dev/docker-build-install.sh
index ff514a3b6..7b7f25ff9 100755
--- a/cmd/arvados-dev/docker-build-install.sh
+++ b/cmd/arvados-dev/docker-build-install.sh
@@ -68,6 +68,7 @@ if [[ "${opts[force-buildimage]}" || -z "$(docker images --format {{.Repository}
            -v "$(pwd)":/arvados:ro \
            "${osbase}" \
            /arvados-server install \
+           -eatmydata \
            -type package \
            -source /arvados \
            -package-version "${version}"
@@ -90,6 +91,7 @@ docker run --rm \
        -v "${GOPATH:-${HOME}/go}"/bin/arvados-dev:/arvados-dev:ro \
        -v "$(pwd)":/arvados:ro \
        "${buildimage}" \
+       eatmydata \
        /arvados-dev buildpackage \
        -source /arvados \
        -package-version "${version}" \
@@ -113,8 +115,9 @@ if [[ "${opts[force-installimage]}" || -z "$(docker images --format {{.Repositor
            --name "${installctr}" \
            -v /tmp/pkg:/pkg:ro \
            -v ${sourcesfile}:/etc/apt/sources.list.d/arvados-local.list:ro \
+           --env DEBIAN_FRONTEND=noninteractive \
            "${osbase}" \
-           bash -c 'apt update && DEBIAN_FRONTEND=noninteractive apt install -y arvados-server-easy postgresql'
+           bash -c 'apt update && apt install -y eatmydata && eatmydata apt install -y arvados-server-easy postgresql'
     docker commit "${installctr}" "${installimage}"
     docker rm "${installctr}"
     installctr=
@@ -125,4 +128,4 @@ docker run -it --rm \
        -v /tmp/pkg:/pkg:ro \
        -v ${sourcesfile}:/etc/apt/sources.list.d/arvados-local.list:ro \
        "${installimage}" \
-       bash -c 'apt update && DEBIAN_FRONTEND=noninteractive apt install --reinstall -y arvados-server-easy postgresql && /etc/init.d/postgresql start && /var/lib/arvados/bin/arvados-server init -cluster-id x1234 && /var/lib/arvados/bin/arvados-server boot -listen-host 0.0.0.0'
+       bash -c 'apt update && DEBIAN_FRONTEND=noninteractive eatmydata apt install --reinstall -y arvados-server-easy postgresql && /etc/init.d/postgresql start && /var/lib/arvados/bin/arvados-server init -cluster-id x1234 && /var/lib/arvados/bin/arvados-server boot -listen-host 0.0.0.0'
diff --git a/lib/install/deps.go b/lib/install/deps.go
index cc9595db6..34fe7cc6d 100644
--- a/lib/install/deps.go
+++ b/lib/install/deps.go
@@ -34,6 +34,7 @@ type installCommand struct {
 	ClusterType    string
 	SourcePath     string
 	PackageVersion string
+	EatMyData      bool
 }
 
 func (inst *installCommand) RunCommand(prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) int {
@@ -55,6 +56,7 @@ func (inst *installCommand) RunCommand(prog string, args []string, stdin io.Read
 	flags.StringVar(&inst.ClusterType, "type", "production", "cluster `type`: development, test, production, or package")
 	flags.StringVar(&inst.SourcePath, "source", "/arvados", "source tree location (required for -type=package)")
 	flags.StringVar(&inst.PackageVersion, "package-version", "0.0.0", "version string to embed in executable files")
+	flags.BoolVar(&inst.EatMyData, "eatmydata", false, "use eatmydata to speed up install")
 	err = flags.Parse(args)
 	if err == flag.ErrHelp {
 		err = nil
@@ -109,11 +111,23 @@ func (inst *installCommand) RunCommand(prog string, args []string, stdin io.Read
 		}
 	}
 
+	if inst.EatMyData {
+		cmd := exec.CommandContext(ctx, "apt-get", "install", "--yes", "--no-install-recommends", "eatmydata")
+		cmd.Env = append(os.Environ(), "DEBIAN_FRONTEND=noninteractive")
+		cmd.Stdout = stdout
+		cmd.Stderr = stderr
+		err = cmd.Run()
+		if err != nil {
+			return 1
+		}
+	}
+
 	pkgs := prodpkgs(osv)
 
 	if pkg {
 		pkgs = append(pkgs,
 			"dpkg-dev",
+			"eatmydata", // install it for later steps, even if we're not using it now
 			"rsync",
 		)
 	}
@@ -174,7 +188,11 @@ func (inst *installCommand) RunCommand(prog string, args []string, stdin io.Read
 		default:
 			pkgs = append(pkgs, "libcurl3")
 		}
-		cmd := exec.CommandContext(ctx, "apt-get", "install", "--yes", "--no-install-recommends")
+		cmd := exec.CommandContext(ctx, "apt-get")
+		if inst.EatMyData {
+			cmd = exec.CommandContext(ctx, "eatmydata", "apt-get")
+		}
+		cmd.Args = append(cmd.Args, "install", "--yes", "--no-install-recommends")
 		cmd.Args = append(cmd.Args, pkgs...)
 		cmd.Env = append(os.Environ(), "DEBIAN_FRONTEND=noninteractive")
 		cmd.Stdout = stdout
@@ -205,7 +223,7 @@ func (inst *installCommand) RunCommand(prog string, args []string, stdin io.Read
 	if haverubyversion, err := exec.Command("/var/lib/arvados/bin/ruby", "-v").CombinedOutput(); err == nil && bytes.HasPrefix(haverubyversion, []byte("ruby "+rubyversion)) {
 		logger.Print("ruby " + rubyversion + " already installed")
 	} else {
-		err = runBash(`
+		err = inst.runBash(`
 tmp=/var/lib/arvados/tmp/ruby-`+rubyversion+`
 trap "rm -r ${tmp}" ERR
 wget --progress=dot:giga -O- https://cache.ruby-lang.org/pub/ruby/2.5/ruby-`+rubyversion+`.tar.gz | tar -C /var/lib/arvados/tmp -xzf -
@@ -228,7 +246,7 @@ rm -r ${tmp}
 		if havegoversion, err := exec.Command("/usr/local/bin/go", "version").CombinedOutput(); err == nil && bytes.HasPrefix(havegoversion, []byte("go version go"+goversion+" ")) {
 			logger.Print("go " + goversion + " already installed")
 		} else {
-			err = runBash(`
+			err = inst.runBash(`
 cd /tmp
 wget --progress=dot:giga -O- https://storage.googleapis.com/golang/go`+goversion+`.linux-amd64.tar.gz | tar -C /var/lib/arvados -xzf -
 ln -sf /var/lib/arvados/go/bin/* /usr/local/bin/
@@ -244,7 +262,7 @@ ln -sf /var/lib/arvados/go/bin/* /usr/local/bin/
 		if havepjsversion, err := exec.Command("/usr/local/bin/phantomjs", "--version").CombinedOutput(); err == nil && string(havepjsversion) == "1.9.8\n" {
 			logger.Print("phantomjs " + pjsversion + " already installed")
 		} else {
-			err = runBash(`
+			err = inst.runBash(`
 PJS=phantomjs-`+pjsversion+`-linux-x86_64
 wget --progress=dot:giga -O- https://bitbucket.org/ariya/phantomjs/downloads/$PJS.tar.bz2 | tar -C /var/lib/arvados -xjf -
 ln -sf /var/lib/arvados/$PJS/bin/phantomjs /usr/local/bin/
@@ -258,7 +276,7 @@ ln -sf /var/lib/arvados/$PJS/bin/phantomjs /usr/local/bin/
 		if havegeckoversion, err := exec.Command("/usr/local/bin/geckodriver", "--version").CombinedOutput(); err == nil && strings.Contains(string(havegeckoversion), " "+geckoversion+" ") {
 			logger.Print("geckodriver " + geckoversion + " already installed")
 		} else {
-			err = runBash(`
+			err = inst.runBash(`
 GD=v`+geckoversion+`
 wget --progress=dot:giga -O- https://github.com/mozilla/geckodriver/releases/download/$GD/geckodriver-$GD-linux64.tar.gz | tar -C /var/lib/arvados/bin -xzf - geckodriver
 ln -sf /var/lib/arvados/bin/geckodriver /usr/local/bin/
@@ -272,7 +290,7 @@ ln -sf /var/lib/arvados/bin/geckodriver /usr/local/bin/
 		if havenodejsversion, err := exec.Command("/usr/local/bin/node", "--version").CombinedOutput(); err == nil && string(havenodejsversion) == nodejsversion+"\n" {
 			logger.Print("nodejs " + nodejsversion + " already installed")
 		} else {
-			err = runBash(`
+			err = inst.runBash(`
 NJS=`+nodejsversion+`
 wget --progress=dot:giga -O- https://nodejs.org/dist/${NJS}/node-${NJS}-linux-x64.tar.xz | sudo tar -C /var/lib/arvados -xJf -
 ln -sf /var/lib/arvados/node-${NJS}-linux-x64/bin/{node,npm} /usr/local/bin/
@@ -286,7 +304,7 @@ ln -sf /var/lib/arvados/node-${NJS}-linux-x64/bin/{node,npm} /usr/local/bin/
 		if havegradleversion, err := exec.Command("/usr/local/bin/gradle", "--version").CombinedOutput(); err == nil && strings.Contains(string(havegradleversion), "Gradle "+gradleversion+"\n") {
 			logger.Print("gradle " + gradleversion + " already installed")
 		} else {
-			err = runBash(`
+			err = inst.runBash(`
 G=`+gradleversion+`
 zip=/var/lib/arvados/tmp/gradle-${G}-bin.zip
 trap "rm ${zip}" ERR
@@ -307,7 +325,7 @@ rm ${zip}
 		if havelocales, err := exec.Command("locale", "-a").CombinedOutput(); err == nil && bytes.Contains(havelocales, []byte(strings.Replace(wantlocale+"\n", "UTF-", "utf", 1))) {
 			logger.Print("locale " + wantlocale + " already installed")
 		} else {
-			err = runBash(`sed -i 's/^# *\(`+wantlocale+`\)/\1/' /etc/locale.gen && locale-gen`, stdout, stderr)
+			err = inst.runBash(`sed -i 's/^# *\(`+wantlocale+`\)/\1/' /etc/locale.gen && locale-gen`, stdout, stderr)
 			if err != nil {
 				return 1
 			}
@@ -386,7 +404,7 @@ rm ${zip}
 			// locales. Otherwise, it might need a
 			// restart, so we attempt to restart it with
 			// systemd.
-			if err = runBash(`sudo systemctl restart postgresql`, stdout, stderr); err != nil {
+			if err = inst.runBash(`sudo systemctl restart postgresql`, stdout, stderr); err != nil {
 				logger.Warn("`systemctl restart postgresql` failed; hoping postgresql does not need to be restarted")
 			} else if err = waitPostgreSQLReady(); err != nil {
 				return 1
@@ -585,8 +603,11 @@ func waitPostgreSQLReady() error {
 	}
 }
 
-func runBash(script string, stdout, stderr io.Writer) error {
+func (inst *installCommand) runBash(script string, stdout, stderr io.Writer) error {
 	cmd := exec.Command("bash", "-")
+	if inst.EatMyData {
+		cmd = exec.Command("eatmydata", "bash", "-")
+	}
 	cmd.Stdin = bytes.NewBufferString("set -ex -o pipefail\n" + script)
 	cmd.Stdout = stdout
 	cmd.Stderr = stderr

commit 3aaefcb3c76ff470b475d950398d01255e87712a
Merge: c59af50bc 2c8874c06
Author: Tom Clegg <tom at curii.com>
Date:   Tue Dec 22 16:48:37 2020 -0500

    16306: Merge branch 'master'
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --cc doc/install/index.html.textile.liquid
index 81d7b2159,1b27ca6ed..f16ae2dad
--- a/doc/install/index.html.textile.liquid
+++ b/doc/install/index.html.textile.liquid
@@@ -20,11 -20,12 +20,13 @@@ Arvados components can be installed an
  <div class="offset1">
  table(table table-bordered table-condensed).
  |||\5=. Appropriate for|
- ||_. Ease of setup|_. Multiuser/networked access|_. Workflow Development and Testing|_. Large Scale Production|_. Development of Arvados|_. Arvados Evaluation|
+ ||_. Setup difficulty|_. Multiuser/networked access|_. Workflow Development and Testing|_. Large Scale Production|_. Development of Arvados|_. Arvados Evaluation|
  |"Arvados-in-a-box":arvbox.html (arvbox)|Easy|no|yes|no|yes|yes|
+ |"Installation with Salt":salt-single-host.html (single host)|Easy|no|yes|no|yes|yes|
+ |"Installation with Salt":salt-multi-host.html (multi host)|Moderate|yes|yes|yes|yes|yes|
  |"Arvados on Kubernetes":arvados-on-kubernetes.html|Easy ^1^|yes|yes ^2^|no ^2^|no|yes|
 +|"Automatic single-node install":automatic.html (experimental)|Easy|yes|yes|no|yes|yes|
- |"Manual installation":install-manual-prerequisites.html|Complicated|yes|yes|yes|no|no|
+ |"Manual installation":install-manual-prerequisites.html|Hard|yes|yes|yes|no|no|
  |"Cluster Operation Subscription supported by Curii":mailto:info at curii.com|N/A ^3^|yes|yes|yes|yes|yes|
  </div>
  
diff --cc lib/install/deps.go
index da45b393b,342ef03a7..cc9595db6
--- a/lib/install/deps.go
+++ b/lib/install/deps.go
@@@ -124,8 -101,10 +124,9 @@@ func (inst *installCommand) RunCommand(
  			"bison",
  			"bsdmainutils",
  			"build-essential",
 -			"ca-certificates",
  			"cadaver",
- 			"cython",
+ 			"curl",
+ 			"cython3",
  			"daemontools", // lib/boot uses setuidgid to drop privileges when running as root
  			"default-jdk-headless",
  			"default-jre-headless",
@@@ -136,9 -120,13 +137,9 @@@
  			"libfuse-dev",
  			"libgnutls28-dev",
  			"libjson-perl",
 -			"libjson-perl",
  			"libpam-dev",
  			"libpcre3-dev",
- 			"libpython2.7-dev",
+ 			"libpq-dev",
  			"libreadline-dev",
  			"libssl-dev",
  			"libwww-perl",
@@@ -154,22 -142,28 +155,27 @@@
  			"postgresql",
  			"postgresql-contrib",
  			"python3-dev",
- 			"python-epydoc",
+ 			"python3-venv",
+ 			"python3-virtualenv",
  			"r-base",
  			"r-cran-testthat",
+ 			"r-cran-devtools",
+ 			"r-cran-knitr",
+ 			"r-cran-markdown",
+ 			"r-cran-roxygen2",
+ 			"r-cran-xml",
  			"sudo",
- 			"virtualenv",
  			"wget",
  			"xvfb",
 -			"zlib1g-dev",
 -		}
 +		)
  		switch {
  		case osv.Debian && osv.Major >= 10:
 -			debs = append(debs, "libcurl4")
 +			pkgs = append(pkgs, "libcurl4")
  		default:
 -			debs = append(debs, "libcurl3")
 +			pkgs = append(pkgs, "libcurl3")
  		}
  		cmd := exec.CommandContext(ctx, "apt-get", "install", "--yes", "--no-install-recommends")
 -		cmd.Args = append(cmd.Args, debs...)
 +		cmd.Args = append(cmd.Args, pkgs...)
  		cmd.Env = append(os.Environ(), "DEBIAN_FRONTEND=noninteractive")
  		cmd.Stdout = stdout
  		cmd.Stderr = stderr

commit c59af50bc2f7a366cd12a8dd6fc7d7e3b1c32480
Author: Tom Clegg <tom at curii.com>
Date:   Tue Dec 22 16:15:21 2020 -0500

    16306: Move nginx temp dirs into a subdir.
    
    When running as root, Nginx changes ownership of these temp dirs to
    "nobody".  We also use the same TMPDIR for standalone passenger
    processes, which run as www-data, so we need Nginx to leave it alone.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/sdk/python/tests/nginx.conf b/sdk/python/tests/nginx.conf
index cdca68dd6..a4336049f 100644
--- a/sdk/python/tests/nginx.conf
+++ b/sdk/python/tests/nginx.conf
@@ -11,11 +11,11 @@ http {
     '[$time_local] "$http_x_request_id" $server_name $status $body_bytes_sent $request_time $request_method "$scheme://$http_host$request_uri" $remote_addr:$remote_port '
     '"$http_referer" "$http_user_agent"';
   access_log "{{ACCESSLOG}}" customlog;
-  client_body_temp_path "{{TMPDIR}}";
-  proxy_temp_path "{{TMPDIR}}";
-  fastcgi_temp_path "{{TMPDIR}}";
-  uwsgi_temp_path "{{TMPDIR}}";
-  scgi_temp_path "{{TMPDIR}}";
+  client_body_temp_path "{{TMPDIR}}/nginx";
+  proxy_temp_path "{{TMPDIR}}/nginx";
+  fastcgi_temp_path "{{TMPDIR}}/nginx";
+  uwsgi_temp_path "{{TMPDIR}}/nginx";
+  scgi_temp_path "{{TMPDIR}}/nginx";
   upstream controller {
     server {{LISTENHOST}}:{{CONTROLLERPORT}};
   }

commit f1bc1872a9ead4f3cb1c23c79507870c1b0f7b53
Author: Tom Clegg <tom at curii.com>
Date:   Tue Dec 22 16:14:55 2020 -0500

    16306: Remove some unneeded deps from prod/pkg.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/lib/install/deps.go b/lib/install/deps.go
index 38f9e888d..da45b393b 100644
--- a/lib/install/deps.go
+++ b/lib/install/deps.go
@@ -120,6 +120,8 @@ func (inst *installCommand) RunCommand(prog string, args []string, stdin io.Read
 
 	if dev || test || pkg {
 		pkgs = append(pkgs,
+			"automake",
+			"bison",
 			"bsdmainutils",
 			"build-essential",
 			"cadaver",
@@ -144,6 +146,7 @@ func (inst *installCommand) RunCommand(prog string, args []string, stdin io.Read
 			"libxslt1-dev",
 			"linkchecker",
 			"lsof",
+			"make",
 			"net-tools",
 			"pandoc",
 			"perl-modules",
@@ -412,14 +415,20 @@ rm ${zip}
 		}
 	}
 
-	if pkg {
+	if prod || pkg {
 		// Install Rails apps to /var/lib/arvados/{railsapi,workbench1}/
 		for dstdir, srcdir := range map[string]string{
 			"railsapi":   "services/api",
 			"workbench1": "apps/workbench",
 		} {
 			fmt.Fprintf(stderr, "building %s...\n", srcdir)
-			cmd := exec.Command("rsync", "-a", "--no-owner", "--delete-after", "--exclude", "/tmp", "--exclude", "/log", "--exclude", "/vendor", "./", "/var/lib/arvados/"+dstdir+"/")
+			cmd := exec.Command("rsync",
+				"-a", "--no-owner", "--delete-after", "--delete-excluded",
+				"--exclude", "/coverage",
+				"--exclude", "/log",
+				"--exclude", "/tmp",
+				"--exclude", "/vendor",
+				"./", "/var/lib/arvados/"+dstdir+"/")
 			cmd.Dir = filepath.Join(inst.SourcePath, srcdir)
 			cmd.Stdout = stdout
 			cmd.Stderr = stderr
@@ -580,8 +589,6 @@ func runBash(script string, stdout, stderr io.Writer) error {
 
 func prodpkgs(osv osversion) []string {
 	pkgs := []string{
-		"automake",
-		"bison",
 		"ca-certificates",
 		"curl",
 		"fuse",
@@ -591,7 +598,6 @@ func prodpkgs(osv osversion) []string {
 		"haveged",
 		"libcurl3-gnutls",
 		"libxslt1.1",
-		"make",
 		"nginx",
 		"python",
 		"sudo",

commit 3feaf72ad2a9a7b740bb3976f351f5020129eda4
Author: Tom Clegg <tom at curii.com>
Date:   Tue Dec 22 16:13:49 2020 -0500

    16306: Monkeypatch fpm bug.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/cmd/arvados-dev/buildpackage.go b/cmd/arvados-dev/buildpackage.go
index 76228324e..a6e0b544a 100644
--- a/cmd/arvados-dev/buildpackage.go
+++ b/cmd/arvados-dev/buildpackage.go
@@ -9,6 +9,7 @@ import (
 	"flag"
 	"fmt"
 	"io"
+	"os"
 	"os/exec"
 
 	"git.arvados.org/arvados.git/lib/install"
@@ -70,6 +71,17 @@ func (bldr *builder) run(ctx context.Context, prog string, args []string, stdin
 		return fmt.Errorf("gem install fpm: %w", err)
 	}
 
+	if _, err := os.Stat("/root/.gem/ruby/2.5.0/gems/fpm-1.11.0/lib/fpm/package/deb.rb"); err == nil {
+		// Workaround for fpm bug https://github.com/jordansissel/fpm/issues/1739
+		cmd = exec.Command("sed", "-i", `/require "digest"/a require "zlib"`, "/root/.gem/ruby/2.5.0/gems/fpm-1.11.0/lib/fpm/package/deb.rb")
+		cmd.Stdout = stdout
+		cmd.Stderr = stderr
+		err = cmd.Run()
+		if err != nil {
+			return fmt.Errorf("monkeypatch fpm: %w", err)
+		}
+	}
+
 	// Remove unneeded files. This is much faster than "fpm
 	// --exclude X" because fpm copies everything into a staging
 	// area before looking at the --exclude args.

commit 209403e32bdd6164404240af2959de86a3c46165
Author: Tom Clegg <tom at curii.com>
Date:   Tue Dec 22 16:13:45 2020 -0500

    16306: Comment why rm instead of exclude. Delete go tools, too.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/cmd/arvados-dev/buildpackage.go b/cmd/arvados-dev/buildpackage.go
index 93482e1c7..76228324e 100644
--- a/cmd/arvados-dev/buildpackage.go
+++ b/cmd/arvados-dev/buildpackage.go
@@ -69,8 +69,11 @@ func (bldr *builder) run(ctx context.Context, prog string, args []string, stdin
 	if err != nil {
 		return fmt.Errorf("gem install fpm: %w", err)
 	}
-	// Shrink our package, remove unneeded stuff
-	cmd = exec.Command("bash", "-c", "rm -rf /var/www/.gem/ruby/*/cache/ /var/www/.gem/ruby/*/bundler/gems/arvados-*/.git /var/www/.gem/ruby/*/bundler/gems/nulldb-*/.git /var/www/.gem/ruby/*/bundler/gems/themes_for_rails-*/.git")
+
+	// Remove unneeded files. This is much faster than "fpm
+	// --exclude X" because fpm copies everything into a staging
+	// area before looking at the --exclude args.
+	cmd = exec.Command("bash", "-c", "cd /var/www/.gem/ruby && rm -rf */cache */bundler/gems/*/.git /var/lib/arvados/go")
 	cmd.Stdout = stdout
 	cmd.Stderr = stderr
 	err = cmd.Run()
@@ -93,12 +96,9 @@ func (bldr *builder) run(ctx context.Context, prog string, args []string, stdin
 		cmd.Args = append(cmd.Args, "--depends", pkg)
 	}
 	cmd.Args = append(cmd.Args,
+		"--verbose",
 		"--deb-use-file-permissions",
 		"--rpm-use-file-permissions",
-		"--exclude", "var/lib/arvados/go",
-		"--exclude", "tmp",
-		"--exclude", "log",
-		"--exclude", "coverage",
 		"/var/lib/arvados",
 		"/var/www/.gem",
 		"/var/www/.passenger",

commit 54849feb0cf30bd3d78f14f1a41e6bc464fb80d6
Author: Tom Clegg <tom at curii.com>
Date:   Tue Dec 22 10:19:43 2020 -0500

    16306: Fix Nginx not starting when running as non-root.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/lib/boot/nginx.go b/lib/boot/nginx.go
index 07ff1fc1d..d49fabe56 100644
--- a/lib/boot/nginx.go
+++ b/lib/boot/nginx.go
@@ -12,6 +12,7 @@ import (
 	"net/url"
 	"os"
 	"os/exec"
+	"os/user"
 	"path/filepath"
 	"regexp"
 
@@ -100,13 +101,26 @@ func (runNginx) Run(ctx context.Context, fail func(error), super *Supervisor) er
 			}
 		}
 	}
+
+	args := []string{
+		"-g", "error_log stderr info;",
+		"-g", "pid " + filepath.Join(super.wwwtempdir, "nginx.pid") + ";",
+		"-c", conffile,
+	}
+	// Nginx ignores "user www-data;" when running as a non-root
+	// user... except that it causes it to ignore our other -g
+	// options. So we still have to decide for ourselves whether
+	// it's needed.
+	if u, err := user.Current(); err != nil {
+		return fmt.Errorf("user.Current(): %w", err)
+	} else if u.Uid == "0" {
+		args = append([]string{"-g", "user www-data;"}, args...)
+	}
+
 	super.waitShutdown.Add(1)
 	go func() {
 		defer super.waitShutdown.Done()
-		fail(super.RunProgram(ctx, ".", nil, nil, nginx,
-			"-g", "error_log stderr info;",
-			"-g", "user www-data; pid "+filepath.Join(super.wwwtempdir, "nginx.pid")+";",
-			"-c", conffile))
+		fail(super.RunProgram(ctx, ".", nil, nil, nginx, args...))
 	}()
 	// Choose one of the ports where Nginx should listen, and wait
 	// here until we can connect. If ExternalURL is https://foo (with no port) then we connect to "foo:https"
diff --git a/lib/boot/postgresql.go b/lib/boot/postgresql.go
index 199a93a9d..fc23eb913 100644
--- a/lib/boot/postgresql.go
+++ b/lib/boot/postgresql.go
@@ -42,7 +42,7 @@ func (runPostgreSQL) Run(ctx context.Context, fail func(error), super *Superviso
 
 	iamroot := false
 	if u, err := user.Current(); err != nil {
-		return fmt.Errorf("user.Current(): %s", err)
+		return fmt.Errorf("user.Current(): %w", err)
 	} else if u.Uid == "0" {
 		iamroot = true
 	}

commit d5c034b4e90d3fba74e5b0a879d8af424023d7b1
Author: Tom Clegg <tom at curii.com>
Date:   Tue Dec 22 10:03:30 2020 -0500

    16360: Don't bypass autofillConfig in production mode.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/lib/boot/supervisor.go b/lib/boot/supervisor.go
index 417f09d23..138c802e1 100644
--- a/lib/boot/supervisor.go
+++ b/lib/boot/supervisor.go
@@ -143,7 +143,6 @@ func (super *Supervisor) run(cfg *arvados.Config) error {
 		super.tempdir = "/var/lib/arvados/tmp"
 		super.wwwtempdir = "/var/lib/arvados/wwwtmp"
 		super.bindir = "/var/lib/arvados/bin"
-		super.configfile = "/etc/arvados/config.yml"
 	} else {
 		super.tempdir, err = ioutil.TempDir("", "arvados-server-boot-")
 		if err != nil {
@@ -155,28 +154,28 @@ func (super *Supervisor) run(cfg *arvados.Config) error {
 		if err := os.Mkdir(super.bindir, 0755); err != nil {
 			return err
 		}
+	}
 
-		// Fill in any missing config keys, and write the resulting
-		// config in the temp dir for child services to use.
-		err = super.autofillConfig(cfg)
-		if err != nil {
-			return err
-		}
-		conffile, err := os.OpenFile(filepath.Join(super.tempdir, "config.yml"), os.O_CREATE|os.O_WRONLY, 0644)
-		if err != nil {
-			return err
-		}
-		defer conffile.Close()
-		err = json.NewEncoder(conffile).Encode(cfg)
-		if err != nil {
-			return err
-		}
-		err = conffile.Close()
-		if err != nil {
-			return err
-		}
-		super.configfile = conffile.Name()
+	// Fill in any missing config keys, and write the resulting
+	// config in the temp dir for child services to use.
+	err = super.autofillConfig(cfg)
+	if err != nil {
+		return err
+	}
+	conffile, err := os.OpenFile(filepath.Join(super.tempdir, "config.yml"), os.O_CREATE|os.O_WRONLY, 0644)
+	if err != nil {
+		return err
+	}
+	defer conffile.Close()
+	err = json.NewEncoder(conffile).Encode(cfg)
+	if err != nil {
+		return err
 	}
+	err = conffile.Close()
+	if err != nil {
+		return err
+	}
+	super.configfile = conffile.Name()
 
 	super.environ = os.Environ()
 	super.cleanEnv([]string{"ARVADOS_"})
@@ -655,26 +654,26 @@ func (super *Supervisor) autofillConfig(cfg *arvados.Config) error {
 			}
 		}
 	}
-	if cluster.SystemRootToken == "" {
-		cluster.SystemRootToken = randomHexString(64)
-	}
-	if cluster.ManagementToken == "" {
-		cluster.ManagementToken = randomHexString(64)
-	}
-	if cluster.API.RailsSessionSecretToken == "" {
-		cluster.API.RailsSessionSecretToken = randomHexString(64)
-	}
-	if cluster.Collections.BlobSigningKey == "" {
-		cluster.Collections.BlobSigningKey = randomHexString(64)
-	}
-	if super.ClusterType != "production" && cluster.Containers.DispatchPrivateKey == "" {
-		buf, err := ioutil.ReadFile(filepath.Join(super.SourcePath, "lib", "dispatchcloud", "test", "sshkey_dispatch"))
-		if err != nil {
-			return err
-		}
-		cluster.Containers.DispatchPrivateKey = string(buf)
-	}
 	if super.ClusterType != "production" {
+		if cluster.SystemRootToken == "" {
+			cluster.SystemRootToken = randomHexString(64)
+		}
+		if cluster.ManagementToken == "" {
+			cluster.ManagementToken = randomHexString(64)
+		}
+		if cluster.API.RailsSessionSecretToken == "" {
+			cluster.API.RailsSessionSecretToken = randomHexString(64)
+		}
+		if cluster.Collections.BlobSigningKey == "" {
+			cluster.Collections.BlobSigningKey = randomHexString(64)
+		}
+		if cluster.Containers.DispatchPrivateKey == "" {
+			buf, err := ioutil.ReadFile(filepath.Join(super.SourcePath, "lib", "dispatchcloud", "test", "sshkey_dispatch"))
+			if err != nil {
+				return err
+			}
+			cluster.Containers.DispatchPrivateKey = string(buf)
+		}
 		cluster.TLS.Insecure = true
 	}
 	if super.ClusterType == "test" {

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list