11002: Added note explaining why we're expecting a SystemExit to catch a SIGINT ...
[arvados.git] / sdk / python / arvados / commands / arv_copy.py
index 71820b3d2eae8b64377e0b185ea73c6cb2720f84..5c5192860ccd0ed6b079c98d76b164c2ed3800a6 100755 (executable)
@@ -113,7 +113,7 @@ def main():
     copy_opts.set_defaults(recursive=True)
 
     parser = argparse.ArgumentParser(
-        description='Copy a pipeline instance, template or collection from one Arvados instance to another.',
+        description='Copy a pipeline instance, template, workflow, or collection from one Arvados instance to another.',
         parents=[copy_opts, arv_cmd.retry_opt])
     args = parser.parse_args()
 
@@ -425,33 +425,47 @@ def copy_workflow(wf_uuid, src, dst, args):
     # fetch the workflow from the source instance
     wf = src.workflows().get(uuid=wf_uuid).execute(num_retries=args.retries)
 
+    # copy collections and docker images
     if args.recursive:
         wf_def = yaml.safe_load(wf["definition"])
         if wf_def is not None:
-            colls = []
+            locations = []
+            docker_images = {}
             graph = wf_def.get('$graph', None)
             if graph is not None:
-                workflow_collections(graph, colls)
+                workflow_collections(graph, locations, docker_images)
             else:
-                workflow_collections(wf_def, colls)
-            copy_collections(colls, src, dst, args)
+                workflow_collections(wf_def, locations, docker_images)
 
+            if locations:
+                copy_collections(locations, src, dst, args)
+
+            for image in docker_images:
+                copy_docker_image(image, docker_images[image], src, dst, args)
+
+    # copy the workflow itself
     del wf['uuid']
     wf['owner_uuid'] = args.project_uuid
-
     return dst.workflows().create(body=wf).execute(num_retries=args.retries)
 
-def workflow_collections(obj, colls):
+def workflow_collections(obj, locations, docker_images):
     if isinstance(obj, dict):
         loc = obj.get('location', None)
         if loc is not None:
             if loc.startswith("keep:"):
-                colls.append(loc[5:])
+                locations.append(loc[5:])
+
+        docker_image = obj.get('dockerImageId', None) or obj.get('dockerPull', None)
+        if docker_image is not None:
+            ds = docker_image.split(":", 1)
+            tag = ds[1] if len(ds)==2 else 'latest'
+            docker_images[ds[0]] = tag
+
         for x in obj:
-            workflow_collections(obj[x], colls)
-    if isinstance(obj, list):
+            workflow_collections(obj[x], locations, docker_images)
+    elif isinstance(obj, list):
         for x in obj:
-            workflow_collections(x, colls)
+            workflow_collections(x, locations, docker_images)
 
 # copy_collections(obj, src, dst, args)
 #