From 0d3d672b304929597e2eec164608dd558e700a89 Mon Sep 17 00:00:00 2001
From: Bryton Lacquement <bryton.lacquement@nexedi.com>
Date: Wed, 22 Jan 2020 15:05:43 +0000
Subject: [PATCH] stack/resilient: partial support for Python 3

---
 stack/resilient/buildout.hash.cfg             |  8 ++---
 .../resilient-web-takeover-cgi-script.py.in   | 29 +++++++++++--------
 stack/resilient/template-replicated.cfg.in    | 14 ++++-----
 .../templates/monitor-check-resilient-feed.in | 19 ++++++++----
 .../templates/notifier-feed-promise.py.in     | 10 +++++--
 5 files changed, 48 insertions(+), 32 deletions(-)

diff --git a/stack/resilient/buildout.hash.cfg b/stack/resilient/buildout.hash.cfg
index ed1310bb9..3c88ae09d 100644
--- a/stack/resilient/buildout.hash.cfg
+++ b/stack/resilient/buildout.hash.cfg
@@ -30,7 +30,7 @@ md5sum = 0bbe16f3d805afd880a251a4f40ecaf1
 
 [template-replicated]
 filename = template-replicated.cfg.in
-md5sum = 290b380fe3da8736642bc10a8b1163d1
+md5sum = 815fd8f7c42b9cf59b286b0fe77fa76d
 
 [template-parts]
 filename = template-parts.cfg.in
@@ -46,7 +46,7 @@ md5sum = d21472f0e58f928fb827f2cbf22c4d4a
 
 [resilient-web-takeover-cgi-script-download]
 filename = resilient-web-takeover-cgi-script.py.in
-md5sum = 60d4912fdf5e8dafaba9d9f333aa9e36
+md5sum = 675ac9e1cf49ccc8f8eddb541a62d899
 
 [template-wrapper]
 filename = templates/wrapper.in
@@ -54,9 +54,9 @@ md5sum = 8cde04bfd0c0e9bd56744b988275cfd8
 
 [notifier-feed-promise-template]
 filename = templates/notifier-feed-promise.py.in
-md5sum = d75346911dbc4cfcdb39a21e56cd5016
+md5sum = fa6521daaa02fef4dd2ce06d29ef90be
 
 [template-monitor-check-resilient-feed]
 filename = templates/monitor-check-resilient-feed.in
-md5sum = 19ee9055de961acf402e2dfe5b9581d2
+md5sum = af9787f8440fef19924b2e765372b20f
 
diff --git a/stack/resilient/resilient-web-takeover-cgi-script.py.in b/stack/resilient/resilient-web-takeover-cgi-script.py.in
index c9d200596..83ebaa46d 100644
--- a/stack/resilient/resilient-web-takeover-cgi-script.py.in
+++ b/stack/resilient/resilient-web-takeover-cgi-script.py.in
@@ -1,5 +1,6 @@
 #!${buildout:executable}
 
+from __future__ import print_function
 equeue_database = '${equeue:database}'
 equeue_lockfile = '${equeue:lockfile}'
 takeover_script = '${resiliency-takeover-script:wrapper-takeover}'
@@ -8,7 +9,11 @@ import atexit
 import cgi
 import cgitb
 import datetime
-import gdbm
+try:
+  import dbm.gnu as gdbm
+except ImportError:
+  import gdbm
+
 import os
 import shutil
 import subprocess
@@ -39,11 +44,12 @@ def getLatestBackupDate():
   # Usually, there is only one callback (so only one key
   # in the db), but if there are several:
   # Take the "oldest" one (oldest value).
-  if not db.keys():
+  db_keys = db.keys()
+  if not db_keys:
     result = False
   else:
-    last_backup = db[db.keys()[-1]]
-    for callback in db.keys():
+    last_backup = db[db_keys[-1]]
+    for callback in db_keys:
       timestamp = float(db[callback])
       if timestamp < last_backup:
         last_backup = timestamp
