[arvados] updated: 2.7.0-6584-gb22c56b714

git repository hosting git at public.arvados.org
Wed May 15 23:01:52 UTC 2024


Summary of changes:
 .licenseignore                                     |    1 +
 build/run-tests.sh                                 |   19 +-
 doc/_config.yml                                    |   12 -
 doc/admin/scoped-tokens.html.textile.liquid        |    2 -
 doc/admin/upgrading.html.textile.liquid            |   15 +
 doc/admin/user-management-cli.html.textile.liquid  |    2 -
 .../api_client_authorizations.html.textile.liquid  |    1 -
 doc/install/salt-multi-host.html.textile.liquid    |   14 +-
 lib/config/config.default.yml                      |   53 +-
 lib/config/export.go                               |    5 -
 lib/controller/handler_test.go                     |   24 +-
 lib/controller/integration_test.go                 |   10 +-
 lib/controller/localdb/log_activity.go             |    7 +-
 lib/controller/trash.go                            |   32 +-
 lib/crunchrun/crunchrun.go                         |   90 +-
 lib/crunchrun/crunchrun_test.go                    |  227 +-
 lib/crunchrun/cuda.go                              |    8 +-
 lib/crunchrun/logging.go                           |  396 +--
 lib/crunchrun/logging_test.go                      |  192 +-
 sdk/R/README.md                                    |    2 +-
 sdk/cwl/arvados_version.py                         |    8 -
 sdk/cwl/pytest.ini                                 |    1 +
 sdk/cwl/tests/test_copy_deps.py                    |   12 +-
 sdk/cwl/tests/test_set_output_prop.py              |    4 +-
 sdk/go/arvados/api_client_authorization.go         |    2 -
 sdk/go/arvados/client.go                           |    4 +
 sdk/go/arvados/config.go                           |   18 +-
 sdk/go/arvados/job.go                              |    1 -
 sdk/go/arvados/keep_cache.go                       |    6 +-
 sdk/go/arvados/pipeline_instance.go                |    1 -
 sdk/go/arvados/pipeline_template.go                |    1 -
 sdk/go/arvados/trait.go                            |    1 -
 sdk/go/arvadosclient/arvadosclient.go              |    5 +
 sdk/go/keepclient/discover.go                      |    6 +-
 sdk/go/keepclient/keepclient.go                    |   16 +-
 sdk/go/keepclient/keepclient_test.go               |    3 -
 sdk/go/keepclient/support.go                       |   30 +-
 sdk/python/arvados-v1-discovery.json               | 2785 ++++----------------
 sdk/python/arvados/__init__.py                     |  135 +-
 sdk/python/arvados/api.py                          |   46 -
 sdk/python/arvados/collection.py                   |  451 ----
 sdk/python/arvados/crunch.py                       |   34 -
 sdk/python/arvados/util.py                         |  315 ---
 sdk/python/arvados_version.py                      |    8 -
 sdk/python/{bin/arv-ws => pytest.ini}              |    5 +-
 sdk/python/setup.py                                |    1 -
 sdk/python/tests/run_test_server.py                |    5 +-
 sdk/python/tests/slow_test.py                      |   11 -
 sdk/python/tests/test_api.py                       |   15 -
 sdk/python/tests/test_arv_put.py                   |    3 +-
 sdk/python/tests/test_crunch.py                    |   31 -
 sdk/python/tests/test_util.py                      |   30 -
 .../v1/api_client_authorizations_controller.rb     |    8 +-
 .../controllers/arvados/v1/schema_controller.rb    |   49 +-
 .../api/app/models/api_client_authorization.rb     |   11 +-
 services/api/config/arvados_config.rb              |   10 -
 services/api/lib/create_superuser_token.rb         |   10 +-
 .../api_client_authorizations_scopes_test.rb       |    2 +-
 services/api/test/unit/arvados_model_test.rb       |    6 +-
 services/api/test/unit/group_test.rb               |    4 +-
 services/dockercleaner/arvados_version.py          |    8 -
 services/dockercleaner/pytest.ini                  |    1 +
 services/dockercleaner/setup.py                    |    1 -
 services/fuse/arvados_version.py                   |    8 -
 services/fuse/pytest.ini                           |    1 +
 services/fuse/setup.py                             |    1 -
 services/fuse/tests/integration_test.py            |   16 +-
 services/fuse/tests/mount_test_base.py             |   16 +-
 services/fuse/tests/performance/__init__.py        |    0
 .../fuse/tests/performance/performance_profiler.py |    1 -
 .../performance/test_collection_performance.py     |  488 ----
 services/fuse/tests/slow_test.py                   |    1 -
 services/keep-balance/integration_test.go          |    2 +-
 services/keep-web/cache.go                         |    5 +-
 .../workbench2/cypress/e2e/banner-tooltip.cy.js    |    9 +-
 .../src/store/advanced-tab/advanced-tab.tsx        |    4 +-
 tools/crunchstat-summary/arvados_version.py        |    8 -
 tools/crunchstat-summary/pytest.ini                |    1 +
 tools/crunchstat-summary/setup.py                  |    1 -
 tools/salt-install/installer.sh                    |   36 +-
 tools/salt-install/terraform/aws/services/main.tf  |    1 +
 tools/user-activity/arvados_version.py             |    8 -
 tools/user-activity/pytest.ini                     |    1 +
 83 files changed, 1050 insertions(+), 4774 deletions(-)
 create mode 120000 sdk/cwl/pytest.ini
 delete mode 100644 sdk/python/arvados/crunch.py
 copy sdk/python/{bin/arv-ws => pytest.ini} (73%)
 mode change 100755 => 100644
 delete mode 100644 sdk/python/tests/slow_test.py
 delete mode 100644 sdk/python/tests/test_crunch.py
 create mode 120000 services/dockercleaner/pytest.ini
 create mode 120000 services/fuse/pytest.ini
 delete mode 100644 services/fuse/tests/performance/__init__.py
 delete mode 120000 services/fuse/tests/performance/performance_profiler.py
 delete mode 100644 services/fuse/tests/performance/test_collection_performance.py
 delete mode 120000 services/fuse/tests/slow_test.py
 create mode 120000 tools/crunchstat-summary/pytest.ini
 create mode 120000 tools/user-activity/pytest.ini

       via  b22c56b7148b10bcae5b15d42e522c50cdeb5c0c (commit)
       via  c0c3cedc411f1e5c446ce1423be0e2a4e1ec2df8 (commit)
       via  28fb2fc7ebc231e91e6831aca12edc57bf604ae4 (commit)
       via  5754d95ba6da4cd949ea2788e79bac9e87bdddaf (commit)
       via  29b8327c0b741f9ed92baa57e7ebdb45e2267c6a (commit)
       via  6bd3ba426afa94cfab04f1619f50f8b7f6509024 (commit)
       via  019c07a3ab1a24700a652a1484430e564526e6e8 (commit)
       via  84650a094921bb149ffb31a95bee9875dfd1c1df (commit)
       via  18322a336bb994d02e630fd9b398351d5346a32d (commit)
       via  80ac334d1ded6139d9c1ae59b0e257b1138fad39 (commit)
       via  b1ffc878a5ea6ba083b8fbc8f20c15c7a6f1e1ec (commit)
       via  5208605890afc290d28d43cf6c4ebf88f989ba47 (commit)
       via  f11933fe893204fc0378d83b25167eb14ba4a265 (commit)
       via  62810af07121274e38a85dcb9c1d7cf5512815d2 (commit)
       via  c0c47d765087ade9cfe749bb4afc29c7c64892de (commit)
       via  ef4f350438ec7465b5fd71aeda834c2a707b80b3 (commit)
       via  218b4d51dd9b31604a37d78bb602151bdc2af4d6 (commit)
       via  7b2e98f3880b8c3dfc1155a29dd3a9b36f5d7976 (commit)
       via  6a1a9849137351b7ddbfe52011174ea3182f4b30 (commit)
       via  c28159e9eda5bdd027792a20fa8d0ad04efb74f7 (commit)
       via  f15670e518fb8bf8b2fd26eb3efd6d34c2f8b78b (commit)
       via  d7eff3ca2b97bd1729e85c3c85547c9519957b51 (commit)
       via  3b7b36a745e07b09bfa61932f5de2e22fb42a4e7 (commit)
       via  1c0fbb6e173cabf66db7ef0ee64e32db19626af4 (commit)
       via  887751a6c862fdd9184f5f9c58e6bfaa61269e23 (commit)
       via  e3de17acb936b9b6795ca6ff610d40a950ba5ff3 (commit)
       via  dcdaf7450fb66da2bc904a21f29660ac75e5864a (commit)
       via  6e3b86c8e0c90d71a7920d595e1087ffe465130e (commit)
       via  8a5db7b48c1fb11423110490267fea17161f7674 (commit)
       via  5fb720b670c3bd986898d7597e700cb12d1647ae (commit)
       via  f049ebcb40b5509413f73840ead3ef8893f9331b (commit)
       via  b0079c916db05e728cca119333e6dd6a1afd8a83 (commit)
       via  52048aaf666d2ce32d387fe02c8469cb050fdbb7 (commit)
       via  47a0e74fd1c13060fc3e38fe30dafc8686b5d113 (commit)
       via  b8751a1a220ea451d44303268ea9207c2152aed2 (commit)
       via  c58300cc5eff7a227d8a0499ac3dc2c125ad4c3e (commit)
       via  9de62c160f7cc9c9c994e4ced447cd5bef88333e (commit)
       via  2f7673c45f9945ba04eabba97a4bdf4d3d340688 (commit)
       via  6ff9889d875d23780114ad74d90e07c890fce8d6 (commit)
       via  92d6698f3c2d1c8109a9cf08f25da408c3a7b442 (commit)
       via  09fdded2857597bd3d3ea5a0029fecbe993130ee (commit)
       via  c57b6ac55b1eaeae3786d1d83158f22e3d8e253f (commit)
       via  5dfd9a57f9d65ea91295e8502cf7f6e748fc4010 (commit)
       via  b73b1475bdfdfd5431912e4a6af0f6306a8f5aa5 (commit)
      from  a1cc22fad427a935d7747bd6dc2c6b901c8a799a (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 b22c56b7148b10bcae5b15d42e522c50cdeb5c0c
Author: Tom Clegg <tom at curii.com>
Date:   Wed May 15 19:01:02 2024 -0400

    15397: Remove deprecated Python SDK facilities.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/sdk/python/arvados/__init__.py b/sdk/python/arvados/__init__.py
index 83f658201c..81a20dd15f 100644
--- a/sdk/python/arvados/__init__.py
+++ b/sdk/python/arvados/__init__.py
@@ -28,7 +28,7 @@ from collections import UserDict
 
 from . import api, errors, util
 from .api import api_from_config, http_cache
-from .collection import CollectionReader, CollectionWriter, ResumableCollectionWriter
+from .collection import CollectionReader
 from arvados.keep import *
 from arvados.stream import *
 from .arvfile import StreamFileReader
@@ -55,136 +55,3 @@ logger = stdliblog.getLogger('arvados')
 logger.addHandler(log_handler)
 logger.setLevel(stdliblog.DEBUG if config.get('ARVADOS_DEBUG')
                 else stdliblog.WARNING)
-
- at util._deprecated('3.0', 'arvados-cwl-runner or the containers API')
-def task_set_output(self, s, num_retries=5):
-    for tries_left in RetryLoop(num_retries=num_retries, backoff_start=0):
-        try:
-            return api('v1').job_tasks().update(
-                uuid=self['uuid'],
-                body={
-                    'output':s,
-                    'success':True,
-                    'progress':1.0
-                }).execute()
-        except errors.ApiError as error:
-            if retry.check_http_response_success(error.resp.status) is None and tries_left > 0:
-                logger.debug("task_set_output: job_tasks().update() raised {}, retrying with {} tries left".format(repr(error),tries_left))
-            else:
-                raise
-
-_current_task = None
- at util._deprecated('3.0', 'arvados-cwl-runner or the containers API')
-def current_task(num_retries=5):
-    global _current_task
-    if _current_task:
-        return _current_task
-
-    for tries_left in RetryLoop(num_retries=num_retries, backoff_start=2):
-        try:
-            task = api('v1').job_tasks().get(uuid=os.environ['TASK_UUID']).execute()
-            task = UserDict(task)
-            task.set_output = types.MethodType(task_set_output, task)
-            task.tmpdir = os.environ['TASK_WORK']
-            _current_task = task
-            return task
-        except errors.ApiError as error:
-            if retry.check_http_response_success(error.resp.status) is None and tries_left > 0:
-                logger.debug("current_task: job_tasks().get() raised {}, retrying with {} tries left".format(repr(error),tries_left))
-            else:
-                raise
-
-_current_job = None
- at util._deprecated('3.0', 'arvados-cwl-runner or the containers API')
-def current_job(num_retries=5):
-    global _current_job
-    if _current_job:
-        return _current_job
-
-    for tries_left in RetryLoop(num_retries=num_retries, backoff_start=2):
-        try:
-            job = api('v1').jobs().get(uuid=os.environ['JOB_UUID']).execute()
-            job = UserDict(job)
-            job.tmpdir = os.environ['JOB_WORK']
-            _current_job = job
-            return job
-        except errors.ApiError as error:
-            if retry.check_http_response_success(error.resp.status) is None and tries_left > 0:
-                logger.debug("current_job: jobs().get() raised {}, retrying with {} tries left".format(repr(error),tries_left))
-            else:
-                raise
-
- at util._deprecated('3.0', 'arvados-cwl-runner or the containers API')
-def getjobparam(*args):
-    return current_job()['script_parameters'].get(*args)
-
- at util._deprecated('3.0', 'arvados-cwl-runner or the containers API')
-def get_job_param_mount(*args):
-    return os.path.join(os.environ['TASK_KEEPMOUNT'], current_job()['script_parameters'].get(*args))
-
- at util._deprecated('3.0', 'arvados-cwl-runner or the containers API')
-def get_task_param_mount(*args):
-    return os.path.join(os.environ['TASK_KEEPMOUNT'], current_task()['parameters'].get(*args))
-
-class JobTask(object):
-    @util._deprecated('3.0', 'arvados-cwl-runner or the containers API')
-    def __init__(self, parameters=dict(), runtime_constraints=dict()):
-        print("init jobtask %s %s" % (parameters, runtime_constraints))
-
-class job_setup(object):
-    @staticmethod
-    @util._deprecated('3.0', 'arvados-cwl-runner or the containers API')
-    def one_task_per_input_file(if_sequence=0, and_end_task=True, input_as_path=False, api_client=None):
-        if if_sequence != current_task()['sequence']:
-            return
-
-        if not api_client:
-            api_client = api('v1')
-
-        job_input = current_job()['script_parameters']['input']
-        cr = CollectionReader(job_input, api_client=api_client)
-        cr.normalize()
-        for s in cr.all_streams():
-            for f in s.all_files():
-                if input_as_path:
-                    task_input = os.path.join(job_input, s.name(), f.name())
-                else:
-                    task_input = f.as_manifest()
-                new_task_attrs = {
-                    'job_uuid': current_job()['uuid'],
-                    'created_by_job_task_uuid': current_task()['uuid'],
-                    'sequence': if_sequence + 1,
-                    'parameters': {
-                        'input':task_input
-                        }
-                    }
-                api_client.job_tasks().create(body=new_task_attrs).execute()
-        if and_end_task:
-            api_client.job_tasks().update(uuid=current_task()['uuid'],
-                                       body={'success':True}
-                                       ).execute()
-            exit(0)
-
-    @staticmethod
-    @util._deprecated('3.0', 'arvados-cwl-runner or the containers API')
-    def one_task_per_input_stream(if_sequence=0, and_end_task=True):
-        if if_sequence != current_task()['sequence']:
-            return
-        job_input = current_job()['script_parameters']['input']
-        cr = CollectionReader(job_input)
-        for s in cr.all_streams():
-            task_input = s.tokens()
-            new_task_attrs = {
-                'job_uuid': current_job()['uuid'],
-                'created_by_job_task_uuid': current_task()['uuid'],
-                'sequence': if_sequence + 1,
-                'parameters': {
-                    'input':task_input
-                    }
-                }
-            api('v1').job_tasks().create(body=new_task_attrs).execute()
-        if and_end_task:
-            api('v1').job_tasks().update(uuid=current_task()['uuid'],
-                                       body={'success':True}
-                                       ).execute()
-            exit(0)
diff --git a/sdk/python/arvados/api.py b/sdk/python/arvados/api.py
index 8a17e42fcb..0cfaf19238 100644
--- a/sdk/python/arvados/api.py
+++ b/sdk/python/arvados/api.py
@@ -496,49 +496,3 @@ def api_from_config(
     docstring for more information about their meaning.
     """
     return api(**api_kwargs_from_config(version, apiconfig, **kwargs))
-
-class OrderedJsonModel(apiclient.model.JsonModel):
-    """Model class for JSON that preserves the contents' order
-
-    .. WARNING:: Deprecated
-       This model is redundant now that Python dictionaries preserve insertion
-       ordering. Code that passes this model to API constructors can remove it.
-
-    In Python versions before 3.6, API clients that cared about preserving the
-    order of fields in API server responses could use this model to do so.
-    Typical usage looked like:
-
-        from arvados.api import OrderedJsonModel
-        client = arvados.api('v1', ..., model=OrderedJsonModel())
-    """
-    @util._deprecated(preferred="the default model and rely on Python's built-in dictionary ordering")
-    def __init__(self, data_wrapper=False):
-        return super().__init__(data_wrapper)
-
-
-RETRY_DELAY_INITIAL = 0
-"""
-.. WARNING:: Deprecated
-   This constant was used by retry code in previous versions of the Arvados SDK.
-   Changing the value has no effect anymore.
-   Prefer passing `num_retries` to an API client constructor instead.
-   Refer to the constructor docstrings for details.
-"""
-
-RETRY_DELAY_BACKOFF = 0
-"""
-.. WARNING:: Deprecated
-   This constant was used by retry code in previous versions of the Arvados SDK.
-   Changing the value has no effect anymore.
-   Prefer passing `num_retries` to an API client constructor instead.
-   Refer to the constructor docstrings for details.
-"""
-
-RETRY_COUNT = 0
-"""
-.. WARNING:: Deprecated
-   This constant was used by retry code in previous versions of the Arvados SDK.
-   Changing the value has no effect anymore.
-   Prefer passing `num_retries` to an API client constructor instead.
-   Refer to the constructor docstrings for details.
-"""
diff --git a/sdk/python/arvados/collection.py b/sdk/python/arvados/collection.py
index 1050d4c093..b002ec59ab 100644
--- a/sdk/python/arvados/collection.py
+++ b/sdk/python/arvados/collection.py
@@ -1854,454 +1854,3 @@ class CollectionReader(Collection):
                     self._streams = []
             return orig_func(self, *args, **kwargs)
         return populate_streams_wrapper
-
-    @arvados.util._deprecated('3.0', 'Collection iteration')
-    @_populate_streams
-    def normalize(self):
-        """Normalize the streams returned by `all_streams`"""
-        streams = {}
-        for s in self.all_streams():
-            for f in s.all_files():
-                streamname, filename = split(s.name() + "/" + f.name())
-                if streamname not in streams:
-                    streams[streamname] = {}
-                if filename not in streams[streamname]:
-                    streams[streamname][filename] = []
-                for r in f.segments:
-                    streams[streamname][filename].extend(s.locators_and_ranges(r.locator, r.range_size))
-
-        self._streams = [normalize_stream(s, streams[s])
-                         for s in sorted(streams)]
-
-    @arvados.util._deprecated('3.0', 'Collection iteration')
-    @_populate_streams
-    def all_streams(self):
-        return [StreamReader(s, self._my_keep(), num_retries=self.num_retries)
-                for s in self._streams]
-
-    @arvados.util._deprecated('3.0', 'Collection iteration')
-    @_populate_streams
-    def all_files(self):
-        for s in self.all_streams():
-            for f in s.all_files():
-                yield f
-
-
-class CollectionWriter(CollectionBase):
-    """Create a new collection from scratch
-
-    .. WARNING:: Deprecated
-       This class is deprecated. Prefer `arvados.collection.Collection`
-       instead.
-    """
-
-    @arvados.util._deprecated('3.0', 'arvados.collection.Collection')
-    def __init__(self, api_client=None, num_retries=0, replication=None):
-        """Instantiate a CollectionWriter.
-
-        CollectionWriter lets you build a new Arvados Collection from scratch.
-        Write files to it.  The CollectionWriter will upload data to Keep as
-        appropriate, and provide you with the Collection manifest text when
-        you're finished.
-
-        Arguments:
-        * api_client: The API client to use to look up Collections.  If not
-          provided, CollectionReader will build one from available Arvados
-          configuration.
-        * num_retries: The default number of times to retry failed
-          service requests.  Default 0.  You may change this value
-          after instantiation, but note those changes may not
-          propagate to related objects like the Keep client.
-        * replication: The number of copies of each block to store.
-          If this argument is None or not supplied, replication is
-          the server-provided default if available, otherwise 2.
-        """
-        self._api_client = api_client
-        self.num_retries = num_retries
-        self.replication = (2 if replication is None else replication)
-        self._keep_client = None
-        self._data_buffer = []
-        self._data_buffer_len = 0
-        self._current_stream_files = []
-        self._current_stream_length = 0
-        self._current_stream_locators = []
-        self._current_stream_name = '.'
-        self._current_file_name = None
-        self._current_file_pos = 0
-        self._finished_streams = []
-        self._close_file = None
-        self._queued_file = None
-        self._queued_dirents = deque()
-        self._queued_trees = deque()
-        self._last_open = None
-
-    def __exit__(self, exc_type, exc_value, traceback):
-        if exc_type is None:
-            self.finish()
-
-    def do_queued_work(self):
-        # The work queue consists of three pieces:
-        # * _queued_file: The file object we're currently writing to the
-        #   Collection.
-        # * _queued_dirents: Entries under the current directory
-        #   (_queued_trees[0]) that we want to write or recurse through.
-        #   This may contain files from subdirectories if
-        #   max_manifest_depth == 0 for this directory.
-        # * _queued_trees: Directories that should be written as separate
-        #   streams to the Collection.
-        # This function handles the smallest piece of work currently queued
-        # (current file, then current directory, then next directory) until
-        # no work remains.  The _work_THING methods each do a unit of work on
-        # THING.  _queue_THING methods add a THING to the work queue.
-        while True:
-            if self._queued_file:
-                self._work_file()
-            elif self._queued_dirents:
-                self._work_dirents()
-            elif self._queued_trees:
-                self._work_trees()
-            else:
-                break
-
-    def _work_file(self):
-        while True:
-            buf = self._queued_file.read(config.KEEP_BLOCK_SIZE)
-            if not buf:
-                break
-            self.write(buf)
-        self.finish_current_file()
-        if self._close_file:
-            self._queued_file.close()
-        self._close_file = None
-        self._queued_file = None
-
-    def _work_dirents(self):
-        path, stream_name, max_manifest_depth = self._queued_trees[0]
-        if stream_name != self.current_stream_name():
-            self.start_new_stream(stream_name)
-        while self._queued_dirents:
-            dirent = self._queued_dirents.popleft()
-            target = os.path.join(path, dirent)
-            if os.path.isdir(target):
-                self._queue_tree(target,
-                                 os.path.join(stream_name, dirent),
-                                 max_manifest_depth - 1)
-            else:
-                self._queue_file(target, dirent)
-                break
-        if not self._queued_dirents:
-            self._queued_trees.popleft()
-
-    def _work_trees(self):
-        path, stream_name, max_manifest_depth = self._queued_trees[0]
-        d = arvados.util.listdir_recursive(
-            path, max_depth = (None if max_manifest_depth == 0 else 0))
-        if d:
-            self._queue_dirents(stream_name, d)
-        else:
-            self._queued_trees.popleft()
-
-    def _queue_file(self, source, filename=None):
-        assert (self._queued_file is None), "tried to queue more than one file"
-        if not hasattr(source, 'read'):
-            source = open(source, 'rb')
-            self._close_file = True
-        else:
-            self._close_file = False
-        if filename is None:
-            filename = os.path.basename(source.name)
-        self.start_new_file(filename)
-        self._queued_file = source
-
-    def _queue_dirents(self, stream_name, dirents):
-        assert (not self._queued_dirents), "tried to queue more than one tree"
-        self._queued_dirents = deque(sorted(dirents))
-
-    def _queue_tree(self, path, stream_name, max_manifest_depth):
-        self._queued_trees.append((path, stream_name, max_manifest_depth))
-
-    def write_file(self, source, filename=None):
-        self._queue_file(source, filename)
-        self.do_queued_work()
-
-    def write_directory_tree(self,
-                             path, stream_name='.', max_manifest_depth=-1):
-        self._queue_tree(path, stream_name, max_manifest_depth)
-        self.do_queued_work()
-
-    def write(self, newdata):
-        if isinstance(newdata, bytes):
-            pass
-        elif isinstance(newdata, str):
-            newdata = newdata.encode()
-        elif hasattr(newdata, '__iter__'):
-            for s in newdata:
-                self.write(s)
-            return
-        self._data_buffer.append(newdata)
-        self._data_buffer_len += len(newdata)
-        self._current_stream_length += len(newdata)
-        while self._data_buffer_len >= config.KEEP_BLOCK_SIZE:
-            self.flush_data()
-
-    def open(self, streampath, filename=None):
-        """open(streampath[, filename]) -> file-like object
-
-        Pass in the path of a file to write to the Collection, either as a
-        single string or as two separate stream name and file name arguments.
-        This method returns a file-like object you can write to add it to the
-        Collection.
-
-        You may only have one file object from the Collection open at a time,
-        so be sure to close the object when you're done.  Using the object in
-        a with statement makes that easy:
-
-            with cwriter.open('./doc/page1.txt') as outfile:
-                outfile.write(page1_data)
-            with cwriter.open('./doc/page2.txt') as outfile:
-                outfile.write(page2_data)
-        """
-        if filename is None:
-            streampath, filename = split(streampath)
-        if self._last_open and not self._last_open.closed:
-            raise errors.AssertionError(
-                u"can't open '{}' when '{}' is still open".format(
-                    filename, self._last_open.name))
-        if streampath != self.current_stream_name():
-            self.start_new_stream(streampath)
-        self.set_current_file_name(filename)
-        self._last_open = _WriterFile(self, filename)
-        return self._last_open
-
-    def flush_data(self):
-        data_buffer = b''.join(self._data_buffer)
-        if data_buffer:
-            self._current_stream_locators.append(
-                self._my_keep().put(
-                    data_buffer[0:config.KEEP_BLOCK_SIZE],
-                    copies=self.replication))
-            self._data_buffer = [data_buffer[config.KEEP_BLOCK_SIZE:]]
-            self._data_buffer_len = len(self._data_buffer[0])
-
-    def start_new_file(self, newfilename=None):
-        self.finish_current_file()
-        self.set_current_file_name(newfilename)
-
-    def set_current_file_name(self, newfilename):
-        if re.search(r'[\t\n]', newfilename):
-            raise errors.AssertionError(
-                "Manifest filenames cannot contain whitespace: %s" %
-                newfilename)
-        elif re.search(r'\x00', newfilename):
-            raise errors.AssertionError(
-                "Manifest filenames cannot contain NUL characters: %s" %
-                newfilename)
-        self._current_file_name = newfilename
-
-    def current_file_name(self):
-        return self._current_file_name
-
-    def finish_current_file(self):
-        if self._current_file_name is None:
-            if self._current_file_pos == self._current_stream_length:
-                return
-            raise errors.AssertionError(
-                "Cannot finish an unnamed file " +
-                "(%d bytes at offset %d in '%s' stream)" %
-                (self._current_stream_length - self._current_file_pos,
-                 self._current_file_pos,
-                 self._current_stream_name))
-        self._current_stream_files.append([
-                self._current_file_pos,
-                self._current_stream_length - self._current_file_pos,
-                self._current_file_name])
-        self._current_file_pos = self._current_stream_length
-        self._current_file_name = None
-
-    def start_new_stream(self, newstreamname='.'):
-        self.finish_current_stream()
-        self.set_current_stream_name(newstreamname)
-
-    def set_current_stream_name(self, newstreamname):
-        if re.search(r'[\t\n]', newstreamname):
-            raise errors.AssertionError(
-                "Manifest stream names cannot contain whitespace: '%s'" %
-                (newstreamname))
-        self._current_stream_name = '.' if newstreamname=='' else newstreamname
-
-    def current_stream_name(self):
-        return self._current_stream_name
-
-    def finish_current_stream(self):
-        self.finish_current_file()
-        self.flush_data()
-        if not self._current_stream_files:
-            pass
-        elif self._current_stream_name is None:
-            raise errors.AssertionError(
-                "Cannot finish an unnamed stream (%d bytes in %d files)" %
-                (self._current_stream_length, len(self._current_stream_files)))
-        else:
-            if not self._current_stream_locators:
-                self._current_stream_locators.append(config.EMPTY_BLOCK_LOCATOR)
-            self._finished_streams.append([self._current_stream_name,
-                                           self._current_stream_locators,
-                                           self._current_stream_files])
-        self._current_stream_files = []
-        self._current_stream_length = 0
-        self._current_stream_locators = []
-        self._current_stream_name = None
-        self._current_file_pos = 0
-        self._current_file_name = None
-
-    def finish(self):
-        """Store the manifest in Keep and return its locator.
-
-        This is useful for storing manifest fragments (task outputs)
-        temporarily in Keep during a Crunch job.
-
-        In other cases you should make a collection instead, by
-        sending manifest_text() to the API server's "create
-        collection" endpoint.
-        """
-        return self._my_keep().put(self.manifest_text().encode(),
-                                   copies=self.replication)
-
-    def portable_data_hash(self):
-        stripped = self.stripped_manifest().encode()
-        return '{}+{}'.format(hashlib.md5(stripped).hexdigest(), len(stripped))
-
-    def manifest_text(self):
-        self.finish_current_stream()
-        manifest = ''
-
-        for stream in self._finished_streams:
-            if not re.search(r'^\.(/.*)?$', stream[0]):
-                manifest += './'
-            manifest += stream[0].replace(' ', '\\040')
-            manifest += ' ' + ' '.join(stream[1])
-            manifest += ' ' + ' '.join("%d:%d:%s" % (sfile[0], sfile[1], sfile[2].replace(' ', '\\040')) for sfile in stream[2])
-            manifest += "\n"
-
-        return manifest
-
-    def data_locators(self):
-        ret = []
-        for name, locators, files in self._finished_streams:
-            ret += locators
-        return ret
-
-    def save_new(self, name=None):
-        return self._api_client.collections().create(
-            ensure_unique_name=True,
-            body={
-                'name': name,
-                'manifest_text': self.manifest_text(),
-            }).execute(num_retries=self.num_retries)
-
-
-class ResumableCollectionWriter(CollectionWriter):
-    """CollectionWriter that can serialize internal state to disk
-
-    .. WARNING:: Deprecated
-       This class is deprecated. Prefer `arvados.collection.Collection`
-       instead.
-    """
-
-    STATE_PROPS = ['_current_stream_files', '_current_stream_length',
-                   '_current_stream_locators', '_current_stream_name',
-                   '_current_file_name', '_current_file_pos', '_close_file',
-                   '_data_buffer', '_dependencies', '_finished_streams',
-                   '_queued_dirents', '_queued_trees']
-
-    @arvados.util._deprecated('3.0', 'arvados.collection.Collection')
-    def __init__(self, api_client=None, **kwargs):
-        self._dependencies = {}
-        super(ResumableCollectionWriter, self).__init__(api_client, **kwargs)
-
-    @classmethod
-    def from_state(cls, state, *init_args, **init_kwargs):
-        # Try to build a new writer from scratch with the given state.
-        # If the state is not suitable to resume (because files have changed,
-        # been deleted, aren't predictable, etc.), raise a
-        # StaleWriterStateError.  Otherwise, return the initialized writer.
-        # The caller is responsible for calling writer.do_queued_work()
-        # appropriately after it's returned.
-        writer = cls(*init_args, **init_kwargs)
-        for attr_name in cls.STATE_PROPS:
-            attr_value = state[attr_name]
-            attr_class = getattr(writer, attr_name).__class__
-            # Coerce the value into the same type as the initial value, if
-            # needed.
-            if attr_class not in (type(None), attr_value.__class__):
-                attr_value = attr_class(attr_value)
-            setattr(writer, attr_name, attr_value)
-        # Check dependencies before we try to resume anything.
-        if any(KeepLocator(ls).permission_expired()
-               for ls in writer._current_stream_locators):
-            raise errors.StaleWriterStateError(
-                "locators include expired permission hint")
-        writer.check_dependencies()
-        if state['_current_file'] is not None:
-            path, pos = state['_current_file']
-            try:
-                writer._queued_file = open(path, 'rb')
-                writer._queued_file.seek(pos)
-            except IOError as error:
-                raise errors.StaleWriterStateError(
-                    u"failed to reopen active file {}: {}".format(path, error))
-        return writer
-
-    def check_dependencies(self):
-        for path, orig_stat in self._dependencies.items():
-            if not S_ISREG(orig_stat[ST_MODE]):
-                raise errors.StaleWriterStateError(u"{} not file".format(path))
-            try:
-                now_stat = tuple(os.stat(path))
-            except OSError as error:
-                raise errors.StaleWriterStateError(
-                    u"failed to stat {}: {}".format(path, error))
-            if ((not S_ISREG(now_stat[ST_MODE])) or
-                (orig_stat[ST_MTIME] != now_stat[ST_MTIME]) or
-                (orig_stat[ST_SIZE] != now_stat[ST_SIZE])):
-                raise errors.StaleWriterStateError(u"{} changed".format(path))
-
-    def dump_state(self, copy_func=lambda x: x):
-        state = {attr: copy_func(getattr(self, attr))
-                 for attr in self.STATE_PROPS}
-        if self._queued_file is None:
-            state['_current_file'] = None
-        else:
-            state['_current_file'] = (os.path.realpath(self._queued_file.name),
-                                      self._queued_file.tell())
-        return state
-
-    def _queue_file(self, source, filename=None):
-        try:
-            src_path = os.path.realpath(source)
-        except Exception:
-            raise errors.AssertionError(u"{} not a file path".format(source))
-        try:
-            path_stat = os.stat(src_path)
-        except OSError as stat_error:
-            path_stat = None
-        super(ResumableCollectionWriter, self)._queue_file(source, filename)
-        fd_stat = os.fstat(self._queued_file.fileno())
-        if not S_ISREG(fd_stat.st_mode):
-            # We won't be able to resume from this cache anyway, so don't
-            # worry about further checks.
-            self._dependencies[source] = tuple(fd_stat)
-        elif path_stat is None:
-            raise errors.AssertionError(
-                u"could not stat {}: {}".format(source, stat_error))
-        elif path_stat.st_ino != fd_stat.st_ino:
-            raise errors.AssertionError(
-                u"{} changed between open and stat calls".format(source))
-        else:
-            self._dependencies[src_path] = tuple(fd_stat)
-
-    def write(self, data):
-        if self._queued_file is None:
-            raise errors.AssertionError(
-                "resumable writer can't accept unsourced data")
-        return super(ResumableCollectionWriter, self).write(data)
diff --git a/sdk/python/arvados/crunch.py b/sdk/python/arvados/crunch.py
deleted file mode 100644
index 57cf2e01ef..0000000000
--- a/sdk/python/arvados/crunch.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) The Arvados Authors. All rights reserved.
-#
-# SPDX-License-Identifier: Apache-2.0
-
-import json
-import os
-
-from . import util
-
-class TaskOutputDir(object):
-    """Keep-backed directory for staging outputs of Crunch tasks.
-
-    Example, in a crunch task whose output is a file called "out.txt"
-    containing "42":
-
-        import arvados
-        import arvados.crunch
-        import os
-
-        out = arvados.crunch.TaskOutputDir()
-        with open(os.path.join(out.path, 'out.txt'), 'w') as f:
-            f.write('42')
-        arvados.current_task().set_output(out.manifest_text())
-    """
-    @util._deprecated('3.0', 'arvados-cwl-runner or the containers API')
-    def __init__(self):
-        self.path = os.environ['TASK_KEEPMOUNT_TMP']
-
-    def __str__(self):
-        return self.path
-
-    def manifest_text(self):
-        snapshot = os.path.join(self.path, '.arvados#collection')
-        return json.load(open(snapshot))['manifest_text']
diff --git a/sdk/python/arvados/util.py b/sdk/python/arvados/util.py
index 050c67f68d..d9bbfe955e 100644
--- a/sdk/python/arvados/util.py
+++ b/sdk/python/arvados/util.py
@@ -66,13 +66,6 @@ link_uuid_pattern = re.compile(r'[a-z0-9]{5}-o0j2j-[a-z0-9]{15}')
 """Regular expression to match any Arvados link UUID"""
 user_uuid_pattern = re.compile(r'[a-z0-9]{5}-tpzed-[a-z0-9]{15}')
 """Regular expression to match any Arvados user UUID"""
-job_uuid_pattern = re.compile(r'[a-z0-9]{5}-8i9sb-[a-z0-9]{15}')
-"""Regular expression to match any Arvados job UUID
-
-.. WARNING:: Deprecated
-   Arvados job resources are deprecated and will be removed in a future
-   release. Prefer the containers API instead.
-"""
 
 def _deprecated(version=None, preferred=None):
     """Mark a callable as deprecated in the SDK
@@ -396,314 +389,6 @@ def list_all(fn, num_retries=0, **kwargs):
         offset = c['offset'] + len(c['items'])
     return items
 
- at _deprecated('3.0')
-def clear_tmpdir(path=None):
-    """
-    Ensure the given directory (or TASK_TMPDIR if none given)
-    exists and is empty.
-    """
-    from arvados import current_task
-    if path is None:
-        path = current_task().tmpdir
-    if os.path.exists(path):
-        p = subprocess.Popen(['rm', '-rf', path])
-        stdout, stderr = p.communicate(None)
-        if p.returncode != 0:
-            raise Exception('rm -rf %s: %s' % (path, stderr))
-    os.mkdir(path)
-
- at _deprecated('3.0', 'subprocess.run')
-def run_command(execargs, **kwargs):
-    kwargs.setdefault('stdin', subprocess.PIPE)
-    kwargs.setdefault('stdout', subprocess.PIPE)
-    kwargs.setdefault('stderr', sys.stderr)
-    kwargs.setdefault('close_fds', True)
-    kwargs.setdefault('shell', False)
-    p = subprocess.Popen(execargs, **kwargs)
-    stdoutdata, stderrdata = p.communicate(None)
-    if p.returncode != 0:
-        raise arvados.errors.CommandFailedError(
-            "run_command %s exit %d:\n%s" %
-            (execargs, p.returncode, stderrdata))
-    return stdoutdata, stderrdata
-
- at _deprecated('3.0')
-def git_checkout(url, version, path):
-    from arvados import current_job
-    if not re.search('^/', path):
-        path = os.path.join(current_job().tmpdir, path)
-    if not os.path.exists(path):
-        run_command(["git", "clone", url, path],
-                    cwd=os.path.dirname(path))
-    run_command(["git", "checkout", version],
-                cwd=path)
-    return path
-
- at _deprecated('3.0')
-def tar_extractor(path, decompress_flag):
-    return subprocess.Popen(["tar",
-                             "-C", path,
-                             ("-x%sf" % decompress_flag),
-                             "-"],
-                            stdout=None,
-                            stdin=subprocess.PIPE, stderr=sys.stderr,
-                            shell=False, close_fds=True)
-
- at _deprecated('3.0', 'arvados.collection.Collection.open and the tarfile module')
-def tarball_extract(tarball, path):
-    """Retrieve a tarball from Keep and extract it to a local
-    directory.  Return the absolute path where the tarball was
-    extracted. If the top level of the tarball contained just one
-    file or directory, return the absolute path of that single
-    item.
-
-    tarball -- collection locator
-    path -- where to extract the tarball: absolute, or relative to job tmp
-    """
-    from arvados import current_job
-    from arvados.collection import CollectionReader
-    if not re.search('^/', path):
-        path = os.path.join(current_job().tmpdir, path)
-    lockfile = open(path + '.lock', 'w')
-    fcntl.flock(lockfile, fcntl.LOCK_EX)
-    try:
-        os.stat(path)
-    except OSError:
-        os.mkdir(path)
-    already_have_it = False
-    try:
-        if os.readlink(os.path.join(path, '.locator')) == tarball:
-            already_have_it = True
-    except OSError:
-        pass
-    if not already_have_it:
-
-        # emulate "rm -f" (i.e., if the file does not exist, we win)
-        try:
-            os.unlink(os.path.join(path, '.locator'))
-        except OSError:
-            if os.path.exists(os.path.join(path, '.locator')):
-                os.unlink(os.path.join(path, '.locator'))
-
-        for f in CollectionReader(tarball).all_files():
-            f_name = f.name()
-            if f_name.endswith(('.tbz', '.tar.bz2')):
-                p = tar_extractor(path, 'j')
-            elif f_name.endswith(('.tgz', '.tar.gz')):
-                p = tar_extractor(path, 'z')
-            elif f_name.endswith('.tar'):
-                p = tar_extractor(path, '')
-            else:
-                raise arvados.errors.AssertionError(
-                    "tarball_extract cannot handle filename %s" % f.name())
-            while True:
-                buf = f.read(2**20)
-                if len(buf) == 0:
-                    break
-                p.stdin.write(buf)
-            p.stdin.close()
-            p.wait()
-            if p.returncode != 0:
-                lockfile.close()
-                raise arvados.errors.CommandFailedError(
-                    "tar exited %d" % p.returncode)
-        os.symlink(tarball, os.path.join(path, '.locator'))
-    tld_extracts = [f for f in os.listdir(path) if f != '.locator']
-    lockfile.close()
-    if len(tld_extracts) == 1:
-        return os.path.join(path, tld_extracts[0])
-    return path
-
- at _deprecated('3.0', 'arvados.collection.Collection.open and the zipfile module')
-def zipball_extract(zipball, path):
-    """Retrieve a zip archive from Keep and extract it to a local
-    directory.  Return the absolute path where the archive was
-    extracted. If the top level of the archive contained just one
-    file or directory, return the absolute path of that single
-    item.
-
-    zipball -- collection locator
-    path -- where to extract the archive: absolute, or relative to job tmp
-    """
-    from arvados import current_job
-    from arvados.collection import CollectionReader
-    if not re.search('^/', path):
-        path = os.path.join(current_job().tmpdir, path)
-    lockfile = open(path + '.lock', 'w')
-    fcntl.flock(lockfile, fcntl.LOCK_EX)
-    try:
-        os.stat(path)
-    except OSError:
-        os.mkdir(path)
-    already_have_it = False
-    try:
-        if os.readlink(os.path.join(path, '.locator')) == zipball:
-            already_have_it = True
-    except OSError:
-        pass
-    if not already_have_it:
-
-        # emulate "rm -f" (i.e., if the file does not exist, we win)
-        try:
-            os.unlink(os.path.join(path, '.locator'))
-        except OSError:
-            if os.path.exists(os.path.join(path, '.locator')):
-                os.unlink(os.path.join(path, '.locator'))
-
-        for f in CollectionReader(zipball).all_files():
-            if not f.name().endswith('.zip'):
-                raise arvados.errors.NotImplementedError(
-                    "zipball_extract cannot handle filename %s" % f.name())
-            zip_filename = os.path.join(path, os.path.basename(f.name()))
-            zip_file = open(zip_filename, 'wb')
-            while True:
-                buf = f.read(2**20)
-                if len(buf) == 0:
-                    break
-                zip_file.write(buf)
-            zip_file.close()
-
-            p = subprocess.Popen(["unzip",
-                                  "-q", "-o",
-                                  "-d", path,
-                                  zip_filename],
-                                 stdout=None,
-                                 stdin=None, stderr=sys.stderr,
-                                 shell=False, close_fds=True)
-            p.wait()
-            if p.returncode != 0:
-                lockfile.close()
-                raise arvados.errors.CommandFailedError(
-                    "unzip exited %d" % p.returncode)
-            os.unlink(zip_filename)
-        os.symlink(zipball, os.path.join(path, '.locator'))
-    tld_extracts = [f for f in os.listdir(path) if f != '.locator']
-    lockfile.close()
-    if len(tld_extracts) == 1:
-        return os.path.join(path, tld_extracts[0])
-    return path
-
- at _deprecated('3.0', 'arvados.collection.Collection')
-def collection_extract(collection, path, files=[], decompress=True):
-    """Retrieve a collection from Keep and extract it to a local
-    directory.  Return the absolute path where the collection was
-    extracted.
-
-    collection -- collection locator
-    path -- where to extract: absolute, or relative to job tmp
-    """
-    from arvados import current_job
-    from arvados.collection import CollectionReader
-    matches = re.search(r'^([0-9a-f]+)(\+[\w@]+)*$', collection)
-    if matches:
-        collection_hash = matches.group(1)
-    else:
-        collection_hash = hashlib.md5(collection).hexdigest()
-    if not re.search('^/', path):
-        path = os.path.join(current_job().tmpdir, path)
-    lockfile = open(path + '.lock', 'w')
-    fcntl.flock(lockfile, fcntl.LOCK_EX)
-    try:
-        os.stat(path)
-    except OSError:
-        os.mkdir(path)
-    already_have_it = False
-    try:
-        if os.readlink(os.path.join(path, '.locator')) == collection_hash:
-            already_have_it = True
-    except OSError:
-        pass
-
-    # emulate "rm -f" (i.e., if the file does not exist, we win)
-    try:
-        os.unlink(os.path.join(path, '.locator'))
-    except OSError:
-        if os.path.exists(os.path.join(path, '.locator')):
-            os.unlink(os.path.join(path, '.locator'))
-
-    files_got = []
-    for s in CollectionReader(collection).all_streams():
-        stream_name = s.name()
-        for f in s.all_files():
-            if (files == [] or
-                ((f.name() not in files_got) and
-                 (f.name() in files or
-                  (decompress and f.decompressed_name() in files)))):
-                outname = f.decompressed_name() if decompress else f.name()
-                files_got += [outname]
-                if os.path.exists(os.path.join(path, stream_name, outname)):
-                    continue
-                mkdir_dash_p(os.path.dirname(os.path.join(path, stream_name, outname)))
-                outfile = open(os.path.join(path, stream_name, outname), 'wb')
-                for buf in (f.readall_decompressed() if decompress
-                            else f.readall()):
-                    outfile.write(buf)
-                outfile.close()
-    if len(files_got) < len(files):
-        raise arvados.errors.AssertionError(
-            "Wanted files %s but only got %s from %s" %
-            (files, files_got,
-             [z.name() for z in CollectionReader(collection).all_files()]))
-    os.symlink(collection_hash, os.path.join(path, '.locator'))
-
-    lockfile.close()
-    return path
-
- at _deprecated('3.0', 'pathlib.Path().mkdir(parents=True, exist_ok=True)')
-def mkdir_dash_p(path):
-    if not os.path.isdir(path):
-        try:
-            os.makedirs(path)
-        except OSError as e:
-            if e.errno == errno.EEXIST and os.path.isdir(path):
-                # It is not an error if someone else creates the
-                # directory between our exists() and makedirs() calls.
-                pass
-            else:
-                raise
-
- at _deprecated('3.0', 'arvados.collection.Collection')
-def stream_extract(stream, path, files=[], decompress=True):
-    """Retrieve a stream from Keep and extract it to a local
-    directory.  Return the absolute path where the stream was
-    extracted.
-
-    stream -- StreamReader object
-    path -- where to extract: absolute, or relative to job tmp
-    """
-    from arvados import current_job
-    if not re.search('^/', path):
-        path = os.path.join(current_job().tmpdir, path)
-    lockfile = open(path + '.lock', 'w')
-    fcntl.flock(lockfile, fcntl.LOCK_EX)
-    try:
-        os.stat(path)
-    except OSError:
-        os.mkdir(path)
-
-    files_got = []
-    for f in stream.all_files():
-        if (files == [] or
-            ((f.name() not in files_got) and
-             (f.name() in files or
-              (decompress and f.decompressed_name() in files)))):
-            outname = f.decompressed_name() if decompress else f.name()
-            files_got += [outname]
-            if os.path.exists(os.path.join(path, outname)):
-                os.unlink(os.path.join(path, outname))
-            mkdir_dash_p(os.path.dirname(os.path.join(path, outname)))
-            outfile = open(os.path.join(path, outname), 'wb')
-            for buf in (f.readall_decompressed() if decompress
-                        else f.readall()):
-                outfile.write(buf)
-            outfile.close()
-    if len(files_got) < len(files):
-        raise arvados.errors.AssertionError(
-            "Wanted files %s but only got %s from %s" %
-            (files, files_got, [z.name() for z in stream.all_files()]))
-    lockfile.close()
-    return path
-
 @_deprecated('3.0', 'os.walk')
 def listdir_recursive(dirname, base=None, max_depth=None):
     """listdir_recursive(dirname, base, max_depth)
diff --git a/sdk/python/tests/test_api.py b/sdk/python/tests/test_api.py
index 7d7cc9ba59..f659e43025 100644
--- a/sdk/python/tests/test_api.py
+++ b/sdk/python/tests/test_api.py
@@ -201,21 +201,6 @@ class ArvadosApiTest(run_test_server.TestCaseWithServers):
                 self.assertEqual(response.status, code)
                 self.assertEqual(response.get('status'), str(code))
 
-    def test_ordered_json_model(self):
-        mock_responses = {
-            'arvados.collections.get': (
-                None,
-                json.dumps(collections.OrderedDict(
-                    (c, int(c, 16)) for c in string.hexdigits
-                )).encode(),
-            ),
-        }
-        req_builder = apiclient_http.RequestMockBuilder(mock_responses)
-        api = arvados.api('v1',
-                          requestBuilder=req_builder, model=OrderedJsonModel())
-        result = api.collections().get(uuid='test').execute()
-        self.assertEqual(string.hexdigits, ''.join(list(result.keys())))
-
     def test_api_is_threadsafe(self):
         api_kwargs = {
             'host': os.environ['ARVADOS_API_HOST'],
diff --git a/sdk/python/tests/test_crunch.py b/sdk/python/tests/test_crunch.py
deleted file mode 100644
index 809e229b20..0000000000
--- a/sdk/python/tests/test_crunch.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) The Arvados Authors. All rights reserved.
-#
-# SPDX-License-Identifier: Apache-2.0
-
-import arvados.crunch
-import os
-import shutil
-import tempfile
-import unittest
-
-class TaskOutputDirTest(unittest.TestCase):
-    def setUp(self):
-        self.tmp = tempfile.mkdtemp()
-        os.environ['TASK_KEEPMOUNT_TMP'] = self.tmp
-
-    def tearDown(self):
-        os.environ.pop('TASK_KEEPMOUNT_TMP')
-        shutil.rmtree(self.tmp)
-
-    def test_env_var(self):
-        out = arvados.crunch.TaskOutputDir()
-        self.assertEqual(out.path, self.tmp)
-
-        with open(os.path.join(self.tmp, '.arvados#collection'), 'w') as f:
-            f.write('{\n  "manifest_text":"",\n  "uuid":null\n}\n')
-        self.assertEqual(out.manifest_text(), '')
-
-        # Special file must be re-read on each call to manifest_text().
-        with open(os.path.join(self.tmp, '.arvados#collection'), 'w') as f:
-            f.write(r'{"manifest_text":". unparsed 0:3:foo\n","uuid":null}')
-        self.assertEqual(out.manifest_text(), ". unparsed 0:3:foo\n")
diff --git a/sdk/python/tests/test_util.py b/sdk/python/tests/test_util.py
index 75d4a89e30..3055599ca5 100644
--- a/sdk/python/tests/test_util.py
+++ b/sdk/python/tests/test_util.py
@@ -13,36 +13,6 @@ from unittest import mock
 import arvados
 import arvados.util
 
-class MkdirDashPTest(unittest.TestCase):
-    def setUp(self):
-        try:
-            os.path.mkdir('./tmp')
-        except:
-            pass
-    def tearDown(self):
-        try:
-            os.unlink('./tmp/bar')
-            os.rmdir('./tmp/foo')
-            os.rmdir('./tmp')
-        except:
-            pass
-    def runTest(self):
-        arvados.util.mkdir_dash_p('./tmp/foo')
-        with open('./tmp/bar', 'wb') as f:
-            f.write(b'bar')
-        self.assertRaises(OSError, arvados.util.mkdir_dash_p, './tmp/bar')
-
-
-class RunCommandTestCase(unittest.TestCase):
-    def test_success(self):
-        stdout, stderr = arvados.util.run_command(['echo', 'test'],
-                                                  stderr=subprocess.PIPE)
-        self.assertEqual("test\n".encode(), stdout)
-        self.assertEqual("".encode(), stderr)
-
-    def test_failure(self):
-        with self.assertRaises(arvados.errors.CommandFailedError):
-            arvados.util.run_command(['false'])
 
 class KeysetTestHelper:
     def __init__(self, expect):

commit c0c3cedc411f1e5c446ce1423be0e2a4e1ec2df8
Author: Tom Clegg <tom at curii.com>
Date:   Wed May 15 18:44:57 2024 -0400

    15937: Remove destroy/index/show methods from discovery doc.
    
    In favor of delete/list/get.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/sdk/python/arvados-v1-discovery.json b/sdk/python/arvados-v1-discovery.json
index 52d198eafd..73522011b9 100644
--- a/sdk/python/arvados-v1-discovery.json
+++ b/sdk/python/arvados-v1-discovery.json
@@ -63,6 +63,12 @@
               "description": "The UUID of the ApiClient in question.",
               "required": true,
               "location": "path"
+            },
+            "select": {
+              "type": "array",
+              "description": "Attributes of the object to return in the response.",
+              "required": false,
+              "location": "query"
             }
           },
           "parameterOrder": [
@@ -76,7 +82,7 @@
             "https://api.arvados.org/auth/arvados.readonly"
           ]
         },
-        "index": {
+        "list": {
           "id": "arvados.api_clients.list",
           "path": "api_clients",
           "httpMethod": "GET",
@@ -249,131 +255,6 @@
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
-        },
-        "list": {
-          "id": "arvados.api_clients.list",
-          "path": "api_clients",
-          "httpMethod": "GET",
-          "description": "List ApiClients.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching ApiClients. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#apiClientList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
-          "parameters": {
-            "filters": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "where": {
-              "type": "object",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "order": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of each object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "distinct": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "",
-              "location": "query"
-            },
-            "limit": {
-              "type": "integer",
-              "required": false,
-              "default": "100",
-              "description": "",
-              "location": "query"
-            },
-            "offset": {
-              "type": "integer",
-              "required": false,
-              "default": "0",
-              "description": "",
-              "location": "query"
-            },
-            "count": {
-              "type": "string",
-              "required": false,
-              "default": "exact",
-              "description": "",
-              "location": "query"
-            },
-            "cluster_id": {
-              "type": "string",
-              "description": "List objects on a remote federated cluster instead of the current one.",
-              "location": "query",
-              "required": false
-            },
-            "bypass_federation": {
-              "type": "boolean",
-              "required": false,
-              "description": "bypass federation behavior, list items from local instance database only",
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "ApiClientList"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados",
-            "https://api.arvados.org/auth/arvados.readonly"
-          ]
-        },
-        "show": {
-          "id": "arvados.api_clients.show",
-          "path": "api_clients/{uuid}",
-          "httpMethod": "GET",
-          "description": "show api_clients",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of the object to return in the response.",
-              "required": false,
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "ApiClient"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "destroy": {
-          "id": "arvados.api_clients.destroy",
-          "path": "api_clients/{uuid}",
-          "httpMethod": "DELETE",
-          "description": "destroy api_clients",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            }
-          },
-          "response": {
-            "$ref": "ApiClient"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
         }
       }
     },
@@ -390,6 +271,12 @@
               "description": "The UUID of the ApiClientAuthorization in question.",
               "required": true,
               "location": "path"
+            },
+            "select": {
+              "type": "array",
+              "description": "Attributes of the object to return in the response.",
+              "required": false,
+              "location": "query"
             }
           },
           "parameterOrder": [
@@ -403,7 +290,7 @@
             "https://api.arvados.org/auth/arvados.readonly"
           ]
         },
-        "index": {
+        "list": {
           "id": "arvados.api_client_authorizations.list",
           "path": "api_client_authorizations",
           "httpMethod": "GET",
@@ -609,12 +496,46 @@
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
+        }
+      }
+    },
+    "authorized_keys": {
+      "methods": {
+        "get": {
+          "id": "arvados.authorized_keys.get",
+          "path": "authorized_keys/{uuid}",
+          "httpMethod": "GET",
+          "description": "Gets a AuthorizedKey's metadata by UUID.",
+          "parameters": {
+            "uuid": {
+              "type": "string",
+              "description": "The UUID of the AuthorizedKey in question.",
+              "required": true,
+              "location": "path"
+            },
+            "select": {
+              "type": "array",
+              "description": "Attributes of the object to return in the response.",
+              "required": false,
+              "location": "query"
+            }
+          },
+          "parameterOrder": [
+            "uuid"
+          ],
+          "response": {
+            "$ref": "AuthorizedKey"
+          },
+          "scopes": [
+            "https://api.arvados.org/auth/arvados",
+            "https://api.arvados.org/auth/arvados.readonly"
+          ]
         },
         "list": {
-          "id": "arvados.api_client_authorizations.list",
-          "path": "api_client_authorizations",
+          "id": "arvados.authorized_keys.list",
+          "path": "authorized_keys",
           "httpMethod": "GET",
-          "description": "List ApiClientAuthorizations.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching ApiClientAuthorizations. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#apiClientAuthorizationList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
+          "description": "List AuthorizedKeys.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching AuthorizedKeys. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#authorizedKeyList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
           "parameters": {
             "filters": {
               "type": "array",
@@ -682,54 +603,103 @@
             }
           },
           "response": {
-            "$ref": "ApiClientAuthorizationList"
+            "$ref": "AuthorizedKeyList"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados",
             "https://api.arvados.org/auth/arvados.readonly"
           ]
         },
-        "show": {
-          "id": "arvados.api_client_authorizations.show",
-          "path": "api_client_authorizations/{uuid}",
-          "httpMethod": "GET",
-          "description": "show api_client_authorizations",
+        "create": {
+          "id": "arvados.authorized_keys.create",
+          "path": "authorized_keys",
+          "httpMethod": "POST",
+          "description": "Create a new AuthorizedKey.",
+          "parameters": {
+            "select": {
+              "type": "array",
+              "description": "Attributes of the new object to return in the response.",
+              "required": false,
+              "location": "query"
+            },
+            "ensure_unique_name": {
+              "type": "boolean",
+              "description": "Adjust name to ensure uniqueness instead of returning an error on (owner_uuid, name) collision.",
+              "location": "query",
+              "required": false,
+              "default": "false"
+            },
+            "cluster_id": {
+              "type": "string",
+              "description": "Create object on a remote federated cluster instead of the current one.",
+              "location": "query",
+              "required": false
+            }
+          },
+          "request": {
+            "required": true,
+            "properties": {
+              "authorized_key": {
+                "$ref": "AuthorizedKey"
+              }
+            }
+          },
+          "response": {
+            "$ref": "AuthorizedKey"
+          },
+          "scopes": [
+            "https://api.arvados.org/auth/arvados"
+          ]
+        },
+        "update": {
+          "id": "arvados.authorized_keys.update",
+          "path": "authorized_keys/{uuid}",
+          "httpMethod": "PUT",
+          "description": "Update attributes of an existing AuthorizedKey.",
           "parameters": {
             "uuid": {
               "type": "string",
-              "description": "",
+              "description": "The UUID of the AuthorizedKey in question.",
               "required": true,
               "location": "path"
             },
             "select": {
               "type": "array",
-              "description": "Attributes of the object to return in the response.",
+              "description": "Attributes of the updated object to return in the response.",
               "required": false,
               "location": "query"
             }
           },
+          "request": {
+            "required": true,
+            "properties": {
+              "authorized_key": {
+                "$ref": "AuthorizedKey"
+              }
+            }
+          },
           "response": {
-            "$ref": "ApiClientAuthorization"
+            "$ref": "AuthorizedKey"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
         },
-        "destroy": {
-          "id": "arvados.api_client_authorizations.destroy",
-          "path": "api_client_authorizations/{uuid}",
+        "delete": {
+          "id": "arvados.authorized_keys.delete",
+          "path": "authorized_keys/{uuid}",
           "httpMethod": "DELETE",
-          "description": "destroy api_client_authorizations",
+          "description": "Delete an existing AuthorizedKey.",
           "parameters": {
             "uuid": {
               "type": "string",
-              "description": "",
+              "description": "The UUID of the AuthorizedKey in question.",
               "required": true,
               "location": "path"
             }
           },
           "response": {
-            "$ref": "ApiClientAuthorization"
+            "$ref": "AuthorizedKey"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados"
@@ -737,37 +707,57 @@
         }
       }
     },
-    "authorized_keys": {
+    "collections": {
       "methods": {
         "get": {
-          "id": "arvados.authorized_keys.get",
-          "path": "authorized_keys/{uuid}",
+          "id": "arvados.collections.get",
+          "path": "collections/{uuid}",
           "httpMethod": "GET",
-          "description": "Gets a AuthorizedKey's metadata by UUID.",
+          "description": "Gets a Collection's metadata by UUID.",
           "parameters": {
             "uuid": {
               "type": "string",
-              "description": "The UUID of the AuthorizedKey in question.",
+              "description": "The UUID of the Collection in question.",
               "required": true,
               "location": "path"
+            },
+            "select": {
+              "type": "array",
+              "description": "Attributes of the object to return in the response.",
+              "required": false,
+              "location": "query"
+            },
+            "include_trash": {
+              "type": "boolean",
+              "required": false,
+              "default": "false",
+              "description": "Show collection even if its is_trashed attribute is true.",
+              "location": "query"
+            },
+            "include_old_versions": {
+              "type": "boolean",
+              "required": false,
+              "default": "true",
+              "description": "Include past collection versions.",
+              "location": "query"
             }
           },
           "parameterOrder": [
             "uuid"
           ],
           "response": {
-            "$ref": "AuthorizedKey"
+            "$ref": "Collection"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados",
             "https://api.arvados.org/auth/arvados.readonly"
           ]
         },
-        "index": {
-          "id": "arvados.authorized_keys.list",
-          "path": "authorized_keys",
+        "list": {
+          "id": "arvados.collections.list",
+          "path": "collections",
           "httpMethod": "GET",
-          "description": "List AuthorizedKeys.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching AuthorizedKeys. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#authorizedKeyList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
+          "description": "List Collections.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching Collections. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#collectionList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
           "parameters": {
             "filters": {
               "type": "array",
@@ -832,10 +822,24 @@
               "required": false,
               "description": "bypass federation behavior, list items from local instance database only",
               "location": "query"
+            },
+            "include_trash": {
+              "type": "boolean",
+              "required": false,
+              "default": "false",
+              "description": "Include collections whose is_trashed attribute is true.",
+              "location": "query"
+            },
+            "include_old_versions": {
+              "type": "boolean",
+              "required": false,
+              "default": "false",
+              "description": "Include past collection versions.",
+              "location": "query"
             }
           },
           "response": {
-            "$ref": "AuthorizedKeyList"
+            "$ref": "CollectionList"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados",
@@ -843,10 +847,10 @@
           ]
         },
         "create": {
-          "id": "arvados.authorized_keys.create",
-          "path": "authorized_keys",
+          "id": "arvados.collections.create",
+          "path": "collections",
           "httpMethod": "POST",
-          "description": "Create a new AuthorizedKey.",
+          "description": "Create a new Collection.",
           "parameters": {
             "select": {
               "type": "array",
@@ -866,32 +870,42 @@
               "description": "Create object on a remote federated cluster instead of the current one.",
               "location": "query",
               "required": false
+            },
+            "replace_files": {
+              "type": "object",
+              "description": "Files and directories to initialize/replace with content from other collections.",
+              "required": false,
+              "location": "query",
+              "properties": {},
+              "additionalProperties": {
+                "type": "string"
+              }
             }
           },
           "request": {
             "required": true,
             "properties": {
-              "authorized_key": {
-                "$ref": "AuthorizedKey"
+              "collection": {
+                "$ref": "Collection"
               }
             }
           },
           "response": {
-            "$ref": "AuthorizedKey"
+            "$ref": "Collection"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
         },
         "update": {
-          "id": "arvados.authorized_keys.update",
-          "path": "authorized_keys/{uuid}",
+          "id": "arvados.collections.update",
+          "path": "collections/{uuid}",
           "httpMethod": "PUT",
-          "description": "Update attributes of an existing AuthorizedKey.",
+          "description": "Update attributes of an existing Collection.",
           "parameters": {
             "uuid": {
               "type": "string",
-              "description": "The UUID of the AuthorizedKey in question.",
+              "description": "The UUID of the Collection in question.",
               "required": true,
               "location": "path"
             },
@@ -900,153 +914,98 @@
               "description": "Attributes of the updated object to return in the response.",
               "required": false,
               "location": "query"
+            },
+            "replace_files": {
+              "type": "object",
+              "description": "Files and directories to initialize/replace with content from other collections.",
+              "required": false,
+              "location": "query",
+              "properties": {},
+              "additionalProperties": {
+                "type": "string"
+              }
             }
           },
           "request": {
             "required": true,
             "properties": {
-              "authorized_key": {
-                "$ref": "AuthorizedKey"
+              "collection": {
+                "$ref": "Collection"
               }
             }
           },
           "response": {
-            "$ref": "AuthorizedKey"
+            "$ref": "Collection"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
         },
         "delete": {
-          "id": "arvados.authorized_keys.delete",
-          "path": "authorized_keys/{uuid}",
+          "id": "arvados.collections.delete",
+          "path": "collections/{uuid}",
           "httpMethod": "DELETE",
-          "description": "Delete an existing AuthorizedKey.",
+          "description": "Delete an existing Collection.",
           "parameters": {
             "uuid": {
               "type": "string",
-              "description": "The UUID of the AuthorizedKey in question.",
+              "description": "The UUID of the Collection in question.",
               "required": true,
               "location": "path"
             }
           },
           "response": {
-            "$ref": "AuthorizedKey"
+            "$ref": "Collection"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
         },
-        "list": {
-          "id": "arvados.authorized_keys.list",
-          "path": "authorized_keys",
+        "provenance": {
+          "id": "arvados.collections.provenance",
+          "path": "collections/{uuid}/provenance",
           "httpMethod": "GET",
-          "description": "List AuthorizedKeys.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching AuthorizedKeys. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#authorizedKeyList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
+          "description": "provenance collections",
           "parameters": {
-            "filters": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "where": {
-              "type": "object",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "order": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of each object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "distinct": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "",
-              "location": "query"
-            },
-            "limit": {
-              "type": "integer",
-              "required": false,
-              "default": "100",
-              "description": "",
-              "location": "query"
-            },
-            "offset": {
-              "type": "integer",
-              "required": false,
-              "default": "0",
-              "description": "",
-              "location": "query"
-            },
-            "count": {
+            "uuid": {
               "type": "string",
-              "required": false,
-              "default": "exact",
               "description": "",
-              "location": "query"
-            },
-            "cluster_id": {
-              "type": "string",
-              "description": "List objects on a remote federated cluster instead of the current one.",
-              "location": "query",
-              "required": false
-            },
-            "bypass_federation": {
-              "type": "boolean",
-              "required": false,
-              "description": "bypass federation behavior, list items from local instance database only",
-              "location": "query"
+              "required": true,
+              "location": "path"
             }
           },
           "response": {
-            "$ref": "AuthorizedKeyList"
+            "$ref": "Collection"
           },
           "scopes": [
-            "https://api.arvados.org/auth/arvados",
-            "https://api.arvados.org/auth/arvados.readonly"
+            "https://api.arvados.org/auth/arvados"
           ]
         },
-        "show": {
-          "id": "arvados.authorized_keys.show",
-          "path": "authorized_keys/{uuid}",
+        "used_by": {
+          "id": "arvados.collections.used_by",
+          "path": "collections/{uuid}/used_by",
           "httpMethod": "GET",
-          "description": "show authorized_keys",
+          "description": "used_by collections",
           "parameters": {
             "uuid": {
               "type": "string",
               "description": "",
               "required": true,
               "location": "path"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of the object to return in the response.",
-              "required": false,
-              "location": "query"
             }
           },
           "response": {
-            "$ref": "AuthorizedKey"
+            "$ref": "Collection"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
         },
-        "destroy": {
-          "id": "arvados.authorized_keys.destroy",
-          "path": "authorized_keys/{uuid}",
-          "httpMethod": "DELETE",
-          "description": "destroy authorized_keys",
+        "trash": {
+          "id": "arvados.collections.trash",
+          "path": "collections/{uuid}/trash",
+          "httpMethod": "POST",
+          "description": "trash collections",
           "parameters": {
             "uuid": {
               "type": "string",
@@ -1056,7 +1015,27 @@
             }
           },
           "response": {
-            "$ref": "AuthorizedKey"
+            "$ref": "Collection"
+          },
+          "scopes": [
+            "https://api.arvados.org/auth/arvados"
+          ]
+        },
+        "untrash": {
+          "id": "arvados.collections.untrash",
+          "path": "collections/{uuid}/untrash",
+          "httpMethod": "POST",
+          "description": "untrash collections",
+          "parameters": {
+            "uuid": {
+              "type": "string",
+              "description": "",
+              "required": true,
+              "location": "path"
+            }
+          },
+          "response": {
+            "$ref": "Collection"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados"
@@ -1064,37 +1043,43 @@
         }
       }
     },
-    "collections": {
+    "containers": {
       "methods": {
         "get": {
-          "id": "arvados.collections.get",
-          "path": "collections/{uuid}",
+          "id": "arvados.containers.get",
+          "path": "containers/{uuid}",
           "httpMethod": "GET",
-          "description": "Gets a Collection's metadata by UUID.",
+          "description": "Gets a Container's metadata by UUID.",
           "parameters": {
             "uuid": {
               "type": "string",
-              "description": "The UUID of the Collection in question.",
+              "description": "The UUID of the Container in question.",
               "required": true,
               "location": "path"
+            },
+            "select": {
+              "type": "array",
+              "description": "Attributes of the object to return in the response.",
+              "required": false,
+              "location": "query"
             }
           },
           "parameterOrder": [
             "uuid"
           ],
           "response": {
-            "$ref": "Collection"
+            "$ref": "Container"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados",
             "https://api.arvados.org/auth/arvados.readonly"
           ]
         },
-        "index": {
-          "id": "arvados.collections.list",
-          "path": "collections",
+        "list": {
+          "id": "arvados.containers.list",
+          "path": "containers",
           "httpMethod": "GET",
-          "description": "List Collections.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching Collections. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#collectionList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
+          "description": "List Containers.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching Containers. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#containerList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
           "parameters": {
             "filters": {
               "type": "array",
@@ -1159,24 +1144,10 @@
               "required": false,
               "description": "bypass federation behavior, list items from local instance database only",
               "location": "query"
-            },
-            "include_trash": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "Include collections whose is_trashed attribute is true.",
-              "location": "query"
-            },
-            "include_old_versions": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "Include past collection versions.",
-              "location": "query"
             }
           },
           "response": {
-            "$ref": "CollectionList"
+            "$ref": "ContainerList"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados",
@@ -1184,10 +1155,10 @@
           ]
         },
         "create": {
-          "id": "arvados.collections.create",
-          "path": "collections",
+          "id": "arvados.containers.create",
+          "path": "containers",
           "httpMethod": "POST",
-          "description": "Create a new Collection.",
+          "description": "Create a new Container.",
           "parameters": {
             "select": {
               "type": "array",
@@ -1207,42 +1178,32 @@
               "description": "Create object on a remote federated cluster instead of the current one.",
               "location": "query",
               "required": false
-            },
-            "replace_files": {
-              "type": "object",
-              "description": "Files and directories to initialize/replace with content from other collections.",
-              "required": false,
-              "location": "query",
-              "properties": {},
-              "additionalProperties": {
-                "type": "string"
-              }
             }
           },
           "request": {
             "required": true,
             "properties": {
-              "collection": {
-                "$ref": "Collection"
+              "container": {
+                "$ref": "Container"
               }
             }
           },
           "response": {
-            "$ref": "Collection"
+            "$ref": "Container"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
         },
         "update": {
-          "id": "arvados.collections.update",
-          "path": "collections/{uuid}",
+          "id": "arvados.containers.update",
+          "path": "containers/{uuid}",
           "httpMethod": "PUT",
-          "description": "Update attributes of an existing Collection.",
+          "description": "Update attributes of an existing Container.",
           "parameters": {
             "uuid": {
               "type": "string",
-              "description": "The UUID of the Collection in question.",
+              "description": "The UUID of the Container in question.",
               "required": true,
               "location": "path"
             },
@@ -1251,58 +1212,48 @@
               "description": "Attributes of the updated object to return in the response.",
               "required": false,
               "location": "query"
-            },
-            "replace_files": {
-              "type": "object",
-              "description": "Files and directories to initialize/replace with content from other collections.",
-              "required": false,
-              "location": "query",
-              "properties": {},
-              "additionalProperties": {
-                "type": "string"
-              }
             }
           },
           "request": {
             "required": true,
             "properties": {
-              "collection": {
-                "$ref": "Collection"
+              "container": {
+                "$ref": "Container"
               }
             }
           },
           "response": {
-            "$ref": "Collection"
+            "$ref": "Container"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
         },
         "delete": {
-          "id": "arvados.collections.delete",
-          "path": "collections/{uuid}",
+          "id": "arvados.containers.delete",
+          "path": "containers/{uuid}",
           "httpMethod": "DELETE",
-          "description": "Delete an existing Collection.",
+          "description": "Delete an existing Container.",
           "parameters": {
             "uuid": {
               "type": "string",
-              "description": "The UUID of the Collection in question.",
+              "description": "The UUID of the Container in question.",
               "required": true,
               "location": "path"
             }
           },
           "response": {
-            "$ref": "Collection"
+            "$ref": "Container"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
         },
-        "provenance": {
-          "id": "arvados.collections.provenance",
-          "path": "collections/{uuid}/provenance",
+        "auth": {
+          "id": "arvados.containers.auth",
+          "path": "containers/{uuid}/auth",
           "httpMethod": "GET",
-          "description": "provenance collections",
+          "description": "auth containers",
           "parameters": {
             "uuid": {
               "type": "string",
@@ -1312,17 +1263,17 @@
             }
           },
           "response": {
-            "$ref": "Collection"
+            "$ref": "Container"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
         },
-        "used_by": {
-          "id": "arvados.collections.used_by",
-          "path": "collections/{uuid}/used_by",
-          "httpMethod": "GET",
-          "description": "used_by collections",
+        "lock": {
+          "id": "arvados.containers.lock",
+          "path": "containers/{uuid}/lock",
+          "httpMethod": "POST",
+          "description": "lock containers",
           "parameters": {
             "uuid": {
               "type": "string",
@@ -1332,17 +1283,17 @@
             }
           },
           "response": {
-            "$ref": "Collection"
+            "$ref": "Container"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
         },
-        "trash": {
-          "id": "arvados.collections.trash",
-          "path": "collections/{uuid}/trash",
+        "unlock": {
+          "id": "arvados.containers.unlock",
+          "path": "containers/{uuid}/unlock",
           "httpMethod": "POST",
-          "description": "trash collections",
+          "description": "unlock containers",
           "parameters": {
             "uuid": {
               "type": "string",
@@ -1352,17 +1303,17 @@
             }
           },
           "response": {
-            "$ref": "Collection"
+            "$ref": "Container"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
         },
-        "untrash": {
-          "id": "arvados.collections.untrash",
-          "path": "collections/{uuid}/untrash",
+        "update_priority": {
+          "id": "arvados.containers.update_priority",
+          "path": "containers/{uuid}/update_priority",
           "httpMethod": "POST",
-          "description": "untrash collections",
+          "description": "update_priority containers",
           "parameters": {
             "uuid": {
               "type": "string",
@@ -1372,832 +1323,84 @@
             }
           },
           "response": {
-            "$ref": "Collection"
+            "$ref": "Container"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
         },
-        "list": {
-          "id": "arvados.collections.list",
-          "path": "collections",
-          "httpMethod": "GET",
-          "description": "List Collections.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching Collections. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#collectionList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
-          "parameters": {
-            "filters": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "where": {
-              "type": "object",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "order": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of each object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "distinct": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "",
-              "location": "query"
-            },
-            "limit": {
-              "type": "integer",
-              "required": false,
-              "default": "100",
-              "description": "",
-              "location": "query"
-            },
-            "offset": {
-              "type": "integer",
-              "required": false,
-              "default": "0",
-              "description": "",
-              "location": "query"
-            },
-            "count": {
-              "type": "string",
-              "required": false,
-              "default": "exact",
-              "description": "",
-              "location": "query"
-            },
-            "cluster_id": {
-              "type": "string",
-              "description": "List objects on a remote federated cluster instead of the current one.",
-              "location": "query",
-              "required": false
-            },
-            "bypass_federation": {
-              "type": "boolean",
-              "required": false,
-              "description": "bypass federation behavior, list items from local instance database only",
-              "location": "query"
-            },
-            "include_trash": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "Include collections whose is_trashed attribute is true.",
-              "location": "query"
-            },
-            "include_old_versions": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "Include past collection versions.",
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "CollectionList"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados",
-            "https://api.arvados.org/auth/arvados.readonly"
-          ]
-        },
-        "show": {
-          "id": "arvados.collections.show",
-          "path": "collections/{uuid}",
+        "secret_mounts": {
+          "id": "arvados.containers.secret_mounts",
+          "path": "containers/{uuid}/secret_mounts",
           "httpMethod": "GET",
-          "description": "show collections",
+          "description": "secret_mounts containers",
           "parameters": {
             "uuid": {
               "type": "string",
               "description": "",
               "required": true,
               "location": "path"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of the object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "include_trash": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "Show collection even if its is_trashed attribute is true.",
-              "location": "query"
-            },
-            "include_old_versions": {
-              "type": "boolean",
-              "required": false,
-              "default": "true",
-              "description": "Include past collection versions.",
-              "location": "query"
             }
           },
           "response": {
-            "$ref": "Collection"
+            "$ref": "Container"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
         },
-        "destroy": {
-          "id": "arvados.collections.destroy",
-          "path": "collections/{uuid}",
-          "httpMethod": "DELETE",
-          "description": "destroy collections",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            }
-          },
+        "current": {
+          "id": "arvados.containers.current",
+          "path": "containers/current",
+          "httpMethod": "GET",
+          "description": "current containers",
+          "parameters": {},
           "response": {
-            "$ref": "Collection"
+            "$ref": "Container"
           },
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
         }
       }
-    },
-    "containers": {
-      "methods": {
-        "get": {
-          "id": "arvados.containers.get",
-          "path": "containers/{uuid}",
-          "httpMethod": "GET",
-          "description": "Gets a Container's metadata by UUID.",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "The UUID of the Container in question.",
-              "required": true,
-              "location": "path"
-            }
-          },
-          "parameterOrder": [
-            "uuid"
-          ],
-          "response": {
-            "$ref": "Container"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados",
-            "https://api.arvados.org/auth/arvados.readonly"
-          ]
-        },
-        "index": {
-          "id": "arvados.containers.list",
-          "path": "containers",
-          "httpMethod": "GET",
-          "description": "List Containers.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching Containers. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#containerList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
-          "parameters": {
-            "filters": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "where": {
-              "type": "object",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "order": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of each object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "distinct": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "",
-              "location": "query"
-            },
-            "limit": {
-              "type": "integer",
-              "required": false,
-              "default": "100",
-              "description": "",
-              "location": "query"
-            },
-            "offset": {
-              "type": "integer",
-              "required": false,
-              "default": "0",
-              "description": "",
-              "location": "query"
-            },
-            "count": {
-              "type": "string",
-              "required": false,
-              "default": "exact",
-              "description": "",
-              "location": "query"
-            },
-            "cluster_id": {
-              "type": "string",
-              "description": "List objects on a remote federated cluster instead of the current one.",
-              "location": "query",
-              "required": false
-            },
-            "bypass_federation": {
-              "type": "boolean",
-              "required": false,
-              "description": "bypass federation behavior, list items from local instance database only",
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "ContainerList"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados",
-            "https://api.arvados.org/auth/arvados.readonly"
-          ]
-        },
-        "create": {
-          "id": "arvados.containers.create",
-          "path": "containers",
-          "httpMethod": "POST",
-          "description": "Create a new Container.",
-          "parameters": {
-            "select": {
-              "type": "array",
-              "description": "Attributes of the new object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "ensure_unique_name": {
-              "type": "boolean",
-              "description": "Adjust name to ensure uniqueness instead of returning an error on (owner_uuid, name) collision.",
-              "location": "query",
-              "required": false,
-              "default": "false"
-            },
-            "cluster_id": {
-              "type": "string",
-              "description": "Create object on a remote federated cluster instead of the current one.",
-              "location": "query",
-              "required": false
-            }
-          },
-          "request": {
-            "required": true,
-            "properties": {
-              "container": {
-                "$ref": "Container"
-              }
-            }
-          },
-          "response": {
-            "$ref": "Container"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "update": {
-          "id": "arvados.containers.update",
-          "path": "containers/{uuid}",
-          "httpMethod": "PUT",
-          "description": "Update attributes of an existing Container.",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "The UUID of the Container in question.",
-              "required": true,
-              "location": "path"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of the updated object to return in the response.",
-              "required": false,
-              "location": "query"
-            }
-          },
-          "request": {
-            "required": true,
-            "properties": {
-              "container": {
-                "$ref": "Container"
-              }
-            }
-          },
-          "response": {
-            "$ref": "Container"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "delete": {
-          "id": "arvados.containers.delete",
-          "path": "containers/{uuid}",
-          "httpMethod": "DELETE",
-          "description": "Delete an existing Container.",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "The UUID of the Container in question.",
-              "required": true,
-              "location": "path"
-            }
-          },
-          "response": {
-            "$ref": "Container"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "auth": {
-          "id": "arvados.containers.auth",
-          "path": "containers/{uuid}/auth",
-          "httpMethod": "GET",
-          "description": "auth containers",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            }
-          },
-          "response": {
-            "$ref": "Container"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "lock": {
-          "id": "arvados.containers.lock",
-          "path": "containers/{uuid}/lock",
-          "httpMethod": "POST",
-          "description": "lock containers",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            }
-          },
-          "response": {
-            "$ref": "Container"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "unlock": {
-          "id": "arvados.containers.unlock",
-          "path": "containers/{uuid}/unlock",
-          "httpMethod": "POST",
-          "description": "unlock containers",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            }
-          },
-          "response": {
-            "$ref": "Container"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "update_priority": {
-          "id": "arvados.containers.update_priority",
-          "path": "containers/{uuid}/update_priority",
-          "httpMethod": "POST",
-          "description": "update_priority containers",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            }
-          },
-          "response": {
-            "$ref": "Container"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "secret_mounts": {
-          "id": "arvados.containers.secret_mounts",
-          "path": "containers/{uuid}/secret_mounts",
-          "httpMethod": "GET",
-          "description": "secret_mounts containers",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            }
-          },
-          "response": {
-            "$ref": "Container"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "current": {
-          "id": "arvados.containers.current",
-          "path": "containers/current",
-          "httpMethod": "GET",
-          "description": "current containers",
-          "parameters": {},
-          "response": {
-            "$ref": "Container"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "list": {
-          "id": "arvados.containers.list",
-          "path": "containers",
-          "httpMethod": "GET",
-          "description": "List Containers.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching Containers. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#containerList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
-          "parameters": {
-            "filters": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "where": {
-              "type": "object",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "order": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of each object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "distinct": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "",
-              "location": "query"
-            },
-            "limit": {
-              "type": "integer",
-              "required": false,
-              "default": "100",
-              "description": "",
-              "location": "query"
-            },
-            "offset": {
-              "type": "integer",
-              "required": false,
-              "default": "0",
-              "description": "",
-              "location": "query"
-            },
-            "count": {
-              "type": "string",
-              "required": false,
-              "default": "exact",
-              "description": "",
-              "location": "query"
-            },
-            "cluster_id": {
-              "type": "string",
-              "description": "List objects on a remote federated cluster instead of the current one.",
-              "location": "query",
-              "required": false
-            },
-            "bypass_federation": {
-              "type": "boolean",
-              "required": false,
-              "description": "bypass federation behavior, list items from local instance database only",
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "ContainerList"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados",
-            "https://api.arvados.org/auth/arvados.readonly"
-          ]
-        },
-        "show": {
-          "id": "arvados.containers.show",
-          "path": "containers/{uuid}",
-          "httpMethod": "GET",
-          "description": "show containers",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of the object to return in the response.",
-              "required": false,
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "Container"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "destroy": {
-          "id": "arvados.containers.destroy",
-          "path": "containers/{uuid}",
-          "httpMethod": "DELETE",
-          "description": "destroy containers",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            }
-          },
-          "response": {
-            "$ref": "Container"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        }
-      }
-    },
-    "container_requests": {
-      "methods": {
-        "get": {
-          "id": "arvados.container_requests.get",
-          "path": "container_requests/{uuid}",
-          "httpMethod": "GET",
-          "description": "Gets a ContainerRequest's metadata by UUID.",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "The UUID of the ContainerRequest in question.",
-              "required": true,
-              "location": "path"
-            }
-          },
-          "parameterOrder": [
-            "uuid"
-          ],
-          "response": {
-            "$ref": "ContainerRequest"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados",
-            "https://api.arvados.org/auth/arvados.readonly"
-          ]
-        },
-        "index": {
-          "id": "arvados.container_requests.list",
-          "path": "container_requests",
-          "httpMethod": "GET",
-          "description": "List ContainerRequests.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching ContainerRequests. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#containerRequestList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
-          "parameters": {
-            "filters": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "where": {
-              "type": "object",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "order": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of each object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "distinct": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "",
-              "location": "query"
-            },
-            "limit": {
-              "type": "integer",
-              "required": false,
-              "default": "100",
-              "description": "",
-              "location": "query"
-            },
-            "offset": {
-              "type": "integer",
-              "required": false,
-              "default": "0",
-              "description": "",
-              "location": "query"
-            },
-            "count": {
-              "type": "string",
-              "required": false,
-              "default": "exact",
-              "description": "",
-              "location": "query"
-            },
-            "cluster_id": {
-              "type": "string",
-              "description": "List objects on a remote federated cluster instead of the current one.",
-              "location": "query",
-              "required": false
-            },
-            "bypass_federation": {
-              "type": "boolean",
-              "required": false,
-              "description": "bypass federation behavior, list items from local instance database only",
-              "location": "query"
-            },
-            "include_trash": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "Include container requests whose owner project is trashed.",
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "ContainerRequestList"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados",
-            "https://api.arvados.org/auth/arvados.readonly"
-          ]
-        },
-        "create": {
-          "id": "arvados.container_requests.create",
-          "path": "container_requests",
-          "httpMethod": "POST",
-          "description": "Create a new ContainerRequest.",
-          "parameters": {
-            "select": {
-              "type": "array",
-              "description": "Attributes of the new object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "ensure_unique_name": {
-              "type": "boolean",
-              "description": "Adjust name to ensure uniqueness instead of returning an error on (owner_uuid, name) collision.",
-              "location": "query",
-              "required": false,
-              "default": "false"
-            },
-            "cluster_id": {
-              "type": "string",
-              "description": "Create object on a remote federated cluster instead of the current one.",
-              "location": "query",
-              "required": false
-            }
-          },
-          "request": {
-            "required": true,
-            "properties": {
-              "container_request": {
-                "$ref": "ContainerRequest"
-              }
-            }
-          },
-          "response": {
-            "$ref": "ContainerRequest"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "update": {
-          "id": "arvados.container_requests.update",
-          "path": "container_requests/{uuid}",
-          "httpMethod": "PUT",
-          "description": "Update attributes of an existing ContainerRequest.",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "The UUID of the ContainerRequest in question.",
-              "required": true,
-              "location": "path"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of the updated object to return in the response.",
-              "required": false,
-              "location": "query"
-            }
-          },
-          "request": {
-            "required": true,
-            "properties": {
-              "container_request": {
-                "$ref": "ContainerRequest"
-              }
-            }
-          },
-          "response": {
-            "$ref": "ContainerRequest"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "delete": {
-          "id": "arvados.container_requests.delete",
-          "path": "container_requests/{uuid}",
-          "httpMethod": "DELETE",
-          "description": "Delete an existing ContainerRequest.",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "The UUID of the ContainerRequest in question.",
-              "required": true,
-              "location": "path"
-            }
-          },
-          "response": {
-            "$ref": "ContainerRequest"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "container_status": {
-          "id": "arvados.container_requests.container_status",
-          "path": "container_requests/{uuid}/container_status",
+    },
+    "container_requests": {
+      "methods": {
+        "get": {
+          "id": "arvados.container_requests.get",
+          "path": "container_requests/{uuid}",
           "httpMethod": "GET",
-          "description": "container_status container_requests",
+          "description": "Gets a ContainerRequest's metadata by UUID.",
           "parameters": {
             "uuid": {
               "type": "string",
-              "required": true,
               "description": "The UUID of the ContainerRequest in question.",
+              "required": true,
+              "location": "path"
+            },
+            "select": {
+              "type": "array",
+              "description": "Attributes of the object to return in the response.",
+              "required": false,
+              "location": "query"
+            },
+            "include_trash": {
+              "type": "boolean",
+              "required": false,
+              "default": "false",
+              "description": "Show container request even if its owner project is trashed.",
               "location": "query"
             }
           },
+          "parameterOrder": [
+            "uuid"
+          ],
           "response": {
             "$ref": "ContainerRequest"
           },
           "scopes": [
-            "https://api.arvados.org/auth/arvados"
+            "https://api.arvados.org/auth/arvados",
+            "https://api.arvados.org/auth/arvados.readonly"
           ]
         },
         "list": {
@@ -2286,32 +1489,74 @@
             "https://api.arvados.org/auth/arvados.readonly"
           ]
         },
-        "show": {
-          "id": "arvados.container_requests.show",
+        "create": {
+          "id": "arvados.container_requests.create",
+          "path": "container_requests",
+          "httpMethod": "POST",
+          "description": "Create a new ContainerRequest.",
+          "parameters": {
+            "select": {
+              "type": "array",
+              "description": "Attributes of the new object to return in the response.",
+              "required": false,
+              "location": "query"
+            },
+            "ensure_unique_name": {
+              "type": "boolean",
+              "description": "Adjust name to ensure uniqueness instead of returning an error on (owner_uuid, name) collision.",
+              "location": "query",
+              "required": false,
+              "default": "false"
+            },
+            "cluster_id": {
+              "type": "string",
+              "description": "Create object on a remote federated cluster instead of the current one.",
+              "location": "query",
+              "required": false
+            }
+          },
+          "request": {
+            "required": true,
+            "properties": {
+              "container_request": {
+                "$ref": "ContainerRequest"
+              }
+            }
+          },
+          "response": {
+            "$ref": "ContainerRequest"
+          },
+          "scopes": [
+            "https://api.arvados.org/auth/arvados"
+          ]
+        },
+        "update": {
+          "id": "arvados.container_requests.update",
           "path": "container_requests/{uuid}",
-          "httpMethod": "GET",
-          "description": "show container_requests",
+          "httpMethod": "PUT",
+          "description": "Update attributes of an existing ContainerRequest.",
           "parameters": {
             "uuid": {
               "type": "string",
-              "description": "",
+              "description": "The UUID of the ContainerRequest in question.",
               "required": true,
               "location": "path"
             },
             "select": {
               "type": "array",
-              "description": "Attributes of the object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "include_trash": {
-              "type": "boolean",
+              "description": "Attributes of the updated object to return in the response.",
               "required": false,
-              "default": "false",
-              "description": "Show container request even if its owner project is trashed.",
               "location": "query"
             }
           },
+          "request": {
+            "required": true,
+            "properties": {
+              "container_request": {
+                "$ref": "ContainerRequest"
+              }
+            }
+          },
           "response": {
             "$ref": "ContainerRequest"
           },
@@ -2319,15 +1564,15 @@
             "https://api.arvados.org/auth/arvados"
           ]
         },
-        "destroy": {
-          "id": "arvados.container_requests.destroy",
+        "delete": {
+          "id": "arvados.container_requests.delete",
           "path": "container_requests/{uuid}",
           "httpMethod": "DELETE",
-          "description": "destroy container_requests",
+          "description": "Delete an existing ContainerRequest.",
           "parameters": {
             "uuid": {
               "type": "string",
-              "description": "",
+              "description": "The UUID of the ContainerRequest in question.",
               "required": true,
               "location": "path"
             }
@@ -2338,6 +1583,26 @@
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
+        },
+        "container_status": {
+          "id": "arvados.container_requests.container_status",
+          "path": "container_requests/{uuid}/container_status",
+          "httpMethod": "GET",
+          "description": "container_status container_requests",
+          "parameters": {
+            "uuid": {
+              "type": "string",
+              "required": true,
+              "description": "The UUID of the ContainerRequest in question.",
+              "location": "query"
+            }
+          },
+          "response": {
+            "$ref": "ContainerRequest"
+          },
+          "scopes": [
+            "https://api.arvados.org/auth/arvados"
+          ]
         }
       }
     },
@@ -2354,6 +1619,19 @@
               "description": "The UUID of the Group in question.",
               "required": true,
               "location": "path"
+            },
+            "select": {
+              "type": "array",
+              "description": "Attributes of the object to return in the response.",
+              "required": false,
+              "location": "query"
+            },
+            "include_trash": {
+              "type": "boolean",
+              "required": false,
+              "default": "false",
+              "description": "Show group/project even if its is_trashed attribute is true.",
+              "location": "query"
             }
           },
           "parameterOrder": [
@@ -2367,7 +1645,7 @@
             "https://api.arvados.org/auth/arvados.readonly"
           ]
         },
-        "index": {
+        "list": {
           "id": "arvados.groups.list",
           "path": "groups",
           "httpMethod": "GET",
@@ -2542,129 +1820,17 @@
             "https://api.arvados.org/auth/arvados"
           ]
         },
-        "delete": {
-          "id": "arvados.groups.delete",
-          "path": "groups/{uuid}",
-          "httpMethod": "DELETE",
-          "description": "Delete an existing Group.",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "The UUID of the Group in question.",
-              "required": true,
-              "location": "path"
-            }
-          },
-          "response": {
-            "$ref": "Group"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "contents": {
-          "id": "arvados.groups.contents",
-          "path": "groups/contents",
-          "httpMethod": "GET",
-          "description": "contents groups",
-          "parameters": {
-            "filters": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "where": {
-              "type": "object",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "order": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of each object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "distinct": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "",
-              "location": "query"
-            },
-            "limit": {
-              "type": "integer",
-              "required": false,
-              "default": "100",
-              "description": "",
-              "location": "query"
-            },
-            "offset": {
-              "type": "integer",
-              "required": false,
-              "default": "0",
-              "description": "",
-              "location": "query"
-            },
-            "count": {
-              "type": "string",
-              "required": false,
-              "default": "exact",
-              "description": "",
-              "location": "query"
-            },
-            "cluster_id": {
-              "type": "string",
-              "description": "List objects on a remote federated cluster instead of the current one.",
-              "location": "query",
-              "required": false
-            },
-            "bypass_federation": {
-              "type": "boolean",
-              "required": false,
-              "description": "bypass federation behavior, list items from local instance database only",
-              "location": "query"
-            },
-            "include_trash": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "Include items whose is_trashed attribute is true.",
-              "location": "query"
-            },
-            "uuid": {
-              "type": "string",
-              "required": false,
-              "default": "",
-              "description": "",
-              "location": "query"
-            },
-            "recursive": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "Include contents from child groups recursively.",
-              "location": "query"
-            },
-            "include": {
-              "type": "string",
-              "required": false,
-              "description": "Include objects referred to by listed field in \"included\" (only owner_uuid).",
-              "location": "query"
-            },
-            "include_old_versions": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "Include past collection versions.",
-              "location": "query"
+        "delete": {
+          "id": "arvados.groups.delete",
+          "path": "groups/{uuid}",
+          "httpMethod": "DELETE",
+          "description": "Delete an existing Group.",
+          "parameters": {
+            "uuid": {
+              "type": "string",
+              "description": "The UUID of the Group in question.",
+              "required": true,
+              "location": "path"
             }
           },
           "response": {
@@ -2674,11 +1840,11 @@
             "https://api.arvados.org/auth/arvados"
           ]
         },
-        "shared": {
-          "id": "arvados.groups.shared",
-          "path": "groups/shared",
+        "contents": {
+          "id": "arvados.groups.contents",
+          "path": "groups/contents",
           "httpMethod": "GET",
-          "description": "shared groups",
+          "description": "contents groups",
           "parameters": {
             "filters": {
               "type": "array",
@@ -2751,51 +1917,32 @@
               "description": "Include items whose is_trashed attribute is true.",
               "location": "query"
             },
-            "include": {
+            "uuid": {
               "type": "string",
               "required": false,
+              "default": "",
               "description": "",
               "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "Group"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "trash": {
-          "id": "arvados.groups.trash",
-          "path": "groups/{uuid}/trash",
-          "httpMethod": "POST",
-          "description": "trash groups",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            }
-          },
-          "response": {
-            "$ref": "Group"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "untrash": {
-          "id": "arvados.groups.untrash",
-          "path": "groups/{uuid}/untrash",
-          "httpMethod": "POST",
-          "description": "untrash groups",
-          "parameters": {
-            "uuid": {
+            },
+            "recursive": {
+              "type": "boolean",
+              "required": false,
+              "default": "false",
+              "description": "Include contents from child groups recursively.",
+              "location": "query"
+            },
+            "include": {
               "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
+              "required": false,
+              "description": "Include objects referred to by listed field in \"included\" (only owner_uuid).",
+              "location": "query"
+            },
+            "include_old_versions": {
+              "type": "boolean",
+              "required": false,
+              "default": "false",
+              "description": "Include past collection versions.",
+              "location": "query"
             }
           },
           "response": {
@@ -2805,11 +1952,11 @@
             "https://api.arvados.org/auth/arvados"
           ]
         },
-        "list": {
-          "id": "arvados.groups.list",
-          "path": "groups",
+        "shared": {
+          "id": "arvados.groups.shared",
+          "path": "groups/shared",
           "httpMethod": "GET",
-          "description": "List Groups.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching Groups. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#groupList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
+          "description": "shared groups",
           "parameters": {
             "filters": {
               "type": "array",
@@ -2881,40 +2028,32 @@
               "default": "false",
               "description": "Include items whose is_trashed attribute is true.",
               "location": "query"
+            },
+            "include": {
+              "type": "string",
+              "required": false,
+              "description": "",
+              "location": "query"
             }
           },
           "response": {
-            "$ref": "GroupList"
+            "$ref": "Group"
           },
           "scopes": [
-            "https://api.arvados.org/auth/arvados",
-            "https://api.arvados.org/auth/arvados.readonly"
+            "https://api.arvados.org/auth/arvados"
           ]
         },
-        "show": {
-          "id": "arvados.groups.show",
-          "path": "groups/{uuid}",
-          "httpMethod": "GET",
-          "description": "show groups",
+        "trash": {
+          "id": "arvados.groups.trash",
+          "path": "groups/{uuid}/trash",
+          "httpMethod": "POST",
+          "description": "trash groups",
           "parameters": {
             "uuid": {
               "type": "string",
               "description": "",
               "required": true,
               "location": "path"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of the object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "include_trash": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "Show group/project even if its is_trashed attribute is true.",
-              "location": "query"
             }
           },
           "response": {
@@ -2924,11 +2063,11 @@
             "https://api.arvados.org/auth/arvados"
           ]
         },
-        "destroy": {
-          "id": "arvados.groups.destroy",
-          "path": "groups/{uuid}",
-          "httpMethod": "DELETE",
-          "description": "destroy groups",
+        "untrash": {
+          "id": "arvados.groups.untrash",
+          "path": "groups/{uuid}/untrash",
+          "httpMethod": "POST",
+          "description": "untrash groups",
           "parameters": {
             "uuid": {
               "type": "string",
@@ -2959,6 +2098,12 @@
               "description": "The UUID of the KeepService in question.",
               "required": true,
               "location": "path"
+            },
+            "select": {
+              "type": "array",
+              "description": "Attributes of the object to return in the response.",
+              "required": false,
+              "location": "query"
             }
           },
           "parameterOrder": [
@@ -2972,7 +2117,7 @@
             "https://api.arvados.org/auth/arvados.readonly"
           ]
         },
-        "index": {
+        "list": {
           "id": "arvados.keep_services.list",
           "path": "keep_services",
           "httpMethod": "GET",
@@ -3148,135 +2293,10 @@
         },
         "accessible": {
           "id": "arvados.keep_services.accessible",
-          "path": "keep_services/accessible",
-          "httpMethod": "GET",
-          "description": "accessible keep_services",
-          "parameters": {},
-          "response": {
-            "$ref": "KeepService"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "list": {
-          "id": "arvados.keep_services.list",
-          "path": "keep_services",
-          "httpMethod": "GET",
-          "description": "List KeepServices.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching KeepServices. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#keepServiceList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
-          "parameters": {
-            "filters": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "where": {
-              "type": "object",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "order": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of each object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "distinct": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "",
-              "location": "query"
-            },
-            "limit": {
-              "type": "integer",
-              "required": false,
-              "default": "100",
-              "description": "",
-              "location": "query"
-            },
-            "offset": {
-              "type": "integer",
-              "required": false,
-              "default": "0",
-              "description": "",
-              "location": "query"
-            },
-            "count": {
-              "type": "string",
-              "required": false,
-              "default": "exact",
-              "description": "",
-              "location": "query"
-            },
-            "cluster_id": {
-              "type": "string",
-              "description": "List objects on a remote federated cluster instead of the current one.",
-              "location": "query",
-              "required": false
-            },
-            "bypass_federation": {
-              "type": "boolean",
-              "required": false,
-              "description": "bypass federation behavior, list items from local instance database only",
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "KeepServiceList"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados",
-            "https://api.arvados.org/auth/arvados.readonly"
-          ]
-        },
-        "show": {
-          "id": "arvados.keep_services.show",
-          "path": "keep_services/{uuid}",
-          "httpMethod": "GET",
-          "description": "show keep_services",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of the object to return in the response.",
-              "required": false,
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "KeepService"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "destroy": {
-          "id": "arvados.keep_services.destroy",
-          "path": "keep_services/{uuid}",
-          "httpMethod": "DELETE",
-          "description": "destroy keep_services",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            }
-          },
+          "path": "keep_services/accessible",
+          "httpMethod": "GET",
+          "description": "accessible keep_services",
+          "parameters": {},
           "response": {
             "$ref": "KeepService"
           },
@@ -3299,6 +2319,12 @@
               "description": "The UUID of the Link in question.",
               "required": true,
               "location": "path"
+            },
+            "select": {
+              "type": "array",
+              "description": "Attributes of the object to return in the response.",
+              "required": false,
+              "location": "query"
             }
           },
           "parameterOrder": [
@@ -3312,7 +2338,7 @@
             "https://api.arvados.org/auth/arvados.readonly"
           ]
         },
-        "index": {
+        "list": {
           "id": "arvados.links.list",
           "path": "links",
           "httpMethod": "GET",
@@ -3486,131 +2512,6 @@
             "https://api.arvados.org/auth/arvados"
           ]
         },
-        "list": {
-          "id": "arvados.links.list",
-          "path": "links",
-          "httpMethod": "GET",
-          "description": "List Links.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching Links. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#linkList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
-          "parameters": {
-            "filters": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "where": {
-              "type": "object",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "order": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of each object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "distinct": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "",
-              "location": "query"
-            },
-            "limit": {
-              "type": "integer",
-              "required": false,
-              "default": "100",
-              "description": "",
-              "location": "query"
-            },
-            "offset": {
-              "type": "integer",
-              "required": false,
-              "default": "0",
-              "description": "",
-              "location": "query"
-            },
-            "count": {
-              "type": "string",
-              "required": false,
-              "default": "exact",
-              "description": "",
-              "location": "query"
-            },
-            "cluster_id": {
-              "type": "string",
-              "description": "List objects on a remote federated cluster instead of the current one.",
-              "location": "query",
-              "required": false
-            },
-            "bypass_federation": {
-              "type": "boolean",
-              "required": false,
-              "description": "bypass federation behavior, list items from local instance database only",
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "LinkList"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados",
-            "https://api.arvados.org/auth/arvados.readonly"
-          ]
-        },
-        "show": {
-          "id": "arvados.links.show",
-          "path": "links/{uuid}",
-          "httpMethod": "GET",
-          "description": "show links",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of the object to return in the response.",
-              "required": false,
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "Link"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "destroy": {
-          "id": "arvados.links.destroy",
-          "path": "links/{uuid}",
-          "httpMethod": "DELETE",
-          "description": "destroy links",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            }
-          },
-          "response": {
-            "$ref": "Link"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
         "get_permissions": {
           "id": "arvados.links.get_permissions",
           "path": "permissions/{uuid}",
@@ -3646,6 +2547,12 @@
               "description": "The UUID of the Log in question.",
               "required": true,
               "location": "path"
+            },
+            "select": {
+              "type": "array",
+              "description": "Attributes of the object to return in the response.",
+              "required": false,
+              "location": "query"
             }
           },
           "parameterOrder": [
@@ -3659,7 +2566,7 @@
             "https://api.arvados.org/auth/arvados.readonly"
           ]
         },
-        "index": {
+        "list": {
           "id": "arvados.logs.list",
           "path": "logs",
           "httpMethod": "GET",
@@ -3832,131 +2739,6 @@
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
-        },
-        "list": {
-          "id": "arvados.logs.list",
-          "path": "logs",
-          "httpMethod": "GET",
-          "description": "List Logs.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching Logs. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#logList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
-          "parameters": {
-            "filters": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "where": {
-              "type": "object",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "order": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of each object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "distinct": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "",
-              "location": "query"
-            },
-            "limit": {
-              "type": "integer",
-              "required": false,
-              "default": "100",
-              "description": "",
-              "location": "query"
-            },
-            "offset": {
-              "type": "integer",
-              "required": false,
-              "default": "0",
-              "description": "",
-              "location": "query"
-            },
-            "count": {
-              "type": "string",
-              "required": false,
-              "default": "exact",
-              "description": "",
-              "location": "query"
-            },
-            "cluster_id": {
-              "type": "string",
-              "description": "List objects on a remote federated cluster instead of the current one.",
-              "location": "query",
-              "required": false
-            },
-            "bypass_federation": {
-              "type": "boolean",
-              "required": false,
-              "description": "bypass federation behavior, list items from local instance database only",
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "LogList"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados",
-            "https://api.arvados.org/auth/arvados.readonly"
-          ]
-        },
-        "show": {
-          "id": "arvados.logs.show",
-          "path": "logs/{uuid}",
-          "httpMethod": "GET",
-          "description": "show logs",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of the object to return in the response.",
-              "required": false,
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "Log"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "destroy": {
-          "id": "arvados.logs.destroy",
-          "path": "logs/{uuid}",
-          "httpMethod": "DELETE",
-          "description": "destroy logs",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            }
-          },
-          "response": {
-            "$ref": "Log"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
         }
       }
     },
@@ -3973,6 +2755,12 @@
               "description": "The UUID of the User in question.",
               "required": true,
               "location": "path"
+            },
+            "select": {
+              "type": "array",
+              "description": "Attributes of the object to return in the response.",
+              "required": false,
+              "location": "query"
             }
           },
           "parameterOrder": [
@@ -3986,7 +2774,7 @@
             "https://api.arvados.org/auth/arvados.readonly"
           ]
         },
-        "index": {
+        "list": {
           "id": "arvados.users.list",
           "path": "users",
           "httpMethod": "GET",
@@ -4322,131 +3110,6 @@
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
-        },
-        "list": {
-          "id": "arvados.users.list",
-          "path": "users",
-          "httpMethod": "GET",
-          "description": "List Users.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching Users. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#userList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
-          "parameters": {
-            "filters": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "where": {
-              "type": "object",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "order": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of each object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "distinct": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "",
-              "location": "query"
-            },
-            "limit": {
-              "type": "integer",
-              "required": false,
-              "default": "100",
-              "description": "",
-              "location": "query"
-            },
-            "offset": {
-              "type": "integer",
-              "required": false,
-              "default": "0",
-              "description": "",
-              "location": "query"
-            },
-            "count": {
-              "type": "string",
-              "required": false,
-              "default": "exact",
-              "description": "",
-              "location": "query"
-            },
-            "cluster_id": {
-              "type": "string",
-              "description": "List objects on a remote federated cluster instead of the current one.",
-              "location": "query",
-              "required": false
-            },
-            "bypass_federation": {
-              "type": "boolean",
-              "required": false,
-              "description": "bypass federation behavior, list items from local instance database only",
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "UserList"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados",
-            "https://api.arvados.org/auth/arvados.readonly"
-          ]
-        },
-        "show": {
-          "id": "arvados.users.show",
-          "path": "users/{uuid}",
-          "httpMethod": "GET",
-          "description": "show users",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of the object to return in the response.",
-              "required": false,
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "User"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "destroy": {
-          "id": "arvados.users.destroy",
-          "path": "users/{uuid}",
-          "httpMethod": "DELETE",
-          "description": "destroy users",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            }
-          },
-          "response": {
-            "$ref": "User"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
         }
       }
     },
@@ -4463,6 +3126,12 @@
               "description": "The UUID of the UserAgreement in question.",
               "required": true,
               "location": "path"
+            },
+            "select": {
+              "type": "array",
+              "description": "Attributes of the object to return in the response.",
+              "required": false,
+              "location": "query"
             }
           },
           "parameterOrder": [
@@ -4476,7 +3145,7 @@
             "https://api.arvados.org/auth/arvados.readonly"
           ]
         },
-        "index": {
+        "list": {
           "id": "arvados.user_agreements.list",
           "path": "user_agreements",
           "httpMethod": "GET",
@@ -4676,137 +3345,12 @@
             "https://api.arvados.org/auth/arvados"
           ]
         },
-        "list": {
-          "id": "arvados.user_agreements.list",
-          "path": "user_agreements",
-          "httpMethod": "GET",
-          "description": "List UserAgreements.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching UserAgreements. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#userAgreementList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
-          "parameters": {
-            "filters": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "where": {
-              "type": "object",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "order": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of each object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "distinct": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "",
-              "location": "query"
-            },
-            "limit": {
-              "type": "integer",
-              "required": false,
-              "default": "100",
-              "description": "",
-              "location": "query"
-            },
-            "offset": {
-              "type": "integer",
-              "required": false,
-              "default": "0",
-              "description": "",
-              "location": "query"
-            },
-            "count": {
-              "type": "string",
-              "required": false,
-              "default": "exact",
-              "description": "",
-              "location": "query"
-            },
-            "cluster_id": {
-              "type": "string",
-              "description": "List objects on a remote federated cluster instead of the current one.",
-              "location": "query",
-              "required": false
-            },
-            "bypass_federation": {
-              "type": "boolean",
-              "required": false,
-              "description": "bypass federation behavior, list items from local instance database only",
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "UserAgreementList"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados",
-            "https://api.arvados.org/auth/arvados.readonly"
-          ]
-        },
         "new": {
           "id": "arvados.user_agreements.new",
-          "path": "user_agreements/new",
-          "httpMethod": "GET",
-          "description": "new user_agreements",
-          "parameters": {},
-          "response": {
-            "$ref": "UserAgreement"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "show": {
-          "id": "arvados.user_agreements.show",
-          "path": "user_agreements/{uuid}",
-          "httpMethod": "GET",
-          "description": "show user_agreements",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of the object to return in the response.",
-              "required": false,
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "UserAgreement"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "destroy": {
-          "id": "arvados.user_agreements.destroy",
-          "path": "user_agreements/{uuid}",
-          "httpMethod": "DELETE",
-          "description": "destroy user_agreements",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            }
-          },
+          "path": "user_agreements/new",
+          "httpMethod": "GET",
+          "description": "new user_agreements",
+          "parameters": {},
           "response": {
             "$ref": "UserAgreement"
           },
@@ -4829,6 +3373,12 @@
               "description": "The UUID of the VirtualMachine in question.",
               "required": true,
               "location": "path"
+            },
+            "select": {
+              "type": "array",
+              "description": "Attributes of the object to return in the response.",
+              "required": false,
+              "location": "query"
             }
           },
           "parameterOrder": [
@@ -4842,7 +3392,7 @@
             "https://api.arvados.org/auth/arvados.readonly"
           ]
         },
-        "index": {
+        "list": {
           "id": "arvados.virtual_machines.list",
           "path": "virtual_machines",
           "httpMethod": "GET",
@@ -5048,131 +3598,6 @@
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
-        },
-        "list": {
-          "id": "arvados.virtual_machines.list",
-          "path": "virtual_machines",
-          "httpMethod": "GET",
-          "description": "List VirtualMachines.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching VirtualMachines. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#virtualMachineList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
-          "parameters": {
-            "filters": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "where": {
-              "type": "object",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "order": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of each object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "distinct": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "",
-              "location": "query"
-            },
-            "limit": {
-              "type": "integer",
-              "required": false,
-              "default": "100",
-              "description": "",
-              "location": "query"
-            },
-            "offset": {
-              "type": "integer",
-              "required": false,
-              "default": "0",
-              "description": "",
-              "location": "query"
-            },
-            "count": {
-              "type": "string",
-              "required": false,
-              "default": "exact",
-              "description": "",
-              "location": "query"
-            },
-            "cluster_id": {
-              "type": "string",
-              "description": "List objects on a remote federated cluster instead of the current one.",
-              "location": "query",
-              "required": false
-            },
-            "bypass_federation": {
-              "type": "boolean",
-              "required": false,
-              "description": "bypass federation behavior, list items from local instance database only",
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "VirtualMachineList"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados",
-            "https://api.arvados.org/auth/arvados.readonly"
-          ]
-        },
-        "show": {
-          "id": "arvados.virtual_machines.show",
-          "path": "virtual_machines/{uuid}",
-          "httpMethod": "GET",
-          "description": "show virtual_machines",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of the object to return in the response.",
-              "required": false,
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "VirtualMachine"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "destroy": {
-          "id": "arvados.virtual_machines.destroy",
-          "path": "virtual_machines/{uuid}",
-          "httpMethod": "DELETE",
-          "description": "destroy virtual_machines",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            }
-          },
-          "response": {
-            "$ref": "VirtualMachine"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
         }
       }
     },
@@ -5189,6 +3614,12 @@
               "description": "The UUID of the Workflow in question.",
               "required": true,
               "location": "path"
+            },
+            "select": {
+              "type": "array",
+              "description": "Attributes of the object to return in the response.",
+              "required": false,
+              "location": "query"
             }
           },
           "parameterOrder": [
@@ -5202,7 +3633,7 @@
             "https://api.arvados.org/auth/arvados.readonly"
           ]
         },
-        "index": {
+        "list": {
           "id": "arvados.workflows.list",
           "path": "workflows",
           "httpMethod": "GET",
@@ -5375,131 +3806,6 @@
           "scopes": [
             "https://api.arvados.org/auth/arvados"
           ]
-        },
-        "list": {
-          "id": "arvados.workflows.list",
-          "path": "workflows",
-          "httpMethod": "GET",
-          "description": "List Workflows.\n\n                   The <code>list</code> method returns a\n                   <a href=\"/api/resources.html\">resource list</a> of\n                   matching Workflows. For example:\n\n                   <pre>\n                   {\n                    \"kind\":\"arvados#workflowList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    </pre>",
-          "parameters": {
-            "filters": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "where": {
-              "type": "object",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "order": {
-              "type": "array",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of each object to return in the response.",
-              "required": false,
-              "location": "query"
-            },
-            "distinct": {
-              "type": "boolean",
-              "required": false,
-              "default": "false",
-              "description": "",
-              "location": "query"
-            },
-            "limit": {
-              "type": "integer",
-              "required": false,
-              "default": "100",
-              "description": "",
-              "location": "query"
-            },
-            "offset": {
-              "type": "integer",
-              "required": false,
-              "default": "0",
-              "description": "",
-              "location": "query"
-            },
-            "count": {
-              "type": "string",
-              "required": false,
-              "default": "exact",
-              "description": "",
-              "location": "query"
-            },
-            "cluster_id": {
-              "type": "string",
-              "description": "List objects on a remote federated cluster instead of the current one.",
-              "location": "query",
-              "required": false
-            },
-            "bypass_federation": {
-              "type": "boolean",
-              "required": false,
-              "description": "bypass federation behavior, list items from local instance database only",
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "WorkflowList"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados",
-            "https://api.arvados.org/auth/arvados.readonly"
-          ]
-        },
-        "show": {
-          "id": "arvados.workflows.show",
-          "path": "workflows/{uuid}",
-          "httpMethod": "GET",
-          "description": "show workflows",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            },
-            "select": {
-              "type": "array",
-              "description": "Attributes of the object to return in the response.",
-              "required": false,
-              "location": "query"
-            }
-          },
-          "response": {
-            "$ref": "Workflow"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
-        },
-        "destroy": {
-          "id": "arvados.workflows.destroy",
-          "path": "workflows/{uuid}",
-          "httpMethod": "DELETE",
-          "description": "destroy workflows",
-          "parameters": {
-            "uuid": {
-              "type": "string",
-              "description": "",
-              "required": true,
-              "location": "path"
-            }
-          },
-          "response": {
-            "$ref": "Workflow"
-          },
-          "scopes": [
-            "https://api.arvados.org/auth/arvados"
-          ]
         }
       }
     },
diff --git a/services/api/app/controllers/arvados/v1/schema_controller.rb b/services/api/app/controllers/arvados/v1/schema_controller.rb
index dd7a7a759e..94e6690b23 100644
--- a/services/api/app/controllers/arvados/v1/schema_controller.rb
+++ b/services/api/app/controllers/arvados/v1/schema_controller.rb
@@ -23,6 +23,12 @@ class Arvados::V1::SchemaController < ApplicationController
 
   protected
 
+  ActionNameMap = {
+    'destroy' => 'delete',
+    'index' => 'list',
+    'show' => 'get',
+  }
+
   def discovery_doc
     Rails.application.eager_load!
     remoteHosts = {}
@@ -216,14 +222,14 @@ class Arvados::V1::SchemaController < ApplicationController
               "https://api.arvados.org/auth/arvados.readonly"
             ]
           },
-          index: {
-            id: "arvados.#{k.to_s.underscore.pluralize}.index",
+          list: {
+            id: "arvados.#{k.to_s.underscore.pluralize}.list",
             path: k.to_s.underscore.pluralize,
             httpMethod: "GET",
             description:
-              %|Index #{k.to_s.pluralize}.
+              %|List #{k.to_s.pluralize}.
 
-                   The <code>index</code> method returns a
+                   The <code>list</code> method returns a
                    <a href="/api/resources.html">resource list</a> of
                    matching #{k.to_s.pluralize}. For example:
 
@@ -331,18 +337,20 @@ class Arvados::V1::SchemaController < ApplicationController
         httpMethod = ['GET', 'POST', 'PUT', 'DELETE'].map { |method|
           method if route.verb.match(method)
         }.compact.first
-        if httpMethod and
-          route.defaults[:controller] == 'arvados/v1/' + k.to_s.underscore.pluralize and
-          ctl_class.action_methods.include? action
-          if !d_methods[action.to_sym]
+        if httpMethod &&
+          route.defaults[:controller] == 'arvados/v1/' + k.to_s.underscore.pluralize &&
+          ctl_class.action_methods.include?(action)
+          method_name = ActionNameMap[action] || action
+          method_key = method_name.to_sym
+          if !d_methods[method_key]
             method = {
-              id: "arvados.#{k.to_s.underscore.pluralize}.#{action}",
+              id: "arvados.#{k.to_s.underscore.pluralize}.#{method_name}",
               path: route.path.spec.to_s.sub('/arvados/v1/','').sub('(.:format)','').sub(/:(uu)?id/,'{uuid}'),
               httpMethod: httpMethod,
-              description: "#{action} #{k.to_s.underscore.pluralize}",
+              description: "#{method_name} #{k.to_s.underscore.pluralize}",
               parameters: {},
               response: {
-                "$ref" => (action == 'index' ? "#{k.to_s}List" : k.to_s)
+                "$ref" => (method_name == 'list' ? "#{k.to_s}List" : k.to_s)
               },
               scopes: [
                 "https://api.arvados.org/auth/arvados"
@@ -363,7 +371,7 @@ class Arvados::V1::SchemaController < ApplicationController
             # We already built a generic method description, but we
             # might find some more required parameters through
             # introspection.
-            method = d_methods[action.to_sym]
+            method = d_methods[method_key]
           end
           if ctl_class.respond_to? "_#{action}_requires_parameters".to_sym
             ctl_class.send("_#{action}_requires_parameters".to_sym).each do |l, v|
@@ -384,15 +392,7 @@ class Arvados::V1::SchemaController < ApplicationController
               end
             end
           end
-          d_methods[action.to_sym] = method
-
-          if action == 'index'
-            list_method = method.dup
-            list_method[:id].sub!('index', 'list')
-            list_method[:description].sub!('Index', 'List')
-            list_method[:description].sub!('index', 'list')
-            d_methods[:list] = list_method
-          end
+          d_methods[method_key] = method
         end
       end
     end

commit 28fb2fc7ebc231e91e6831aca12edc57bf604ae4
Author: Tom Clegg <tom at curii.com>
Date:   Wed May 15 17:11:04 2024 -0400

    15937: Remove unused mail configs.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/lib/config/config.default.yml b/lib/config/config.default.yml
index e32c168e2d..045ce1c212 100644
--- a/lib/config/config.default.yml
+++ b/lib/config/config.default.yml
@@ -1757,17 +1757,9 @@ Clusters:
       # earlier in Users.UserSetupMailText
       SendUserSetupNotificationEmail: true
 
-      # Bug/issue report notification to and from addresses
-      IssueReporterEmailFrom: "arvados at example.com"
-      IssueReporterEmailTo: "arvados at example.com"
+      # Support email address to display in Workbench.
       SupportEmailAddress: "arvados at example.com"
 
-      # Generic issue email from
-      EmailFrom: "arvados at example.com"
-
-      # No longer supported, to be removed.
-      MailchimpAPIKey: ""
-      MailchimpListID: ""
     RemoteClusters:
       "*":
         Host: ""
diff --git a/lib/config/export.go b/lib/config/export.go
index 3c1e6bc008..5c41b6b725 100644
--- a/lib/config/export.go
+++ b/lib/config/export.go
@@ -203,11 +203,6 @@ var whitelist = map[string]bool{
 	"Login.TrustedClients":                                false,
 	"Login.TrustPrivateNetworks":                          false,
 	"Mail":                                                true,
-	"Mail.EmailFrom":                                      false,
-	"Mail.IssueReporterEmailFrom":                         false,
-	"Mail.IssueReporterEmailTo":                           false,
-	"Mail.MailchimpAPIKey":                                false,
-	"Mail.MailchimpListID":                                false,
 	"Mail.SendUserSetupNotificationEmail":                 false,
 	"Mail.SupportEmailAddress":                            true,
 	"ManagementToken":                                     false,
diff --git a/sdk/go/arvados/config.go b/sdk/go/arvados/config.go
index 8572613e94..149e319a7e 100644
--- a/sdk/go/arvados/config.go
+++ b/sdk/go/arvados/config.go
@@ -214,13 +214,8 @@ type Cluster struct {
 		IssueTrustedTokens   bool
 	}
 	Mail struct {
-		MailchimpAPIKey                string
-		MailchimpListID                string
 		SendUserSetupNotificationEmail bool
-		IssueReporterEmailFrom         string
-		IssueReporterEmailTo           string
 		SupportEmailAddress            string
-		EmailFrom                      string
 	}
 	SystemLogs struct {
 		LogLevel                  string
diff --git a/services/api/config/arvados_config.rb b/services/api/config/arvados_config.rb
index c3a1bed482..a3123c7dc4 100644
--- a/services/api/config/arvados_config.rb
+++ b/services/api/config/arvados_config.rb
@@ -132,8 +132,6 @@ arvcfg.declare_config "Containers.MaxRetryAttempts", Integer, :container_count_m
 arvcfg.declare_config "Containers.AlwaysUsePreemptibleInstances", Boolean, :preemptible_instances
 arvcfg.declare_config "Containers.Logging.LogUpdatePeriod", ActiveSupport::Duration, :crunch_log_update_period
 arvcfg.declare_config "Containers.Logging.LogUpdateSize", Integer, :crunch_log_update_size
-arvcfg.declare_config "Mail.MailchimpAPIKey", String, :mailchimp_api_key
-arvcfg.declare_config "Mail.MailchimpListID", String, :mailchimp_list_id
 arvcfg.declare_config "Services.Controller.ExternalURL", URI
 arvcfg.declare_config "Services.Workbench1.ExternalURL", URI, :workbench_address
 arvcfg.declare_config "Services.Websocket.ExternalURL", URI, :websocket_address

commit 5754d95ba6da4cd949ea2788e79bac9e87bdddaf
Author: Tom Clegg <tom at curii.com>
Date:   Wed May 15 17:04:43 2024 -0400

    15397: Remove updated_at usage.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/sdk/go/arvados/job.go b/sdk/go/arvados/job.go
index ccf752ce7c..1daf07154d 100644
--- a/sdk/go/arvados/job.go
+++ b/sdk/go/arvados/job.go
@@ -25,7 +25,6 @@ type Job struct {
 	Success                bool                   `json:"success"`
 	Output                 string                 `json:"output"`
 	CreatedAt              time.Time              `json:"created_at"`
-	UpdatedAt              time.Time              `json:"updated_at"`
 	IsLockedByUUID         string                 `json:"is_locked_by_uuid"`
 	Log                    string                 `json:"log"`
 	TasksSummary           map[string]interface{} `json:"tasks_summary"`
diff --git a/sdk/go/arvados/pipeline_instance.go b/sdk/go/arvados/pipeline_instance.go
index ace1826850..507982647c 100644
--- a/sdk/go/arvados/pipeline_instance.go
+++ b/sdk/go/arvados/pipeline_instance.go
@@ -18,7 +18,6 @@ type PipelineInstance struct {
 	PipelineTemplateUUID string                 `json:"pipeline_template_uuid"`
 	Name                 string                 `json:"name"`
 	Components           map[string]interface{} `json:"components"`
-	UpdatedAt            time.Time              `json:"updated_at"`
 	Properties           map[string]interface{} `json:"properties"`
 	State                string                 `json:"state"`
 	ComponentsSummary    map[string]interface{} `json:"components_summary"`
diff --git a/sdk/go/arvados/pipeline_template.go b/sdk/go/arvados/pipeline_template.go
index 31d9e8b2fe..259f12513b 100644
--- a/sdk/go/arvados/pipeline_template.go
+++ b/sdk/go/arvados/pipeline_template.go
@@ -17,7 +17,6 @@ type PipelineTemplate struct {
 	ModifiedAt           time.Time              `json:"modified_at"`
 	Name                 string                 `json:"name"`
 	Components           map[string]interface{} `json:"components"`
-	UpdatedAt            time.Time              `json:"updated_at"`
 	Description          string                 `json:"description"`
 	WritableBy           []string               `json:"writable_by,omitempty"`
 }
diff --git a/sdk/go/arvados/trait.go b/sdk/go/arvados/trait.go
index fb0e799b6b..88e7640bed 100644
--- a/sdk/go/arvados/trait.go
+++ b/sdk/go/arvados/trait.go
@@ -17,7 +17,6 @@ type Trait struct {
 	ModifiedAt           time.Time              `json:"modified_at"`
 	Name                 string                 `json:"name"`
 	Properties           map[string]interface{} `json:"properties"`
-	UpdatedAt            time.Time              `json:"updated_at"`
 	WritableBy           []string               `json:"writable_by,omitempty"`
 }
 
diff --git a/services/api/test/unit/arvados_model_test.rb b/services/api/test/unit/arvados_model_test.rb
index 341a8462dd..a6c49dda44 100644
--- a/services/api/test/unit/arvados_model_test.rb
+++ b/services/api/test/unit/arvados_model_test.rb
@@ -230,15 +230,15 @@ class ArvadosModelTest < ActiveSupport::TestCase
     group.update!(name: "test create and update name 1")
     results = Group.where(uuid: group.uuid)
     assert_equal "test create and update name 1", results.first.name, "Expected name to be updated to 1"
-    updated_at_1 = results.first.updated_at.to_f
+    modified_at_1 = results.first.modified_at.to_f
 
     # update 2
     group.update!(name: "test create and update name 2")
     results = Group.where(uuid: group.uuid)
     assert_equal "test create and update name 2", results.first.name, "Expected name to be updated to 2"
-    updated_at_2 = results.first.updated_at.to_f
+    modified_at_2 = results.first.modified_at.to_f
 
-    assert_equal true, (updated_at_2 > updated_at_1), "Expected updated time 2 to be newer than 1"
+    assert_equal true, (modified_at_2 > modified_at_1), "Expected modified time 2 to be newer than 1"
   end
 
   test 'jsonb column' do
diff --git a/services/api/test/unit/group_test.rb b/services/api/test/unit/group_test.rb
index e03ca8da05..4ffa5ff10f 100644
--- a/services/api/test/unit/group_test.rb
+++ b/services/api/test/unit/group_test.rb
@@ -257,10 +257,10 @@ class GroupTest < ActiveSupport::TestCase
 
   def insert_group uuid, owner_uuid, name, group_class
     q = ActiveRecord::Base.connection.exec_query %{
-insert into groups (uuid, owner_uuid, name, group_class, created_at, updated_at)
+insert into groups (uuid, owner_uuid, name, group_class, created_at, updated_at, modified_at)
        values ('#{uuid}', '#{owner_uuid}',
                '#{name}', #{if group_class then "'"+group_class+"'" else 'NULL' end},
-               statement_timestamp(), statement_timestamp())
+               statement_timestamp(), statement_timestamp(), statement_timestamp())
 }
     uuid
   end

commit 29b8327c0b741f9ed92baa57e7ebdb45e2267c6a
Author: Tom Clegg <tom at curii.com>
Date:   Wed May 15 16:55:33 2024 -0400

    15397: Remove api_client_id and user_id fields from api_client_auth.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/doc/admin/scoped-tokens.html.textile.liquid b/doc/admin/scoped-tokens.html.textile.liquid
index 415f635dcd..526bf923b1 100644
--- a/doc/admin/scoped-tokens.html.textile.liquid
+++ b/doc/admin/scoped-tokens.html.textile.liquid
@@ -54,8 +54,6 @@ A scoped token can be created at the command line:
  "modified_by_client_uuid":null,
  "modified_by_user_uuid":null,
  "modified_at":null,
- "user_id":3,
- "api_client_id":7,
  "api_token":"5a74htnoqwkhtfo2upekpfbsg04hv7cy5v4nowf7dtpxer086m",
  "created_by_ip_address":null,
  "default_owner_uuid":null,
diff --git a/doc/admin/user-management-cli.html.textile.liquid b/doc/admin/user-management-cli.html.textile.liquid
index dea705ddaa..d8bb3fbee0 100644
--- a/doc/admin/user-management-cli.html.textile.liquid
+++ b/doc/admin/user-management-cli.html.textile.liquid
@@ -65,8 +65,6 @@ As an admin, you can create tokens for other users.
  "modified_by_client_uuid":null,
  "modified_by_user_uuid":null,
  "modified_at":null,
- "user_id":3,
- "api_client_id":7,
  "api_token":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "created_by_ip_address":null,
  "default_owner_uuid":null,
diff --git a/doc/api/methods/api_client_authorizations.html.textile.liquid b/doc/api/methods/api_client_authorizations.html.textile.liquid
index 5bfeca8bc6..545988056d 100644
--- a/doc/api/methods/api_client_authorizations.html.textile.liquid
+++ b/doc/api/methods/api_client_authorizations.html.textile.liquid
@@ -60,7 +60,6 @@ Arguments:
 
 table(table table-bordered table-condensed).
 |_. Argument |_. Type |_. Description |_. Location |_. Example |
-|api_client_id|integer||query||
 |scopes|array||query||
 
 h3(#current). current
diff --git a/sdk/go/arvados/api_client_authorization.go b/sdk/go/arvados/api_client_authorization.go
index c920d2dc34..5ea824c958 100644
--- a/sdk/go/arvados/api_client_authorization.go
+++ b/sdk/go/arvados/api_client_authorization.go
@@ -9,7 +9,6 @@ import "time"
 // APIClientAuthorization is an arvados#apiClientAuthorization resource.
 type APIClientAuthorization struct {
 	UUID                 string    `json:"uuid"`
-	APIClientID          int       `json:"api_client_id"`
 	APIToken             string    `json:"api_token"`
 	CreatedAt            time.Time `json:"created_at"`
 	CreatedByIPAddress   string    `json:"created_by_ip_address"`
@@ -23,7 +22,6 @@ type APIClientAuthorization struct {
 	ModifiedByUserUUID   string    `json:"modified_by_user_uuid"`
 	OwnerUUID            string    `json:"owner_uuid"`
 	Scopes               []string  `json:"scopes"`
-	UserID               int       `json:"user_id"`
 }
 
 // APIClientAuthorizationList is an arvados#apiClientAuthorizationList resource.
diff --git a/sdk/python/arvados-v1-discovery.json b/sdk/python/arvados-v1-discovery.json
index ef187f6663..52d198eafd 100644
--- a/sdk/python/arvados-v1-discovery.json
+++ b/sdk/python/arvados-v1-discovery.json
@@ -583,12 +583,6 @@
           "httpMethod": "POST",
           "description": "create_system_auth api_client_authorizations",
           "parameters": {
-            "api_client_id": {
-              "type": "integer",
-              "required": false,
-              "description": "",
-              "location": "query"
-            },
             "scopes": {
               "type": "array",
               "required": false,
@@ -5688,12 +5682,6 @@
         "api_token": {
           "type": "string"
         },
-        "api_client_id": {
-          "type": "integer"
-        },
-        "user_id": {
-          "type": "integer"
-        },
         "created_by_ip_address": {
           "type": "string"
         },
@@ -5709,9 +5697,6 @@
         "created_at": {
           "type": "datetime"
         },
-        "default_owner_uuid": {
-          "type": "string"
-        },
         "scopes": {
           "type": "Array"
         }
diff --git a/services/api/app/controllers/arvados/v1/api_client_authorizations_controller.rb b/services/api/app/controllers/arvados/v1/api_client_authorizations_controller.rb
index da7e11cd9f..e6f2a889e7 100644
--- a/services/api/app/controllers/arvados/v1/api_client_authorizations_controller.rb
+++ b/services/api/app/controllers/arvados/v1/api_client_authorizations_controller.rb
@@ -13,7 +13,6 @@ class Arvados::V1::ApiClientAuthorizationsController < ApplicationController
 
   def self._create_system_auth_requires_parameters
     {
-      api_client_id: {type: 'integer', required: false},
       scopes: {type: 'array', required: false}
     }
   end
@@ -21,7 +20,7 @@ class Arvados::V1::ApiClientAuthorizationsController < ApplicationController
   def create_system_auth
     @object = ApiClientAuthorization.
       new(user_id: system_user.id,
-          api_client_id: params[:api_client_id] || current_api_client.andand.id,
+          api_client_id: 0,
           created_by_ip_address: remote_ip,
           scopes: SafeJSON.load(params[:scopes] || '["all"]'))
     @object.save!
@@ -41,10 +40,10 @@ class Arvados::V1::ApiClientAuthorizationsController < ApplicationController
       # translate UUID to numeric ID here.
       resource_attrs[:user_id] =
         User.where(uuid: resource_attrs.delete(:owner_uuid)).first.andand.id
-    elsif not resource_attrs[:user_id]
+    else
       resource_attrs[:user_id] = current_user.id
     end
-    resource_attrs[:api_client_id] = Thread.current[:api_client].id
+    resource_attrs[:api_client_id] = 0
     super
   end
 
@@ -81,7 +80,6 @@ class Arvados::V1::ApiClientAuthorizationsController < ApplicationController
       wanted_scopes << @where['scopes']
       @where.select! { |attr, val|
         # "where":{"uuid":"zzzzz-zzzzz-zzzzzzzzzzzzzzz"} is OK but
-        # "where":{"api_client_id":1} is not supported
         # "where":{"uuid":["contains","-"]} is not supported
         # "where":{"uuid":["uuid1","uuid2","uuid3"]} is not supported
         val.is_a?(String) && (attr == 'uuid' || attr == 'api_token')
diff --git a/services/api/app/models/api_client_authorization.rb b/services/api/app/models/api_client_authorization.rb
index 8311278676..d4cb3b7b09 100644
--- a/services/api/app/models/api_client_authorization.rb
+++ b/services/api/app/models/api_client_authorization.rb
@@ -19,14 +19,11 @@ class ApiClientAuthorization < ArvadosModel
 
   api_accessible :user, extend: :common do |t|
     t.add :owner_uuid
-    t.add :user_id
-    t.add :api_client_id
     # NB the "api_token" db column is a misnomer in that it's only the
     # "secret" part of a token: a v1 token is just the secret, but a
     # v2 token is "v2/uuid/secret".
     t.add :api_token
     t.add :created_by_ip_address
-    t.add :default_owner_uuid
     t.add :expires_at
     t.add :last_used_at
     t.add :last_used_by_ip_address
@@ -421,10 +418,10 @@ class ApiClientAuthorization < ArvadosModel
         end
       end
       auth.update!(user: user,
-                              api_token: stored_secret,
-                              api_client_id: 0,
-                              scopes: scopes,
-                              expires_at: exp)
+                   api_token: stored_secret,
+                   api_client_id: 0,
+                   scopes: scopes,
+                   expires_at: exp)
       Rails.logger.debug "cached remote token #{token_uuid} with secret #{stored_secret} and scopes #{scopes} in local db"
       auth.api_token = secret
       return auth
diff --git a/services/api/lib/create_superuser_token.rb b/services/api/lib/create_superuser_token.rb
index 7a18d97058..9fab3b204c 100755
--- a/services/api/lib/create_superuser_token.rb
+++ b/services/api/lib/create_superuser_token.rb
@@ -29,16 +29,10 @@ module CreateSuperUserToken
 
       # need to create a token
       if !api_client_auth
-        # Get (or create) trusted api client
-        apiClient =  ApiClient.
-          find_or_create_by(url_prefix: "ssh://root@localhost/",
-                            is_trusted: true)
-
-        # Check if there is an unexpired superuser token corresponding to this api client
+        # Check if there is an unexpired superuser token
         api_client_auth =
           ApiClientAuthorization.
           where(user_id: system_user.id).
-          where(api_client_id: apiClient.id).
           where_serialized(:scopes, ['all']).
           where('(expires_at IS NULL OR expires_at > CURRENT_TIMESTAMP)').
           first
@@ -47,7 +41,7 @@ module CreateSuperUserToken
         if !api_client_auth
           api_client_auth = ApiClientAuthorization.
             new(user: system_user,
-              api_client_id: apiClient.id,
+              api_client_id: 0,
               created_by_ip_address: '::1',
               api_token: supplied_token)
           api_client_auth.save!
diff --git a/services/api/test/integration/api_client_authorizations_scopes_test.rb b/services/api/test/integration/api_client_authorizations_scopes_test.rb
index 83a6337644..93e5b42a21 100644
--- a/services/api/test/integration/api_client_authorizations_scopes_test.rb
+++ b/services/api/test/integration/api_client_authorizations_scopes_test.rb
@@ -70,7 +70,7 @@ class ApiTokensScopeTest < ActionDispatch::IntegrationTest
     token_count = get_token_count
     # Test the POST scope.
     post(v1_url('api_client_authorizations'),
-      params: {api_client_authorization: {user_id: users(:active).id}},
+      params: {api_client_authorization: {owner_uuid: users(:active).uuid}},
       headers: auth(:active_apitokens))
     assert_response :success
     assert_equal(token_count + 1, get_token_count,
diff --git a/services/workbench2/src/store/advanced-tab/advanced-tab.tsx b/services/workbench2/src/store/advanced-tab/advanced-tab.tsx
index fedd551864..130a601697 100644
--- a/services/workbench2/src/store/advanced-tab/advanced-tab.tsx
+++ b/services/workbench2/src/store/advanced-tab/advanced-tab.tsx
@@ -583,15 +583,13 @@ const userApiResponse = (apiResponse: UserResource): JSX.Element => {
 
 const apiClientAuthorizationApiResponse = (apiResponse: ApiClientAuthorization): JSX.Element => {
     const {
-        uuid, ownerUuid, apiToken, apiClientId, userId, createdByIpAddress, lastUsedByIpAddress,
+        uuid, ownerUuid, apiToken, createdByIpAddress, lastUsedByIpAddress,
         lastUsedAt, expiresAt, defaultOwnerUuid, scopes, updatedAt, createdAt
     } = apiResponse;
     const response = `
 "uuid": "${uuid}",
 "owner_uuid": "${ownerUuid}",
 "api_token": "${stringify(apiToken)}",
-"api_client_id": "${stringify(apiClientId)}",
-"user_id": "${stringify(userId)}",
 "created_by_ip_address": "${stringify(createdByIpAddress)}",
 "last_used_by_ip_address": "${stringify(lastUsedByIpAddress)}",
 "last_used_at": "${stringify(lastUsedAt)}",

commit 6bd3ba426afa94cfab04f1619f50f8b7f6509024
Author: Tom Clegg <tom at curii.com>
Date:   Wed May 15 16:50:31 2024 -0400

    15397: Update example to non-deprecated API.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/sdk/R/README.md b/sdk/R/README.md
index fe98e648ca..32df6d3a47 100644
--- a/sdk/R/README.md
+++ b/sdk/R/README.md
@@ -346,7 +346,7 @@ subcollection$copy("destination/folder")
 
 ```r
 ?collections_update
-?jobs_get
+?workflows_get
 ```
 
  <!-- Taka konwencja USAGE -->

commit 019c07a3ab1a24700a652a1484430e564526e6e8
Author: Tom Clegg <tom at curii.com>
Date:   Wed May 15 14:03:22 2024 -0400

    15397: Remove TOC links to removed pages.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>

diff --git a/doc/_config.yml b/doc/_config.yml
index d64bc4b7dc..79e9ac95b4 100644
--- a/doc/_config.yml
+++ b/doc/_config.yml
@@ -134,18 +134,6 @@ navbar:
       - api/methods/containers.html.textile.liquid
       - api/methods/workflows.html.textile.liquid
       - api/dispatch.html.textile.liquid
-    - Jobs engine (legacy):
-      - api/crunch-scripts.html.textile.liquid
-      - api/methods/jobs.html.textile.liquid
-      - api/methods/job_tasks.html.textile.liquid
-      - api/methods/pipeline_instances.html.textile.liquid
-      - api/methods/pipeline_templates.html.textile.liquid
-      - api/methods/nodes.html.textile.liquid
-      - api/methods/keep_disks.html.textile.liquid
-    - Metadata for bioinformatics (legacy):
-      - api/methods/humans.html.textile.liquid
-      - api/methods/specimens.html.textile.liquid
-      - api/methods/traits.html.textile.liquid
   architecture:
     - Topics:
       - architecture/index.html.textile.liquid

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


hooks/post-receive
-- 




More information about the arvados-commits mailing list