[ARVADOS] updated: f69d2824c997c53caa11d30ba816768bad52e12b

git at public.curoverse.com git at public.curoverse.com
Tue Apr 21 13:41:53 EDT 2015


Summary of changes:
 apps/workbench/Gemfile                             |   2 +-
 apps/workbench/Gemfile.lock                        |   4 +-
 apps/workbench/app/assets/images/mouse-move.gif    | Bin 0 -> 26082 bytes
 .../app/assets/images/pipeline-running.gif         | Bin 0 -> 114564 bytes
 .../app/assets/javascripts/application.js          |   6 +
 .../app/assets/javascripts/modal_pager.js          |  44 +++
 .../app/assets/javascripts/pipeline_instances.js   |  13 +-
 .../app/assets/stylesheets/application.css.scss    |   4 +
 .../app/controllers/actions_controller.rb          | 202 ++++++------
 .../controllers/pipeline_instances_controller.rb   |  54 ++++
 apps/workbench/app/controllers/users_controller.rb |   6 +-
 apps/workbench/app/helpers/application_helper.rb   |  43 ++-
 .../app/helpers/pipeline_instances_helper.rb       |   7 +
 .../views/application/_title_and_buttons.html.erb  |  24 +-
 .../_getting_started_popup.html.erb                | 179 +++++++++++
 apps/workbench/app/views/layouts/body.html.erb     |  34 +-
 .../pipeline_instances/_show_components.html.erb   |   2 +
 .../_show_components_editable.html.erb             |  20 --
 .../views/pipeline_instances/_show_inputs.html.erb |   2 +
 .../views/projects/_show_contents_rows.html.erb    |   4 +-
 apps/workbench/app/views/users/profile.html.erb    |  13 +-
 apps/workbench/config/application.default.yml      |   1 +
 .../test/controllers/actions_controller_test.rb    |  69 ++--
 .../test/helpers/collections_helper_test.rb        |   2 +
 .../test/integration/anonymous_access_test.rb      |  21 +-
 .../test/integration/application_layout_test.rb    |  60 +++-
 apps/workbench/test/integration/errors_test.rb     |  65 ++--
 apps/workbench/test/integration/jobs_test.rb       |   4 +-
 apps/workbench/test/integration/projects_test.rb   |   2 +-
 .../test/integration/report_issue_test.rb          |   3 +-
 .../test/integration/user_profile_test.rb          |  24 +-
 apps/workbench/test/test_helper.rb                 |   2 +-
 doc/_config.yml                                    |  20 +-
 doc/_includes/_navbar_top.liquid                   |   6 +-
 doc/_layouts/default.html.liquid                   |   2 +-
 doc/api/methods/jobs.html.textile.liquid           |   6 +-
 doc/api/schema/Job.html.textile.liquid             |   5 +-
 doc/index.html.liquid                              |  32 +-
 doc/user/index.html.textile.liquid                 |   4 +-
 docker/keep/run-keep.in                            |   2 +-
 docker/mkimage-debootstrap.sh                      |   2 +-
 docker/sso/Dockerfile                              |   3 +-
 sdk/cli/bin/crunch-job                             |  52 ++-
 sdk/go/keepclient/keepclient.go                    | 347 ++++++++++-----------
 sdk/go/keepclient/keepclient_test.go               | 269 ++++++++++++----
 sdk/go/keepclient/root_sorter.go                   |  12 +-
 sdk/go/keepclient/root_sorter_test.go              |   9 +-
 sdk/go/keepclient/support.go                       |  46 +--
 sdk/python/arvados/arvfile.py                      |  16 +-
 sdk/python/arvados/collection.py                   |  77 ++++-
 sdk/python/arvados/keep.py                         | 103 ++++--
 sdk/python/tests/arvados_testutil.py               |   5 +-
 sdk/python/tests/run_test_server.py                |   2 +-
 sdk/python/tests/test_arvfile.py                   |  54 +++-
 sdk/python/tests/test_collections.py               |  59 ++--
 sdk/python/tests/test_keep_client.py               |  67 +++-
 sdk/ruby/lib/arvados/collection.rb                 |  55 +++-
 sdk/ruby/test/test_collection.rb                   |  87 +++++-
 services/api/Gemfile                               |   1 +
 services/api/Gemfile.lock                          |   4 +
 .../app/controllers/arvados/v1/jobs_controller.rb  |  13 +-
 services/api/app/models/commit.rb                  | 255 +++++++++------
 services/api/app/models/job.rb                     |  43 ++-
 services/api/app/models/user.rb                    |   2 +-
 services/api/config/application.default.yml        |   2 +
 .../{zz_load_config.rb => load_config.rb}          |  10 +
 ...preload_all_models.rb => preload_all_models.rb} |   7 +-
 services/api/script/crunch-dispatch.rb             |  80 +++--
 .../test/fixtures/api_client_authorizations.yml    |  10 +-
 services/api/test/fixtures/pipeline_instances.yml  |  19 +-
 services/api/test/fixtures/users.yml               |  27 +-
 .../arvados/v1/commits_controller_test.rb          |  98 ------
 .../functional/arvados/v1/jobs_controller_test.rb  |  41 +++
 .../functional/arvados/v1/users_controller_test.rb |   6 +-
 services/api/test/helpers/git_test_helper.rb       |  30 +-
 services/api/test/test_helper.rb                   |   1 +
 services/api/test/unit/commit_test.rb              | 156 ++++++++-
 services/api/test/unit/job_test.rb                 |  11 +
 services/api/test/unit/user_test.rb                |   3 +
 services/keepproxy/keepproxy.go                    | 220 ++++++-------
 services/keepproxy/keepproxy_test.go               |  10 +-
 services/keepstore/handler_test.go                 |  54 +++-
 services/keepstore/handlers.go                     | 185 +++++------
 services/keepstore/keepstore.go                    | 166 ++++++----
 services/keepstore/keepstore_test.go               | 163 +++++-----
 services/keepstore/pull_worker.go                  |   8 +-
 services/keepstore/pull_worker_integration_test.go |  10 +-
 services/keepstore/pull_worker_test.go             |   2 +-
 services/keepstore/trash_worker.go                 |  15 +-
 services/keepstore/trash_worker_test.go            |   6 +-
 services/keepstore/volume.go                       | 185 +++--------
 services/keepstore/volume_test.go                  | 151 +++++++++
 services/keepstore/volume_unix.go                  |  31 +-
 services/keepstore/volume_unix_test.go             |  57 +++-
 .../arvnodeman/computenode/dispatch/__init__.py    |  10 +-
 services/nodemanager/arvnodeman/daemon.py          |  11 +-
 .../nodemanager/tests/test_computenode_dispatch.py |   6 +-
 services/nodemanager/tests/test_daemon.py          |  26 +-
 98 files changed, 2891 insertions(+), 1502 deletions(-)
 create mode 100644 apps/workbench/app/assets/images/mouse-move.gif
 create mode 100644 apps/workbench/app/assets/images/pipeline-running.gif
 create mode 100644 apps/workbench/app/assets/javascripts/modal_pager.js
 create mode 100644 apps/workbench/app/views/getting_started/_getting_started_popup.html.erb
 rename services/api/config/initializers/{zz_load_config.rb => load_config.rb} (80%)
 rename services/api/config/initializers/{zz_preload_all_models.rb => preload_all_models.rb} (55%)
 create mode 100644 services/keepstore/volume_test.go

       via  f69d2824c997c53caa11d30ba816768bad52e12b (commit)
       via  c674deff8855005e39b5ddf230372cb241bc22b3 (commit)
       via  916a3a8b0dc64709b32e491cf249fcafe0762e65 (commit)
       via  86e078ae126f6651428219c726c34da3bd7f7495 (commit)
       via  e36e6c4e56b4c0667ee3c75cd20e78382327aee9 (commit)
       via  29a1b2c8894db8e6c6b840220b45371c521a17d2 (commit)
       via  f8e6cb30ca6a3cdb20be47f7a81663d4affd0b7f (commit)
       via  b3a23a94b826de04ae02b889eba4e71d9a4ee11f (commit)
       via  2fe2dca0080d20a257e9d750cd6ca9d094f01a61 (commit)
       via  528f9bb789c2c7f5fbf0838732d470a332292901 (commit)
       via  0f56ce4b6192c3d8e00d1fcbb9d5a2e1a2d953c9 (commit)
       via  430ed273384c153c9c78c653db8e02fd54aa2e4a (commit)
       via  c550609485691d8107ae364bfc982569f81f1725 (commit)
       via  3355f801d1c2bb243e4091a4f31cc83a5a1a5d77 (commit)
       via  ae34bc2de285f5bce4a3a6537d454a62f2fa52e6 (commit)
       via  a0993e451f8a5e209df74dc9f8f0e55bdf1c73bd (commit)
       via  9ede4c6a9d45033d0874cb3fa8d2356aeae6fa83 (commit)
       via  1fe347f8cf77564a791b9f98963fc73ee6802c4f (commit)
       via  c5cd44ad4ff0b5d65cab30b8eb702ab3e238a499 (commit)
       via  4ccec6c3e6e96edc4917f15769a30e187484ee52 (commit)
       via  de0f310b710c2a05517e231a8b489301300fed11 (commit)
       via  e9be782d70efaf8c9bf3fc0043d8a17dfe776bfc (commit)
       via  6a8f05bbd4e8ae51464ece5ee73898d7f58edd71 (commit)
       via  dcf97f13fa730ba7af3fee9b6d7044592a30a2be (commit)
       via  52a9e646ea8247d5e1446ab98ba72ab2edb5c703 (commit)
       via  4d078362f10fba8b94cce3ecc3ed8b4924b79b41 (commit)
       via  b0ec95277b9be2bcbe8e35008f490855a98cd70e (commit)
       via  d037508525b0e3c09a475e2ccfb5f7dd7f39f62d (commit)
       via  fc9a042a58627303ecfbda7660563fcfbe458ea5 (commit)
       via  7afe2c73ccdaad21b2d36b345a1627c1ad3f51a1 (commit)
       via  dc96093e6a9d30699ea06d65ebe1ffe6d59977b9 (commit)
       via  41caa50724d03189c5b4104c52bd5253974cf535 (commit)
       via  397191893819083925600a61e2f355a3b6513354 (commit)
       via  d2e7a97c8d24ef8ae61d860e9c972626f80cf2b4 (commit)
       via  dcedf34693a7fcb8e423403d7d1727066ea9ef12 (commit)
       via  0d8d66df56992a39cc032ba482e1ff88de7f22ab (commit)
       via  de34089011627304e8e7588def5f6848311a9843 (commit)
       via  ddd8d6e3452d2c3ff5193a3988c7b6194134d703 (commit)
       via  0b1d679afec2976ee170692f4178fdc28eb25a04 (commit)
       via  bb1380996abe05337ba86061f5edd921dd3b9193 (commit)
       via  efa119244cd38090933fbd0ba29f3604889e9aa9 (commit)
       via  976f560ab04bf570ed58664d97b8b6069b314941 (commit)
       via  912464ad82bad38f1ce7984b6d4b19734a9816a9 (commit)
       via  c50acf62d8bc4a25f3fb432479fabad9b060f878 (commit)
       via  1f6a187a7011becd08bb3cef8bc5c4e253900590 (commit)
       via  08c4f5f03fd9afd86c4d9c43c7b8620ef9a0fade (commit)
       via  33d54abd1574c16685e2d631d367a1be4e969018 (commit)
       via  cdecff5125a3bc09720be4d210536a183e43ce7e (commit)
       via  18ac672a5c9b5416e21a3d45ed268f2edb509786 (commit)
       via  cd8db86a9178dd43f9582f55d9a14bde3f2e348a (commit)
       via  0bff4d895d0ce312524c9d689923c9590f81f36f (commit)
       via  be238c74d0d3835b0a384b712d7591dc95da8c07 (commit)
       via  a756a90a381473adcfe8cce6a022f1733395610a (commit)
       via  8e2150eb5dd257f0715c9ac050a8260279bb5d5c (commit)
       via  d743a56addcde9d92876d19201b9f46db42ea582 (commit)
       via  aafef3d22a7b225e82da5f146cb05472747a7b6e (commit)
       via  6261cf9003ec37622d38a3c40d94a75eff397922 (commit)
       via  1b2afc5aa599eb452a1f30e706e19b964e26cae0 (commit)
       via  0f119f7707d93e90842fce3890deffc59c5e7081 (commit)
       via  0d1d51b93a9009b6d4e423871886f0cbc65584c7 (commit)
       via  3bc94fb2d1e5c1e351f822ca5ec8f83260e039bb (commit)
       via  58e91ef73e6802978dfea0f93072d75be8ee221c (commit)
       via  e5b35f15d99b6371ef477408552375a762a12b38 (commit)
       via  986e124a61c64ae1a31fdbc33d2da6ac061ada17 (commit)
       via  3280e2dc5fd16dca63c389b931658d4420faabaf (commit)
       via  3f59bec0b3be2cb8718ee310df490c7f41aa8194 (commit)
       via  a632845c40c3a3421914efa1617e0a886d8b1d63 (commit)
       via  84f85c502498a863ea6bdc0fb6d2a7d0d4175936 (commit)
       via  dbdd94518d916b89f8e3a3fa0901da21a2493962 (commit)
       via  3e271eb8bc19f67465a33a69dc66a27021301fae (commit)
       via  fe9235552e6998eb86bc2ad80716bafe7a7ffd16 (commit)
       via  01dae203dd620f02b5bfa4aebf4fb217aa2817dc (commit)
       via  6c4d59cb70206b1770bd64b8db204d669cb2c55a (commit)
       via  93f6a595b7e69f955f2adee12ec512aa078cfdc9 (commit)
       via  92b3f3edf77492c6667d785e2d7214231dd9e78a (commit)
       via  9fb28073a1c7a140e44a20e0555028e9a9dbcf51 (commit)
       via  3f016eae9d2431abfb8e8cc1cabdb1a494e49bf2 (commit)
       via  d72f3039300613487af606ce69e5b7b8b2c67027 (commit)
       via  cc133acd3b94cfdf6b0770f12c0a4ed6b458ef18 (commit)
       via  a8ef8be836b1805b4e35922ea787caad7b81f689 (commit)
       via  320c333f2b49acd698b49b73ed01d32da4d15c8c (commit)
       via  43aa02f5af636f874bac5ffe96cff0061bcd6a44 (commit)
       via  ee60fe9a20238dfac97dd988380c0149a84c372a (commit)
       via  ef2572886ea8693f16316cbfe537053f106a2bb5 (commit)
       via  95298001afb4cb471d16bd181a8487ebe58bb0d4 (commit)
       via  0acda438a00257099b07141f21ad18cf92f03355 (commit)
       via  8893e8cf0dfd542508e9e45d715ee0165b249bd8 (commit)
       via  c17712a6fd8264e3b9fecfedc5124a9b6df00a14 (commit)
       via  ec8879aa56810dfc6475ad8cdc56770ff91f84f2 (commit)
       via  ee0411ef10f4e1c9aa207b8aa9c92bc36cb629e6 (commit)
       via  bd4fd5000f4f55035a0c31abb134d743888de72e (commit)
       via  873226313cdc0d05a39a79a60a4fccdbf8b8c0fc (commit)
       via  679eef491b59a4c38a0b2914ff85e0a8c5059b2c (commit)
       via  c162a42573cdce83a35c54e630622544404012f7 (commit)
       via  88f57312fe5e2226f113dc5ecb0a5edce018701d (commit)
       via  de7c71aac6a8e93f84d515e42859cce674eab009 (commit)
       via  645b161de03001fee5663397f033a2efb17bda98 (commit)
       via  6dffa00d8e284e3e5266b9d318cd6c732ae905f4 (commit)
       via  dcd96ef83d878c48e588a815d7793e6004c4f08c (commit)
       via  37b57a092568ba92a41ee94a74bb0c73e569a18c (commit)
       via  58bd86e6912e25fcee566abd130997dd7bfc8b3c (commit)
       via  6b00d3b8212e8775bb59c5f4deec4797ce44e576 (commit)
       via  9e60acc645d8ee8e223398830e1ccfed3ea18e80 (commit)
       via  9ae180ec18f1f397889a4531a12999942edd003a (commit)
       via  8e4ed0edeadc4dfcc85666ef5c36619815dca8e2 (commit)
       via  50843fcf14d836e82af855fa6775d409054b708d (commit)
       via  a89c721eeb4115b5c6fc38071ef6192e604c4e12 (commit)
       via  e3c562dff0f84634c12e14c232a5ab677892ed6e (commit)
       via  17379ed7eb6e143667e53097f5ada570f051efd1 (commit)
       via  1f5a673014724c3444404658e65e32a6f9c562f3 (commit)
       via  4108d902330bb04a70885f316700cf1da9e7d920 (commit)
       via  15303f9cf99f00ccdef948e5ce593d9a3a88d21a (commit)
       via  7a54e370484b9adb7479fde69665d4adcbb7331f (commit)
       via  b0a3771f2110b691882226c559eab736ab9aa34d (commit)
       via  1f225f2c8479adcaaa918df25455b69464263b2c (commit)
       via  dd532a66ecc0d7ac4a90786d3a4de0c5c00c414e (commit)
       via  e59bc286dd018450cce0b662eeff8effe393d8ae (commit)
       via  7ec30c76580397ca6b06bf1bbdb1ca9dc9f7af2f (commit)
       via  663d024598ea7b6384b9e24e5ea760ecb710ecda (commit)
       via  b10a9487702db5d776c09bfa11f8abcb62f7419a (commit)
       via  53fac68b8025db64c50c0370a16c7afaf4be7bd3 (commit)
       via  5380c722ce344d712cab307d41e0f7a654a4070c (commit)
      from  4077a9af0985d3c85f2f2de2bb7a0f6be581e71e (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 f69d2824c997c53caa11d30ba816768bad52e12b
Merge: 4077a9a c674def
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Tue Apr 21 13:39:36 2015 -0400

    Merge branch 'master' into 3198-writable-fuse
    
    Conflicts:
    	sdk/python/arvados/arvfile.py

diff --cc sdk/python/arvados/arvfile.py
index 95acb9c,7742c45..c0ef581
--- a/sdk/python/arvados/arvfile.py
+++ b/sdk/python/arvados/arvfile.py
@@@ -473,34 -461,30 +473,37 @@@ class _BlockManager(object)
                      if self._put_queue is not None:
                          self._put_queue.task_done()
  
 -        with self.lock:
 -            if self._put_threads is None:
 -                # Start uploader threads.
 -
 -                # If we don't limit the Queue size, the upload queue can quickly
 -                # grow to take up gigabytes of RAM if the writing process is
 -                # generating data more quickly than it can be send to the Keep
 -                # servers.
 -                #
 -                # With two upload threads and a queue size of 2, this means up to 4
 -                # blocks pending.  If they are full 64 MiB blocks, that means up to
 -                # 256 MiB of internal buffering, which is the same size as the
 -                # default download block cache in KeepClient.
 -                self._put_queue = Queue.Queue(maxsize=2)
 -                self._put_errors = Queue.Queue()
 -
 -                self._put_threads = []
 -                for i in xrange(0, self.num_put_threads):
 -                    thread = threading.Thread(target=commit_bufferblock_worker, args=(self,))
 -                    self._put_threads.append(thread)
 -                    thread.daemon = True
 -                    thread.start()
++        if block.state() != _BufferBlock.WRITABLE:
++            return
++
 +        if wait:
 +            block.set_state(_BufferBlock.PENDING)
 +            loc = self._keep.put(block.buffer_view[0:block.write_pointer].tobytes())
 +            block.set_state(_BufferBlock.COMMITTED, loc)
 +        else:
 +            with self.lock:
 +                if self._put_threads is None:
 +                    # Start uploader threads.
 +
 +                    # If we don't limit the Queue size, the upload queue can quickly
 +                    # grow to take up gigabytes of RAM if the writing process is
 +                    # generating data more quickly than it can be send to the Keep
 +                    # servers.
 +                    #
 +                    # With two upload threads and a queue size of 2, this means up to 4
 +                    # blocks pending.  If they are full 64 MiB blocks, that means up to
 +                    # 256 MiB of internal buffering, which is the same size as the
 +                    # default download block cache in KeepClient.
 +                    self._put_queue = Queue.Queue(maxsize=2)
 +                    self._put_errors = Queue.Queue()
 +
 +                    self._put_threads = []
 +                    for i in xrange(0, self.num_put_threads):
 +                        thread = threading.Thread(target=commit_bufferblock_worker, args=(self,))
 +                        self._put_threads.append(thread)
 +                        thread.daemon = True
 +                        thread.start()
  
 -        if block.state() == _BufferBlock.WRITABLE:
              # Mark the block as PENDING so to disallow any more appends.
              block.set_state(_BufferBlock.PENDING)
              self._put_queue.put(block)
@@@ -540,8 -524,7 +543,8 @@@
              items = self._bufferblocks.items()
  
          for k,v in items:
 -            v.owner.flush()
 +            if v.state() == _BufferBlock.WRITABLE:
-                 self.commit_bufferblock(v, False)
++                v.owner.flush(False)
  
          with self.lock:
              if self._put_queue is not None:
@@@ -809,26 -786,20 +813,26 @@@ class ArvadosFile(object)
              self._current_bblock = self.parent._my_block_manager().alloc_bufferblock(owner=self)
  
          if (self._current_bblock.size() + len(data)) > config.KEEP_BLOCK_SIZE:
-             self._repack_writes()
+             self._repack_writes(num_retries)
              if (self._current_bblock.size() + len(data)) > config.KEEP_BLOCK_SIZE:
 -                self.parent._my_block_manager().commit_bufferblock(self._current_bblock)
 +                self.parent._my_block_manager().commit_bufferblock(self._current_bblock, False)
                  self._current_bblock = self.parent._my_block_manager().alloc_bufferblock(owner=self)
  
          self._current_bblock.append(data)
  
          replace_range(self._segments, offset, len(data), self._current_bblock.blockid, self._current_bblock.write_pointer - len(data))
  
 +        self.parent.notify(MOD, self.parent, self.name, (self, self))
 +
 +        return len(data)
 +
      @synchronized
-     def flush(self, wait=True):
 -    def flush(self, num_retries=0):
 -        if self._current_bblock:
 -            self._repack_writes(num_retries)
 -            self.parent._my_block_manager().commit_bufferblock(self._current_bblock)
++    def flush(self, wait=True, num_retries=0):
 +        if self.modified():
 +            if self._current_bblock and self._current_bblock.state() == _BufferBlock.WRITABLE:
-                 self._repack_writes()
++                self._repack_writes(num_retries)
 +                self.parent._my_block_manager().commit_bufferblock(self._current_bblock, wait)
 +            self.parent.notify(MOD, self.parent, self.name, (self, self))
  
      @must_be_writable
      @synchronized
diff --cc sdk/python/arvados/collection.py
index 0ecc34a,11eb666..c90f7b3
--- a/sdk/python/arvados/collection.py
+++ b/sdk/python/arvados/collection.py
@@@ -843,37 -792,48 +843,48 @@@ class RichCollectionBase(CollectionBase
          :overwrite:
            Whether to overwrite target file if it already exists.
          """
 -        if source_collection is None:
 -            source_collection = self
  
 -        # Find the object to copy
 -        if isinstance(source, basestring):
 -            source_obj = source_collection.find(source)
 -            if source_obj is None:
 -                raise IOError((errno.ENOENT, "File not found"))
 -            sourcecomponents = source.split("/")
 -        else:
 -            source_obj = source
 -            sourcecomponents = None
 +        source_obj, target_dir, target_name = self._get_src_target(source, target_path, source_collection, True)
 +        target_dir.add(source_obj, target_name, overwrite, False)
  
 -        # Find parent collection the target path
 -        targetcomponents = target_path.split("/")
 +    @must_be_writable
 +    @synchronized
 +    def rename(self, source, target_path, source_collection=None, overwrite=False):
 +        """Move a file or subcollection from `source_collection` to a new path in this collection.
  
 -        # Determine the name to use.
 -        target_name = targetcomponents[-1] if targetcomponents[-1] else (sourcecomponents[-1] if sourcecomponents else None)
 +        :source:
 +          A string with a path to source file or subcollection.
  
 -        if not target_name:
 -            raise errors.ArgumentError("Target path is empty and source is an object.  Cannot determine destination filename to use.")
 +        :target_path:
 +          Destination file or path.  If the target path already exists and is a
 +          subcollection, the item will be placed inside the subcollection.  If
 +          the target path already exists and is a file, this will raise an error
 +          unless you specify `overwrite=True`.
  
 -        target_dir = self.find_or_create("/".join(targetcomponents[0:-1]), COLLECTION)
 +        :source_collection:
 +          Collection to copy `source_path` from (default `self`)
  
 -        if target_name in target_dir and isinstance(self[target_name], RichCollectionBase) and sourcecomponents:
 -            target_dir = target_dir[target_name]
 -            target_name = sourcecomponents[-1]
 +        :overwrite:
 +          Whether to overwrite target file if it already exists.
 +        """
  
 -        target_dir.add(source_obj, target_name, overwrite)
 +        source_obj, target_dir, target_name = self._get_src_target(source, target_path, source_collection, False)
 +        if not source_obj.writable():
 +            raise IOError(errno.EROFS, "Source collection must be writable.")
 +        target_dir.add(source_obj, target_name, overwrite, True)
  
-     @synchronized
+     def portable_manifest_text(self, stream_name="."):
+         """Get the manifest text for this collection, sub collections and files.
+ 
+         This method does not flush outstanding blocks to Keep.  It will return
+         a normalized manifest with access tokens stripped.
+ 
+         :stream_name:
+           Name to use for this stream (directory)
+ 
+         """
+         return self._get_manifest_text(stream_name, True, True)
+ 
      def manifest_text(self, stream_name=".", strip=False, normalize=False):
          """Get the manifest text for this collection, sub collections and files.
  
@@@ -1399,10 -1373,25 +1442,12 @@@ class Collection(RichCollectionBase)
  
              self._manifest_locator = self._api_response["uuid"]
  
-         self._manifest_text = text
-         self.set_unmodified()
+             self._manifest_text = text
+             self.set_unmodified()
+ 
+         return text
  
      @synchronized
 -    def subscribe(self, callback):
 -        self.callbacks.append(callback)
 -
 -    @synchronized
 -    def unsubscribe(self, callback):
 -        self.callbacks.remove(callback)
 -
 -    @synchronized
 -    def notify(self, event, collection, name, item):
 -        for c in self.callbacks:
 -            c(event, collection, name, item)
 -
 -    @synchronized
      def _import_manifest(self, manifest_text):
          """Import a manifest into a `Collection`.
  
diff --cc sdk/python/tests/test_arvfile.py
index 3041e28,3bba841..f89ac72
--- a/sdk/python/tests/test_arvfile.py
+++ b/sdk/python/tests/test_arvfile.py
@@@ -569,8 -591,11 +591,11 @@@ class BlockManagerTest(unittest.TestCas
          mockkeep = mock.MagicMock()
          blockmanager = arvados.arvfile._BlockManager(mockkeep)
          bufferblock = blockmanager.alloc_bufferblock()
+         bufferblock.owner = mock.MagicMock()
 -        bufferblock.owner.flush.side_effect = lambda: blockmanager.commit_bufferblock(bufferblock)
++        bufferblock.owner.flush.side_effect = lambda x: blockmanager.commit_bufferblock(bufferblock, False)
          bufferblock.append("foo")
          blockmanager.commit_all()
+         self.assertTrue(bufferblock.owner.flush.called)
          self.assertTrue(mockkeep.put.called)
          self.assertEqual(bufferblock.state(), arvados.arvfile._BufferBlock.COMMITTED)
          self.assertIsNone(bufferblock.buffer_view)
@@@ -581,6 -606,8 +606,8 @@@
          mockkeep.put.side_effect = arvados.errors.KeepWriteError("fail")
          blockmanager = arvados.arvfile._BlockManager(mockkeep)
          bufferblock = blockmanager.alloc_bufferblock()
+         bufferblock.owner = mock.MagicMock()
 -        bufferblock.owner.flush.side_effect = lambda: blockmanager.commit_bufferblock(bufferblock)
++        bufferblock.owner.flush.side_effect = lambda x: blockmanager.commit_bufferblock(bufferblock, False)
          bufferblock.append("foo")
          with self.assertRaises(arvados.errors.KeepWriteError) as err:
              blockmanager.commit_all()
diff --cc sdk/python/tests/test_collections.py
index 95b6dbe,d3198be..c882971
--- a/sdk/python/tests/test_collections.py
+++ b/sdk/python/tests/test_collections.py
@@@ -884,26 -884,8 +884,26 @@@ class NewCollectionTestCase(unittest.Te
      def test_copy_to_new_dir(self):
          c = Collection('. 781e5e245d69b566979b86e28d23f2c7+10 0:10:count1.txt\n')
          c.copy("count1.txt", "foo/")
-         self.assertEqual(". 781e5e245d69b566979b86e28d23f2c7+10 0:10:count1.txt\n./foo 781e5e245d69b566979b86e28d23f2c7+10 0:10:count1.txt\n", c.manifest_text())
+         self.assertEqual(". 781e5e245d69b566979b86e28d23f2c7+10 0:10:count1.txt\n./foo 781e5e245d69b566979b86e28d23f2c7+10 0:10:count1.txt\n", c.portable_manifest_text())
  
 +    def test_rename_file(self):
 +        c = Collection('. 781e5e245d69b566979b86e28d23f2c7+10 0:10:count1.txt\n')
 +        c.rename("count1.txt", "count2.txt")
 +        self.assertEqual(". 781e5e245d69b566979b86e28d23f2c7+10 0:10:count2.txt\n", c.manifest_text())
 +
 +    def test_move_file_to_dir(self):
 +        c = Collection('. 781e5e245d69b566979b86e28d23f2c7+10 0:10:count1.txt\n')
 +        c.mkdirs("foo")
 +        c.rename("count1.txt", "foo/count2.txt")
 +        self.assertEqual("./foo 781e5e245d69b566979b86e28d23f2c7+10 0:10:count2.txt\n", c.manifest_text())
 +
 +    def test_move_file_to_other(self):
 +        c1 = Collection('. 781e5e245d69b566979b86e28d23f2c7+10 0:10:count1.txt\n')
 +        c2 = Collection()
 +        c2.rename("count1.txt", "count2.txt", source_collection=c1)
 +        self.assertEqual("", c1.manifest_text())
 +        self.assertEqual(". 781e5e245d69b566979b86e28d23f2c7+10 0:10:count2.txt\n", c2.manifest_text())
 +
      def test_clone(self):
          c = Collection('. 781e5e245d69b566979b86e28d23f2c7+10 0:10:count1.txt\n./foo 781e5e245d69b566979b86e28d23f2c7+10 0:10:count2.txt\n')
          cl = c.clone()

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


hooks/post-receive
-- 




More information about the arvados-commits mailing list