#!${buildout:executable} equeue_database = '${equeue:database}' equeue_lockfile = '${equeue:lockfile}' takeover_script = '${resiliency-takeover-script:wrapper-takeover}' import atexit import cgi import cgitb import datetime import gdbm import os import shutil import subprocess import sys import tempfile if os.path.exists('resilient_software_release_information.py'): from resilient_software_release_information import main as resilient_main else: resilient_main = lambda: {} cgitb.enable() def deleteTemporaryDirectory(path): if os.path.exists(path): shutil.rmtree(path) def getLatestBackupDate(): """ Get the date of the latest successful backup. """ # Create a copy of the db (locked by equeue process) temporary_directory = tempfile.mkdtemp() atexit.register(deleteTemporaryDirectory, temporary_directory) equeue_database_copy = os.path.join(temporary_directory, 'equeue.db') shutil.copyfile(equeue_database, equeue_database_copy) db = gdbm.open(equeue_database_copy) # 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(): result = False else: last_backup = db[db.keys()[0]] for callback in db.keys(): timestamp = float(db[callback]) if timestamp < last_backup: last_backup = timestamp result = datetime.datetime.fromtimestamp(last_backup) db.close() shutil.rmtree(temporary_directory) return result def isBackupInProgress(): """ Check if backup is in progress (importer script is running) by checking if equeue lockfile exists. """ # XXX: check if file is valid return os.path.exists(equeue_lockfile) def getInformationFromSoftwareRelease(): result = resilient_main() if isinstance(result, dict): return result else: return {'Custom Information': 'Error, received information is malformed'} def getSoftwareReleaseInformationFormatted(): result_string = "" for key, value in getInformationFromSoftwareRelease().items(): result_string += "

%s: %s

" % (key, value) return result_string latest_backup_date = getLatestBackupDate() if latest_backup_date == False: latest_backup_message = "No backup downloaded yet, takeover should not happen now." else: latest_backup_message = latest_backup_date.strftime('%Y-%m-%d %H:%M:%S') print "Content-Type: text/html" print form = cgi.FieldStorage() if "password" not in form: print """

This is takeover web interface.

Calling takeover will stop and freeze the current main instance, and make this clone instance the new main instance, replacing the old one.

Warning: submit the form only if you understand what you are doing.

Note: the password asked here can be found within the parameters of your SlapOS instance page.

Last valid backup: %s

Importer script(s) of backup in progress: %s

Backup Signature: ${resilient-web-takeover-cgi-script:proof-signature-url}

""" % (latest_backup_message, isBackupInProgress(), getSoftwareReleaseInformationFormatted()) sys.exit(0) if form['password'].value != '${:password}': print "


" print "Password is invalid." sys.exit(1) # XXX hardcoded location result = subprocess.check_output([takeover_script], stderr=subprocess.STDOUT) print 'Success.' print '
' % result