@@ -79,12 +85,11 @@ if latest_backup_date == False:
 else:
   latest_backup_message = latest_backup_date.strftime('%Y-%m-%d %H:%M:%S')
 
-print "Content-Type: text/html"
-print
+print("Content-Type: text/html\n")
 
 form = cgi.FieldStorage()
 if "password" not in form:
-  print """<html>
+  print("""<html>
 <body>
   <h1>This is takeover web interface.</h1>
   <p>Calling takeover will stop and freeze the current main instance, and make this clone instance the new main instance, replacing the old one.</p>
@@ -100,15 +105,15 @@ if "password" not in form:
     <input type="submit" value="Take over" style="background: red;">
   </form>
 </body>
-</html>""" % (latest_backup_message, isBackupInProgress(), getSoftwareReleaseInformationFormatted())
+</html>""" % (latest_backup_message, isBackupInProgress(), getSoftwareReleaseInformationFormatted()))
   sys.exit(0)
 
 if form['password'].value != '${:password}':
-  print "<H1>Error</H1>"
-  print "Password is invalid."
+  print("<H1>Error</H1>")
+  print("Password is invalid.")
   sys.exit(1)
 
 # XXX hardcoded location
 result = subprocess.check_output([takeover_script], stderr=subprocess.STDOUT)
