20937: Fix progress writer
[arvados.git] / sdk / python / arvados / commands / federation_migrate.py
index 11f9d14d3956b32514660edd3010e2bc19429255..770e1609db6ec60dc39567678986c53f3a6f5a35 100755 (executable)
@@ -24,6 +24,7 @@ import os
 import hashlib
 import re
 from arvados._version import __version__
+from . import _util as arv_cmd
 
 EMAIL=0
 USERNAME=1
@@ -43,10 +44,10 @@ def connect_clusters(args):
                 host = r[0]
                 token = r[1]
                 print("Contacting %s" % (host))
-                arv = arvados.api(host=host, token=token, cache=False)
+                arv = arvados.api(host=host, token=token, cache=False, num_retries=args.retries)
                 clusters[arv._rootDesc["uuidPrefix"]] = arv
     else:
-        arv = arvados.api(cache=False)
+        arv = arvados.api(cache=False, num_retries=args.retries)
         rh = arv._rootDesc["remoteHosts"]
         tok = arv.api_client_authorizations().current().execute()
         token = "v2/%s/%s" % (tok["uuid"], tok["api_token"])
@@ -96,13 +97,12 @@ def fetch_users(clusters, loginCluster):
     by_email = {}
     by_username = {}
 
-    users = []
-    for c, arv in clusters.items():
-        print("Getting user list from %s" % c)
-        ul = arvados.util.list_all(arv.users().list, bypass_federation=True)
-        for l in ul:
-            if l["uuid"].startswith(c):
-                users.append(l)
+    users = [
+        user
+        for prefix, arv in clusters.items()
+        for user in arvados.util.keyset_list_all(arv.users().list, bypass_federation=True)
+        if user['uuid'].startswith(prefix)
+    ]
 
     # Users list is sorted by email
     # Go through users and collect users with same email
@@ -110,7 +110,7 @@ def fetch_users(clusters, loginCluster):
     # call add_accum_rows() to generate the report rows with
     # the "home cluster" set, and also fill in the by_email table.
 
-    users = sorted(users, key=lambda u: u["email"]+"::"+(u["username"] or "")+"::"+u["uuid"])
+    users.sort(key=lambda u: (u["email"], u["username"] or "", u["uuid"]))
 
     accum = []
     lastemail = None
@@ -320,13 +320,16 @@ def migrate_user(args, migratearv, email, new_user_uuid, old_user_uuid):
         name_collision = re.search(r'Key \(owner_uuid, name\)=\((.*?), (.*?)\) already exists\.\n.*UPDATE "(.*?)"', e._get_reason())
         if name_collision:
             target_owner, rsc_name, rsc_type = name_collision.groups()
-            print("(%s) Target owner %s already has a %s named '%s', skipping. Please rename it or use --data-into-subproject to migrate all users' data into a special subproject." % (email, target_owner, rsc_type[:-1], rsc_name))
+            print("(%s) Cannot migrate to %s because both origin and target users have a %s named '%s'. Please rename the conflicting items or use --data-into-subproject to migrate all users' data into a special subproject." % (email, target_owner, rsc_type[:-1], rsc_name))
         else:
             print("(%s) Skipping user migration because of error: %s" % (email, e))
 
 
 def main():
-    parser = argparse.ArgumentParser(description='Migrate users to federated identity, see https://doc.arvados.org/admin/merge-remote-account.html')
+    parser = argparse.ArgumentParser(
+        description='Migrate users to federated identity, see https://doc.arvados.org/admin/merge-remote-account.html',
+        parents=[arv_cmd.retry_opt],
+    )
     parser.add_argument(
         '--version', action='version', version="%s %s" % (sys.argv[0], __version__),
         help='Print version and exit.')