resilient-web-takeover-cgi-script.py.in 2.24 KB
Newer Older
1
#!${buildout:executable}
2 3

equeue_database = '${equeue:database}'
4
equeue_lockfile = '${equeue:lockfile}'
5

6 7
import cgi
import cgitb
8 9
import datetime
import gdbm
10
import os
11
import shutil
12 13
import subprocess
import sys
14
import tempfile
15 16
cgitb.enable()

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
def getLatestBackupDate():
  """
  Get the date of the latest successful backup.
  """
  # Create a copy of the db (locked by equeue process)
  temporary_directory = tempfile.mkdtemp()
  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).
  last_backup = db[db.keys()[0]]
  for callback in db.keys():
    timestamp = float(db[callback])
    if timestamp < last_backup:
      last_backup = timestamp
  return datetime.datetime.fromtimestamp(last_backup)

36 37 38 39 40 41 42 43
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)

44
print "Content-Type: text/html"
45
print
46 47 48 49 50 51 52 53 54

form = cgi.FieldStorage()
if "password" not in form:
  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>
  <p><b>Warning: submit the form only if you understand what you are doing.</b></p>
  <p>Note: the password asked here can be found within the parameters of your SlapOS instance page.</p>
55
  <p>Last valid backup: %s</p>
56
  <p>Importer script(s) of backup in progress: %s</p>
57 58 59 60 61
  <form action="/">
    Password: <input type="text" name="password">
    <input type="submit" value="Take over" style="background: red;">
  </form>
</body>
62
</html>""" % (getLatestBackupDate().strftime('%Y-%m-%d %H:%M:%S'), isBackupInProgress())
63 64 65 66 67 68 69 70 71 72 73
  sys.exit(0)

if form['password'].value != '${:password}':
  print "<H1>Error</H1>"
  print "Password is invalid."
  sys.exit(1)

# XXX hardcoded location
result = subprocess.check_output([os.path.expanduser("~/bin/takeover")], stderr=subprocess.STDOUT)
print 'Success.'
print '<pre>%s</pre>' % result