-print 'Success.'
-print '<pre>%s</pre>' % result
+print('Success.')
+print('<pre>%s</pre>' % result)
diff --git a/stack/resilient/template-replicated.cfg.in b/stack/resilient/template-replicated.cfg.in
index 6a990ae36..f5fab9935 100644
--- a/stack/resilient/template-replicated.cfg.in
+++ b/stack/resilient/template-replicated.cfg.in
@@ -41,7 +41,7 @@ config-notify = {% for id in range(1,nbbackup|int) %} ${request-pbs-{{namebase}}
 config-name = {{namebase}}0
 # Bubble up all the instance parameters to the requested export instance.
 {% if slapparameter_dict is defined %}
-{% for parameter_name, parameter_value in slapparameter_dict.items() %}
+{% for parameter_name, parameter_value in six.iteritems(slapparameter_dict) %}
 {% if parameter_value is string %}
 config-{{parameter_name}} = {{ parameter_value.split('\n') | join('\n  ') }}
 {% else %}
@@ -49,7 +49,7 @@ config-{{parameter_name}} = {{ parameter_value }}
 {% endif %}
 {% endfor %}
 {% endif %}
-{% for key, value in monitor_dict.iteritems() -%}
+{% for key, value in six.iteritems(monitor_dict) -%}
 config-{{ key }} = {{ value }}
 {% endfor -%}
 {% if sla_parameter_dict == {} -%}
@@ -67,7 +67,7 @@ sla-mode = unique_by_network
 {%         do sla_dict.__setitem__(key[sla_key_secondary_length:], sla_parameter_dict.get(key)) -%}
 {%     endif -%}
 {%   endfor -%}
-{%   for key, value in sla_dict.iteritems() -%}
+{%   for key, value in six.iteritems(sla_dict) -%}
 sla-{{ key }} = {{ value }}
 {%   endfor -%}
 {% endif -%}
@@ -101,7 +101,7 @@ config-number = {{id}}
 config-name = {{namebase}}{{id}}
 config-authorized-key = ${request-pbs-{{namebase}}-{{id}}:connection-ssh-key}
 config-on-notification = ${request-pbs-{{namebase}}-{{id}}:connection-feeds-url}${:pbs-notification-id}
-{% for key, value in monitor_dict.iteritems() -%}
+{% for key, value in six.iteritems(monitor_dict) -%}
 config-{{ key }} = {{ value }}
 {% endfor -%}
 {% if sla_parameter_dict == {} -%}
@@ -119,7 +119,7 @@ sla-mode = unique_by_network
 {%         do sla_dict.__setitem__(key[sla_key_secondary_length:], sla_parameter_dict.get(key)) -%}
 {%     endif -%}
 {%   endfor -%}
-{%   for key, value in sla_dict.iteritems() -%}
+{%   for key, value in six.iteritems(sla_dict) -%}
 sla-{{ key }} = {{ value }}
 {%   endfor -%}
 {% endif %}
@@ -202,7 +202,7 @@ software-type = pull-backup
 name = PBS ({{namebase}} / {{id}})
 config-ignore-known-hosts-file = ${slap-parameter:ignore-known-hosts-file}
 config-monitor-title = PBS ${slap-connection:computer-id}-{{namebase}}-{{id}}
-{% for key, value in monitor_dict.iteritems() -%}
+{% for key, value in six.iteritems(monitor_dict) -%}
 config-{{ key }} = {{ value }}
 {% endfor -%}
 return = ssh-key notification-url feeds-url  {{ monitor_return }}
@@ -222,7 +222,7 @@ sla-mode = unique_by_network
 {%         do sla_dict.__setitem__(key[sla_key_secondary_length:], sla_parameter_dict.get(key)) -%}
 {%     endif -%}
 {%   endfor -%}
-{%   for key, value in sla_dict.iteritems() -%}
+{%   for key, value in six.iteritems(sla_dict) -%}
 sla-{{ key }} = {{ value }}
 {%   endfor %}
 {% endif %}
diff --git a/stack/resilient/templates/monitor-check-resilient-feed.in b/stack/resilient/templates/monitor-check-resilient-feed.in
index de3f6bffa..e8a1e0db0 100644
--- a/stack/resilient/templates/monitor-check-resilient-feed.in
+++ b/stack/resilient/templates/monitor-check-resilient-feed.in
@@ -1,7 +1,12 @@
 #!{{ python_executable }}
 
+from __future__ import print_function
 import os
-import urllib2
+try:
+  from urllib2 import HTTPError, urlopen
+except ImportError:
+  from urllib.error import HTTPError
+  from urllib.request import urlopen
 import sys
 
 input_feed_directory = '{{ input_feed_directory }}'
@@ -12,12 +17,14 @@ feed_file_list = os.listdir(input_feed_directory)
 rss_ok = True
 
 for feed_file_name in feed_file_list:
-  print "Getting %s" % feed_file_name
+  print("Getting", feed_file_name)
   url = base_url + feed_file_name
   try:
-    feed = urllib2.urlopen(url)
+    feed = urlopen(url)
     body = feed.read()
-    open(os.path.join(monitor_feed_directory, feed_file_name + '.rss'), 'w').write(body)
-    print "FEED is ok"
-  except urllib2.HTTPError as e:
+    with open(os.path.join(monitor_feed_directory, feed_file_name + '.rss'),
+              'wb') as f:
+      f.write(body)
+    print("FEED is ok")
+  except HTTPError as e:
     sys.exit("%s is unvailable: %s" % (feed_file_name, e))
diff --git a/stack/resilient/templates/notifier-feed-promise.py.in b/stack/resilient/templates/notifier-feed-promise.py.in
index fb021dabe..e694760fb 100644
--- a/stack/resilient/templates/notifier-feed-promise.py.in
+++ b/stack/resilient/templates/notifier-feed-promise.py.in
@@ -2,7 +2,11 @@
 import csv
 import os
 import sys
-import urllib2
+try:
+  from urllib2 import HTTPError, urlopen
+except ImportError:
+  from urllib.error import HTTPError
+  from urllib.request import urlopen
 
 csv.field_size_limit(sys.maxsize)
 
@@ -15,9 +19,9 @@ for feed_file_name in feed_file_list:
   url = base_url + feed_file_name
   # Try feed consistency
   try:
-    feed = urllib2.urlopen(url)
+    feed = urlopen(url)
     body = feed.read()
-  except urllib2.HTTPError as e:
+  except HTTPError as e:
     sys.exit("%s is unavailable: %s" % (feed_file_name, e))
   with open(os.path.join(notifier_feed_directory, feed_file_name)) as feed_file:
     reader = csv.reader(feed_file)
-- 
2.30.9