[WIP] ONOS-8091 Port python script and utilities to python3

Steps performed so far:
- Updated bash scripts and similar to explicitly invoke python3 (instead of python)
- Updated all python scripts using 2to3

Testing these changes will be a major headache because:
- different scripts are executed in different environments
  (e.g., Jenkins, cell servers, tutorial VMs, etc.)
- we don’t have control on all environments
- some environments we used to control have been dismissed
  (e.g., cell servers)

The approach for now is to focus on the essentials:
- Jenkins jobs for pre-merge and release

Test and fix everything else as the need arises.

Change-Id: I943e214760c9dea9a7ded0d47ef08adbc0ed0bec
diff --git a/tools/build/bazel/dependencies_pom_generator.py b/tools/build/bazel/dependencies_pom_generator.py
index f2df0c2..2eefc1a 100755
--- a/tools/build/bazel/dependencies_pom_generator.py
+++ b/tools/build/bazel/dependencies_pom_generator.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # Copyright 2019-present Open Networking Foundation
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,7 +20,7 @@
 def resolve(mvn_coord):
     mvn_pieces = mvn_coord.split(":")
     if mvn_pieces[0] != "mvn":
-        raise ("Invalid Maven coordinate: %s" % mvn_coord)
+        raise "Invalid Maven coordinate: %s"
     return dict(
         groupId=mvn_pieces[1],
         artifactId=mvn_pieces[2],
@@ -79,7 +79,7 @@
                 dep_template.format(scope='test', **deps[x])
                 for x in test_deps])
         else:
-            for old, new in var_dict.items():
+            for old, new in list(var_dict.items()):
                 line = line.replace(old, new)
             new_lines.append(line)
 
@@ -111,7 +111,7 @@
     for var in args.vars:
         pieces = var.split('=')
         if len(pieces) != 2:
