Add 'apps/arv-web/' from commit 'f9732ad8460d013c2f28363655d0d1b91894dca5'
[arvados.git] / crunch_scripts / crunchutil / vwd.py
1 import arvados
2 import os
3 import robust_put
4 import stat
5
6 # Implements "Virtual Working Directory"
7 # Provides a way of emulating a shared writable directory in Keep based
8 # on a "check out, edit, check in, merge" model.
9 # At the moment, this only permits adding new files, applications
10 # cannot modify or delete existing files.
11
12 # Create a symlink tree rooted at target_dir mirroring arv-mounted
13 # source_collection.  target_dir must be empty, and will be created if it
14 # doesn't exist.
15 def checkout(source_collection, target_dir, keepmount=None):
16     # create symlinks
17     if keepmount is None:
18         keepmount = os.environ['TASK_KEEPMOUNT']
19
20     if not os.path.exists(target_dir):
21         os.makedirs(target_dir)
22
23     l = os.listdir(target_dir)
24     if len(l) > 0:
25         raise Exception("target_dir must be empty before checkout, contains %s" % l)
26
27     stem = os.path.join(keepmount, source_collection)
28     for root, dirs, files in os.walk(os.path.join(keepmount, source_collection), topdown=True):
29         rel = root[len(stem)+1:]
30         for d in dirs:
31             os.mkdir(os.path.join(target_dir, rel, d))
32         for f in files:
33             os.symlink(os.path.join(root, f), os.path.join(target_dir, rel, f))
34
35 # Delete all symlinks and check in any remaining normal files.
36 # If merge == True, merge the manifest with source_collection and return a
37 # CollectionReader for the combined collection.
38 def checkin(source_collection, target_dir, merge=True):
39     # delete symlinks, commit directory, merge manifests and return combined
40     # collection.
41     for root, dirs, files in os.walk(target_dir):
42         for f in files:
43             s = os.lstat(os.path.join(root, f))
44             if stat.S_ISLNK(s.st_mode):
45                 os.unlink(os.path.join(root, f))
46
47     uuid = robust_put.upload(target_dir)
48     if merge:
49         cr1 = arvados.CollectionReader(source_collection)
50         cr2 = arvados.CollectionReader(uuid)
51         combined = arvados.CollectionReader(cr1.manifest_text() + cr2.manifest_text())
52         return combined
53     else:
54         return arvados.CollectionReader(uuid)