Repository: DataBiosphere/toil

Issue:
_fixPermissions isn't being used in dockerCall 
From the code:
```
# We call this explicitly later on in this function, but we defer it as well to handle unexpected job failure.
    job.defer(_fixPermissions, tool, workDir)
```
Then it is never explicitly called. Things are mostly working OK right now since most of our Dockerized tools have redundant chown functionality builtin. 
_fixPermissions isn't being used in dockerCall 
From the code:
```
# We call this explicitly later on in this function, but we defer it as well to handle unexpected job failure.
    job.defer(_fixPermissions, tool, workDir)
```
Then it is never explicitly called. Things are mostly working OK right now since most of our Dockerized tools have redundant chown functionality builtin. 


Discussion:

Resolving patch:
diff --git a/src/toil/lib/docker.py b/src/toil/lib/docker.py
--- a/src/toil/lib/docker.py
+++ b/src/toil/lib/docker.py
@@ -164,11 +164,16 @@ def _docker(job,
 
     if outfile:
         subprocess.check_call(call, stdout=outfile)
+        _fixPermissions(tool=tool, workDir=workDir)
     else:
         if checkOutput:
-            return subprocess.check_output(call)
+            output = subprocess.check_output(call)
+            _fixPermissions(tool=tool, workDir=workDir)
+            return output
+
         else:
             subprocess.check_call(call)
+            _fixPermissions(tool=tool, workDir=workDir)
 
 
 FORGO = 0


Test patch:
diff --git a/src/toil/test/lib/__init__.py b/src/toil/test/lib/__init__.py
new file mode 100644
diff --git a/src/toil/test/lib/dockerTest.py b/src/toil/test/lib/dockerTest.py
--- a/src/toil/test/lib/dockerTest.py
+++ b/src/toil/test/lib/dockerTest.py
@@ -2,6 +2,7 @@
 import signal
 import time
 import uuid
+from pwd import getpwuid
 from threading import Thread
 
 import os
@@ -112,12 +113,26 @@ def testDockerPipeChain(self, caching=True):
         rv = Job.Runner.startToil(A, options)
         assert rv.strip() == '2'
 
+    def testDockerPermissions(self, caching=True):
+        options = Job.Runner.getDefaultOptions(os.path.join(self.tempDir, 'jobstore'))
+        options.logLevel = 'INFO'
+        options.workDir = self.tempDir
+        options.clean = 'always'
+        if not caching:
+            options.disableCaching = True
+        A = Job.wrapJobFn(_testDockerPermissions)
+        Job.Runner.startToil(A, options)
+
+    def testDockerPermissionsNonCaching(self):
+        self.testDockerPermissions(caching=False)
+
     def testNonCachingDockerChain(self):
         self.testDockerPipeChain(caching=False)
 
     def testNonCachingDockerClean(self):
         self.testDockerClean(caching=False)
 
+
 def _testDockerCleanFn(job, workDir, detached=None, rm=None, defer=None, containerName=None):
     """
     Test function for test docker_clean.  Runs a container with given flags and then dies leaving
@@ -151,9 +166,23 @@ def killSelf():
     t.start()
     dockerCall(job, tool='quay.io/ucsc_cgl/spooky_test', workDir=workDir, defer=defer, dockerParameters=dockerParameters)
 
+
 def _testDockerPipeChainFn(job):
     """
     Return the result of simple pipe chain.  Should be 2
     """
     parameters = [ ['printf', 'x\n y\n'], ['wc', '-l'] ]
     return dockerCheckOutput(job, tool='quay.io/ucsc_cgl/spooky_test', parameters=parameters)
+
+
+def _testDockerPermissions(job):
+    def ownerName(filename):
+        return getpwuid(os.stat(filename).st_uid).pw_name
+
+    testDir = job.fileStore.getLocalTempDir()
+    dockerCall(job, tool='ubuntu', workDir=testDir, parameters=[['touch', '/data/test.txt']])
+    outFile = os.path.join(testDir, 'test.txt')
+    assert os.path.exists(outFile)
+    assert not "root" == ownerName(outFile)
+
+