-            raise ("Invalid var '%s'" % var)
+            raise "Invalid var '%s'"
         processed_vars["<!-- %s -->" % pieces[0]] = pieces[1]
 
     generate_pom(
diff --git a/tools/build/bazel/onos_app_bundler.py b/tools/build/bazel/onos_app_bundler.py
index 6c4ca68..5aa77a0 100755
--- a/tools/build/bazel/onos_app_bundler.py
+++ b/tools/build/bazel/onos_app_bundler.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 """
  Copyright 2018-present Open Networking Foundation
 
@@ -60,5 +60,5 @@
         print('There must be an even number of args: file mvn_coords')
         sys.exit(2)
 
-    files = zip(*[iter(args)]*2)
+    files = list(zip(*[iter(args)]*2))
     generateOar(output, files)
diff --git a/tools/build/bazel/onos_app_tools.py b/tools/build/bazel/onos_app_tools.py
index 9979ab5..d780634 100755
--- a/tools/build/bazel/onos_app_tools.py
+++ b/tools/build/bazel/onos_app_tools.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 """
  Copyright 2018-present Open Networking Foundation
 
diff --git a/tools/build/bazel/osgi_feature_bundler.py b/tools/build/bazel/osgi_feature_bundler.py
index a4550e0..f390c88 100755
--- a/tools/build/bazel/osgi_feature_bundler.py
+++ b/tools/build/bazel/osgi_feature_bundler.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 """
  Copyright 2018-present Open Networking Foundation
 
@@ -56,5 +56,5 @@
         print('There must be an even number of args: file mvn_coords')
         sys.exit(2)
 
-    files = zip(*[iter(args)]*2)
+    files = list(zip(*[iter(args)]*2))
     writeFeatureBundle(output, files)
diff --git a/tools/build/bazel/pom_generator.py b/tools/build/bazel/pom_generator.py
index 2e16f49..1ad54ec 100755
--- a/tools/build/bazel/pom_generator.py
+++ b/tools/build/bazel/pom_generator.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 """
  Copyright 2018-present Open Networking Foundation
 
@@ -49,7 +49,7 @@
         with open(name, "w") as file:
             file.write(msg)
     else:
-        print msg
+        print(msg)
 
 
 def write_pom(output, coords, deps):
@@ -70,7 +70,7 @@
     import sys
 
     if len(sys.argv) < 3:
-        print 'usage: pom_generator pom.xml maven_coords dep_coords1 dep_coords2 ...'
+        print('usage: pom_generator pom.xml maven_coords dep_coords1 dep_coords2 ...')
         sys.exit(1)
 
     output = sys.argv[1]
diff --git a/tools/build/check-uploaded-maven-artifacts b/tools/build/check-uploaded-maven-artifacts
index 05819f1..2dfc4ad 100755
--- a/tools/build/check-uploaded-maven-artifacts
+++ b/tools/build/check-uploaded-maven-artifacts
@@ -1,5 +1,4 @@
-#! /usr/bin/env python
-
+#! /usr/bin/env python3
 # Spot checks some published artifacts to be sure that they uploaded correctly
 # to the release repository
 
@@ -12,7 +11,7 @@
 from requests.auth import HTTPBasicAuth
 
 if len(sys.argv) != 4:
-    print "usage: check-uploaded-maven-artifact version buildRoot repoRoot"
+    print("usage: check-uploaded-maven-artifact version buildRoot repoRoot")
     sys.exit(1)
 
 version = sys.argv[1]
@@ -24,8 +23,8 @@
     repoResponse = requests.head(remoteUrl)
 
     if repoResponse.status_code != 200:
-        print 'Cannot find jar file artifact at ' + remoteUrl
-        print repoResponse.text
+        print('Cannot find jar file artifact at ' + remoteUrl)
+        print(repoResponse.text)
         sys.exit(1)
 
     remoteSize = int(repoResponse.headers['content-length'])
@@ -38,7 +37,7 @@
     expectedSha1 = localArtifactSha.hexdigest()
 
     if localSize != remoteSize:
-        print 'Size for ' + remoteUrl + ' is wrong local ' + str(localSize) + ' but found remote ' + str(remoteSize)
+        print('Size for ' + remoteUrl + ' is wrong local ' + str(localSize) + ' but found remote ' + str(remoteSize))
         sys.exit(1)
 
     sha1 = ''
@@ -49,8 +48,8 @@
         sha1 = repoResponse.headers['x-checksum-sha1']
 
     if sha1 != expectedSha1:
-        print 'SHA1 hash is wrong for ' + remoteUrl + ' expected ' + \
-              expectedSha1 + ' but found ' + sha1
+        print('SHA1 hash is wrong for ' + remoteUrl + ' expected ' + \
+              expectedSha1 + ' but found ' + sha1)
         sys.exit(1)
 
 def checkArtifactsForComponent(version, name, component, buildRoot, repoRoot):
diff --git a/tools/build/onos-close-staging b/tools/build/onos-close-staging
index e70d119..1e37ef3 100755
--- a/tools/build/onos-close-staging
+++ b/tools/build/onos-close-staging
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # This script finds an open staging repository, checks that it contains an
 # expected artifact, attemps to close the repository, and checks that it is closed.
@@ -29,7 +29,7 @@
       resp.raise_for_status()
       return resp
     except requests.exceptions.HTTPError as e:
-      print 'Encountered error:', e
+      print('Encountered error:', e)
       error = e
       time.sleep(1)
   if error:
@@ -46,7 +46,7 @@
       resp.raise_for_status()
       return resp
     except requests.exceptions.HTTPError as e:
-      print 'Encountered error:', e
+      print('Encountered error:', e)
       error = e
       time.sleep(1)
   if error:
@@ -64,11 +64,11 @@
       repos.append(( entry['repositoryId'], entry['profileId'] ))
   
   if len(repos) > 1:
-    print 'Aborting... too many open staging repos'
-    print repos
+    print('Aborting... too many open staging repos')
+    print(repos)
     sys.exit(1)
   elif len(repos) == 0:
-    print 'Aborting... there are no open staging repos'
+    print('Aborting... there are no open staging repos')
     sys.exit(1)
 
   return repos[0]  
@@ -131,8 +131,8 @@
     if event['name'] == 'repositoryClosed':
       return True
     elif event['name'] == 'repositoryCloseFailed':
-      print 'Aborting... repository failed to close'
-      print json.dumps(activity, sort_keys=True, indent=2, separators=(',', ': '))
+      print('Aborting... repository failed to close')
+      print(json.dumps(activity, sort_keys=True, indent=2, separators=(',', ': ')))
       sys.exit(1)
   return False
 
@@ -144,12 +144,12 @@
     sys.stdout.write('.')
     sys.stdout.flush()     
     time.sleep(2)
-  print ' Closed.'
+  print(' Closed.')
 
 if __name__ == '__main__':
   repositoryId, profileId = getStagingRepo(GROUP_ID)
-  print 'Repository Id:', repositoryId
-  print 'Profile Id:', profileId
+  print('Repository Id:', repositoryId)
+  print('Profile Id:', profileId)
 
   checkStagingRepo(repositoryId, ARTIFACT, GROUP_ID, VERSION)
 
@@ -158,5 +158,5 @@
   waitClosed(repositoryId)
 
   if '-d' in sys.argv:
-    print 'Dropping repo %s' % repositoryId
+    print('Dropping repo %s' % repositoryId)
     dropRepo(repositoryId, profileId)
diff --git a/tools/build/onos-prepare-sonar b/tools/build/onos-prepare-sonar
index 1520d9c..feac3fb 100755
--- a/tools/build/onos-prepare-sonar
+++ b/tools/build/onos-prepare-sonar
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
 This script prepares this ONOS directory so that the Sonar Scanner can be run.
@@ -161,7 +161,7 @@
         for coverage_target in coverage_targets_result:
             run_coverage_command.append(str(coverage_target))
     except CalledProcessError:
-        print "Error querying test files for target " + target
+        print("Error querying test files for target " + target)
         return
 
     try:
@@ -175,7 +175,7 @@
         # Find the source files used by the tests
         test_sources = run_command(['bazel', 'query', tests_query])
     except CalledProcessError as exc:
-        print "Error running test files for target " + target
+        print("Error running test files for target " + target)
         raise exc
 
     if not os.path.exists('/tmp/jacoco.exec'):
@@ -317,7 +317,7 @@
     with open(SONAR_PROPERTIES_FILE_NAME, 'w') as out:
         out.write(ROOT_TEMPLATE % sonar_parameters)
         for target in targets:
-            print "Processing coverage for target " + target
+            print("Processing coverage for target " + target)
             write_module(target, out)
 
 
diff --git a/tools/build/onos-release-prerequisites b/tools/build/onos-release-prerequisites
index 92e201d..c1605ac 100755
--- a/tools/build/onos-release-prerequisites
+++ b/tools/build/onos-release-prerequisites
@@ -50,7 +50,7 @@
 
 # Tests availability of the required tools
 function testToolchain {
-    for tool in bash python git java javac mvn tar; do
+    for tool in bash python3 git java javac mvn tar; do
         testTool $tool;
     done
     testGerritTool
diff --git a/tools/build/onos-upload-artifacts.py b/tools/build/onos-upload-artifacts.py
index a9b24c5..d5f0079 100755
--- a/tools/build/onos-upload-artifacts.py
+++ b/tools/build/onos-upload-artifacts.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 """
  Copyright 2018-present Open Networking Foundation
 
@@ -147,8 +147,8 @@
         with open(file, 'rb') as f:
             r = requests.post(url, data=f.read(), headers=headers, auth=(SONATYPE_USER, SONATYPE_PASSWORD))
             if r.status_code != 201:
-                print (r.status_code)
-                print (r.text)
+                print((r.status_code))
+                print((r.text))
                 sys.exit(1)
     else:
         # deploy to local repo
@@ -165,7 +165,7 @@
 
 
 def upload_file(src, dest):
-    print ("publishing: " + dest.replace("org/onosproject", ""))
+    print(("publishing: " + dest.replace("org/onosproject", "")))
     files = generate_metadata_files(src, dest)
     stage_files(files, dest)
 
@@ -174,7 +174,7 @@
     import sys
 
     if len(sys.argv) < 2:
-        print 'USAGE: upload-maven-artifacts catalog-file-name [nexus root url]'
+        print('USAGE: upload-maven-artifacts catalog-file-name [nexus root url]')
         sys.exit(1)
 
     input_list_file = sys.argv[1]
@@ -191,20 +191,20 @@
 
     if destination_repo_url is not None:
         if SONATYPE_USER is None:
-            print "Environment variable SONATYPE_USER must be set"
+            print("Environment variable SONATYPE_USER must be set")
             sys.exit(1)
 
         if SONATYPE_PASSWORD is None:
-            print "Environment variable SONATYPE_PASSWORD must be set"
+            print("Environment variable SONATYPE_PASSWORD must be set")
             sys.exit(1)
 
         if SONATYPE_PROFILE is None:
-            print "Environment variable SONATYPE_PROFILE must be set"
+            print("Environment variable SONATYPE_PROFILE must be set")
             sys.exit(1)
 
-        print ("Uploading to remote repo: " + destination_repo_url)
+        print(("Uploading to remote repo: " + destination_repo_url))
     else:
-        print ("Installing in local repo: " + local_maven_repo)
+        print(("Installing in local repo: " + local_maven_repo))
 
     list_file = open(input_list_file, "r")
     lines = list_file.readlines()
diff --git a/tools/build/onosUploadBits.py b/tools/build/onosUploadBits.py
index ae88b5c..03327c9 100755
--- a/tools/build/onosUploadBits.py
+++ b/tools/build/onosUploadBits.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # -----------------------------------------------------------------------------
 # Uploads ONOS distributable bits.
 # -----------------------------------------------------------------------------
@@ -29,7 +29,7 @@
         if match:
             version = match.group(1)
             if target_version is not None and version != target_version:
-                print 'Skipping %s...' % filePath
+                print('Skipping %s...' % filePath)
                 continue
             build = match.group(2)
             if build:
diff --git a/tools/build/uploadToS3.py b/tools/build/uploadToS3.py
index 720878c..40ebe34 100755
--- a/tools/build/uploadToS3.py
+++ b/tools/build/uploadToS3.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 """
 Upload a file to S3
 """
@@ -20,7 +20,7 @@
         key = basename( filename )
     else:
         key = dest + basename( filename ) #FIXME add the /
-    print '* Uploading', filename, 'to bucket', bucket, 'as', key
+    print('* Uploading', filename, 'to bucket', bucket, 'as', key)
     stdout.flush()
     start = time()
     def callback( transmitted, size ):
@@ -28,9 +28,9 @@
         elapsed = time() - start
         percent = 100.0 * transmitted / size
         kbps = .001 * transmitted / elapsed
-        print ( '\r%d bytes transmitted of %d (%.2f%%),'
+        print(( '\r%d bytes transmitted of %d (%.2f%%),'
                 ' %.2f KB/sec ' %
-                ( transmitted, size, percent, kbps ) ),
+                ( transmitted, size, percent, kbps ) ), end=' ')
         stdout.flush()
     conn = S3Connection()
     bucket = conn.get_bucket( bucket )
@@ -38,11 +38,11 @@
     k.key = key
     if overwrite or not k.exists():
         k.set_contents_from_filename( filename, cb=callback, num_cb=100 )
-        print
+        print()
         elapsed = time() - start
-        print "* elapsed time: %.2f seconds" % elapsed
+        print("* elapsed time: %.2f seconds" % elapsed)
     else:
-        print 'file', basename( filename ), 'already exists in', bucket.name
+        print('file', basename( filename ), 'already exists in', bucket.name)
 
 def testAccess( bucket=None ):
     "Verify access to a bucket"
@@ -51,7 +51,7 @@
 
     conn = S3Connection()
     bucket = conn.get_bucket( bucket )
-    print bucket.get_acl()
+    print(bucket.get_acl())
 
 
 if __name__ == '__main__':